|
|
1.1 root 1: /*
2: * dcheck - check directory consistency
3: */
4: #define NI 16
5: #define NB 10
6:
7: #include <stdio.h>
8: #include <sys/param.h>
9: #include <sys/inode.h>
10: #include <sys/ino.h>
11: #include <sys/dir.h>
12: #include <sys/filsys.h>
13: #include <sys/fblk.h>
14: #include <sys/stat.h>
15:
16: #define BITFSBIT 64 /* should be in param.h */
17: #define BIGINOPB INOPB(BITFSBIT)
18: #define BIGBSIZE BSIZE(BITFSBIT)
19: #define BIGNINDIR NINDIR(BITFSBIT)
20: #define BIGNDIR (BIGBSIZE/sizeof(struct direct))
21:
22: #define NDIR(dev) (BSIZE(dev)/sizeof(struct direct))
23:
24: struct filsys sblock;
25: struct stat status;
26: #define dev status.st_rdev
27: struct dinode itab[BIGINOPB*NI];
28: daddr_t iaddr[NADDR];
29: ino_t ilist[NB];
30: int bigdev;
31:
32: int fi;
33: long ino;
34: char *ecount;
35: int headpr;
36: long nfiles;
37: int bigflag;
38:
39: int nerror;
40: daddr_t bmap();
41: long atol();
42: char *malloc();
43:
44: main(argc, argv)
45: char *argv[];
46: {
47: register i;
48: long n;
49:
50: setbuf(stdout, NULL);
51: while (--argc) {
52: argv++;
53: if (**argv=='-')
54: switch ((*argv)[1]) {
55:
56: case 'i':
57: for(i=0; i<NB; i++) {
58: n = atol(argv[1]);
59: if(n == 0)
60: break;
61: ilist[i] = n;
62: argv++;
63: argc--;
64: }
65: ilist[i] = 0;
66: continue;
67:
68: case 'B':
69: bigflag = BITFSBIT;
70: continue;
71:
72: default:
73: fprintf(stderr, "Bad flag %c\n", (*argv)[1]);
74: nerror++;
75: }
76: check(*argv);
77: }
78: return(nerror);
79: }
80:
81: check(file)
82: char *file;
83: {
84: register i;
85: register j;
86: register nchunk;
87:
88: fi = open(file, 0);
89: if(fi < 0) {
90: perror(file);
91: nerror++;
92: return;
93: }
94: if (fstat(fi, &status) < 0) {
95: fprintf(stderr, "ncheck: cannot stat %s\n", file);
96: nerror++;
97: close(fi);
98: return;
99: }
100: if ((status.st_mode & S_IFMT) == S_IFREG)
101: dev = makedev(0, bigflag);
102: headpr = 0;
103: printf("%s:\n", file);
104: sync();
105: bread((daddr_t)1, (char *)&sblock, sizeof(sblock));
106: nfiles = (sblock.s_isize-2)*INOPB(dev);
107: nchunk = INOPB(dev)*NI;
108: ecount = malloc(nfiles+1);
109: if (ecount==NULL) {
110: fprintf(stderr, "Not enough core\n");
111: exit(04);
112: }
113: for (i=0; i<=nfiles; i++)
114: ecount[i] = 0;
115: ino = 0;
116: for(i=2;; i+=NI) {
117: if(ino >= nfiles)
118: break;
119: bread((daddr_t)i, (char *)itab, BSIZE(dev)*NI);
120: for(j=0; j<nchunk; j++) {
121: if(ino >= nfiles)
122: break;
123: ino++;
124: pass1(&itab[j]);
125: }
126: }
127: ino = 0;
128: for(i=2;; i+=NI) {
129: if(ino >= nfiles)
130: break;
131: bread((daddr_t)i, (char *)itab, BSIZE(dev)*NI);
132: for(j=0; j<nchunk; j++) {
133: if(ino >= nfiles)
134: break;
135: ino++;
136: pass2(&itab[j]);
137: }
138: }
139: free(ecount);
140: }
141:
142: pass1(ip)
143: register struct dinode *ip;
144: {
145: struct direct dbuf[BIGNDIR];
146: off_t doff;
147: struct direct *dp;
148: register i, j;
149: int k;
150: daddr_t d;
151: ino_t kno;
152:
153: if((ip->di_mode&IFMT) != IFDIR)
154: return;
155: l3tol(iaddr, ip->di_addr, NADDR);
156: doff = 0;
157: for(i=0;; i++) {
158: if(doff >= ip->di_size)
159: break;
160: d = bmap(i);
161: if(d == 0)
162: break;
163: bread(d, (char *)dbuf, BSIZE(dev));
164: for(j=0; j<NDIR(dev); j++) {
165: if(doff >= ip->di_size)
166: break;
167: doff += sizeof(struct direct);
168: dp = &dbuf[j];
169: kno = dp->d_ino;
170: if(kno == 0)
171: continue;
172: if (kno > nfiles) {
173: printf("%5u bad; %u/%.14s\n", kno, ino, dp->d_name);
174: nerror++;
175: continue;
176: }
177: for (k=0; ilist[k] != 0; k++)
178: if (ilist[k]==kno) {
179: printf("%5u arg; %u/%.14s\n", kno, ino, dp->d_name);
180: nerror++;
181: }
182: ecount[kno]++;
183: if (ecount[kno] == 0)
184: ecount[kno] = 0377;
185: }
186: }
187: }
188:
189: pass2(ip)
190: register struct dinode *ip;
191: {
192: register i;
193:
194: i = ino;
195: if ((ip->di_mode&IFMT)==0 && ecount[i]==0)
196: return;
197: if (ip->di_nlink==((ecount[i])&0377) && ip->di_nlink!=0)
198: return;
199: if (ino <= 0 && ip->di_nlink==0 && ecount[i]==0)
200: return;
201: if (headpr==0) {
202: printf(" entries link cnt\n");
203: headpr++;
204: }
205: printf("%u %d %d\n", ino,
206: ecount[i]&0377, ip->di_nlink);
207: }
208:
209: bread(bno, buf, cnt)
210: daddr_t bno;
211: char *buf;
212: {
213: register i;
214:
215: lseek(fi, bno*BSIZE(dev), 0);
216: if (read(fi, buf, cnt) != cnt) {
217: fprintf(stderr, "read error %ld\n", bno);
218: for(i=0; i<BSIZE(dev); i++)
219: buf[i] = 0;
220: }
221: }
222:
223:
224: daddr_t
225: bmap(i)
226: {
227: daddr_t ibuf[BIGNINDIR];
228:
229: if(i < NADDR-3)
230: return(iaddr[i]);
231: i -= NADDR-3;
232: if(i > NINDIR(dev)) {
233: fprintf(stderr, "%u - huge directory\n", ino);
234: return((daddr_t)0);
235: }
236: bread(iaddr[NADDR-3], (char *)ibuf, sizeof(daddr_t)*NINDIR(dev));
237: return(ibuf[i]);
238: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.