GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: bin/pax/options.c Lines: 122 635 19.2 %
Date: 2016-12-06 Branches: 66 433 15.2 %

Line Branch Exec Source
1
/*	$OpenBSD: options.c,v 1.93 2016/04/19 03:26:11 guenther 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/time.h>
39
#include <sys/stat.h>
40
#include <sys/mtio.h>
41
#include <stdio.h>
42
#include <string.h>
43
#include <errno.h>
44
#include <unistd.h>
45
#include <stdlib.h>
46
#include <limits.h>
47
#include <paths.h>
48
#include "pax.h"
49
#include "options.h"
50
#include "cpio.h"
51
#include "tar.h"
52
#include "extern.h"
53
54
/*
55
 * Routines which handle command line options
56
 */
57
58
static char flgch[] = FLGCH;	/* list of all possible flags */
59
static OPLIST *ophead = NULL;	/* head for format specific options -x */
60
static OPLIST *optail = NULL;	/* option tail */
61
62
static int no_op(void);
63
static void printflg(unsigned int);
64
static off_t str_offt(char *);
65
static char *get_line(FILE *fp);
66
static void pax_options(int, char **);
67
static void pax_usage(void);
68
static void tar_options(int, char **);
69
static void tar_usage(void);
70
static void cpio_options(int, char **);
71
static void cpio_usage(void);
72
73
static int compress_id(char *_blk, int _size);
74
static int gzip_id(char *_blk, int _size);
75
static int bzip2_id(char *_blk, int _size);
76
static int xz_id(char *_blk, int _size);
77
78
#define GZIP_CMD	"gzip"		/* command to run as gzip */
79
#define COMPRESS_CMD	"compress"	/* command to run as compress */
80
#define BZIP2_CMD	"bzip2"		/* command to run as bzip2 */
81
82
/*
83
 *	Format specific routine table
84
 *	(see pax.h for description of each function)
85
 *
86
 *	name, blksz, hdsz, udev, hlk, blkagn, inhead, id, st_read,
87
 *	read, end_read, st_write, write, end_write, trail,
88
 *	rd_data, wr_data, options
89
 */
90
91
FSUB fsub[] = {
92
#ifdef NOCPIO
93
/* 0: OLD BINARY CPIO */
94
	{ },
95
/* 1: OLD OCTAL CHARACTER CPIO */
96
	{ },
97
/* 2: SVR4 HEX CPIO */
98
	{ },
99
/* 3: SVR4 HEX CPIO WITH CRC */
100
	{ },
101
#else
102
/* 0: OLD BINARY CPIO */
103
	{"bcpio", 5120, sizeof(HD_BCPIO), 1, 0, 0, 1, bcpio_id, cpio_strd,
104
	bcpio_rd, bcpio_endrd, cpio_stwr, bcpio_wr, cpio_endwr, cpio_trail,
105
	bad_opt},
106
107
/* 1: OLD OCTAL CHARACTER CPIO */
108
	{"cpio", 5120, sizeof(HD_CPIO), 1, 0, 0, 1, cpio_id, cpio_strd,
109
	cpio_rd, cpio_endrd, cpio_stwr, cpio_wr, cpio_endwr, cpio_trail,
110
	bad_opt},
111
112
/* 2: SVR4 HEX CPIO */
113
	{"sv4cpio", 5120, sizeof(HD_VCPIO), 1, 0, 0, 1, vcpio_id, cpio_strd,
114
	vcpio_rd, vcpio_endrd, cpio_stwr, vcpio_wr, cpio_endwr, cpio_trail,
115
	bad_opt},
116
117
/* 3: SVR4 HEX CPIO WITH CRC */
118
	{"sv4crc", 5120, sizeof(HD_VCPIO), 1, 0, 0, 1, crc_id, crc_strd,
119
	vcpio_rd, vcpio_endrd, crc_stwr, vcpio_wr, cpio_endwr, cpio_trail,
120
	bad_opt},
121
#endif
122
/* 4: OLD TAR */
123
	{"tar", 10240, BLKMULT, 0, 1, BLKMULT, 0, tar_id, no_op,
124
	tar_rd, tar_endrd, no_op, tar_wr, tar_endwr, tar_trail,
125
	tar_opt},
126
127
/* 5: POSIX USTAR */
128
	{"ustar", 10240, BLKMULT, 0, 1, BLKMULT, 0, ustar_id, ustar_strd,
129
	ustar_rd, tar_endrd, ustar_stwr, ustar_wr, tar_endwr, tar_trail,
130
	tar_opt},
131
132
#ifdef SMALL
133
/* 6: compress, to detect failure to use -Z */
134
	{ },
135
/* 7: xz, to detect failure to decompress it */
136
	{ },
137
/* 8: bzip2, to detect failure to use -j */
138
	{ },
139
/* 9: gzip, to detect failure to use -z */
140
	{ },
141
#else
142
/* 6: compress, to detect failure to use -Z */
143
	{NULL, 0, 4, 0, 0, 0, 0, compress_id},
144
/* 7: xz, to detect failure to decompress it */
145
	{NULL, 0, 4, 0, 0, 0, 0, xz_id},
146
/* 8: bzip2, to detect failure to use -j */
147
	{NULL, 0, 4, 0, 0, 0, 0, bzip2_id},
148
/* 9: gzip, to detect failure to use -z */
149
	{NULL, 0, 4, 0, 0, 0, 0, gzip_id},
150
#endif
151
};
152
#define	F_OCPIO	0	/* format when called as cpio -6 */
153
#define	F_ACPIO	1	/* format when called as cpio -c */
154
#define	F_CPIO	3	/* format when called as cpio */
155
#define F_OTAR	4	/* format when called as tar -o */
156
#define F_TAR	5	/* format when called as tar */
157
#define DEFLT	5	/* default write format from list above */
158
159
/*
160
 * ford is the archive search order used by get_arc() to determine what kind
161
 * of archive we are dealing with. This helps to properly id archive formats
162
 * some formats may be subsets of others....
163
 */
164
int ford[] = {5, 4, 9, 8, 7, 6, 3, 2, 1, 0, -1};
165
166
/*
167
 * Do we have -C anywhere and what is it?
168
 */
169
int havechd = 0;
170
char *chdname = NULL;
171
172
/*
173
 * options()
174
 *	figure out if we are pax, tar or cpio. Call the appropriate options
175
 *	parser
176
 */
