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