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