BSD 4_3_Tahoe release
[unix-history] / usr / src / etc / ncheck.c
index bf4439a..4e92589 100644 (file)
@@ -1,12 +1,24 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.  The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ */
+
 #ifndef lint
 #ifndef lint
-static char *sccsid = "@(#)ncheck.c    2.4 (Berkeley) 9/22/83";
-#endif
+char copyright[] =
+"@(#) Copyright (c) 1980 Regents of the University of California.\n\
+ All rights reserved.\n";
+#endif not lint
+
+#ifndef lint
+static char sccsid[] = "@(#)ncheck.c   5.7 (Berkeley) 5/2/88";
+#endif not lint
+
 /*
  * ncheck -- obtain file names from reading filesystem
  */
 
 #define        NB              500
 /*
  * ncheck -- obtain file names from reading filesystem
  */
 
 #define        NB              500
-#define        HSIZE           5651
 #define        MAXNINDIR       (MAXBSIZE / sizeof (daddr_t))
 
 #include <sys/param.h>
 #define        MAXNINDIR       (MAXBSIZE / sizeof (daddr_t))
 
 #include <sys/param.h>
@@ -16,7 +28,7 @@ static        char *sccsid = "@(#)ncheck.c    2.4 (Berkeley) 9/22/83";
 #include <stdio.h>
 
 struct fs      sblock;
 #include <stdio.h>
 
 struct fs      sblock;