177
178
void
179
options(int argc, char **argv)
180
32
{
181
	extern char *__progname;
182
183
	/*
184
	 * Are we acting like pax, tar or cpio (based on argv[0])
185
	 */
186
32
	argv0 = __progname;
187
188
32
	if (strcmp(NM_TAR, argv0) == 0) {
189
22
		tar_options(argc, argv);
190
22
		return;
191
	}
192
#ifndef NOCPIO
193
10
	else if (strcmp(NM_CPIO, argv0) == 0) {
194
2
		cpio_options(argc, argv);
195
2
		return;
196
	}
197
#endif /* !NOCPIO */
198
	/*
199
	 * assume pax as the default
200
	 */
201
8
	argv0 = NM_PAX;
202
8
	pax_options(argc, argv);
203
}
204
205
/*
206
 * pax_options()
207
 *	look at the user specified flags. set globals as required and check if
208
 *	the user specified a legal set of flags. If not, complain and exit
209
 */
210
211
static void
212
pax_options(int argc, char **argv)
213
8
{
214
	int c;
215
	unsigned i;
216
8
	unsigned int flg = 0;
217
8
	unsigned int bflg = 0;
218
	const char *errstr;
219
	char *pt;
220
221
	/*
222
	 * process option flags
223
	 */
224
38
	while ((c=getopt(argc,argv,"ab:cdf:ijklno:p:rs:tuvwx:zB:DE:G:HLOPT:U:XYZ0"))
225
	    != -1) {
226








22
		switch (c) {
227
		case 'a':
228
			/*
229
			 * append
230
			 */
231
6
			flg |= AF;
232
6
			break;
233
		case 'b':
234
			/*
235
			 * specify blocksize
236
			 */
237
			flg |= BF;
238
			if ((wrblksz = (int)str_offt(optarg)) <= 0) {
239
				paxwarn(1, "Invalid block size %s", optarg);
240
				pax_usage();
241
			}
242
			break;
243
		case 'c':
244
			/*
245
			 * inverse match on patterns
246
			 */
247
			cflag = 1;
248
			flg |= CF;
249
			break;
250
		case 'd':
251
			/*
252
			 * match only dir on extract, not the subtree at dir
253
			 */
254
			dflag = 1;
255
			flg |= DF;
256
			break;
257
		case 'f':
258
			/*
259
			 * filename where the archive is stored
260
			 */
261
8
			arcname = optarg;
262
8
			flg |= FF;
263
8
			break;
264
		case 'i':
265
			/*
266
			 * interactive file rename
267
			 */
268
			iflag = 1;
269
			flg |= IF;
270
			break;
271
		case 'j':
272
			/*
273
			 * use bzip2.  Non standard option.
274
			 */
275
			gzip_program = BZIP2_CMD;
276
			break;
277
		case 'k':
278
			/*
279
			 * do not clobber files that exist
280
			 */
281
			kflag = 1;
282
			flg |= KF;
283
			break;
284
		case 'l':
285
			/*
286
			 * try to link src to dest with copy (-rw)
287
			 */
288
			lflag = 1;
289
			flg |= LF;
290
			break;
291
		case 'n':
292
			/*
293
			 * select first match for a pattern only
294
			 */
295
			nflag = 1;
296
			flg |= NF;
297
			break;
298
		case 'o':
299
			/*
300
			 * pass format specific options
301
			 */
302
			flg |= OF;
303
			if (opt_add(optarg) < 0)
304
				pax_usage();
305
			break;
306
		case 'p':
307
			/*
308
			 * specify file characteristic options
309
			 */
310
			for (pt = optarg; *pt != '\0'; ++pt) {
311
				switch (*pt) {
312
				case 'a':
313
					/*
314
					 * do not preserve access time
315
					 */
316
					patime = 0;
317
					break;
318
				case 'e':
319
					/*
320
					 * preserve user id, group id, file
321
					 * mode, access/modification times
322
					 */
323
					pids = 1;
324
					pmode = 1;
325
					patime = 1;
326
					pmtime = 1;
327
					break;
328
				case 'm':
329
					/*
330
					 * do not preserve modification time
331
					 */
332
					pmtime = 0;
333
					break;
334
				case 'o':
335
					/*
336
					 * preserve uid/gid
337
					 */
338
					pids = 1;
339
					break;
340
				case 'p':
341
					/*
342
					 * preserve file mode bits
343
					 */
344
					pmode = 1;
345
					break;
346
				default:
347
					paxwarn(1, "Invalid -p string: %c", *pt);
348
					pax_usage();
349
					break;
350
				}
351
			}
352
			flg |= PF;
353
			break;
354
		case 'r':
355
			/*
356
			 * read the archive
357
			 */
358
			flg |= RF;
359
			break;
360
		case 's':
361
			/*
362
			 * file name substitution name pattern
363
			 */
364
			if (rep_add(optarg) < 0) {
365
				pax_usage();
366
				break;
367
			}
368
			flg |= SF;
369
			break;
370
		case 't':
371
			/*
372
			 * preserve access time on filesystem nodes we read
373
			 */
374
			tflag = 1;
375
			flg |= TF;
376
			break;
377
		case 'u':
378
			/*
379
			 * ignore those older files
380
			 */
381
			uflag = 1;
382
			flg |= UF;
383
			break;
384
		case 'v':
385
			/*
386
			 * verbose operation mode
387
			 */
388
			vflag = 1;
389
			flg |= VF;
390
			break;
391
		case 'w':
392
			/*
393
			 * write an archive
394
			 */
395
8
			flg |= WF;
396
8
			break;
397
		case 'x':
398
			/*
399
			 * specify an archive format on write
400
			 */
401
			for (i = 0; i < sizeof(fsub)/sizeof(FSUB); ++i)
402
				if (fsub[i].name != NULL &&
403
				    strcmp(fsub[i].name, optarg) == 0)
404
					break;
405
			if (i < sizeof(fsub)/sizeof(FSUB)) {
406
				frmt = &fsub[i];
407
				flg |= XF;
408
				break;
409
			}
410
			paxwarn(1, "Unknown -x format: %s", optarg);
411
			(void)fputs("pax: Known -x formats are:", stderr);
412
			for (i = 0; i < (sizeof(fsub)/sizeof(FSUB)); ++i)
413
				if (fsub[i].name != NULL)
414
					(void)fprintf(stderr, " %s",
415
					    fsub[i].name);
416
			(void)fputs("\n\n", stderr);
417
			pax_usage();
418
			break;
419
		case 'z':
420
			/*
421
			 * use gzip.  Non standard option.
422
			 */
423
			gzip_program = GZIP_CMD;
424
			break;
425
		case 'B':
426
			/*
427
			 * non-standard option on number of bytes written on a
428
			 * single archive volume.
429
			 */
430
			if ((wrlimit = str_offt(optarg)) <= 0) {
431
				paxwarn(1, "Invalid write limit %s", optarg);
432
				pax_usage();
433
			}
434
			if (wrlimit % BLKMULT) {
435
				paxwarn(1, "Write limit is not a %d byte multiple",
436
				    BLKMULT);
437
				pax_usage();
438
			}
439
			flg |= CBF;
440
			break;
441
		case 'D':
442
			/*
443
			 * On extraction check file inode change time before the
444
			 * modification of the file name. Non standard option.
445
			 */
446
			Dflag = 1;
447
			flg |= CDF;
448
			break;
449
		case 'E':
450
			/*
451
			 * non-standard limit on read faults
452
			 * 0 indicates stop after first error, values
453
			 * indicate a limit, "NONE" try forever
454
			 */
455
			flg |= CEF;
456
			if (strcmp(NONE, optarg) == 0)
457
				maxflt = -1;
458
			else {
459
				maxflt = strtonum(optarg, 0, INT_MAX, &errstr);
460
				if (errstr) {
461
					paxwarn(1, "Error count value: %s", errstr);
462
					pax_usage();
463
				}
464
			}
465
			break;
466
		case 'G':
467
			/*
468
			 * non-standard option for selecting files within an
469
			 * archive by group (gid or name)
470
			 */
471
			if (grp_add(optarg) < 0) {
472
				pax_usage();
473
				break;
474
			}
475
			flg |= CGF;
476
			break;
477
		case 'H':
478
			/*
479
			 * follow command line symlinks only
480
			 */
481
			Hflag = 1;
482
			flg |= CHF;
483
			break;
484
		case 'L':
485
			/*
486
			 * follow symlinks
487
			 */
488
			Lflag = 1;
489
			flg |= CLF;
490
			break;
491
		case 'O':
492
			/*
493
			 * Force one volume.  Non standard option.
494
			 */
495
			force_one_volume = 1;
496
			break;
497
		case 'P':
498
			/*
499
			 * do NOT follow symlinks (default)
500
			 */
501
			Lflag = 0;
502
			flg |= CPF;
503
			break;
504
		case 'T':
505
			/*
506
			 * non-standard option for selecting files within an
507
			 * archive by modification time range (lower,upper)
508
			 */
509
			if (trng_add(optarg) < 0) {
510
				pax_usage();
511
				break;
512
			}
513
			flg |= CTF;
514
			break;
515
		case 'U':
516
			/*
517
			 * non-standard option for selecting files within an
518
			 * archive by user (uid or name)
519
			 */
520
			if (usr_add(optarg) < 0) {
521
				pax_usage();
522
				break;
523
			}
524
			flg |= CUF;
525
			break;
526
		case 'X':
527
			/*
528
			 * do not pass over mount points in the file system
529
			 */
530
			Xflag = 1;
531
			flg |= CXF;
532
			break;
533
		case 'Y':
534
			/*
535
			 * On extraction check file inode change time after the
536
			 * modification of the file name. Non standard option.
537
			 */
538
			Yflag = 1;
539
			flg |= CYF;
540
			break;
541
		case 'Z':
542
			/*
543
			 * On extraction check modification time after the
544
			 * modification of the file name. Non standard option.
545
			 */
546
			Zflag = 1;
547
			flg |= CZF;
548
			break;
549
		case '0':
550
			/*
551
			 * Use \0 as pathname terminator.
552
			 * (For use with the -print0 option of find(1).)
553
			 */
554
			zeroflag = 1;
555
			flg |= C0F;
556
			break;
557
		default:
558
			pax_usage();
559
			break;
560
		}
561
	}
562
563
	/*
564
	 * figure out the operation mode of pax read,write,extract,copy,append
565
	 * or list. check that we have not been given a bogus set of flags
566
	 * for the operation mode.
567
	 */
568
8
	if (ISLIST(flg)) {
569
		act = LIST;
570
		listf = stdout;
571
		bflg = flg & BDLIST;
572
8
	} else if (ISEXTRACT(flg)) {
573
		act = EXTRACT;
574
		bflg = flg & BDEXTR;
575
8
	} else if (ISARCHIVE(flg)) {
576
2
		act = ARCHIVE;
577
2
		bflg = flg & BDARCH;
578
6
	} else if (ISAPPND(flg)) {
579
6
		act = APPND;
580
6
		bflg = flg & BDARCH;
581
	} else if (ISCOPY(flg)) {
582
		act = COPY;
583
		bflg = flg & BDCOPY;
584
	} else
585
		pax_usage();
586
8
	if (bflg) {
587
		printflg(flg);
588
		pax_usage();
589
	}
590
591
	/*
592
	 * if we are writing (ARCHIVE) we use the default format if the user
593
	 * did not specify a format. when we write during an APPEND, we will
594
	 * adopt the format of the existing archive if none was supplied.
595
	 */
596

8
	if (!(flg & XF) && (act == ARCHIVE))
597
2
		frmt = &(fsub[DEFLT]);
598
599
	/*
600
	 * process the args as they are interpreted by the operation mode
601
	 */
602

8
	switch (act) {
603
	case LIST:
604
	case EXTRACT:
605
		for (; optind < argc; optind++)
606
			if (pat_add(argv[optind], NULL) < 0)
607
				pax_usage();
608
		break;
609
	case COPY:
610
		if (optind >= argc) {
611
			paxwarn(0, "Destination directory was not supplied");
612
			pax_usage();
613
		}
614
		--argc;
615
		dirptr = argv[argc];
616
		/* FALL THROUGH */
617
	case ARCHIVE:
618
	case APPND:
619
		for (; optind < argc; optind++)
620
			if (ftree_add(argv[optind], 0) < 0)
621
				pax_usage();
622
		/*
623
		 * no read errors allowed on updates/append operation!
624
		 */
625
8
		maxflt = 0;
626
		break;
627
	}
628
8
}
629
630
631
/*
632
 * tar_options()
633
 *	look at the user specified flags. set globals as required and check if
634
 *	the user specified a legal set of flags. If not, complain and exit
635
 */
