file_cmds-220.4.tar.gz
[apple/file_cmds.git] / pax / options.c
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
39 static const char sccsid[] = "@(#)options.c 8.2 (Berkeley) 4/18/94";
40 #else
41 static 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
71 static char flgch[] = FLGCH; /* list of all possible flags */
72 static OPLIST *ophead = NULL; /* head for format specific options -x */
73 static OPLIST *optail = NULL; /* option tail */
74
75 static int no_op(void);
76 static void printflg(unsigned int);
77 static int c_frmt(const void *, const void *);
78 static off_t str_offt(char *);
79 static char *pax_getline(FILE *fp);
80 static void pax_options(int, char **);
81 void pax_usage(void);
82 static void tar_options(int, char **);
83 static void tar_usage(void);
84 static void cpio_options(int, char **);
85 static void cpio_usage(void);
86
87 /* errors from getline */
88 #define GETLINE_FILE_CORRUPT 1
89 #define GETLINE_OUT_OF_MEM 2
90 static 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
106 FSUB 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 */
155 int ford[] = {6, 5, 4, 3, 2, 1, 0, -1 };
156
157 /*
158 * Do we have -C anywhere?
159 */
160 int havechd = 0;
161
162 /*
163 * options()
164 * figure out if we are pax, tar or cpio. Call the appropriate options
165 * parser
166 */
167
168 void
169 options(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
195 struct 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
206 static void
207 pax_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
668 static void
669 tar_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
1057 int mkpath(char *);
1058
1059 int
1060 mkpath(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
1098 static void
1099 cpio_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
1366 static void
1367 printflg(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
1387 static int
1388 c_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
1401 OPLIST *
1402 opt_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
1417 int
1418 bad_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
1450 int
1451 opt_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
1515 int
1516 pax_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
1591 static off_t
1592 str_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
1653 char *
1654 pax_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
1683 static int
1684 no_op(void)
1685 {
1686 return(0);
1687 }
1688
1689 /*
1690 * pax_usage()
1691 * print the usage summary to the user
1692 */
1693
1694 void
1695 pax_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
1716 void
1717 tar_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
1734 void
1735 cpio_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 }