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