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