|
|
1.1 root 1: static char *sccsid = "@(#)ncheck.c 4.1 (Berkeley) 10/1/80";
2: /*
3: * ncheck -- obtain file names from reading filesystem
4: */
5:
6: #define NI 4
7: #define NB 1000
8: #define HSIZE 8209
9:
10: #include <stdio.h>
11: #include <sys/param.h>
12: #include <sys/inode.h>
13: #include <sys/ino.h>
14: #include <sys/dir.h>
15: #include <sys/filsys.h>
16: #include <sys/fblk.h>
17: #include <sys/stat.h>
18:
19: #define BITFSBIT 64 /* should be in param.h */
20: #define BIGINOPB INOPB(BITFSBIT)
21: #define BIGBSIZE BSIZE(BITFSBIT)
22: #define BIGNINDIR NINDIR(BITFSBIT)
23: #define BIGNDIR (BIGBSIZE/sizeof(struct direct))
24:
25: #define NDIR(dev) (BSIZE(dev)/sizeof(struct direct))
26:
27: struct filsys sblock;
28: struct stat status;
29: #define dev status.st_rdev
30: struct dinode itab[BIGINOPB*NI];
31: daddr_t iaddr[NADDR];
32: ino_t ilist[NB];
33: unsigned short imodes[NB];
34: struct htab
35: {
36: ino_t h_ino;
37: ino_t h_pino;
38: char h_name[DIRSIZ];
39: } htab[HSIZE];
40:
41: int aflg;
42: int sflg;
43: int fi;
44: ino_t ino;
45: int nhent;
46: int nxfile;
47: int bigflag;
48:
49: int nerror;
50: daddr_t bmap();
51: long atol();
52: struct htab *lookup();
53:
54: main(argc, argv)
55: char *argv[];
56: {
57: register i;
58: long n;
59:
60: while (--argc) {
61: argv++;
62: if (**argv=='-')
63: switch ((*argv)[1]) {
64:
65: case 'a':
66: aflg++;
67: continue;
68:
69: case 'i':
70: for(i=0; i<NB; i++) {
71: n = atol(argv[1]);
72: if(n == 0)
73: break;
74: ilist[i] = n;
75: nxfile = i;
76: argv++;
77: argc--;
78: }
79: continue;
80:
81: case 's':
82: sflg++;
83: continue;
84:
85: case 'B':
86: bigflag = BITFSBIT;
87: continue;
88:
89: default:
90: fprintf(stderr, "ncheck: bad flag %c\n", (*argv)[1]);
91: nerror++;
92: }
93: check(*argv);
94: }
95: return(nerror);
96: }
97:
98: check(file)
99: char *file;
100: {
101: register i, j;
102: ino_t mino;
103:
104: fi = open(file, 0);
105: if(fi < 0) {
106: fprintf(stderr, "ncheck: cannot open %s\n", file);
107: nerror++;
108: return;
109: }
110: if (fstat(fi, &status) < 0) {
111: fprintf(stderr, "ncheck: cannot stat %s\n", file);
112: nerror++;
113: close(fi);
114: return;
115: }
116: if ((status.st_mode & S_IFMT) == S_IFREG)
117: dev = makedev(0, bigflag);
118: nhent = 0;
119: printf("%s:\n", file);
120: sync();
121: bread((daddr_t)1, (char *)&sblock, BSIZE(dev));
122: mino = (sblock.s_isize-2) * INOPB(dev);
123: ino = 0;
124: for(i=2;; i+=NI) {
125: if(ino >= mino)
126: break;
127: bread((daddr_t)i, (char *)itab, BSIZE(dev)*NI);
128: for(j=0; j<INOPB(dev)*NI; j++) {
129: if(ino >= mino)
130: break;
131: ino++;
132: pass1(&itab[j]);
133: }
134: }
135: ilist[nxfile+1] = 0;
136: ino = 0;
137: for(i=2;; i+=NI) {
138: if(ino >= mino)
139: break;
140: bread((daddr_t)i, (char *)itab, BSIZE(dev)*NI);
141: for(j=0; j<INOPB(dev)*NI; j++) {
142: if(ino >= mino)
143: break;
144: ino++;
145: pass2(&itab[j]);
146: }
147: }
148: ino = 0;
149: for(i=2;; i+=NI) {
150: if(ino >= mino)
151: break;
152: bread((daddr_t)i, (char *)itab, BSIZE(dev)*NI);
153: for(j=0; j<INOPB(dev)*NI; j++) {
154: if(ino >= mino)
155: break;
156: ino++;
157: pass3(&itab[j]);
158: }
159: }
160: }
161:
162: pass1(ip)
163: register struct dinode *ip;
164: {
165: register struct htab * hp;
166:
167: if((ip->di_mode & IFMT) != IFDIR) {
168: if (sflg==0 || nxfile>=NB)
169: return;
170: if ((ip->di_mode & IFMT) == IFBLK || (ip->di_mode & IFMT) ==
171: IFCHR || ip->di_mode & (ISUID | ISGID))
172: {
173: ilist[nxfile] = ino;
174: imodes[nxfile++] = ip->di_mode;
175: }
176: return;
177: }
178: lookup(ino, 1);
179: }
180:
181: pass2(ip)
182: register struct dinode *ip;
183: {
184: struct direct dbuf[BIGNDIR];
185: long doff;
186: struct direct *dp;
187: register i, j;
188: int k;
189: struct htab *hp;
190: daddr_t d;
191: ino_t kno;
192:
193: if((ip->di_mode&IFMT) != IFDIR)
194: return;
195: l3tol(iaddr, ip->di_addr, NADDR);
196: doff = 0;
197: for(i=0;; i++) {
198: if(doff >= ip->di_size)
199: break;
200: d = bmap(i);
201: if(d == 0)
202: break;
203: bread(d, (char *)dbuf, BSIZE(dev));
204: for(j=0; j<NDIR(dev); j++) {
205: if(doff >= ip->di_size)
206: break;
207: doff += sizeof(struct direct);
208: dp = dbuf+j;
209: kno = dp->d_ino;
210: if(kno == 0)
211: continue;
212: hp = lookup(kno, 0);
213: if(hp == 0)
214: continue;
215: if(dotname(dp))
216: continue;
217: hp->h_pino = ino;
218: for(k=0; k<DIRSIZ; k++)
219: hp->h_name[k] = dp->d_name[k];
220: }
221: }
222: }
223:
224: pass3(ip)
225: register struct dinode *ip;
226: {
227: struct direct dbuf[BIGNDIR];
228: long doff;
229: register struct direct *dp;
230: register i, j;
231: int k;
232: daddr_t d;
233: ino_t kno;
234: struct htab * hp;
235:
236: if((ip->di_mode&IFMT) != IFDIR)
237: return;
238: l3tol(iaddr, ip->di_addr, NADDR);
239: doff = 0;
240: for(i=0;; i++) {
241: if(doff >= ip->di_size)
242: break;
243: d = bmap(i);
244: if(d == 0)
245: break;
246: bread(d, (char *)dbuf, BSIZE(dev));
247: for(j=0; j<NDIR(dev); j++) {
248: if(doff >= ip->di_size)
249: break;
250: doff += sizeof(struct direct);
251: dp = dbuf+j;
252: kno = dp->d_ino;
253: if(kno == 0)
254: continue;
255: if(aflg==0 && dotname(dp))
256: continue;
257: if(ilist[0]) {
258: for(k=0; ilist[k] != 0; k++)
259: if(ilist[k] == kno)
260: goto pr;
261: continue;
262: }
263: pr:
264: hp = lookup(kno, 0);
265: printf("%u\t", kno);
266: if (sflg && kno == ilist[k])
267: printf("%o\t", imodes[k]);
268: pname(ino, 0);
269: printf("/%.14s", dp->d_name);
270: if (hp)
271: printf("/.");
272: printf("\n");
273: }
274: }
275: }
276:
277: dotname(dp)
278: register struct direct *dp;
279: {
280:
281: if (dp->d_name[0]=='.')
282: if (dp->d_name[1]==0 || (dp->d_name[1]=='.' && dp->d_name[2]==0))
283: return(1);
284: return(0);
285: }
286:
287: pname(i, lev)
288: ino_t i;
289: {
290: register struct htab *hp;
291:
292: if (i==ROOTINO)
293: return;
294: if ((hp = lookup(i, 0)) == 0) {
295: printf("???");
296: return;
297: }
298: if (lev > 10) {
299: printf("...");
300: return;
301: }
302: pname(hp->h_pino, ++lev);
303: printf("/%.14s", hp->h_name);
304: }
305:
306: struct htab *
307: lookup(i, ef)
308: ino_t i;
309: {
310: register struct htab *hp;
311:
312: for (hp = &htab[i%HSIZE]; hp->h_ino;) {
313: if (hp->h_ino==i)
314: return(hp);
315: if (++hp >= &htab[HSIZE])
316: hp = htab;
317: }
318: if (ef==0)
319: return(0);
320: if (++nhent >= HSIZE) {
321: fprintf(stderr, "ncheck: out of core-- increase HSIZE\n");
322: exit(1);
323: }
324: hp->h_ino = i;
325: return(hp);
326: }
327:
328: bread(bno, buf, cnt)
329: daddr_t bno;
330: char *buf;
331: {
332: register i;
333:
334: lseek(fi, bno*BSIZE(dev), 0);
335: if (read(fi, buf, cnt) != cnt) {
336: fprintf(stderr, "ncheck: read error %d\n", bno);
337: for(i=0; i<BSIZE(dev); i++)
338: buf[i] = 0;
339: }
340: }
341:
342: daddr_t
343: bmap(i)
344: {
345: daddr_t ibuf[BIGNINDIR];
346:
347: if(i < NADDR-3)
348: return(iaddr[i]);
349: i -= NADDR-3;
350: if(i > NINDIR(dev)) {
351: fprintf(stderr, "ncheck: %u - huge directory\n", ino);
352: return((daddr_t)0);
353: }
354: bread(iaddr[NADDR-3], (char *)ibuf, BSIZE(dev));
355: return(ibuf[i]);
356: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.