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