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