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