arbitrarily cut off searching around orphaned directory loops
[unix-history] / usr / src / sbin / dump / traverse.c
index 9468713..27b4db6 100644 (file)
@@ -1,25 +1,18 @@
-static char *sccsid = "@(#)traverse.c  1.2 (Berkeley) %G%";
-#include "dump.h"
+static char *sccsid = "@(#)traverse.c  1.14 (Berkeley) %G%";
 
 
-struct fs      sblock;
+#include "dump.h"
 
 pass(fn, map)
        int (*fn)();
 
 pass(fn, map)
        int (*fn)();
-       short *map;
+       char *map;
 {
        struct dinode *dp;
        int bits;
        ino_t maxino;
 
 {
        struct dinode *dp;
        int bits;
        ino_t maxino;
 
-       sync();
-       bread(SBLOCK, &sblock, sizeof sblock);
-       if (sblock.fs_magic != FS_MAGIC) {
-               msg("bad sblock magic number\n");
-               dumpabort();
-       }
-       maxino = sblock.fs_ipg * sblock.fs_ncg;
+       maxino = sblock->fs_ipg * sblock->fs_ncg - 1;
        for (ino = 0; ino < maxino; ) {
        for (ino = 0; ino < maxino; ) {
-               if((ino % MLEN) == 0) {
+               if((ino % NBBY) == 0) {
                        bits = ~0;
                        if(map != NULL)
                                bits = *map++;
                        bits = ~0;
                        if(map != NULL)
                                bits = *map++;
@@ -33,51 +26,8 @@ pass(fn, map)
        }
 }
 
        }
 }
 
-icat(dp, fn1, fn2)
-       register struct dinode  *dp;
-       int (*fn1)(), (*fn2)();
-{
-       register int i;
-
-       (*fn2)(dp->di_db, NDADDR);
-       for (i = 0; i < NDADDR; i++) {
-               if (dp->di_db[i] != 0)
-                       (*fn1)(dp->di_db[i]);
-       }
-       for (i = 0; i < NIADDR; i++) {
-               if (dp->di_ib[i] != 0)
-                       indir(dp->di_ib[i], fn1, fn2, i);
-       }
-}
-
-indir(d, fn1, fn2, n)
-daddr_t d;
-int (*fn1)(), (*fn2)();
-{
-       register i;
-       daddr_t idblk[NINDIR];
-
-       bread(d, (char *)idblk, sizeof(idblk));
-       if(n <= 0) {
-               spcl.c_type = TS_ADDR;
-               (*fn2)(idblk, NINDIR);
-               for(i=0; i<NINDIR; i++) {
-                       d = idblk[i];
-                       if(d != 0)
-                               (*fn1)(d);
-               }
-       } else {
-               n--;
-               for(i=0; i<NINDIR; i++) {
-                       d = idblk[i];
-                       if(d != 0)
-                               indir(d, fn1, fn2, n);
-               }
-       }
-}
-
 mark(ip)
 mark(ip)
-struct dinode *ip;
+       struct dinode *ip;
 {
        register f;
 
 {
        register f;
 
@@ -87,10 +37,10 @@ struct dinode *ip;
        BIS(ino, clrmap);
        if(f == IFDIR)
                BIS(ino, dirmap);
        BIS(ino, clrmap);
        if(f == IFDIR)
                BIS(ino, dirmap);
-       if(ip->di_mtime >= spcl.c_ddate ||
-          ip->di_ctime >= spcl.c_ddate) {
+       if ((ip->di_mtime >= spcl.c_ddate || ip->di_ctime >= spcl.c_ddate) &&
+           !BIT(ino, nodmap)) {
                BIS(ino, nodmap);
                BIS(ino, nodmap);
-               if (f != IFREG){
+               if (f != IFREG && f != IFDIR && f != IFLNK) {
                        esize += 1;
                        return;
                }
                        esize += 1;
                        return;
                }
@@ -99,28 +49,67 @@ struct dinode *ip;
 }
 
 add(ip)
 }
 
 add(ip)
-struct dinode *ip;
+       register struct dinode  *ip;
 {
 {
+       register int i;
+       long filesize;
 
        if(BIT(ino, nodmap))
                return;
        nsubdir = 0;
        dadded = 0;
 
        if(BIT(ino, nodmap))
                return;
        nsubdir = 0;
        dadded = 0;
-       icat(ip, dsrch, nullf);
+       filesize = ip->di_size;
+       for (i = 0; i < NDADDR; i++) {
+               if (ip->di_db[i] != 0)
+                       dsrch(ip->di_db[i], dblksize(sblock, ip, i), filesize);
+               filesize -= sblock->fs_bsize;
+       }
+       for (i = 0; i < NIADDR; i++) {
+               if (ip->di_ib[i] != 0)
+                       indir(ip->di_ib[i], i, &filesize);
+       }
        if(dadded) {
        if(dadded) {
-               BIS(ino, nodmap);
-               est(ip);
                nadded++;
                nadded++;
+               if (!BIT(ino, nodmap)) {
+                       BIS(ino, nodmap);
+                       est(ip);
+               }
        }
        if(nsubdir == 0)
                if(!BIT(ino, nodmap))
                        BIC(ino, dirmap);
 }
 
        }
        if(nsubdir == 0)
                if(!BIT(ino, nodmap))
                        BIC(ino, dirmap);
 }
 
-dump(ip)
-struct dinode *ip;
+indir(d, n, filesize)
+       daddr_t d;
+       int n, *filesize;
 {
        register i;
 {
        register i;
+       daddr_t idblk[MAXNINDIR];
+
+       bread(fsbtodb(sblock, d), (char *)idblk, sblock->fs_bsize);
+       if(n <= 0) {
+               for(i=0; i < NINDIR(sblock); i++) {
+                       d = idblk[i];
+                       if(d != 0)
+                               dsrch(d, sblock->fs_bsize, *filesize);
+                       *filesize -= sblock->fs_bsize;
+               }
+       } else {
+               n--;
+               for(i=0; i < NINDIR(sblock); i++) {
+                       d = idblk[i];
+                       if(d != 0)
+                               indir(d, n, filesize);
+               }
+       }
+}
+
+dump(ip)
+       struct dinode *ip;
+{
+       register int i;
+       long size;
 
        if(newtape) {
                newtape = 0;
 
        if(newtape) {
                newtape = 0;
@@ -131,113 +120,171 @@ struct dinode *ip;
        spcl.c_type = TS_INODE;
        spcl.c_count = 0;
        i = ip->di_mode & IFMT;
        spcl.c_type = TS_INODE;
        spcl.c_count = 0;
        i = ip->di_mode & IFMT;
-       if(i != IFDIR && i != IFREG) {
+       if ((i != IFDIR && i != IFREG && i != IFLNK) || ip->di_size == 0) {
                spclrec();
                return;
        }
                spclrec();
                return;
        }
-       icat(ip, tapsrec, dmpspc);
+       if (ip->di_size > NDADDR * sblock->fs_bsize)
+               i = NDADDR * sblock->fs_frag;
+       else
+               i = howmany(ip->di_size, sblock->fs_fsize);
+       blksout(&ip->di_db[0], i);
+       size = ip->di_size - NDADDR * sblock->fs_bsize;
+       if (size <= 0)
+               return;
+       for (i = 0; i < NIADDR; i++) {
+               dmpindir(ip->di_ib[i], i, &size);
+               if (size <= 0)
+                       return;
+       }
 }
 
 }
 
-dmpspc(dp, n)
-daddr_t *dp;
+dmpindir(blk, lvl, size)
+       daddr_t blk;
+       int lvl;
+       long *size;
 {
 {
-       register i, t;
+       int i, cnt;
+       daddr_t idblk[MAXNINDIR];
 
 
-       spcl.c_count = n;
-       for(i=0; i<n; i++) {
-               t = 0;
-               if(dp[i] != 0)
-                       t++;
-               spcl.c_addr[i] = t;
+       if (blk != 0)
+               bread(fsbtodb(sblock, blk), (char *)idblk, sblock->fs_bsize);
+       else
+               bzero(idblk, sblock->fs_bsize);
+       if (lvl <= 0) {
+               if (*size < NINDIR(sblock) * sblock->fs_bsize)
+                       cnt = howmany(*size, sblock->fs_fsize);
+               else
+                       cnt = NINDIR(sblock) * sblock->fs_frag;
+               *size -= NINDIR(sblock) * sblock->fs_bsize;
+               blksout(&idblk[0], cnt);
+               return;
+       }
+       lvl--;
+       for (i = 0; i < NINDIR(sblock); i++) {
+               dmpindir(idblk[i], lvl, size);
+               if (*size <= 0)
+                       return;
+       }
+}
+
+blksout(blkp, frags)
+       daddr_t *blkp;
+       int frags;
+{
+       int i, j, count, blks, tbperdb;
+
+       blks = howmany(frags * sblock->fs_fsize, TP_BSIZE);
+       tbperdb = sblock->fs_bsize / TP_BSIZE;
+       for (i = 0; i < blks; i += TP_NINDIR) {
+               if (i + TP_NINDIR > blks)
+                       count = blks;
+               else
+                       count = i + TP_NINDIR;
+               for (j = i; j < count; j++)
+                       if (blkp[j / tbperdb] != 0)
+                               spcl.c_addr[j - i] = 1;
+                       else
+                               spcl.c_addr[j - i] = 0;
+               spcl.c_count = count - i;
+               spclrec();
+               for (j = i; j < count; j += tbperdb)
+                       if (blkp[j / tbperdb] != 0)
+                               if (j + tbperdb <= count)
+                                       dmpblk(blkp[j / tbperdb],
+                                           sblock->fs_bsize);
+                               else
+                                       dmpblk(blkp[j / tbperdb],
+                                           (count - j) * TP_BSIZE);
+               spcl.c_type = TS_ADDR;
        }
        }
-       spclrec();
 }
 
 bitmap(map, typ)
 }
 
 bitmap(map, typ)
-short *map;
+       char *map;
 {
        register i, n;
        char *cp;
 
        n = -1;
 {
        register i, n;
        char *cp;
 
        n = -1;
-       for(i=0; i<MSIZ; i++)
+       for (i = 0; i < msiz; i++)
                if(map[i])
                        n = i;
                if(map[i])
                        n = i;
-       if(n < 0)
+       if (n < 0)
                return;
                return;
+       n++;
        spcl.c_type = typ;
        spcl.c_type = typ;
-       spcl.c_count = (n*sizeof(map[0]) + BSIZE)/BSIZE;
+       spcl.c_count = howmany(n * sizeof(map[0]), TP_BSIZE);
        spclrec();
        spclrec();
-       cp = (char *)map;
-       for(i=0; i<spcl.c_count; i++) {
+       for (i = 0, cp = map; i < spcl.c_count; i++, cp += TP_BSIZE)
                taprec(cp);
                taprec(cp);
-               cp += BSIZE;
-       }
 }
 
 spclrec()
 {
 }
 
 spclrec()
 {
-       register i, *ip, s;
+       register int s, i, *ip;
 
        spcl.c_inumber = ino;
 
        spcl.c_inumber = ino;
-       spcl.c_magic = MAGIC;
+       spcl.c_magic = NFS_MAGIC;
        spcl.c_checksum = 0;
        ip = (int *)&spcl;
        s = 0;
        spcl.c_checksum = 0;
        ip = (int *)&spcl;
        s = 0;
-       for(i=0; i<BSIZE/sizeof(*ip); i++)
+       for(i = 0; i < sizeof(union u_spcl)/sizeof(int); i++)
                s += *ip++;
        spcl.c_checksum = CHECKSUM - s;
        taprec((char *)&spcl);
 }
 
                s += *ip++;
        spcl.c_checksum = CHECKSUM - s;
        taprec((char *)&spcl);
 }
 
-dsrch(d)
-daddr_t d;
+dsrch(d, size, filesize)
+       daddr_t d;
+       int size, filesize;
 {
 {
-       register char *cp;
-       register i;
-       register ino_t in;
-       struct direct dblk[DIRPB];
+       register struct direct *dp;
+       long loc;
+       char dblk[MAXBSIZE];
 
        if(dadded)
                return;
 
        if(dadded)
                return;
-       bread(d, (char *)dblk, sizeof(dblk));
-       for(i=0; i<DIRPB; i++) {
-               in = dblk[i].d_ino;
-               if(in == 0)
+       bread(fsbtodb(sblock, d), dblk, size);
+       if (filesize > size)
+               filesize = size;
+       for (loc = 0; loc < filesize; ) {
+               dp = (struct direct *)(dblk + loc);
+               if (dp->d_reclen == 0) {
+                       msg("corrupted directory, inumber %d\n", ino);
+                       break;
+               }
+               loc += dp->d_reclen;
+               if(dp->d_ino == 0)
                        continue;
                        continue;
-               cp = dblk[i].d_name;
-               if(cp[0] == '.') {
-                       if(cp[1] == '\0')
+               if(dp->d_name[0] == '.') {
+                       if(dp->d_name[1] == '\0')
                                continue;
                                continue;
-                       if(cp[1] == '.' && cp[2] == '\0')
+                       if(dp->d_name[1] == '.' && dp->d_name[2] == '\0')
                                continue;
                }
                                continue;
                }
-               if(BIT(in, nodmap)) {
+               if(BIT(dp->d_ino, nodmap)) {
                        dadded++;
                        return;
                }
                        dadded++;
                        return;
                }
-               if(BIT(in, dirmap))
+               if(BIT(dp->d_ino, dirmap))
                        nsubdir++;
        }
 }
 
                        nsubdir++;
        }
 }
 
-nullf()
-{
-}
-
 struct dinode *
 getino(ino)
        daddr_t ino;
 {
        static daddr_t minino, maxino;
 struct dinode *
 getino(ino)
        daddr_t ino;
 {
        static daddr_t minino, maxino;
-       static struct dinode itab[INOPB];
+       static struct dinode itab[MAXINOPB];
 
        if (ino >= minino && ino < maxino) {
                return (&itab[ino - minino]);
        }
 
        if (ino >= minino && ino < maxino) {
                return (&itab[ino - minino]);
        }
-       bread(itod(ino, &sblock), itab, BSIZE);
-       minino = ino - (ino % INOPB);
-       maxino = minino + INOPB;
+       bread(fsbtodb(sblock, itod(sblock, ino)), itab, sblock->fs_bsize);
+       minino = ino - (ino % INOPB(sblock));
+       maxino = minino + INOPB(sblock);
        return (&itab[ino - minino]);
 }
 
        return (&itab[ino - minino]);
 }
 
@@ -252,12 +299,12 @@ bread(da, ba, c)
        register n;
        register        regc;
 
        register n;
        register        regc;
 
-       if (lseek(fi, (long)(da*FSIZE), 0) < 0){
+       if (lseek(fi, (long)(da * DEV_BSIZE), 0) < 0){
                msg("bread: lseek fails\n");
        }
        regc = c;       /* put c someplace safe; it gets clobbered */
        n = read(fi, ba, c);
                msg("bread: lseek fails\n");
        }
        regc = c;       /* put c someplace safe; it gets clobbered */
        n = read(fi, ba, c);
-       if(n != c || regc != c){
+       if (n != c || regc != c) {
                msg("(This should not happen)bread from %s [block %d]: c=0x%x, regc=0x%x, &c=0x%x, n=0x%x\n",
                        disk, da, c, regc, &c, n);
 #ifdef ERNIE
                msg("(This should not happen)bread from %s [block %d]: c=0x%x, regc=0x%x, &c=0x%x, n=0x%x\n",
                        disk, da, c, regc, &c, n);
 #ifdef ERNIE
@@ -276,15 +323,3 @@ bread(da, ba, c)
                }
        }
 }
                }
        }
 }
-
-CLR(map)
-register short *map;
-{
-       register n;
-
-       n = MSIZ;
-       do
-               *map++ = 0;
-       while(--n);
-}
-