1*1426Sroot static char *sccsid = "@(#)traverse.c 1.1 (Berkeley) 10/13/80"; 2*1426Sroot #include "dump.h" 3*1426Sroot 4*1426Sroot struct filsys sblock; 5*1426Sroot struct dinode itab[INOPB * NI]; 6*1426Sroot 7*1426Sroot pass(fn, map) 8*1426Sroot int (*fn)(); 9*1426Sroot short *map; 10*1426Sroot { 11*1426Sroot register i, j; 12*1426Sroot int bits; 13*1426Sroot ino_t mino; 14*1426Sroot daddr_t d; 15*1426Sroot 16*1426Sroot sync(); 17*1426Sroot bread((daddr_t)1, (char *)&sblock, sizeof(sblock)); 18*1426Sroot mino = (sblock.s_isize-2) * INOPB; 19*1426Sroot ino = 0; 20*1426Sroot for(i=2;; i+=NI) { 21*1426Sroot if(ino >= mino) 22*1426Sroot break; 23*1426Sroot d = (unsigned)i; 24*1426Sroot for(j=0; j<INOPB*NI; j++) { 25*1426Sroot if(ino >= mino) 26*1426Sroot break; 27*1426Sroot if((ino % MLEN) == 0) { 28*1426Sroot bits = ~0; 29*1426Sroot if(map != NULL) 30*1426Sroot bits = *map++; 31*1426Sroot } 32*1426Sroot ino++; 33*1426Sroot if(bits & 1) { 34*1426Sroot if(d != 0) { 35*1426Sroot bread(d, (char *)itab, sizeof(itab)); 36*1426Sroot d = 0; 37*1426Sroot } 38*1426Sroot (*fn)(&itab[j]); 39*1426Sroot } 40*1426Sroot bits >>= 1; 41*1426Sroot } 42*1426Sroot } 43*1426Sroot } 44*1426Sroot 45*1426Sroot icat(ip, fn1, fn2) 46*1426Sroot struct dinode *ip; 47*1426Sroot int (*fn1)(), (*fn2)(); 48*1426Sroot { 49*1426Sroot register i; 50*1426Sroot daddr_t d[NADDR]; 51*1426Sroot 52*1426Sroot l3tol(&d[0], &ip->di_addr[0], NADDR); 53*1426Sroot (*fn2)(d, NADDR-3); 54*1426Sroot for(i=0; i<NADDR; i++) { 55*1426Sroot if(d[i] != 0) { 56*1426Sroot if(i < NADDR-3) 57*1426Sroot (*fn1)(d[i]); else 58*1426Sroot indir(d[i], fn1, fn2, i-(NADDR-3)); 59*1426Sroot } 60*1426Sroot } 61*1426Sroot } 62*1426Sroot 63*1426Sroot indir(d, fn1, fn2, n) 64*1426Sroot daddr_t d; 65*1426Sroot int (*fn1)(), (*fn2)(); 66*1426Sroot { 67*1426Sroot register i; 68*1426Sroot daddr_t idblk[NINDIR]; 69*1426Sroot 70*1426Sroot bread(d, (char *)idblk, sizeof(idblk)); 71*1426Sroot if(n <= 0) { 72*1426Sroot spcl.c_type = TS_ADDR; 73*1426Sroot (*fn2)(idblk, NINDIR); 74*1426Sroot for(i=0; i<NINDIR; i++) { 75*1426Sroot d = idblk[i]; 76*1426Sroot if(d != 0) 77*1426Sroot (*fn1)(d); 78*1426Sroot } 79*1426Sroot } else { 80*1426Sroot n--; 81*1426Sroot for(i=0; i<NINDIR; i++) { 82*1426Sroot d = idblk[i]; 83*1426Sroot if(d != 0) 84*1426Sroot indir(d, fn1, fn2, n); 85*1426Sroot } 86*1426Sroot } 87*1426Sroot } 88*1426Sroot 89*1426Sroot mark(ip) 90*1426Sroot struct dinode *ip; 91*1426Sroot { 92*1426Sroot register f; 93*1426Sroot 94*1426Sroot f = ip->di_mode & IFMT; 95*1426Sroot if(f == 0) 96*1426Sroot return; 97*1426Sroot BIS(ino, clrmap); 98*1426Sroot if(f == IFDIR) 99*1426Sroot BIS(ino, dirmap); 100*1426Sroot if(ip->di_mtime >= spcl.c_ddate || 101*1426Sroot ip->di_ctime >= spcl.c_ddate) { 102*1426Sroot BIS(ino, nodmap); 103*1426Sroot if (f != IFREG){ 104*1426Sroot esize += 1; 105*1426Sroot return; 106*1426Sroot } 107*1426Sroot est(ip); 108*1426Sroot } 109*1426Sroot } 110*1426Sroot 111*1426Sroot add(ip) 112*1426Sroot struct dinode *ip; 113*1426Sroot { 114*1426Sroot 115*1426Sroot if(BIT(ino, nodmap)) 116*1426Sroot return; 117*1426Sroot nsubdir = 0; 118*1426Sroot dadded = 0; 119*1426Sroot icat(ip, dsrch, nullf); 120*1426Sroot if(dadded) { 121*1426Sroot BIS(ino, nodmap); 122*1426Sroot est(ip); 123*1426Sroot nadded++; 124*1426Sroot } 125*1426Sroot if(nsubdir == 0) 126*1426Sroot if(!BIT(ino, nodmap)) 127*1426Sroot BIC(ino, dirmap); 128*1426Sroot } 129*1426Sroot 130*1426Sroot dump(ip) 131*1426Sroot struct dinode *ip; 132*1426Sroot { 133*1426Sroot register i; 134*1426Sroot 135*1426Sroot if(newtape) { 136*1426Sroot newtape = 0; 137*1426Sroot bitmap(nodmap, TS_BITS); 138*1426Sroot } 139*1426Sroot BIC(ino, nodmap); 140*1426Sroot spcl.c_dinode = *ip; 141*1426Sroot spcl.c_type = TS_INODE; 142*1426Sroot spcl.c_count = 0; 143*1426Sroot i = ip->di_mode & IFMT; 144*1426Sroot if(i != IFDIR && i != IFREG) { 145*1426Sroot spclrec(); 146*1426Sroot return; 147*1426Sroot } 148*1426Sroot icat(ip, tapsrec, dmpspc); 149*1426Sroot } 150*1426Sroot 151*1426Sroot dmpspc(dp, n) 152*1426Sroot daddr_t *dp; 153*1426Sroot { 154*1426Sroot register i, t; 155*1426Sroot 156*1426Sroot spcl.c_count = n; 157*1426Sroot for(i=0; i<n; i++) { 158*1426Sroot t = 0; 159*1426Sroot if(dp[i] != 0) 160*1426Sroot t++; 161*1426Sroot spcl.c_addr[i] = t; 162*1426Sroot } 163*1426Sroot spclrec(); 164*1426Sroot } 165*1426Sroot 166*1426Sroot bitmap(map, typ) 167*1426Sroot short *map; 168*1426Sroot { 169*1426Sroot register i, n; 170*1426Sroot char *cp; 171*1426Sroot 172*1426Sroot n = -1; 173*1426Sroot for(i=0; i<MSIZ; i++) 174*1426Sroot if(map[i]) 175*1426Sroot n = i; 176*1426Sroot if(n < 0) 177*1426Sroot return; 178*1426Sroot spcl.c_type = typ; 179*1426Sroot spcl.c_count = (n*sizeof(map[0]) + BSIZE)/BSIZE; 180*1426Sroot spclrec(); 181*1426Sroot cp = (char *)map; 182*1426Sroot for(i=0; i<spcl.c_count; i++) { 183*1426Sroot taprec(cp); 184*1426Sroot cp += BSIZE; 185*1426Sroot } 186*1426Sroot } 187*1426Sroot 188*1426Sroot spclrec() 189*1426Sroot { 190*1426Sroot register i, *ip, s; 191*1426Sroot 192*1426Sroot spcl.c_inumber = ino; 193*1426Sroot spcl.c_magic = MAGIC; 194*1426Sroot spcl.c_checksum = 0; 195*1426Sroot ip = (int *)&spcl; 196*1426Sroot s = 0; 197*1426Sroot for(i=0; i<BSIZE/sizeof(*ip); i++) 198*1426Sroot s += *ip++; 199*1426Sroot spcl.c_checksum = CHECKSUM - s; 200*1426Sroot taprec((char *)&spcl); 201*1426Sroot } 202*1426Sroot 203*1426Sroot dsrch(d) 204*1426Sroot daddr_t d; 205*1426Sroot { 206*1426Sroot register char *cp; 207*1426Sroot register i; 208*1426Sroot register ino_t in; 209*1426Sroot struct direct dblk[DIRPB]; 210*1426Sroot 211*1426Sroot if(dadded) 212*1426Sroot return; 213*1426Sroot bread(d, (char *)dblk, sizeof(dblk)); 214*1426Sroot for(i=0; i<DIRPB; i++) { 215*1426Sroot in = dblk[i].d_ino; 216*1426Sroot if(in == 0) 217*1426Sroot continue; 218*1426Sroot cp = dblk[i].d_name; 219*1426Sroot if(cp[0] == '.') { 220*1426Sroot if(cp[1] == '\0') 221*1426Sroot continue; 222*1426Sroot if(cp[1] == '.' && cp[2] == '\0') 223*1426Sroot continue; 224*1426Sroot } 225*1426Sroot if(BIT(in, nodmap)) { 226*1426Sroot dadded++; 227*1426Sroot return; 228*1426Sroot } 229*1426Sroot if(BIT(in, dirmap)) 230*1426Sroot nsubdir++; 231*1426Sroot } 232*1426Sroot } 233*1426Sroot 234*1426Sroot nullf() 235*1426Sroot { 236*1426Sroot } 237*1426Sroot 238*1426Sroot int breaderrors = 0; 239*1426Sroot #define BREADEMAX 32 240*1426Sroot 241*1426Sroot bread(da, ba, c) 242*1426Sroot daddr_t da; 243*1426Sroot char *ba; 244*1426Sroot int c; 245*1426Sroot { 246*1426Sroot register n; 247*1426Sroot register regc; 248*1426Sroot 249*1426Sroot if (lseek(fi, (long)(da*BSIZE), 0) < 0){ 250*1426Sroot msg("bread: lseek fails\n"); 251*1426Sroot } 252*1426Sroot regc = c; /* put c someplace safe; it gets clobbered */ 253*1426Sroot n = read(fi, ba, c); 254*1426Sroot if(n != c || regc != c){ 255*1426Sroot msg("(This should not happen)bread from %s [block %d]: c=0x%x, regc=0x%x, &c=0x%x, n=0x%x\n", 256*1426Sroot disk, da, c, regc, &c, n); 257*1426Sroot #ifdef ERNIE 258*1426Sroot msg("Notify Robert Henry of this error.\n"); 259*1426Sroot #endif 260*1426Sroot if (++breaderrors > BREADEMAX){ 261*1426Sroot msg("More than %d block read errors from %d\n", 262*1426Sroot BREADEMAX, disk); 263*1426Sroot broadcast("DUMP IS AILING!\n"); 264*1426Sroot msg("This is an unrecoverable error.\n"); 265*1426Sroot if (!query("Do you want to attempt to continue?")){ 266*1426Sroot dumpabort(); 267*1426Sroot /*NOTREACHED*/ 268*1426Sroot } else 269*1426Sroot breaderrors = 0; 270*1426Sroot } 271*1426Sroot } 272*1426Sroot } 273*1426Sroot 274*1426Sroot CLR(map) 275*1426Sroot register short *map; 276*1426Sroot { 277*1426Sroot register n; 278*1426Sroot 279*1426Sroot n = MSIZ; 280*1426Sroot do 281*1426Sroot *map++ = 0; 282*1426Sroot while(--n); 283*1426Sroot } 284*1426Sroot 285