-struct dinode  itab[MAXIPG];
+struct dinode  itab[MAXBSIZE/sizeof(struct dinode)];
 struct         dinode  *gip;
 struct ilist {
        ino_t   ino;
 struct         dinode  *gip;
 struct ilist {
        ino_t   ino;
@@ -29,8 +41,9 @@ struct        htab
        ino_t   h_ino;
        ino_t   h_pino;
        char    *h_name;
        ino_t   h_ino;
        ino_t   h_pino;
        char    *h_name;
-} htab[HSIZE];
-char strngtab[30 * HSIZE];
+} *htab;
+char *strngtab;
+long hsize;
 int strngloc;
 
 struct dirstuff {
 int strngloc;
 
 struct dirstuff {
@@ -47,6 +60,7 @@ int   fi;
 ino_t  ino;
 int    nhent;
 int    nxfile;
 ino_t  ino;
 int    nhent;
 int    nxfile;
+long   dev_bsize = 1;
 
 int    nerror;
 daddr_t        bmap();
 
 int    nerror;
 daddr_t        bmap();
@@ -113,45 +127,66 @@ check(file)
        nhent = 0;
        printf("%s:\n", file);
        sync();
        nhent = 0;
        printf("%s:\n", file);
        sync();
-       bread(SBLOCK, (char *)&sblock, SBSIZE);
+       bread(SBOFF, (char *)&sblock, SBSIZE);
        if (sblock.fs_magic != FS_MAGIC) {
                printf("%s: not a file system\n", file);
                nerror++;
                return;
        }
        if (sblock.fs_magic != FS_MAGIC) {
                printf("%s: not a file system\n", file);
                nerror++;
                return;
        }
+       dev_bsize = sblock.fs_fsize / fsbtodb(&sblock, 1);
+       hsize = sblock.fs_ipg * sblock.fs_ncg - sblock.fs_cstotal.cs_nifree + 1;
+       htab = (struct htab *)malloc(hsize * sizeof(struct htab));
+       strngtab = (char *)malloc(30 * hsize);
+       if (htab == 0 || strngtab == 0) {
+               printf("not enough memory to allocate tables\n");
+               nerror++;
+               return;
+       }
        ino = 0;
        for (c = 0; c < sblock.fs_ncg; c++) {
        ino = 0;
        for (c = 0; c < sblock.fs_ncg; c++) {
-               bread(fsbtodb(&sblock, cgimin(&sblock, c)), (char *)itab,
-                   sblock.fs_ipg * sizeof (struct dinode));
-               for(j = 0; j < sblock.fs_ipg; j++) {
-                       if (itab[j].di_mode != 0)
-                               pass1(&itab[j]);
-                       ino++;
+               for (i = 0;
+                    i < sblock.fs_ipg / INOPF(&sblock);
+                    i += sblock.fs_frag) {
+                       bread(fsbtodb(&sblock, cgimin(&sblock, c) + i),
+                           (char *)itab, sblock.fs_bsize);
+                       for (j = 0; j < INOPB(&sblock); j++) {
+                               if (itab[j].di_mode != 0)
+                                       pass1(&itab[j]);
+                               ino++;
+                       }
                }
        }
        ilist[nxfile+1].ino = 0;
        ino = 0;
        for (c = 0; c < sblock.fs_ncg; c++) {
                }
        }
        ilist[nxfile+1].ino = 0;
        ino = 0;
        for (c = 0; c < sblock.fs_ncg; c++) {
-               bread(fsbtodb(&sblock, cgimin(&sblock, c)), (char *)itab,
-                   sblock.fs_ipg * sizeof (struct dinode));
-               for(j = 0; j < sblock.fs_ipg; j++) {
-                       if (itab[j].di_mode != 0)
-                               pass2(&itab[j]);
-                       ino++;
+               for (i = 0;
+                    i < sblock.fs_ipg / INOPF(&sblock);
+                    i += sblock.fs_frag) {
+                       bread(fsbtodb(&sblock, cgimin(&sblock, c) + i),
+                           (char *)itab, sblock.fs_bsize);
+                       for (j = 0; j < INOPB(&sblock); j++) {
+                               if (itab[j].di_mode != 0)
+                                       pass2(&itab[j]);
+                               ino++;
+                       }
                }
        }
        ino = 0;
        for (c = 0; c < sblock.fs_ncg; c++) {
                }
        }
        ino = 0;
        for (c = 0; c < sblock.fs_ncg; c++) {
-               bread(fsbtodb(&sblock, cgimin(&sblock, c)), (char *)itab,
-                   sblock.fs_ipg * sizeof (struct dinode));
-               for(j = 0; j < sblock.fs_ipg; j++) {
-                       if (itab[j].di_mode != 0)
-                               pass3(&itab[j]);
-                       ino++;
+               for (i = 0;
+                    i < sblock.fs_ipg / INOPF(&sblock);
+                    i += sblock.fs_frag) {
+                       bread(fsbtodb(&sblock, cgimin(&sblock, c) + i),
+                           (char *)itab, sblock.fs_bsize);
+                       for (j = 0; j < INOPB(&sblock); j++) {
+                               if (itab[j].di_mode != 0)
+                                       pass3(&itab[j]);
+                               ino++;
+                       }
                }
        }
        close(fi);
                }
        }
        close(fi);
-       for (i = 0; i < HSIZE; i++)
+       for (i = 0; i < hsize; i++)
                htab[i].h_ino = 0;
        for (i = iflg; i < NB; i++)
                ilist[i].ino = 0;
                htab[i].h_ino = 0;
        for (i = iflg; i < NB; i++)
                ilist[i].ino = 0;
@@ -260,7 +295,8 @@ readdir(dirp)
        for(;;) {
                if (dirp->loc >= dirp->ip->di_size)
                        return NULL;
        for(;;) {
                if (dirp->loc >= dirp->ip->di_size)
                        return NULL;
-               if ((lbn = lblkno(&sblock, dirp->loc)) == 0) {
+               if (blkoff(&sblock, dirp->loc) == 0) {
+                       lbn = lblkno(&sblock, dirp->loc);
                        d = bmap(lbn);
                        if(d == 0)
                                return NULL;
                        d = bmap(lbn);
                        if(d == 0)
                                return NULL;
@@ -314,16 +350,16 @@ lookup(i, ef)
 {
        register struct htab *hp;
 
 {
        register struct htab *hp;
 
-       for (hp = &htab[i%HSIZE]; hp->h_ino;) {
+       for (hp = &htab[i%hsize]; hp->h_ino;) {
                if (hp->h_ino==i)
                        return(hp);
                if (hp->h_ino==i)
                        return(hp);
-               if (++hp >= &htab[HSIZE])
+               if (++hp >= &htab[hsize])
                        hp = htab;
        }
        if (ef==0)
                return(0);
                        hp = htab;
        }
        if (ef==0)
                return(0);
-       if (++nhent >= HSIZE) {
-               fprintf(stderr, "ncheck: out of core-- increase HSIZE\n");
+       if (++nhent >= hsize) {
+               fprintf(stderr, "ncheck: hsize of %d is too small\n", hsize);
                exit(1);
        }
        hp->h_ino = i;
                exit(1);
        }
        hp->h_ino = i;
@@ -337,7 +373,7 @@ bread(bno, buf, cnt)
 {
        register i;
 
 {
        register i;
 
-       lseek(fi, bno * DEV_BSIZE, 0);
+       lseek(fi, bno * dev_bsize, 0);
        if (read(fi, buf, cnt) != cnt) {
                fprintf(stderr, "ncheck: read error %d\n", bno);
                for(i=0; i < cnt; i++)
        if (read(fi, buf, cnt) != cnt) {
                fprintf(stderr, "ncheck: read error %d\n", bno);
                for(i=0; i < cnt; i++)
@@ -345,19 +381,74 @@ bread(bno, buf, cnt)
        }
 }
 
        }
 }
 
+/*
+ * Swiped from standalone sys.c.
+ */
+#define        NBUFS   4
+char   b[NBUFS][MAXBSIZE];
+daddr_t        blknos[NBUFS];
+
 daddr_t
 daddr_t
-bmap(i)
-       int i;
+bmap(bn)
+       register daddr_t bn;
 {
 {
-       daddr_t ibuf[MAXNINDIR];
-
-       if(i < NDADDR)
-               return(gip->di_db[i]);
-       i -= NDADDR;
-       if(i > NINDIR(&sblock)) {
-               fprintf(stderr, "ncheck: %u - huge directory\n", ino);
-               return((daddr_t)0);
+       register int j;
+       int i, sh;
+       daddr_t nb, *bap;
+
+       if (bn < 0) {
+               fprintf(stderr, "ncheck: bn %d negative\n", bn);
+               return ((daddr_t)0);
+       }
+
+       /*
+        * blocks 0..NDADDR are direct blocks
+        */
+       if(bn < NDADDR)
+               return(gip->di_db[bn]);
+
+       /*
+        * addresses NIADDR have single and double indirect blocks.
+        * the first step is to determine how many levels of indirection.
+        */
+       sh = 1;
+       bn -= NDADDR;
+       for (j = NIADDR; j > 0; j--) {
+               sh *= NINDIR(&sblock);
+               if (bn < sh)
+                       break;
+               bn -= sh;
+       }
+       if (j == 0) {
+               printf("ncheck: bn %ld ovf, ino %u\n", bn, ino);
+               return ((daddr_t)0);
+       }
+
+       /*
+        * fetch the first indirect block address from the inode
+        */
+       nb = gip->di_ib[NIADDR - j];
+       if (nb == 0) {
+               printf("ncheck: bn %ld void1, ino %u\n", bn, ino);
+               return ((daddr_t)0);
+       }
+
+       /*
+        * fetch through the indirect blocks
+        */
+       for (; j <= NIADDR; j++) {
+               if (blknos[j] != nb) {
+                       bread(fsbtodb(&sblock, nb), b[j], sblock.fs_bsize);
+                       blknos[j] = nb;
+               }
+               bap = (daddr_t *)b[j];
+               sh /= NINDIR(&sblock);
+               i = (bn / sh) % NINDIR(&sblock);
+               nb = bap[i];
+               if(nb == 0) {
+                       printf("ncheck: bn %ld void2, ino %u\n", bn, ino);
+                       return ((daddr_t)0);
+               }
        }
        }
-       bread(fsbtodb(&sblock, gip->di_ib[i]), (char *)ibuf, sizeof(ibuf));
-       return(ibuf[i]);
+       return (nb);
 }
 }