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