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