1 #ifndef lint 2 static char *sccsid = "@(#)tar.c 4.23 (Berkeley) 06/05/85"; 3 #endif 4 5 /* 6 * Tape Archival Program 7 */ 8 #include <stdio.h> 9 #include <sys/param.h> 10 #include <sys/stat.h> 11 #include <sys/dir.h> 12 #include <sys/ioctl.h> 13 #include <sys/mtio.h> 14 #include <sys/time.h> 15 #include <signal.h> 16 #include <errno.h> 17 18 #define TBLOCK 512 19 #define NBLOCK 20 20 #define NAMSIZ 100 21 #define FILEBLOCK 20 22 23 #define writetape(b) writetbuf(b, 1) 24 #define min(a,b) ((a) < (b) ? (a) : (b)) 25 #define max(a,b) ((a) > (b) ? (a) : (b)) 26 27 union hblock { 28 char dummy[TBLOCK]; 29 struct header { 30 char name[NAMSIZ]; 31 char mode[8]; 32 char uid[8]; 33 char gid[8]; 34 char size[12]; 35 char mtime[12]; 36 char chksum[8]; 37 char linkflag; 38 char linkname[NAMSIZ]; 39 } dbuf; 40 }; 41 42 struct linkbuf { 43 ino_t inum; 44 dev_t devnum; 45 int count; 46 char pathname[NAMSIZ]; 47 struct linkbuf *nextp; 48 }; 49 50 union hblock dblock; 51 union hblock *tbuf; 52 struct linkbuf *ihead; 53 struct stat stbuf; 54 55 int rflag; 56 int xflag; 57 int vflag; 58 int tflag; 59 int cflag; 60 int mflag; 61 int fflag; 62 int iflag; 63 int oflag; 64 int pflag; 65 int wflag; 66 int hflag; 67 int Bflag; 68 int Fflag; 69 70 int mt; 71 int mtdev = 1; 72 int term; 73 int chksum; 74 int recno; 75 int first = 0; 76 int linkerrok; 77 int freemem = 1; 78 int nblock = 0; 79 int onintr(); 80 int onquit(); 81 int onhup(); 82 int onterm(); 83 84 daddr_t low; 85 daddr_t high; 86 daddr_t bsrch(); 87 88 FILE *vfile = stdout; 89 FILE *tfile; 90 char tname[] = "/tmp/tarXXXXXX"; 91 char *usefile; 92 char magtape[] = "/dev/rmt8"; 93 char *malloc(); 94 char *sprintf(); 95 char *strcat(); 96 char *rindex(); 97 char *getcwd(); 98 char *getwd(); 99 100 main(argc, argv) 101 int argc; 102 char *argv[]; 103 { 104 char *cp; 105 106 if (argc < 2) 107 usage(); 108 109 tfile = NULL; 110 usefile = magtape; 111 argv[argc] = 0; 112 argv++; 113 for (cp = *argv++; *cp; cp++) 114 switch(*cp) { 115 116 case 'f': 117 if (*argv == 0) { 118 fprintf(stderr, 119 "tar: tapefile must be specified with 'f' option\n"); 120 usage(); 121 } 122 usefile = *argv++; 123 fflag++; 124 break; 125 126 case 'c': 127 cflag++; 128 rflag++; 129 break; 130 131 case 'o': 132 oflag++; 133 break; 134 135 case 'p': 136 pflag++; 137 break; 138 139 case 'u': 140 mktemp(tname); 141 if ((tfile = fopen(tname, "w")) == NULL) { 142 fprintf(stderr, 143 "Tar: cannot create temporary file (%s)\n", 144 tname); 145 done(1); 146 } 147 fprintf(tfile, "!!!!!/!/!/!/!/!/!/! 000\n"); 148 /*FALL THRU*/ 149 150 case 'r': 151 rflag++; 152 break; 153 154 case 'v': 155 vflag++; 156 break; 157 158 case 'w': 159 wflag++; 160 break; 161 162 case 'x': 163 xflag++; 164 break; 165 166 case 't': 167 tflag++; 168 break; 169 170 case 'm': 171 mflag++; 172 break; 173 174 case '-': 175 break; 176 177 case '0': 178 case '1': 179 case '4': 180 case '5': 181 case '7': 182 case '8': 183 magtape[8] = *cp; 184 usefile = magtape; 185 break; 186 187 case 'b': 188 if (*argv == 0) { 189 fprintf(stderr, 190 "tar: blocksize must be specified with 'b' option\n"); 191 usage(); 192 } 193 nblock = atoi(*argv); 194 if (nblock <= 0) { 195 fprintf(stderr, 196 "tar: invalid blocksize \"%s\"\n", *argv); 197 done(1); 198 } 199 argv++; 200 break; 201 202 case 'l': 203 linkerrok++; 204 break; 205 206 case 'h': 207 hflag++; 208 break; 209 210 case 'i': 211 iflag++; 212 break; 213 214 case 'B': 215 Bflag++; 216 break; 217 218 case 'F': 219 Fflag++; 220 break; 221 222 default: 223 fprintf(stderr, "tar: %c: unknown option\n", *cp); 224 usage(); 225 } 226 227 if (!rflag && !xflag && !tflag) 228 usage(); 229 if (rflag) { 230 if (cflag && tfile != NULL) 231 usage(); 232 if (signal(SIGINT, SIG_IGN) != SIG_IGN) 233 signal(SIGINT, onintr); 234 if (signal(SIGHUP, SIG_IGN) != SIG_IGN) 235 signal(SIGHUP, onhup); 236 if (signal(SIGQUIT, SIG_IGN) != SIG_IGN) 237 signal(SIGQUIT, onquit); 238 #ifdef notdef 239 if (signal(SIGTERM, SIG_IGN) != SIG_IGN) 240 signal(SIGTERM, onterm); 241 #endif 242 if (strcmp(usefile, "-") == 0) { 243 if (cflag == 0) { 244 fprintf(stderr, 245 "tar: can only create standard output archives\n"); 246 done(1); 247 } 248 vfile = stderr; 249 setlinebuf(vfile); 250 mt = dup(1); 251 } else if ((mt = open(usefile, 2)) < 0) { 252 if (cflag == 0 || (mt = creat(usefile, 0666)) < 0) { 253 fprintf(stderr, 254 "tar: cannot open %s\n", usefile); 255 done(1); 256 } 257 } 258 dorep(argv); 259 done(0); 260 } 261 if (strcmp(usefile, "-") == 0) { 262 mt = dup(0); 263 } else if ((mt = open(usefile, 0)) < 0) { 264 fprintf(stderr, "tar: cannot open %s\n", usefile); 265 done(1); 266 } 267 if (xflag) 268 doxtract(argv); 269 else 270 dotable(); 271 done(0); 272 } 273 274 usage() 275 { 276 fprintf(stderr, 277 "tar: usage: tar -{txru}[cvfblmhopwBi] [tapefile] [blocksize] file1 file2...\n"); 278 done(1); 279 } 280 281 dorep(argv) 282 char *argv[]; 283 { 284 register char *cp, *cp2; 285 char wdir[MAXPATHLEN], tempdir[MAXPATHLEN], *parent; 286 287 if (!cflag) { 288 getdir(); 289 do { 290 passtape(); 291 if (term) 292 done(0); 293 getdir(); 294 } while (!endtape()); 295 backtape(); 296 if (tfile != NULL) { 297 char buf[200]; 298 299 sprintf(buf, 300 "sort +0 -1 +1nr %s -o %s; awk '$1 != prev {print; prev=$1}' %s >%sX; mv %sX %s", 301 tname, tname, tname, tname, tname, tname); 302 fflush(tfile); 303 system(buf); 304 freopen(tname, "r", tfile); 305 fstat(fileno(tfile), &stbuf); 306 high = stbuf.st_size; 307 } 308 } 309 310 (void) getcwd(wdir); 311 while (*argv && ! term) { 312 cp2 = *argv; 313 if (!strcmp(cp2, "-C") && argv[1]) { 314 argv++; 315 if (chdir(*argv) < 0) 316 perror(*argv); 317 else 318 (void) getcwd(wdir); 319 argv++; 320 continue; 321 } 322 parent = wdir; 323 for (cp = *argv; *cp; cp++) 324 if (*cp == '/') 325 cp2 = cp; 326 if (cp2 != *argv) { 327 *cp2 = '\0'; 328 if (chdir(*argv) < 0) { 329 perror(*argv); 330 continue; 331 } 332 parent = getcwd(tempdir); 333 *cp2 = '/'; 334 cp2++; 335 } 336 putfile(*argv++, cp2, parent); 337 if (chdir(wdir) < 0) { 338 fprintf(stderr, "cannot change back?: "); 339 perror(wdir); 340 } 341 } 342 putempty(); 343 putempty(); 344 flushtape(); 345 if (linkerrok == 0) 346 return; 347 for (; ihead != NULL; ihead = ihead->nextp) { 348 if (ihead->count == 0) 349 continue; 350 fprintf(stderr, "tar: missing links to %s\n", ihead->pathname); 351 } 352 } 353 354 endtape() 355 { 356 return (dblock.dbuf.name[0] == '\0'); 357 } 358 359 getdir() 360 { 361 register struct stat *sp; 362 int i; 363 364 top: 365 readtape((char *)&dblock); 366 if (dblock.dbuf.name[0] == '\0') 367 return; 368 sp = &stbuf; 369 sscanf(dblock.dbuf.mode, "%o", &i); 370 sp->st_mode = i; 371 sscanf(dblock.dbuf.uid, "%o", &i); 372 sp->st_uid = i; 373 sscanf(dblock.dbuf.gid, "%o", &i); 374 sp->st_gid = i; 375 sscanf(dblock.dbuf.size, "%lo", &sp->st_size); 376 sscanf(dblock.dbuf.mtime, "%lo", &sp->st_mtime); 377 sscanf(dblock.dbuf.chksum, "%o", &chksum); 378 if (chksum != (i = checksum())) { 379 fprintf(stderr, "tar: directory checksum error (%d != %d)\n", 380 chksum, i); 381 if (iflag) 382 goto top; 383 done(2); 384 } 385 if (tfile != NULL) 386 fprintf(tfile, "%s %s\n", dblock.dbuf.name, dblock.dbuf.mtime); 387 } 388 389 passtape() 390 { 391 long blocks; 392 char *bufp; 393 394 if (dblock.dbuf.linkflag == '1') 395 return; 396 blocks = stbuf.st_size; 397 blocks += TBLOCK-1; 398 blocks /= TBLOCK; 399 400 while (blocks-- > 0) 401 readtbuf(&bufp, TBLOCK); 402 } 403 404 putfile(longname, shortname, parent) 405 char *longname; 406 char *shortname; 407 char *parent; 408 { 409 int infile = 0; 410 long blocks; 411 char buf[TBLOCK]; 412 char *origbuf; 413 char *bigbuf; 414 register char *cp, *cp2; 415 struct direct *dp; 416 DIR *dirp; 417 int i, j; 418 char newparent[NAMSIZ+64]; 419 extern int errno; 420 int maxread; 421 int hint; /* amount to write to get "in sync" */ 422 423 if (!hflag) 424 i = lstat(shortname, &stbuf); 425 else 426 i = stat(shortname, &stbuf); 427 if (i < 0) { 428 switch (errno) { 429 case EACCES: 430 fprintf(stderr, "tar: %s: cannot open file\n", longname); 431 break; 432 case ENOENT: 433 fprintf(stderr, "tar: %s: no such file or directory\n", 434 longname); 435 break; 436 default: 437 fprintf(stderr, "tar: %s: cannot stat file\n", longname); 438 break; 439 } 440 return; 441 } 442 if (tfile != NULL && checkupdate(longname) == 0) 443 return; 444 if (checkw('r', longname) == 0) 445 return; 446 if (Fflag && checkf(shortname, stbuf.st_mode, Fflag) == 0) 447 return; 448 449 switch (stbuf.st_mode & S_IFMT) { 450 case S_IFDIR: 451 for (i = 0, cp = buf; *cp++ = longname[i++];) 452 ; 453 *--cp = '/'; 454 *++cp = 0 ; 455 if (!oflag) { 456 if ((cp - buf) >= NAMSIZ) { 457 fprintf(stderr, "tar: %s: file name too long\n", 458 longname); 459 return; 460 } 461 stbuf.st_size = 0; 462 tomodes(&stbuf); 463 strcpy(dblock.dbuf.name,buf); 464 sprintf(dblock.dbuf.chksum, "%6o", checksum()); 465 writetape((char *)&dblock); 466 } 467 sprintf(newparent, "%s/%s", parent, shortname); 468 if (chdir(shortname) < 0) { 469 perror(shortname); 470 return; 471 } 472 if ((dirp = opendir(".")) == NULL) { 473 fprintf(stderr, "tar: %s: directory read error\n", 474 longname); 475 if (chdir(parent) < 0) { 476 fprintf(stderr, "cannot change back?: "); 477 perror(parent); 478 } 479 return; 480 } 481 while ((dp = readdir(dirp)) != NULL && !term) { 482 if (dp->d_ino == 0) 483 continue; 484 if (!strcmp(".", dp->d_name) || 485 !strcmp("..", dp->d_name)) 486 continue; 487 strcpy(cp, dp->d_name); 488 i = telldir(dirp); 489 closedir(dirp); 490 putfile(buf, cp, newparent); 491 dirp = opendir("."); 492 seekdir(dirp, i); 493 } 494 closedir(dirp); 495 if (chdir(parent) < 0) { 496 fprintf(stderr, "cannot change back?: "); 497 perror(parent); 498 } 499 break; 500 501 case S_IFLNK: 502 tomodes(&stbuf); 503 if (strlen(longname) >= NAMSIZ) { 504 fprintf(stderr, "tar: %s: file name too long\n", 505 longname); 506 return; 507 } 508 strcpy(dblock.dbuf.name, longname); 509 if (stbuf.st_size + 1 >= NAMSIZ) { 510 fprintf(stderr, "tar: %s: symbolic link too long\n", 511 longname); 512 return; 513 } 514 i = readlink(shortname, dblock.dbuf.linkname, NAMSIZ - 1); 515 if (i < 0) { 516 perror(longname); 517 return; 518 } 519 dblock.dbuf.linkname[i] = '\0'; 520 dblock.dbuf.linkflag = '2'; 521 if (vflag) { 522 fprintf(vfile, "a %s ", longname); 523 fprintf(vfile, "symbolic link to %s\n", 524 dblock.dbuf.linkname); 525 } 526 sprintf(dblock.dbuf.size, "%11lo", 0); 527 sprintf(dblock.dbuf.chksum, "%6o", checksum()); 528 writetape((char *)&dblock); 529 break; 530 531 case S_IFREG: 532 if ((infile = open(shortname, 0)) < 0) { 533 fprintf(stderr, "tar: %s: cannot open file\n", longname); 534 return; 535 } 536 tomodes(&stbuf); 537 if (strlen(longname) >= NAMSIZ) { 538 fprintf(stderr, "tar: %s: file name too long\n", 539 longname); 540 close(infile); 541 return; 542 } 543 strcpy(dblock.dbuf.name, longname); 544 if (stbuf.st_nlink > 1) { 545 struct linkbuf *lp; 546 int found = 0; 547 548 for (lp = ihead; lp != NULL; lp = lp->nextp) 549 if (lp->inum == stbuf.st_ino && 550 lp->devnum == stbuf.st_dev) { 551 found++; 552 break; 553 } 554 if (found) { 555 strcpy(dblock.dbuf.linkname, lp->pathname); 556 dblock.dbuf.linkflag = '1'; 557 sprintf(dblock.dbuf.chksum, "%6o", checksum()); 558 writetape( (char *) &dblock); 559 if (vflag) { 560 fprintf(vfile, "a %s ", longname); 561 fprintf(vfile, "link to %s\n", 562 lp->pathname); 563 } 564 lp->count--; 565 close(infile); 566 return; 567 } 568 lp = (struct linkbuf *) malloc(sizeof(*lp)); 569 if (lp == NULL) { 570 if (freemem) { 571 fprintf(stderr, 572 "tar: out of memory, link information lost\n"); 573 freemem = 0; 574 } 575 } else { 576 lp->nextp = ihead; 577 ihead = lp; 578 lp->inum = stbuf.st_ino; 579 lp->devnum = stbuf.st_dev; 580 lp->count = stbuf.st_nlink - 1; 581 strcpy(lp->pathname, longname); 582 } 583 } 584 blocks = (stbuf.st_size + (TBLOCK-1)) / TBLOCK; 585 if (vflag) { 586 fprintf(vfile, "a %s ", longname); 587 fprintf(vfile, "%ld blocks\n", blocks); 588 } 589 sprintf(dblock.dbuf.chksum, "%6o", checksum()); 590 hint = writetape((char *)&dblock); 591 maxread = max(stbuf.st_blksize, (nblock * TBLOCK)); 592 if ((bigbuf = malloc(maxread)) == 0) { 593 maxread = TBLOCK; 594 bigbuf = buf; 595 } 596 597 while ((i = read(infile, bigbuf, min((hint*TBLOCK), maxread))) > 0 598 && blocks > 0) { 599 register int nblks; 600 601 nblks = ((i-1)/TBLOCK)+1; 602 if (nblks > blocks) 603 nblks = blocks; 604 hint = writetbuf(bigbuf, nblks); 605 blocks -= nblks; 606 } 607 close(infile); 608 if (bigbuf != buf) 609 free(bigbuf); 610 if (blocks != 0 || i != 0) 611 fprintf(stderr, "tar: %s: file changed size\n", 612 longname); 613 while (--blocks >= 0) 614 putempty(); 615 break; 616 617 default: 618 fprintf(stderr, "tar: %s is not a file. Not dumped\n", 619 longname); 620 break; 621 } 622 } 623 624 doxtract(argv) 625 char *argv[]; 626 { 627 long blocks, bytes; 628 char **cp; 629 int ofile; 630 631 for (;;) { 632 getdir(); 633 if (endtape()) 634 break; 635 if (*argv == 0) 636 goto gotit; 637 for (cp = argv; *cp; cp++) 638 if (prefix(*cp, dblock.dbuf.name)) 639 goto gotit; 640 passtape(); 641 continue; 642 643 gotit: 644 if (checkw('x', dblock.dbuf.name) == 0) { 645 passtape(); 646 continue; 647 } 648 if (Fflag) { 649 char *s; 650 651 if ((s = rindex(dblock.dbuf.name, '/')) == 0) 652 s = dblock.dbuf.name; 653 else 654 s++; 655 if (checkf(s, stbuf.st_mode, Fflag) == 0) { 656 passtape(); 657 continue; 658 } 659 } 660 if (checkdir(dblock.dbuf.name)) 661 continue; 662 if (dblock.dbuf.linkflag == '2') { 663 unlink(dblock.dbuf.name); 664 if (symlink(dblock.dbuf.linkname, dblock.dbuf.name)<0) { 665 fprintf(stderr, "tar: %s: symbolic link failed\n", 666 dblock.dbuf.name); 667 continue; 668 } 669 if (vflag) 670 fprintf(vfile, "x %s symbolic link to %s\n", 671 dblock.dbuf.name, dblock.dbuf.linkname); 672 #ifdef notdef 673 /* ignore alien orders */ 674 chown(dblock.dbuf.name, stbuf.st_uid, stbuf.st_gid); 675 if (mflag == 0) { 676 struct timeval tv[2]; 677 678 tv[0].tv_sec = time(0); 679 tv[0].tv_usec = 0; 680 tv[1].tv_sec = stbuf.st_mtime; 681 tv[1].tv_usec = 0; 682 utimes(dblock.dbuf.name, tv); 683 } 684 if (pflag) 685 chmod(dblock.dbuf.name, stbuf.st_mode & 07777); 686 #endif 687 continue; 688 } 689 if (dblock.dbuf.linkflag == '1') { 690 unlink(dblock.dbuf.name); 691 if (link(dblock.dbuf.linkname, dblock.dbuf.name) < 0) { 692 fprintf(stderr, "tar: %s: cannot link\n", 693 dblock.dbuf.name); 694 continue; 695 } 696 if (vflag) 697 fprintf(vfile, "%s linked to %s", 698 dblock.dbuf.name, dblock.dbuf.linkname); 699 continue; 700 } 701 if ((ofile = creat(dblock.dbuf.name,stbuf.st_mode&0xfff)) < 0) { 702 fprintf(stderr, "tar: %s - cannot create\n", 703 dblock.dbuf.name); 704 passtape(); 705 continue; 706 } 707 chown(dblock.dbuf.name, stbuf.st_uid, stbuf.st_gid); 708 blocks = ((bytes = stbuf.st_size) + TBLOCK-1)/TBLOCK; 709 if (vflag) 710 fprintf(vfile, "x %s, %ld bytes, %ld tape blocks", 711 dblock.dbuf.name, bytes, blocks); 712 for (; blocks > 0;) { 713 register int nread; 714 char *bufp; 715 register int nwant; 716 717 nwant = NBLOCK*TBLOCK; 718 if (nwant > (blocks*TBLOCK)) 719 nwant = (blocks*TBLOCK); 720 nread = readtbuf(&bufp, nwant); 721 if (bytes > nread) { 722 if (write(ofile, bufp, nread) < 0) { 723 fprintf(stderr, 724 "tar: %s: HELP - extract write error\n", 725 dblock.dbuf.name); 726 done(2); 727 } 728 } else if (write(ofile, bufp, (int) bytes) < 0) { 729 fprintf(stderr, 730 "tar: %s: HELP - extract write error\n", 731 dblock.dbuf.name); 732 done(2); 733 } 734 bytes -= nread; 735 blocks -= (((nread-1)/TBLOCK)+1); 736 fprintf(stderr,"\n"); 737 } 738 close(ofile); 739 if (mflag == 0) { 740 struct timeval tv[2]; 741 742 tv[0].tv_sec = time(0); 743 tv[0].tv_usec = 0; 744 tv[1].tv_sec = stbuf.st_mtime; 745 tv[1].tv_usec = 0; 746 utimes(dblock.dbuf.name, tv); 747 } 748 if (pflag) 749 chmod(dblock.dbuf.name, stbuf.st_mode & 07777); 750 } 751 } 752 753 dotable() 754 { 755 for (;;) { 756 getdir(); 757 if (endtape()) 758 break; 759 if (vflag) 760 longt(&stbuf); 761 printf("%s", dblock.dbuf.name); 762 if (dblock.dbuf.linkflag == '1') 763 printf(" linked to %s", dblock.dbuf.linkname); 764 if (dblock.dbuf.linkflag == '2') 765 printf(" symbolic link to %s", dblock.dbuf.linkname); 766 printf("\n"); 767 passtape(); 768 } 769 } 770 771 putempty() 772 { 773 char buf[TBLOCK]; 774 775 bzero(buf, sizeof (buf)); 776 writetape(buf); 777 } 778 779 longt(st) 780 register struct stat *st; 781 { 782 register char *cp; 783 char *ctime(); 784 785 pmode(st); 786 printf("%3d/%1d", st->st_uid, st->st_gid); 787 printf("%7D", st->st_size); 788 cp = ctime(&st->st_mtime); 789 printf(" %-12.12s %-4.4s ", cp+4, cp+20); 790 } 791 792 #define SUID 04000 793 #define SGID 02000 794 #define ROWN 0400 795 #define WOWN 0200 796 #define XOWN 0100 797 #define RGRP 040 798 #define WGRP 020 799 #define XGRP 010 800 #define ROTH 04 801 #define WOTH 02 802 #define XOTH 01 803 #define STXT 01000 804 int m1[] = { 1, ROWN, 'r', '-' }; 805 int m2[] = { 1, WOWN, 'w', '-' }; 806 int m3[] = { 2, SUID, 's', XOWN, 'x', '-' }; 807 int m4[] = { 1, RGRP, 'r', '-' }; 808 int m5[] = { 1, WGRP, 'w', '-' }; 809 int m6[] = { 2, SGID, 's', XGRP, 'x', '-' }; 810 int m7[] = { 1, ROTH, 'r', '-' }; 811 int m8[] = { 1, WOTH, 'w', '-' }; 812 int m9[] = { 2, STXT, 't', XOTH, 'x', '-' }; 813 814 int *m[] = { m1, m2, m3, m4, m5, m6, m7, m8, m9}; 815 816 pmode(st) 817 register struct stat *st; 818 { 819 register int **mp; 820 821 for (mp = &m[0]; mp < &m[9];) 822 select(*mp++, st); 823 } 824 825 select(pairp, st) 826 int *pairp; 827 struct stat *st; 828 { 829 register int n, *ap; 830 831 ap = pairp; 832 n = *ap++; 833 while (--n>=0 && (st->st_mode&*ap++)==0) 834 ap++; 835 printf("%c", *ap); 836 } 837 838 checkdir(name) 839 register char *name; 840 { 841 register char *cp; 842 843 /* 844 * Quick check for existance of directory. 845 */ 846 if ((cp = rindex(name, '/')) == 0) 847 return (0); 848 *cp = '\0'; 849 if (access(name, 0) >= 0) { 850 *cp = '/'; 851 return (cp[1] == '\0'); 852 } 853 *cp = '/'; 854 855 /* 856 * No luck, try to make all directories in path. 857 */ 858 for (cp = name; *cp; cp++) { 859 if (*cp != '/') 860 continue; 861 *cp = '\0'; 862 if (access(name, 0) < 0) { 863 if (mkdir(name, 0777) < 0) { 864 perror(name); 865 *cp = '/'; 866 return (0); 867 } 868 chown(name, stbuf.st_uid, stbuf.st_gid); 869 if (pflag && cp[1] == '\0') 870 chmod(name, stbuf.st_mode & 0777); 871 } 872 *cp = '/'; 873 } 874 return (cp[-1]=='/'); 875 } 876 877 onintr() 878 { 879 signal(SIGINT, SIG_IGN); 880 term++; 881 } 882 883 onquit() 884 { 885 signal(SIGQUIT, SIG_IGN); 886 term++; 887 } 888 889 onhup() 890 { 891 signal(SIGHUP, SIG_IGN); 892 term++; 893 } 894 895 onterm() 896 { 897 signal(SIGTERM, SIG_IGN); 898 term++; 899 } 900 901 tomodes(sp) 902 register struct stat *sp; 903 { 904 register char *cp; 905 906 for (cp = dblock.dummy; cp < &dblock.dummy[TBLOCK]; cp++) 907 *cp = '\0'; 908 sprintf(dblock.dbuf.mode, "%6o ", sp->st_mode & 07777); 909 sprintf(dblock.dbuf.uid, "%6o ", sp->st_uid); 910 sprintf(dblock.dbuf.gid, "%6o ", sp->st_gid); 911 sprintf(dblock.dbuf.size, "%11lo ", sp->st_size); 912 sprintf(dblock.dbuf.mtime, "%11lo ", sp->st_mtime); 913 } 914 915 checksum() 916 { 917 register i; 918 register char *cp; 919 920 for (cp = dblock.dbuf.chksum; 921 cp < &dblock.dbuf.chksum[sizeof(dblock.dbuf.chksum)]; cp++) 922 *cp = ' '; 923 i = 0; 924 for (cp = dblock.dummy; cp < &dblock.dummy[TBLOCK]; cp++) 925 i += *cp; 926 return (i); 927 } 928 929 checkw(c, name) 930 char *name; 931 { 932 if (!wflag) 933 return (1); 934 printf("%c ", c); 935 if (vflag) 936 longt(&stbuf); 937 printf("%s: ", name); 938 return (response() == 'y'); 939 } 940 941 response() 942 { 943 char c; 944 945 c = getchar(); 946 if (c != '\n') 947 while (getchar() != '\n') 948 ; 949 else 950 c = 'n'; 951 return (c); 952 } 953 954 checkf(name, mode, howmuch) 955 char *name; 956 int mode, howmuch; 957 { 958 int l; 959 960 if ((mode & S_IFMT) == S_IFDIR){ 961 if ((strcmp(name, "SCCS")==0) || (strcmp(name, "RCS")==0)) 962 return(0); 963 return(1); 964 } 965 if ((l = strlen(name)) < 3) 966 return (1); 967 if (howmuch > 1 && name[l-2] == '.' && name[l-1] == 'o') 968 return (0); 969 if (strcmp(name, "core") == 0 || 970 strcmp(name, "errs") == 0 || 971 (howmuch > 1 && strcmp(name, "a.out") == 0)) 972 return (0); 973 /* SHOULD CHECK IF IT IS EXECUTABLE */ 974 return (1); 975 } 976 977 checkupdate(arg) 978 char *arg; 979 { 980 char name[100]; 981 long mtime; 982 daddr_t seekp; 983 daddr_t lookup(); 984 985 rewind(tfile); 986 for (;;) { 987 if ((seekp = lookup(arg)) < 0) 988 return (1); 989 fseek(tfile, seekp, 0); 990 fscanf(tfile, "%s %lo", name, &mtime); 991 return (stbuf.st_mtime > mtime); 992 } 993 } 994 995 done(n) 996 { 997 unlink(tname); 998 exit(n); 999 } 1000 1001 prefix(s1, s2) 1002 register char *s1, *s2; 1003 { 1004 while (*s1) 1005 if (*s1++ != *s2++) 1006 return (0); 1007 if (*s2) 1008 return (*s2 == '/'); 1009 return (1); 1010 } 1011 1012 #define N 200 1013 int njab; 1014 1015 daddr_t 1016 lookup(s) 1017 char *s; 1018 { 1019 register i; 1020 daddr_t a; 1021 1022 for(i=0; s[i]; i++) 1023 if (s[i] == ' ') 1024 break; 1025 a = bsrch(s, i, low, high); 1026 return (a); 1027 } 1028 1029 daddr_t 1030 bsrch(s, n, l, h) 1031 daddr_t l, h; 1032 char *s; 1033 { 1034 register i, j; 1035 char b[N]; 1036 daddr_t m, m1; 1037 1038 njab = 0; 1039 1040 loop: 1041 if (l >= h) 1042 return (-1L); 1043 m = l + (h-l)/2 - N/2; 1044 if (m < l) 1045 m = l; 1046 fseek(tfile, m, 0); 1047 fread(b, 1, N, tfile); 1048 njab++; 1049 for(i=0; i<N; i++) { 1050 if (b[i] == '\n') 1051 break; 1052 m++; 1053 } 1054 if (m >= h) 1055 return (-1L); 1056 m1 = m; 1057 j = i; 1058 for(i++; i<N; i++) { 1059 m1++; 1060 if (b[i] == '\n') 1061 break; 1062 } 1063 i = cmp(b+j, s, n); 1064 if (i < 0) { 1065 h = m; 1066 goto loop; 1067 } 1068 if (i > 0) { 1069 l = m1; 1070 goto loop; 1071 } 1072 return (m); 1073 } 1074 1075 cmp(b, s, n) 1076 char *b, *s; 1077 { 1078 register i; 1079 1080 if (b[0] != '\n') 1081 exit(2); 1082 for(i=0; i<n; i++) { 1083 if (b[i+1] > s[i]) 1084 return (-1); 1085 if (b[i+1] < s[i]) 1086 return (1); 1087 } 1088 return (b[i+1] == ' '? 0 : -1); 1089 } 1090 1091 readtape (buffer) 1092 char *buffer; 1093 { 1094 char *bufp; 1095 int nread; 1096 1097 if (first==0) getbuf(); 1098 readtbuf (&bufp, TBLOCK); 1099 bcopy(bufp, buffer, TBLOCK); 1100 return(TBLOCK); 1101 } 1102 1103 readtbuf(bufpp, size) 1104 char **bufpp; 1105 int size; 1106 { 1107 register int i; 1108 1109 if (recno >= nblock || first == 0) { 1110 if ((i = bread(mt, tbuf, TBLOCK*nblock)) < 0) { 1111 fprintf(stderr, "tar: tape read error\n"); 1112 done(3); 1113 } 1114 if (first == 0) { 1115 if ((i % TBLOCK) != 0) { 1116 fprintf(stderr, "tar: tape blocksize error\n"); 1117 done(3); 1118 } 1119 i /= TBLOCK; 1120 if (i != nblock) { 1121 fprintf(stderr, "tar: blocksize = %d\n", i); 1122 nblock = i; 1123 } 1124 first = 1; 1125 } 1126 recno = 0; 1127 } 1128 if (size > ((nblock-recno)*TBLOCK)) 1129 size = (nblock-recno)*TBLOCK; 1130 *bufpp = (char *)&tbuf[recno]; 1131 recno += (size/TBLOCK); 1132 return (size); 1133 } 1134 1135 writetbuf(buffer, n) 1136 register char *buffer; 1137 register int n; 1138 { 1139 int i; 1140 if (first==0) { 1141 getbuf(); 1142 first = 1; 1143 } 1144 if (recno >= nblock) { 1145 if ( write(mt, tbuf, TBLOCK*nblock) < 0) { 1146 perror("tar"); 1147 done(2); 1148 } 1149 recno = 0; 1150 } 1151 1152 /* 1153 * Special case: We have an empty tape buffer, and the 1154 * users data size is >= the tape block size: Avoid 1155 * the bcopy and dma direct to tape. BIG WIN. Add the 1156 * residual to the tape buffer. 1157 */ 1158 while (recno == 0 && n >= nblock) { 1159 if (write(mt, buffer, TBLOCK*nblock) < 0) { 1160 perror("tar"); 1161 done(2); 1162 } 1163 n -= nblock; 1164 buffer += (nblock * TBLOCK); 1165 } 1166 1167 while (n-- > 0) { 1168 bcopy(buffer, (char *)&tbuf[recno++], TBLOCK); 1169 buffer += TBLOCK; 1170 if (recno >= nblock) { 1171 if (write(mt, tbuf, TBLOCK*nblock) < 0) { 1172 fprintf(stderr,"tar: tape write error\n"); 1173 done(2); 1174 } 1175 recno = 0; 1176 } 1177 } 1178 1179 /* Tell the user how much to write to get in sync */ 1180 return (nblock - recno); 1181 } 1182 1183 backtape() 1184 { 1185 static struct mtop mtop = {MTBSR, 1}; 1186 struct mtget mtget; 1187 1188 if (mtdev == 0) { 1189 if (ioctl(mt, MTIOCTOP, &mtop) < 0) { 1190 fprintf(stderr, "tar: tape backspace error\n"); 1191 done(4); 1192 } 1193 } else 1194 lseek(mt, (long) -TBLOCK*nblock, 1); 1195 recno--; 1196 } 1197 1198 flushtape() 1199 { 1200 write(mt, tbuf, TBLOCK*nblock); 1201 } 1202 1203 bread(fd, buf, size) 1204 int fd; 1205 char *buf; 1206 int size; 1207 { 1208 int count; 1209 int i; 1210 static int lastread = 0; 1211 1212 if (!Bflag) { 1213 return (read(fd, buf, size)); 1214 } 1215 1216 1217 for (count = 0; count < size; count += lastread) { 1218 if (lastread < 0) { 1219 if (count > 0) 1220 return (count); 1221 return (lastread); 1222 } 1223 lastread = read(fd, buf, size - count); 1224 buf += lastread; 1225 } 1226 return (count); 1227 } 1228 1229 char * 1230 getcwd(buf) 1231 char *buf; 1232 { 1233 if (getwd(buf) == NULL) { 1234 fprintf(stderr, "tar: %s\n", buf); 1235 exit(1); 1236 } 1237 return (buf); 1238 } 1239 1240 getbuf() 1241 { 1242 struct mtget mtget; 1243 1244 if ( mtdev == 1) { 1245 fstat(mt, &stbuf); 1246 if ((stbuf.st_mode & S_IFMT) == S_IFCHR) 1247 mtdev = 0; 1248 else 1249 mtdev = -1; 1250 } 1251 if (nblock==0) { 1252 if (mtdev == 0) 1253 nblock = FILEBLOCK; 1254 else { 1255 fstat(mt, &stbuf); 1256 nblock = stbuf.st_blocks / TBLOCK; 1257 } 1258 } 1259 if (nblock == 0) nblock = FILEBLOCK; 1260 tbuf = (union hblock *)malloc(nblock*TBLOCK); 1261 if (tbuf == NULL) { 1262 fprintf(stderr, "tar: blocksize %d too big, can't get memory\n", 1263 nblock); 1264 done(1); 1265 } 1266 } 1267 1268 1269 chgreel(x, fl) 1270 int x, fl; 1271 { 1272 register int f; 1273 char str[BUFSIZ]; 1274 char *pstr; 1275 FILE *devtty; 1276 struct stat statb; 1277 1278 perror("tar"); 1279 fprintf(stderr, "Can't %s\n", x ? "write output": "read input"); 1280 fstat(fl, &statb); 1281 if ((statb.st_mode & S_IFMT) != S_IFCHR) 1282 done(2); 1283 1284 close(fl); 1285 devtty = fopen("/dev/tty", "r"); 1286 for (;;) { 1287 fprintf(stderr, "tar: If you want to go on, type \"yes\" or a new\npathname of a device/file name when you are ready\n"); 1288 if (fgets(str, sizeof (str), devtty) == NULL) 1289 break; 1290 str[strlen(str) - 1] = '\0'; 1291 1292 switch (*str) { 1293 case '\0': 1294 case 'N': 1295 case 'n': 1296 goto done; 1297 1298 case 'Y': 1299 case 'y': 1300 case '\n': 1301 pstr = usefile; 1302 break; 1303 1304 default: 1305 pstr = str; 1306 } 1307 if ((f = open(pstr, x ? 1 : 0)) >= 0) { 1308 fclose(devtty); 1309 return (f); 1310 } 1311 fprintf(stderr, "tar: open of %s failed\n", pstr); 1312 } 1313 done: 1314 fclose(devtty); 1315 return (-1); 1316 } 1317