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