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