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

Defined functions

checksum defined in line 450; used 1 times
checktype defined in line 442; used 6 times
checkvol defined in line 467; used 2 times
dcvt defined in line 191; used 1 times
flushent defined in line 342; used 1 times
getfile defined in line 207; used 1 times
gethead defined in line 411; used 5 times
ishead defined in line 418; used 1 times
main defined in line 62; never used
null defined in line 504; used 2 times
pass1 defined in line 103; used 1 times
  • in line 91
printem defined in line 146; used 2 times
putdir defined in line 293; used 2 times
putent defined in line 326; used 3 times
rddir defined in line 351; used 2 times
readbits defined in line 489; used 2 times
readhdr defined in line 476; used 2 times
readtape defined in line 253; used 4 times
search defined in line 386; used 1 times

Defined variables

bct defined in line 52; used 5 times
clrimap defined in line 49; used 1 times
cvtflag defined in line 60; used 5 times
dirfile defined in line 29; used 5 times
drblock defined in line 57; used 26 times
dumpmap defined in line 48; used 2 times
ipos defined in line 42; used 3 times
magtape defined in line 24; used 4 times
mt defined in line 22; used 5 times
ofile defined in line 27; never used
prebuf defined in line 55; used 2 times
prev defined in line 58; used 6 times
seekpt defined in line 26; used 2 times
tapename defined in line 23; used 1 times
  • in line 24
tbf defined in line 53; used 3 times
volno defined in line 60; used 3 times

Defined struct's

odirect defined in line 32; used 8 times

Defined macros

BIC defined in line 19; never used
BIS defined in line 18; never used
BIT defined in line 20; 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 17; used 3 times
MWORD defined in line 16; used 3 times
ODIRSIZ defined in line 31; used 2 times
ONTAPE defined in line 44; never used
XINUSE defined in line 46; never used
XTRACTD defined in line 45; never used
Last modified: 1990-04-30
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 4331
Valid CSS Valid XHTML 1.0 Strict