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