636
637
static void
638
tar_options(int argc, char **argv)
639
22
{
640
	int c;
641
22
	int fstdin = 0;
642
22
	int Oflag = 0;
643
22
	int nincfiles = 0;
644
22
	int incfiles_max = 0;
645
	struct incfile {
646
		char *file;
647
		char *dir;
648
	};
649
22
	struct incfile *incfiles = NULL;
650
651
	/*
652
	 * Set default values.
653
	 */
654
22
	rmleadslash = 1;
655
656
	/*
657
	 * process option flags
658
	 */
659
96
	while ((c = getoldopt(argc, argv,
660
	    "b:cef:hjmopqruts:vwxzBC:HI:LNOPXZ014578")) != -1) {
661








52
		switch (c) {
662
		case 'b':
663
			/*
664
			 * specify blocksize in 512-byte blocks
665
			 */
666
			if ((wrblksz = (int)str_offt(optarg)) <= 0) {
667
				paxwarn(1, "Invalid block size %s", optarg);
668
				tar_usage();
669
			}
670
			wrblksz *= 512;		/* XXX - check for int oflow */
671
			break;
672
		case 'c':
673
			/*
674
			 * create an archive
675
			 */
676
2
			act = ARCHIVE;
677
2
			break;
678
		case 'e':
679
			/*
680
			 * stop after first error
681
			 */
682
			maxflt = 0;
683
			break;
684
		case 'f':
685
			/*
686
			 * filename where the archive is stored
687
			 */
688

22
			if ((optarg[0] == '-') && (optarg[1]== '\0')) {
689
				/*
690
				 * treat a - as stdin
691
				 */
692
10
				fstdin = 1;
693
10
				arcname = NULL;
694
10
				break;
695
			}
696
12
			fstdin = 0;
697
12
			arcname = optarg;
698
12
			break;
699
		case 'h':
700
			/*
701
			 * follow symlinks
702
			 */
703
			Lflag = 1;
704
			break;
705
		case 'j':
706
			/*
707
			 * use bzip2.  Non standard option.
708
			 */
709
			gzip_program = BZIP2_CMD;
710
			break;
711
		case 'm':
712
			/*
713
			 * do not preserve modification time
714
			 */
715
			pmtime = 0;
716
			break;
717
		case 'O':
718
2
			Oflag = 1;
719
2
			break;
720
		case 'o':
721
			Oflag = 2;
722
			tar_nodir = 1;
723
			break;
724
		case 'p':
725
			/*
726
			 * preserve uid/gid and file mode, regardless of umask
727
			 */
728
			pmode = 1;
729
			pids = 1;
730
			break;
731
		case 'q':
732
			/*
733
			 * select first match for a pattern only
734
			 */
735
			nflag = 1;
736
			break;
737
		case 'r':
738
		case 'u':
739
			/*
740
			 * append to the archive
741
			 */
742
			act = APPND;
743
			break;
744
		case 's':
745
			/*
746
			 * file name substitution name pattern
747
			 */
748
			if (rep_add(optarg) < 0) {
749
				tar_usage();
750
				break;
751
			}
752
			break;
753
		case 't':
754
			/*
755
			 * list contents of the tape
756
			 */
757
18
			act = LIST;
758
18
			break;
759
		case 'v':
760
			/*
761
			 * verbose operation mode
762
			 */
763
			vflag++;
764
			break;
765
		case 'w':
766
			/*
767
			 * interactive file rename
768
			 */
769
			iflag = 1;
770
			break;
771
		case 'x':
772
			/*
773
			 * extract an archive, preserving mode,
774
			 * and mtime if possible.
775
			 */
776
2
			act = EXTRACT;
777
2
			pmtime = 1;
778
2
			break;
779
		case 'z':
780
			/*
781
			 * use gzip.  Non standard option.
782
			 */
783
6
			gzip_program = GZIP_CMD;
784
6
			break;
785
		case 'B':
786
			/*
787
			 * Nothing to do here, this is pax default
788
			 */
789
			break;
790
		case 'C':
791
			havechd++;
792
			chdname = optarg;
793
			break;
794
		case 'H':
795
			/*
796
			 * follow command line symlinks only
797
			 */
798
			Hflag = 1;
799
			break;
800
		case 'I':
801
			if (++nincfiles > incfiles_max) {
802
				size_t n = nincfiles + 3;
803
				struct incfile *p;
804
805
				p = reallocarray(incfiles, n,
806
				    sizeof(*incfiles));
807
				if (p == NULL) {
808
					paxwarn(0, "Unable to allocate space "
809
					    "for option list");
810
					exit(1);
811
				}
812
				incfiles = p;
813
				incfiles_max = n;
814
			}
815
			incfiles[nincfiles - 1].file = optarg;
816
			incfiles[nincfiles - 1].dir = chdname;
817
			break;
818
		case 'L':
819
			/*
820
			 * follow symlinks
821
			 */
822
			Lflag = 1;
823
			break;
824
		case 'N':
825
			/* numeric uid and gid only */
826
			Nflag = 1;
827
			break;
828
		case 'P':
829
			/*
830
			 * do not remove leading '/' from pathnames
831
			 */
832
			rmleadslash = 0;
833
			break;
834
		case 'X':
835
			/*
836
			 * do not pass over mount points in the file system
837
			 */
838
			Xflag = 1;
839
			break;
840
		case 'Z':
841
			/*
842
			 * use compress.
843
			 */
844
			gzip_program = COMPRESS_CMD;
845
			break;
846
		case '0':
847
			arcname = DEV_0;
848
			break;
849
		case '1':
850
			arcname = DEV_1;
851
			break;
852
		case '4':
853
			arcname = DEV_4;
854
			break;
855
		case '5':
856
			arcname = DEV_5;
857
			break;
858
		case '7':
859
			arcname = DEV_7;
860
			break;
861
		case '8':
862
			arcname = DEV_8;
863
			break;
864
		default:
865
			tar_usage();
866
			break;
867
		}
868
	}
869
22
	argc -= optind;
870
22
	argv += optind;
871
872

22
	if (!fstdin && ((arcname == NULL) || (*arcname == '\0'))) {
873
		arcname = getenv("TAPE");
874
		if ((arcname == NULL) || (*arcname == '\0'))
875
			arcname = _PATH_DEFTAPE;
876
		else if ((arcname[0] == '-') && (arcname[1]== '\0')) {
877
			arcname = NULL;
878
			fstdin = 1;
879
		}
880
	}
881
882
	/* Traditional tar behaviour (pax uses stderr unless in list mode) */
883

24
	if (fstdin == 1 && act == ARCHIVE)
884
2
		listf = stderr;
885
	else
886
20
		listf = stdout;
887
888
	/* Traditional tar behaviour (pax wants to read file list from stdin) */
889

22
	if ((act == ARCHIVE || act == APPND) && argc == 0 && nincfiles == 0)
890
		exit(0);
891
892
	/*
893
	 * process the args as they are interpreted by the operation mode
894
	 */
895
22
	switch (act) {
896
	case LIST:
897
	case EXTRACT:
898
	default:
899
		{
900
20
			int sawpat = 0;
901
			char *file, *dir;
902
903

40
			while (nincfiles || *argv != NULL) {
904
				/*
905
				 * If we queued up any include files,
906
				 * pull them in now.  Otherwise, check
907
				 * for -I and -C positional flags.
908
				 * Anything else must be a file to
909
				 * extract.
910
				 */
911
				if (nincfiles) {
912
					file = incfiles->file;
913
					dir = incfiles->dir;
914
					incfiles++;
915
					nincfiles--;
916
				} else if (strcmp(*argv, "-I") == 0) {
917
					if (*++argv == NULL)
918
						break;
919
					file = *argv++;
920
					dir = chdname;
921
				} else
922
					file = NULL;
923
				if (file != NULL) {
924
					FILE *fp;
925
					char *str;
926
927
					if (strcmp(file, "-") == 0)
928
						fp = stdin;
929
					else if ((fp = fopen(file, "r")) == NULL) {
930
						syswarn(1, errno,
931
						    "Unable to open %s", file);
932
						tar_usage();
933
					}
934
					while ((str = get_line(fp)) != NULL) {
935
						if (pat_add(str, dir) < 0)
936
							tar_usage();
937
						sawpat = 1;
938
					}
939
					if (ferror(fp)) {
940
						syswarn(1, errno,
941
						    "Unable to read from %s",
942
						    strcmp(file, "-") ? file :
943
						    "stdin");
944
						tar_usage();
945
					}
946
					if (strcmp(file, "-") != 0)
947
						fclose(fp);
948
				} else if (strcmp(*argv, "-C") == 0) {
949
					if (*++argv == NULL)
950
						break;
951
					chdname = *argv++;
952
					havechd++;
953
				} else if (pat_add(*argv++, chdname) < 0)
954
					tar_usage();
955
				else
956
					sawpat = 1;
957
			}
958
			/*
959
			 * if patterns were added, we are doing	chdir()
960
			 * on a file-by-file basis, else, just one
961
			 * global chdir (if any) after opening input.
962
			 */
963
20
			if (sawpat > 0)
964
				chdname = NULL;
965
		}
966
		break;
967
	case ARCHIVE:
968
	case APPND:
969
2
		frmt = &(fsub[Oflag ? F_OTAR : F_TAR]);
970
971
2
		if (chdname != NULL) {	/* initial chdir() */
972
			if (ftree_add(chdname, 1) < 0)
973
				tar_usage();
974
		}
975
976

14
		while (nincfiles || *argv != NULL) {
977
			char *file, *dir;
978
979
			/*
980
			 * If we queued up any include files, pull them in
981
			 * now.  Otherwise, check for -I and -C positional
982
			 * flags.  Anything else must be a file to include
983
			 * in the archive.
984
			 */
985
12
			if (nincfiles) {
986
				file = incfiles->file;
987
				dir = incfiles->dir;
988
				incfiles++;
989
				nincfiles--;
990
12
			} else if (strcmp(*argv, "-I") == 0) {
991
				if (*++argv == NULL)
992
					break;
993
				file = *argv++;
994
				dir = NULL;
995
			} else
996
12
				file = NULL;
997
12
			if (file != NULL) {
998
				FILE *fp;
999
				char *str;
1000
1001
				/* Set directory if needed */
1002
				if (dir) {
1003
					if (ftree_add(dir, 1) < 0)
1004
						tar_usage();
1005
				}
1006
1007
				if (strcmp(file, "-") == 0)
1008
					fp = stdin;
1009
				else if ((fp = fopen(file, "r")) == NULL) {
1010
					syswarn(1, errno, "Unable to open %s",
1011
					    file);
1012
					tar_usage();
1013
				}
1014
				while ((str = get_line(fp)) != NULL) {
1015
					if (ftree_add(str, 0) < 0)
1016
						tar_usage();
1017
				}
1018
				if (ferror(fp)) {
1019
					syswarn(1, errno,
1020
					    "Unable to read from %s",
1021
					    strcmp(file, "-") ? file : "stdin");
1022
					tar_usage();
1023
				}
1024
				if (strcmp(file, "-") != 0)
1025
					fclose(fp);
1026
12
			} else if (strcmp(*argv, "-C") == 0) {
1027
				if (*++argv == NULL)
1028
					break;
1029
				if (ftree_add(*argv++, 1) < 0)
1030
					tar_usage();
1031
				havechd++;
1032
12
			} else if (ftree_add(*argv++, 0) < 0)
1033
				tar_usage();
1034
		}
1035
		/*
1036
		 * no read errors allowed on updates/append operation!
1037
		 */
1038
2
		maxflt = 0;
1039
		break;
1040
	}
1041
22
}
1042
1043
int mkpath(char *);
1044
1045
int
1046
mkpath(path)
1047
	char *path;
