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