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