1048
{
1049
	struct stat sb;
1050
	char *slash;
1051
	int done = 0;
1052
1053
	slash = path;
1054
1055
	while (!done) {
1056
		slash += strspn(slash, "/");
1057
		slash += strcspn(slash, "/");
1058
1059
		done = (*slash == '\0');
1060
		*slash = '\0';
1061
1062
		if (stat(path, &sb)) {
1063
			if (errno != ENOENT || mkdir(path, 0777)) {
1064
				paxwarn(1, "%s", path);
1065
				return (-1);
1066
			}
1067
		} else if (!S_ISDIR(sb.st_mode)) {
1068
			syswarn(1, ENOTDIR, "%s", path);
1069
			return (-1);
1070
		}
1071
1072
		if (!done)
1073
			*slash = '/';
1074
	}
1075
1076
	return (0);
1077
}
1078
1079
#ifndef NOCPIO
1080
/*
1081
 * cpio_options()
1082
 *	look at the user specified flags. set globals as required and check if
1083
 *	the user specified a legal set of flags. If not, complain and exit
1084
 */
1085
1086
static void
1087
cpio_options(int argc, char **argv)
1088
2
{
1089
	const char *errstr;
1090
	int c;
1091
	unsigned i;
1092
	char *str;
1093
	FILE *fp;
1094
1095
2
	kflag = 1;
1096
2
	pids = 1;
1097
2
	pmode = 1;
1098
2
	pmtime = 0;
1099
2
	arcname = NULL;
1100
2
	dflag = 1;
1101
2
	act = -1;
1102
2
	nodirs = 1;
1103
6
	while ((c=getopt(argc,argv,"abcdfijklmoprstuvzABC:E:F:H:I:LO:SZ6")) != -1)
1104






2
		switch (c) {
1105
			case 'a':
1106
				/*
1107
				 * preserve access time on files read
1108
				 */
1109
				tflag = 1;
1110
				break;
1111
			case 'b':
1112
				/*
1113
				 * swap bytes and half-words when reading data
1114
				 */
1115
				break;
1116
			case 'c':
1117
				/*
1118
				 * ASCII cpio header
1119
				 */
1120
				frmt = &(fsub[F_ACPIO]);
1121
				break;
1122
			case 'd':
1123
				/*
1124
				 * create directories as needed
1125
				 */
1126
				nodirs = 0;
1127
				break;
1128
			case 'f':
1129
				/*
1130
				 * invert meaning of pattern list
1131
				 */
1132
				cflag = 1;
1133
				break;
1134
			case 'i':
1135
				/*
1136
				 * restore an archive
1137
				 */
1138
				act = EXTRACT;
1139
				break;
1140
			case 'j':
1141
				/*
1142
				 * use bzip2.  Non standard option.
1143
				 */
1144
				gzip_program = BZIP2_CMD;
1145
				break;
1146
			case 'k':
1147
				break;
1148
			case 'l':
1149
				/*
1150
				 * use links instead of copies when possible
1151
				 */
1152
				lflag = 1;
1153
				break;
1154
			case 'm':
1155
				/*
1156
				 * preserve modification time
1157
				 */
1158
				pmtime = 1;
1159
				break;
1160
			case 'o':
1161
				/*
1162
				 * create an archive
1163
				 */
1164
2
				act = ARCHIVE;
1165
2
				frmt = &(fsub[F_CPIO]);
1166
2
				break;
1167
			case 'p':
1168
				/*
1169
				 * copy-pass mode
1170
				 */
1171
				act = COPY;
1172
				break;
1173
			case 'r':
1174
				/*
1175
				 * interactively rename files
1176
				 */
1177
				iflag = 1;
1178
				break;
1179
			case 's':
1180
				/*
1181
				 * swap bytes after reading data
1182
				 */
1183
				break;
1184
			case 't':
1185
				/*
1186
				 * list contents of archive
1187
				 */
1188
				act = LIST;
1189
				listf = stdout;
1190
				break;
1191
			case 'u':
1192
				/*
1193
				 * replace newer files
1194
				 */
1195
				kflag = 0;
1196
				break;
1197
			case 'v':
1198
				/*
1199
				 * verbose operation mode
1200
				 */
1201
				vflag = 1;
1202
				break;
1203
			case 'z':
1204
				/*
1205
				 * use gzip.  Non standard option.
1206
				 */
1207
				gzip_program = GZIP_CMD;
1208
				break;
1209
			case 'A':
1210
				/*
1211
				 * append mode
1212
				 */
1213
				act = APPND;
1214
				break;
1215
			case 'B':
1216
				/*
1217
				 * Use 5120 byte block size
1218
				 */
1219
				wrblksz = 5120;
1220
				break;
1221
			case 'C':
1222
				/*
1223
				 * set block size in bytes
1224
				 */
1225
				wrblksz = strtonum(optarg, 0, INT_MAX, &errstr);
1226
				if (errstr) {
1227
					paxwarn(1, "Invalid block size %s: %s",
1228
					    optarg, errstr);
1229
					pax_usage();
1230
				}
1231
				break;
1232
			case 'E':
1233
				/*
1234
				 * file with patterns to extract or list
1235
				 */
1236
				if ((fp = fopen(optarg, "r")) == NULL) {
1237
					syswarn(1, errno, "Unable to open %s",
1238
					    optarg);
1239
					cpio_usage();
1240
				}
1241
				while ((str = get_line(fp)) != NULL) {
1242
					pat_add(str, NULL);
1243
				}
1244
				if (ferror(fp)) {
1245
					syswarn(1, errno,
1246
					    "Unable to read from %s", optarg);
1247
					cpio_usage();
1248
				}
1249
				fclose(fp);
1250
				break;
1251
			case 'F':
1252
			case 'I':
1253
			case 'O':
1254
				/*
1255
				 * filename where the archive is stored
1256
				 */
1257
				if ((optarg[0] == '-') && (optarg[1]== '\0')) {
1258
					/*
1259
					 * treat a - as stdin
1260
					 */
1261
					arcname = NULL;
1262
					break;
1263
				}
1264
				arcname = optarg;
1265
				break;
1266
			case 'H':
1267
				/*
1268
				 * specify an archive format on write
1269
				 */
1270
				for (i = 0; i < sizeof(fsub)/sizeof(FSUB); ++i)
1271
					if (fsub[i].name != NULL &&
1272
					    strcmp(fsub[i].name, optarg) == 0)
1273
						break;
1274
				if (i < sizeof(fsub)/sizeof(FSUB)) {
1275
					frmt = &fsub[i];
1276
					break;
1277
				}
1278
				paxwarn(1, "Unknown -H format: %s", optarg);
1279
				(void)fputs("cpio: Known -H formats are:", stderr);
1280
				for (i = 0; i < (sizeof(fsub)/sizeof(FSUB)); ++i)
1281
					if (fsub[i].name != NULL)
1282
						(void)fprintf(stderr, " %s",
1283
						    fsub[i].name);
1284
				(void)fputs("\n\n", stderr);
1285
				cpio_usage();
1286
				break;
1287
			case 'L':
1288
				/*
1289
				 * follow symbolic links
1290
				 */
1291
				Lflag = 1;
1292
				break;
1293
			case 'S':
1294
				/*
1295
				 * swap halfwords after reading data
1296
				 */
1297
				break;
1298
			case 'Z':
1299
				/*
1300
				 * use compress.  Non standard option.
1301
				 */
1302
				gzip_program = COMPRESS_CMD;
1303
				break;
1304
			case '6':
1305
				/*
1306
				 * process Version 6 cpio format
1307
				 */
1308
				frmt = &(fsub[F_OCPIO]);
1309
				break;
1310
			case '?':
1311
			default:
1312
				cpio_usage();
1313
				break;
1314
		}
1315
2
	argc -= optind;
1316
2
	argv += optind;
1317
1318
	/*
1319
	 * process the args as they are interpreted by the operation mode
1320
	 */
1321

2
	switch (act) {
1322
		case LIST:
1323
		case EXTRACT:
1324
			while (*argv != NULL)
1325
				if (pat_add(*argv++, NULL) < 0)
1326
					cpio_usage();
1327
			break;
1328
		case COPY:
1329
			if (*argv == NULL) {
1330
				paxwarn(0, "Destination directory was not supplied");
1331
				cpio_usage();
1332
			}
1333
			dirptr = *argv;
1334
			if (mkpath(dirptr) < 0)
1335
				cpio_usage();
1336
			--argc;
1337
			++argv;
1338
			/* FALL THROUGH */
1339
		case ARCHIVE:
1340
		case APPND:
1341
2
			if (*argv != NULL)
1342
				cpio_usage();
1343
			/*
1344
			 * no read errors allowed on updates/append operation!
1345
			 */
1346
2
			maxflt = 0;
1347
4
			while ((str = get_line(stdin)) != NULL) {
1348
				ftree_add(str, 0);
1349
			}
1350

2
			if (ferror(stdin)) {
1351
				syswarn(1, errno, "Unable to read from %s",
1352
				    "stdin");
1353
				cpio_usage();
1354
			}
1355
			break;
1356
		default:
1357
			cpio_usage();
1358
			break;
1359
	}
1360
2
}
1361
#endif /* !NOCPIO */
1362
1363
/*
1364
 * printflg()
1365
 *	print out those invalid flag sets found to the user
1366
 */
