1 static char *sccsid = "@(#)dumptraverse.c 1.1 (Berkeley) 10/13/80"; 2 #include "dump.h" 3 4 struct filsys sblock; 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.s_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){ 104 esize += 1; 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) { 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]) + BSIZE)/BSIZE; 180 spclrec(); 181 cp = (char *)map; 182 for(i=0; i<spcl.c_count; i++) { 183 taprec(cp); 184 cp += 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<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 direct 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 int c; 245 { 246 register n; 247 register regc; 248 249 if (lseek(fi, (long)(da*BSIZE), 0) < 0){ 250 msg("bread: lseek fails\n"); 251 } 252 regc = c; /* put c someplace safe; it gets clobbered */ 253 n = read(fi, ba, c); 254 if(n != c || regc != c){ 255 msg("(This should not happen)bread from %s [block %d]: c=0x%x, regc=0x%x, &c=0x%x, n=0x%x\n", 256 disk, da, c, regc, &c, n); 257 #ifdef ERNIE 258 msg("Notify Robert Henry of this error.\n"); 259 #endif 260 if (++breaderrors > BREADEMAX){ 261 msg("More than %d block read errors from %d\n", 262 BREADEMAX, disk); 263 broadcast("DUMP IS AILING!\n"); 264 msg("This is an unrecoverable error.\n"); 265 if (!query("Do you want to attempt to continue?")){ 266 dumpabort(); 267 /*NOTREACHED*/ 268 } else 269 breaderrors = 0; 270 } 271 } 272 } 273 274 CLR(map) 275 register short *map; 276 { 277 register n; 278 279 n = MSIZ; 280 do 281 *map++ = 0; 282 while(--n); 283 } 284 285