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