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