1: #if !defined(lint) && defined(DOSCCS) 2: char *sccsid = "@(#)icheck.c 2.5"; 3: #endif 4: 5: #include <sys/param.h> 6: 7: #ifdef STANDALONE 8: #define NI 4 9: #else 10: #define NI 8 11: #endif 12: 13: #define NB 10 14: #define BITS 8 15: #define MAXFN 500 16: 17: #ifndef STANDALONE 18: #include <stdio.h> 19: #endif !STANDALONE 20: #include <sys/inode.h> 21: #include <sys/fs.h> 22: 23: struct fs sblock; 24: struct dinode itab[INOPB*NI]; 25: daddr_t blist[NB]; 26: char *bmap; 27: 28: int sflg; 29: int mflg; 30: int dflg; 31: int fi; 32: ino_t ino; 33: 34: ino_t nrfile; 35: ino_t nsfile; 36: ino_t ndfile; 37: ino_t nbfile; 38: ino_t ncfile; 39: ino_t nlfile; 40: 41: daddr_t ndirect; 42: daddr_t nindir; 43: daddr_t niindir; 44: daddr_t niiindir; 45: daddr_t nfree; 46: daddr_t ndup; 47: 48: int nerror; 49: 50: long atol(); 51: daddr_t alloc(); 52: 53: #ifdef STANDALONE 54: char module[] = "Icheck"; 55: #define STDBUFSIZ 16000 /* Small enough for 407 */ 56: char stdbuf[STDBUFSIZ]; 57: #else !STANDALONE 58: char *malloc(); 59: #endif STANDALONE 60: 61: main(argc, argv) 62: char *argv[]; 63: { 64: register i; 65: long n; 66: 67: blist[0] = -1; 68: #ifndef STANDALONE 69: while (--argc) { 70: argv++; 71: if (**argv=='-') 72: switch ((*argv)[1]) { 73: case 'd': 74: dflg++; 75: continue; 76: 77: 78: case 'm': 79: mflg++; 80: continue; 81: 82: case 's': 83: sflg++; 84: continue; 85: 86: case 'b': 87: for(i=0; i<NB; i++) { 88: n = atol(argv[1]); 89: if(n == 0) 90: break; 91: blist[i] = n; 92: argv++; 93: argc--; 94: } 95: blist[i] = -1; 96: continue; 97: 98: default: 99: printf("Bad flag\n"); 100: } 101: check(*argv); 102: } 103: #else 104: { 105: static char fname[100]; 106: printf("%s\n",module); 107: printf("File: "); 108: gets(fname); 109: check(fname); 110: } 111: #endif 112: return(nerror); 113: } 114: 115: check(file) 116: char *file; 117: { 118: register i, j; 119: ino_t mino; 120: daddr_t d; 121: long n; 122: 123: fi = open(file, sflg?2:0); 124: if (fi < 0) { 125: printf("cannot open %s\n", file); 126: nerror |= 04; 127: return; 128: } 129: printf("%s:\n", file); 130: nrfile = 0; 131: nsfile = 0; 132: ndfile = 0; 133: ncfile = 0; 134: nbfile = 0; 135: nlfile = 0; 136: 137: ndirect = 0; 138: nindir = 0; 139: niindir = 0; 140: niiindir = 0; 141: 142: ndup = 0; 143: #ifndef STANDALONE 144: sync(); 145: #endif 146: bread((daddr_t)SBLOCK, (char *)&sblock, sizeof(sblock)); 147: mino = (sblock.fs_isize-2) * INOPB; 148: ino = 0; 149: n = (sblock.fs_fsize - sblock.fs_isize + BITS-1) / BITS; 150: if (n != (unsigned)n) { 151: printf("Check fsize and isize: %D, %u\n", 152: sblock.fs_fsize, sblock.fs_isize); 153: } 154: #ifdef STANDALONE 155: if((unsigned)n > STDBUFSIZ) 156: bmap = NULL; 157: else 158: bmap = stdbuf; 159: #else 160: bmap = malloc((unsigned)n); 161: #endif 162: if (bmap==NULL) { 163: printf("Not enough core; duplicates unchecked\n"); 164: dflg++; 165: sflg = 0; 166: } 167: if(!dflg) 168: bzero(bmap, (u_short) n); 169: for(i=2;; i+=NI) { 170: if(ino >= mino) 171: break; 172: bread((daddr_t)i, (char *)itab, sizeof(itab)); 173: for(j=0; j<INOPB*NI; j++) { 174: if(ino >= mino) 175: break; 176: ino++; 177: pass1(&itab[j]); 178: } 179: } 180: ino = 0; 181: #ifndef STANDALONE 182: sync(); 183: #endif 184: bread((daddr_t)SBLOCK, (char *)&sblock, sizeof(sblock)); 185: if (sflg) { 186: makefree(); 187: close(fi); 188: #ifndef STANDALONE 189: if (bmap) 190: free(bmap); 191: #endif 192: return; 193: } 194: nfree = 0; 195: while(n = alloc()) { 196: if (chk(n, "free")) 197: break; 198: nfree++; 199: } 200: close(fi); 201: #ifndef STANDALONE 202: if (bmap) 203: free(bmap); 204: #endif 205: 206: i = nrfile + ndfile + ncfile + nbfile; 207: i += nlfile; 208: printf("files %u (r=%u,d=%u,b=%u,c=%u,l=%u,s=%u)\n", 209: i, nrfile, ndfile, nbfile, ncfile, nlfile,nsfile); 210: n = ndirect + nindir + niindir + niindir; 211: printf("used %D (i=%D,ii=%D,iii=%D,d=%D)\n", 212: n, nindir, niindir, niiindir, ndirect); 213: printf("free %D\n", nfree); 214: if(!dflg) { 215: n = 0; 216: for(d=sblock.fs_isize; d<sblock.fs_fsize; d++) 217: if(!duped(d)) { 218: if(mflg) 219: printf("%D missing\n", d); 220: n++; 221: } 222: printf("missing %D\n", n); 223: } 224: } 225: 226: pass1(ip) 227: register struct dinode *ip; 228: { 229: daddr_t ind1[NINDIR]; 230: daddr_t ind2[NINDIR]; 231: daddr_t ind3[NINDIR]; 232: register i, j; 233: int k, l; 234: 235: i = ip->di_mode & IFMT; 236: if(i == 0) { 237: sblock.fs_tinode++; 238: return; 239: } 240: if(i == IFCHR) { 241: ncfile++; 242: return; 243: } 244: if(i == IFBLK) { 245: nbfile++; 246: return; 247: } 248: if(i == IFLNK) 249: nlfile++; 250: else if(i == IFDIR) 251: ndfile++; 252: else if(i == IFREG) 253: nrfile++; 254: else if(i == IFSOCK) 255: nsfile++; 256: else { 257: printf("bad mode %u\n", ino); 258: return; 259: } 260: for(i=0; i<NADDR; i++) { 261: if(ip->di_addr[i] == 0) 262: continue; 263: if(i < NADDR-3) { 264: ndirect++; 265: chk(ip->di_addr[i], "data (small)"); 266: continue; 267: } 268: nindir++; 269: if (chk(ip->di_addr[i], "1st indirect")) 270: continue; 271: bread(ip->di_addr[i], (char *)ind1, DEV_BSIZE); 272: for(j=0; j<NINDIR; j++) { 273: if(ind1[j] == 0) 274: continue; 275: if(i == NADDR-3) { 276: ndirect++; 277: chk(ind1[j], "data (large)"); 278: continue; 279: } 280: niindir++; 281: if(chk(ind1[j], "2nd indirect")) 282: continue; 283: bread(ind1[j], (char *)ind2, DEV_BSIZE); 284: for(k=0; k<NINDIR; k++) { 285: if(ind2[k] == 0) 286: continue; 287: if(i == NADDR-2) { 288: ndirect++; 289: chk(ind2[k], "data (huge)"); 290: continue; 291: } 292: niiindir++; 293: if(chk(ind2[k], "3rd indirect")) 294: continue; 295: bread(ind2[k], (char *)ind3, DEV_BSIZE); 296: for(l=0; l<NINDIR; l++) 297: if(ind3[l]) { 298: ndirect++; 299: chk(ind3[l], "data (garg)"); 300: } 301: } 302: } 303: } 304: } 305: 306: chk(bno, s) 307: daddr_t bno; 308: char *s; 309: { 310: register n; 311: 312: if (bno<sblock.fs_isize || bno>=sblock.fs_fsize) { 313: printf("%D bad; inode=%u, class=%s\n", bno, ino, s); 314: return(1); 315: } 316: if(duped(bno)) { 317: printf("%D dup; inode=%u, class=%s\n", bno, ino, s); 318: ndup++; 319: } 320: for (n=0; blist[n] != -1; n++) 321: if (bno == blist[n]) 322: printf("%D arg; inode=%u, class=%s\n", bno, ino, s); 323: return(0); 324: } 325: 326: duped(bno) 327: daddr_t bno; 328: { 329: daddr_t d; 330: register m, n; 331: 332: if(dflg) 333: return(0); 334: d = bno - sblock.fs_isize; 335: m = 1 << (d%BITS); 336: n = (d/BITS); 337: if(bmap[n] & m) 338: return(1); 339: bmap[n] |= m; 340: return(0); 341: } 342: 343: daddr_t 344: alloc() 345: { 346: int i; 347: daddr_t bno; 348: union { 349: char data[DEV_BSIZE]; 350: struct fblk fb; 351: } buf; 352: 353: sblock.fs_tfree--; 354: if (sblock.fs_nfree<=0) 355: return(0); 356: if (sblock.fs_nfree>NICFREE) { 357: printf("Bad free list, s.b. count = %d\n", sblock.fs_nfree); 358: return(0); 359: } 360: bno = sblock.fs_free[--sblock.fs_nfree]; 361: sblock.fs_free[sblock.fs_nfree] = (daddr_t)0; 362: if(bno == 0) 363: return(bno); 364: if(sblock.fs_nfree <= 0) { 365: bread(bno, buf.data, DEV_BSIZE); 366: sblock.fs_nfree = buf.fb.df_nfree; 367: if (sblock.fs_nfree<0 || sblock.fs_nfree>NICFREE) { 368: printf("Bad free list, entry count of block %D = %d\n", 369: bno, sblock.fs_nfree); 370: sblock.fs_nfree = 0; 371: return(0); 372: } 373: for(i=0; i<NICFREE; i++) 374: sblock.fs_free[i] = buf.fb.df_free[i]; 375: } 376: return(bno); 377: } 378: 379: bfree(bno) 380: daddr_t bno; 381: { 382: union { 383: char data[DEV_BSIZE]; 384: struct fblk fb; 385: } buf; 386: register int i; 387: 388: sblock.fs_tfree++; 389: if(sblock.fs_nfree >= NICFREE) { 390: bzero(buf.data, DEV_BSIZE); 391: buf.fb.df_nfree = sblock.fs_nfree; 392: for(i=0; i<NICFREE; i++) 393: buf.fb.df_free[i] = sblock.fs_free[i]; 394: bwrite(bno, buf.data); 395: sblock.fs_nfree = 0; 396: } 397: sblock.fs_free[sblock.fs_nfree] = bno; 398: sblock.fs_nfree++; 399: } 400: 401: bread(bno, buf, cnt) 402: daddr_t bno; 403: char *buf; 404: { 405: 406: lseek(fi, bno*DEV_BSIZE, 0); 407: if (read(fi, buf, cnt) != cnt) { 408: printf("read error %D\n", bno); 409: if (sflg) { 410: printf("No update\n"); 411: sflg = 0; 412: } 413: bzero(buf, DEV_BSIZE); 414: } 415: } 416: 417: bwrite(bno, buf) 418: daddr_t bno; 419: char *buf; 420: { 421: 422: lseek(fi, bno*DEV_BSIZE, 0); 423: if (write(fi, buf, DEV_BSIZE) != DEV_BSIZE) 424: printf("write error %D\n", bno); 425: } 426: 427: makefree() 428: { 429: char flg[MAXFN]; 430: int adr[MAXFN]; 431: register i, j; 432: daddr_t f, d; 433: int m, n; 434: 435: n = sblock.fs_cyl; 436: if(n <= 0 || n > MAXFN) 437: n = MAXFN; 438: sblock.fs_cyl = n; 439: m = sblock.fs_step; 440: if(m <= 0 || m > sblock.fs_cyl) 441: m = 3; 442: sblock.fs_step = m; 443: 444: bzero(flg, n); 445: i = 0; 446: for(j=0; j<n; j++) { 447: while(flg[i]) 448: i = (i+1)%n; 449: adr[j] = i+1; 450: flg[i]++; 451: i = (i+m)%n; 452: } 453: 454: sblock.fs_nfree = 0; 455: sblock.fs_ninode = 0; 456: sblock.fs_flock = 0; 457: sblock.fs_ilock = 0; 458: sblock.fs_fmod = 0; 459: sblock.fs_ronly = 0; 460: #ifndef STANDALONE 461: time(&sblock.fs_time); 462: #endif 463: sblock.fs_tfree = 0; 464: sblock.fs_tinode = 0; 465: 466: bfree((daddr_t)0); 467: d = sblock.fs_fsize-1; 468: while(d%sblock.fs_cyl) 469: d++; 470: for(; d > 0; d -= sblock.fs_cyl) 471: for(i=0; i<sblock.fs_cyl; i++) { 472: f = d - adr[i]; 473: if(f < sblock.fs_fsize && f >= sblock.fs_isize) 474: if(!duped(f)) 475: bfree(f); 476: } 477: bwrite((daddr_t)1, (char *)&sblock); 478: #ifndef STANDALONE 479: sync(); 480: #endif 481: return; 482: }