1: #include <stdio.h>
   2: 
   3: 
   4: /* old <sys/param.h> */
   5: #include <sys/types.h>
   6: #define BSIZE 512
   7: 
   8: /* old <sys/inode.h> */
   9: /* modes */
  10: #define IFMT    0170000     /* type of file */
  11: #define     IFDIR   0040000 /* directory */
  12: #define     IFCHR   0020000 /* character special */
  13: #define     IFMPC   0030000 /* multiplexed char special */
  14: #define     IFBLK   0060000 /* block special */
  15: #define     IFMPB   0070000 /* multiplexed block special */
  16: #define     IFREG   0100000 /* regular */
  17: #define     IFLNK   0120000 /* symbolic link */
  18: #define     IFQUOT  0140000 /* quota */
  19: #define ISUID   04000       /* set user id on execution */
  20: #define ISGID   02000       /* set group id on execution */
  21: #define ISVTX   01000       /* save swapped text even after use */
  22: #define IREAD   0400        /* read, write, execute permissions */
  23: #define IWRITE  0200
  24: #define IEXEC   0100
  25: 
  26: /* old <sys/ino.h> */
  27: /*
  28:  * Inode structure as it appears on
  29:  * a disk block.
  30:  */
  31: struct dinode
  32: {
  33:     u_short di_mode;        /* mode and type of file */
  34:     short   di_nlink;       /* number of links to file */
  35:     short   di_uid;         /* owner's user id */
  36:     short   di_gid;         /* owner's group id */
  37:     off_t   di_size;        /* number of bytes in file */
  38:     char    di_addr[40];    /* disk block addresses */
  39:     time_t  di_atime;       /* time last accessed */
  40:     time_t  di_mtime;       /* time last modified */
  41:     time_t  di_ctime;       /* time created */
  42: };
  43: 
  44: #define INOPB   8   /* 8 inodes per block */
  45: /*
  46:  *	39 of the address bytes are used;
  47:  *	13 addresses of 3 bytes each.
  48:  */
  49: 
  50: /* old <sys/dir.h> */
  51: #define DIRSIZ  14
  52: 
  53: struct  direct
  54: {
  55:     ino_t   d_ino;
  56:     char    d_name[DIRSIZ];
  57: };
  58: 
  59: /* old <dumprestor.h> */
  60: #define NTREC       20
  61: #define MLEN        16
  62: #define MSIZ        4096
  63: 
  64: #define TS_TAPE     1
  65: #define TS_INODE    2
  66: #define TS_BITS     3
  67: #define TS_ADDR     4
  68: #define TS_END      5
  69: #define TS_CLRI     6
  70: #define MAGIC       (int)60011
  71: #define CHECKSUM    (int)84446
  72: struct  spcl
  73: {
  74:     int c_type;
  75:     time_t  c_date;
  76:     time_t  c_ddate;
  77:     int c_volume;
  78:     daddr_t c_tapea;
  79:     ino_t   c_inumber;
  80:     int c_magic;
  81:     int c_checksum;
  82:     struct  dinode  c_dinode;
  83:     int c_count;
  84:     char    c_addr[BSIZE];
  85: } spcl;
  86: 
  87: struct  idates
  88: {
  89:     char    id_name[16];
  90:     char    id_incno;
  91:     time_t  id_ddate;
  92: };
  93: 
  94: /* end of old includes */
  95: 
  96: #ifdef NONSEPARATE
  97: #define MAXINO 1000
  98: #else
  99: #define MAXINO 2500
 100: #endif
 101: #define BITS    8
 102: #define MAXXTR  60
 103: #define NCACHE  3
 104: 
 105: 
 106: #define MWORD(m,i) (m[(unsigned)(i-1)/MLEN])
 107: #define MBIT(i) (1<<((unsigned)(i-1)%MLEN))
 108: #define BIS(i,w)    (MWORD(w,i) |=  MBIT(i))
 109: #define BIC(i,w)    (MWORD(w,i) &= ~MBIT(i))
 110: #define BIT(i,w)    (MWORD(w,i) & MBIT(i))
 111: 
 112: int mt;
 113: char    tapename[] = "/dev/rmt8";
 114: char    *magtape = tapename;
 115: 
 116: daddr_t seekpt;
 117: int ofile;
 118: FILE    *df;
 119: char    dirfile[] = "/tmp/rstXXXXXX";
 120: 
 121: struct {
 122:     ino_t   t_ino;
 123:     daddr_t t_seekpt;
 124: } inotab[MAXINO];
 125: int ipos;
 126: 
 127: #define ONTAPE  1
 128: #define XTRACTD 2
 129: #define XINUSE  4
 130: 
 131: short   dumpmap[MSIZ];
 132: short   clrimap[MSIZ];
 133: 
 134: 
 135: int bct = NTREC+1;
 136: char tbf[NTREC*BSIZE];
 137: 
 138: char prebuf[512];
 139: 
 140: int volno;
 141: 
 142: main(argc, argv)
 143: char *argv[];
 144: {
 145:     extern char *ctime();
 146: 
 147:     mktemp(dirfile);
 148:     argv++;
 149:     if (argc>=3 && *argv[0] == 'f')
 150:         magtape = *++argv;
 151:     df = fopen(dirfile, "w");
 152:     if (df == NULL) {
 153:         printf("dumpdir: %s - cannot create directory temporary\n", dirfile);
 154:         exit(1);
 155:     }
 156: 
 157:     if ((mt = open(magtape, 0)) < 0) {
 158:         printf("%s: cannot open tape\n", magtape);
 159:         exit(1);
 160:     }
 161:     if (readhdr(&spcl) == 0) {
 162:         printf("Tape is not a dump tape\n");
 163:         exit(1);
 164:     }
 165:     printf("Dump   date: %s", ctime(&spcl.c_date));
 166:     printf("Dumped from: %s", ctime(&spcl.c_ddate));
 167:     if (checkvol(&spcl, 1) == 0) {
 168:         printf("Tape is not volume 1 of the dump\n");
 169:         exit(1);
 170:     }
 171:     pass1();  /* This sets the various maps on the way by */
 172:     freopen(dirfile, "r", df);
 173:     strcpy(prebuf, "/");
 174:     printem(prebuf, (ino_t) 2);
 175:     exit(0);
 176: }
 177:     i = 0;
 178: /*
 179:  * Read the tape, bulding up a directory structure for extraction
 180:  * by name
 181:  */
 182: pass1()
 183: {
 184:     register i;
 185:     struct dinode *ip;
 186:     int putdir(), null();
 187: 
 188:     while (gethead(&spcl) == 0) {
 189:         printf("Can't find directory header!\n");
 190:     }
 191:     for (;;) {
 192:         if (checktype(&spcl, TS_BITS) == 1) {
 193:             readbits(dumpmap);
 194:             continue;
 195:         }
 196:         if (checktype(&spcl, TS_CLRI) == 1) {
 197:             readbits(clrimap);
 198:             continue;
 199:         }
 200:         if (checktype(&spcl, TS_INODE) == 0) {
 201: finish:
 202:             flsh();
 203:             close(mt);
 204:             return;
 205:         }
 206:         ip = &spcl.c_dinode;
 207:         i = ip->di_mode & IFMT;
 208:         if (i != IFDIR) {
 209:             goto finish;
 210:         }
 211:         inotab[ipos].t_ino = spcl.c_inumber;
 212:         inotab[ipos++].t_seekpt = seekpt;
 213:         getfile(spcl.c_inumber, putdir, null, spcl.c_dinode.di_size);
 214:         putent("\000\000/");
 215:     }
 216: }
 217: 
 218: printem(prefix, inum)
 219: char *prefix;
 220: ino_t   inum;
 221: {
 222:     struct direct dir;
 223:     register int i;
 224: 
 225:     for (i = 0; i < MAXINO; i++)
 226:         if (inotab[i].t_ino == inum) {
 227:             goto found;
 228:         }
 229:     printf("PANIC - can't find directory %d\n", inum);
 230:     return;
 231: found:
 232:     mseek(inotab[i].t_seekpt);
 233:     for (;;) {
 234:         getent((char *) &dir);
 235:         if (direq(dir.d_name, "/"))
 236:             return;
 237:         if (search(dir.d_ino) != 0 && direq(dir.d_name, ".") == 0 && direq(dir.d_name, "..") == 0) {
 238:             int len;
 239:             FILE *tdf;
 240: 
 241:             tdf = df;
 242:             df = fopen(dirfile, "r");
 243:             len = strlen(prefix);
 244:             strncat(prefix, dir.d_name, sizeof(dir.d_name));
 245:             strcat(prefix, "/");
 246:             printem(prefix, dir.d_ino);
 247:             prefix[len] = '\0';
 248:             fclose(df);
 249:             df = tdf;
 250:         }
 251:         else
 252:             if (BIT(dir.d_ino, dumpmap))
 253:                 printf("%5d	%s%-.14s\n", dir.d_ino, prefix, dir.d_name);
 254:     }
 255: }
 256: /*
 257:  * Do the file extraction, calling the supplied functions
 258:  * with the blocks
 259:  */
 260: getfile(n, f1, f2, size)
 261: ino_t   n;
 262: int (*f2)(), (*f1)();
 263: long    size;
 264: {
 265:     register i;
 266:     struct spcl addrblock;
 267:     char buf[BSIZE];
 268: 
 269:     addrblock = spcl;
 270:     goto start;
 271:     for (;;) {
 272:         if (gethead(&addrblock) == 0) {
 273:             printf("Missing address (header) block\n");
 274:             goto eloop;
 275:         }
 276:         if (checktype(&addrblock, TS_ADDR) == 0) {
 277:             spcl = addrblock;
 278:             return;
 279:         }
 280: start:
 281:         for (i = 0; i < addrblock.c_count; i++) {
 282:             if (addrblock.c_addr[i]) {
 283:                 readtape(buf);
 284:                 (*f1)(buf, size > BSIZE ? (long) BSIZE : size);
 285:             }
 286:             else {
 287:                 clearbuf(buf);
 288:                 (*f2)(buf, size > BSIZE ? (long) BSIZE : size);
 289:             }
 290:             if ((size -= BSIZE) <= 0) {
 291: eloop:
 292:                 while (gethead(&spcl) == 0)
 293:                     ;
 294:                 if (checktype(&spcl, TS_ADDR) == 1)
 295:                     goto eloop;
 296:                 return;
 297:             }
 298:         }
 299:     }
 300: }
 301: 
 302: /*
 303:  * Do the tape i\/o, dealling with volume changes
 304:  * etc..
 305:  */
 306: readtape(b)
 307: char *b;
 308: {
 309:     register i;
 310:     struct spcl tmpbuf;
 311: 
 312:     if (bct >= NTREC) {
 313:         for (i = 0; i < NTREC; i++)
 314:             ((struct spcl *)&tbf[i*BSIZE])->c_magic = 0;
 315:         bct = 0;
 316:         if ((i = read(mt, tbf, NTREC*BSIZE)) < 0) {
 317:             exit(1);
 318:         }
 319:         if (i == 0) {
 320:             bct = NTREC + 1;
 321:             volno++;
 322: loop:
 323:             flsht();
 324:             close(mt);
 325:             printf("Mount volume %d\n", volno);
 326:             while (getchar() != '\n')
 327:                 ;
 328:             if ((mt = open(magtape, 0)) == -1) {
 329:                 printf("Cannot open tape!\n");
 330:             }
 331:             if (readhdr(&tmpbuf) == 0) {
 332:                 printf("Not a dump tape.Try again\n");
 333:                 goto loop;
 334:             }
 335:             if (checkvol(&tmpbuf, volno) == 0) {
 336:                 printf("Wrong tape. Try again\n");
 337:                 goto loop;
 338:             }
 339:             readtape(b);
 340:             return;
 341:         }
 342:     }
 343:     copy(&tbf[(bct++*BSIZE)], b, BSIZE);
 344: }
 345: 
 346: flsht()
 347: {
 348:     bct = NTREC+1;
 349: }
 350: 
 351: copy(f, t, s)
 352: register char *f, *t;
 353: {
 354:     register i;
 355: 
 356:     i = s;
 357:     do
 358:         *t++ = *f++;
 359:     while (--i);
 360: }
 361: 
 362: clearbuf(cp)
 363: register char *cp;
 364: {
 365:     register i;
 366: 
 367:     i = BSIZE;
 368:     do
 369:         *cp++ = 0;
 370:     while (--i);
 371: }
 372: 
 373: /*
 374:  * Put and get the directory entries from the compressed
 375:  * directory file
 376:  */
 377: putent(cp)
 378: char    *cp;
 379: {
 380:     register i;
 381: 
 382:     for (i = 0; i < sizeof(ino_t); i++)
 383:         writec(*cp++);
 384:     for (i = 0; i < DIRSIZ; i++) {
 385:         writec(*cp);
 386:         if (*cp++ == 0)
 387:             return;
 388:     }
 389:     return;
 390: }
 391: 
 392: getent(bf)
 393: register char *bf;
 394: {
 395:     register i;
 396: 
 397:     for (i = 0; i < sizeof(ino_t); i++)
 398:         *bf++ = readc();
 399:     for (i = 0; i < DIRSIZ; i++)
 400:         if ((*bf++ = readc()) == 0)
 401:             return;
 402:     return;
 403: }
 404: 
 405: /*
 406:  * read/write te directory file
 407:  */
 408: writec(c)
 409: char c;
 410: {
 411:     seekpt++;
 412:     fwrite(&c, 1, 1, df);
 413: }
 414: 
 415: readc()
 416: {
 417:     char c;
 418: 
 419:     fread(&c, 1, 1, df);
 420:     return(c);
 421: }
 422: 
 423: mseek(pt)
 424: daddr_t pt;
 425: {
 426:     fseek(df, pt, 0);
 427: }
 428: 
 429: flsh()
 430: {
 431:     fflush(df);
 432: }
 433: 
 434: /*
 435:  * search the directory inode ino
 436:  * looking for entry cp
 437:  */
 438: search(inum)
 439: ino_t   inum;
 440: {
 441:     register low, high, probe;
 442: 
 443:     low = 0;
 444:     high = ipos-1;
 445: 
 446:     while (low != high) {
 447:         probe = (high - low + 1)/2 + low;
 448: /*
 449: printf("low = %d, high = %d, probe = %d, ino = %d, inum = %d\n", low, high, probe, inum, inotab[probe].t_ino);
 450: */
 451:         if (inum >= inotab[probe].t_ino)
 452:             low = probe;
 453:         else
 454:             high = probe - 1;
 455:     }
 456:     return(inum == inotab[low].t_ino);
 457: }
 458: 
 459: direq(s1, s2)
 460: register char *s1, *s2;
 461: {
 462:     register i;
 463: 
 464:     for (i = 0; i < DIRSIZ; i++)
 465:         if (*s1++ == *s2) {
 466:             if (*s2++ == 0)
 467:                 return(1);
 468:         } else
 469:             return(0);
 470:     return(1);
 471: }
 472: 
 473: /*
 474:  * read the tape into buf, then return whether or
 475:  * or not it is a header block.
 476:  */
 477: gethead(buf)
 478: struct spcl *buf;
 479: {
 480:     readtape((char *)buf);
 481:     if (buf->c_magic != MAGIC || checksum((int *) buf) == 0)
 482:         return(0);
 483:     return(1);
 484: }
 485: 
 486: /*
 487:  * return whether or not the buffer contains a header block
 488:  */
 489: checktype(b, t)
 490: struct  spcl *b;
 491: int t;
 492: {
 493:     return(b->c_type == t);
 494: }
 495: 
 496: 
 497: checksum(b)
 498: int *b;
 499: {
 500:     register i, j;
 501: 
 502:     j = BSIZE/sizeof(int);
 503:     i = 0;
 504:     do
 505:         i += *b++;
 506:     while (--j);
 507:     if (i != CHECKSUM) {
 508:         printf("Checksum error %o\n", i);
 509:         return(0);
 510:     }
 511:     return(1);
 512: }
 513: 
 514: checkvol(b, t)
 515: struct spcl *b;
 516: int t;
 517: {
 518:     if (b->c_volume == t)
 519:         return(1);
 520:     return(0);
 521: }
 522: 
 523: readhdr(b)
 524: struct  spcl *b;
 525: {
 526:     if (gethead(b) == 0)
 527:         return(0);
 528:     if (checktype(b, TS_TAPE) == 0)
 529:         return(0);
 530:     return(1);
 531: }
 532: 
 533: putdir(b)
 534: char *b;
 535: {
 536:     register struct direct *dp;
 537:     register i;
 538: 
 539:     for (dp = (struct direct *) b, i = 0; i < BSIZE; dp++, i += sizeof(*dp)) {
 540:         if (dp->d_ino == 0)
 541:             continue;
 542:         putent((char *) dp);
 543:     }
 544: }
 545: 
 546: /*
 547:  * read a bit mask from the tape into m.
 548:  */
 549: readbits(m)
 550: short   *m;
 551: {
 552:     register i;
 553: 
 554:     i = spcl.c_count;
 555: 
 556:     while (i--) {
 557:         readtape((char *) m);
 558:         m += (BSIZE/(MLEN/BITS));
 559:     }
 560:     while (gethead(&spcl) == 0)
 561:         ;
 562: }
 563: 
 564: null() { ; }

