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