fsdbutil.c revision 1.18
1/*	$OpenBSD: fsdbutil.c,v 1.18 2017/07/29 21:14:56 fcambus 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#include <sys/stat.h>
34#include <sys/time.h>
35#include <sys/mount.h>
36#include <ctype.h>
37#include <err.h>
38#include <fcntl.h>
39#include <grp.h>
40#include <pwd.h>
41#include <stdio.h>
42#include <stdlib.h>
43#include <string.h>
44#include <unistd.h>
45
46#include <ufs/ufs/dinode.h>
47#include <ufs/ffs/fs.h>
48
49#include "fsdb.h"
50#include "fsck.h"
51
52char **
53crack(char *line, int *argc)
54{
55	static char *argv[8];
56	int i;
57	char *p, *val;
58
59	for (p = line, i = 0; p != NULL && i < 8; i++) {
60		while ((val = strsep(&p, " \t\n")) != NULL && *val == '\0')
61			/**/;
62		if (val)
63			argv[i] = val;
64		else
65			break;
66	}
67	*argc = i;
68	return argv;
69}
70
71int
72argcount(struct cmdtable *cmdp, int argc, char *argv[])
73{
74	if (cmdp->minargc == cmdp->maxargc)
75		warnx("command `%s' takes %u arguments", cmdp->cmd, cmdp->minargc-1);
76	else
77		warnx("command `%s' takes from %u to %u arguments",
78		    cmdp->cmd, cmdp->minargc-1, cmdp->maxargc-1);
79	warnx("usage: %s: %s", cmdp->cmd, cmdp->helptxt);
80	return 1;
81}
82
83void
84printstat(const char *cp, ino_t inum, union dinode *dp)
85{
86	struct group *grp;
87	struct passwd *pw;
88	time_t t;
89	char *p;
90
91	printf("%s: ", cp);
92	switch (DIP(dp, di_mode) & IFMT) {
93	case IFDIR:
94		puts("directory");
95		break;
96	case IFREG:
97		puts("regular file");
98		break;
99	case IFBLK:
100		printf("block special (%d,%d)",
101		    (int)major(DIP(dp, di_rdev)), (int)minor(DIP(dp, di_rdev)));
102		break;
103	case IFCHR:
104		printf("character special (%d,%d)",
105		    (int)major(DIP(dp, di_rdev)), (int)minor(DIP(dp, di_rdev)));
106		break;
107	case IFLNK:
108		fputs("symlink",stdout);
109		if (DIP(dp, di_size) > 0 &&
110		    DIP(dp, di_size) < sblock.fs_maxsymlinklen &&
111		    DIP(dp, di_blocks) == 0) {
112			char *p = sblock.fs_magic == FS_UFS1_MAGIC ?
113			    (char *)dp->dp1.di_shortlink :
114			    (char *)dp->dp2.di_shortlink;
115			printf(" to `%.*s'\n", (int)DIP(dp, di_size), p);
116		} else
117			putchar('\n');
118		break;
119	case IFSOCK:
120		puts("socket");
121		break;
122	case IFIFO:
123		puts("fifo");
124		break;
125	}
126
127	printf("I=%llu MODE=%o SIZE=%llu", (unsigned long long)inum,
128	    DIP(dp, di_mode), DIP(dp, di_size));
129	t = DIP(dp, di_mtime);
130	p = ctime(&t);
131	printf("\n\tMTIME=%15.15s %4.4s [%d nsec]", &p[4], &p[20],
132	    DIP(dp, di_mtimensec));
133	t = DIP(dp, di_ctime);
134	p = ctime(&t);
135	printf("\n\tCTIME=%15.15s %4.4s [%d nsec]", &p[4], &p[20],
136	    DIP(dp, di_ctimensec));
137	t = DIP(dp, di_atime);
138	p = ctime(&t);
139	printf("\n\tATIME=%15.15s %4.4s [%d nsec]\n", &p[4], &p[20],
140	    DIP(dp, di_atimensec));
141
142	if ((pw = getpwuid(DIP(dp, di_uid))))
143		printf("OWNER=%s ", pw->pw_name);
144	else
145		printf("OWNUID=%u ", DIP(dp, di_uid));
146	if ((grp = getgrgid(DIP(dp, di_gid))))
147		printf("GRP=%s ", grp->gr_name);
148	else
149		printf("GID=%u ", DIP(dp, di_gid));
150
151	printf("LINKCNT=%d FLAGS=%#x BLKCNT=%x GEN=%x\n", DIP(dp, di_nlink),
152	    DIP(dp, di_flags), (unsigned)DIP(dp, di_blocks), DIP(dp, di_gen));
153}
154
155int
156checkactive(void)
157{
158	if (!curinode) {
159		warnx("no current inode");
160		return 0;
161	}
162	return 1;
163}
164
165int
166checkactivedir(void)
167{
168	if (!curinode) {
169		warnx("no current inode");
170		return 0;
171	}
172	if ((DIP(curinode, di_mode) & IFMT) != IFDIR) {
173		warnx("inode %llu not a directory",
174		    (unsigned long long)curinum);
175		return 0;
176	}
177	return 1;
178}
179
180int
181printactive(void)
182{
183	if (!checkactive())
184		return 1;
185	switch (DIP(curinode, di_mode) & IFMT) {
186	case IFDIR:
187	case IFREG:
188	case IFBLK:
189	case IFCHR:
190	case IFLNK:
191	case IFSOCK:
192	case IFIFO:
193		printstat("current inode", curinum, curinode);
194		break;
195	case 0:
196		printf("current inode %llu: unallocated inode\n",
197		    (unsigned long long)curinum);
198		break;
199	default:
200		printf("current inode %llu: screwy itype 0%o (mode 0%o)?\n",
201		    (unsigned long long)curinum, DIP(curinode, di_mode) & IFMT,
202		    DIP(curinode, di_mode));
203		break;
204	}
205	return 0;
206}
207