Defined functions

checksum defined in line 497; used 1 times
checktype defined in line 489; used 6 times
checkvol defined in line 514; used 2 times
clearbuf defined in line 362; used 1 times
copy defined in line 351; used 1 times
direq defined in line 459; used 3 times
flsh defined in line 429; used 1 times
flsht defined in line 346; used 1 times
getent defined in line 392; used 1 times
getfile defined in line 260; used 1 times
gethead defined in line 477; used 5 times
main defined in line 142; never used
mseek defined in line 423; used 1 times
null defined in line 564; used 2 times
pass1 defined in line 182; used 1 times
printem defined in line 218; used 2 times
putdir defined in line 533; used 2 times
putent defined in line 377; used 2 times
readbits defined in line 549; used 2 times
readc defined in line 415; used 2 times
readhdr defined in line 523; used 2 times
readtape defined in line 306; used 4 times
search defined in line 438; used 1 times
writec defined in line 408; used 2 times

Defined variables

bct defined in line 135; used 5 times
clrimap defined in line 132; used 1 times
dirfile defined in line 119; used 5 times
dumpmap defined in line 131; used 2 times
ipos defined in line 125; used 3 times
magtape defined in line 114; used 4 times
mt defined in line 112; used 5 times
ofile defined in line 117; never used
prebuf defined in line 138; used 2 times
seekpt defined in line 116; used 2 times
spcl defined in line 85; used 18 times
tapename defined in line 113; used 1 times
tbf defined in line 136; used 3 times
volno defined in line 140; used 3 times