1367
1368
static void
1369
printflg(unsigned int flg)
1370
{
1371
	int nxt;
1372
	int pos = 0;
1373
1374
	(void)fprintf(stderr,"%s: Invalid combination of options:", argv0);
1375
	while ((nxt = ffs(flg)) != 0) {
1376
		flg = flg >> nxt;
1377
		pos += nxt;
1378
		(void)fprintf(stderr, " -%c", flgch[pos-1]);
1379
	}
1380
	(void)putc('\n', stderr);
1381
}
1382
1383
/*
1384
 * opt_next()
1385
 *	called by format specific options routines to get each format specific
1386
 *	flag and value specified with -o
1387
 * Return:
1388
 *	pointer to next OPLIST entry or NULL (end of list).
1389
 */
1390
1391
OPLIST *
1392
opt_next(void)
1393
30
{
1394
	OPLIST *opt;
1395
1396
30
	if ((opt = ophead) != NULL)
1397
		ophead = ophead->fow;
1398
30
	return(opt);
1399
}
1400
1401
/*
1402
 * bad_opt()
1403
 *	generic routine used to complain about a format specific options
1404
 *	when the format does not support options.
1405
 */
1406
1407
int
1408
bad_opt(void)
1409
2
{
1410
	OPLIST *opt;
1411
1412
2
	if (ophead == NULL)
1413
2
		return(0);
1414
	/*
1415
	 * print all we were given
1416
	 */
1417
	paxwarn(1,"These format options are not supported");
1418
	while ((opt = opt_next()) != NULL)
1419
		(void)fprintf(stderr, "\t%s = %s\n", opt->name, opt->value);
1420
	pax_usage();
1421
	return(0);
1422
}
1423
1424
/*
1425
 * opt_add()
1426
 *	breaks the value supplied to -o into a option name and value. options
1427
 *	are given to -o in the form -o name-value,name=value
1428
 *	multiple -o may be specified.
1429
 * Return:
1430
 *	0 if format in name=value format, -1 if -o is passed junk
1431
 */
