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

Defined functions

checksum defined in line 409; used 1 times
checktype defined in line 401; used 6 times
checkvol defined in line 426; used 2 times
clearbuf defined in line 274; used 1 times
copy defined in line 263; used 1 times
direq defined in line 371; used 3 times
flsh defined in line 341; used 1 times
flsht defined in line 258; used 1 times
getent defined in line 304; used 1 times
getfile defined in line 172; used 1 times
gethead defined in line 389; used 5 times
main defined in line 54; never used
mseek defined in line 335; used 1 times
null defined in line 476; used 2 times
pass1 defined in line 94; used 1 times
  • in line 83
printem defined in line 130; used 2 times
putdir defined in line 445; used 2 times
putent defined in line 289; used 2 times
readbits defined in line 461; used 2 times
readc defined in line 327; used 2 times
readhdr defined in line 435; used 2 times
readtape defined in line 218; used 4 times
search defined in line 350; used 1 times
writec defined in line 320; used 2 times

Defined variables

bct defined in line 47; used 5 times
clrimap defined in line 44; used 1 times
dirfile defined in line 31; used 5 times
dumpmap defined in line 43; used 2 times
ipos defined in line 37; used 3 times
magtape defined in line 26; used 4 times
mt defined in line 24; used 5 times
ofile defined in line 29; never used
prebuf defined in line 50; used 2 times
seekpt defined in line 28; used 2 times
tapename defined in line 25; used 1 times
  • in line 26
tbf defined in line 48; used 3 times
volno defined in line 52; used 3 times

Defined macros

BIC defined in line 21; never used
BIS defined in line 20; never used
BIT defined in line 22; used 1 times
BITS defined in line 13; used 1 times
MAXINO defined in line 11; used 2 times
MAXXTR defined in line 14; never used
MBIT defined in line 19; used 3 times
MWORD defined in line 18; used 3 times
NCACHE defined in line 15; never used
ONTAPE defined in line 39; never used
XINUSE defined in line 41; never used
XTRACTD defined in line 40; never used
Last modified: 1988-12-25
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 4600
Valid CSS Valid XHTML 1.0 Strict