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