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