|
|
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[] = "@(#)dcheck.c 5.3 (Berkeley) 5/2/88";
15: #endif not lint
16:
17: /*
18: * dcheck - check directory consistency
19: */
20: #define NB 10
21: #define MAXNINDIR (MAXBSIZE / sizeof (daddr_t))
22:
23: #include <sys/param.h>
24: #include <sys/inode.h>
25: #include <sys/fs.h>
26: #include <sys/dir.h>
27: #include <stdio.h>
28:
29: union {
30: struct fs fs;
31: char pad[SBSIZE];
32: } fsun;
33: #define sblock fsun.fs
34:
35: struct dirstuff {
36: int loc;
37: struct dinode *ip;
38: char dbuf[MAXBSIZE];
39: };
40:
41: struct dinode itab[MAXBSIZE / sizeof(struct dinode)];
42: struct dinode *gip;
43: ino_t ilist[NB];
44:
45: int fi;
46: ino_t ino;
47: ino_t *ecount;
48: int headpr;
49: int nfiles;
50: long dev_bsize = 1;
51:
52: int nerror;
53: daddr_t bmap();
54: long atol();
55: char *malloc();
56:
57: main(argc, argv)
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 'i':
69: for(i=0; i<NB; i++) {
70: n = atol(argv[1]);
71: if(n == 0)
72: break;
73: ilist[i] = n;
74: argv++;
75: argc--;
76: }
77: ilist[i] = 0;
78: continue;
79:
80: default:
81: printf("Bad flag %c\n", (*argv)[1]);
82: nerror++;
83: }
84: check(*argv);
85: }
86: return(nerror);
87: }
88:
89: check(file)
90: char *file;
91: {
92: register i, j, c;
93:
94: fi = open(file, 0);
95: if(fi < 0) {
96: printf("cannot open %s\n", file);
97: nerror++;
98: return;
99: }
100: headpr = 0;
101: printf("%s:\n", file);
102: sync();
103: bread(SBOFF, (char *)&sblock, SBSIZE);
104: if (sblock.fs_magic != FS_MAGIC) {
105: printf("%s: not a file system\n", file);
106: nerror++;
107: return;
108: }
109: dev_bsize = sblock.fs_fsize / fsbtodb(&sblock, 1);
110: nfiles = sblock.fs_ipg * sblock.fs_ncg;
111: ecount = (ino_t *)malloc((nfiles+1) * sizeof (*ecount));
112: if (ecount == 0) {
113: printf("%s: not enough core for %d files\n", file, nfiles);
114: exit(04);
115: }
116: for (i = 0; i<=nfiles; i++)
117: ecount[i] = 0;
118: ino = 0;
119: for (c = 0; c < sblock.fs_ncg; c++) {
120: for (i = 0;
121: i < sblock.fs_ipg / INOPF(&sblock);
122: i += sblock.fs_frag) {
123: bread(fsbtodb(&sblock, cgimin(&sblock, c) + i),
124: (char *)itab, sblock.fs_bsize);
125: for (j = 0; j < INOPB(&sblock); j++) {
126: pass1(&itab[j]);
127: ino++;
128: }
129: }
130: }
131: ino = 0;
132: for (c = 0; c < sblock.fs_ncg; c++) {
133: for (i = 0;
134: i < sblock.fs_ipg / INOPF(&sblock);
135: i += sblock.fs_frag) {
136: bread(fsbtodb(&sblock, cgimin(&sblock, c) + i),
137: (char *)itab, sblock.fs_bsize);
138: for (j = 0; j < INOPB(&sblock); j++) {
139: pass2(&itab[j]);
140: ino++;
141: }
142: }
143: }
144: free(ecount);
145: }
146:
147: pass1(ip)
148: register struct dinode *ip;
149: {
150: register struct direct *dp;
151: struct dirstuff dirp;
152: int k;
153:
154: if((ip->di_mode&IFMT) != IFDIR)
155: return;
156: dirp.loc = 0;
157: dirp.ip = ip;
158: gip = ip;
159: for (dp = readdir(&dirp); dp != NULL; dp = readdir(&dirp)) {
160: if(dp->d_ino == 0)
161: continue;
162: if(dp->d_ino > nfiles || dp->d_ino < ROOTINO) {
163: printf("%d bad; %d/%s\n",
164: dp->d_ino, ino, dp->d_name);
165: nerror++;
166: continue;
167: }
168: for (k = 0; ilist[k] != 0; k++)
169: if (ilist[k] == dp->d_ino) {
170: printf("%d arg; %d/%s\n",
171: dp->d_ino, ino, dp->d_name);
172: nerror++;
173: }
174: ecount[dp->d_ino]++;
175: }
176: }
177:
178: pass2(ip)
179: register struct dinode *ip;
180: {
181: register i;
182:
183: i = ino;
184: if ((ip->di_mode&IFMT)==0 && ecount[i]==0)
185: return;
186: if (ip->di_nlink==ecount[i] && ip->di_nlink!=0)
187: return;
188: if (headpr==0) {
189: printf(" entries link cnt\n");
190: headpr++;
191: }
192: printf("%u\t%d\t%d\n", ino,
193: ecount[i], ip->di_nlink);
194: }
195:
196: /*
197: * get next entry in a directory.
198: */
199: struct direct *
200: readdir(dirp)
201: register struct dirstuff *dirp;
202: {
203: register struct direct *dp;
204: daddr_t lbn, d;
205:
206: for(;;) {
207: if (dirp->loc >= dirp->ip->di_size)
208: return NULL;
209: if ((lbn = lblkno(&sblock, dirp->loc)) == 0) {
210: d = bmap(lbn);
211: if(d == 0)
212: return NULL;
213: bread(fsbtodb(&sblock, d), dirp->dbuf,
214: dblksize(&sblock, dirp->ip, lbn));
215: }
216: dp = (struct direct *)
217: (dirp->dbuf + blkoff(&sblock, dirp->loc));
218: dirp->loc += dp->d_reclen;
219: if (dp->d_ino == 0)
220: continue;
221: return (dp);
222: }
223: }
224:
225: bread(bno, buf, cnt)
226: daddr_t bno;
227: char *buf;
228: {
229: register i;
230:
231: lseek(fi, bno * dev_bsize, 0);
232: if (read(fi, buf, cnt) != cnt) {
233: printf("read error %d\n", bno);
234: for(i=0; i < cnt; i++)
235: buf[i] = 0;
236: }
237: }
238:
239: daddr_t
240: bmap(i)
241: {
242: daddr_t ibuf[MAXNINDIR];
243:
244: if(i < NDADDR)
245: return(gip->di_db[i]);
246: i -= NDADDR;
247: if(i > NINDIR(&sblock)) {
248: printf("%u - huge directory\n", ino);
249: return((daddr_t)0);
250: }
251: bread(fsbtodb(&sblock, gip->di_ib[0]), (char *)ibuf, sizeof(ibuf));
252: return(ibuf[i]);
253: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.