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) 06/05/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 } 293 294