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