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