1: #include <stdio.h>
   2: #include <sys/types.h>
   3: #include <sys/stat.h>
   4: #include <sys/dir.h>
   5: #include <signal.h>
   6: 
   7: char    *sprintf();
   8: char    *strcat();
   9: daddr_t bsrch();
  10: #define TBLOCK  512
  11: #define NBLOCK  20
  12: #define NAMSIZ  100
  13: union hblock {
  14:     char dummy[TBLOCK];
  15:     struct header {
  16:         char name[NAMSIZ];
  17:         char mode[8];
  18:         char uid[8];
  19:         char gid[8];
  20:         char size[12];
  21:         char mtime[12];
  22:         char chksum[8];
  23:         char linkflag;
  24:         char linkname[NAMSIZ];
  25:     } dbuf;
  26: } dblock, tbuf[NBLOCK];
  27: 
  28: struct linkbuf {
  29:     ino_t   inum;
  30:     dev_t   devnum;
  31:     int count;
  32:     char    pathname[NAMSIZ];
  33:     struct  linkbuf *nextp;
  34: } *ihead;
  35: 
  36: struct stat stbuf;
  37: 
  38: int rflag, xflag, vflag, tflag, mt, cflag, mflag;
  39: int term, chksum, wflag, recno, first, linkerrok;
  40: int freemem = 1;
  41: int nblock = 1;
  42: 
  43: daddr_t low;
  44: daddr_t high;
  45: 
  46: FILE    *tfile;
  47: char    tname[] = "/tmp/tarXXXXXX";
  48: 
  49: 
  50: char    *usefile;
  51: char    magtape[]   = "/dev/mt1";
  52: 
  53: char    *malloc();
  54: 
  55: main(argc, argv)
  56: int argc;
  57: char    *argv[];
  58: {
  59:     char *cp;
  60:     int onintr(), onquit(), onhup(), onterm();
  61: 
  62:     if (argc < 2)
  63:         usage();
  64: 
  65:     tfile = NULL;
  66:     usefile =  magtape;
  67:     argv[argc] = 0;
  68:     argv++;
  69:     for (cp = *argv++; *cp; cp++)
  70:         switch(*cp) {
  71:         case 'f':
  72:             usefile = *argv++;
  73:             if (nblock == 1)
  74:                 nblock = 0;
  75:             break;
  76:         case 'c':
  77:             cflag++;
  78:             rflag++;
  79:             break;
  80:         case 'u':
  81:             mktemp(tname);
  82:             if ((tfile = fopen(tname, "w")) == NULL) {
  83:                 fprintf(stderr, "Tar: cannot create temporary file (%s)\n", tname);
  84:                 done(1);
  85:             }
  86:             fprintf(tfile, "!!!!!/!/!/!/!/!/!/! 000\n");
  87:             /* FALL THROUGH */
  88:         case 'r':
  89:             rflag++;
  90:             if (nblock != 1 && cflag == 0) {
  91: noupdate:
  92:                 fprintf(stderr, "Tar: Blocked tapes cannot be updated (yet)\n");
  93:                 done(1);
  94:             }
  95:             break;
  96:         case 'v':
  97:             vflag++;
  98:             break;
  99:         case 'w':
 100:             wflag++;
 101:             break;
 102:         case 'x':
 103:             xflag++;
 104:             break;
 105:         case 't':
 106:             tflag++;
 107:             break;
 108:         case 'm':
 109:             mflag++;
 110:             break;
 111:         case '-':
 112:             break;
 113:         case '0':
 114:         case '1':
 115:             magtape[7] = *cp;
 116:             usefile = magtape;
 117:             break;
 118:         case 'b':
 119:             nblock = atoi(*argv++);
 120:             if (nblock > NBLOCK || nblock <= 0) {
 121:                 fprintf(stderr, "Invalid blocksize. (Max %d)\n", NBLOCK);
 122:                 done(1);
 123:             }
 124:             if (rflag && !cflag)
 125:                 goto noupdate;
 126:             break;
 127:         case 'l':
 128:             linkerrok++;
 129:             break;
 130:         default:
 131:             fprintf(stderr, "tar: %c: unknown option\n", *cp);
 132:             usage();
 133:         }
 134: 
 135:     if (rflag) {
 136:         if (cflag && tfile != NULL) {
 137:             usage();
 138:             done(1);
 139:         }
 140:         if (signal(SIGINT, SIG_IGN) != SIG_IGN)
 141:             signal(SIGINT, onintr);
 142:         if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
 143:             signal(SIGHUP, onhup);
 144:         if (signal(SIGQUIT, SIG_IGN) != SIG_IGN)
 145:             signal(SIGQUIT, onquit);
 146: /*
 147: 		if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
 148: 			signal(SIGTERM, onterm);
 149: */
 150:         if (strcmp(usefile, "-") == 0) {
 151:             if (cflag == 0) {
 152:                 fprintf(stderr, "Can only create standard output archives\n");
 153:                 done(1);
 154:             }
 155:             mt = dup(1);
 156:             nblock = 1;
 157:         }
 158:         else if ((mt = open(usefile, 2)) < 0) {
 159:             if (cflag == 0 || (mt =  creat(usefile, 0666)) < 0) {
 160:                 fprintf(stderr, "tar: cannot open %s\n", usefile);
 161:                 done(1);
 162:             }
 163:         }
 164:         if (cflag == 0 && nblock == 0)
 165:             nblock = 1;
 166:         dorep(argv);
 167:     }
 168:     else if (xflag)  {
 169:         if (strcmp(usefile, "-") == 0) {
 170:             mt = dup(0);
 171:             nblock = 1;
 172:         }
 173:         else if ((mt = open(usefile, 0)) < 0) {
 174:             fprintf(stderr, "tar: cannot open %s\n", usefile);
 175:             done(1);
 176:         }
 177:         doxtract(argv);
 178:     }
 179:     else if (tflag) {
 180:         if (strcmp(usefile, "-") == 0) {
 181:             mt = dup(0);
 182:             nblock = 1;
 183:         }
 184:         else if ((mt = open(usefile, 0)) < 0) {
 185:             fprintf(stderr, "tar: cannot open %s\n", usefile);
 186:             done(1);
 187:         }
 188:         dotable();
 189:     }
 190:     else
 191:         usage();
 192:     done(0);
 193: }
 194: 
 195: usage()
 196: {
 197:     fprintf(stderr, "tar: usage  tar -{txru}[cvfblm] [tapefile] [blocksize] file1 file2...\n");
 198:     done(1);
 199: }
 200: 
 201: dorep(argv)
 202: char    *argv[];
 203: {
 204:     register char *cp, *cp2;
 205:     char wdir[60];
 206: 
 207:     if (!cflag) {
 208:         getdir();
 209:         do {
 210:             passtape();
 211:             if (term)
 212:                 done(0);
 213:             getdir();
 214:         } while (!endtape());
 215:         if (tfile != NULL) {
 216:             char buf[200];
 217: 
 218:             strcat(buf, "sort +0 -1 +1nr ");
 219:             strcat(buf, tname);
 220:             strcat(buf, " -o ");
 221:             strcat(buf, tname);
 222:             sprintf(buf, "sort +0 -1 +1nr %s -o %s; awk '$1 != prev {print; prev=$1}' %s >%sX;mv %sX %s",
 223:                 tname, tname, tname, tname, tname, tname);
 224:             fflush(tfile);
 225:             system(buf);
 226:             freopen(tname, "r", tfile);
 227:             fstat(fileno(tfile), &stbuf);
 228:             high = stbuf.st_size;
 229:         }
 230:     }
 231: 
 232:     getwdir(wdir);
 233:     while (*argv && ! term) {
 234:         cp2 = *argv;
 235:         for (cp = *argv; *cp; cp++)
 236:             if (*cp == '/')
 237:                 cp2 = cp;
 238:         if (cp2 != *argv) {
 239:             *cp2 = '\0';
 240:             chdir(*argv);
 241:             *cp2 = '/';
 242:             cp2++;
 243:         }
 244:         putfile(*argv++, cp2);
 245:         chdir(wdir);
 246:     }
 247:     putempty();
 248:     putempty();
 249:     flushtape();
 250:     if (linkerrok == 1)
 251:         for (; ihead != NULL; ihead = ihead->nextp)
 252:             if (ihead->count != 0)
 253:                 fprintf(stderr, "Missing links to %s\n", ihead->pathname);
 254: }
 255: 
 256: endtape()
 257: {
 258:     if (dblock.dbuf.name[0] == '\0') {
 259:         backtape();
 260:         return(1);
 261:     }
 262:     else
 263:         return(0);
 264: }
 265: 
 266: getdir()
 267: {
 268:     register struct stat *sp;
 269:     int i;
 270: 
 271:     readtape( (char *) &dblock);
 272:     if (dblock.dbuf.name[0] == '\0')
 273:         return;
 274:     sp = &stbuf;
 275:     sscanf(dblock.dbuf.mode, "%o", &i);
 276:     sp->st_mode = i;
 277:     sscanf(dblock.dbuf.uid, "%o", &i);
 278:     sp->st_uid = i;
 279:     sscanf(dblock.dbuf.gid, "%o", &i);
 280:     sp->st_gid = i;
 281:     sscanf(dblock.dbuf.size, "%lo", &sp->st_size);
 282:     sscanf(dblock.dbuf.mtime, "%lo", &sp->st_mtime);
 283:     sscanf(dblock.dbuf.chksum, "%o", &chksum);
 284:     if (chksum != checksum()) {
 285:         fprintf(stderr, "directory checksum error\n");
 286:         done(2);
 287:     }
 288:     if (tfile != NULL)
 289:         fprintf(tfile, "%s %s\n", dblock.dbuf.name, dblock.dbuf.mtime);
 290: }
 291: 
 292: passtape()
 293: {
 294:     long blocks;
 295:     char buf[TBLOCK];
 296: 
 297:     if (dblock.dbuf.linkflag == '1')
 298:         return;
 299:     blocks = stbuf.st_size;
 300:     blocks += TBLOCK-1;
 301:     blocks /= TBLOCK;
 302: 
 303:     while (blocks-- > 0)
 304:         readtape(buf);
 305: }
 306: 
 307: putfile(longname, shortname)
 308: char *longname;
 309: char *shortname;
 310: {
 311:     int infile;
 312:     long blocks;
 313:     char buf[TBLOCK];
 314:     register char *cp, *cp2;
 315:     struct direct dbuf;
 316:     int i, j;
 317: 
 318:     infile = open(shortname, 0);
 319:     if (infile < 0) {
 320:         fprintf(stderr, "tar: %s: cannot open file\n", longname);
 321:         return;
 322:     }
 323: 
 324:     fstat(infile, &stbuf);
 325: 
 326:     if (tfile != NULL && checkupdate(longname) == 0) {
 327:         close(infile);
 328:         return;
 329:     }
 330:     if (checkw('r', longname) == 0) {
 331:         close(infile);
 332:         return;
 333:     }
 334: 
 335:     if ((stbuf.st_mode & S_IFMT) == S_IFDIR) {
 336:         for (i = 0, cp = buf; *cp++ = longname[i++];);
 337:         *--cp = '/';
 338:         cp++;
 339:         i = 0;
 340:         chdir(shortname);
 341:         while (read(infile, (char *)&dbuf, sizeof(dbuf)) > 0 && !term) {
 342:             if (dbuf.d_ino == 0) {
 343:                 i++;
 344:                 continue;
 345:             }
 346:             if (strcmp(".", dbuf.d_name) == 0 || strcmp("..", dbuf.d_name) == 0) {
 347:                 i++;
 348:                 continue;
 349:             }
 350:             cp2 = cp;
 351:             for (j=0; j < DIRSIZ; j++)
 352:                 *cp2++ = dbuf.d_name[j];
 353:             *cp2 = '\0';
 354:             close(infile);
 355:             putfile(buf, cp);
 356:             infile = open(".", 0);
 357:             i++;
 358:             lseek(infile, (long) (sizeof(dbuf) * i), 0);
 359:         }
 360:         close(infile);
 361:         chdir("..");
 362:         return;
 363:     }
 364:     if ((stbuf.st_mode & S_IFMT) != S_IFREG) {
 365:         fprintf(stderr, "tar: %s is not a file. Not dumped\n", longname);
 366:         return;
 367:     }
 368: 
 369:     tomodes(&stbuf);
 370: 
 371:     cp2 = longname;
 372:     for (cp = dblock.dbuf.name, i=0; (*cp++ = *cp2++) && i < NAMSIZ; i++);
 373:     if (i >= NAMSIZ) {
 374:         fprintf(stderr, "%s: file name too long\n", longname);
 375:         close(infile);
 376:         return;
 377:     }
 378: 
 379:     if (stbuf.st_nlink > 1) {
 380:         struct linkbuf *lp;
 381:         int found = 0;
 382: 
 383:         for (lp = ihead; lp != NULL; lp = lp->nextp) {
 384:             if (lp->inum == stbuf.st_ino && lp->devnum == stbuf.st_dev) {
 385:                 found++;
 386:                 break;
 387:             }
 388:         }
 389:         if (found) {
 390:             strcpy(dblock.dbuf.linkname, lp->pathname);
 391:             dblock.dbuf.linkflag = '1';
 392:             sprintf(dblock.dbuf.chksum, "%6o", checksum());
 393:             writetape( (char *) &dblock);
 394:             if (vflag) {
 395:                 fprintf(stderr, "a %s ", longname);
 396:                 fprintf(stderr, "link to %s\n", lp->pathname);
 397:             }
 398:             lp->count--;
 399:             close(infile);
 400:             return;
 401:         }
 402:         else {
 403:             lp = (struct linkbuf *) malloc(sizeof(*lp));
 404:             if (lp == NULL) {
 405:                 if (freemem) {
 406:                     fprintf(stderr, "Out of memory. Link information lost\n");
 407:                     freemem = 0;
 408:                 }
 409:             }
 410:             else {
 411:                 lp->nextp = ihead;
 412:                 ihead = lp;
 413:                 lp->inum = stbuf.st_ino;
 414:                 lp->devnum = stbuf.st_dev;
 415:                 lp->count = stbuf.st_nlink - 1;
 416:                 strcpy(lp->pathname, longname);
 417:             }
 418:         }
 419:     }
 420: 
 421:     blocks = (stbuf.st_size + (TBLOCK-1)) / TBLOCK;
 422:     if (vflag) {
 423:         fprintf(stderr, "a %s ", longname);
 424:         fprintf(stderr, "%ld blocks\n", blocks);
 425:     }
 426:     sprintf(dblock.dbuf.chksum, "%6o", checksum());
 427:     writetape( (char *) &dblock);
 428: 
 429:     while ((i = read(infile, buf, TBLOCK)) > 0 && blocks > 0) {
 430:         writetape(buf);
 431:         blocks--;
 432:     }
 433:     close(infile);
 434:     if (blocks != 0 || i != 0)
 435:         fprintf(stderr, "%s: file changed size\n", longname);
 436:     while (blocks-- >  0)
 437:         putempty();
 438: }
 439: 
 440: 
 441: 
 442: doxtract(argv)
 443: char    *argv[];
 444: {
 445:     long blocks, bytes;
 446:     char buf[TBLOCK];
 447:     char **cp;
 448:     int ofile;
 449: 
 450:     for (;;) {
 451:         getdir();
 452:         if (endtape())
 453:             break;
 454: 
 455:         if (*argv == 0)
 456:             goto gotit;
 457: 
 458:         for (cp = argv; *cp; cp++)
 459:             if (prefix(*cp, dblock.dbuf.name))
 460:                 goto gotit;
 461:         passtape();
 462:         continue;
 463: 
 464: gotit:
 465:         if (checkw('x', dblock.dbuf.name) == 0) {
 466:             passtape();
 467:             continue;
 468:         }
 469: 
 470:         checkdir(dblock.dbuf.name);
 471: 
 472:         if (dblock.dbuf.linkflag == '1') {
 473:             unlink(dblock.dbuf.name);
 474:             if (link(dblock.dbuf.linkname, dblock.dbuf.name) < 0) {
 475:                 fprintf(stderr, "%s: cannot link\n", dblock.dbuf.name);
 476:                 continue;
 477:             }
 478:             if (vflag)
 479:                 fprintf(stderr, "%s linked to %s\n", dblock.dbuf.name, dblock.dbuf.linkname);
 480:             continue;
 481:         }
 482:         if ((ofile = creat(dblock.dbuf.name, stbuf.st_mode & 07777)) < 0) {
 483:             fprintf(stderr, "tar: %s - cannot create\n", dblock.dbuf.name);
 484:             passtape();
 485:             continue;
 486:         }
 487: 
 488:         chown(dblock.dbuf.name, stbuf.st_uid, stbuf.st_gid);
 489: 
 490:         blocks = ((bytes = stbuf.st_size) + TBLOCK-1)/TBLOCK;
 491:         if (vflag)
 492:             fprintf(stderr, "x %s, %ld bytes, %ld tape blocks\n", dblock.dbuf.name, bytes, blocks);
 493:         while (blocks-- > 0) {
 494:             readtape(buf);
 495:             if (bytes > TBLOCK) {
 496:                 if (write(ofile, buf, TBLOCK) < 0) {
 497:                     fprintf(stderr, "tar: %s: HELP - extract write error\n", dblock.dbuf.name);
 498:                     done(2);
 499:                 }
 500:             } else
 501:                 if (write(ofile, buf, (int) bytes) < 0) {
 502:                     fprintf(stderr, "tar: %s: HELP - extract write error\n", dblock.dbuf.name);
 503:                     done(2);
 504:                 }
 505:             bytes -= TBLOCK;
 506:         }
 507:         close(ofile);
 508:         if (mflag == 0) {
 509:             time_t timep[2];
 510: 
 511:             timep[0] = time(NULL);
 512:             timep[1] = stbuf.st_mtime;
 513:             utime(dblock.dbuf.name, timep);
 514:         }
 515:     }
 516: }
 517: 
 518: dotable()
 519: {
 520:     for (;;) {
 521:         getdir();
 522:         if (endtape())
 523:             break;
 524:         if (vflag)
 525:             longt(&stbuf);
 526:         printf("%s", dblock.dbuf.name);
 527:         if (dblock.dbuf.linkflag == '1')
 528:             printf(" linked to %s", dblock.dbuf.linkname);
 529:         printf("\n");
 530:         passtape();
 531:     }
 532: }
 533: 
 534: putempty()
 535: {
 536:     char buf[TBLOCK];
 537:     char *cp;
 538: 
 539:     for (cp = buf; cp < &buf[TBLOCK]; )
 540:         *cp++ = '\0';
 541:     writetape(buf);
 542: }
 543: 
 544: longt(st)
 545: register struct stat *st;
 546: {
 547:     register char *cp;
 548:     char *ctime();
 549: 
 550:     pmode(st);
 551:     printf("%3d/%1d", st->st_uid, st->st_gid);
 552:     printf("%7D", st->st_size);
 553:     cp = ctime(&st->st_mtime);
 554:     printf(" %-12.12s %-4.4s ", cp+4, cp+20);
 555: }
 556: 
 557: #define SUID    04000
 558: #define SGID    02000
 559: #define ROWN    0400
 560: #define WOWN    0200
 561: #define XOWN    0100
 562: #define RGRP    040
 563: #define WGRP    020
 564: #define XGRP    010
 565: #define ROTH    04
 566: #define WOTH    02
 567: #define XOTH    01
 568: #define STXT    01000
 569: int m1[] = { 1, ROWN, 'r', '-' };
 570: int m2[] = { 1, WOWN, 'w', '-' };
 571: int m3[] = { 2, SUID, 's', XOWN, 'x', '-' };
 572: int m4[] = { 1, RGRP, 'r', '-' };
 573: int m5[] = { 1, WGRP, 'w', '-' };
 574: int m6[] = { 2, SGID, 's', XGRP, 'x', '-' };
 575: int m7[] = { 1, ROTH, 'r', '-' };
 576: int m8[] = { 1, WOTH, 'w', '-' };
 577: int m9[] = { 2, STXT, 't', XOTH, 'x', '-' };
 578: 
 579: int *m[] = { m1, m2, m3, m4, m5, m6, m7, m8, m9};
 580: 
 581: pmode(st)
 582: register struct stat *st;
 583: {
 584:     register int **mp;
 585: 
 586:     for (mp = &m[0]; mp < &m[9];)
 587:         select(*mp++, st);
 588: }
 589: 
 590: select(pairp, st)
 591: int *pairp;
 592: struct stat *st;
 593: {
 594:     register int n, *ap;
 595: 
 596:     ap = pairp;
 597:     n = *ap++;
 598:     while (--n>=0 && (st->st_mode&*ap++)==0)
 599:         ap++;
 600:     printf("%c", *ap);
 601: }
 602: 
 603: checkdir(name)
 604: register char *name;
 605: {
 606:     register char *cp;
 607:     int i;
 608:     for (cp = name; *cp; cp++) {
 609:         if (*cp == '/') {
 610:             *cp = '\0';
 611:             if (access(name, 01) < 0) {
 612:                 if (fork() == 0) {
 613:                     execl("/bin/mkdir", "mkdir", name, 0);
 614:                     execl("/usr/bin/mkdir", "mkdir", name, 0);
 615:                     fprintf(stderr, "tar: cannot find mkdir!\n");
 616:                     done(0);
 617:                 }
 618:                 while (wait(&i) >= 0);
 619:                 chown(name, stbuf.st_uid, stbuf.st_gid);
 620:             }
 621:             *cp = '/';
 622:         }
 623:     }
 624: }
 625: 
 626: onintr()
 627: {
 628:     signal(SIGINT, SIG_IGN);
 629:     term++;
 630: }
 631: 
 632: onquit()
 633: {
 634:     signal(SIGQUIT, SIG_IGN);
 635:     term++;
 636: }
 637: 
 638: onhup()
 639: {
 640:     signal(SIGHUP, SIG_IGN);
 641:     term++;
 642: }
 643: 
 644: onterm()
 645: {
 646:     signal(SIGTERM, SIG_IGN);
 647:     term++;
 648: }
 649: 
 650: tomodes(sp)
 651: register struct stat *sp;
 652: {
 653:     register char *cp;
 654: 
 655:     for (cp = dblock.dummy; cp < &dblock.dummy[TBLOCK]; cp++)
 656:         *cp = '\0';
 657:     sprintf(dblock.dbuf.mode, "%6o ", sp->st_mode & 07777);
 658:     sprintf(dblock.dbuf.uid, "%6o ", sp->st_uid);
 659:     sprintf(dblock.dbuf.gid, "%6o ", sp->st_gid);
 660:     sprintf(dblock.dbuf.size, "%11lo ", sp->st_size);
 661:     sprintf(dblock.dbuf.mtime, "%11lo ", sp->st_mtime);
 662: }
 663: 
 664: checksum()
 665: {
 666:     register i;
 667:     register char *cp;
 668: 
 669:     for (cp = dblock.dbuf.chksum; cp < &dblock.dbuf.chksum[sizeof(dblock.dbuf.chksum)]; cp++)
 670:         *cp = ' ';
 671:     i = 0;
 672:     for (cp = dblock.dummy; cp < &dblock.dummy[TBLOCK]; cp++)
 673:         i += *cp;
 674:     return(i);
 675: }
 676: 
 677: checkw(c, name)
 678: char *name;
 679: {
 680:     if (wflag) {
 681:         printf("%c ", c);
 682:         if (vflag)
 683:             longt(&stbuf);
 684:         printf("%s: ", name);
 685:         if (response() == 'y'){
 686:             return(1);
 687:         }
 688:         return(0);
 689:     }
 690:     return(1);
 691: }
 692: 
 693: response()
 694: {
 695:     char c;
 696: 
 697:     c = getchar();
 698:     if (c != '\n')
 699:         while (getchar() != '\n');
 700:     else c = 'n';
 701:     return(c);
 702: }
 703: 
 704: checkupdate(arg)
 705: char    *arg;
 706: {
 707:     char name[100];
 708:     long    mtime;
 709:     daddr_t seekp;
 710:     daddr_t lookup();
 711: 
 712:     rewind(tfile);
 713:     for (;;) {
 714:         if ((seekp = lookup(arg)) < 0)
 715:             return(1);
 716:         fseek(tfile, seekp, 0);
 717:         fscanf(tfile, "%s %lo", name, &mtime);
 718:         if (stbuf.st_mtime > mtime)
 719:             return(1);
 720:         else
 721:             return(0);
 722:     }
 723: }
 724: 
 725: done(n)
 726: {
 727:     unlink(tname);
 728:     exit(n);
 729: }
 730: 
 731: prefix(s1, s2)
 732: register char *s1, *s2;
 733: {
 734:     while (*s1)
 735:         if (*s1++ != *s2++)
 736:             return(0);
 737:     if (*s2)
 738:         return(*s2 == '/');
 739:     return(1);
 740: }
 741: 
 742: getwdir(s)
 743: char *s;
 744: {
 745:     int i;
 746:     int pipdes[2];
 747: 
 748:     pipe(pipdes);
 749:     if ((i = fork()) == 0) {
 750:         close(1);
 751:         dup(pipdes[1]);
 752:         execl("/bin/pwd", "pwd", 0);
 753:         execl("/usr/bin/pwd", "pwd", 0);
 754:         fprintf(stderr, "pwd failed!\n");
 755:         printf("/\n");
 756:         exit(1);
 757:     }
 758:     while (wait((int *)NULL) != -1)
 759:             ;
 760:     read(pipdes[0], s, 50);
 761:     while(*s != '\n')
 762:         s++;
 763:     *s = '\0';
 764:     close(pipdes[0]);
 765:     close(pipdes[1]);
 766: }
 767: 
 768: #define N   200
 769: int njab;
 770: daddr_t
 771: lookup(s)
 772: char *s;
 773: {
 774:     register i;
 775:     daddr_t a;
 776: 
 777:     for(i=0; s[i]; i++)
 778:         if(s[i] == ' ')
 779:             break;
 780:     a = bsrch(s, i, low, high);
 781:     return(a);
 782: }
 783: 
 784: daddr_t
 785: bsrch(s, n, l, h)
 786: daddr_t l, h;
 787: char *s;
 788: {
 789:     register i, j;
 790:     char b[N];
 791:     daddr_t m, m1;
 792: 
 793:     njab = 0;
 794: 
 795: loop:
 796:     if(l >= h)
 797:         return(-1L);
 798:     m = l + (h-l)/2 - N/2;
 799:     if(m < l)
 800:         m = l;
 801:     fseek(tfile, m, 0);
 802:     fread(b, 1, N, tfile);
 803:     njab++;
 804:     for(i=0; i<N; i++) {
 805:         if(b[i] == '\n')
 806:             break;
 807:         m++;
 808:     }
 809:     if(m >= h)
 810:         return(-1L);
 811:     m1 = m;
 812:     j = i;
 813:     for(i++; i<N; i++) {
 814:         m1++;
 815:         if(b[i] == '\n')
 816:             break;
 817:     }
 818:     i = cmp(b+j, s, n);
 819:     if(i < 0) {
 820:         h = m;
 821:         goto loop;
 822:     }
 823:     if(i > 0) {
 824:         l = m1;
 825:         goto loop;
 826:     }
 827:     return(m);
 828: }
 829: 
 830: cmp(b, s, n)
 831: char *b, *s;
 832: {
 833:     register i;
 834: 
 835:     if(b[0] != '\n')
 836:         exit(2);
 837:     for(i=0; i<n; i++) {
 838:         if(b[i+1] > s[i])
 839:             return(-1);
 840:         if(b[i+1] < s[i])
 841:             return(1);
 842:     }
 843:     return(b[i+1] == ' '? 0 : -1);
 844: }
 845: 
 846: readtape(buffer)
 847: char *buffer;
 848: {
 849:     int i, j;
 850: 
 851:     if (recno >= nblock || first == 0) {
 852:         if (first == 0 && nblock == 0)
 853:             j = NBLOCK;
 854:         else
 855:             j = nblock;
 856:         if ((i = read(mt, tbuf, TBLOCK*j)) < 0) {
 857:             fprintf(stderr, "Tar: tape read error\n");
 858:             done(3);
 859:         }
 860:         if (first == 0) {
 861:             if ((i % TBLOCK) != 0) {
 862:                 fprintf(stderr, "Tar: tape blocksize error\n");
 863:                 done(3);
 864:             }
 865:             i /= TBLOCK;
 866:             if (rflag && i != 1) {
 867:                 fprintf(stderr, "Tar: Cannot update blocked tapes (yet)\n");
 868:                 done(4);
 869:             }
 870:             if (i != nblock && i != 1) {
 871:                 fprintf(stderr, "Tar: blocksize = %d\n", i);
 872:                 nblock = i;
 873:             }
 874:         }
 875:         recno = 0;
 876:     }
 877:     first = 1;
 878:     copy(buffer, &tbuf[recno++]);
 879:     return(TBLOCK);
 880: }
 881: 
 882: writetape(buffer)
 883: char *buffer;
 884: {
 885:     first = 1;
 886:     if (nblock == 0)
 887:         nblock = 1;
 888:     if (recno >= nblock) {
 889:         if (write(mt, tbuf, TBLOCK*nblock) < 0) {
 890:             fprintf(stderr, "Tar: tape write error\n");
 891:             done(2);
 892:         }
 893:         recno = 0;
 894:     }
 895:     copy(&tbuf[recno++], buffer);
 896:     if (recno >= nblock) {
 897:         if (write(mt, tbuf, TBLOCK*nblock) < 0) {
 898:             fprintf(stderr, "Tar: tape write error\n");
 899:             done(2);
 900:         }
 901:         recno = 0;
 902:     }
 903:     return(TBLOCK);
 904: }
 905: 
 906: backtape()
 907: {
 908:     lseek(mt, (long) -TBLOCK, 1);
 909:     if (recno >= nblock) {
 910:         recno = nblock - 1;
 911:         if (read(mt, tbuf, TBLOCK*nblock) < 0) {
 912:             fprintf(stderr, "Tar: tape read error after seek\n");
 913:             done(4);
 914:         }
 915:         lseek(mt, (long) -TBLOCK, 1);
 916:     }
 917: }
 918: 
 919: flushtape()
 920: {
 921:     write(mt, tbuf, TBLOCK*nblock);
 922: }
 923: 
 924: copy(to, from)
 925: register char *to, *from;
 926: {
 927:     register i;
 928: 
 929:     i = TBLOCK;
 930:     do {
 931:         *to++ = *from++;
 932:     } while (--i);
 933: }

