1 /* $OpenBSD: fsdbutil.c,v 1.21 2024/05/09 08:35:40 florian 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
52 char **
crack(char * line,int * argc)53 crack(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
71 int
argcount(struct cmdtable * cmdp,int argc,char * argv[])72 argcount(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
83 void
printstat(const char * cp,ino_t inum,union dinode * dp)84 printstat(const char *cp, ino_t inum, union dinode *dp)
85 {
86 const char *name;
87 time_t t;
88 char *p;
89
90 printf("%s: ", cp);
91 switch (DIP(dp, di_mode) & IFMT) {
92 case IFDIR:
93 puts("directory");
94 break;
95 case IFREG:
96 puts("regular file");
97 break;
98 case IFBLK:
99 printf("block special (%u,%u)",
100 (int)major(DIP(dp, di_rdev)), (int)minor(DIP(dp, di_rdev)));
101 break;
102 case IFCHR:
103 printf("character special (%u,%u)",
104 (int)major(DIP(dp, di_rdev)), (int)minor(DIP(dp, di_rdev)));
105 break;
106 case IFLNK:
107 fputs("symlink",stdout);
108 if (DIP(dp, di_size) > 0 &&
109 DIP(dp, di_size) < sblock.fs_maxsymlinklen &&
110 DIP(dp, di_blocks) == 0) {
111 char *p = sblock.fs_magic == FS_UFS1_MAGIC ?
112 (char *)dp->dp1.di_shortlink :
113 (char *)dp->dp2.di_shortlink;
114 printf(" to `%.*s'\n", (int)DIP(dp, di_size), p);
115 } else
116 putchar('\n');
117 break;
118 case IFSOCK:
119 puts("socket");
120 break;
121 case IFIFO:
122 puts("fifo");
123 break;
124 }
125
126 printf("I=%llu MODE=%o SIZE=%llu", (unsigned long long)inum,
127 DIP(dp, di_mode), DIP(dp, di_size));
128 t = DIP(dp, di_mtime);
129 p = ctime(&t);
130 if (p)
131 printf("\n\tMTIME=%15.15s %4.4s [%d nsec]", &p[4], &p[20],
132 DIP(dp, di_mtimensec));
133 else
134 printf("\n\tMTIME=%lld [%d nsec]", t, DIP(dp, di_mtimensec));
135 t = DIP(dp, di_ctime);
136 p = ctime(&t);
137 if (p)
138 printf("\n\tCTIME=%15.15s %4.4s [%d nsec]", &p[4], &p[20],
139 DIP(dp, di_ctimensec));
140 else
141 printf("\n\tCTIME=%lld [%d nsec]", t, DIP(dp, di_ctimensec));
142 t = DIP(dp, di_atime);
143 p = ctime(&t);
144 if (p)
145 printf("\n\tATIME=%15.15s %4.4s [%d nsec]\n", &p[4], &p[20],
146 DIP(dp, di_atimensec));
147 else
148 printf("\n\tATIME=%lld [%d nsec]\n", t, DIP(dp, di_atimensec));
149 if ((name = user_from_uid(DIP(dp, di_uid), 1)) != NULL)
150 printf("OWNER=%s ", name);
151 else
152 printf("OWNUID=%u ", DIP(dp, di_uid));
153 if ((name = group_from_gid(DIP(dp, di_gid), 1)) != NULL)
154 printf("GRP=%s ", name);
155 else
156 printf("GID=%u ", DIP(dp, di_gid));
157
158 printf("LINKCNT=%d FLAGS=%#x BLKCNT=%x GEN=%x\n", DIP(dp, di_nlink),
159 DIP(dp, di_flags), (unsigned)DIP(dp, di_blocks), DIP(dp, di_gen));
160 }
161
162 int
checkactive(void)163 checkactive(void)
164 {
165 if (!curinode) {
166 warnx("no current inode");
167 return 0;
168 }
169 return 1;
170 }
171
172 int
checkactivedir(void)173 checkactivedir(void)
174 {
175 if (!curinode) {
176 warnx("no current inode");
177 return 0;
178 }
179 if ((DIP(curinode, di_mode) & IFMT) != IFDIR) {
180 warnx("inode %llu not a directory",
181 (unsigned long long)curinum);
182 return 0;
183 }
184 return 1;
185 }
186
187 int
printactive(void)188 printactive(void)
189 {
190 if (!checkactive())
191 return 1;
192 switch (DIP(curinode, di_mode) & IFMT) {
193 case IFDIR:
194 case IFREG:
195 case IFBLK:
196 case IFCHR:
197 case IFLNK:
198 case IFSOCK:
199 case IFIFO:
200 printstat("current inode", curinum, curinode);
201 break;
202 case 0:
203 printf("current inode %llu: unallocated inode\n",
204 (unsigned long long)curinum);
205 break;
206 default:
207 printf("current inode %llu: screwy itype 0%o (mode 0%o)?\n",
208 (unsigned long long)curinum, DIP(curinode, di_mode) & IFMT,
209 DIP(curinode, di_mode));
210 break;
211 }
212 return 0;
213 }
214