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