Defined struct's

dinode defined in line 31; used 4 times
direct defined in line 53; used 6 times
idates defined in line 87; never used
spcl defined in line 72; used 14 times

Defined macros

BIC defined in line 109; never used
BIS defined in line 108; never used
BIT defined in line 110; used 1 times
BITS defined in line 101; used 1 times
BSIZE defined in line 6; used 16 times
CHECKSUM defined in line 71; used 1 times
DIRSIZ defined in line 51; used 4 times
IEXEC defined in line 24; never used
IFBLK defined in line 14; never used
IFCHR defined in line 12; never used
IFDIR defined in line 11; used 1 times
IFLNK defined in line 17; never used
IFMPB defined in line 15; never used
IFMPC defined in line 13; never used
IFMT defined in line 10; used 1 times
IFQUOT defined in line 18; never used
IFREG defined in line 16; never used
INOPB defined in line 44; never used
IREAD defined in line 22; never used
ISGID defined in line 20; never used
ISUID defined in line 19; never used
ISVTX defined in line 21; never used
IWRITE defined in line 23; never used
MAGIC defined in line 70; used 1 times
MAXINO defined in line 99; used 2 times
MAXXTR defined in line 102; never used
MBIT defined in line 107; used 3 times
MLEN defined in line 61; used 3 times
MSIZ defined in line 62; used 2 times
MWORD defined in line 106; used 3 times
NCACHE defined in line 103; never used
NTREC defined in line 60; used 7 times
ONTAPE defined in line 127; never used
TS_ADDR defined in line 67; used 2 times
TS_BITS defined in line 66; used 1 times
TS_CLRI defined in line 69; used 1 times
TS_END defined in line 68; never used
TS_INODE defined in line 65; used 1 times
TS_TAPE defined in line 64; used 1 times
XINUSE defined in line 129; never used
XTRACTD defined in line 128; never used
Last modified: 1987-08-06
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 4761
Valid CSS Valid XHTML 1.0 Strict