minor fixups with initialization
[unix-history] / usr / src / sbin / ncheck / ncheck.c
CommitLineData
5086d197 1static 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
16struct fs sblock;
17struct dinode itab[MAXIPG];
56d45dcd 18struct dinode *gip;
d9c5783d
KM
19ino_t ilist[NB];
20struct htab
21{
22 ino_t h_ino;
23 ino_t h_pino;
5086d197 24 char *h_name;
d9c5783d 25} htab[HSIZE];
5086d197
KM
26char strngtab[30 * HSIZE];
27int strngloc;
28
29struct dirstuff {
30 int loc;
31 struct dinode *ip;
32 char dbuf[MAXBSIZE];
33};
d9c5783d
KM
34
35int aflg;
36int sflg;
37int fi;
38ino_t ino;
39int nhent;
40int nxfile;
41
42int nerror;
43daddr_t bmap();
44long atol();
45struct htab *lookup();
46
47main(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
88check(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
146pass1(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
160pass2(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
187pass3(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 */
223struct direct *
224readdir(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
249dotname(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
260pname(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
280struct htab *
281lookup(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
303bread(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
318daddr_t
319bmap(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}