Defined functions

backtape defined in line 906; used 1 times
bsrch defined in line 784; used 2 times
checkdir defined in line 603; used 1 times
checksum defined in line 664; used 3 times
checkupdate defined in line 704; used 1 times
checkw defined in line 677; used 2 times
cmp defined in line 830; used 1 times
copy defined in line 924; used 2 times
done defined in line 725; used 21 times
dorep defined in line 201; used 1 times
dotable defined in line 518; used 1 times
doxtract defined in line 442; used 1 times
endtape defined in line 256; used 3 times
flushtape defined in line 919; used 1 times
getdir defined in line 266; used 4 times
getwdir defined in line 742; used 1 times
longt defined in line 544; used 2 times
lookup defined in line 770; used 2 times
main defined in line 55; never used
onhup defined in line 638; used 2 times
onintr defined in line 626; used 2 times
onquit defined in line 632; used 2 times
onterm defined in line 644; used 1 times
  • in line 60
passtape defined in line 292; used 5 times
pmode defined in line 581; used 1 times
prefix defined in line 731; used 1 times
putempty defined in line 534; used 3 times
putfile defined in line 307; used 2 times
readtape defined in line 846; used 3 times
response defined in line 693; used 1 times
select defined in line 590; used 1 times
tomodes defined in line 650; used 1 times
usage defined in line 195; used 4 times
writetape defined in line 882; used 4 times

