1: # 2: 3: /* 4: * incremental dump 5: * dump fisbuodh filesystem 6: * f take output tape from arglist 7: * i from date in /etc/dtab 8: * s specify tape size in feet (feet = blocks/9) 9: * b specify tape size in blocks 10: * u update /etc/dtab to current date 11: * 0 dump from the epoch 12: * d dump specified number of days 13: * h dump specified number of hours 14: * a on incremental dump, dump files even >= MAXSIZE 15: */ 16: 17: char *dargv[] 18: { 19: 0, 20: "i", 21: "/dev/rp0", 22: 0 23: }; 24: 25: #include "/usr/sys/ino.h" 26: #include "/usr/sys/filsys.h" 27: #define MAXSIZE 1000 28: struct filsys sblock; 29: struct 30: { 31: char name[16]; 32: int date[2]; 33: } dtab[10]; 34: char *dfile "/etc/dtab"; 35: char *ofile; 36: int *talist; 37: int fi; 38: int buf[256]; 39: int dbuf[256]; 40: int ibuf[256]; 41: int vbuf[256]; 42: char *date[2]; 43: char *ddate[2]; 44: int fo -1; 45: int pher; 46: int dflg; 47: int iflg; 48: int cflg; 49: int aflg; 50: char *tsize 19000; 51: char *taddr; 52: 53: main(argc, argv) 54: char **argv; 55: { 56: char *key; 57: int s, i, nfil, nblk, f; 58: register *tap; 59: register struct inode *ip; 60: int ino; 61: 62: ofile = "/dev/mt0"; 63: time(date); 64: if(argc == 1) { 65: argv = dargv; 66: for(argc = 1; dargv[argc]; argc++); 67: } 68: 69: argc--; 70: argv++; 71: key = *argv; 72: while(*key) 73: switch(*key++) { 74: 75: default: 76: printf("bad character in key\n"); 77: exit(); 78: 79: case 'a': /* dump all (even large) */ 80: aflg++; 81: continue; 82: 83: case '-': 84: continue; 85: 86: case 'c': /* increment file name */ 87: cflg++; 88: continue; 89: 90: case 'f': /* file name from arg list */ 91: argc--; 92: argv++; 93: ofile = *argv; 94: continue; 95: 96: case 'i': /* date from date file */ 97: iflg++; 98: continue; 99: 100: case 's': /* tape size */ 101: tsize = number(argv[1]) * 9; 102: argv++; 103: argc--; 104: continue; 105: 106: case 'b': /* tape size */ 107: tsize = number(argv[1]); 108: argv++; 109: argc--; 110: continue; 111: 112: case 'u': /* rewrite date */ 113: dflg++; 114: continue; 115: 116: case '0': /* dump all */ 117: ddate[0] = ddate[1] = 0; 118: continue; 119: 120: case 'd': /* dump some number of days */ 121: i = 21600; 122: goto sd; 123: 124: case 'h': /* dump some number of hours */ 125: i = 900; 126: goto sd; 127: 128: sd: 129: ddate[0] = date[0]; 130: ddate[1] = date[1]; 131: s = number(argv[1])*4; 132: argv++; 133: argc--; 134: while(s) { 135: if(i > ddate[1]) 136: ddate[0]--; 137: ddate[1] =- i; 138: s--; 139: } 140: continue; 141: } 142: if(argc <= 1) { 143: printf("no file system specified\n"); 144: exit(); 145: } 146: if(iflg) { 147: f = open(dfile, 0); 148: if(f >= 0) { 149: read(f, dtab, sizeof dtab); 150: close(f); 151: for(i=0; i<10; i++) 152: if(equal(dtab[i].name, argv[1])) { 153: ddate[0] = dtab[i].date[0]; 154: ddate[1] = dtab[i].date[1]; 155: } 156: } 157: } 158: printf("%s:\n", argv[1]); 159: fi = open(argv[1], 0); 160: if(fi < 0) { 161: printf("cannot open %s\n", argv[1]); 162: exit(); 163: } 164: printf("incremental dump from\n"); 165: pdate(ddate); 166: sync(); 167: bread(1, &sblock); 168: talist = sbrk(size(0, sblock.s_isize*32)*512); 169: tap = talist; 170: if(tap == -1) { 171: printf("No memory\n"); 172: exit(); 173: } 174: nfil = 0; 175: nblk = size(0, sblock.s_isize*32); 176: ino = 0; 177: for(i=0; i<sblock.s_isize; i++) { 178: bread(i+2, buf); 179: for(ip = &buf[0]; ip < &buf[256]; ip++) { 180: ino++; 181: if(ip->i_mode == 0 || ip->i_nlink == 0) { 182: *tap++ = -1; 183: continue; 184: } 185: if(ip->i_mtime[0] < ddate[0]) 186: goto no; 187: if(ip->i_mtime[0] == ddate[0] && 188: ip->i_mtime[1] < ddate[1]) 189: goto no; 190: s = size(ip->i_size0&0377, ip->i_size1) + 1; 191: if (s>MAXSIZE && aflg==0 && iflg!=0) { 192: printf("%l big; not dumped.\n", ino); 193: goto no; 194: } 195: nfil++; 196: nblk =+ s; 197: *tap++ = s; 198: continue; 199: no: 200: *tap++ = 0; 201: } 202: } 203: printf("%l files\n%l blocks\n", nfil, nblk); 204: i = ldiv(0, nblk, ldiv(0, tsize, 10)); 205: printf("%l.%l tapes\n", i/10, i%10); 206: tap = buf; 207: clrbuf(tap); 208: *tap++ = sblock.s_isize; 209: *tap++ = sblock.s_fsize; 210: *tap++ = date[0]; 211: *tap++ = date[1]; 212: *tap++ = ddate[0]; 213: *tap++ = ddate[1]; 214: *tap++ = tsize; 215: swrite(buf); 216: i = size(0, sblock.s_isize*32); 217: tap = talist; 218: while(i--) { 219: bwrite(tap); 220: tap =+ 256; 221: } 222: tap = talist; 223: for(i=0; i<sblock.s_isize; i++) { 224: bread(i+2, buf); 225: for(ip = &buf[0]; ip < &buf[256]; ip++) { 226: if(*tap && *tap != -1) 227: dump(ip, *tap-1); 228: tap++; 229: } 230: } 231: printf("%l phase errors\n", pher); 232: if(!dflg) 233: exit(); 234: for(i=0; i<10; i++) 235: dtab[i].name[0] = 0; 236: f = open(dfile, 2); 237: if(f < 0) { 238: f = creat(dfile, 0666); 239: if(f < 0) { 240: printf("cannot create %s\n", dfile); 241: exit(); 242: } 243: } else 244: read(f, dtab, sizeof dtab); 245: for(i=0; i<10; i++) 246: if(dtab[i].name[0] == 0 || equal(dtab[i].name, argv[1])) 247: goto found; 248: printf("%s full\n", dfile); 249: exit(); 250: 251: found: 252: for(s=0; s<15; s++) { 253: dtab[i].name[s] = argv[1][s]; 254: if(argv[1][s] == 0) 255: break; 256: } 257: dtab[i].date[0] = date[0]; 258: dtab[i].date[1] = date[1]; 259: seek(f, 0, 0); 260: write(f, dtab, sizeof dtab); 261: printf("date updated\n"); 262: pdate(date); 263: } 264: 265: pdate(d) 266: int *d; 267: { 268: 269: if(d[0] == 0 && d[1] == 0) 270: printf("the epoch\n"); else 271: printf(ctime(d)); 272: } 273: 274: dump(ip, sz) 275: struct inode *ip; 276: { 277: register *p, *q, *r; 278: 279: p = dbuf; 280: q = ip; 281: clrbuf(p); 282: while(q < &ip->i_mtime[2]) 283: *p++ = *q++; 284: swrite(dbuf); 285: if(ip->i_mode & (IFBLK&IFCHR)) { 286: if(sz != 0) 287: printf("special\n"); 288: return; 289: } 290: for(p = &ip->i_addr[0]; p < &ip->i_addr[8]; p++) 291: if(*p) { 292: if(ip->i_mode&ILARG) { 293: bread(*p, ibuf); 294: for(q = &ibuf[0]; q < &ibuf[256]; q++) 295: if(*q) { 296: if(p == &ip->i_addr[7]) { 297: bread(*q, vbuf); 298: for(r = &vbuf[0]; r < &vbuf[256]; r++) 299: if(*r) { 300: if(--sz < 0) 301: goto pe; 302: bread(*r, dbuf); 303: bwrite(dbuf); 304: } 305: continue; 306: } 307: if(--sz < 0) 308: goto pe; 309: bread(*q, dbuf); 310: bwrite(dbuf); 311: } 312: } else { 313: if(--sz < 0) 314: goto pe; 315: bread(*p, dbuf); 316: bwrite(dbuf); 317: } 318: } 319: if(sz) 320: goto pe; 321: return; 322: 323: pe: 324: clrbuf(dbuf); 325: while(--sz >= 0) 326: bwrite(dbuf); 327: pher++; 328: } 329: 330: bread(bno, b) 331: { 332: 333: seek(fi, bno, 3); 334: if(read(fi, b, 512) != 512) { 335: printf("read error %l\n", bno); 336: } 337: } 338: 339: clrbuf(b) 340: int *b; 341: { 342: register i, *p; 343: 344: p = b; 345: i = 256; 346: while(i--) 347: *p++ = 0; 348: } 349: 350: swrite(b) 351: int *b; 352: { 353: register i, s, *p; 354: 355: i = 254; 356: s = taddr; 357: p = b; 358: while(i--) 359: s =+ *p++; 360: *p++ = taddr; 361: *p = 031415 - s; 362: bwrite(b); 363: } 364: 365: bwrite(b) 366: { 367: 368: if(taddr == 0) { 369: if(fo != -1) { 370: printf("change tapes\n"); 371: close(fo); 372: rdline(); 373: } 374: otape(); 375: } 376: wloop: 377: if(write(fo, b, 512) != 512) { 378: printf("write error\n"); 379: rdline(); 380: seek(fo, taddr, 3); 381: goto wloop; 382: } 383: taddr++; 384: if(taddr >= tsize) 385: taddr = 0; 386: } 387: 388: rdline() 389: { 390: int c; 391: 392: loop: 393: c = 0; 394: read(0, &c, 1); 395: if(c == 0) 396: exit(); 397: if(c != '\n') 398: goto loop; 399: } 400: 401: number(s) 402: char *s; 403: { 404: register n, c; 405: 406: n = 0; 407: while(c = *s++) { 408: if(c<'0' || c>'9') 409: continue; 410: n = n*10+c-'0'; 411: } 412: return(n); 413: } 414: 415: size(s0, s1) 416: { 417: register s; 418: extern ldivr; 419: 420: s = ldiv(s0&0377, s1, 512); 421: if(ldivr) 422: s++; 423: return(s); 424: } 425: 426: otape() 427: { 428: register char *p; 429: 430: fo = creat(ofile, 0666); 431: if(fo < 0) { 432: printf("can not open %s\n", ofile); 433: exit(); 434: } 435: if(!cflg) 436: return; 437: p = ofile; 438: while(*p++) 439: ; 440: p[-2]++; 441: } 442: 443: equal(a, b) 444: char *a, *b; 445: { 446: 447: while(*a++ == *b) 448: if(*b++ == 0) 449: return(1); 450: return(0); 451: }