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