xref: /openbsd-src/sbin/fsdb/fsdbutil.c (revision a7b9eedcb4c1ab985f28fc923822c24bc6417908)
1*a7b9eedcSflorian /*	$OpenBSD: fsdbutil.c,v 1.21 2024/05/09 08:35:40 florian Exp $	*/
200829d25Smillert /*	$NetBSD: fsdbutil.c,v 1.5 1996/09/28 19:30:37 christos Exp $	*/
3df930be7Sderaadt 
4be0fe854Sniklas /*-
5be0fe854Sniklas  * Copyright (c) 1996 The NetBSD Foundation, Inc.
6df930be7Sderaadt  * All rights reserved.
7df930be7Sderaadt  *
8be0fe854Sniklas  * This code is derived from software contributed to The NetBSD Foundation
9be0fe854Sniklas  * by John T. Kohl.
10be0fe854Sniklas  *
11df930be7Sderaadt  * Redistribution and use in source and binary forms, with or without
12df930be7Sderaadt  * modification, are permitted provided that the following conditions
13df930be7Sderaadt  * are met:
14df930be7Sderaadt  * 1. Redistributions of source code must retain the above copyright
15df930be7Sderaadt  *    notice, this list of conditions and the following disclaimer.
16df930be7Sderaadt  * 2. Redistributions in binary form must reproduce the above copyright
17df930be7Sderaadt  *    notice, this list of conditions and the following disclaimer in the
18df930be7Sderaadt  *    documentation and/or other materials provided with the distribution.
19df930be7Sderaadt  *
20be0fe854Sniklas  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21be0fe854Sniklas  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22be0fe854Sniklas  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23be0fe854Sniklas  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
24be0fe854Sniklas  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25be0fe854Sniklas  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26be0fe854Sniklas  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27be0fe854Sniklas  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28be0fe854Sniklas  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29be0fe854Sniklas  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30df930be7Sderaadt  * POSSIBILITY OF SUCH DAMAGE.
31df930be7Sderaadt  */
32df930be7Sderaadt 
33df930be7Sderaadt #include <sys/stat.h>
34df930be7Sderaadt #include <sys/time.h>
35df930be7Sderaadt #include <sys/mount.h>
36df930be7Sderaadt #include <ctype.h>
3700829d25Smillert #include <err.h>
38df930be7Sderaadt #include <fcntl.h>
39df930be7Sderaadt #include <grp.h>
40df930be7Sderaadt #include <pwd.h>
41df930be7Sderaadt #include <stdio.h>
42df930be7Sderaadt #include <stdlib.h>
43df930be7Sderaadt #include <string.h>
44df930be7Sderaadt #include <unistd.h>
45df930be7Sderaadt 
46df930be7Sderaadt #include <ufs/ufs/dinode.h>
47df930be7Sderaadt #include <ufs/ffs/fs.h>
48df930be7Sderaadt 
49df930be7Sderaadt #include "fsdb.h"
50df930be7Sderaadt #include "fsck.h"
51df930be7Sderaadt 
52df930be7Sderaadt char **
crack(char * line,int * argc)538809fabbSderaadt crack(char *line, int *argc)
54df930be7Sderaadt {
55df930be7Sderaadt 	static char *argv[8];
56df930be7Sderaadt 	int i;
57df930be7Sderaadt 	char *p, *val;
588809fabbSderaadt 
59df930be7Sderaadt 	for (p = line, i = 0; p != NULL && i < 8; i++) {
60df930be7Sderaadt 		while ((val = strsep(&p, " \t\n")) != NULL && *val == '\0')
61df930be7Sderaadt 			/**/;
62df930be7Sderaadt 		if (val)
63df930be7Sderaadt 			argv[i] = val;
64df930be7Sderaadt 		else
65df930be7Sderaadt 			break;
66df930be7Sderaadt 	}
67df930be7Sderaadt 	*argc = i;
68df930be7Sderaadt 	return argv;
69df930be7Sderaadt }
70df930be7Sderaadt 
71df930be7Sderaadt int
argcount(struct cmdtable * cmdp,int argc,char * argv[])728809fabbSderaadt argcount(struct cmdtable *cmdp, int argc, char *argv[])
73df930be7Sderaadt {
74df930be7Sderaadt 	if (cmdp->minargc == cmdp->maxargc)
75df930be7Sderaadt 		warnx("command `%s' takes %u arguments", cmdp->cmd, cmdp->minargc-1);
76df930be7Sderaadt 	else
77df930be7Sderaadt 		warnx("command `%s' takes from %u to %u arguments",
78df930be7Sderaadt 		    cmdp->cmd, cmdp->minargc-1, cmdp->maxargc-1);
79df930be7Sderaadt 	warnx("usage: %s: %s", cmdp->cmd, cmdp->helptxt);
80df930be7Sderaadt 	return 1;
81df930be7Sderaadt }
82df930be7Sderaadt 
83df930be7Sderaadt void
printstat(const char * cp,ino_t inum,union dinode * dp)84c913562aSmillert printstat(const char *cp, ino_t inum, union dinode *dp)
85df930be7Sderaadt {
86dee31871Smillert 	const char *name;
876ae81f76Sderaadt 	time_t t;
88df930be7Sderaadt 	char *p;
89df930be7Sderaadt 
90df930be7Sderaadt 	printf("%s: ", cp);
91c913562aSmillert 	switch (DIP(dp, di_mode) & IFMT) {
92df930be7Sderaadt 	case IFDIR:
93df930be7Sderaadt 		puts("directory");
94df930be7Sderaadt 		break;
95df930be7Sderaadt 	case IFREG:
96df930be7Sderaadt 		puts("regular file");
97df930be7Sderaadt 		break;
98df930be7Sderaadt 	case IFBLK:
997aa9f692Sderaadt 		printf("block special (%u,%u)",
100c913562aSmillert 		    (int)major(DIP(dp, di_rdev)), (int)minor(DIP(dp, di_rdev)));
101df930be7Sderaadt 		break;
102df930be7Sderaadt 	case IFCHR:
1037aa9f692Sderaadt 		printf("character special (%u,%u)",
104c913562aSmillert 		    (int)major(DIP(dp, di_rdev)), (int)minor(DIP(dp, di_rdev)));
105df930be7Sderaadt 		break;
106df930be7Sderaadt 	case IFLNK:
107df930be7Sderaadt 		fputs("symlink",stdout);
108c913562aSmillert 		if (DIP(dp, di_size) > 0 &&
109c913562aSmillert 		    DIP(dp, di_size) < sblock.fs_maxsymlinklen &&
110c913562aSmillert 		    DIP(dp, di_blocks) == 0) {
111c913562aSmillert 			char *p = sblock.fs_magic == FS_UFS1_MAGIC ?
112c913562aSmillert 			    (char *)dp->dp1.di_shortlink :
113c913562aSmillert 			    (char *)dp->dp2.di_shortlink;
114c913562aSmillert 			printf(" to `%.*s'\n", (int)DIP(dp, di_size), p);
115c913562aSmillert 		} else
116df930be7Sderaadt 			putchar('\n');
117df930be7Sderaadt 		break;
118df930be7Sderaadt 	case IFSOCK:
119df930be7Sderaadt 		puts("socket");
120df930be7Sderaadt 		break;
121df930be7Sderaadt 	case IFIFO:
122df930be7Sderaadt 		puts("fifo");
123df930be7Sderaadt 		break;
124df930be7Sderaadt 	}
1258809fabbSderaadt 
1263b92bd08Sderaadt 	printf("I=%llu MODE=%o SIZE=%llu", (unsigned long long)inum,
1273b92bd08Sderaadt 	    DIP(dp, di_mode), DIP(dp, di_size));
128c913562aSmillert 	t = DIP(dp, di_mtime);
1296ae81f76Sderaadt 	p = ctime(&t);
130*a7b9eedcSflorian 	if (p)
131df930be7Sderaadt 		printf("\n\tMTIME=%15.15s %4.4s [%d nsec]", &p[4], &p[20],
132c913562aSmillert 		    DIP(dp, di_mtimensec));
133*a7b9eedcSflorian 	else
134*a7b9eedcSflorian 		printf("\n\tMTIME=%lld [%d nsec]", t, DIP(dp, di_mtimensec));
135c913562aSmillert 	t = DIP(dp, di_ctime);
1366ae81f76Sderaadt 	p = ctime(&t);
137*a7b9eedcSflorian 	if (p)
138df930be7Sderaadt 		printf("\n\tCTIME=%15.15s %4.4s [%d nsec]", &p[4], &p[20],
139c913562aSmillert 		    DIP(dp, di_ctimensec));
140*a7b9eedcSflorian 	else
141*a7b9eedcSflorian 		printf("\n\tCTIME=%lld [%d nsec]", t, DIP(dp, di_ctimensec));
142c913562aSmillert 	t = DIP(dp, di_atime);
1436ae81f76Sderaadt 	p = ctime(&t);
144*a7b9eedcSflorian 	if (p)
145df930be7Sderaadt 		printf("\n\tATIME=%15.15s %4.4s [%d nsec]\n", &p[4], &p[20],
146c913562aSmillert 		    DIP(dp, di_atimensec));
147*a7b9eedcSflorian 	else
148*a7b9eedcSflorian 		printf("\n\tATIME=%lld [%d nsec]\n", t, DIP(dp, di_atimensec));
149dee31871Smillert 	if ((name = user_from_uid(DIP(dp, di_uid), 1)) != NULL)
150dee31871Smillert 		printf("OWNER=%s ", name);
151df930be7Sderaadt 	else
152c913562aSmillert 		printf("OWNUID=%u ", DIP(dp, di_uid));
153dee31871Smillert 	if ((name = group_from_gid(DIP(dp, di_gid), 1)) != NULL)
154dee31871Smillert 		printf("GRP=%s ", name);
155df930be7Sderaadt 	else
156c913562aSmillert 		printf("GID=%u ", DIP(dp, di_gid));
157df930be7Sderaadt 
1586630c211Sfcambus 	printf("LINKCNT=%d FLAGS=%#x BLKCNT=%x GEN=%x\n", DIP(dp, di_nlink),
159c913562aSmillert 	    DIP(dp, di_flags), (unsigned)DIP(dp, di_blocks), DIP(dp, di_gen));
160df930be7Sderaadt }
161df930be7Sderaadt 
162df930be7Sderaadt int
checkactive(void)1638809fabbSderaadt checkactive(void)
164df930be7Sderaadt {
165df930be7Sderaadt 	if (!curinode) {
16646347781Smpech 		warnx("no current inode");
167df930be7Sderaadt 		return 0;
168df930be7Sderaadt 	}
169df930be7Sderaadt 	return 1;
170df930be7Sderaadt }
171df930be7Sderaadt 
172df930be7Sderaadt int
checkactivedir(void)1738809fabbSderaadt checkactivedir(void)
174df930be7Sderaadt {
175df930be7Sderaadt 	if (!curinode) {
17646347781Smpech 		warnx("no current inode");
177df930be7Sderaadt 		return 0;
178df930be7Sderaadt 	}
179c913562aSmillert 	if ((DIP(curinode, di_mode) & IFMT) != IFDIR) {
1803b92bd08Sderaadt 		warnx("inode %llu not a directory",
1813b92bd08Sderaadt 		    (unsigned long long)curinum);
182df930be7Sderaadt 		return 0;
183df930be7Sderaadt 	}
184df930be7Sderaadt 	return 1;
185df930be7Sderaadt }
186df930be7Sderaadt 
187df930be7Sderaadt int
printactive(void)1888809fabbSderaadt printactive(void)
189df930be7Sderaadt {
190df930be7Sderaadt 	if (!checkactive())
191df930be7Sderaadt 		return 1;
192c913562aSmillert 	switch (DIP(curinode, di_mode) & IFMT) {
193df930be7Sderaadt 	case IFDIR:
194df930be7Sderaadt 	case IFREG:
195df930be7Sderaadt 	case IFBLK:
196df930be7Sderaadt 	case IFCHR:
197df930be7Sderaadt 	case IFLNK:
198df930be7Sderaadt 	case IFSOCK:
199df930be7Sderaadt 	case IFIFO:
200df930be7Sderaadt 		printstat("current inode", curinum, curinode);
201df930be7Sderaadt 		break;
202df930be7Sderaadt 	case 0:
2033b92bd08Sderaadt 		printf("current inode %llu: unallocated inode\n",
2043b92bd08Sderaadt 		    (unsigned long long)curinum);
205df930be7Sderaadt 		break;
206df930be7Sderaadt 	default:
2073b92bd08Sderaadt 		printf("current inode %llu: screwy itype 0%o (mode 0%o)?\n",
2083b92bd08Sderaadt 		    (unsigned long long)curinum, DIP(curinode, di_mode) & IFMT,
209c913562aSmillert 		    DIP(curinode, di_mode));
210df930be7Sderaadt 		break;
211df930be7Sderaadt 	}
212df930be7Sderaadt 	return 0;
213df930be7Sderaadt }
214