1251876Speter/*	$OpenBSD: fsdbutil.c,v 1.21 2024/05/09 08:35:40 florian Exp $	*/
2251876Speter/*	$NetBSD: fsdbutil.c,v 1.5 1996/09/28 19:30:37 christos Exp $	*/
3251876Speter
4251876Speter/*-
5251876Speter * Copyright (c) 1996 The NetBSD Foundation, Inc.
6251876Speter * All rights reserved.
7251876Speter *
8251876Speter * This code is derived from software contributed to The NetBSD Foundation
9251876Speter * by John T. Kohl.
10251876Speter *
11251876Speter * Redistribution and use in source and binary forms, with or without
12251876Speter * modification, are permitted provided that the following conditions
13251876Speter * are met:
14251876Speter * 1. Redistributions of source code must retain the above copyright
15251876Speter *    notice, this list of conditions and the following disclaimer.
16251876Speter * 2. Redistributions in binary form must reproduce the above copyright
17251876Speter *    notice, this list of conditions and the following disclaimer in the
18251876Speter *    documentation and/or other materials provided with the distribution.
19251876Speter *
20251876Speter * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21251876Speter * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22251876Speter * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23251876Speter * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
24251876Speter * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25251876Speter * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26251876Speter * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27251876Speter * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28251876Speter * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29251876Speter * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30251876Speter * POSSIBILITY OF SUCH DAMAGE.
31251876Speter */
32251876Speter
33251876Speter#include <sys/stat.h>
34251876Speter#include <sys/time.h>
35251876Speter#include <sys/mount.h>
36251876Speter#include <ctype.h>
37251876Speter#include <err.h>
38251876Speter#include <fcntl.h>
39251876Speter#include <grp.h>
40251876Speter#include <pwd.h>
41251876Speter#include <stdio.h>
42251876Speter#include <stdlib.h>
43251876Speter#include <string.h>
44251876Speter#include <unistd.h>
45251876Speter
46251876Speter#include <ufs/ufs/dinode.h>
47251876Speter#include <ufs/ffs/fs.h>
48251876Speter
49251876Speter#include "fsdb.h"
50251876Speter#include "fsck.h"
51251876Speter
52251876Speterchar **
53251876Spetercrack(char *line, int *argc)
54251876Speter{
55251876Speter	static char *argv[8];
56251876Speter	int i;
57251876Speter	char *p, *val;
58251876Speter
59251876Speter	for (p = line, i = 0; p != NULL && i < 8; i++) {
60251876Speter		while ((val = strsep(&p, " \t\n")) != NULL && *val == '\0')
61251876Speter			/**/;
62251876Speter		if (val)
63251876Speter			argv[i] = val;
64251876Speter		else
65251876Speter			break;
66251876Speter	}
67251876Speter	*argc = i;
68251876Speter	return argv;
69251876Speter}
70251876Speter
71251876Speterint
72251876Speterargcount(struct cmdtable *cmdp, int argc, char *argv[])
73251876Speter{
74251876Speter	if (cmdp->minargc == cmdp->maxargc)
75251876Speter		warnx("command `%s' takes %u arguments", cmdp->cmd, cmdp->minargc-1);
76251876Speter	else
77251876Speter		warnx("command `%s' takes from %u to %u arguments",
78251876Speter		    cmdp->cmd, cmdp->minargc-1, cmdp->maxargc-1);
79251876Speter	warnx("usage: %s: %s", cmdp->cmd, cmdp->helptxt);
80251876Speter	return 1;
81251876Speter}
82251876Speter
83251876Spetervoid
84251876Speterprintstat(const char *cp, ino_t inum, union dinode *dp)
85251876Speter{
86251876Speter	const char *name;
87251876Speter	time_t t;
88251876Speter	char *p;
89251876Speter
90251876Speter	printf("%s: ", cp);
91251876Speter	switch (DIP(dp, di_mode) & IFMT) {
92251876Speter	case IFDIR:
93251876Speter		puts("directory");
94251876Speter		break;
95251876Speter	case IFREG:
96251876Speter		puts("regular file");
97251876Speter		break;
98251876Speter	case IFBLK:
99251876Speter		printf("block special (%u,%u)",
100251876Speter		    (int)major(DIP(dp, di_rdev)), (int)minor(DIP(dp, di_rdev)));
101251876Speter		break;
102251876Speter	case IFCHR:
103251876Speter		printf("character special (%u,%u)",
104251876Speter		    (int)major(DIP(dp, di_rdev)), (int)minor(DIP(dp, di_rdev)));
105251876Speter		break;
106251876Speter	case IFLNK:
107251876Speter		fputs("symlink",stdout);
108251876Speter		if (DIP(dp, di_size) > 0 &&
109251876Speter		    DIP(dp, di_size) < sblock.fs_maxsymlinklen &&
110251876Speter		    DIP(dp, di_blocks) == 0) {
111251876Speter			char *p = sblock.fs_magic == FS_UFS1_MAGIC ?
112251876Speter			    (char *)dp->dp1.di_shortlink :
113251876Speter			    (char *)dp->dp2.di_shortlink;
114251876Speter			printf(" to `%.*s'\n", (int)DIP(dp, di_size), p);
115251876Speter		} else
116251876Speter			putchar('\n');
117251876Speter		break;
118251876Speter	case IFSOCK:
119251876Speter		puts("socket");
120251876Speter		break;
121251876Speter	case IFIFO:
122251876Speter		puts("fifo");
123251876Speter		break;
124251876Speter	}
125251876Speter
126251876Speter	printf("I=%llu MODE=%o SIZE=%llu", (unsigned long long)inum,
127251876Speter	    DIP(dp, di_mode), DIP(dp, di_size));
128251876Speter	t = DIP(dp, di_mtime);
129251876Speter	p = ctime(&t);
130251876Speter	if (p)
131251876Speter		printf("\n\tMTIME=%15.15s %4.4s [%d nsec]", &p[4], &p[20],
132251876Speter		    DIP(dp, di_mtimensec));
133251876Speter	else
134251876Speter		printf("\n\tMTIME=%lld [%d nsec]", t, DIP(dp, di_mtimensec));
135251876Speter	t = DIP(dp, di_ctime);
136251876Speter	p = ctime(&t);
137251876Speter	if (p)
138251876Speter		printf("\n\tCTIME=%15.15s %4.4s [%d nsec]", &p[4], &p[20],
139251876Speter		    DIP(dp, di_ctimensec));
140251876Speter	else
141251876Speter		printf("\n\tCTIME=%lld [%d nsec]", t, DIP(dp, di_ctimensec));
142251876Speter	t = DIP(dp, di_atime);
143251876Speter	p = ctime(&t);
144251876Speter	if (p)
145251876Speter		printf("\n\tATIME=%15.15s %4.4s [%d nsec]\n", &p[4], &p[20],
146251876Speter		    DIP(dp, di_atimensec));
147251876Speter	else
148251876Speter		printf("\n\tATIME=%lld [%d nsec]\n", t, DIP(dp, di_atimensec));
149251876Speter	if ((name = user_from_uid(DIP(dp, di_uid), 1)) != NULL)
150251876Speter		printf("OWNER=%s ", name);
151251876Speter	else
152251876Speter		printf("OWNUID=%u ", DIP(dp, di_uid));
153251876Speter	if ((name = group_from_gid(DIP(dp, di_gid), 1)) != NULL)
154251876Speter		printf("GRP=%s ", name);
155251876Speter	else
156251876Speter		printf("GID=%u ", DIP(dp, di_gid));
157251876Speter
158251876Speter	printf("LINKCNT=%d FLAGS=%#x BLKCNT=%x GEN=%x\n", DIP(dp, di_nlink),
159251876Speter	    DIP(dp, di_flags), (unsigned)DIP(dp, di_blocks), DIP(dp, di_gen));
160251876Speter}
161251876Speter
162251876Speterint
163251876Spetercheckactive(void)
164251876Speter{
165251876Speter	if (!curinode) {
166251876Speter		warnx("no current inode");
167251876Speter		return 0;
168251876Speter	}
169251876Speter	return 1;
170251876Speter}
171251876Speter
172251876Speterint
173251876Spetercheckactivedir(void)
174251876Speter{
175251876Speter	if (!curinode) {
176251876Speter		warnx("no current inode");
177251876Speter		return 0;
178251876Speter	}
179251876Speter	if ((DIP(curinode, di_mode) & IFMT) != IFDIR) {
180251876Speter		warnx("inode %llu not a directory",
181251876Speter		    (unsigned long long)curinum);
182251876Speter		return 0;
183251876Speter	}
184251876Speter	return 1;
185251876Speter}
186251876Speter
187251876Speterint
188251876Speterprintactive(void)
189251876Speter{
190251876Speter	if (!checkactive())
191251876Speter		return 1;
192251876Speter	switch (DIP(curinode, di_mode) & IFMT) {
193251876Speter	case IFDIR:
194251876Speter	case IFREG:
195251876Speter	case IFBLK:
196251876Speter	case IFCHR:
197251876Speter	case IFLNK:
198251876Speter	case IFSOCK:
199251876Speter	case IFIFO:
200251876Speter		printstat("current inode", curinum, curinode);
201251876Speter		break;
202251876Speter	case 0:
203251876Speter		printf("current inode %llu: unallocated inode\n",
204251876Speter		    (unsigned long long)curinum);
205251876Speter		break;
206251876Speter	default:
207251876Speter		printf("current inode %llu: screwy itype 0%o (mode 0%o)?\n",
208251876Speter		    (unsigned long long)curinum, DIP(curinode, di_mode) & IFMT,
209251876Speter		    DIP(curinode, di_mode));
210251876Speter		break;
211251876Speter	}
212251876Speter	return 0;
213251876Speter}
214251876Speter