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