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