1*4777Smckusic static char *sccsid = "@(#)traverse.c 1.3 (Berkeley) 11/07/81"; 21426Sroot #include "dump.h" 31426Sroot 44702Smckusic struct fs sblock; 51426Sroot 61426Sroot pass(fn, map) 74702Smckusic int (*fn)(); 84702Smckusic short *map; 91426Sroot { 104702Smckusic struct dinode *dp; 111426Sroot int bits; 124702Smckusic ino_t maxino; 131426Sroot 141426Sroot sync(); 154702Smckusic bread(SBLOCK, &sblock, sizeof sblock); 164702Smckusic if (sblock.fs_magic != FS_MAGIC) { 174702Smckusic msg("bad sblock magic number\n"); 184702Smckusic dumpabort(); 194702Smckusic } 204702Smckusic maxino = sblock.fs_ipg * sblock.fs_ncg; 214702Smckusic for (ino = 0; ino < maxino; ) { 224702Smckusic if((ino % MLEN) == 0) { 234702Smckusic bits = ~0; 244702Smckusic if(map != NULL) 254702Smckusic bits = *map++; 261426Sroot } 274702Smckusic ino++; 284702Smckusic if(bits & 1) { 294702Smckusic dp = getino(ino); 304702Smckusic (*fn)(dp); 314702Smckusic } 324702Smckusic bits >>= 1; 331426Sroot } 341426Sroot } 351426Sroot 36*4777Smckusic icat(dp, fn1) 374702Smckusic register struct dinode *dp; 38*4777Smckusic int (*fn1)(); 391426Sroot { 404702Smckusic register int i; 411426Sroot 424702Smckusic for (i = 0; i < NDADDR; i++) { 434702Smckusic if (dp->di_db[i] != 0) 444702Smckusic (*fn1)(dp->di_db[i]); 451426Sroot } 464702Smckusic for (i = 0; i < NIADDR; i++) { 474702Smckusic if (dp->di_ib[i] != 0) 48*4777Smckusic indir(dp->di_ib[i], fn1, i); 494702Smckusic } 501426Sroot } 511426Sroot 52*4777Smckusic indir(d, fn1, n) 53*4777Smckusic daddr_t d; 54*4777Smckusic int (*fn1)(); 55*4777Smckusic int n; 561426Sroot { 571426Sroot register i; 581426Sroot daddr_t idblk[NINDIR]; 591426Sroot 601426Sroot bread(d, (char *)idblk, sizeof(idblk)); 611426Sroot if(n <= 0) { 621426Sroot for(i=0; i<NINDIR; i++) { 631426Sroot d = idblk[i]; 641426Sroot if(d != 0) 651426Sroot (*fn1)(d); 661426Sroot } 671426Sroot } else { 681426Sroot n--; 691426Sroot for(i=0; i<NINDIR; i++) { 701426Sroot d = idblk[i]; 711426Sroot if(d != 0) 72*4777Smckusic indir(d, fn1, n); 731426Sroot } 741426Sroot } 751426Sroot } 761426Sroot 771426Sroot mark(ip) 78*4777Smckusic struct dinode *ip; 791426Sroot { 801426Sroot register f; 811426Sroot 821426Sroot f = ip->di_mode & IFMT; 831426Sroot if(f == 0) 841426Sroot return; 851426Sroot BIS(ino, clrmap); 861426Sroot if(f == IFDIR) 871426Sroot BIS(ino, dirmap); 881426Sroot if(ip->di_mtime >= spcl.c_ddate || 891426Sroot ip->di_ctime >= spcl.c_ddate) { 901426Sroot BIS(ino, nodmap); 911426Sroot if (f != IFREG){ 921426Sroot esize += 1; 931426Sroot return; 941426Sroot } 951426Sroot est(ip); 961426Sroot } 971426Sroot } 981426Sroot 991426Sroot add(ip) 100*4777Smckusic struct dinode *ip; 1011426Sroot { 1021426Sroot 1031426Sroot if(BIT(ino, nodmap)) 1041426Sroot return; 1051426Sroot nsubdir = 0; 1061426Sroot dadded = 0; 107*4777Smckusic icat(ip, dsrch); 1081426Sroot if(dadded) { 1091426Sroot BIS(ino, nodmap); 1101426Sroot est(ip); 1111426Sroot nadded++; 1121426Sroot } 1131426Sroot if(nsubdir == 0) 1141426Sroot if(!BIT(ino, nodmap)) 1151426Sroot BIC(ino, dirmap); 1161426Sroot } 1171426Sroot 1181426Sroot dump(ip) 119*4777Smckusic struct dinode *ip; 1201426Sroot { 121*4777Smckusic register int i; 122*4777Smckusic long size; 1231426Sroot 1241426Sroot if(newtape) { 1251426Sroot newtape = 0; 1261426Sroot bitmap(nodmap, TS_BITS); 1271426Sroot } 1281426Sroot BIC(ino, nodmap); 1291426Sroot spcl.c_dinode = *ip; 1301426Sroot spcl.c_type = TS_INODE; 1311426Sroot spcl.c_count = 0; 1321426Sroot i = ip->di_mode & IFMT; 133*4777Smckusic if ((i != IFDIR && i != IFREG) || ip->di_size == 0) { 1341426Sroot spclrec(); 1351426Sroot return; 1361426Sroot } 137*4777Smckusic if (ip->di_size > NDADDR * BSIZE) 138*4777Smckusic i = NDADDR * FRAG; 139*4777Smckusic else 140*4777Smckusic i = howmany(ip->di_size, FSIZE); 141*4777Smckusic blksout(&ip->di_db[0], i); 142*4777Smckusic size = ip->di_size - NDADDR * BSIZE; 143*4777Smckusic if (size <= 0) 144*4777Smckusic return; 145*4777Smckusic for (i = 0; i < NIADDR; i++) { 146*4777Smckusic dmpindir(ip->di_ib[i], i, &size); 147*4777Smckusic if (size <= 0) 148*4777Smckusic return; 149*4777Smckusic } 1501426Sroot } 1511426Sroot 152*4777Smckusic dmpindir(blk, lvl, size) 153*4777Smckusic daddr_t blk; 154*4777Smckusic int lvl; 155*4777Smckusic long *size; 1561426Sroot { 157*4777Smckusic int i, cnt; 158*4777Smckusic daddr_t idblk[NINDIR]; 1591426Sroot 160*4777Smckusic if (blk != 0) 161*4777Smckusic bread(blk, (char *)idblk, sizeof(idblk)); 162*4777Smckusic else 163*4777Smckusic blkclr(idblk, sizeof(idblk)); 164*4777Smckusic if (lvl <= 0) { 165*4777Smckusic if (*size < NINDIR * BSIZE) 166*4777Smckusic cnt = howmany(*size, TP_BSIZE); 167*4777Smckusic else 168*4777Smckusic cnt = NINDIR * BLKING * FRAG; 169*4777Smckusic *size -= NINDIR * BSIZE; 170*4777Smckusic blksout(&idblk[0], cnt); 171*4777Smckusic return; 1721426Sroot } 173*4777Smckusic lvl--; 174*4777Smckusic for (i = 0; i < NINDIR; i++) { 175*4777Smckusic dmpindir(idblk[i], lvl, size); 176*4777Smckusic if (*size <= 0) 177*4777Smckusic return; 178*4777Smckusic } 1791426Sroot } 1801426Sroot 181*4777Smckusic blksout(blkp, frags) 182*4777Smckusic daddr_t *blkp; 183*4777Smckusic int frags; 184*4777Smckusic { 185*4777Smckusic int i, j, count, blks; 186*4777Smckusic 187*4777Smckusic blks = frags * BLKING; 188*4777Smckusic for (i = 0; i < blks; i += TP_NINDIR) { 189*4777Smckusic if (i + TP_NINDIR > blks) 190*4777Smckusic count = blks; 191*4777Smckusic else 192*4777Smckusic count = i + TP_NINDIR; 193*4777Smckusic for (j = i; j < count; j++) 194*4777Smckusic if (blkp[j / (BLKING * FRAG)] != 0) 195*4777Smckusic spcl.c_addr[j - i] = 1; 196*4777Smckusic else 197*4777Smckusic spcl.c_addr[j - i] = 0; 198*4777Smckusic spcl.c_count = count - i; 199*4777Smckusic spclrec(); 200*4777Smckusic for (j = i; j < count; j += (BLKING * FRAG)) 201*4777Smckusic if (blkp[j / (BLKING * FRAG)] != 0) 202*4777Smckusic if (j + (BLKING * FRAG) <= count) 203*4777Smckusic dmpblk(blkp[j / (BLKING * FRAG)], 204*4777Smckusic BSIZE); 205*4777Smckusic else 206*4777Smckusic dmpblk(blkp[j / (BLKING * FRAG)], 207*4777Smckusic (count - j) * TP_BSIZE); 208*4777Smckusic spcl.c_type = TS_ADDR; 209*4777Smckusic } 210*4777Smckusic } 211*4777Smckusic 2121426Sroot bitmap(map, typ) 213*4777Smckusic short *map; 2141426Sroot { 2151426Sroot register i, n; 2161426Sroot char *cp; 2171426Sroot 2181426Sroot n = -1; 2191426Sroot for(i=0; i<MSIZ; i++) 2201426Sroot if(map[i]) 2211426Sroot n = i; 2221426Sroot if(n < 0) 2231426Sroot return; 2241426Sroot spcl.c_type = typ; 225*4777Smckusic spcl.c_count = (n*sizeof(map[0]) + TP_BSIZE)/TP_BSIZE; 2261426Sroot spclrec(); 2271426Sroot cp = (char *)map; 2281426Sroot for(i=0; i<spcl.c_count; i++) { 2291426Sroot taprec(cp); 230*4777Smckusic cp += TP_BSIZE; 2311426Sroot } 2321426Sroot } 2331426Sroot 2341426Sroot spclrec() 2351426Sroot { 236*4777Smckusic register int s, i, *ip; 2371426Sroot 2381426Sroot spcl.c_inumber = ino; 2391426Sroot spcl.c_magic = MAGIC; 2401426Sroot spcl.c_checksum = 0; 2411426Sroot ip = (int *)&spcl; 2421426Sroot s = 0; 243*4777Smckusic for(i = 0; i < sizeof(union u_spcl)/sizeof(int); i++) 2441426Sroot s += *ip++; 2451426Sroot spcl.c_checksum = CHECKSUM - s; 2461426Sroot taprec((char *)&spcl); 2471426Sroot } 2481426Sroot 2491426Sroot dsrch(d) 250*4777Smckusic daddr_t d; 2511426Sroot { 2521426Sroot register char *cp; 2531426Sroot register i; 2541426Sroot register ino_t in; 2551426Sroot struct direct dblk[DIRPB]; 2561426Sroot 2571426Sroot if(dadded) 2581426Sroot return; 2591426Sroot bread(d, (char *)dblk, sizeof(dblk)); 2601426Sroot for(i=0; i<DIRPB; i++) { 2611426Sroot in = dblk[i].d_ino; 2621426Sroot if(in == 0) 2631426Sroot continue; 2641426Sroot cp = dblk[i].d_name; 2651426Sroot if(cp[0] == '.') { 2661426Sroot if(cp[1] == '\0') 2671426Sroot continue; 2681426Sroot if(cp[1] == '.' && cp[2] == '\0') 2691426Sroot continue; 2701426Sroot } 2711426Sroot if(BIT(in, nodmap)) { 2721426Sroot dadded++; 2731426Sroot return; 2741426Sroot } 2751426Sroot if(BIT(in, dirmap)) 2761426Sroot nsubdir++; 2771426Sroot } 2781426Sroot } 2791426Sroot 2804702Smckusic struct dinode * 2814702Smckusic getino(ino) 2824702Smckusic daddr_t ino; 2834702Smckusic { 2844702Smckusic static daddr_t minino, maxino; 2854702Smckusic static struct dinode itab[INOPB]; 2864702Smckusic 2874702Smckusic if (ino >= minino && ino < maxino) { 2884702Smckusic return (&itab[ino - minino]); 2894702Smckusic } 2904702Smckusic bread(itod(ino, &sblock), itab, BSIZE); 2914702Smckusic minino = ino - (ino % INOPB); 2924702Smckusic maxino = minino + INOPB; 2934702Smckusic return (&itab[ino - minino]); 2944702Smckusic } 2954702Smckusic 2961426Sroot int breaderrors = 0; 2971426Sroot #define BREADEMAX 32 2981426Sroot 2991426Sroot bread(da, ba, c) 3001426Sroot daddr_t da; 3011426Sroot char *ba; 3021426Sroot int c; 3031426Sroot { 3041426Sroot register n; 3051426Sroot register regc; 3061426Sroot 3074702Smckusic if (lseek(fi, (long)(da*FSIZE), 0) < 0){ 3081426Sroot msg("bread: lseek fails\n"); 3091426Sroot } 3101426Sroot regc = c; /* put c someplace safe; it gets clobbered */ 3111426Sroot n = read(fi, ba, c); 3121426Sroot if(n != c || regc != c){ 3131426Sroot msg("(This should not happen)bread from %s [block %d]: c=0x%x, regc=0x%x, &c=0x%x, n=0x%x\n", 3141426Sroot disk, da, c, regc, &c, n); 3151426Sroot #ifdef ERNIE 3161426Sroot msg("Notify Robert Henry of this error.\n"); 3171426Sroot #endif 3181426Sroot if (++breaderrors > BREADEMAX){ 3191426Sroot msg("More than %d block read errors from %d\n", 3201426Sroot BREADEMAX, disk); 3211426Sroot broadcast("DUMP IS AILING!\n"); 3221426Sroot msg("This is an unrecoverable error.\n"); 3231426Sroot if (!query("Do you want to attempt to continue?")){ 3241426Sroot dumpabort(); 3251426Sroot /*NOTREACHED*/ 3261426Sroot } else 3271426Sroot breaderrors = 0; 3281426Sroot } 3291426Sroot } 3301426Sroot } 3311426Sroot 3321426Sroot CLR(map) 333*4777Smckusic register short *map; 3341426Sroot { 3351426Sroot register n; 3361426Sroot 3371426Sroot n = MSIZ; 3381426Sroot do 3391426Sroot *map++ = 0; 3401426Sroot while(--n); 3411426Sroot } 3421426Sroot 343*4777Smckusic blkclr(cp, size) 344*4777Smckusic char *cp; 345*4777Smckusic long size; 346*4777Smckusic { 347*4777Smckusic asm("movc5 $0,(r0),$0,8(ap),*4(ap)"); 348*4777Smckusic } 349