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