Commit | Line | Data |
---|---|---|
5086d197 | 1 | static char *sccsid = "@(#)ncheck.c 1.7 (Berkeley) %G%"; |
d9c5783d KM |
2 | /* |
3 | * ncheck -- obtain file names from reading filesystem | |
4 | */ | |
5 | ||
b6407c9d KM |
6 | #define NB 500 |
7 | #define HSIZE 2503 | |
c312eebd | 8 | #define MAXNINDIR (MAXBSIZE / sizeof (daddr_t)) |
d9c5783d | 9 | |
d9c5783d KM |
10 | #include "../h/param.h" |
11 | #include "../h/inode.h" | |
d9c5783d | 12 | #include "../h/fs.h" |
5086d197 KM |
13 | #include <stdio.h> |
14 | #include <ndir.h> | |
d9c5783d KM |
15 | |
16 | struct fs sblock; | |
17 | struct dinode itab[MAXIPG]; | |
56d45dcd | 18 | struct dinode *gip; |
d9c5783d KM |
19 | ino_t ilist[NB]; |
20 | struct htab | |
21 | { | |
22 | ino_t h_ino; | |
23 | ino_t h_pino; | |
5086d197 | 24 | char *h_name; |
d9c5783d | 25 | } htab[HSIZE]; |
5086d197 KM |
26 | char strngtab[30 * HSIZE]; |
27 | int strngloc; | |
28 | ||
29 | struct dirstuff { | |
30 | int loc; | |
31 | struct dinode *ip; | |
32 | char dbuf[MAXBSIZE]; | |
33 | }; | |
d9c5783d KM |
34 | |
35 | int aflg; | |
36 | int sflg; | |
37 | int fi; | |
38 | ino_t ino; | |
39 | int nhent; | |
40 | int nxfile; | |
41 | ||
42 | int nerror; | |
43 | daddr_t bmap(); | |
44 | long atol(); | |
45 | struct htab *lookup(); | |
46 | ||
47 | main(argc, argv) | |
20380c05 KM |
48 | int argc; |
49 | char *argv[]; | |
d9c5783d KM |
50 | { |
51 | register i; | |
52 | long n; | |
53 | ||
54 | while (--argc) { | |
55 | argv++; | |
56 | if (**argv=='-') | |
57 | switch ((*argv)[1]) { | |
58 | ||
59 | case 'a': | |
60 | aflg++; | |
61 | continue; | |
62 | ||
63 | case 'i': | |
64 | for(i=0; i<NB; i++) { | |
65 | n = atol(argv[1]); | |
66 | if(n == 0) | |
67 | break; | |
68 | ilist[i] = n; | |
69 | nxfile = i; | |
70 | argv++; | |
71 | argc--; | |
72 | } | |
73 | continue; | |
74 | ||
75 | case 's': | |
76 | sflg++; | |
77 | continue; | |
78 | ||
79 | default: | |
80 | fprintf(stderr, "ncheck: bad flag %c\n", (*argv)[1]); | |
81 | nerror++; | |
82 | } | |
83 | check(*argv); | |
84 | } | |
85 | return(nerror); | |
86 | } | |
87 | ||
88 | check(file) | |
20380c05 | 89 | char *file; |
d9c5783d | 90 | { |
20380c05 KM |
91 | register int i, j, c; |
92 | int nfiles; | |
d9c5783d KM |
93 | |
94 | fi = open(file, 0); | |
95 | if(fi < 0) { | |
96 | fprintf(stderr, "ncheck: cannot open %s\n", file); | |
97 | nerror++; | |
98 | return; | |
99 | } | |
100 | nhent = 0; | |
101 | printf("%s:\n", file); | |
102 | sync(); | |
c312eebd | 103 | bread(SBLOCK, (char *)&sblock, SBSIZE); |
20380c05 KM |
104 | if (sblock.fs_magic != FS_MAGIC) { |
105 | printf("%s: not a file system\n", file); | |
106 | nerror++; | |
107 | return; | |
108 | } | |
109 | nfiles = sblock.fs_ipg * sblock.fs_ncg; | |
110 | if (nfiles > 65535) { | |
111 | printf("%s: %d is a preposterous number of files\n", | |
112 | file, nfiles); | |
113 | nerror++; | |
114 | return; | |
115 | } | |
d9c5783d KM |
116 | ino = 0; |
117 | for (c = 0; c < sblock.fs_ncg; c++) { | |
6994bf5d | 118 | bread(fsbtodb(&sblock, cgimin(&sblock, c)), (char *)itab, |
d9c5783d KM |
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 | ilist[nxfile+1] = 0; | |
126 | ino = 0; | |
127 | for (c = 0; c < sblock.fs_ncg; c++) { | |
6994bf5d | 128 | bread(fsbtodb(&sblock, cgimin(&sblock, c)), (char *)itab, |
d9c5783d KM |
129 | sblock.fs_ipg * sizeof (struct dinode)); |
130 | for(j=0; j<sblock.fs_ipg; j++) { | |
131 | pass2(&itab[j]); | |
132 | ino++; | |
133 | } | |
134 | } | |
135 | ino = 0; | |
136 | for (c = 0; c < sblock.fs_ncg; c++) { | |
6994bf5d | 137 | bread(fsbtodb(&sblock, cgimin(&sblock, c)), (char *)itab, |
d9c5783d KM |
138 | sblock.fs_ipg * sizeof (struct dinode)); |
139 | for(j=0; j<sblock.fs_ipg; j++) { | |
140 | pass3(&itab[j]); | |
141 | ino++; | |
142 | } | |
143 | } | |
144 | } | |
145 | ||
146 | pass1(ip) | |
20380c05 | 147 | register struct dinode *ip; |
d9c5783d KM |
148 | { |
149 | if((ip->di_mode & IFMT) != IFDIR) { | |
150 | if (sflg==0 || nxfile>=NB) | |
151 | return; | |
152 | if ((ip->di_mode&IFMT)==IFBLK || (ip->di_mode&IFMT)==IFCHR | |
153 | || ip->di_mode&(ISUID|ISGID)) | |
154 | ilist[nxfile++] = ino; | |
155 | return; | |
156 | } | |
157 | lookup(ino, 1); | |
158 | } | |
159 | ||
160 | pass2(ip) | |
20380c05 | 161 | register struct dinode *ip; |
d9c5783d | 162 | { |
5086d197 KM |
163 | register struct direct *dp; |
164 | struct dirstuff dirp; | |
d9c5783d | 165 | struct htab *hp; |
d9c5783d KM |
166 | |
167 | if((ip->di_mode&IFMT) != IFDIR) | |
168 | return; | |
5086d197 KM |
169 | dirp.loc = 0; |
170 | dirp.ip = ip; | |
56d45dcd | 171 | gip = ip; |
5086d197 KM |
172 | for (dp = readdir(&dirp); dp != NULL; dp = readdir(&dirp)) { |
173 | if(dp->d_ino == 0) | |
174 | continue; | |
175 | hp = lookup(dp->d_ino, 0); | |
176 | if(hp == 0) | |
177 | continue; | |
178 | if(dotname(dp)) | |
179 | continue; | |
180 | hp->h_pino = ino; | |
181 | hp->h_name = &strngtab[strngloc]; | |
182 | strngloc += strlen(dp->d_name) + 1; | |
183 | strcpy(hp->h_name, dp->d_name); | |
d9c5783d KM |
184 | } |
185 | } | |
186 | ||
187 | pass3(ip) | |
20380c05 | 188 | register struct dinode *ip; |
d9c5783d | 189 | { |
5086d197 KM |
190 | register struct direct *dp; |
191 | struct dirstuff dirp; | |
d9c5783d | 192 | int k; |
d9c5783d KM |
193 | |
194 | if((ip->di_mode&IFMT) != IFDIR) | |
195 | return; | |
5086d197 KM |
196 | dirp.loc = 0; |
197 | dirp.ip = ip; | |
56d45dcd | 198 | gip = ip; |
5086d197 KM |
199 | for(dp = readdir(&dirp); dp != NULL; dp = readdir(&dirp)) { |
200 | if(dp->d_ino == 0) | |
d9c5783d | 201 | continue; |
5086d197 KM |
202 | if(aflg==0 && dotname(dp)) |
203 | continue; | |
204 | if(ilist[0] == 0) | |
205 | goto pr; | |
206 | for(k = 0; ilist[k] != 0; k++) | |
207 | if(ilist[k] == dp->d_ino) | |
208 | goto pr; | |
209 | continue; | |
210 | pr: | |
211 | printf("%u ", dp->d_ino); | |
212 | pname(ino, 0); | |
213 | printf("/%s", dp->d_name); | |
214 | if (lookup(dp->d_ino, 0)) | |
215 | printf("/."); | |
216 | printf("\n"); | |
217 | } | |
218 | } | |
219 | ||
220 | /* | |
221 | * get next entry in a directory. | |
222 | */ | |
223 | struct direct * | |
224 | readdir(dirp) | |
225 | register struct dirstuff *dirp; | |
226 | { | |
227 | register struct direct *dp; | |
228 | daddr_t lbn, d; | |
229 | ||
230 | for(;;) { | |
231 | if (dirp->loc >= dirp->ip->di_size) | |
232 | return NULL; | |
233 | if ((lbn = dirp->loc / sblock.fs_bsize) == 0) { | |
234 | d = bmap(lbn); | |
235 | if(d == 0) | |
236 | return NULL; | |
237 | bread(fsbtodb(&sblock, d), dirp->dbuf, | |
238 | dblksize(&sblock, dirp->ip, lbn)); | |
d9c5783d | 239 | } |
5086d197 KM |
240 | dp = (struct direct *) |
241 | (dirp->dbuf + dirp->loc % sblock.fs_bsize); | |
242 | dirp->loc += dp->d_reclen; | |
243 | if (dp->d_ino == 0) | |
244 | continue; | |
245 | return (dp); | |
d9c5783d KM |
246 | } |
247 | } | |
248 | ||
249 | dotname(dp) | |
20380c05 | 250 | register struct direct *dp; |
d9c5783d KM |
251 | { |
252 | ||
253 | if (dp->d_name[0]=='.') | |
5086d197 KM |
254 | if (dp->d_name[1]==0 || |
255 | (dp->d_name[1]=='.' && dp->d_name[2]==0)) | |
d9c5783d KM |
256 | return(1); |
257 | return(0); | |
258 | } | |
259 | ||
260 | pname(i, lev) | |
20380c05 KM |
261 | ino_t i; |
262 | int lev; | |
d9c5783d KM |
263 | { |
264 | register struct htab *hp; | |
265 | ||
266 | if (i==ROOTINO) | |
267 | return; | |
268 | if ((hp = lookup(i, 0)) == 0) { | |
269 | printf("???"); | |
270 | return; | |
271 | } | |
272 | if (lev > 10) { | |
273 | printf("..."); | |
274 | return; | |
275 | } | |
276 | pname(hp->h_pino, ++lev); | |
5086d197 | 277 | printf("/%s", hp->h_name); |
d9c5783d KM |
278 | } |
279 | ||
280 | struct htab * | |
281 | lookup(i, ef) | |
20380c05 KM |
282 | ino_t i; |
283 | int ef; | |
d9c5783d KM |
284 | { |
285 | register struct htab *hp; | |
286 | ||
287 | for (hp = &htab[i%HSIZE]; hp->h_ino;) { | |
288 | if (hp->h_ino==i) | |
289 | return(hp); | |
290 | if (++hp >= &htab[HSIZE]) | |
291 | hp = htab; | |
292 | } | |
293 | if (ef==0) | |
294 | return(0); | |
295 | if (++nhent >= HSIZE) { | |
296 | fprintf(stderr, "ncheck: out of core-- increase HSIZE\n"); | |
297 | exit(1); | |
298 | } | |
299 | hp->h_ino = i; | |
300 | return(hp); | |
301 | } | |
302 | ||
303 | bread(bno, buf, cnt) | |
20380c05 KM |
304 | daddr_t bno; |
305 | char *buf; | |
306 | int cnt; | |
d9c5783d KM |
307 | { |
308 | register i; | |
309 | ||
b6407c9d | 310 | lseek(fi, bno * DEV_BSIZE, 0); |
d9c5783d KM |
311 | if (read(fi, buf, cnt) != cnt) { |
312 | fprintf(stderr, "ncheck: read error %d\n", bno); | |
b6407c9d | 313 | for(i=0; i < cnt; i++) |
d9c5783d KM |
314 | buf[i] = 0; |
315 | } | |
316 | } | |
317 | ||
318 | daddr_t | |
319 | bmap(i) | |
20380c05 | 320 | int i; |
d9c5783d | 321 | { |
b6407c9d | 322 | daddr_t ibuf[MAXNINDIR]; |
d9c5783d | 323 | |
56d45dcd KM |
324 | if(i < NDADDR) |
325 | return(gip->di_db[i]); | |
326 | i -= NDADDR; | |
b6407c9d | 327 | if(i > NINDIR(&sblock)) { |
d9c5783d KM |
328 | fprintf(stderr, "ncheck: %u - huge directory\n", ino); |
329 | return((daddr_t)0); | |
330 | } | |
b6407c9d | 331 | bread(fsbtodb(&sblock, gip->di_ib[i]), (char *)ibuf, sizeof(ibuf)); |
d9c5783d KM |
332 | return(ibuf[i]); |
333 | } |