1432
1433
int
1434
opt_add(const char *str)
1435
{
1436
	OPLIST *opt;
1437
	char *frpt;
1438
	char *pt;
1439
	char *endpt;
1440
	char *dstr;
1441
1442
	if ((str == NULL) || (*str == '\0')) {
1443
		paxwarn(0, "Invalid option name");
1444
		return(-1);
1445
	}
1446
	if ((dstr = strdup(str)) == NULL) {
1447
		paxwarn(0, "Unable to allocate space for option list");
1448
		return(-1);
1449
	}
1450
	frpt = endpt = dstr;
1451
1452
	/*
1453
	 * break into name and values pieces and stuff each one into a
1454
	 * OPLIST structure. When we know the format, the format specific
1455
	 * option function will go through this list
1456
	 */
1457
	while ((frpt != NULL) && (*frpt != '\0')) {
1458
		if ((endpt = strchr(frpt, ',')) != NULL)
1459
			*endpt = '\0';
1460
		if ((pt = strchr(frpt, '=')) == NULL) {
1461
			paxwarn(0, "Invalid options format");
1462
			free(dstr);
1463
			return(-1);
1464
		}
1465
		if ((opt = malloc(sizeof(OPLIST))) == NULL) {
1466
			paxwarn(0, "Unable to allocate space for option list");
1467
			free(dstr);
1468
			return(-1);
1469
		}
1470
		dstr = NULL;	/* parts of string going onto the OPLIST */
1471
		*pt++ = '\0';
1472
		opt->name = frpt;
1473
		opt->value = pt;
1474
		opt->fow = NULL;
1475
		if (endpt != NULL)
1476
			frpt = endpt + 1;
1477
		else
1478
			frpt = NULL;
1479
		if (ophead == NULL) {
1480
			optail = ophead = opt;
1481
			continue;
1482
		}
1483
		optail->fow = opt;
1484
		optail = opt;
1485
	}
1486
	free(dstr);
1487
	return(0);
1488
}
1489
1490
/*
1491
 * str_offt()
1492
 *	Convert an expression of the following forms to an off_t > 0.
1493
 *	1) A positive decimal number.
1494
 *	2) A positive decimal number followed by a b (mult by 512).
1495
 *	3) A positive decimal number followed by a k (mult by 1024).
1496
 *	4) A positive decimal number followed by a m (mult by 512).
1497
 *	5) A positive decimal number followed by a w (mult by sizeof int)
1498
 *	6) Two or more positive decimal numbers (with/without k,b or w).
1499
 *	   separated by x (also * for backwards compatibility), specifying
1500
 *	   the product of the indicated values.
1501
 * Return:
1502
 *	0 for an error, a positive value o.w.
1503
 */
