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