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