get rid of unused variables
[unix-history] / usr / src / sbin / icheck / icheck.c
CommitLineData
528b0614
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
7#ifndef lint
2785316e 8static char sccsid[] = "@(#)icheck.c 5.5 (Berkeley) %G%";
528b0614
DF
9#endif not lint
10
b42940ce
KM
11/*
12 * icheck
13 */
14#define NB 500
b42940ce 15#define MAXFN 500
c312eebd 16#define MAXNINDIR (MAXBSIZE / sizeof (daddr_t))
b42940ce 17
2785316e
KB
18#include <sys/param.h>
19#include <sys/time.h>
20#include <sys/vnode.h>
21#include <ufs/inode.h>
22#include <ufs/fs.h>
b42940ce
KM
23#ifndef STANDALONE
24#include <stdio.h>
25#endif
b42940ce 26
b42940ce
KM
27union {
28 struct fs sb;
ed4adff6 29 char pad[SBSIZE];
b42940ce
KM
30} sbun;
31#define sblock sbun.sb
32
33union {
34 struct cg cg;
b6407c9d 35 char pad[MAXBSIZE];
b42940ce
KM
36} cgun;
37#define cgrp cgun.cg
38
ed4adff6
KM
39struct dinode itab[MAXBSIZE / sizeof(struct dinode)];
40
b42940ce 41daddr_t blist[NB];
211b1482 42daddr_t fsblist[NB];
b42940ce
KM
43char *bmap;
44
b42940ce
KM
45int mflg;
46int dflg;
47int fi;
48ino_t ino;
49int cginit;
50
51ino_t nrfile;
52ino_t ndfile;
53ino_t nbfile;
54ino_t ncfile;
ea47352d 55ino_t nlfile;
ed4adff6 56ino_t nsfile;
b42940ce
KM
57
58daddr_t nblock;
59daddr_t nfrag;
b42940ce 60daddr_t nindir;
b42940ce
KM
61daddr_t niindir;
62
63daddr_t nffree;
b42940ce
KM
64daddr_t nbfree;
65
66daddr_t ndup;
67
68int nerror;
a66ab591 69long dev_bsize = 1;
b42940ce
KM
70
71long atol();
b42940ce
KM
72#ifndef STANDALONE
73char *malloc();
19f19804 74char *calloc();
b42940ce
KM
75#endif
76
77main(argc, argv)
19f19804
KM
78 int argc;
79 char *argv[];
b42940ce
KM
80{
81 register i;
82 long n;
83
84 blist[0] = -1;
85#ifndef STANDALONE
86 while (--argc) {
87 argv++;
88 if (**argv=='-')
89 switch ((*argv)[1]) {
90 case 'd':
91 dflg++;
92 continue;
93
94 case 'm':
95 mflg++;
96 continue;
97
b42940ce
KM
98 case 'b':
99 for(i=0; i<NB; i++) {
100 n = atol(argv[1]);
101 if(n == 0)
102 break;
103 blist[i] = n;
104 argv++;
105 argc--;
106 }
107 blist[i] = -1;
108 continue;
109
110 default:
111 printf("Bad flag\n");
112 }
113 check(*argv);
114 }
115#else
116 {
117 static char fname[128];
118
119 printf("File: ");
120 gets(fname);
121 check(fname);
122 }
123#endif
124 return(nerror);
125}
126
127check(file)
19f19804 128 char *file;
b42940ce
KM
129{
130 register i, j, c;
131 daddr_t d, cgd, cbase, b;
132 long n;
211b1482 133 char buf[BUFSIZ];
b42940ce 134
ed4adff6 135 fi = open(file, 0);
b42940ce 136 if (fi < 0) {
19f19804 137 perror(file);
b42940ce
KM
138 nerror |= 04;
139 return;
140 }
141 printf("%s:\n", file);
142 nrfile = 0;
143 ndfile = 0;
144 ncfile = 0;
145 nbfile = 0;
ea47352d 146 nlfile = 0;
ed4adff6 147 nsfile = 0;
b42940ce
KM
148
149 nblock = 0;
150 nfrag = 0;
b42940ce 151 nindir = 0;
b42940ce
KM
152 niindir = 0;
153
154 ndup = 0;
155#ifndef STANDALONE
156 sync();
157#endif
b6407c9d
KM
158 getsb(&sblock, file);
159 if (nerror)
b42940ce 160 return;
211b1482
KM
161 for (n=0; blist[n] != -1; n++)
162 fsblist[n] = dbtofsb(&sblock, blist[n]);
b42940ce 163 ino = 0;
19f19804 164 n = roundup(howmany(sblock.fs_size, NBBY), sizeof(short));
b42940ce
KM
165#ifdef STANDALONE
166 bmap = NULL;
167#else
168 bmap = malloc((unsigned)n);
169#endif
170 if (bmap==NULL) {
171 printf("Not enough core; duplicates unchecked\n");
172 dflg++;
b42940ce
KM
173 }
174 ino = 0;
175 cginit = 1;
bf541624
KM
176 if (!dflg) {
177 for (i = 0; i < (unsigned)n; i++)
b42940ce 178 bmap[i] = 0;
bf541624 179 for (c = 0; c < sblock.fs_ncg; c++) {
6994bf5d 180 cgd = cgtod(&sblock, c);
bf541624
KM
181 if (c == 0)
182 d = cgbase(&sblock, c);
183 else
184 d = cgsblock(&sblock, c);
9bd38ba8 185 (void)sprintf(buf, "spare super block %d", c);
bf541624 186 for (; d < cgd; d += sblock.fs_frag)
211b1482 187 chk(d, buf, sblock.fs_bsize);
6994bf5d 188 d = cgimin(&sblock, c);
9bd38ba8 189 (void)sprintf(buf, "cylinder group %d", c);
b42940ce 190 while (cgd < d) {
211b1482 191 chk(cgd, buf, sblock.fs_bsize);
b6407c9d 192 cgd += sblock.fs_frag;
b42940ce 193 }
6994bf5d 194 d = cgdmin(&sblock, c);
211b1482
KM
195 i = INOPB(&sblock);
196 for (; cgd < d; cgd += sblock.fs_frag) {
9bd38ba8 197 (void)sprintf(buf, "inodes %d-%d", ino, ino + i);
211b1482
KM
198 chk(cgd, buf, sblock.fs_bsize);
199 ino += i;
200 }
b42940ce 201 if (c == 0) {
bf541624
KM
202 d += howmany(sblock.fs_cssize, sblock.fs_fsize);
203 for (; cgd < d; cgd++)
204 chk(cgd, "csum", sblock.fs_fsize);
b42940ce
KM
205 }
206 }
207 }
211b1482 208 ino = 0;
b42940ce
KM
209 cginit = 0;
210 for (c = 0; c < sblock.fs_ncg; c++) {
ed4adff6
KM
211 for (i = 0;
212 i < sblock.fs_ipg / INOPF(&sblock);
213 i += sblock.fs_frag) {
214 bread(fsbtodb(&sblock, cgimin(&sblock, c) + i),
215 (char *)itab, sblock.fs_bsize);
216 for (j = 0; j < INOPB(&sblock); j++) {
217 pass1(&itab[j]);
218 ino++;
219 }
b42940ce
KM
220 }
221 }
222 ino = 0;
223#ifndef STANDALONE
224 sync();
225#endif
b42940ce 226 nffree = 0;
b42940ce
KM
227 nbfree = 0;
228 for (c = 0; c < sblock.fs_ncg; c++) {
6994bf5d
KM
229 cbase = cgbase(&sblock, c);
230 bread(fsbtodb(&sblock, cgtod(&sblock, c)), (char *)&cgrp,
b6407c9d 231 sblock.fs_cgsize);
ed4adff6 232 if (!cg_chkmagic(&cgrp))
bf541624 233 printf("cg %d: bad magic number\n", c);
b6407c9d 234 for (b = 0; b < sblock.fs_fpg; b += sblock.fs_frag) {
ed4adff6 235 if (isblock(&sblock, cg_blksfree(&cgrp),
b6407c9d 236 b / sblock.fs_frag)) {
b42940ce 237 nbfree++;
211b1482 238 chk(cbase+b, "free block", sblock.fs_bsize);
b42940ce 239 } else {
b6407c9d 240 for (d = 0; d < sblock.fs_frag; d++)
ed4adff6 241 if (isset(cg_blksfree(&cgrp), b+d)) {
211b1482 242 chk(cbase+b+d, "free frag", sblock.fs_fsize);
b42940ce 243 nffree++;
b42940ce
KM
244 }
245 }
246 }
247 }
248 close(fi);
249#ifndef STANDALONE
250 if (bmap)
251 free(bmap);
252#endif
253
ed4adff6 254 i = nrfile + ndfile + ncfile + nbfile + nlfile + nsfile;
b42940ce 255#ifndef STANDALONE
ed4adff6
KM
256 printf("files %6u (r=%u,d=%u,b=%u,c=%u,sl=%u,sock=%u)\n",
257 i, nrfile, ndfile, nbfile, ncfile, nlfile, nsfile);
b42940ce 258#else
ed4adff6
KM
259 printf("files %u (r=%u,d=%u,b=%u,c=%u,sl=%u,sock=%u)\n",
260 i, nrfile, ndfile, nbfile, ncfile, nlfile, nsfile);
b42940ce 261#endif
b6407c9d 262 n = (nblock + nindir + niindir) * sblock.fs_frag + nfrag;
b42940ce
KM
263#ifdef STANDALONE
264 printf("used %ld (i=%ld,ii=%ld,b=%ld,f=%ld)\n",
265 n, nindir, niindir, nblock, nfrag);
b6407c9d 266 printf("free %ld (b=%ld,f=%ld)\n", nffree + sblock.fs_frag * nbfree,
b42940ce
KM
267 nbfree, nffree);
268#else
269 printf("used %7ld (i=%ld,ii=%ld,b=%ld,f=%ld)\n",
270 n, nindir, niindir, nblock, nfrag);
b6407c9d 271 printf("free %7ld (b=%ld,f=%ld)\n", nffree + sblock.fs_frag * nbfree,
b42940ce
KM
272 nbfree, nffree);
273#endif
274 if(!dflg) {
275 n = 0;
955f6ff8 276 for (d = 0; d < sblock.fs_size; d++)
b6407c9d 277 if(!duped(d, sblock.fs_fsize)) {
b42940ce
KM
278 if(mflg)
279 printf("%ld missing\n", d);
280 n++;
281 }
282 printf("missing%5ld\n", n);
283 }
284}
285
286pass1(ip)
955f6ff8 287 register struct dinode *ip;
b42940ce 288{
b6407c9d
KM
289 daddr_t ind1[MAXNINDIR];
290 daddr_t ind2[MAXNINDIR];
07670f7d
KM
291 daddr_t db, ib;
292 register int i, j, k, siz;
211b1482
KM
293 int lbn;
294 char buf[BUFSIZ];
b42940ce
KM
295
296 i = ip->di_mode & IFMT;
0947395d 297 if(i == 0)
b42940ce 298 return;
b42940ce
KM
299 switch (i) {
300 case IFCHR:
301 ncfile++;
302 return;
303 case IFBLK:
304 nbfile++;
305 return;
306 case IFDIR:
307 ndfile++;
308 break;
309 case IFREG:
310 nrfile++;
311 break;
ed4adff6
KM
312 case IFSOCK:
313 nsfile++;
314 break;
ea47352d
KM
315 case IFLNK:
316 nlfile++;
317 break;
b42940ce
KM
318 default:
319 printf("bad mode %u\n", ino);
320 return;
321 }
955f6ff8
KM
322 for (i = 0; i < NDADDR; i++) {
323 db = ip->di_db[i];
324 if (db == 0)
b42940ce 325 continue;
b6407c9d 326 siz = dblksize(&sblock, ip, i);
9bd38ba8 327 (void)sprintf(buf, "logical data block %d", i);
211b1482 328 chk(db, buf, siz);
b6407c9d 329 if (siz == sblock.fs_bsize)
07670f7d
KM
330 nblock++;
331 else
b6407c9d 332 nfrag += howmany(siz, sblock.fs_fsize);
b42940ce 333 }
955f6ff8
KM
334 for(i = 0; i < NIADDR; i++) {
335 ib = ip->di_ib[i];
211b1482 336 if (ib == 0)
955f6ff8 337 continue;
b6407c9d 338 if (chk(ib, "1st indirect", sblock.fs_bsize))
b42940ce 339 continue;
b6407c9d 340 bread(fsbtodb(&sblock, ib), (char *)ind1, sblock.fs_bsize);
b42940ce 341 nindir++;
b6407c9d 342 for (j = 0; j < NINDIR(&sblock); j++) {
955f6ff8
KM
343 ib = ind1[j];
344 if (ib == 0)
b42940ce 345 continue;
955f6ff8 346 if (i == 0) {
211b1482
KM
347 lbn = NDADDR + j;
348 siz = dblksize(&sblock, ip, lbn);
9bd38ba8 349 (void)sprintf(buf, "logical data block %d", lbn);
211b1482 350 chk(ib, buf, siz);
b6407c9d 351 if (siz == sblock.fs_bsize)
07670f7d
KM
352 nblock++;
353 else
b6407c9d 354 nfrag += howmany(siz, sblock.fs_fsize);
b42940ce
KM
355 continue;
356 }
b6407c9d 357 if (chk(ib, "2nd indirect", sblock.fs_bsize))
955f6ff8 358 continue;
b6407c9d
KM
359 bread(fsbtodb(&sblock, ib), (char *)ind2,
360 sblock.fs_bsize);
b42940ce 361 niindir++;
b6407c9d 362 for (k = 0; k < NINDIR(&sblock); k++) {
955f6ff8
KM
363 ib = ind2[k];
364 if (ib == 0)
b42940ce 365 continue;
211b1482
KM
366 lbn = NDADDR + NINDIR(&sblock) * (i + j) + k;
367 siz = dblksize(&sblock, ip, lbn);
9bd38ba8 368 (void)sprintf(buf, "logical data block %d", lbn);
211b1482 369 chk(ib, buf, siz);
b6407c9d 370 if (siz == sblock.fs_bsize)
07670f7d
KM
371 nblock++;
372 else
b6407c9d 373 nfrag += howmany(siz, sblock.fs_fsize);
b42940ce 374 }
b42940ce
KM
375 }
376 }
377}
378
07670f7d 379chk(bno, s, size)
955f6ff8
KM
380 daddr_t bno;
381 char *s;
07670f7d 382 int size;
b42940ce
KM
383{
384 register n, cg;
3352e84a 385 int frags;
b42940ce 386
6994bf5d 387 cg = dtog(&sblock, bno);
bf541624 388 if (cginit == 0 && bno >= sblock.fs_frag * sblock.fs_size) {
b42940ce
KM
389 printf("%ld bad; inode=%u, class=%s\n", bno, ino, s);
390 return(1);
391 }
211b1482
KM
392 frags = numfrags(&sblock, size);
393 if (frags == sblock.fs_frag) {
07670f7d
KM
394 if (duped(bno, size)) {
395 printf("%ld dup block; inode=%u, class=%s\n",
396 bno, ino, s);
b6407c9d 397 ndup += sblock.fs_frag;
07670f7d
KM
398 }
399 } else {
3352e84a 400 for (n = 0; n < frags; n++) {
b6407c9d 401 if (duped(bno + n, sblock.fs_fsize)) {
07670f7d
KM
402 printf("%ld dup frag; inode=%u, class=%s\n",
403 bno, ino, s);
404 ndup++;
405 }
406 }
b42940ce
KM
407 }
408 for (n=0; blist[n] != -1; n++)
211b1482
KM
409 if (fsblist[n] >= bno && fsblist[n] < bno + frags)
410 printf("%ld arg; frag %d of %d, inode=%u, class=%s\n",
411 blist[n], fsblist[n] - bno, frags, ino, s);
b42940ce
KM
412 return(0);
413}
414
07670f7d 415duped(bno, size)
955f6ff8 416 daddr_t bno;
07670f7d 417 int size;
b42940ce 418{
b42940ce
KM
419 if(dflg)
420 return(0);
b6407c9d 421 if (size != sblock.fs_fsize && size != sblock.fs_bsize)
07670f7d 422 printf("bad size %d to duped\n", size);
b6407c9d 423 if (size == sblock.fs_fsize) {
955f6ff8
KM
424 if (isset(bmap, bno))
425 return(1);
426 setbit(bmap, bno);
427 return (0);
428 }
b6407c9d 429 if (bno % sblock.fs_frag != 0)
955f6ff8 430 printf("bad bno %d to duped\n", bno);
b6407c9d 431 if (isblock(&sblock, bmap, bno/sblock.fs_frag))
955f6ff8 432 return (1);
b6407c9d 433 setblock(&sblock, bmap, bno/sblock.fs_frag);
b42940ce
KM
434 return(0);
435}
436
b6407c9d
KM
437getsb(fs, file)
438 register struct fs *fs;
439 char *file;
440{
bf541624 441 int i, j, size;
b6407c9d 442
a66ab591 443 if (bread(SBOFF, fs, SBSIZE)) {
b6407c9d
KM
444 printf("bad super block");
445 perror(file);
446 nerror |= 04;
447 return;
448 }
449 if (fs->fs_magic != FS_MAGIC) {
450 printf("%s: bad magic number\n", file);
451 nerror |= 04;
452 return;
453 }
a66ab591 454 dev_bsize = fs->fs_fsize / fsbtodb(fs, 1);
bf541624
KM
455 for (i = 0, j = 0; i < sblock.fs_cssize; i += sblock.fs_bsize, j++) {
456 size = sblock.fs_cssize - i < sblock.fs_bsize ?
457 sblock.fs_cssize - i : sblock.fs_bsize;
458 sblock.fs_csp[j] = (struct csum *)calloc(1, size);
459 bread(fsbtodb(fs, fs->fs_csaddr + (j * fs->fs_frag)),
460 (char *)fs->fs_csp[j], size);
b6407c9d
KM
461 }
462}
463
b42940ce 464bread(bno, buf, cnt)
955f6ff8
KM
465 daddr_t bno;
466 char *buf;
b42940ce
KM
467{
468 register i;
469
a66ab591 470 lseek(fi, bno * dev_bsize, 0);
b42940ce 471 if ((i = read(fi, buf, cnt)) != cnt) {
b6407c9d 472 for(i=0; i<sblock.fs_bsize; i++)
b42940ce 473 buf[i] = 0;
b6407c9d
KM
474 return (1);
475 }
476 return (0);
477}
478
479/*
3969097b 480 * check if a block is available
b6407c9d 481 */
b6407c9d
KM
482isblock(fs, cp, h)
483 struct fs *fs;
484 unsigned char *cp;
485 int h;
486{
487 unsigned char mask;
488
489 switch (fs->fs_frag) {
490 case 8:
491 return (cp[h] == 0xff);
492 case 4:
493 mask = 0x0f << ((h & 0x1) << 2);
494 return ((cp[h >> 1] & mask) == mask);
495 case 2:
496 mask = 0x03 << ((h & 0x3) << 1);
497 return ((cp[h >> 2] & mask) == mask);
498 case 1:
499 mask = 0x01 << (h & 0x7);
500 return ((cp[h >> 3] & mask) == mask);
501 default:
3969097b
KM
502#ifdef STANDALONE
503 printf("isblock bad fs_frag %d\n", fs->fs_frag);
504#else
b6407c9d 505 fprintf(stderr, "isblock bad fs_frag %d\n", fs->fs_frag);
3969097b
KM
506#endif
507 return;
508 }
509}
510
3969097b
KM
511/*
512 * put a block into the map
513 */
b6407c9d
KM
514setblock(fs, cp, h)
515 struct fs *fs;
516 unsigned char *cp;
517 int h;
518{
519 switch (fs->fs_frag) {
520 case 8:
521 cp[h] = 0xff;
522 return;
523 case 4:
524 cp[h >> 1] |= (0x0f << ((h & 0x1) << 2));
525 return;
526 case 2:
527 cp[h >> 2] |= (0x03 << ((h & 0x3) << 1));
528 return;
529 case 1:
530 cp[h >> 3] |= (0x01 << (h & 0x7));
531 return;
532 default:
3969097b
KM
533#ifdef STANDALONE
534 printf("setblock bad fs_frag %d\n", fs->fs_frag);
535#else
b6407c9d 536 fprintf(stderr, "setblock bad fs_frag %d\n", fs->fs_frag);
3969097b 537#endif
b6407c9d 538 return;
b42940ce
KM
539 }
540}