|
|
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.4 (Berkeley) 1/9/86";
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[MAXIPG];
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:
64: int nerror;
65: daddr_t bmap();
66: long atol();
67: struct htab *lookup();
68:
69: main(argc, argv)
70: int argc;
71: char *argv[];
72: {
73: register i;
74: long n;
75:
76: while (--argc) {
77: argv++;
78: if (**argv=='-')
79: switch ((*argv)[1]) {
80:
81: case 'a':
82: aflg++;
83: continue;
84:
85: case 'i':
86: for(iflg=0; iflg<NB; iflg++) {
87: n = atol(argv[1]);
88: if(n == 0)
89: break;
90: ilist[iflg].ino = n;
91: nxfile = iflg;
92: argv++;
93: argc--;
94: }
95: continue;
96:
97: case 'm':
98: mflg++;
99: continue;
100:
101: case 's':
102: sflg++;
103: continue;
104:
105: default:
106: fprintf(stderr, "ncheck: bad flag %c\n", (*argv)[1]);
107: nerror++;
108: }
109: check(*argv);
110: }
111: return(nerror);
112: }
113:
114: check(file)
115: char *file;
116: {
117: register int i, j, c;
118: int nfiles;
119:
120: fi = open(file, 0);
121: if(fi < 0) {
122: fprintf(stderr, "ncheck: cannot open %s\n", file);
123: nerror++;
124: return;
125: }
126: nhent = 0;
127: printf("%s:\n", file);
128: sync();
129: bread(SBLOCK, (char *)&sblock, SBSIZE);
130: if (sblock.fs_magic != FS_MAGIC) {
131: printf("%s: not a file system\n", file);
132: nerror++;
133: return;
134: }
135: hsize = sblock.fs_ipg * sblock.fs_ncg - sblock.fs_cstotal.cs_nifree + 1;
136: htab = (struct htab *)malloc(hsize * sizeof(struct htab));
137: strngtab = (char *)malloc(30 * hsize);
138: if (htab == 0 || strngtab == 0) {
139: printf("not enough memory to allocate tables\n");
140: nerror++;
141: return;
142: }
143: ino = 0;
144: for (c = 0; c < sblock.fs_ncg; c++) {
145: bread(fsbtodb(&sblock, cgimin(&sblock, c)), (char *)itab,
146: sblock.fs_ipg * sizeof (struct dinode));
147: for(j = 0; j < sblock.fs_ipg; j++) {
148: if (itab[j].di_mode != 0)
149: pass1(&itab[j]);
150: ino++;
151: }
152: }
153: ilist[nxfile+1].ino = 0;
154: ino = 0;
155: for (c = 0; c < sblock.fs_ncg; c++) {
156: bread(fsbtodb(&sblock, cgimin(&sblock, c)), (char *)itab,
157: sblock.fs_ipg * sizeof (struct dinode));
158: for(j = 0; j < sblock.fs_ipg; j++) {
159: if (itab[j].di_mode != 0)
160: pass2(&itab[j]);
161: ino++;
162: }
163: }
164: ino = 0;
165: for (c = 0; c < sblock.fs_ncg; c++) {
166: bread(fsbtodb(&sblock, cgimin(&sblock, c)), (char *)itab,
167: sblock.fs_ipg * sizeof (struct dinode));
168: for(j = 0; j < sblock.fs_ipg; j++) {
169: if (itab[j].di_mode != 0)
170: pass3(&itab[j]);
171: ino++;
172: }
173: }
174: close(fi);
175: for (i = 0; i < hsize; i++)
176: htab[i].h_ino = 0;
177: for (i = iflg; i < NB; i++)
178: ilist[i].ino = 0;
179: nxfile = iflg;
180: }
181:
182: pass1(ip)
183: register struct dinode *ip;
184: {
185: int i;
186:
187: if (mflg)
188: for (i = 0; i < iflg; i++)
189: if (ino == ilist[i].ino) {
190: ilist[i].mode = ip->di_mode;
191: ilist[i].uid = ip->di_uid;
192: ilist[i].gid = ip->di_gid;
193: }
194: if ((ip->di_mode & IFMT) != IFDIR) {
195: if (sflg==0 || nxfile>=NB)
196: return;
197: if ((ip->di_mode&IFMT)==IFBLK || (ip->di_mode&IFMT)==IFCHR
198: || ip->di_mode&(ISUID|ISGID)) {
199: ilist[nxfile].ino = ino;
200: ilist[nxfile].mode = ip->di_mode;
201: ilist[nxfile].uid = ip->di_uid;
202: ilist[nxfile++].gid = ip->di_gid;
203: return;
204: }
205: }
206: lookup(ino, 1);
207: }
208:
209: pass2(ip)
210: register struct dinode *ip;
211: {
212: register struct direct *dp;
213: struct dirstuff dirp;
214: struct htab *hp;
215:
216: if((ip->di_mode&IFMT) != IFDIR)
217: return;
218: dirp.loc = 0;
219: dirp.ip = ip;
220: gip = ip;
221: for (dp = readdir(&dirp); dp != NULL; dp = readdir(&dirp)) {
222: if(dp->d_ino == 0)
223: continue;
224: hp = lookup(dp->d_ino, 0);
225: if(hp == 0)
226: continue;
227: if(dotname(dp))
228: continue;
229: hp->h_pino = ino;
230: hp->h_name = &strngtab[strngloc];
231: strngloc += strlen(dp->d_name) + 1;
232: strcpy(hp->h_name, dp->d_name);
233: }
234: }
235:
236: pass3(ip)
237: register struct dinode *ip;
238: {
239: register struct direct *dp;
240: struct dirstuff dirp;
241: int k;
242:
243: if((ip->di_mode&IFMT) != IFDIR)
244: return;
245: dirp.loc = 0;
246: dirp.ip = ip;
247: gip = ip;
248: for(dp = readdir(&dirp); dp != NULL; dp = readdir(&dirp)) {
249: if(aflg==0 && dotname(dp))
250: continue;
251: if(sflg == 0 && iflg == 0)
252: goto pr;
253: for(k = 0; ilist[k].ino != 0; k++)
254: if(ilist[k].ino == dp->d_ino)
255: break;
256: if (ilist[k].ino == 0)
257: continue;
258: if (mflg)
259: printf("mode %-6o uid %-5d gid %-5d ino ",
260: ilist[k].mode, ilist[k].uid, ilist[k].gid);
261: pr:
262: printf("%-5u\t", dp->d_ino);
263: pname(ino, 0);
264: printf("/%s", dp->d_name);
265: if (lookup(dp->d_ino, 0))
266: printf("/.");
267: printf("\n");
268: }
269: }
270:
271: /*
272: * get next entry in a directory.
273: */
274: struct direct *
275: readdir(dirp)
276: register struct dirstuff *dirp;
277: {
278: register struct direct *dp;
279: daddr_t lbn, d;
280:
281: for(;;) {
282: if (dirp->loc >= dirp->ip->di_size)
283: return NULL;
284: if (blkoff(&sblock, dirp->loc) == 0) {
285: lbn = lblkno(&sblock, dirp->loc);
286: d = bmap(lbn);
287: if(d == 0)
288: return NULL;
289: bread(fsbtodb(&sblock, d), dirp->dbuf,
290: dblksize(&sblock, dirp->ip, lbn));
291: }
292: dp = (struct direct *)
293: (dirp->dbuf + blkoff(&sblock, dirp->loc));
294: dirp->loc += dp->d_reclen;
295: if (dp->d_ino == 0)
296: continue;
297: return (dp);
298: }
299: }
300:
301: dotname(dp)
302: register struct direct *dp;
303: {
304:
305: if (dp->d_name[0]=='.')
306: if (dp->d_name[1]==0 ||
307: (dp->d_name[1]=='.' && dp->d_name[2]==0))
308: return(1);
309: return(0);
310: }
311:
312: pname(i, lev)
313: ino_t i;
314: int lev;
315: {
316: register struct htab *hp;
317:
318: if (i==ROOTINO)
319: return;
320: if ((hp = lookup(i, 0)) == 0) {
321: printf("???");
322: return;
323: }
324: if (lev > 10) {
325: printf("...");
326: return;
327: }
328: pname(hp->h_pino, ++lev);
329: printf("/%s", hp->h_name);
330: }
331:
332: struct htab *
333: lookup(i, ef)
334: ino_t i;
335: int ef;
336: {
337: register struct htab *hp;
338:
339: for (hp = &htab[i%hsize]; hp->h_ino;) {
340: if (hp->h_ino==i)
341: return(hp);
342: if (++hp >= &htab[hsize])
343: hp = htab;
344: }
345: if (ef==0)
346: return(0);
347: if (++nhent >= hsize) {
348: fprintf(stderr, "ncheck: hsize of %d is too small\n", hsize);
349: exit(1);
350: }
351: hp->h_ino = i;
352: return(hp);
353: }
354:
355: bread(bno, buf, cnt)
356: daddr_t bno;
357: char *buf;
358: int cnt;
359: {
360: register i;
361:
362: lseek(fi, bno * DEV_BSIZE, 0);
363: if (read(fi, buf, cnt) != cnt) {
364: fprintf(stderr, "ncheck: read error %d\n", bno);
365: for(i=0; i < cnt; i++)
366: buf[i] = 0;
367: }
368: }
369:
370: daddr_t
371: bmap(i)
372: int i;
373: {
374: daddr_t ibuf[MAXNINDIR];
375:
376: if(i < NDADDR)
377: return(gip->di_db[i]);
378: i -= NDADDR;
379: if(i > NINDIR(&sblock)) {
380: fprintf(stderr, "ncheck: %u - huge directory\n", ino);
381: return((daddr_t)0);
382: }
383: bread(fsbtodb(&sblock, gip->di_ib[i]), (char *)ibuf, sizeof(ibuf));
384: return(ibuf[i]);
385: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.