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