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