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