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