1*4702Smckusic static char *sccsid = "@(#)traverse.c 1.2 (Berkeley) 10/31/81"; 21426Sroot #include "dump.h" 31426Sroot 4*4702Smckusic struct fs sblock; 51426Sroot 61426Sroot pass(fn, map) 7*4702Smckusic int (*fn)(); 8*4702Smckusic short *map; 91426Sroot { 10*4702Smckusic struct dinode *dp; 111426Sroot int bits; 12*4702Smckusic ino_t maxino; 131426Sroot 141426Sroot sync(); 15*4702Smckusic bread(SBLOCK, &sblock, sizeof sblock); 16*4702Smckusic if (sblock.fs_magic != FS_MAGIC) { 17*4702Smckusic msg("bad sblock magic number\n"); 18*4702Smckusic dumpabort(); 19*4702Smckusic } 20*4702Smckusic maxino = sblock.fs_ipg * sblock.fs_ncg; 21*4702Smckusic for (ino = 0; ino < maxino; ) { 22*4702Smckusic if((ino % MLEN) == 0) { 23*4702Smckusic bits = ~0; 24*4702Smckusic if(map != NULL) 25*4702Smckusic bits = *map++; 261426Sroot } 27*4702Smckusic ino++; 28*4702Smckusic if(bits & 1) { 29*4702Smckusic dp = getino(ino); 30*4702Smckusic (*fn)(dp); 31*4702Smckusic } 32*4702Smckusic bits >>= 1; 331426Sroot } 341426Sroot } 351426Sroot 36*4702Smckusic icat(dp, fn1, fn2) 37*4702Smckusic register struct dinode *dp; 38*4702Smckusic int (*fn1)(), (*fn2)(); 391426Sroot { 40*4702Smckusic register int i; 411426Sroot 42*4702Smckusic (*fn2)(dp->di_db, NDADDR); 43*4702Smckusic for (i = 0; i < NDADDR; i++) { 44*4702Smckusic if (dp->di_db[i] != 0) 45*4702Smckusic (*fn1)(dp->di_db[i]); 461426Sroot } 47*4702Smckusic for (i = 0; i < NIADDR; i++) { 48*4702Smckusic if (dp->di_ib[i] != 0) 49*4702Smckusic indir(dp->di_ib[i], fn1, fn2, i); 50*4702Smckusic } 511426Sroot } 521426Sroot 531426Sroot indir(d, fn1, fn2, n) 541426Sroot daddr_t d; 551426Sroot int (*fn1)(), (*fn2)(); 561426Sroot { 571426Sroot register i; 581426Sroot daddr_t idblk[NINDIR]; 591426Sroot 601426Sroot bread(d, (char *)idblk, sizeof(idblk)); 611426Sroot if(n <= 0) { 621426Sroot spcl.c_type = TS_ADDR; 631426Sroot (*fn2)(idblk, NINDIR); 641426Sroot for(i=0; i<NINDIR; i++) { 651426Sroot d = idblk[i]; 661426Sroot if(d != 0) 671426Sroot (*fn1)(d); 681426Sroot } 691426Sroot } else { 701426Sroot n--; 711426Sroot for(i=0; i<NINDIR; i++) { 721426Sroot d = idblk[i]; 731426Sroot if(d != 0) 741426Sroot indir(d, fn1, fn2, n); 751426Sroot } 761426Sroot } 771426Sroot } 781426Sroot 791426Sroot mark(ip) 801426Sroot struct dinode *ip; 811426Sroot { 821426Sroot register f; 831426Sroot 841426Sroot f = ip->di_mode & IFMT; 851426Sroot if(f == 0) 861426Sroot return; 871426Sroot BIS(ino, clrmap); 881426Sroot if(f == IFDIR) 891426Sroot BIS(ino, dirmap); 901426Sroot if(ip->di_mtime >= spcl.c_ddate || 911426Sroot ip->di_ctime >= spcl.c_ddate) { 921426Sroot BIS(ino, nodmap); 931426Sroot if (f != IFREG){ 941426Sroot esize += 1; 951426Sroot return; 961426Sroot } 971426Sroot est(ip); 981426Sroot } 991426Sroot } 1001426Sroot 1011426Sroot add(ip) 1021426Sroot struct dinode *ip; 1031426Sroot { 1041426Sroot 1051426Sroot if(BIT(ino, nodmap)) 1061426Sroot return; 1071426Sroot nsubdir = 0; 1081426Sroot dadded = 0; 1091426Sroot icat(ip, dsrch, nullf); 1101426Sroot if(dadded) { 1111426Sroot BIS(ino, nodmap); 1121426Sroot est(ip); 1131426Sroot nadded++; 1141426Sroot } 1151426Sroot if(nsubdir == 0) 1161426Sroot if(!BIT(ino, nodmap)) 1171426Sroot BIC(ino, dirmap); 1181426Sroot } 1191426Sroot 1201426Sroot dump(ip) 1211426Sroot struct dinode *ip; 1221426Sroot { 1231426Sroot register i; 1241426Sroot 1251426Sroot if(newtape) { 1261426Sroot newtape = 0; 1271426Sroot bitmap(nodmap, TS_BITS); 1281426Sroot } 1291426Sroot BIC(ino, nodmap); 1301426Sroot spcl.c_dinode = *ip; 1311426Sroot spcl.c_type = TS_INODE; 1321426Sroot spcl.c_count = 0; 1331426Sroot i = ip->di_mode & IFMT; 1341426Sroot if(i != IFDIR && i != IFREG) { 1351426Sroot spclrec(); 1361426Sroot return; 1371426Sroot } 1381426Sroot icat(ip, tapsrec, dmpspc); 1391426Sroot } 1401426Sroot 1411426Sroot dmpspc(dp, n) 1421426Sroot daddr_t *dp; 1431426Sroot { 1441426Sroot register i, t; 1451426Sroot 1461426Sroot spcl.c_count = n; 1471426Sroot for(i=0; i<n; i++) { 1481426Sroot t = 0; 1491426Sroot if(dp[i] != 0) 1501426Sroot t++; 1511426Sroot spcl.c_addr[i] = t; 1521426Sroot } 1531426Sroot spclrec(); 1541426Sroot } 1551426Sroot 1561426Sroot bitmap(map, typ) 1571426Sroot short *map; 1581426Sroot { 1591426Sroot register i, n; 1601426Sroot char *cp; 1611426Sroot 1621426Sroot n = -1; 1631426Sroot for(i=0; i<MSIZ; i++) 1641426Sroot if(map[i]) 1651426Sroot n = i; 1661426Sroot if(n < 0) 1671426Sroot return; 1681426Sroot spcl.c_type = typ; 1691426Sroot spcl.c_count = (n*sizeof(map[0]) + BSIZE)/BSIZE; 1701426Sroot spclrec(); 1711426Sroot cp = (char *)map; 1721426Sroot for(i=0; i<spcl.c_count; i++) { 1731426Sroot taprec(cp); 1741426Sroot cp += BSIZE; 1751426Sroot } 1761426Sroot } 1771426Sroot 1781426Sroot spclrec() 1791426Sroot { 1801426Sroot register i, *ip, s; 1811426Sroot 1821426Sroot spcl.c_inumber = ino; 1831426Sroot spcl.c_magic = MAGIC; 1841426Sroot spcl.c_checksum = 0; 1851426Sroot ip = (int *)&spcl; 1861426Sroot s = 0; 1871426Sroot for(i=0; i<BSIZE/sizeof(*ip); i++) 1881426Sroot s += *ip++; 1891426Sroot spcl.c_checksum = CHECKSUM - s; 1901426Sroot taprec((char *)&spcl); 1911426Sroot } 1921426Sroot 1931426Sroot dsrch(d) 1941426Sroot daddr_t d; 1951426Sroot { 1961426Sroot register char *cp; 1971426Sroot register i; 1981426Sroot register ino_t in; 1991426Sroot struct direct dblk[DIRPB]; 2001426Sroot 2011426Sroot if(dadded) 2021426Sroot return; 2031426Sroot bread(d, (char *)dblk, sizeof(dblk)); 2041426Sroot for(i=0; i<DIRPB; i++) { 2051426Sroot in = dblk[i].d_ino; 2061426Sroot if(in == 0) 2071426Sroot continue; 2081426Sroot cp = dblk[i].d_name; 2091426Sroot if(cp[0] == '.') { 2101426Sroot if(cp[1] == '\0') 2111426Sroot continue; 2121426Sroot if(cp[1] == '.' && cp[2] == '\0') 2131426Sroot continue; 2141426Sroot } 2151426Sroot if(BIT(in, nodmap)) { 2161426Sroot dadded++; 2171426Sroot return; 2181426Sroot } 2191426Sroot if(BIT(in, dirmap)) 2201426Sroot nsubdir++; 2211426Sroot } 2221426Sroot } 2231426Sroot 2241426Sroot nullf() 2251426Sroot { 2261426Sroot } 2271426Sroot 228*4702Smckusic struct dinode * 229*4702Smckusic getino(ino) 230*4702Smckusic daddr_t ino; 231*4702Smckusic { 232*4702Smckusic static daddr_t minino, maxino; 233*4702Smckusic static struct dinode itab[INOPB]; 234*4702Smckusic 235*4702Smckusic if (ino >= minino && ino < maxino) { 236*4702Smckusic return (&itab[ino - minino]); 237*4702Smckusic } 238*4702Smckusic bread(itod(ino, &sblock), itab, BSIZE); 239*4702Smckusic minino = ino - (ino % INOPB); 240*4702Smckusic maxino = minino + INOPB; 241*4702Smckusic return (&itab[ino - minino]); 242*4702Smckusic } 243*4702Smckusic 2441426Sroot int breaderrors = 0; 2451426Sroot #define BREADEMAX 32 2461426Sroot 2471426Sroot bread(da, ba, c) 2481426Sroot daddr_t da; 2491426Sroot char *ba; 2501426Sroot int c; 2511426Sroot { 2521426Sroot register n; 2531426Sroot register regc; 2541426Sroot 255*4702Smckusic if (lseek(fi, (long)(da*FSIZE), 0) < 0){ 2561426Sroot msg("bread: lseek fails\n"); 2571426Sroot } 2581426Sroot regc = c; /* put c someplace safe; it gets clobbered */ 2591426Sroot n = read(fi, ba, c); 2601426Sroot if(n != c || regc != c){ 2611426Sroot msg("(This should not happen)bread from %s [block %d]: c=0x%x, regc=0x%x, &c=0x%x, n=0x%x\n", 2621426Sroot disk, da, c, regc, &c, n); 2631426Sroot #ifdef ERNIE 2641426Sroot msg("Notify Robert Henry of this error.\n"); 2651426Sroot #endif 2661426Sroot if (++breaderrors > BREADEMAX){ 2671426Sroot msg("More than %d block read errors from %d\n", 2681426Sroot BREADEMAX, disk); 2691426Sroot broadcast("DUMP IS AILING!\n"); 2701426Sroot msg("This is an unrecoverable error.\n"); 2711426Sroot if (!query("Do you want to attempt to continue?")){ 2721426Sroot dumpabort(); 2731426Sroot /*NOTREACHED*/ 2741426Sroot } else 2751426Sroot breaderrors = 0; 2761426Sroot } 2771426Sroot } 2781426Sroot } 2791426Sroot 2801426Sroot CLR(map) 2811426Sroot register short *map; 2821426Sroot { 2831426Sroot register n; 2841426Sroot 2851426Sroot n = MSIZ; 2861426Sroot do 2871426Sroot *map++ = 0; 2881426Sroot while(--n); 2891426Sroot } 2901426Sroot 291