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