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