|
|
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.1 (Berkeley) 6/6/85";
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[MAXBSIZE];
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[MAXIPG];
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:
51: int nerror;
52: daddr_t bmap();
53: long atol();
54: char *malloc();
55:
56: main(argc, argv)
57: char *argv[];
58: {
59: register i;
60: long n;
61:
62: while (--argc) {
63: argv++;
64: if (**argv=='-')
65: switch ((*argv)[1]) {
66:
67: case 'i':
68: for(i=0; i<NB; i++) {
69: n = atol(argv[1]);
70: if(n == 0)
71: break;
72: ilist[i] = n;
73: argv++;
74: argc--;
75: }
76: ilist[i] = 0;
77: continue;
78:
79: default:
80: printf("Bad flag %c\n", (*argv)[1]);
81: nerror++;
82: }
83: check(*argv);
84: }
85: return(nerror);
86: }
87:
88: check(file)
89: char *file;
90: {
91: register i, j, c;
92:
93: fi = open(file, 0);
94: if(fi < 0) {
95: printf("cannot open %s\n", file);
96: nerror++;
97: return;
98: }
99: headpr = 0;
100: printf("%s:\n", file);
101: sync();
102: bread(SBLOCK, (char *)&sblock, SBSIZE);
103: if (sblock.fs_magic != FS_MAGIC) {
104: printf("%s: not a file system\n", file);
105: nerror++;
106: return;
107: }
108: nfiles = sblock.fs_ipg * sblock.fs_ncg;
109: ecount = (ino_t *)malloc((nfiles+1) * sizeof (*ecount));
110: if (ecount == 0) {
111: printf("%s: not enough core for %d files\n", file, nfiles);
112: exit(04);
113: }
114: for (i = 0; i<=nfiles; i++)
115: ecount[i] = 0;
116: ino = 0;
117: for (c = 0; c < sblock.fs_ncg; c++) {
118: bread(fsbtodb(&sblock, cgimin(&sblock, c)), (char *)itab,
119: sblock.fs_ipg * sizeof (struct dinode));
120: for (j = 0; j < sblock.fs_ipg; j++) {
121: pass1(&itab[j]);
122: ino++;
123: }
124: }
125: ino = 0;
126: for (c = 0; c < sblock.fs_ncg; c++) {
127: bread(fsbtodb(&sblock, cgimin(&sblock, c)), (char *)itab,
128: sblock.fs_ipg * sizeof (struct dinode));
129: for (j = 0; j < sblock.fs_ipg; j++) {
130: pass2(&itab[j]);
131: ino++;
132: }
133: }
134: free(ecount);
135: }
136:
137: pass1(ip)
138: register struct dinode *ip;
139: {
140: register struct direct *dp;
141: struct dirstuff dirp;
142: int k;
143:
144: if((ip->di_mode&IFMT) != IFDIR)
145: return;
146: dirp.loc = 0;
147: dirp.ip = ip;
148: gip = ip;
149: for (dp = readdir(&dirp); dp != NULL; dp = readdir(&dirp)) {
150: if(dp->d_ino == 0)
151: continue;
152: if(dp->d_ino > nfiles || dp->d_ino < ROOTINO) {
153: printf("%d bad; %d/%s\n",
154: dp->d_ino, ino, dp->d_name);
155: nerror++;
156: continue;
157: }
158: for (k = 0; ilist[k] != 0; k++)
159: if (ilist[k] == dp->d_ino) {
160: printf("%d arg; %d/%s\n",
161: dp->d_ino, ino, dp->d_name);
162: nerror++;
163: }
164: ecount[dp->d_ino]++;
165: }
166: }
167:
168: pass2(ip)
169: register struct dinode *ip;
170: {
171: register i;
172:
173: i = ino;
174: if ((ip->di_mode&IFMT)==0 && ecount[i]==0)
175: return;
176: if (ip->di_nlink==ecount[i] && ip->di_nlink!=0)
177: return;
178: if (headpr==0) {
179: printf(" entries link cnt\n");
180: headpr++;
181: }
182: printf("%u\t%d\t%d\n", ino,
183: ecount[i], ip->di_nlink);
184: }
185:
186: /*
187: * get next entry in a directory.
188: */
189: struct direct *
190: readdir(dirp)
191: register struct dirstuff *dirp;
192: {
193: register struct direct *dp;
194: daddr_t lbn, d;
195:
196: for(;;) {
197: if (dirp->loc >= dirp->ip->di_size)
198: return NULL;
199: if ((lbn = lblkno(&sblock, dirp->loc)) == 0) {
200: d = bmap(lbn);
201: if(d == 0)
202: return NULL;
203: bread(fsbtodb(&sblock, d), dirp->dbuf,
204: dblksize(&sblock, dirp->ip, lbn));
205: }
206: dp = (struct direct *)
207: (dirp->dbuf + blkoff(&sblock, dirp->loc));
208: dirp->loc += dp->d_reclen;
209: if (dp->d_ino == 0)
210: continue;
211: return (dp);
212: }
213: }
214:
215: bread(bno, buf, cnt)
216: daddr_t bno;
217: char *buf;
218: {
219: register i;
220:
221: lseek(fi, bno * DEV_BSIZE, 0);
222: if (read(fi, buf, cnt) != cnt) {
223: printf("read error %d\n", bno);
224: for(i=0; i < cnt; i++)
225: buf[i] = 0;
226: }
227: }
228:
229: daddr_t
230: bmap(i)
231: {
232: daddr_t ibuf[MAXNINDIR];
233:
234: if(i < NDADDR)
235: return(gip->di_db[i]);
236: i -= NDADDR;
237: if(i > NINDIR(&sblock)) {
238: printf("%u - huge directory\n", ino);
239: return((daddr_t)0);
240: }
241: bread(fsbtodb(&sblock, gip->di_ib[0]), (char *)ibuf, sizeof(ibuf));
242: return(ibuf[i]);
243: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.