1504
1505
static off_t
1506
str_offt(char *val)
1507
{
1508
	char *expr;
1509
	off_t num, t;
1510
1511
	num = strtoll(val, &expr, 0);
1512
	if ((num == LLONG_MAX) || (num <= 0) || (expr == val))
1513
		return(0);
1514
1515
	switch (*expr) {
1516
	case 'b':
1517
		t = num;
1518
		num *= 512;
1519
		if (t > num)
1520
			return(0);
1521
		++expr;
1522
		break;
1523
	case 'k':
1524
		t = num;
1525
		num *= 1024;
1526
		if (t > num)
1527
			return(0);
1528
		++expr;
1529
		break;
1530
	case 'm':
1531
		t = num;
1532
		num *= 1048576;
1533
		if (t > num)
1534
			return(0);
1535
		++expr;
1536
		break;
1537
	case 'w':
1538
		t = num;
1539
		num *= sizeof(int);
1540
		if (t > num)
1541
			return(0);
1542
		++expr;
1543
		break;
1544
	}
1545
1546
	switch (*expr) {
1547
		case '\0':
1548
			break;
1549
		case '*':
1550
		case 'x':
1551
			t = num;
1552
			num *= str_offt(expr + 1);
1553
			if (t > num)
1554
				return(0);
1555
			break;
1556
		default:
1557
			return(0);
1558
	}
1559
	return(num);
1560
}
1561
1562
char *
1563
get_line(FILE *f)
1564
2
{
1565
2
	char *str = NULL;
1566
2
	size_t size = 0;
1567
	ssize_t len;
1568
1569
	do {
1570
2
		len = getline(&str, &size, f);
1571
2
		if (len == -1) {
1572
2
			free(str);
1573
2
			return NULL;
1574
		}
1575
		if (str[len - 1] == '\n')
1576
			str[len - 1] = '\0';
1577
	} while (str[0] == '\0');
1578
	return str;
1579
}
1580
1581
/*
1582
 * no_op()
1583
 *	for those option functions where the archive format has nothing to do.
1584
 * Return:
1585
 *	0
1586
 */
