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