1: #include <whoami.h> 2: #undef UCB_NKB 3: #include <stdio.h> 4: #include <sys/param.h> 5: #include <sys/inode.h> 6: #include <sys/ino.h> 7: #include <sys/fblk.h> 8: #include <sys/filsys.h> 9: #include <sys/dir.h> 10: #undef BSIZE 11: #define BSIZE 512 12: /* old <dumprestor.h> */ 13: #define NTREC 20 14: #define MLEN 16 15: #define MSIZ 4096 16: 17: #define TS_TAPE 1 18: #define TS_INODE 2 19: #define TS_BITS 3 20: #define TS_ADDR 4 21: #define TS_END 5 22: #define TS_CLRI 6 23: #define MAGIC (int)60011 24: #define CHECKSUM (int)84446 25: struct spcl 26: { 27: int c_type; 28: time_t c_date; 29: time_t c_ddate; 30: int c_volume; 31: daddr_t c_tapea; 32: ino_t c_inumber; 33: int c_magic; 34: int c_checksum; 35: struct dinode c_dinode; 36: int c_count; 37: char c_addr[BSIZE]; 38: } spcl; 39: 40: struct idates 41: { 42: char id_name[16]; 43: char id_incno; 44: time_t id_ddate; 45: }; 46: 47: /* end of old <dumprestor.h> */ 48: #ifdef NONSEPARATE 49: #define MAXINO 1000 50: #else 51: #define MAXINO 3000 52: #endif 53: #define BITS 8 54: #define MAXXTR 60 55: #define NCACHE 3 56: 57: 58: #define MWORD(m,i) (m[(unsigned)(i-1)/MLEN]) 59: #define MBIT(i) (1<<((unsigned)(i-1)%MLEN)) 60: #define BIS(i,w) (MWORD(w,i) |= MBIT(i)) 61: #define BIC(i,w) (MWORD(w,i) &= ~MBIT(i)) 62: #define BIT(i,w) (MWORD(w,i) & MBIT(i)) 63: 64: int mt; 65: char tapename[] = "/dev/rmt1"; 66: char *magtape = tapename; 67: 68: daddr_t seekpt; 69: int ofile; 70: FILE *df; 71: char dirfile[] = "/tmp/rstXXXXXX"; 72: 73: struct { 74: ino_t t_ino; 75: daddr_t t_seekpt; 76: } inotab[MAXINO]; 77: int ipos; 78: 79: #define ONTAPE 1 80: #define XTRACTD 2 81: #define XINUSE 4 82: 83: short dumpmap[MSIZ]; 84: short clrimap[MSIZ]; 85: 86: 87: int bct = NTREC+1; 88: char tbf[NTREC*BSIZE]; 89: 90: char prebuf[512]; 91: 92: int volno; 93: 94: main(argc, argv) 95: char *argv[]; 96: { 97: extern char *ctime(); 98: 99: mktemp(dirfile); 100: argv++; 101: if (argc>=3 && *argv[0] == 'f') 102: magtape = *++argv; 103: df = fopen(dirfile, "w"); 104: if (df == NULL) { 105: printf("dumpdir: %s - cannot create directory temporary\n", dirfile); 106: exit(1); 107: } 108: 109: if ((mt = open(magtape, 0)) < 0) { 110: printf("%s: cannot open tape\n", magtape); 111: exit(1); 112: } 113: if (readhdr(&spcl) == 0) { 114: printf("Tape is not a dump tape\n"); 115: exit(1); 116: } 117: printf("Dump date: %s", ctime(&spcl.c_date)); 118: printf("Dumped from: %s", ctime(&spcl.c_ddate)); 119: if (checkvol(&spcl, 1) == 0) { 120: printf("Tape is not volume 1 of the dump\n"); 121: exit(1); 122: } 123: pass1(); /* This sets the various maps on the way by */ 124: freopen(dirfile, "r", df); 125: strcpy(prebuf, "/"); 126: printem(prebuf, (ino_t) 2); 127: exit(0); 128: } 129: i = 0; 130: /* 131: * Read the tape, bulding up a directory structure for extraction 132: * by name 133: */ 134: pass1() 135: { 136: register i; 137: struct dinode *ip; 138: int putdir(), null(); 139: 140: while (gethead(&spcl) == 0) { 141: printf("Can't find directory header!\n"); 142: } 143: for (;;) { 144: if (checktype(&spcl, TS_BITS) == 1) { 145: readbits(dumpmap); 146: continue; 147: } 148: if (checktype(&spcl, TS_CLRI) == 1) { 149: readbits(clrimap); 150: continue; 151: } 152: if (checktype(&spcl, TS_INODE) == 0) { 153: finish: 154: flsh(); 155: close(mt); 156: return; 157: } 158: ip = &spcl.c_dinode; 159: i = ip->di_mode & IFMT; 160: if (i != IFDIR) { 161: goto finish; 162: } 163: inotab[ipos].t_ino = spcl.c_inumber; 164: inotab[ipos++].t_seekpt = seekpt; 165: getfile(spcl.c_inumber, putdir, null, spcl.c_dinode.di_size); 166: putent("\000\000/"); 167: } 168: } 169: 170: printem(prefix, inum) 171: char *prefix; 172: ino_t inum; 173: { 174: struct direct dir; 175: register int i; 176: 177: for (i = 0; i < MAXINO; i++) 178: if (inotab[i].t_ino == inum) { 179: goto found; 180: } 181: printf("PANIC - can't find directory %d\n", inum); 182: return; 183: found: 184: mseek(inotab[i].t_seekpt); 185: for (;;) { 186: getent((char *) &dir); 187: if (direq(dir.d_name, "/")) 188: return; 189: if (search(dir.d_ino) != 0 && direq(dir.d_name, ".") == 0 && direq(dir.d_name, "..") == 0) { 190: int len; 191: FILE *tdf; 192: 193: tdf = df; 194: df = fopen(dirfile, "r"); 195: len = strlen(prefix); 196: strncat(prefix, dir.d_name, sizeof(dir.d_name)); 197: strcat(prefix, "/"); 198: printem(prefix, dir.d_ino); 199: prefix[len] = '\0'; 200: fclose(df); 201: df = tdf; 202: } 203: else 204: if (BIT(dir.d_ino, dumpmap)) 205: printf("%5d %s%-.14s\n", dir.d_ino, prefix, dir.d_name); 206: } 207: } 208: /* 209: * Do the file extraction, calling the supplied functions 210: * with the blocks 211: */ 212: getfile(n, f1, f2, size) 213: ino_t n; 214: int (*f2)(), (*f1)(); 215: long size; 216: { 217: register i; 218: struct spcl addrblock; 219: char buf[BSIZE]; 220: 221: addrblock = spcl; 222: goto start; 223: for (;;) { 224: if (gethead(&addrblock) == 0) { 225: printf("Missing address (header) block\n"); 226: goto eloop; 227: } 228: if (checktype(&addrblock, TS_ADDR) == 0) { 229: spcl = addrblock; 230: return; 231: } 232: start: 233: for (i = 0; i < addrblock.c_count; i++) { 234: if (addrblock.c_addr[i]) { 235: readtape(buf); 236: (*f1)(buf, size > BSIZE ? (long) BSIZE : size); 237: } 238: else { 239: clearbuf(buf); 240: (*f2)(buf, size > BSIZE ? (long) BSIZE : size); 241: } 242: if ((size -= BSIZE) <= 0) { 243: eloop: 244: while (gethead(&spcl) == 0) 245: ; 246: if (checktype(&spcl, TS_ADDR) == 1) 247: goto eloop; 248: return; 249: } 250: } 251: } 252: } 253: 254: /* 255: * Do the tape i\/o, dealling with volume changes 256: * etc.. 257: */ 258: readtape(b) 259: char *b; 260: { 261: register i; 262: struct spcl tmpbuf; 263: 264: if (bct >= NTREC) { 265: for (i = 0; i < NTREC; i++) 266: ((struct spcl *)&tbf[i*BSIZE])->c_magic = 0; 267: bct = 0; 268: if ((i = read(mt, tbf, NTREC*BSIZE)) < 0) { 269: exit(1); 270: } 271: if (i == 0) { 272: bct = NTREC + 1; 273: volno++; 274: loop: 275: flsht(); 276: close(mt); 277: printf("Mount volume %d\n", volno); 278: while (getchar() != '\n') 279: ; 280: if ((mt = open(magtape, 0)) == -1) { 281: printf("Cannot open tape!\n"); 282: } 283: if (readhdr(&tmpbuf) == 0) { 284: printf("Not a dump tape.Try again\n"); 285: goto loop; 286: } 287: if (checkvol(&tmpbuf, volno) == 0) { 288: printf("Wrong tape. Try again\n"); 289: goto loop; 290: } 291: readtape(b); 292: return; 293: } 294: } 295: copy(&tbf[(bct++*BSIZE)], b, BSIZE); 296: } 297: 298: flsht() 299: { 300: bct = NTREC+1; 301: } 302: 303: copy(f, t, s) 304: register char *f, *t; 305: { 306: register i; 307: 308: i = s; 309: do 310: *t++ = *f++; 311: while (--i); 312: } 313: 314: clearbuf(cp) 315: register char *cp; 316: { 317: register i; 318: 319: i = BSIZE; 320: do 321: *cp++ = 0; 322: while (--i); 323: } 324: 325: /* 326: * Put and get the directory entries from the compressed 327: * directory file 328: */ 329: putent(cp) 330: char *cp; 331: { 332: register i; 333: 334: for (i = 0; i < sizeof(ino_t); i++) 335: writec(*cp++); 336: for (i = 0; i < DIRSIZ; i++) { 337: writec(*cp); 338: if (*cp++ == 0) 339: return; 340: } 341: return; 342: } 343: 344: getent(bf) 345: register char *bf; 346: { 347: register i; 348: 349: for (i = 0; i < sizeof(ino_t); i++) 350: *bf++ = readc(); 351: for (i = 0; i < DIRSIZ; i++) 352: if ((*bf++ = readc()) == 0) 353: return; 354: return; 355: } 356: 357: /* 358: * read/write te directory file 359: */ 360: writec(c) 361: char c; 362: { 363: seekpt++; 364: fwrite(&c, 1, 1, df); 365: } 366: 367: readc() 368: { 369: char c; 370: 371: fread(&c, 1, 1, df); 372: return(c); 373: } 374: 375: mseek(pt) 376: daddr_t pt; 377: { 378: fseek(df, pt, 0); 379: } 380: 381: flsh() 382: { 383: fflush(df); 384: } 385: 386: /* 387: * search the directory inode ino 388: * looking for entry cp 389: */ 390: search(inum) 391: ino_t inum; 392: { 393: register low, high, probe; 394: 395: low = 0; 396: high = ipos-1; 397: 398: while (low != high) { 399: probe = (high - low + 1)/2 + low; 400: /* 401: printf("low = %d, high = %d, probe = %d, ino = %d, inum = %d\n", low, high, probe, inum, inotab[probe].t_ino); 402: */ 403: if (inum >= inotab[probe].t_ino) 404: low = probe; 405: else 406: high = probe - 1; 407: } 408: return(inum == inotab[low].t_ino); 409: } 410: 411: direq(s1, s2) 412: register char *s1, *s2; 413: { 414: register i; 415: 416: for (i = 0; i < DIRSIZ; i++) 417: if (*s1++ == *s2) { 418: if (*s2++ == 0) 419: return(1); 420: } else 421: return(0); 422: return(1); 423: } 424: 425: /* 426: * read the tape into buf, then return whether or 427: * or not it is a header block. 428: */ 429: gethead(buf) 430: struct spcl *buf; 431: { 432: readtape((char *)buf); 433: if (buf->c_magic != MAGIC || checksum((int *) buf) == 0) 434: return(0); 435: return(1); 436: } 437: 438: /* 439: * return whether or not the buffer contains a header block 440: */ 441: checktype(b, t) 442: struct spcl *b; 443: int t; 444: { 445: return(b->c_type == t); 446: } 447: 448: 449: checksum(b) 450: int *b; 451: { 452: register i, j; 453: 454: j = BSIZE/sizeof(int); 455: i = 0; 456: do 457: i += *b++; 458: while (--j); 459: if (i != CHECKSUM) { 460: printf("Checksum error %o\n", i); 461: return(0); 462: } 463: return(1); 464: } 465: 466: checkvol(b, t) 467: struct spcl *b; 468: int t; 469: { 470: if (b->c_volume == t) 471: return(1); 472: return(0); 473: } 474: 475: readhdr(b) 476: struct spcl *b; 477: { 478: if (gethead(b) == 0) 479: return(0); 480: if (checktype(b, TS_TAPE) == 0) 481: return(0); 482: return(1); 483: } 484: 485: putdir(b) 486: char *b; 487: { 488: register struct direct *dp; 489: register i; 490: 491: for (dp = (struct direct *) b, i = 0; i < BSIZE; dp++, i += sizeof(*dp)) { 492: if (dp->d_ino == 0) 493: continue; 494: putent((char *) dp); 495: } 496: } 497: 498: /* 499: * read a bit mask from the tape into m. 500: */ 501: readbits(m) 502: short *m; 503: { 504: register i; 505: 506: i = spcl.c_count; 507: 508: while (i--) { 509: readtape((char *) m); 510: m += (BSIZE/(MLEN/BITS)); 511: } 512: while (gethead(&spcl) == 0) 513: ; 514: } 515: 516: null() { ; }