options.c revision 20420
1233294Sstas/*-
2178825Sdfr * Copyright (c) 1992 Keith Muller.
3178825Sdfr * Copyright (c) 1992, 1993
4178825Sdfr *	The Regents of the University of California.  All rights reserved.
5178825Sdfr *
6178825Sdfr * This code is derived from software contributed to Berkeley by
7178825Sdfr * Keith Muller of the University of California, San Diego.
8178825Sdfr *
9233294Sstas * Redistribution and use in source and binary forms, with or without
10178825Sdfr * modification, are permitted provided that the following conditions
11178825Sdfr * are met:
12178825Sdfr * 1. Redistributions of source code must retain the above copyright
13233294Sstas *    notice, this list of conditions and the following disclaimer.
14178825Sdfr * 2. Redistributions in binary form must reproduce the above copyright
15178825Sdfr *    notice, this list of conditions and the following disclaimer in the
16178825Sdfr *    documentation and/or other materials provided with the distribution.
17178825Sdfr * 3. All advertising materials mentioning features or use of this software
18178825Sdfr *    must display the following acknowledgement:
19178825Sdfr *	This product includes software developed by the University of
20233294Sstas *	California, Berkeley and its contributors.
21178825Sdfr * 4. Neither the name of the University nor the names of its contributors
22178825Sdfr *    may be used to endorse or promote products derived from this software
23178825Sdfr *    without specific prior written permission.
24178825Sdfr *
25233294Sstas * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26178825Sdfr * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27178825Sdfr * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28178825Sdfr * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29178825Sdfr * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30233294Sstas * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31178825Sdfr * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32178825Sdfr * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33178825Sdfr * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34178825Sdfr * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35178825Sdfr * SUCH DAMAGE.
36178825Sdfr *
37178825Sdfr *	$Id: options.c,v 1.4 1995/10/23 21:23:16 ache Exp $
38178825Sdfr */
39178825Sdfr
40178825Sdfr#ifndef lint
41178825Sdfrstatic char const sccsid[] = "@(#)options.c	8.2 (Berkeley) 4/18/94";
42178825Sdfr#endif /* not lint */
43178825Sdfr
44178825Sdfr#include <sys/types.h>
45178825Sdfr#include <sys/time.h>
46178825Sdfr#include <sys/stat.h>
47178825Sdfr#include <sys/mtio.h>
48178825Sdfr#include <sys/param.h>
49178825Sdfr#include <stdio.h>
50178825Sdfr#include <string.h>
51178825Sdfr#include <unistd.h>
52233294Sstas#include <stdlib.h>
53178825Sdfr#include <limits.h>
54178825Sdfr#include "pax.h"
55178825Sdfr#include "options.h"
56178825Sdfr#include "cpio.h"
57233294Sstas#include "tar.h"
58178825Sdfr#include "extern.h"
59178825Sdfr
60178825Sdfr/*
61178825Sdfr * Routines which handle command line options
62178825Sdfr */
63178825Sdfr
64178825Sdfrstatic char flgch[] = FLGCH;	/* list of all possible flags */
65178825Sdfrstatic OPLIST *ophead = NULL;	/* head for format specific options -x */
66178825Sdfrstatic OPLIST *optail = NULL;	/* option tail */
67178825Sdfr
68233294Sstasstatic int no_op __P((void));
69178825Sdfrstatic void printflg __P((unsigned int));
70178825Sdfrstatic int c_frmt __P((const void *, const void *));
71178825Sdfrstatic off_t str_offt __P((char *));
72178825Sdfrstatic void pax_options __P((register int, register char **));
73178825Sdfrstatic void pax_usage __P((void));
74178825Sdfrstatic void tar_options __P((register int, register char **));
75178825Sdfrstatic void tar_usage __P((void));
76233294Sstas#ifdef notdef
77178825Sdfrstatic void cpio_options __P((register int, register char **));
78178825Sdfrstatic void cpio_usage __P((void));
79178825Sdfr#endif
80178825Sdfr
81178825Sdfr/*
82178825Sdfr *	Format specific routine table - MUST BE IN SORTED ORDER BY NAME
83178825Sdfr *	(see pax.h for description of each function)
84178825Sdfr *
85178825Sdfr * 	name, blksz, hdsz, udev, hlk, blkagn, inhead, id, st_read,
86178825Sdfr *	read, end_read, st_write, write, end_write, trail,
87178825Sdfr *	rd_data, wr_data, options
88178825Sdfr */
89233294Sstas
90178825SdfrFSUB fsub[] = {
91178825Sdfr/* 0: OLD BINARY CPIO */
92178825Sdfr	{"bcpio", 5120, sizeof(HD_BCPIO), 1, 0, 0, 1, bcpio_id, cpio_strd,
93178825Sdfr	bcpio_rd, bcpio_endrd, cpio_stwr, bcpio_wr, cpio_endwr, cpio_trail,
94178825Sdfr	rd_wrfile, wr_rdfile, bad_opt},
95233294Sstas
96178825Sdfr/* 1: OLD OCTAL CHARACTER CPIO */
97178825Sdfr	{"cpio", 5120, sizeof(HD_CPIO), 1, 0, 0, 1, cpio_id, cpio_strd,
98178825Sdfr	cpio_rd, cpio_endrd, cpio_stwr, cpio_wr, cpio_endwr, cpio_trail,
99178825Sdfr	rd_wrfile, wr_rdfile, bad_opt},
100178825Sdfr
101178825Sdfr/* 2: SVR4 HEX CPIO */
102178825Sdfr	{"sv4cpio", 5120, sizeof(HD_VCPIO), 1, 0, 0, 1, vcpio_id, cpio_strd,
103178825Sdfr	vcpio_rd, vcpio_endrd, cpio_stwr, vcpio_wr, cpio_endwr, cpio_trail,
104178825Sdfr	rd_wrfile, wr_rdfile, bad_opt},
105178825Sdfr
106178825Sdfr/* 3: SVR4 HEX CPIO WITH CRC */
107178825Sdfr	{"sv4crc", 5120, sizeof(HD_VCPIO), 1, 0, 0, 1, crc_id, crc_strd,
108178825Sdfr	vcpio_rd, vcpio_endrd, crc_stwr, vcpio_wr, cpio_endwr, cpio_trail,
109178825Sdfr	rd_wrfile, wr_rdfile, bad_opt},
110178825Sdfr
111178825Sdfr/* 4: OLD TAR */
112178825Sdfr	{"tar", 10240, BLKMULT, 0, 1, BLKMULT, 0, tar_id, no_op,
113178825Sdfr	tar_rd, tar_endrd, no_op, tar_wr, tar_endwr, tar_trail,
114178825Sdfr	rd_wrfile, wr_rdfile, tar_opt},
115178825Sdfr
116178825Sdfr/* 5: POSIX USTAR */
117178825Sdfr	{"ustar", 10240, BLKMULT, 0, 1, BLKMULT, 0, ustar_id, ustar_strd,
118178825Sdfr	ustar_rd, tar_endrd, ustar_stwr, ustar_wr, tar_endwr, tar_trail,
119178825Sdfr	rd_wrfile, wr_rdfile, bad_opt},
120178825Sdfr};
121178825Sdfr#define F_TAR	4	/* format when called as tar */
122233294Sstas#define DEFLT	5	/* default write format from list above */
123178825Sdfr
124178825Sdfr/*
125178825Sdfr * ford is the archive search order used by get_arc() to determine what kind
126178825Sdfr * of archive we are dealing with. This helps to properly id  archive formats
127178825Sdfr * some formats may be subsets of others....
128178825Sdfr */
129178825Sdfrint ford[] = {5, 4, 3, 2, 1, 0, -1 };
130178825Sdfr
131178825Sdfr/*
132178825Sdfr * options()
133178825Sdfr *	figure out if we are pax, tar or cpio. Call the appropriate options
134178825Sdfr *	parser
135178825Sdfr */
136178825Sdfr
137178825Sdfr#if __STDC__
138178825Sdfrvoid
139178825Sdfroptions(register int argc, register char **argv)
140178825Sdfr#else
141178825Sdfrvoid
142233294Sstasoptions(argc, argv)
143178825Sdfr	register int argc;
144178825Sdfr	register char **argv;
145178825Sdfr#endif
146178825Sdfr{
147233294Sstas
148178825Sdfr	/*
149178825Sdfr	 * Are we acting like pax, tar or cpio (based on argv[0])
150178825Sdfr	 */
151178825Sdfr	if ((argv0 = strrchr(argv[0], '/')) != NULL)
152178825Sdfr		argv0++;
153233294Sstas	else
154178825Sdfr		argv0 = argv[0];
155178825Sdfr
156178825Sdfr	if (strcmp(NM_TAR, argv0) == 0)
157233294Sstas		return(tar_options(argc, argv));
158178825Sdfr#	ifdef notdef
159178825Sdfr	else if (strcmp(NM_CPIO, argv0) == 0)
160178825Sdfr		return(cpio_options(argc, argv));
161178825Sdfr#	endif
162178825Sdfr	/*
163178825Sdfr	 * assume pax as the default
164178825Sdfr	 */
165178825Sdfr	argv0 = NM_PAX;
166178825Sdfr	return(pax_options(argc, argv));
167178825Sdfr}
168178825Sdfr
169178825Sdfr/*
170178825Sdfr * pax_options()
171178825Sdfr *	look at the user specified flags. set globals as required and check if
172178825Sdfr *	the user specified a legal set of flags. If not, complain and exit
173233294Sstas */
174178825Sdfr
175178825Sdfr#if __STDC__
176178825Sdfrstatic void
177178825Sdfrpax_options(register int argc, register char **argv)
178178825Sdfr#else
179178825Sdfrstatic void
180178825Sdfrpax_options(argc, argv)
181178825Sdfr	register int argc;
182178825Sdfr	register char **argv;
183178825Sdfr#endif
184178825Sdfr{
185178825Sdfr	register int c;
186178825Sdfr	register int i;
187178825Sdfr	unsigned int flg = 0;
188178825Sdfr	unsigned int bflg = 0;
189178825Sdfr	register char *pt;
190178825Sdfr        FSUB tmp;
191178825Sdfr	extern char *optarg;
192178825Sdfr	extern int optind;
193178825Sdfr
194178825Sdfr	/*
195178825Sdfr	 * process option flags
196178825Sdfr	 */
197178825Sdfr	while ((c=getopt(argc,argv,"ab:cdf:iklno:p:rs:tuvwx:B:DE:G:HLPT:U:XYZ"))
198233294Sstas	    != EOF) {
199178825Sdfr		switch (c) {
200178825Sdfr		case 'a':
201178825Sdfr			/*
202178825Sdfr			 * append
203178825Sdfr			 */
204178825Sdfr			flg |= AF;
205178825Sdfr			break;
206178825Sdfr		case 'b':
207178825Sdfr			/*
208178825Sdfr			 * specify blocksize
209178825Sdfr			 */
210178825Sdfr			flg |= BF;
211178825Sdfr			if ((wrblksz = (int)str_offt(optarg)) <= 0) {
212178825Sdfr				warn(1, "Invalid block size %s", optarg);
213178825Sdfr				pax_usage();
214178825Sdfr			}
215178825Sdfr			break;
216178825Sdfr		case 'c':
217178825Sdfr			/*
218178825Sdfr			 * inverse match on patterns
219178825Sdfr			 */
220178825Sdfr			cflag = 1;
221233294Sstas			flg |= CF;
222178825Sdfr			break;
223178825Sdfr		case 'd':
224178825Sdfr			/*
225178825Sdfr			 * match only dir on extract, not the subtree at dir
226178825Sdfr			 */
227178825Sdfr			dflag = 1;
228178825Sdfr			flg |= DF;
229178825Sdfr			break;
230178825Sdfr		case 'f':
231178825Sdfr			/*
232178825Sdfr			 * filename where the archive is stored
233178825Sdfr			 */
234178825Sdfr			arcname = optarg;
235233294Sstas			flg |= FF;
236178825Sdfr			break;
237178825Sdfr		case 'i':
238178825Sdfr			/*
239178825Sdfr			 * interactive file rename
240178825Sdfr			 */
241178825Sdfr			iflag = 1;
242178825Sdfr			flg |= IF;
243178825Sdfr			break;
244178825Sdfr		case 'k':
245178825Sdfr			/*
246178825Sdfr			 * do not clobber files that exist
247178825Sdfr			 */
248178825Sdfr			kflag = 1;
249178825Sdfr			flg |= KF;
250178825Sdfr			break;
251178825Sdfr		case 'l':
252233294Sstas			/*
253178825Sdfr			 * try to link src to dest with copy (-rw)
254178825Sdfr			 */
255178825Sdfr			lflag = 1;
256178825Sdfr			flg |= LF;
257178825Sdfr			break;
258178825Sdfr		case 'n':
259178825Sdfr			/*
260178825Sdfr			 * select first match for a pattern only
261178825Sdfr			 */
262178825Sdfr			nflag = 1;
263178825Sdfr			flg |= NF;
264178825Sdfr			break;
265178825Sdfr		case 'o':
266178825Sdfr			/*
267178825Sdfr			 * pass format specific options
268178825Sdfr			 */
269178825Sdfr			flg |= OF;
270178825Sdfr			if (opt_add(optarg) < 0)
271178825Sdfr				pax_usage();
272178825Sdfr			break;
273178825Sdfr		case 'p':
274178825Sdfr			/*
275178825Sdfr			 * specify file characteristic options
276178825Sdfr			 */
277178825Sdfr			for (pt = optarg; *pt != '\0'; ++pt) {
278178825Sdfr				switch(*pt) {
279178825Sdfr				case 'a':
280178825Sdfr					/*
281178825Sdfr					 * do not preserve access time
282178825Sdfr					 */
283178825Sdfr					patime = 0;
284233294Sstas					break;
285178825Sdfr				case 'e':
286178825Sdfr					/*
287178825Sdfr					 * preserve user id, group id, file
288178825Sdfr					 * mode, access/modification times
289178825Sdfr					 */
290178825Sdfr					pids = 1;
291178825Sdfr					pmode = 1;
292178825Sdfr					patime = 1;
293178825Sdfr					pmtime = 1;
294178825Sdfr					break;
295178825Sdfr				case 'm':
296178825Sdfr					/*
297178825Sdfr					 * do not preserve modification time
298178825Sdfr					 */
299178825Sdfr					pmtime = 0;
300178825Sdfr					break;
301178825Sdfr				case 'o':
302178825Sdfr					/*
303178825Sdfr					 * preserve uid/gid
304178825Sdfr					 */
305233294Sstas					pids = 1;
306178825Sdfr					break;
307178825Sdfr				case 'p':
308178825Sdfr					/*
309178825Sdfr					 * preserver file mode bits
310178825Sdfr					 */
311233294Sstas					pmode = 1;
312178825Sdfr					break;
313178825Sdfr				default:
314178825Sdfr					warn(1, "Invalid -p string: %c", *pt);
315178825Sdfr					pax_usage();
316178825Sdfr					break;
317178825Sdfr				}
318178825Sdfr			}
319178825Sdfr			flg |= PF;
320178825Sdfr			break;
321178825Sdfr		case 'r':
322178825Sdfr			/*
323178825Sdfr			 * read the archive
324178825Sdfr			 */
325178825Sdfr			flg |= RF;
326233294Sstas			break;
327178825Sdfr		case 's':
328178825Sdfr			/*
329178825Sdfr			 * file name substitution name pattern
330178825Sdfr			 */
331178825Sdfr			if (rep_add(optarg) < 0) {
332233294Sstas				pax_usage();
333178825Sdfr				break;
334178825Sdfr			}
335178825Sdfr			flg |= SF;
336178825Sdfr			break;
337178825Sdfr		case 't':
338178825Sdfr			/*
339178825Sdfr			 * preserve access time on filesystem nodes we read
340178825Sdfr			 */
341178825Sdfr			tflag = 1;
342178825Sdfr			flg |= TF;
343178825Sdfr			break;
344178825Sdfr		case 'u':
345178825Sdfr			/*
346178825Sdfr			 * ignore those older files
347178825Sdfr			 */
348178825Sdfr			uflag = 1;
349178825Sdfr			flg |= UF;
350178825Sdfr			break;
351178825Sdfr		case 'v':
352178825Sdfr			/*
353178825Sdfr			 * verbose operation mode
354178825Sdfr			 */
355178825Sdfr			vflag = 1;
356178825Sdfr			flg |= VF;
357178825Sdfr			break;
358178825Sdfr		case 'w':
359178825Sdfr			/*
360178825Sdfr			 * write an archive
361178825Sdfr			 */
362178825Sdfr			flg |= WF;
363178825Sdfr			break;
364178825Sdfr		case 'x':
365178825Sdfr			/*
366178825Sdfr			 * specify an archive format on write
367178825Sdfr			 */
368178825Sdfr			tmp.name = optarg;
369178825Sdfr			if ((frmt = (FSUB *)bsearch((void *)&tmp, (void *)fsub,
370178825Sdfr			   sizeof(fsub)/sizeof(FSUB), sizeof(FSUB), c_frmt))) {
371178825Sdfr				flg |= XF;
372178825Sdfr				break;
373178825Sdfr			}
374178825Sdfr			warn(1, "Unknown -x format: %s", optarg);
375178825Sdfr			(void)fputs("pax: Known -x formats are:", stderr);
376178825Sdfr			for (i = 0; i < (sizeof(fsub)/sizeof(FSUB)); ++i)
377233294Sstas				(void)fprintf(stderr, " %s", fsub[i].name);
378178825Sdfr			(void)fputs("\n\n", stderr);
379178825Sdfr			pax_usage();
380178825Sdfr			break;
381178825Sdfr		case 'B':
382233294Sstas			/*
383178825Sdfr			 * non-standard option on number of bytes written on a
384178825Sdfr			 * single archive volume.
385178825Sdfr			 */
386178825Sdfr			if ((wrlimit = str_offt(optarg)) <= 0) {
387178825Sdfr				warn(1, "Invalid write limit %s", optarg);
388178825Sdfr				pax_usage();
389178825Sdfr			}
390178825Sdfr			if (wrlimit % BLKMULT) {
391178825Sdfr				warn(1, "Write limit is not a %d byte multiple",
392178825Sdfr				    BLKMULT);
393178825Sdfr				pax_usage();
394178825Sdfr			}
395178825Sdfr			flg |= CBF;
396178825Sdfr			break;
397178825Sdfr		case 'D':
398178825Sdfr			/*
399178825Sdfr			 * On extraction check file inode change time before the
400178825Sdfr			 * modification of the file name. Non standard option.
401178825Sdfr			 */
402178825Sdfr			Dflag = 1;
403178825Sdfr			flg |= CDF;
404178825Sdfr			break;
405233294Sstas		case 'E':
406178825Sdfr			/*
407178825Sdfr			 * non-standard limit on read faults
408178825Sdfr			 * 0 indicates stop after first error, values
409178825Sdfr			 * indicate a limit, "NONE" try forever
410178825Sdfr			 */
411178825Sdfr			flg |= CEF;
412178825Sdfr			if (strcmp(NONE, optarg) == 0)
413178825Sdfr				maxflt = -1;
414233294Sstas			else if ((maxflt = atoi(optarg)) < 0) {
415178825Sdfr				warn(1, "Error count value must be positive");
416178825Sdfr				pax_usage();
417178825Sdfr			}
418178825Sdfr			break;
419178825Sdfr		case 'G':
420178825Sdfr			/*
421178825Sdfr			 * non-standard option for selecting files within an
422178825Sdfr			 * archive by group (gid or name)
423233294Sstas			 */
424178825Sdfr			if (grp_add(optarg) < 0) {
425178825Sdfr				pax_usage();
426178825Sdfr				break;
427178825Sdfr			}
428178825Sdfr			flg |= CGF;
429178825Sdfr			break;
430178825Sdfr		case 'H':
431178825Sdfr			/*
432178825Sdfr			 * follow command line symlinks only
433178825Sdfr			 */
434178825Sdfr			Hflag = 1;
435233294Sstas			flg |= CHF;
436178825Sdfr			break;
437178825Sdfr		case 'L':
438178825Sdfr			/*
439178825Sdfr			 * follow symlinks
440178825Sdfr			 */
441178825Sdfr			Lflag = 1;
442178825Sdfr			flg |= CLF;
443178825Sdfr			break;
444178825Sdfr		case 'P':
445178825Sdfr			/*
446178825Sdfr			 * do NOT follow symlinks (default)
447233294Sstas			 */
448178825Sdfr			Lflag = 0;
449178825Sdfr			flg |= CPF;
450178825Sdfr			break;
451178825Sdfr		case 'T':
452178825Sdfr			/*
453178825Sdfr			 * non-standard option for selecting files within an
454178825Sdfr			 * archive by modification time range (lower,upper)
455178825Sdfr			 */
456178825Sdfr			if (trng_add(optarg) < 0) {
457178825Sdfr				pax_usage();
458178825Sdfr				break;
459178825Sdfr			}
460178825Sdfr			flg |= CTF;
461178825Sdfr			break;
462178825Sdfr		case 'U':
463233294Sstas			/*
464178825Sdfr			 * non-standard option for selecting files within an
465178825Sdfr			 * archive by user (uid or name)
466178825Sdfr			 */
467178825Sdfr			if (usr_add(optarg) < 0) {
468233294Sstas				pax_usage();
469178825Sdfr				break;
470178825Sdfr			}
471178825Sdfr			flg |= CUF;
472178825Sdfr			break;
473178825Sdfr		case 'X':
474178825Sdfr			/*
475178825Sdfr			 * do not pass over mount points in the file system
476178825Sdfr			 */
477178825Sdfr			Xflag = 1;
478178825Sdfr			flg |= CXF;
479178825Sdfr			break;
480178825Sdfr		case 'Y':
481178825Sdfr			/*
482178825Sdfr			 * On extraction check file inode change time after the
483178825Sdfr			 * modification of the file name. Non standard option.
484178825Sdfr			 */
485178825Sdfr			Yflag = 1;
486178825Sdfr			flg |= CYF;
487178825Sdfr			break;
488178825Sdfr		case 'Z':
489233294Sstas			/*
490178825Sdfr			 * On extraction check modification time after the
491178825Sdfr			 * modification of the file name. Non standard option.
492178825Sdfr			 */
493178825Sdfr			Zflag = 1;
494178825Sdfr			flg |= CZF;
495178825Sdfr			break;
496178825Sdfr		case '?':
497178825Sdfr		default:
498178825Sdfr			pax_usage();
499178825Sdfr			break;
500178825Sdfr		}
501178825Sdfr	}
502178825Sdfr
503178825Sdfr	/*
504178825Sdfr	 * figure out the operation mode of pax read,write,extract,copy,append
505233294Sstas	 * or list. check that we have not been given a bogus set of flags
506178825Sdfr	 * for the operation mode.
507178825Sdfr	 */
508178825Sdfr	if (ISLIST(flg)) {
509178825Sdfr		act = LIST;
510178825Sdfr		bflg = flg & BDLIST;
511178825Sdfr	} else if (ISEXTRACT(flg)) {
512178825Sdfr		act = EXTRACT;
513178825Sdfr		bflg = flg & BDEXTR;
514233294Sstas	} else if (ISARCHIVE(flg)) {
515178825Sdfr		act = ARCHIVE;
516178825Sdfr		bflg = flg & BDARCH;
517178825Sdfr	} else if (ISAPPND(flg)) {
518178825Sdfr		act = APPND;
519178825Sdfr		bflg = flg & BDARCH;
520178825Sdfr	} else if (ISCOPY(flg)) {
521178825Sdfr		act = COPY;
522178825Sdfr		bflg = flg & BDCOPY;
523178825Sdfr	} else
524178825Sdfr		pax_usage();
525178825Sdfr	if (bflg) {
526178825Sdfr		printflg(flg);
527178825Sdfr		pax_usage();
528178825Sdfr	}
529233294Sstas
530178825Sdfr	/*
531178825Sdfr	 * if we are writing (ARCHIVE) we use the default format if the user
532178825Sdfr	 * did not specify a format. when we write during an APPEND, we will
533178825Sdfr	 * adopt the format of the existing archive if none was supplied.
534178825Sdfr	 */
535178825Sdfr	if (!(flg & XF) && (act == ARCHIVE))
536178825Sdfr		frmt = &(fsub[DEFLT]);
537178825Sdfr
538178825Sdfr	/*
539178825Sdfr	 * process the args as they are interpreted by the operation mode
540178825Sdfr	 */
541178825Sdfr	switch (act) {
542178825Sdfr	case LIST:
543178825Sdfr	case EXTRACT:
544178825Sdfr		for (; optind < argc; optind++)
545178825Sdfr			if (pat_add(argv[optind]) < 0)
546178825Sdfr				pax_usage();
547178825Sdfr		break;
548178825Sdfr	case COPY:
549178825Sdfr		if (optind >= argc) {
550178825Sdfr			warn(0, "Destination directory was not supplied");
551178825Sdfr			pax_usage();
552178825Sdfr		}
553178825Sdfr		--argc;
554178825Sdfr		dirptr = argv[argc];
555178825Sdfr		/* FALL THROUGH */
556178825Sdfr	case ARCHIVE:
557178825Sdfr	case APPND:
558178825Sdfr		for (; optind < argc; optind++)
559178825Sdfr			if (ftree_add(argv[optind]) < 0)
560178825Sdfr				pax_usage();
561178825Sdfr		/*
562178825Sdfr		 * no read errors allowed on updates/append operation!
563178825Sdfr		 */
564178825Sdfr		maxflt = 0;
565178825Sdfr		break;
566178825Sdfr	}
567178825Sdfr}
568178825Sdfr
569178825Sdfr
570178825Sdfr/*
571178825Sdfr * tar_options()
572178825Sdfr *	look at the user specified flags. set globals as required and check if
573178825Sdfr *	the user specified a legal set of flags. If not, complain and exit
574178825Sdfr */
575178825Sdfr
576178825Sdfr#if __STDC__
577178825Sdfrstatic void
578178825Sdfrtar_options(register int argc, register char **argv)
579178825Sdfr#else
580178825Sdfrstatic void
581178825Sdfrtar_options(argc, argv)
582178825Sdfr	register int argc;
583178825Sdfr	register char **argv;
584178825Sdfr#endif
585178825Sdfr{
586178825Sdfr	register char *cp;
587178825Sdfr	int fstdin = 0;
588178825Sdfr
589178825Sdfr	if (argc < 2)
590178825Sdfr		tar_usage();
591178825Sdfr	/*
592178825Sdfr	 * process option flags
593178825Sdfr	 */
594178825Sdfr	++argv;
595178825Sdfr	for (cp = *argv++; *cp != '\0'; ++cp) {
596178825Sdfr		switch (*cp) {
597178825Sdfr		case '-':
598178825Sdfr			/*
599178825Sdfr			 * skip over -
600233294Sstas			 */
601178825Sdfr			break;
602178825Sdfr		case 'b':
603178825Sdfr			/*
604178825Sdfr			 * specify blocksize
605178825Sdfr			 */
606178825Sdfr			if (*argv == (char *)NULL) {
607178825Sdfr				warn(1,"blocksize must be specified with 'b'");
608233294Sstas				tar_usage();
609178825Sdfr			}
610178825Sdfr			if ((wrblksz = (int)str_offt(*argv)) <= 0) {
611178825Sdfr				warn(1, "Invalid block size %s", *argv);
612178825Sdfr				tar_usage();
613178825Sdfr			}
614178825Sdfr			++argv;
615178825Sdfr			break;
616178825Sdfr		case 'c':
617233294Sstas			/*
618178825Sdfr			 * create an archive
619178825Sdfr			 */
620178825Sdfr			act = ARCHIVE;
621233294Sstas			break;
622178825Sdfr		case 'e':
623178825Sdfr			/*
624178825Sdfr			 * stop after first error
625178825Sdfr			 */
626178825Sdfr			maxflt = 0;
627178825Sdfr			break;
628233294Sstas		case 'f':
629178825Sdfr			/*
630178825Sdfr			 * filename where the archive is stored
631178825Sdfr			 */
632178825Sdfr			if (*argv == (char *)NULL) {
633178825Sdfr				warn(1, "filename must be specified with 'f'");
634178825Sdfr				tar_usage();
635178825Sdfr			}
636178825Sdfr			if ((argv[0][0] == '-') && (argv[0][1]== '\0')) {
637178825Sdfr				/*
638233294Sstas				 * treat a - as stdin
639178825Sdfr				 */
640178825Sdfr				++argv;
641178825Sdfr				++fstdin;
642233294Sstas				arcname = (char *)0;
643178825Sdfr				break;
644178825Sdfr			}
645178825Sdfr			fstdin = 0;
646178825Sdfr			arcname = *argv++;
647178825Sdfr			break;
648178825Sdfr		case 'm':
649233294Sstas			/*
650178825Sdfr			 * do not preserve modification time
651178825Sdfr			 */
652178825Sdfr			pmtime = 0;
653178825Sdfr			break;
654178825Sdfr		case 'o':
655178825Sdfr			if (opt_add("write_opt=nodir") < 0)
656178825Sdfr				tar_usage();
657178825Sdfr			break;
658178825Sdfr		case 'p':
659233294Sstas			/*
660178825Sdfr			 * preserve user id, group id, file
661178825Sdfr			 * mode, access/modification times
662178825Sdfr			 */
663178825Sdfr			pids = 1;
664178825Sdfr			pmode = 1;
665178825Sdfr			patime = 1;
666178825Sdfr			pmtime = 1;
667178825Sdfr			break;
668178825Sdfr		case 'r':
669233294Sstas		case 'u':
670178825Sdfr			/*
671178825Sdfr			 * append to the archive
672178825Sdfr			 */
673178825Sdfr			act = APPND;
674178825Sdfr			break;
675178825Sdfr		case 't':
676178825Sdfr			/*
677178825Sdfr			 * list contents of the tape
678178825Sdfr			 */
679178825Sdfr			act = LIST;
680178825Sdfr			break;
681178825Sdfr		case 'v':
682178825Sdfr			/*
683178825Sdfr			 * verbose operation mode
684178825Sdfr			 */
685178825Sdfr			vflag = 1;
686178825Sdfr			break;
687178825Sdfr		case 'w':
688178825Sdfr			/*
689178825Sdfr			 * interactive file rename
690178825Sdfr			 */
691178825Sdfr			iflag = 1;
692233294Sstas			break;
693178825Sdfr		case 'x':
694178825Sdfr			/*
695178825Sdfr			 * write an archive
696178825Sdfr			 */
697178825Sdfr			act = EXTRACT;
698178825Sdfr			break;
699178825Sdfr		case 'B':
700178825Sdfr			/*
701178825Sdfr			 * Nothing to do here, this is pax default
702178825Sdfr			 */
703233294Sstas			break;
704178825Sdfr		case 'H':
705178825Sdfr			/*
706178825Sdfr			 * follow command line symlinks only
707178825Sdfr			 */
708178825Sdfr			Hflag = 1;
709178825Sdfr			break;
710178825Sdfr		case 'L':
711178825Sdfr			/*
712233294Sstas			 * follow symlinks
713178825Sdfr			 */
714178825Sdfr			Lflag = 1;
715178825Sdfr			break;
716178825Sdfr		case 'P':
717178825Sdfr			/*
718178825Sdfr			 * do not follow symlinks
719178825Sdfr			 */
720233294Sstas			Lflag = 0;
721178825Sdfr			break;
722178825Sdfr		case 'X':
723178825Sdfr			/*
724178825Sdfr			 * do not pass over mount points in the file system
725178825Sdfr			 */
726178825Sdfr			Xflag = 1;
727178825Sdfr			break;
728178825Sdfr		case '0':
729178825Sdfr			arcname = DEV_0;
730178825Sdfr			break;
731178825Sdfr		case '1':
732178825Sdfr			arcname = DEV_1;
733178825Sdfr			break;
734178825Sdfr		case '4':
735178825Sdfr			arcname = DEV_4;
736178825Sdfr			break;
737178825Sdfr		case '5':
738178825Sdfr			arcname = DEV_5;
739178825Sdfr			break;
740178825Sdfr		case '7':
741178825Sdfr			arcname = DEV_7;
742178825Sdfr			break;
743178825Sdfr		case '8':
744178825Sdfr			arcname = DEV_8;
745178825Sdfr			break;
746233294Sstas		default:
747178825Sdfr			tar_usage();
748178825Sdfr			break;
749178825Sdfr		}
750178825Sdfr	}
751178825Sdfr
752178825Sdfr	/*
753178825Sdfr	 * if we are writing (ARCHIVE) specify tar, otherwise run like pax
754178825Sdfr	 */
755178825Sdfr	if (act == ARCHIVE)
756178825Sdfr		frmt = &(fsub[F_TAR]);
757178825Sdfr
758178825Sdfr	/*
759178825Sdfr	 * process the args as they are interpreted by the operation mode
760178825Sdfr	 */
761178825Sdfr	switch (act) {
762178825Sdfr	case LIST:
763178825Sdfr	case EXTRACT:
764178825Sdfr	default:
765178825Sdfr		while (*argv != (char *)NULL)
766178825Sdfr			if (pat_add(*argv++) < 0)
767178825Sdfr				tar_usage();
768178825Sdfr		break;
769233294Sstas	case ARCHIVE:
770178825Sdfr	case APPND:
771178825Sdfr		while (*argv != (char *)NULL)
772178825Sdfr			if (ftree_add(*argv++) < 0)
773178825Sdfr				tar_usage();
774233294Sstas		/*
775178825Sdfr		 * no read errors allowed on updates/append operation!
776178825Sdfr		 */
777178825Sdfr		maxflt = 0;
778178825Sdfr		break;
779178825Sdfr	}
780233294Sstas	if (!fstdin && ((arcname == (char *)NULL) || (*arcname == '\0'))) {
781178825Sdfr		arcname = getenv("TAPE");
782178825Sdfr		if ((arcname == (char *)NULL) || (*arcname == '\0'))
783178825Sdfr			arcname = DEV_8;
784178825Sdfr	}
785233294Sstas}
786178825Sdfr
787178825Sdfr#ifdef notdef
788178825Sdfr/*
789178825Sdfr * cpio_options()
790178825Sdfr *	look at the user specified flags. set globals as required and check if
791178825Sdfr *	the user specified a legal set of flags. If not, complain and exit
792233294Sstas */
793178825Sdfr
794178825Sdfr#if __STDC__
795178825Sdfrstatic void
796178825Sdfrcpio_options(register int argc, register char **argv)
797233294Sstas#else
798178825Sdfrstatic void
799178825Sdfrcpio_options(argc, argv)
800178825Sdfr	register int argc;
801178825Sdfr	register char **argv;
802178825Sdfr#endif
803178825Sdfr{
804178825Sdfr}
805233294Sstas#endif
806178825Sdfr
807178825Sdfr/*
808178825Sdfr * printflg()
809178825Sdfr *	print out those invalid flag sets found to the user
810178825Sdfr */
811178825Sdfr
812178825Sdfr#if __STDC__
813178825Sdfrstatic void
814178825Sdfrprintflg(unsigned int flg)
815178825Sdfr#else
816178825Sdfrstatic void
817178825Sdfrprintflg(flg)
818178825Sdfr	unsigned int flg;
819178825Sdfr#endif
820178825Sdfr{
821178825Sdfr	int nxt;
822178825Sdfr	int pos = 0;
823178825Sdfr
824178825Sdfr	(void)fprintf(stderr,"%s: Invalid combination of options:", argv0);
825178825Sdfr	while ((nxt = ffs(flg))) {
826178825Sdfr		flg = flg >> nxt;
827178825Sdfr		pos += nxt;
828178825Sdfr		(void)fprintf(stderr, " -%c", flgch[pos-1]);
829178825Sdfr	}
830178825Sdfr	(void)putc('\n', stderr);
831178825Sdfr}
832178825Sdfr
833178825Sdfr/*
834178825Sdfr * c_frmt()
835178825Sdfr *	comparison routine used by bsearch to find the format specified
836178825Sdfr *	by the user
837178825Sdfr */
838178825Sdfr
839178825Sdfr#if __STDC__
840178825Sdfrstatic int
841178825Sdfrc_frmt(const void *a, const void *b)
842178825Sdfr#else
843178825Sdfrstatic int
844178825Sdfrc_frmt(a, b)
845178825Sdfr        void *a;
846178825Sdfr        void *b;
847178825Sdfr#endif
848233294Sstas{
849178825Sdfr        return(strcmp(((FSUB *)a)->name, ((FSUB *)b)->name));
850178825Sdfr}
851178825Sdfr
852178825Sdfr/*
853178825Sdfr * opt_next()
854178825Sdfr *	called by format specific options routines to get each format specific
855178825Sdfr *	flag and value specified with -o
856178825Sdfr * Return:
857178825Sdfr *	pointer to next OPLIST entry or NULL (end of list).
858178825Sdfr */
859178825Sdfr
860178825Sdfr#if __STDC__
861178825SdfrOPLIST *
862178825Sdfropt_next(void)
863178825Sdfr#else
864178825SdfrOPLIST *
865233294Sstasopt_next()
866178825Sdfr#endif
867178825Sdfr{
868178825Sdfr	OPLIST *opt;
869178825Sdfr
870178825Sdfr	if ((opt = ophead) != NULL)
871178825Sdfr		ophead = ophead->fow;
872178825Sdfr	return(opt);
873178825Sdfr}
874178825Sdfr
875178825Sdfr/*
876178825Sdfr * bad_opt()
877178825Sdfr *	generic routine used to complain about a format specific options
878178825Sdfr *	when the format does not support options.
879178825Sdfr */
880178825Sdfr
881178825Sdfr#if __STDC__
882178825Sdfrint
883233294Sstasbad_opt(void)
884178825Sdfr#else
885178825Sdfrint
886178825Sdfrbad_opt()
887178825Sdfr#endif
888178825Sdfr{
889178825Sdfr	register OPLIST *opt;
890178825Sdfr
891178825Sdfr	if (ophead == NULL)
892178825Sdfr		return(0);
893233294Sstas	/*
894178825Sdfr	 * print all we were given
895178825Sdfr	 */
896178825Sdfr	warn(1,"These format options are not supported");
897233294Sstas	while ((opt = opt_next()) != NULL)
898178825Sdfr		(void)fprintf(stderr, "\t%s = %s\n", opt->name, opt->value);
899178825Sdfr	pax_usage();
900178825Sdfr	return(0);
901178825Sdfr}
902178825Sdfr
903178825Sdfr/*
904178825Sdfr * opt_add()
905178825Sdfr *	breaks the value supplied to -o into a option name and value. options
906178825Sdfr *	are given to -o in the form -o name-value,name=value
907233294Sstas *	mulltiple -o may be specified.
908178825Sdfr * Return:
909178825Sdfr *	0 if format in name=value format, -1 if -o is passed junk
910178825Sdfr */
911233294Sstas
912178825Sdfr#if __STDC__
913178825Sdfrint
914178825Sdfropt_add(register char *str)
915178825Sdfr#else
916178825Sdfrint
917178825Sdfropt_add(str)
918178825Sdfr	register char *str;
919178825Sdfr#endif
920178825Sdfr{
921178825Sdfr	register OPLIST *opt;
922178825Sdfr	register char *frpt;
923178825Sdfr	register char *pt;
924178825Sdfr	register char *endpt;
925178825Sdfr
926233294Sstas	if ((str == NULL) || (*str == '\0')) {
927178825Sdfr		warn(0, "Invalid option name");
928178825Sdfr		return(-1);
929178825Sdfr	}
930178825Sdfr	frpt = endpt = str;
931233294Sstas
932178825Sdfr	/*
933178825Sdfr	 * break into name and values pieces and stuff each one into a
934178825Sdfr	 * OPLIST structure. When we know the format, the format specific
935178825Sdfr	 * option function will go through this list
936178825Sdfr	 */
937178825Sdfr	while ((frpt != NULL) && (*frpt != '\0')) {
938178825Sdfr		if ((endpt = strchr(frpt, ',')) != NULL)
939233294Sstas			*endpt = '\0';
940178825Sdfr		if ((pt = strchr(frpt, '=')) == NULL) {
941178825Sdfr			warn(0, "Invalid options format");
942178825Sdfr			return(-1);
943178825Sdfr		}
944178825Sdfr		if ((opt = (OPLIST *)malloc(sizeof(OPLIST))) == NULL) {
945178825Sdfr			warn(0, "Unable to allocate space for option list");
946178825Sdfr			return(-1);
947178825Sdfr		}
948178825Sdfr		*pt++ = '\0';
949178825Sdfr		opt->name = frpt;
950178825Sdfr		opt->value = pt;
951178825Sdfr		opt->fow = NULL;
952178825Sdfr		if (endpt != NULL)
953178825Sdfr			frpt = endpt + 1;
954178825Sdfr		else
955178825Sdfr			frpt = NULL;
956178825Sdfr		if (ophead == NULL) {
957178825Sdfr			optail = ophead = opt;
958178825Sdfr			continue;
959233294Sstas		}
960178825Sdfr		optail->fow = opt;
961178825Sdfr		optail = opt;
962178825Sdfr	}
963178825Sdfr	return(0);
964233294Sstas}
965178825Sdfr
966178825Sdfr/*
967178825Sdfr * str_offt()
968178825Sdfr *	Convert an expression of the following forms to an off_t > 0.
969178825Sdfr * 	1) A positive decimal number.
970178825Sdfr *	2) A positive decimal number followed by a b (mult by 512).
971178825Sdfr *	3) A positive decimal number followed by a k (mult by 1024).
972178825Sdfr *	4) A positive decimal number followed by a m (mult by 512).
973178825Sdfr *	5) A positive decimal number followed by a w (mult by sizeof int)
974178825Sdfr *	6) Two or more positive decimal numbers (with/without k,b or w).
975178825Sdfr *	   seperated by x (also * for backwards compatibility), specifying
976233294Sstas *	   the product of the indicated values.
977178825Sdfr * Return:
978178825Sdfr *	0 for an error, a positive value o.w.
979178825Sdfr */
980178825Sdfr
981178825Sdfr#if __STDC__
982178825Sdfrstatic off_t
983178825Sdfrstr_offt(char *val)
984178825Sdfr#else
985178825Sdfrstatic off_t
986178825Sdfrstr_offt(val)
987178825Sdfr	char *val;
988178825Sdfr#endif
989178825Sdfr{
990178825Sdfr	char *expr;
991178825Sdfr	off_t num, t;
992178825Sdfr
993178825Sdfr#	ifdef NET2_STAT
994178825Sdfr	num = strtol(val, &expr, 0);
995178825Sdfr	if ((num == LONG_MAX) || (num <= 0) || (expr == val))
996233294Sstas#	else
997178825Sdfr	num = strtoq(val, &expr, 0);
998178825Sdfr	if ((num == QUAD_MAX) || (num <= 0) || (expr == val))
999178825Sdfr#	endif
1000178825Sdfr		return(0);
1001178825Sdfr
1002178825Sdfr	switch(*expr) {
1003178825Sdfr	case 'b':
1004178825Sdfr		t = num;
1005178825Sdfr		num *= 512;
1006178825Sdfr		if (t > num)
1007233294Sstas			return(0);
1008178825Sdfr		++expr;
1009178825Sdfr		break;
1010178825Sdfr	case 'k':
1011178825Sdfr		t = num;
1012233294Sstas		num *= 1024;
1013178825Sdfr		if (t > num)
1014178825Sdfr			return(0);
1015178825Sdfr		++expr;
1016178825Sdfr		break;
1017178825Sdfr	case 'm':
1018178825Sdfr		t = num;
1019178825Sdfr		num *= 1048576;
1020178825Sdfr		if (t > num)
1021178825Sdfr			return(0);
1022178825Sdfr		++expr;
1023178825Sdfr		break;
1024178825Sdfr	case 'w':
1025178825Sdfr		t = num;
1026178825Sdfr		num *= sizeof(int);
1027178825Sdfr		if (t > num)
1028178825Sdfr			return(0);
1029178825Sdfr		++expr;
1030178825Sdfr		break;
1031233294Sstas	}
1032178825Sdfr
1033178825Sdfr	switch(*expr) {
1034178825Sdfr		case '\0':
1035178825Sdfr			break;
1036178825Sdfr		case '*':
1037233294Sstas		case 'x':
1038178825Sdfr			t = num;
1039178825Sdfr			num *= str_offt(expr + 1);
1040178825Sdfr			if (t > num)
1041178825Sdfr				return(0);
1042178825Sdfr			break;
1043178825Sdfr		default:
1044178825Sdfr			return(0);
1045178825Sdfr	}
1046178825Sdfr	return(num);
1047178825Sdfr}
1048178825Sdfr
1049178825Sdfr/*
1050178825Sdfr * no_op()
1051178825Sdfr *	for those option functions where the archive format has nothing to do.
1052178825Sdfr * Return:
1053178825Sdfr *	0
1054178825Sdfr */
1055233294Sstas
1056178825Sdfr#if __STDC__
1057178825Sdfrstatic int
1058178825Sdfrno_op(void)
1059178825Sdfr#else
1060178825Sdfrstatic int
1061178825Sdfrno_op()
1062178825Sdfr#endif
1063178825Sdfr{
1064178825Sdfr	return(0);
1065233294Sstas}
1066178825Sdfr
1067178825Sdfr/*
1068178825Sdfr * pax_usage()
1069178825Sdfr *	print the usage summary to the user
1070178825Sdfr */
1071178825Sdfr
1072233294Sstas#if __STDC__
1073178825Sdfrvoid
1074178825Sdfrpax_usage(void)
1075178825Sdfr#else
1076178825Sdfrvoid
1077178825Sdfrpax_usage()
1078178825Sdfr#endif
1079178825Sdfr{
1080233294Sstas	(void)fputs("usage: pax [-cdnv] [-E limit] [-f archive] ", stderr);
1081178825Sdfr	(void)fputs("[-s replstr] ... [-U user] ...", stderr);
1082178825Sdfr	(void)fputs("\n           [-G group] ... ", stderr);
1083178825Sdfr	(void)fputs("[-T [from_date][,to_date]] ... ", stderr);
1084178825Sdfr	(void)fputs("[pattern ...]\n", stderr);
1085178825Sdfr	(void)fputs("       pax -r [-cdiknuvDYZ] [-E limit] ", stderr);
1086178825Sdfr	(void)fputs("[-f archive] [-o options] ... \n", stderr);
1087233294Sstas	(void)fputs("           [-p string] ... [-s replstr] ... ", stderr);
1088178825Sdfr	(void)fputs("[-U user] ... [-G group] ...\n           ", stderr);
1089178825Sdfr	(void)fputs("[-T [from_date][,to_date]] ... ", stderr);
1090178825Sdfr	(void)fputs(" [pattern ...]\n", stderr);
1091178825Sdfr	(void)fputs("       pax -w [-dituvHLPX] [-b blocksize] ", stderr);
1092178825Sdfr	(void)fputs("[ [-a] [-f archive] ] [-x format] \n", stderr);
1093178825Sdfr	(void)fputs("           [-B bytes] [-s replstr] ... ", stderr);
1094178825Sdfr	(void)fputs("[-o options] ... [-U user] ...", stderr);
1095178825Sdfr	(void)fputs("\n           [-G group] ... ", stderr);
1096178825Sdfr	(void)fputs("[-T [from_date][,to_date][/[c][m]]] ... ", stderr);
1097178825Sdfr	(void)fputs("[file ...]\n", stderr);
1098178825Sdfr	(void)fputs("       pax -r -w [-diklntuvDHLPXYZ] ", stderr);
1099178825Sdfr	(void)fputs("[-p string] ... [-s replstr] ...", stderr);
1100233294Sstas	(void)fputs("\n           [-U user] ... [-G group] ... ", stderr);
1101178825Sdfr	(void)fputs("[-T [from_date][,to_date][/[c][m]]] ... ", stderr);
1102178825Sdfr	(void)fputs("\n           [file ...] directory\n", stderr);
1103178825Sdfr	exit(1);
1104178825Sdfr}
1105178825Sdfr
1106178825Sdfr/*
1107178825Sdfr * tar_usage()
1108178825Sdfr *	print the usage summary to the user
1109178825Sdfr */
1110178825Sdfr
1111178825Sdfr#if __STDC__
1112233294Sstasvoid
1113178825Sdfrtar_usage(void)
1114178825Sdfr#else
1115178825Sdfrvoid
1116178825Sdfrtar_usage()
1117178825Sdfr#endif
1118178825Sdfr{
1119178825Sdfr	(void)fputs("usage: tar -{txru}[cevfbmopwBHLPX014578] [tapefile] ",
1120178825Sdfr		 stderr);
1121178825Sdfr	(void)fputs("[blocksize] file1 file2...\n", stderr);
1122178825Sdfr	exit(1);
1123178825Sdfr}
1124178825Sdfr
1125178825Sdfr#ifdef notdef
1126178825Sdfr/*
1127178825Sdfr * cpio_usage()
1128178825Sdfr *	print the usage summary to the user
1129178825Sdfr */
1130178825Sdfr
1131178825Sdfr#if __STDC__
1132178825Sdfrvoid
1133178825Sdfrcpio_usage(void)
1134178825Sdfr#else
1135178825Sdfrvoid
1136178825Sdfrcpio_usage()
1137178825Sdfr#endif
1138178825Sdfr{
1139178825Sdfr	exit(1);
1140178825Sdfr}
1141178825Sdfr#endif
1142178825Sdfr