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