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