date and time created 83/02/18 00:41:40 by mckusick
[unix-history] / usr / src / sbin / ncheck / ncheck.c
CommitLineData
15e0f143 1static char *sccsid = "@(#)ncheck.c 2.2 (Berkeley) %G%";
d9c5783d
KM
2/*
3 * ncheck -- obtain file names from reading filesystem
4 */
5
b6407c9d
KM
6#define NB 500
7#define HSIZE 2503
c312eebd 8#define MAXNINDIR (MAXBSIZE / sizeof (daddr_t))
d9c5783d 9
61b11ef4
KM
10#ifndef SIMFS
11#include <sys/param.h>
12#include <sys/inode.h>
13#include <sys/fs.h>
14#else
d9c5783d
KM
15#include "../h/param.h"
16#include "../h/inode.h"
d9c5783d 17#include "../h/fs.h"
61b11ef4 18#endif
5086d197 19#include <stdio.h>
15e0f143 20#include <dir.h>
d9c5783d
KM
21
22struct fs sblock;
23struct dinode itab[MAXIPG];
56d45dcd 24struct dinode *gip;
61b11ef4
KM
25struct ilist {
26 ino_t ino;
27 u_short mode;
28 short uid;
29 short gid;
30} ilist[NB];
d9c5783d
KM
31struct htab
32{
33 ino_t h_ino;
34 ino_t h_pino;
5086d197 35 char *h_name;
d9c5783d 36} htab[HSIZE];
5086d197
KM
37char strngtab[30 * HSIZE];
38int strngloc;
39
40struct dirstuff {
41 int loc;
42 struct dinode *ip;
43 char dbuf[MAXBSIZE];
44};
d9c5783d
KM
45
46int aflg;
47int sflg;
61b11ef4
KM
48int iflg; /* number of inodes being searched for */
49int mflg;
d9c5783d
KM
50int fi;
51ino_t ino;
52int nhent;
53int nxfile;
54
55int nerror;
56daddr_t bmap();
57long atol();
58struct htab *lookup();
59
60main(argc, argv)
20380c05
KM
61 int argc;
62 char *argv[];
d9c5783d
KM
63{
64 register i;
65 long n;
66
67 while (--argc) {
68 argv++;
69 if (**argv=='-')
70 switch ((*argv)[1]) {
71
72 case 'a':
73 aflg++;
74 continue;
75
76 case 'i':
61b11ef4 77 for(iflg=0; iflg<NB; iflg++) {
d9c5783d
KM
78 n = atol(argv[1]);
79 if(n == 0)
80 break;
61b11ef4
KM
81 ilist[iflg].ino = n;
82 nxfile = iflg;
d9c5783d
KM
83 argv++;
84 argc--;
85 }
86 continue;
87
61b11ef4
KM
88 case 'm':
89 mflg++;
90 continue;
91
d9c5783d
KM
92 case 's':
93 sflg++;
94 continue;
95
96 default:
97 fprintf(stderr, "ncheck: bad flag %c\n", (*argv)[1]);
98 nerror++;
99 }
100 check(*argv);
101 }
102 return(nerror);
103}
104
105check(file)
20380c05 106 char *file;
d9c5783d 107{
20380c05
KM
108 register int i, j, c;
109 int nfiles;
d9c5783d
KM
110
111 fi = open(file, 0);
112 if(fi < 0) {
113 fprintf(stderr, "ncheck: cannot open %s\n", file);
114 nerror++;
115 return;
116 }
117 nhent = 0;
118 printf("%s:\n", file);
119 sync();
c312eebd 120 bread(SBLOCK, (char *)&sblock, SBSIZE);
20380c05
KM
121 if (sblock.fs_magic != FS_MAGIC) {
122 printf("%s: not a file system\n", file);
123 nerror++;
124 return;
125 }
d9c5783d
KM
126 ino = 0;
127 for (c = 0; c < sblock.fs_ncg; c++) {
6994bf5d 128 bread(fsbtodb(&sblock, cgimin(&sblock, c)), (char *)itab,
d9c5783d 129 sblock.fs_ipg * sizeof (struct dinode));
61b11ef4
KM
130 for(j = 0; j < sblock.fs_ipg; j++) {
131 if (itab[j].di_mode != 0)
132 pass1(&itab[j]);
d9c5783d
KM
133 ino++;
134 }
135 }
61b11ef4 136 ilist[nxfile+1].ino = 0;
d9c5783d
KM
137 ino = 0;
138 for (c = 0; c < sblock.fs_ncg; c++) {
6994bf5d 139 bread(fsbtodb(&sblock, cgimin(&sblock, c)), (char *)itab,
d9c5783d 140 sblock.fs_ipg * sizeof (struct dinode));
61b11ef4
KM
141 for(j = 0; j < sblock.fs_ipg; j++) {
142 if (itab[j].di_mode != 0)
143 pass2(&itab[j]);
d9c5783d
KM
144 ino++;
145 }
146 }
147 ino = 0;
148 for (c = 0; c < sblock.fs_ncg; c++) {
6994bf5d 149 bread(fsbtodb(&sblock, cgimin(&sblock, c)), (char *)itab,
d9c5783d 150 sblock.fs_ipg * sizeof (struct dinode));
61b11ef4
KM
151 for(j = 0; j < sblock.fs_ipg; j++) {
152 if (itab[j].di_mode != 0)
153 pass3(&itab[j]);
d9c5783d
KM
154 ino++;
155 }
156 }
61b11ef4
KM
157 close(fi);
158 for (i = 0; i < HSIZE; i++)
159 htab[i].h_ino = 0;
160 for (i = iflg; i < NB; i++)
161 ilist[i].ino = 0;
162 nxfile = iflg;
d9c5783d
KM
163}
164
165pass1(ip)
20380c05 166 register struct dinode *ip;
d9c5783d 167{
61b11ef4
KM
168 int i;
169
170 if (mflg)
171 for (i = 0; i < iflg; i++)
172 if (ino == ilist[i].ino) {
173 ilist[i].mode = ip->di_mode;
174 ilist[i].uid = ip->di_uid;
175 ilist[i].gid = ip->di_gid;
176 }
177 if ((ip->di_mode & IFMT) != IFDIR) {
d9c5783d
KM
178 if (sflg==0 || nxfile>=NB)
179 return;
180 if ((ip->di_mode&IFMT)==IFBLK || (ip->di_mode&IFMT)==IFCHR
61b11ef4
KM
181 || ip->di_mode&(ISUID|ISGID)) {
182 ilist[nxfile].ino = ino;
183 ilist[nxfile].mode = ip->di_mode;
184 ilist[nxfile].uid = ip->di_uid;
185 ilist[nxfile++].gid = ip->di_gid;
d9c5783d 186 return;
61b11ef4 187 }
d9c5783d
KM
188 }
189 lookup(ino, 1);
190}
191
192pass2(ip)
20380c05 193 register struct dinode *ip;
d9c5783d 194{
5086d197
KM
195 register struct direct *dp;
196 struct dirstuff dirp;
d9c5783d 197 struct htab *hp;
d9c5783d
KM
198
199 if((ip->di_mode&IFMT) != IFDIR)
200 return;
5086d197
KM
201 dirp.loc = 0;
202 dirp.ip = ip;
56d45dcd 203 gip = ip;
5086d197
KM
204 for (dp = readdir(&dirp); dp != NULL; dp = readdir(&dirp)) {
205 if(dp->d_ino == 0)
206 continue;
207 hp = lookup(dp->d_ino, 0);
208 if(hp == 0)
209 continue;
210 if(dotname(dp))
211 continue;
212 hp->h_pino = ino;
213 hp->h_name = &strngtab[strngloc];
214 strngloc += strlen(dp->d_name) + 1;
215 strcpy(hp->h_name, dp->d_name);
d9c5783d
KM
216 }
217}
218
219pass3(ip)
20380c05 220 register struct dinode *ip;
d9c5783d 221{
5086d197
KM
222 register struct direct *dp;
223 struct dirstuff dirp;
d9c5783d 224 int k;
d9c5783d
KM
225
226 if((ip->di_mode&IFMT) != IFDIR)
227 return;
5086d197
KM
228 dirp.loc = 0;
229 dirp.ip = ip;
56d45dcd 230 gip = ip;
5086d197 231 for(dp = readdir(&dirp); dp != NULL; dp = readdir(&dirp)) {
5086d197
KM
232 if(aflg==0 && dotname(dp))
233 continue;
61b11ef4 234 if(sflg == 0 && iflg == 0)
5086d197 235 goto pr;
61b11ef4
KM
236 for(k = 0; ilist[k].ino != 0; k++)
237 if(ilist[k].ino == dp->d_ino)
238 break;
239 if (ilist[k].ino == 0)
240 continue;
241 if (mflg)
242 printf("mode %-6o uid %-5d gid %-5d ino ",
243 ilist[k].mode, ilist[k].uid, ilist[k].gid);
5086d197 244 pr:
61b11ef4 245 printf("%-5u\t", dp->d_ino);
5086d197
KM
246 pname(ino, 0);
247 printf("/%s", dp->d_name);
248 if (lookup(dp->d_ino, 0))
249 printf("/.");
250 printf("\n");
251 }
252}
253
254/*
255 * get next entry in a directory.
256 */
257struct direct *
258readdir(dirp)
259 register struct dirstuff *dirp;
260{
261 register struct direct *dp;
262 daddr_t lbn, d;
263
264 for(;;) {
265 if (dirp->loc >= dirp->ip->di_size)
266 return NULL;
3352e84a 267 if ((lbn = lblkno(&sblock, dirp->loc)) == 0) {
5086d197
KM
268 d = bmap(lbn);
269 if(d == 0)
270 return NULL;
271 bread(fsbtodb(&sblock, d), dirp->dbuf,
272 dblksize(&sblock, dirp->ip, lbn));
d9c5783d 273 }
5086d197 274 dp = (struct direct *)
3352e84a 275 (dirp->dbuf + blkoff(&sblock, dirp->loc));
5086d197
KM
276 dirp->loc += dp->d_reclen;
277 if (dp->d_ino == 0)
278 continue;
279 return (dp);
d9c5783d
KM
280 }
281}
282
283dotname(dp)
20380c05 284 register struct direct *dp;
d9c5783d
KM
285{
286
287 if (dp->d_name[0]=='.')
5086d197
KM
288 if (dp->d_name[1]==0 ||
289 (dp->d_name[1]=='.' && dp->d_name[2]==0))
d9c5783d
KM
290 return(1);
291 return(0);
292}
293
294pname(i, lev)
20380c05
KM
295 ino_t i;
296 int lev;
d9c5783d
KM
297{
298 register struct htab *hp;
299
300 if (i==ROOTINO)
301 return;
302 if ((hp = lookup(i, 0)) == 0) {
303 printf("???");
304 return;
305 }
306 if (lev > 10) {
307 printf("...");
308 return;
309 }
310 pname(hp->h_pino, ++lev);
5086d197 311 printf("/%s", hp->h_name);
d9c5783d
KM
312}
313
314struct htab *
315lookup(i, ef)
20380c05
KM
316 ino_t i;
317 int ef;
d9c5783d
KM
318{
319 register struct htab *hp;
320
321 for (hp = &htab[i%HSIZE]; hp->h_ino;) {
322 if (hp->h_ino==i)
323 return(hp);
324 if (++hp >= &htab[HSIZE])
325 hp = htab;
326 }
327 if (ef==0)
328 return(0);
329 if (++nhent >= HSIZE) {
330 fprintf(stderr, "ncheck: out of core-- increase HSIZE\n");
331 exit(1);
332 }
333 hp->h_ino = i;
334 return(hp);
335}
336
337bread(bno, buf, cnt)
20380c05
KM
338 daddr_t bno;
339 char *buf;
340 int cnt;
d9c5783d
KM
341{
342 register i;
343
b6407c9d 344 lseek(fi, bno * DEV_BSIZE, 0);
d9c5783d
KM
345 if (read(fi, buf, cnt) != cnt) {
346 fprintf(stderr, "ncheck: read error %d\n", bno);
b6407c9d 347 for(i=0; i < cnt; i++)
d9c5783d
KM
348 buf[i] = 0;
349 }
350}
351
352daddr_t
353bmap(i)
20380c05 354 int i;
d9c5783d 355{
b6407c9d 356 daddr_t ibuf[MAXNINDIR];
d9c5783d 357
56d45dcd
KM
358 if(i < NDADDR)
359 return(gip->di_db[i]);
360 i -= NDADDR;
b6407c9d 361 if(i > NINDIR(&sblock)) {
d9c5783d
KM
362 fprintf(stderr, "ncheck: %u - huge directory\n", ino);
363 return((daddr_t)0);
364 }
b6407c9d 365 bread(fsbtodb(&sblock, gip->di_ib[i]), (char *)ibuf, sizeof(ibuf));
d9c5783d
KM
366 return(ibuf[i]);
367}