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

Defined functions

checksum defined in line 411; used 1 times
checktype defined in line 403; used 6 times
checkvol defined in line 428; used 2 times
clearbuf defined in line 276; used 1 times
copy defined in line 265; used 1 times
direq defined in line 373; used 3 times
flsh defined in line 343; used 1 times
flsht defined in line 260; used 1 times
getent defined in line 306; used 1 times
getfile defined in line 174; used 1 times
gethead defined in line 391; used 5 times
main defined in line 56; never used
mseek defined in line 337; used 1 times
null defined in line 478; used 2 times
pass1 defined in line 96; used 1 times
  • in line 85
printem defined in line 132; used 2 times
putdir defined in line 447; used 2 times
putent defined in line 291; used 2 times
readbits defined in line 463; used 2 times
readc defined in line 329; used 2 times
readhdr defined in line 437; used 2 times
readtape defined in line 220; used 4 times
search defined in line 352; used 1 times
writec defined in line 322; used 2 times

Defined variables

bct defined in line 49; used 5 times
clrimap defined in line 46; used 1 times
dirfile defined in line 33; used 5 times
dumpmap defined in line 45; used 2 times
ipos defined in line 39; used 3 times
magtape defined in line 28; used 4 times
mt defined in line 26; used 5 times
ofile defined in line 31; never used
prebuf defined in line 52; used 2 times
seekpt defined in line 30; used 2 times
tapename defined in line 27; used 1 times
  • in line 28
tbf defined in line 50; used 3 times
volno defined in line 54; used 3 times

Defined macros

BIC defined in line 23; never used
BIS defined in line 22; never used
BIT defined in line 24; used 1 times
BITS defined in line 15; used 1 times
MAXINO defined in line 13; used 2 times
MAXXTR defined in line 16; never used
MBIT defined in line 21; used 3 times
MWORD defined in line 20; used 3 times
NCACHE defined in line 17; never used
ONTAPE defined in line 41; never used
XINUSE defined in line 43; never used
XTRACTD defined in line 42; never used
Last modified: 1981-12-07
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1558
Valid CSS Valid XHTML 1.0 Strict