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