home *** CD-ROM | disk | FTP | other *** search
/ minnie.tuhs.org / unixen.tar / unixen / PDP-11 / Trees / V7 / usr / src / cmd / icheck.c < prev    next >
Encoding:
C/C++ Source or Header  |  1979-01-10  |  7.6 KB  |  476 lines

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