|
|
1.1 root 1: /*
2: * Copyright (c) 1980 Regents of the University of California.
3: * All rights reserved. The Berkeley software License Agreement
4: * specifies the terms and conditions for redistribution.
5: */
6:
7: #ifndef lint
8: char copyright[] =
9: "@(#) Copyright (c) 1980 Regents of the University of California.\n\
10: All rights reserved.\n";
11: #endif not lint
12:
13: #ifndef lint
14: static char sccsid[] = "@(#)ncheck.c 5.7 (Berkeley) 5/2/88";
15: #endif not lint
16:
17: /*
18: * ncheck -- obtain file names from reading filesystem
19: */
20:
21: #define NB 500
22: #define MAXNINDIR (MAXBSIZE / sizeof (daddr_t))
23:
24: #include <sys/param.h>
25: #include <sys/inode.h>
26: #include <sys/fs.h>
27: #include <sys/dir.h>
28: #include <stdio.h>
29:
30: struct fs sblock;
31: struct dinode itab[MAXBSIZE/sizeof(struct dinode)];
32: struct dinode *gip;
33: struct ilist {
34: ino_t ino;
35: u_short mode;
36: short uid;
37: short gid;
38: } ilist[NB];
39: struct htab
40: {
41: ino_t h_ino;
42: ino_t h_pino;
43: char *h_name;
44: } *htab;
45: char *strngtab;
46: long hsize;
47: int strngloc;
48:
49: struct dirstuff {
50: int loc;
51: struct dinode *ip;
52: char dbuf[MAXBSIZE];
53: };
54:
55: int aflg;
56: int sflg;
57: int iflg; /* number of inodes being searched for */
58: int mflg;
59: int fi;
60: ino_t ino;
61: int nhent;
62: int nxfile;
63: long dev_bsize = 1;
64:
65: int nerror;
66: daddr_t bmap();
67: long atol();
68: struct htab *lookup();
69:
70: main(argc, argv)
71: int argc;
72: char *argv[];
73: {
74: register i;
75: long n;
76:
77: while (--argc) {
78: argv++;
79: if (**argv=='-')
80: switch ((*argv)[1]) {
81:
82: case 'a':
83: aflg++;
84: continue;
85:
86: case 'i':
87: for(iflg=0; iflg<NB; iflg++) {
88: n = atol(argv[1]);
89: if(n == 0)
90: break;
91: ilist[iflg].ino = n;
92: nxfile = iflg;
93: argv++;
94: argc--;
95: }
96: continue;
97:
98: case 'm':
99: mflg++;
100: continue;
101:
102: case 's':
103: sflg++;
104: continue;
105:
106: default:
107: fprintf(stderr, "ncheck: bad flag %c\n", (*argv)[1]);
108: nerror++;
109: }
110: check(*argv);
111: }
112: return(nerror);
113: }
114:
115: check(file)
116: char *file;
117: {
118: register int i, j, c;
119: int nfiles;
120:
121: fi = open(file, 0);
122: if(fi < 0) {
123: fprintf(stderr, "ncheck: cannot open %s\n", file);
124: nerror++;
125: return;
126: }
127: nhent = 0;
128: printf("%s:\n", file);
129: sync();
130: bread(SBOFF, (char *)&sblock, SBSIZE);
131: if (sblock.fs_magic != FS_MAGIC) {
132: printf("%s: not a file system\n", file);
133: nerror++;
134: return;
135: }
136: dev_bsize = sblock.fs_fsize / fsbtodb(&sblock, 1);
137: hsize = sblock.fs_ipg * sblock.fs_ncg - sblock.fs_cstotal.cs_nifree + 1;
138: htab = (struct htab *)malloc(hsize * sizeof(struct htab));
139: strngtab = (char *)malloc(30 * hsize);
140: if (htab == 0 || strngtab == 0) {
141: printf("not enough memory to allocate tables\n");
142: nerror++;
143: return;
144: }
145: ino = 0;
146: for (c = 0; c < sblock.fs_ncg; c++) {
147: for (i = 0;
148: i < sblock.fs_ipg / INOPF(&sblock);
149: i += sblock.fs_frag) {
150: bread(fsbtodb(&sblock, cgimin(&sblock, c) + i),
151: (char *)itab, sblock.fs_bsize);
152: for (j = 0; j < INOPB(&sblock); j++) {
153: if (itab[j].di_mode != 0)
154: pass1(&itab[j]);
155: ino++;
156: }
157: }
158: }
159: ilist[nxfile+1].ino = 0;
160: ino = 0;
161: for (c = 0; c < sblock.fs_ncg; c++) {
162: for (i = 0;
163: i < sblock.fs_ipg / INOPF(&sblock);
164: i += sblock.fs_frag) {
165: bread(fsbtodb(&sblock, cgimin(&sblock, c) + i),
166: (char *)itab, sblock.fs_bsize);
167: for (j = 0; j < INOPB(&sblock); j++) {
168: if (itab[j].di_mode != 0)
169: pass2(&itab[j]);
170: ino++;
171: }
172: }
173: }
174: ino = 0;
175: for (c = 0; c < sblock.fs_ncg; c++) {
176: for (i = 0;
177: i < sblock.fs_ipg / INOPF(&sblock);
178: i += sblock.fs_frag) {
179: bread(fsbtodb(&sblock, cgimin(&sblock, c) + i),
180: (char *)itab, sblock.fs_bsize);
181: for (j = 0; j < INOPB(&sblock); j++) {
182: if (itab[j].di_mode != 0)
183: pass3(&itab[j]);
184: ino++;
185: }
186: }
187: }
188: close(fi);
189: for (i = 0; i < hsize; i++)
190: htab[i].h_ino = 0;
191: for (i = iflg; i < NB; i++)
192: ilist[i].ino = 0;
193: nxfile = iflg;
194: }
195:
196: pass1(ip)
197: register struct dinode *ip;
198: {
199: int i;
200:
201: if (mflg)
202: for (i = 0; i < iflg; i++)
203: if (ino == ilist[i].ino) {
204: ilist[i].mode = ip->di_mode;
205: ilist[i].uid = ip->di_uid;
206: ilist[i].gid = ip->di_gid;
207: }
208: if ((ip->di_mode & IFMT) != IFDIR) {
209: if (sflg==0 || nxfile>=NB)
210: return;
211: if ((ip->di_mode&IFMT)==IFBLK || (ip->di_mode&IFMT)==IFCHR
212: || ip->di_mode&(ISUID|ISGID)) {
213: ilist[nxfile].ino = ino;
214: ilist[nxfile].mode = ip->di_mode;
215: ilist[nxfile].uid = ip->di_uid;
216: ilist[nxfile++].gid = ip->di_gid;
217: return;
218: }
219: }
220: lookup(ino, 1);
221: }
222:
223: pass2(ip)
224: register struct dinode *ip;
225: {
226: register struct direct *dp;
227: struct dirstuff dirp;
228: struct htab *hp;
229:
230: if((ip->di_mode&IFMT) != IFDIR)
231: return;
232: dirp.loc = 0;
233: dirp.ip = ip;
234: gip = ip;
235: for (dp = readdir(&dirp); dp != NULL; dp = readdir(&dirp)) {
236: if(dp->d_ino == 0)
237: continue;
238: hp = lookup(dp->d_ino, 0);
239: if(hp == 0)
240: continue;
241: if(dotname(dp))
242: continue;
243: hp->h_pino = ino;
244: hp->h_name = &strngtab[strngloc];
245: strngloc += strlen(dp->d_name) + 1;
246: strcpy(hp->h_name, dp->d_name);
247: }
248: }
249:
250: pass3(ip)
251: register struct dinode *ip;
252: {
253: register struct direct *dp;
254: struct dirstuff dirp;
255: int k;
256:
257: if((ip->di_mode&IFMT) != IFDIR)
258: return;
259: dirp.loc = 0;
260: dirp.ip = ip;
261: gip = ip;
262: for(dp = readdir(&dirp); dp != NULL; dp = readdir(&dirp)) {
263: if(aflg==0 && dotname(dp))
264: continue;
265: if(sflg == 0 && iflg == 0)
266: goto pr;
267: for(k = 0; ilist[k].ino != 0; k++)
268: if(ilist[k].ino == dp->d_ino)
269: break;
270: if (ilist[k].ino == 0)
271: continue;
272: if (mflg)
273: printf("mode %-6o uid %-5d gid %-5d ino ",
274: ilist[k].mode, ilist[k].uid, ilist[k].gid);
275: pr:
276: printf("%-5u\t", dp->d_ino);
277: pname(ino, 0);
278: printf("/%s", dp->d_name);
279: if (lookup(dp->d_ino, 0))
280: printf("/.");
281: printf("\n");
282: }
283: }
284:
285: /*
286: * get next entry in a directory.
287: */
288: struct direct *
289: readdir(dirp)
290: register struct dirstuff *dirp;
291: {
292: register struct direct *dp;
293: daddr_t lbn, d;
294:
295: for(;;) {
296: if (dirp->loc >= dirp->ip->di_size)
297: return NULL;
298: if (blkoff(&sblock, dirp->loc) == 0) {
299: lbn = lblkno(&sblock, dirp->loc);
300: d = bmap(lbn);
301: if(d == 0)
302: return NULL;
303: bread(fsbtodb(&sblock, d), dirp->dbuf,
304: dblksize(&sblock, dirp->ip, lbn));
305: }
306: dp = (struct direct *)
307: (dirp->dbuf + blkoff(&sblock, dirp->loc));
308: dirp->loc += dp->d_reclen;
309: if (dp->d_ino == 0)
310: continue;
311: return (dp);
312: }
313: }
314:
315: dotname(dp)
316: register struct direct *dp;
317: {
318:
319: if (dp->d_name[0]=='.')
320: if (dp->d_name[1]==0 ||
321: (dp->d_name[1]=='.' && dp->d_name[2]==0))
322: return(1);
323: return(0);
324: }
325:
326: pname(i, lev)
327: ino_t i;
328: int lev;
329: {
330: register struct htab *hp;
331:
332: if (i==ROOTINO)
333: return;
334: if ((hp = lookup(i, 0)) == 0) {
335: printf("???");
336: return;
337: }
338: if (lev > 10) {
339: printf("...");
340: return;
341: }
342: pname(hp->h_pino, ++lev);
343: printf("/%s", hp->h_name);
344: }
345:
346: struct htab *
347: lookup(i, ef)
348: ino_t i;
349: int ef;
350: {
351: register struct htab *hp;
352:
353: for (hp = &htab[i%hsize]; hp->h_ino;) {
354: if (hp->h_ino==i)
355: return(hp);
356: if (++hp >= &htab[hsize])
357: hp = htab;
358: }
359: if (ef==0)
360: return(0);
361: if (++nhent >= hsize) {
362: fprintf(stderr, "ncheck: hsize of %d is too small\n", hsize);
363: exit(1);
364: }
365: hp->h_ino = i;
366: return(hp);
367: }
368:
369: bread(bno, buf, cnt)
370: daddr_t bno;
371: char *buf;
372: int cnt;
373: {
374: register i;
375:
376: lseek(fi, bno * dev_bsize, 0);
377: if (read(fi, buf, cnt) != cnt) {
378: fprintf(stderr, "ncheck: read error %d\n", bno);
379: for(i=0; i < cnt; i++)
380: buf[i] = 0;
381: }
382: }
383:
384: /*
385: * Swiped from standalone sys.c.
386: */
387: #define NBUFS 4
388: char b[NBUFS][MAXBSIZE];
389: daddr_t blknos[NBUFS];
390:
391: daddr_t
392: bmap(bn)
393: register daddr_t bn;
394: {
395: register int j;
396: int i, sh;
397: daddr_t nb, *bap;
398:
399: if (bn < 0) {
400: fprintf(stderr, "ncheck: bn %d negative\n", bn);
401: return ((daddr_t)0);
402: }
403:
404: /*
405: * blocks 0..NDADDR are direct blocks
406: */
407: if(bn < NDADDR)
408: return(gip->di_db[bn]);
409:
410: /*
411: * addresses NIADDR have single and double indirect blocks.
412: * the first step is to determine how many levels of indirection.
413: */
414: sh = 1;
415: bn -= NDADDR;
416: for (j = NIADDR; j > 0; j--) {
417: sh *= NINDIR(&sblock);
418: if (bn < sh)
419: break;
420: bn -= sh;
421: }
422: if (j == 0) {
423: printf("ncheck: bn %ld ovf, ino %u\n", bn, ino);
424: return ((daddr_t)0);
425: }
426:
427: /*
428: * fetch the first indirect block address from the inode
429: */
430: nb = gip->di_ib[NIADDR - j];
431: if (nb == 0) {
432: printf("ncheck: bn %ld void1, ino %u\n", bn, ino);
433: return ((daddr_t)0);
434: }
435:
436: /*
437: * fetch through the indirect blocks
438: */
439: for (; j <= NIADDR; j++) {
440: if (blknos[j] != nb) {
441: bread(fsbtodb(&sblock, nb), b[j], sblock.fs_bsize);
442: blknos[j] = nb;
443: }
444: bap = (daddr_t *)b[j];
445: sh /= NINDIR(&sblock);
446: i = (bn / sh) % NINDIR(&sblock);
447: nb = bap[i];
448: if(nb == 0) {
449: printf("ncheck: bn %ld void2, ino %u\n", bn, ino);
450: return ((daddr_t)0);
451: }
452: }
453: return (nb);
454: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.