1587
1588
static int
1589
no_op(void)
1590
6
{
1591
6
	return(0);
1592
}
1593
1594
/*
1595
 * pax_usage()
1596
 *	print the usage summary to the user
1597
 */
1598
1599
void
1600
pax_usage(void)
1601
{
1602
	(void)fputs(
1603
	    "usage: pax [-0cdjnOvz] [-E limit] [-f archive] [-G group] [-s replstr]\n"
1604
	    "           [-T range] [-U user] [pattern ...]\n"
1605
	    "       pax -r [-0cDdijknOuvYZz] [-E limit] [-f archive] [-G group] [-o options]\n"
1606
	    "           [-p string] [-s replstr] [-T range] [-U user] [pattern ...]\n"
1607
	    "       pax -w [-0adHijLOPtuvXz] [-B bytes] [-b blocksize] [-f archive]\n"
1608
	    "           [-G group] [-o options] [-s replstr] [-T range] [-U user]\n"
1609
	    "           [-x format] [file ...]\n"
1610
	    "       pax -rw [-0DdHikLlnOPtuvXYZ] [-G group] [-p string] [-s replstr]\n"
1611
	    "           [-T range] [-U user] [file ...] directory\n",
1612
	    stderr);
1613
	exit(1);
1614
}
1615
1616
/*
1617
 * tar_usage()
1618
 *	print the usage summary to the user
1619
 */
1620
1621
void
1622
tar_usage(void)
1623
{
1624
	(void)fputs(
1625
	    "usage: tar {crtux}[014578befHhjLmNOoPpqsvwXZz]\n"
1626
	    "           [blocking-factor | archive | replstr] [-C directory] [-I file]\n"
1627
	    "           [file ...]\n"
1628
	    "       tar {-crtux} [-014578eHhjLmNOoPpqvwXZz] [-b blocking-factor]\n"
1629
	    "           [-C directory] [-f archive] [-I file] [-s replstr] [file ...]\n",
1630
	    stderr);
1631
	exit(1);
1632
}
1633
1634
#ifndef NOCPIO
1635
/*
1636
 * cpio_usage()
1637
 *	print the usage summary to the user
1638
 */
1639
1640
void
1641
cpio_usage(void)
1642
{
1643
	(void)fputs(
1644
	    "usage: cpio -o [-AaBcjLvZz] [-C bytes] [-F archive] [-H format]\n"
1645
	    "            [-O archive] < name-list [> archive]\n"
1646
	    "       cpio -i [-6BbcdfjmrSstuvZz] [-C bytes] [-E file] [-F archive] [-H format]\n"
1647
	    "            [-I archive] [pattern ...] [< archive]\n"
1648
	    "       cpio -p [-adLlmuv] destination-directory < name-list\n",
1649
	    stderr);
1650
	exit(1);
1651
}
1652
#endif /* !NOCPIO */
1653
1654
#ifndef SMALL
1655
static int
1656
compress_id(char *blk, int size)
1657
{
1658
	if (size >= 2 && blk[0] == '\037' && blk[1] == '\235') {
1659
		paxwarn(0, "input compressed with %s; use the -%c option"
1660
		    " to decompress it", "compress", 'Z');
1661
		exit(1);
1662
	}
1663
	return (-1);
1664
}
1665
1666
static int
1667
gzip_id(char *blk, int size)
1668
{
1669
	if (size >= 2 && blk[0] == '\037' && blk[1] == '\213') {
1670
		paxwarn(0, "input compressed with %s; use the -%c option"
1671
		    " to decompress it", "gzip", 'z');
1672
		exit(1);
1673
	}
1674
	return (-1);
1675
}
1676
1677
static int
1678
bzip2_id(char *blk, int size)
1679
{
1680
	if (size >= 3 && blk[0] == 'B' && blk[1] == 'Z' && blk[2] == 'h') {
1681
		paxwarn(0, "input compressed with %s; use the -%c option"
1682
		    " to decompress it", "bzip2", 'j');
1683
		exit(1);
1684
	}
1685
	return (-1);
1686
}
1687
1688
static int
1689
xz_id(char *blk, int size)
1690
{
1691
	if (size >= 6 && memcmp(blk, "\xFD\x37\x7A\x58\x5A", 6) == 0) {
1692
		paxwarn(0, "input compressed with xz");
1693
		exit(1);
1694
	}
1695
	return (-1);
1696
}
1697
#endif /* !SMALL */