Defined variables

cflag defined in line 38; used 8 times
chksum defined in line 39; used 9 times
dblock defined in line 26; used 51 times
first defined in line 39; used 5 times
freemem defined in line 40; used 2 times
ihead defined in line 34; used 8 times
linkerrok defined in line 39; used 2 times
m defined in line 579; used 12 times
m1 defined in line 569; used 5 times
m2 defined in line 570; used 1 times
m3 defined in line 571; used 1 times
m4 defined in line 572; used 1 times
m5 defined in line 573; used 1 times
m6 defined in line 574; used 1 times
m7 defined in line 575; used 1 times
m8 defined in line 576; used 1 times
m9 defined in line 577; used 1 times
magtape defined in line 51; used 3 times
mflag defined in line 38; used 2 times
mt defined in line 38; used 14 times
nblock defined in line 41; used 26 times
njab defined in line 769; used 2 times
recno defined in line 39; used 10 times
rflag defined in line 38; used 5 times
stbuf defined in line 36; used 25 times
tbuf defined in line 26; used 7 times
term defined in line 39; used 7 times
tflag defined in line 38; used 2 times
tname defined in line 47; used 13 times
usefile defined in line 50; used 13 times
vflag defined in line 38; used 7 times
wflag defined in line 39; used 2 times
xflag defined in line 38; used 2 times

Defined struct's

header defined in line 15; never used
linkbuf defined in line 28; used 6 times

Defined union's

hblock defined in line 13; never used

Defined macros

N defined in line 768; used 5 times
NAMSIZ defined in line 12; used 5 times
NBLOCK defined in line 11; used 4 times
RGRP defined in line 562; used 1 times
ROTH defined in line 565; used 1 times
ROWN defined in line 559; used 1 times
SGID defined in line 558; used 1 times
STXT defined in line 568; used 1 times
SUID defined in line 557; used 1 times
TBLOCK defined in line 10; used 30 times
WGRP defined in line 563; used 1 times
WOTH defined in line 566; used 1 times
WOWN defined in line 560; used 1 times
XGRP defined in line 564; used 1 times
XOTH defined in line 567; used 1 times
XOWN defined in line 561; used 1 times
Last modified: 1979-02-08
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2480
Valid CSS Valid XHTML 1.0 Strict