1 /* 2 * Copyright (c) 1992 Keith Muller. 3 * Copyright (c) 1992, 1993 4 * The Regents of the University of California. All rights reserved. 5 * 6 * This code is derived from software contributed to Berkeley by 7 * Keith Muller of the University of California, San Diego. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. All advertising materials mentioning features or use of this software 18 * must display the following acknowledgement: 19 * This product includes software developed by the University of 20 * California, Berkeley and its contributors. 21 * 4. Neither the name of the University nor the names of its contributors 22 * may be used to endorse or promote products derived from this software 23 * without specific prior written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 28 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 35 * SUCH DAMAGE. 36 */ 37 38 #ifndef lint 39 #if 0 40 static char sccsid[] = "@(#)options.c 8.2 (Berkeley) 4/18/94"; 41 #endif 42 static const char rcsid[] = 43 "$FreeBSD$"; 44 #endif /* not lint */ 45 46 #include <sys/types.h> 47 #include <sys/stat.h> 48 #include <sys/mtio.h> 49 #include <stdio.h> 50 #include <string.h> 51 #include <errno.h> 52 #include <unistd.h> 53 #include <stdlib.h> 54 #include <limits.h> 55 #include <paths.h> 56 #include "pax.h" 57 #include "options.h" 58 #include "cpio.h" 59 #include "tar.h" 60 #include "extern.h" 61 62 /* 63 * Routines which handle command line options 64 */ 65 66 static char flgch[] = FLGCH; /* list of all possible flags */ 67 static OPLIST *ophead = NULL; /* head for format specific options -x */ 68 static OPLIST *optail = NULL; /* option tail */ 69 70 static int no_op __P((void)); 71 static void printflg __P((unsigned int)); 72 static int c_frmt __P((const void *, const void *)); 73 static off_t str_offt __P((char *)); 74 static char *getline __P((FILE *fp)); 75 static void pax_options __P((register int, register char **)); 76 static void pax_usage __P((void)); 77 static void tar_options __P((register int, register char **)); 78 static void tar_usage __P((void)); 79 static void cpio_options __P((register int, register char **)); 80 static void cpio_usage __P((void)); 81 82 /* errors from getline */ 83 #define GETLINE_FILE_CORRUPT 1 84 #define GETLINE_OUT_OF_MEM 2 85 static int getline_error; 86 87 88 #define GZIP_CMD "gzip" /* command to run as gzip */ 89 #define COMPRESS_CMD "compress" /* command to run as compress */ 90 #define BZIP2_CMD "bzip2" /* command to run as gzip */ 91 92 /* 93 * Format specific routine table - MUST BE IN SORTED ORDER BY NAME 94 * (see pax.h for description of each function) 95 * 96 * name, blksz, hdsz, udev, hlk, blkagn, inhead, id, st_read, 97 * read, end_read, st_write, write, end_write, trail, 98 * rd_data, wr_data, options 99 */ 100 101 FSUB fsub[] = { 102 /* 0: OLD BINARY CPIO */ 103 {"bcpio", 5120, sizeof(HD_BCPIO), 1, 0, 0, 1, bcpio_id, cpio_strd, 104 bcpio_rd, bcpio_endrd, cpio_stwr, bcpio_wr, cpio_endwr, cpio_trail, 105 rd_wrfile, wr_rdfile, bad_opt}, 106 107 /* 1: OLD OCTAL CHARACTER CPIO */ 108 {"cpio", 5120, sizeof(HD_CPIO), 1, 0, 0, 1, cpio_id, cpio_strd, 109 cpio_rd, cpio_endrd, cpio_stwr, cpio_wr, cpio_endwr, cpio_trail, 110 rd_wrfile, wr_rdfile, bad_opt}, 111 112 /* 2: SVR4 HEX CPIO */ 113 {"sv4cpio", 5120, sizeof(HD_VCPIO), 1, 0, 0, 1, vcpio_id, cpio_strd, 114 vcpio_rd, vcpio_endrd, cpio_stwr, vcpio_wr, cpio_endwr, cpio_trail, 115 rd_wrfile, wr_rdfile, bad_opt}, 116 117 /* 3: SVR4 HEX CPIO WITH CRC */ 118 {"sv4crc", 5120, sizeof(HD_VCPIO), 1, 0, 0, 1, crc_id, crc_strd, 119 vcpio_rd, vcpio_endrd, crc_stwr, vcpio_wr, cpio_endwr, cpio_trail, 120 rd_wrfile, wr_rdfile, bad_opt}, 121 122 /* 4: OLD TAR */ 123 {"tar", 10240, BLKMULT, 0, 1, BLKMULT, 0, tar_id, no_op, 124 tar_rd, tar_endrd, no_op, tar_wr, tar_endwr, tar_trail, 125 rd_wrfile, wr_rdfile, tar_opt}, 126 127 /* 5: POSIX USTAR */ 128 {"ustar", 10240, BLKMULT, 0, 1, BLKMULT, 0, ustar_id, ustar_strd, 129 ustar_rd, tar_endrd, ustar_stwr, ustar_wr, tar_endwr, tar_trail, 130 rd_wrfile, wr_rdfile, bad_opt}, 131 }; 132 #define F_OCPIO 0 /* format when called as cpio -6 */ 133 #define F_ACPIO 1 /* format when called as cpio -c */ 134 #define F_CPIO 3 /* format when called as cpio */ 135 #define F_OTAR 4 /* format when called as tar -o */ 136 #define F_TAR 5 /* format when called as tar */ 137 #define DEFLT 5 /* default write format from list above */ 138 139 /* 140 * ford is the archive search order used by get_arc() to determine what kind 141 * of archive we are dealing with. This helps to properly id archive formats 142 * some formats may be subsets of others.... 143 */ 144 int ford[] = {5, 4, 3, 2, 1, 0, -1 }; 145 146 /* 147 * options() 148 * figure out if we are pax, tar or cpio. Call the appropriate options 149 * parser 150 */ 151 152 #ifdef __STDC__ 153 void 154 options(register int argc, register char **argv) 155 #else 156 void 157 options(argc, argv) 158 register int argc; 159 register char **argv; 160 #endif 161 { 162 163 /* 164 * Are we acting like pax, tar or cpio (based on argv[0]) 165 */ 166 if ((argv0 = strrchr(argv[0], '/')) != NULL) 167 argv0++; 168 else 169 argv0 = argv[0]; 170 171 if (strcmp(NM_TAR, argv0) == 0) 172 return(tar_options(argc, argv)); 173 else if (strcmp(NM_CPIO, argv0) == 0) 174 return(cpio_options(argc, argv)); 175 /* 176 * assume pax as the default 177 */ 178 argv0 = NM_PAX; 179 return(pax_options(argc, argv)); 180 } 181 182 /* 183 * pax_options() 184 * look at the user specified flags. set globals as required and check if 185 * the user specified a legal set of flags. If not, complain and exit 186 */ 187 188 #ifdef __STDC__ 189 static void 190 pax_options(register int argc, register char **argv) 191 #else 192 static void 193 pax_options(argc, argv) 194 register int argc; 195 register char **argv; 196 #endif 197 { 198 register int c; 199 register int i; 200 unsigned int flg = 0; 201 unsigned int bflg = 0; 202 register char *pt; 203 FSUB tmp; 204 205 /* 206 * process option flags 207 */ 208 while ((c=getopt(argc,argv,"ab:cdf:iklno:p:rs:tuvwx:zB:DE:G:HLPT:U:XYZ")) 209 != -1) { 210 switch (c) { 211 case 'a': 212 /* 213 * append 214 */ 215 flg |= AF; 216 break; 217 case 'b': 218 /* 219 * specify blocksize 220 */ 221 flg |= BF; 222 if ((wrblksz = (int)str_offt(optarg)) <= 0) { 223 paxwarn(1, "Invalid block size %s", optarg); 224 pax_usage(); 225 } 226 break; 227 case 'c': 228 /* 229 * inverse match on patterns 230 */ 231 cflag = 1; 232 flg |= CF; 233 break; 234 case 'd': 235 /* 236 * match only dir on extract, not the subtree at dir 237 */ 238 dflag = 1; 239 flg |= DF; 240 break; 241 case 'f': 242 /* 243 * filename where the archive is stored 244 */ 245 arcname = optarg; 246 flg |= FF; 247 break; 248 case 'i': 249 /* 250 * interactive file rename 251 */ 252 iflag = 1; 253 flg |= IF; 254 break; 255 case 'k': 256 /* 257 * do not clobber files that exist 258 */ 259 kflag = 1; 260 flg |= KF; 261 break; 262 case 'l': 263 /* 264 * try to link src to dest with copy (-rw) 265 */ 266 lflag = 1; 267 flg |= LF; 268 break; 269 case 'n': 270 /* 271 * select first match for a pattern only 272 */ 273 nflag = 1; 274 flg |= NF; 275 break; 276 case 'o': 277 /* 278 * pass format specific options 279 */ 280 flg |= OF; 281 if (opt_add(optarg) < 0) 282 pax_usage(); 283 break; 284 case 'p': 285 /* 286 * specify file characteristic options 287 */ 288 for (pt = optarg; *pt != '\0'; ++pt) { 289 switch(*pt) { 290 case 'a': 291 /* 292 * do not preserve access time 293 */ 294 patime = 0; 295 break; 296 case 'e': 297 /* 298 * preserve user id, group id, file 299 * mode, access/modification times 300 */ 301 pids = 1; 302 pmode = 1; 303 patime = 1; 304 pmtime = 1; 305 break; 306 case 'm': 307 /* 308 * do not preserve modification time 309 */ 310 pmtime = 0; 311 break; 312 case 'o': 313 /* 314 * preserve uid/gid 315 */ 316 pids = 1; 317 break; 318 case 'p': 319 /* 320 * preserver file mode bits 321 */ 322 pmode = 1; 323 break; 324 default: 325 paxwarn(1, "Invalid -p string: %c", *pt); 326 pax_usage(); 327 break; 328 } 329 } 330 flg |= PF; 331 break; 332 case 'r': 333 /* 334 * read the archive 335 */ 336 flg |= RF; 337 break; 338 case 's': 339 /* 340 * file name substitution name pattern 341 */ 342 if (rep_add(optarg) < 0) { 343 pax_usage(); 344 break; 345 } 346 flg |= SF; 347 break; 348 case 't': 349 /* 350 * preserve access time on filesystem nodes we read 351 */ 352 tflag = 1; 353 flg |= TF; 354 break; 355 case 'u': 356 /* 357 * ignore those older files 358 */ 359 uflag = 1; 360 flg |= UF; 361 break; 362 case 'v': 363 /* 364 * verbose operation mode 365 */ 366 vflag = 1; 367 flg |= VF; 368 break; 369 case 'w': 370 /* 371 * write an archive 372 */ 373 flg |= WF; 374 break; 375 case 'x': 376 /* 377 * specify an archive format on write 378 */ 379 tmp.name = optarg; 380 if ((frmt = (FSUB *)bsearch((void *)&tmp, (void *)fsub, 381 sizeof(fsub)/sizeof(FSUB), sizeof(FSUB), c_frmt)) != NULL) { 382 flg |= XF; 383 break; 384 } 385 paxwarn(1, "Unknown -x format: %s", optarg); 386 (void)fputs("pax: Known -x formats are:", stderr); 387 for (i = 0; i < (sizeof(fsub)/sizeof(FSUB)); ++i) 388 (void)fprintf(stderr, " %s", fsub[i].name); 389 (void)fputs("\n\n", stderr); 390 pax_usage(); 391 break; 392 case 'z': 393 /* 394 * use gzip. Non standard option. 395 */ 396 gzip_program = GZIP_CMD; 397 break; 398 case 'B': 399 /* 400 * non-standard option on number of bytes written on a 401 * single archive volume. 402 */ 403 if ((wrlimit = str_offt(optarg)) <= 0) { 404 paxwarn(1, "Invalid write limit %s", optarg); 405 pax_usage(); 406 } 407 if (wrlimit % BLKMULT) { 408 paxwarn(1, "Write limit is not a %d byte multiple", 409 BLKMULT); 410 pax_usage(); 411 } 412 flg |= CBF; 413 break; 414 case 'D': 415 /* 416 * On extraction check file inode change time before the 417 * modification of the file name. Non standard option. 418 */ 419 Dflag = 1; 420 flg |= CDF; 421 break; 422 case 'E': 423 /* 424 * non-standard limit on read faults 425 * 0 indicates stop after first error, values 426 * indicate a limit, "NONE" try forever 427 */ 428 flg |= CEF; 429 if (strcmp(NONE, optarg) == 0) 430 maxflt = -1; 431 else if ((maxflt = atoi(optarg)) < 0) { 432 paxwarn(1, "Error count value must be positive"); 433 pax_usage(); 434 } 435 break; 436 case 'G': 437 /* 438 * non-standard option for selecting files within an 439 * archive by group (gid or name) 440 */ 441 if (grp_add(optarg) < 0) { 442 pax_usage(); 443 break; 444 } 445 flg |= CGF; 446 break; 447 case 'H': 448 /* 449 * follow command line symlinks only 450 */ 451 Hflag = 1; 452 flg |= CHF; 453 break; 454 case 'L': 455 /* 456 * follow symlinks 457 */ 458 Lflag = 1; 459 flg |= CLF; 460 break; 461 case 'P': 462 /* 463 * do NOT follow symlinks (default) 464 */ 465 Lflag = 0; 466 flg |= CPF; 467 break; 468 case 'T': 469 /* 470 * non-standard option for selecting files within an 471 * archive by modification time range (lower,upper) 472 */ 473 if (trng_add(optarg) < 0) { 474 pax_usage(); 475 break; 476 } 477 flg |= CTF; 478 break; 479 case 'U': 480 /* 481 * non-standard option for selecting files within an 482 * archive by user (uid or name) 483 */ 484 if (usr_add(optarg) < 0) { 485 pax_usage(); 486 break; 487 } 488 flg |= CUF; 489 break; 490 case 'X': 491 /* 492 * do not pass over mount points in the file system 493 */ 494 Xflag = 1; 495 flg |= CXF; 496 break; 497 case 'Y': 498 /* 499 * On extraction check file inode change time after the 500 * modification of the file name. Non standard option. 501 */ 502 Yflag = 1; 503 flg |= CYF; 504 break; 505 case 'Z': 506 /* 507 * On extraction check modification time after the 508 * modification of the file name. Non standard option. 509 */ 510 Zflag = 1; 511 flg |= CZF; 512 break; 513 default: 514 pax_usage(); 515 break; 516 } 517 } 518 519 /* 520 * figure out the operation mode of pax read,write,extract,copy,append 521 * or list. check that we have not been given a bogus set of flags 522 * for the operation mode. 523 */ 524 if (ISLIST(flg)) { 525 act = LIST; 526 listf = stdout; 527 bflg = flg & BDLIST; 528 } else if (ISEXTRACT(flg)) { 529 act = EXTRACT; 530 bflg = flg & BDEXTR; 531 } else if (ISARCHIVE(flg)) { 532 act = ARCHIVE; 533 bflg = flg & BDARCH; 534 } else if (ISAPPND(flg)) { 535 act = APPND; 536 bflg = flg & BDARCH; 537 } else if (ISCOPY(flg)) { 538 act = COPY; 539 bflg = flg & BDCOPY; 540 } else 541 pax_usage(); 542 if (bflg) { 543 printflg(flg); 544 pax_usage(); 545 } 546 547 /* 548 * if we are writing (ARCHIVE) we use the default format if the user 549 * did not specify a format. when we write during an APPEND, we will 550 * adopt the format of the existing archive if none was supplied. 551 */ 552 if (!(flg & XF) && (act == ARCHIVE)) 553 frmt = &(fsub[DEFLT]); 554 555 /* 556 * process the args as they are interpreted by the operation mode 557 */ 558 switch (act) { 559 case LIST: 560 case EXTRACT: 561 for (; optind < argc; optind++) 562 if (pat_add(argv[optind], NULL) < 0) 563 pax_usage(); 564 break; 565 case COPY: 566 if (optind >= argc) { 567 paxwarn(0, "Destination directory was not supplied"); 568 pax_usage(); 569 } 570 --argc; 571 dirptr = argv[argc]; 572 /* FALL THROUGH */ 573 case ARCHIVE: 574 case APPND: 575 for (; optind < argc; optind++) 576 if (ftree_add(argv[optind], 0) < 0) 577 pax_usage(); 578 /* 579 * no read errors allowed on updates/append operation! 580 */ 581 maxflt = 0; 582 break; 583 } 584 } 585 586 587 /* 588 * tar_options() 589 * look at the user specified flags. set globals as required and check if 590 * the user specified a legal set of flags. If not, complain and exit 591 */ 592 593 #ifdef __STDC__ 594 static void 595 tar_options(register int argc, register char **argv) 596 #else 597 static void 598 tar_options(argc, argv) 599 register int argc; 600 register char **argv; 601 #endif 602 { 603 register int c; 604 int fstdin = 0; 605 int Oflag = 0; 606 int nincfiles = 0; 607 int incfiles_max = 0; 608 struct incfile { 609 char *file; 610 char *dir; 611 }; 612 struct incfile *incfiles = NULL; 613 614 /* 615 * Set default values. 616 */ 617 rmleadslash = 1; 618 619 /* 620 * process option flags 621 */ 622 while ((c = getoldopt(argc, argv, 623 "b:cef:hjmopqruts:vwxyzBC:HI:LOPXZ014578")) != -1) { 624 switch(c) { 625 case 'b': 626 /* 627 * specify blocksize in 512-byte blocks 628 */ 629 if ((wrblksz = (int)str_offt(optarg)) <= 0) { 630 paxwarn(1, "Invalid block size %s", optarg); 631 tar_usage(); 632 } 633 wrblksz *= 512; /* XXX - check for int oflow */ 634 break; 635 case 'c': 636 /* 637 * create an archive 638 */ 639 act = ARCHIVE; 640 break; 641 case 'e': 642 /* 643 * stop after first error 644 */ 645 maxflt = 0; 646 break; 647 case 'f': 648 /* 649 * filename where the archive is stored 650 */ 651 if ((optarg[0] == '-') && (optarg[1]== '\0')) { 652 /* 653 * treat a - as stdin 654 */ 655 fstdin = 1; 656 arcname = NULL; 657 break; 658 } 659 fstdin = 0; 660 arcname = optarg; 661 break; 662 case 'h': 663 /* 664 * follow symlinks 665 */ 666 Lflag = 1; 667 break; 668 case 'j': 669 case 'y': 670 /* 671 * use bzip2. Non standard option. 672 */ 673 gzip_program = BZIP2_CMD; 674 break; 675 case 'm': 676 /* 677 * do not preserve modification time 678 */ 679 pmtime = 0; 680 break; 681 case 'o': 682 if (opt_add("write_opt=nodir") < 0) 683 tar_usage(); 684 case 'O': 685 Oflag = 1; 686 break; 687 case 'p': 688 /* 689 * preserve uid/gid and file mode, regardless of umask 690 */ 691 pmode = 1; 692 pids = 1; 693 break; 694 case 'q': 695 /* 696 * select first match for a pattern only 697 */ 698 nflag = 1; 699 break; 700 case 'r': 701 case 'u': 702 /* 703 * append to the archive 704 */ 705 act = APPND; 706 break; 707 case 's': 708 /* 709 * file name substitution name pattern 710 */ 711 if (rep_add(optarg) < 0) { 712 tar_usage(); 713 break; 714 } 715 break; 716 case 't': 717 /* 718 * list contents of the tape 719 */ 720 act = LIST; 721 break; 722 case 'v': 723 /* 724 * verbose operation mode 725 */ 726 vflag++; 727 break; 728 case 'w': 729 /* 730 * interactive file rename 731 */ 732 iflag = 1; 733 break; 734 case 'x': 735 /* 736 * extract an archive, preserving mode, 737 * and mtime if possible. 738 */ 739 act = EXTRACT; 740 pmtime = 1; 741 break; 742 case 'z': 743 /* 744 * use gzip. Non standard option. 745 */ 746 gzip_program = GZIP_CMD; 747 break; 748 case 'B': 749 /* 750 * Nothing to do here, this is pax default 751 */ 752 break; 753 case 'C': 754 chdname = optarg; 755 break; 756 case 'H': 757 /* 758 * follow command line symlinks only 759 */ 760 Hflag = 1; 761 break; 762 case 'I': 763 if (++nincfiles > incfiles_max) { 764 incfiles_max = nincfiles + 3; 765 incfiles = realloc(incfiles, 766 sizeof(*incfiles) * incfiles_max); 767 if (incfiles == NULL) { 768 paxwarn(0, "Unable to allocate space " 769 "for option list"); 770 exit(1); 771 } 772 } 773 incfiles[nincfiles - 1].file = optarg; 774 incfiles[nincfiles - 1].dir = chdname; 775 break; 776 case 'L': 777 /* 778 * follow symlinks 779 */ 780 Lflag = 1; 781 break; 782 case 'P': 783 /* 784 * do not remove leading '/' from pathnames 785 */ 786 rmleadslash = 0; 787 break; 788 case 'X': 789 /* 790 * do not pass over mount points in the file system 791 */ 792 Xflag = 1; 793 break; 794 case 'Z': 795 /* 796 * use compress. 797 */ 798 gzip_program = COMPRESS_CMD; 799 break; 800 case '0': 801 arcname = DEV_0; 802 break; 803 case '1': 804 arcname = DEV_1; 805 break; 806 case '4': 807 arcname = DEV_4; 808 break; 809 case '5': 810 arcname = DEV_5; 811 break; 812 case '7': 813 arcname = DEV_7; 814 break; 815 case '8': 816 arcname = DEV_8; 817 break; 818 default: 819 tar_usage(); 820 break; 821 } 822 } 823 argc -= optind; 824 argv += optind; 825 826 /* Traditional tar behaviour (pax uses stderr unless in list mode) */ 827 if (fstdin == 1 && act == ARCHIVE) 828 listf = stderr; 829 else 830 listf = stdout; 831 832 /* Traditional tar behaviour (pax wants to read file list from stdin) */ 833 if ((act == ARCHIVE || act == APPND) && argc == 0 && nincfiles == 0) 834 exit(0); 835 836 /* 837 * if we are writing (ARCHIVE) specify tar, otherwise run like pax 838 * (unless -o specified) 839 */ 840 if (act == ARCHIVE || act == APPND) 841 frmt = &(fsub[Oflag ? F_OTAR : F_TAR]); 842 else if (Oflag) { 843 paxwarn(1, "The -O/-o options are only valid when writing an archive"); 844 tar_usage(); /* only valid when writing */ 845 } 846 847 /* 848 * process the args as they are interpreted by the operation mode 849 */ 850 switch (act) { 851 case LIST: 852 case EXTRACT: 853 default: 854 { 855 int sawpat = 0; 856 char *file, *dir = NULL; 857 858 while (nincfiles || *argv != NULL) { 859 /* 860 * If we queued up any include files, 861 * pull them in now. Otherwise, check 862 * for -I and -C positional flags. 863 * Anything else must be a file to 864 * extract. 865 */ 866 if (nincfiles) { 867 file = incfiles->file; 868 dir = incfiles->dir; 869 incfiles++; 870 nincfiles--; 871 } else if (strcmp(*argv, "-I") == 0) { 872 if (*++argv == NULL) 873 break; 874 file = *argv++; 875 dir = chdname; 876 } else 877 file = NULL; 878 if (file != NULL) { 879 FILE *fp; 880 char *str; 881 882 if (strcmp(file, "-") == 0) 883 fp = stdin; 884 else if ((fp = fopen(file, "r")) == NULL) { 885 paxwarn(1, "Unable to open file '%s' for read", file); 886 tar_usage(); 887 } 888 while ((str = getline(fp)) != NULL) { 889 if (pat_add(str, dir) < 0) 890 tar_usage(); 891 sawpat = 1; 892 } 893 if (strcmp(file, "-") != 0) 894 fclose(fp); 895 if (getline_error) { 896 paxwarn(1, "Problem with file '%s'", file); 897 tar_usage(); 898 } 899 } else if (strcmp(*argv, "-C") == 0) { 900 if (*++argv == NULL) 901 break; 902 chdname = *argv++; 903 } else if (pat_add(*argv++, chdname) < 0) 904 tar_usage(); 905 else 906 sawpat = 1; 907 } 908 /* 909 * if patterns were added, we are doing chdir() 910 * on a file-by-file basis, else, just one 911 * global chdir (if any) after opening input. 912 */ 913 if (sawpat > 0) 914 chdname = NULL; 915 } 916 break; 917 case ARCHIVE: 918 case APPND: 919 if (chdname != NULL) { /* initial chdir() */ 920 if (ftree_add(chdname, 1) < 0) 921 tar_usage(); 922 } 923 924 while (nincfiles || *argv != NULL) { 925 char *file, *dir = NULL; 926 927 /* 928 * If we queued up any include files, pull them in 929 * now. Otherwise, check for -I and -C positional 930 * flags. Anything else must be a file to include 931 * in the archive. 932 */ 933 if (nincfiles) { 934 file = incfiles->file; 935 dir = incfiles->dir; 936 incfiles++; 937 nincfiles--; 938 } else if (strcmp(*argv, "-I") == 0) { 939 if (*++argv == NULL) 940 break; 941 file = *argv++; 942 dir = NULL; 943 } else 944 file = NULL; 945 if (file != NULL) { 946 FILE *fp; 947 char *str; 948 949 /* Set directory if needed */ 950 if (dir) { 951 if (ftree_add(dir, 1) < 0) 952 tar_usage(); 953 } 954 955 if (strcmp(file, "-") == 0) 956 fp = stdin; 957 else if ((fp = fopen(file, "r")) == NULL) { 958 paxwarn(1, "Unable to open file '%s' for read", file); 959 tar_usage(); 960 } 961 while ((str = getline(fp)) != NULL) { 962 if (ftree_add(str, 0) < 0) 963 tar_usage(); 964 } 965 if (strcmp(file, "-") != 0) 966 fclose(fp); 967 if (getline_error) { 968 paxwarn(1, "Problem with file '%s'", 969 file); 970 tar_usage(); 971 } 972 } else if (strcmp(*argv, "-C") == 0) { 973 if (*++argv == NULL) 974 break; 975 if (ftree_add(*argv++, 1) < 0) 976 tar_usage(); 977 } else if (ftree_add(*argv++, 0) < 0) 978 tar_usage(); 979 } 980 /* 981 * no read errors allowed on updates/append operation! 982 */ 983 maxflt = 0; 984 break; 985 } 986 if (!fstdin && ((arcname == NULL) || (*arcname == '\0'))) { 987 arcname = getenv("TAPE"); 988 if ((arcname == NULL) || (*arcname == '\0')) 989 arcname = _PATH_DEFTAPE; 990 } 991 } 992 993 int 994 mkpath(path) 995 char *path; 996 { 997 struct stat sb; 998 register char *slash; 999 int done = 0; 1000 1001 slash = path; 1002 1003 while (!done) { 1004 slash += strspn(slash, "/"); 1005 slash += strcspn(slash, "/"); 1006 1007 done = (*slash == '\0'); 1008 *slash = '\0'; 1009 1010 if (stat(path, &sb)) { 1011 if (errno != ENOENT || mkdir(path, 0777)) { 1012 paxwarn(1, "%s", path); 1013 return (-1); 1014 } 1015 } else if (!S_ISDIR(sb.st_mode)) { 1016 syswarn(1, ENOTDIR, "%s", path); 1017 return (-1); 1018 } 1019 1020 if (!done) 1021 *slash = '/'; 1022 } 1023 1024 return (0); 1025 } 1026 /* 1027 * cpio_options() 1028 * look at the user specified flags. set globals as required and check if 1029 * the user specified a legal set of flags. If not, complain and exit 1030 */ 1031 1032 #ifdef __STDC__ 1033 static void 1034 cpio_options(register int argc, register char **argv) 1035 #else 1036 static void 1037 cpio_options(argc, argv) 1038 register int argc; 1039 register char **argv; 1040 #endif 1041 { 1042 register int c, i; 1043 char *str; 1044 FSUB tmp; 1045 FILE *fp; 1046 1047 kflag = 1; 1048 pids = 1; 1049 pmode = 1; 1050 pmtime = 0; 1051 arcname = NULL; 1052 dflag = 1; 1053 act = -1; 1054 nodirs = 1; 1055 while ((c=getopt(argc,argv,"abcdfiklmoprstuvzABC:E:F:H:I:LO:SZ6")) != -1) 1056 switch (c) { 1057 case 'a': 1058 /* 1059 * preserve access time on files read 1060 */ 1061 tflag = 1; 1062 break; 1063 case 'b': 1064 /* 1065 * swap bytes and half-words when reading data 1066 */ 1067 break; 1068 case 'c': 1069 /* 1070 * ASCII cpio header 1071 */ 1072 frmt = &(fsub[F_ACPIO]); 1073 break; 1074 case 'd': 1075 /* 1076 * create directories as needed 1077 */ 1078 nodirs = 0; 1079 break; 1080 case 'f': 1081 /* 1082 * invert meaning of pattern list 1083 */ 1084 cflag = 1; 1085 break; 1086 case 'i': 1087 /* 1088 * restore an archive 1089 */ 1090 act = EXTRACT; 1091 break; 1092 case 'k': 1093 break; 1094 case 'l': 1095 /* 1096 * use links instead of copies when possible 1097 */ 1098 lflag = 1; 1099 break; 1100 case 'm': 1101 /* 1102 * preserve modification time 1103 */ 1104 pmtime = 1; 1105 break; 1106 case 'o': 1107 /* 1108 * create an archive 1109 */ 1110 act = ARCHIVE; 1111 frmt = &(fsub[F_CPIO]); 1112 break; 1113 case 'p': 1114 /* 1115 * copy-pass mode 1116 */ 1117 act = COPY; 1118 break; 1119 case 'r': 1120 /* 1121 * interactively rename files 1122 */ 1123 iflag = 1; 1124 break; 1125 case 's': 1126 /* 1127 * swap bytes after reading data 1128 */ 1129 break; 1130 case 't': 1131 /* 1132 * list contents of archive 1133 */ 1134 act = LIST; 1135 listf = stdout; 1136 break; 1137 case 'u': 1138 /* 1139 * replace newer files 1140 */ 1141 kflag = 0; 1142 break; 1143 case 'v': 1144 /* 1145 * verbose operation mode 1146 */ 1147 vflag = 1; 1148 break; 1149 case 'z': 1150 /* 1151 * use gzip. Non standard option. 1152 */ 1153 gzip_program = GZIP_CMD; 1154 break; 1155 case 'A': 1156 /* 1157 * append mode 1158 */ 1159 act = APPND; 1160 break; 1161 case 'B': 1162 /* 1163 * Use 5120 byte block size 1164 */ 1165 wrblksz = 5120; 1166 break; 1167 case 'C': 1168 /* 1169 * set block size in bytes 1170 */ 1171 wrblksz = atoi(optarg); 1172 break; 1173 case 'E': 1174 /* 1175 * file with patterns to extract or list 1176 */ 1177 if ((fp = fopen(optarg, "r")) == NULL) { 1178 paxwarn(1, "Unable to open file '%s' for read", optarg); 1179 cpio_usage(); 1180 } 1181 while ((str = getline(fp)) != NULL) { 1182 pat_add(str, NULL); 1183 } 1184 fclose(fp); 1185 if (getline_error) { 1186 paxwarn(1, "Problem with file '%s'", optarg); 1187 cpio_usage(); 1188 } 1189 break; 1190 case 'F': 1191 case 'I': 1192 case 'O': 1193 /* 1194 * filename where the archive is stored 1195 */ 1196 if ((optarg[0] == '-') && (optarg[1]== '\0')) { 1197 /* 1198 * treat a - as stdin 1199 */ 1200 arcname = NULL; 1201 break; 1202 } 1203 arcname = optarg; 1204 break; 1205 case 'H': 1206 /* 1207 * specify an archive format on write 1208 */ 1209 tmp.name = optarg; 1210 if ((frmt = (FSUB *)bsearch((void *)&tmp, (void *)fsub, 1211 sizeof(fsub)/sizeof(FSUB), sizeof(FSUB), c_frmt)) != NULL) 1212 break; 1213 paxwarn(1, "Unknown -H format: %s", optarg); 1214 (void)fputs("cpio: Known -H formats are:", stderr); 1215 for (i = 0; i < (sizeof(fsub)/sizeof(FSUB)); ++i) 1216 (void)fprintf(stderr, " %s", fsub[i].name); 1217 (void)fputs("\n\n", stderr); 1218 cpio_usage(); 1219 break; 1220 case 'L': 1221 /* 1222 * follow symbolic links 1223 */ 1224 Lflag = 1; 1225 break; 1226 case 'S': 1227 /* 1228 * swap halfwords after reading data 1229 */ 1230 break; 1231 case 'Z': 1232 /* 1233 * use compress. Non standard option. 1234 */ 1235 gzip_program = COMPRESS_CMD; 1236 break; 1237 case '6': 1238 /* 1239 * process Version 6 cpio format 1240 */ 1241 frmt = &(fsub[F_OCPIO]); 1242 break; 1243 case '?': 1244 default: 1245 cpio_usage(); 1246 break; 1247 } 1248 argc -= optind; 1249 argv += optind; 1250 1251 /* 1252 * process the args as they are interpreted by the operation mode 1253 */ 1254 switch (act) { 1255 case LIST: 1256 case EXTRACT: 1257 while (*argv != NULL) 1258 if (pat_add(*argv++, NULL) < 0) 1259 cpio_usage(); 1260 break; 1261 case COPY: 1262 if (*argv == NULL) { 1263 paxwarn(0, "Destination directory was not supplied"); 1264 cpio_usage(); 1265 } 1266 dirptr = *argv; 1267 if (mkpath(dirptr) < 0) 1268 cpio_usage(); 1269 --argc; 1270 ++argv; 1271 /* FALL THROUGH */ 1272 case ARCHIVE: 1273 case APPND: 1274 if (*argv != NULL) 1275 cpio_usage(); 1276 /* 1277 * no read errors allowed on updates/append operation! 1278 */ 1279 maxflt = 0; 1280 while ((str = getline(stdin)) != NULL) { 1281 ftree_add(str, NULL); 1282 } 1283 if (getline_error) { 1284 paxwarn(1, "Problem while reading stdin"); 1285 cpio_usage(); 1286 } 1287 break; 1288 default: 1289 cpio_usage(); 1290 break; 1291 } 1292 } 1293 1294 /* 1295 * printflg() 1296 * print out those invalid flag sets found to the user 1297 */ 1298 1299 #ifdef __STDC__ 1300 static void 1301 printflg(unsigned int flg) 1302 #else 1303 static void 1304 printflg(flg) 1305 unsigned int flg; 1306 #endif 1307 { 1308 int nxt; 1309 int pos = 0; 1310 1311 (void)fprintf(stderr,"%s: Invalid combination of options:", argv0); 1312 while ((nxt = ffs(flg)) != 0) { 1313 flg = flg >> nxt; 1314 pos += nxt; 1315 (void)fprintf(stderr, " -%c", flgch[pos-1]); 1316 } 1317 (void)putc('\n', stderr); 1318 } 1319 1320 /* 1321 * c_frmt() 1322 * comparison routine used by bsearch to find the format specified 1323 * by the user 1324 */ 1325 1326 #ifdef __STDC__ 1327 static int 1328 c_frmt(const void *a, const void *b) 1329 #else 1330 static int 1331 c_frmt(a, b) 1332 void *a; 1333 void *b; 1334 #endif 1335 { 1336 return(strcmp(((FSUB *)a)->name, ((FSUB *)b)->name)); 1337 } 1338 1339 /* 1340 * opt_next() 1341 * called by format specific options routines to get each format specific 1342 * flag and value specified with -o 1343 * Return: 1344 * pointer to next OPLIST entry or NULL (end of list). 1345 */ 1346 1347 #ifdef __STDC__ 1348 OPLIST * 1349 opt_next(void) 1350 #else 1351 OPLIST * 1352 opt_next() 1353 #endif 1354 { 1355 OPLIST *opt; 1356 1357 if ((opt = ophead) != NULL) 1358 ophead = ophead->fow; 1359 return(opt); 1360 } 1361 1362 /* 1363 * bad_opt() 1364 * generic routine used to complain about a format specific options 1365 * when the format does not support options. 1366 */ 1367 1368 #ifdef __STDC__ 1369 int 1370 bad_opt(void) 1371 #else 1372 int 1373 bad_opt() 1374 #endif 1375 { 1376 register OPLIST *opt; 1377 1378 if (ophead == NULL) 1379 return(0); 1380 /* 1381 * print all we were given 1382 */ 1383 paxwarn(1,"These format options are not supported"); 1384 while ((opt = opt_next()) != NULL) 1385 (void)fprintf(stderr, "\t%s = %s\n", opt->name, opt->value); 1386 pax_usage(); 1387 return(0); 1388 } 1389 1390 /* 1391 * opt_add() 1392 * breaks the value supplied to -o into a option name and value. options 1393 * are given to -o in the form -o name-value,name=value 1394 * multiple -o may be specified. 1395 * Return: 1396 * 0 if format in name=value format, -1 if -o is passed junk 1397 */ 1398 1399 #ifdef __STDC__ 1400 int 1401 opt_add(register char *str) 1402 #else 1403 int 1404 opt_add(str) 1405 register char *str; 1406 #endif 1407 { 1408 register OPLIST *opt; 1409 register char *frpt; 1410 register char *pt; 1411 register char *endpt; 1412 1413 if ((str == NULL) || (*str == '\0')) { 1414 paxwarn(0, "Invalid option name"); 1415 return(-1); 1416 } 1417 if ((str = strdup(str)) == NULL) { 1418 paxwarn(0, "Unable to allocate space for option list"); 1419 return(-1); 1420 } 1421 frpt = endpt = str; 1422 1423 /* 1424 * break into name and values pieces and stuff each one into a 1425 * OPLIST structure. When we know the format, the format specific 1426 * option function will go through this list 1427 */ 1428 while ((frpt != NULL) && (*frpt != '\0')) { 1429 if ((endpt = strchr(frpt, ',')) != NULL) 1430 *endpt = '\0'; 1431 if ((pt = strchr(frpt, '=')) == NULL) { 1432 paxwarn(0, "Invalid options format"); 1433 free(str); 1434 return(-1); 1435 } 1436 if ((opt = (OPLIST *)malloc(sizeof(OPLIST))) == NULL) { 1437 paxwarn(0, "Unable to allocate space for option list"); 1438 free(str); 1439 return(-1); 1440 } 1441 *pt++ = '\0'; 1442 opt->name = frpt; 1443 opt->value = pt; 1444 opt->fow = NULL; 1445 if (endpt != NULL) 1446 frpt = endpt + 1; 1447 else 1448 frpt = NULL; 1449 if (ophead == NULL) { 1450 optail = ophead = opt; 1451 continue; 1452 } 1453 optail->fow = opt; 1454 optail = opt; 1455 } 1456 return(0); 1457 } 1458 1459 /* 1460 * str_offt() 1461 * Convert an expression of the following forms to an off_t > 0. 1462 * 1) A positive decimal number. 1463 * 2) A positive decimal number followed by a b (mult by 512). 1464 * 3) A positive decimal number followed by a k (mult by 1024). 1465 * 4) A positive decimal number followed by a m (mult by 512). 1466 * 5) A positive decimal number followed by a w (mult by sizeof int) 1467 * 6) Two or more positive decimal numbers (with/without k,b or w). 1468 * separated by x (also * for backwards compatibility), specifying 1469 * the product of the indicated values. 1470 * Return: 1471 * 0 for an error, a positive value o.w. 1472 */ 1473 1474 #ifdef __STDC__ 1475 static off_t 1476 str_offt(char *val) 1477 #else 1478 static off_t 1479 str_offt(val) 1480 char *val; 1481 #endif 1482 { 1483 char *expr; 1484 off_t num, t; 1485 1486 # ifdef NET2_STAT 1487 num = strtol(val, &expr, 0); 1488 if ((num == LONG_MAX) || (num <= 0) || (expr == val)) 1489 # else 1490 num = strtoq(val, &expr, 0); 1491 if ((num == QUAD_MAX) || (num <= 0) || (expr == val)) 1492 # endif 1493 return(0); 1494 1495 switch(*expr) { 1496 case 'b': 1497 t = num; 1498 num *= 512; 1499 if (t > num) 1500 return(0); 1501 ++expr; 1502 break; 1503 case 'k': 1504 t = num; 1505 num *= 1024; 1506 if (t > num) 1507 return(0); 1508 ++expr; 1509 break; 1510 case 'm': 1511 t = num; 1512 num *= 1048576; 1513 if (t > num) 1514 return(0); 1515 ++expr; 1516 break; 1517 case 'w': 1518 t = num; 1519 num *= sizeof(int); 1520 if (t > num) 1521 return(0); 1522 ++expr; 1523 break; 1524 } 1525 1526 switch(*expr) { 1527 case '\0': 1528 break; 1529 case '*': 1530 case 'x': 1531 t = num; 1532 num *= str_offt(expr + 1); 1533 if (t > num) 1534 return(0); 1535 break; 1536 default: 1537 return(0); 1538 } 1539 return(num); 1540 } 1541 1542 #ifdef __STDC__ 1543 char * 1544 getline(FILE *f) 1545 #else 1546 char * 1547 getline(f) 1548 FILE *f; 1549 #endif 1550 { 1551 char *name, *temp; 1552 size_t len; 1553 1554 name = fgetln(f, &len); 1555 if (!name) { 1556 getline_error = ferror(f) ? GETLINE_FILE_CORRUPT : 0; 1557 return(0); 1558 } 1559 if (name[len-1] != '\n') 1560 len++; 1561 temp = malloc(len); 1562 if (!temp) { 1563 getline_error = GETLINE_OUT_OF_MEM; 1564 return(0); 1565 } 1566 memcpy(temp, name, len-1); 1567 temp[len-1] = 0; 1568 return(temp); 1569 } 1570 1571 /* 1572 * no_op() 1573 * for those option functions where the archive format has nothing to do. 1574 * Return: 1575 * 0 1576 */ 1577 1578 #ifdef __STDC__ 1579 static int 1580 no_op(void) 1581 #else 1582 static int 1583 no_op() 1584 #endif 1585 { 1586 return(0); 1587 } 1588 1589 /* 1590 * pax_usage() 1591 * print the usage summary to the user 1592 */ 1593 1594 #ifdef __STDC__ 1595 void 1596 pax_usage(void) 1597 #else 1598 void 1599 pax_usage() 1600 #endif 1601 { 1602 (void)fputs("usage: pax [-cdnvz] [-E limit] [-f archive] ", stderr); 1603 (void)fputs("[-s replstr] ... [-U user] ...", stderr); 1604 (void)fputs("\n [-G group] ... ", stderr); 1605 (void)fputs("[-T [from_date][,to_date]] ... ", stderr); 1606 (void)fputs("[pattern ...]\n", stderr); 1607 (void)fputs(" pax -r [-cdiknuvzDYZ] [-E limit] ", stderr); 1608 (void)fputs("[-f archive] [-o options] ... \n", stderr); 1609 (void)fputs(" [-p string] ... [-s replstr] ... ", stderr); 1610 (void)fputs("[-U user] ... [-G group] ...\n ", stderr); 1611 (void)fputs("[-T [from_date][,to_date]] ... ", stderr); 1612 (void)fputs(" [pattern ...]\n", stderr); 1613 (void)fputs(" pax -w [-dituvzHLPX] [-b blocksize] ", stderr); 1614 (void)fputs("[ [-a] [-f archive] ] [-x format] \n", stderr); 1615 (void)fputs(" [-B bytes] [-s replstr] ... ", stderr); 1616 (void)fputs("[-o options] ... [-U user] ...", stderr); 1617 (void)fputs("\n [-G group] ... ", stderr); 1618 (void)fputs("[-T [from_date][,to_date][/[c][m]]] ... ", stderr); 1619 (void)fputs("[file ...]\n", stderr); 1620 (void)fputs(" pax -r -w [-diklntuvDHLPXYZ] ", stderr); 1621 (void)fputs("[-p string] ... [-s replstr] ...", stderr); 1622 (void)fputs("\n [-U user] ... [-G group] ... ", stderr); 1623 (void)fputs("[-T [from_date][,to_date][/[c][m]]] ... ", stderr); 1624 (void)fputs("\n [file ...] directory\n", stderr); 1625 exit(1); 1626 } 1627 1628 /* 1629 * tar_usage() 1630 * print the usage summary to the user 1631 */ 1632 1633 #ifdef __STDC__ 1634 void 1635 tar_usage(void) 1636 #else 1637 void 1638 tar_usage() 1639 #endif 1640 { 1641 (void)fputs("usage: tar [-]{crtux}[-befhjmopqsvwyzHLOPXZ014578] [blocksize] ", 1642 stderr); 1643 (void)fputs("[archive] [replstr] [-C directory] [-I file] [file ...]\n", 1644 stderr); 1645 exit(1); 1646 } 1647 1648 /* 1649 * cpio_usage() 1650 * print the usage summary to the user 1651 */ 1652 1653 #ifdef __STDC__ 1654 void 1655 cpio_usage(void) 1656 #else 1657 void 1658 cpio_usage() 1659 #endif 1660 { 1661 (void)fputs("usage: cpio -o [-aABcLvVzZ] [-C bytes] [-H format] [-O archive]\n", stderr); 1662 (void)fputs(" [-F archive] < name-list [> archive]\n", stderr); 1663 (void)fputs(" cpio -i [-bBcdfmnrsStuvVzZ6] [-C bytes] [-E file] [-H format]\n", stderr); 1664 (void)fputs(" [-I archive] [-F archive] [pattern...] [< archive]\n", stderr); 1665 (void)fputs(" cpio -p [-adlLmuvV] destination-directory < name-list\n", stderr); 1666 exit(1); 1667 } 1668