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