Bell 32V development
[unix-history] / usr / src / cmd / ncheck.c
CommitLineData
f6897333
TL
1/*
2 * ncheck -- obtain file names from reading filesystem
3 */
4
5#define NI 16
6#define NB 100
7#define HSIZE 2503
8#define NDIR (BSIZE/sizeof(struct direct))
9
10#include <stdio.h>
11#include <sys/param.h>
12#include <sys/inode.h>
13#include <sys/ino.h>
14#include <sys/dir.h>
15#include <sys/filsys.h>
16#include <sys/fblk.h>
17
18struct filsys sblock;
19struct dinode itab[INOPB*NI];
20daddr_t iaddr[NADDR];
21ino_t ilist[NB];
22struct htab
23{
24 ino_t h_ino;
25 ino_t h_pino;
26 char h_name[DIRSIZ];
27} htab[HSIZE];
28
29int aflg;
30int sflg;
31int fi;
32ino_t ino;
33int nhent;
34int nxfile;
35
36int nerror;
37daddr_t bmap();
38long atol();
39struct htab *lookup();
40
41main(argc, argv)
42char *argv[];
43{
44 register i;
45 long n;
46
47 while (--argc) {
48 argv++;
49 if (**argv=='-')
50 switch ((*argv)[1]) {
51
52 case 'a':
53 aflg++;
54 continue;
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 nxfile = i;
63 argv++;
64 argc--;
65 }
66 continue;
67
68 case 's':
69 sflg++;
70 continue;
71
72 default:
73 fprintf(stderr, "ncheck: bad flag %c\n", (*argv)[1]);
74 nerror++;
75 }
76 check(*argv);
77 }
78 return(nerror);
79}
80
81check(file)
82char *file;
83{
84 register i, j;
85 ino_t mino;
86
87 fi = open(file, 0);
88 if(fi < 0) {
89 fprintf(stderr, "ncheck: cannot open %s\n", file);
90 nerror++;
91 return;
92 }
93 nhent = 0;
94 printf("%s:\n", file);
95 sync();
96 bread((daddr_t)1, (char *)&sblock, sizeof(sblock));
97 mino = (sblock.s_isize-2) * INOPB;
98 ino = 0;
99 for(i=2;; i+=NI) {
100 if(ino >= mino)
101 break;
102 bread((daddr_t)i, (char *)itab, sizeof(itab));
103 for(j=0; j<INOPB*NI; j++) {
104 if(ino >= mino)
105 break;
106 ino++;
107 pass1(&itab[j]);
108 }
109 }
110 ilist[nxfile+1] = 0;
111 ino = 0;
112 for(i=2;; i+=NI) {
113 if(ino >= mino)
114 break;
115 bread((daddr_t)i, (char *)itab, sizeof(itab));
116 for(j=0; j<INOPB*NI; j++) {
117 if(ino >= mino)
118 break;
119 ino++;
120 pass2(&itab[j]);
121 }
122 }
123 ino = 0;
124 for(i=2;; i+=NI) {
125 if(ino >= mino)
126 break;
127 bread((daddr_t)i, (char *)itab, sizeof(itab));
128 for(j=0; j<INOPB*NI; j++) {
129 if(ino >= mino)
130 break;
131 ino++;
132 pass3(&itab[j]);
133 }
134 }
135}
136
137pass1(ip)
138register struct dinode *ip;
139{
140 if((ip->di_mode & IFMT) != IFDIR) {
141 if (sflg==0 || nxfile>=NB)
142 return;
143 if ((ip->di_mode&IFMT)==IFBLK || (ip->di_mode&IFMT)==IFCHR
144 || ip->di_mode&(ISUID|ISGID))
145 ilist[nxfile++] = ino;
146 return;
147 }
148 lookup(ino, 1);
149}
150
151pass2(ip)
152register struct dinode *ip;
153{
154 struct direct dbuf[NDIR];
155 long doff;
156 struct direct *dp;
157 register i, j;
158 int k;
159 struct htab *hp;
160 daddr_t d;
161 ino_t kno;
162
163 if((ip->di_mode&IFMT) != IFDIR)
164 return;
165 l3tol(iaddr, ip->di_addr, NADDR);
166 doff = 0;
167 for(i=0;; i++) {
168 if(doff >= ip->di_size)
169 break;
170 d = bmap(i);
171 if(d == 0)
172 break;
173 bread(d, (char *)dbuf, sizeof(dbuf));
174 for(j=0; j<NDIR; j++) {
175 if(doff >= ip->di_size)
176 break;
177 doff += sizeof(struct direct);
178 dp = dbuf+j;
179 kno = dp->d_ino;
180 if(kno == 0)
181 continue;
182 hp = lookup(kno, 0);
183 if(hp == 0)
184 continue;
185 if(dotname(dp))
186 continue;
187 hp->h_pino = ino;
188 for(k=0; k<DIRSIZ; k++)
189 hp->h_name[k] = dp->d_name[k];
190 }
191 }
192}
193
194pass3(ip)
195register struct dinode *ip;
196{
197 struct direct dbuf[NDIR];
198 long doff;
199 struct direct *dp;
200 register i, j;
201 int k;
202 daddr_t d;
203 ino_t kno;
204
205 if((ip->di_mode&IFMT) != IFDIR)
206 return;
207 l3tol(iaddr, ip->di_addr, NADDR);
208 doff = 0;
209 for(i=0;; i++) {
210 if(doff >= ip->di_size)
211 break;
212 d = bmap(i);
213 if(d == 0)
214 break;
215 bread(d, (char *)dbuf, sizeof(dbuf));
216 for(j=0; j<NDIR; j++) {
217 if(doff >= ip->di_size)
218 break;
219 doff += sizeof(struct direct);
220 dp = dbuf+j;
221 kno = dp->d_ino;
222 if(kno == 0)
223 continue;
224 if(aflg==0 && dotname(dp))
225 continue;
226 if(ilist[0] == 0)
227 goto pr;
228 for(k=0; ilist[k] != 0; k++)
229 if(ilist[k] == kno)
230 goto pr;
231 continue;
232 pr:
233 printf("%u ", kno);
234 pname(ino, 0);
235 printf("/%.14s", dp->d_name);
236 if (lookup(kno, 0))
237 printf("/.");
238 printf("\n");
239 }
240 }
241}
242
243dotname(dp)
244register struct direct *dp;
245{
246
247 if (dp->d_name[0]=='.')
248 if (dp->d_name[1]==0 || (dp->d_name[1]=='.' && dp->d_name[2]==0))
249 return(1);
250 return(0);
251}
252
253pname(i, lev)
254ino_t i;
255{
256 register struct htab *hp;
257
258 if (i==ROOTINO)
259 return;
260 if ((hp = lookup(i, 0)) == 0) {
261 printf("???");
262 return;
263 }
264 if (lev > 10) {
265 printf("...");
266 return;
267 }
268 pname(hp->h_pino, ++lev);
269 printf("/%.14s", hp->h_name);
270}
271
272struct htab *
273lookup(i, ef)
274ino_t i;
275{
276 register struct htab *hp;
277
278 for (hp = &htab[i%HSIZE]; hp->h_ino;) {
279 if (hp->h_ino==i)
280 return(hp);
281 if (++hp >= &htab[HSIZE])
282 hp = htab;
283 }
284 if (ef==0)
285 return(0);
286 if (++nhent >= HSIZE) {
287 fprintf(stderr, "ncheck: out of core-- increase HSIZE\n");
288 exit(1);
289 }
290 hp->h_ino = i;
291 return(hp);
292}
293
294bread(bno, buf, cnt)
295daddr_t bno;
296char *buf;
297{
298 register i;
299
300 lseek(fi, bno*BSIZE, 0);
301 if (read(fi, buf, cnt) != cnt) {
302 fprintf(stderr, "ncheck: read error %d\n", bno);
303 for(i=0; i<BSIZE; i++)
304 buf[i] = 0;
305 }
306}
307
308daddr_t
309bmap(i)
310{
311 daddr_t ibuf[NINDIR];
312
313 if(i < NADDR-3)
314 return(iaddr[i]);
315 i -= NADDR-3;
316 if(i > NINDIR) {
317 fprintf(stderr, "ncheck: %u - huge directory\n", ino);
318 return((daddr_t)0);
319 }
320 bread(iaddr[NADDR-3], (char *)ibuf, sizeof(ibuf));
321 return(ibuf[i]);
322}