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