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