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