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