* Copyright (c) 1992 Keith Muller.
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
* This code is derived from software contributed to Berkeley by
* Keith Muller of the University of California, San Diego.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
static char sccsid
[] = "@(#)options.c 8.1 (Berkeley) 5/31/93";
* Routines which handle command line options
static char flgch
[] = FLGCH
; /* list of all possible flags */
static OPLIST
*ophead
= NULL
; /* head for format specific options -x */
static OPLIST
*optail
= NULL
; /* option tail */
static int no_op
__P((void));
static void printflg
__P((unsigned int));
static int c_frmt
__P((const void *, const void *));
static off_t str_offt
__P((char *));
* Format specific routine table - MUST BE IN SORTED ORDER BY NAME
* (see pax.h for description of each function)
* name, blksz, hdsz, udev, hlk, blkagn, inhead, id, st_read,
* read, end_read, st_write, write, end_write, trail,
* rd_data, wr_data, options
"bcpio", 5120, sizeof(HD_BCPIO
), 1, 0, 0, 1, bcpio_id
, cpio_strd
,
bcpio_rd
, bcpio_endrd
, cpio_stwr
, bcpio_wr
, cpio_endwr
, cpio_trail
,
rd_wrfile
, wr_rdfile
, bad_opt
,
/* 1: OLD OCTAL CHARACTER CPIO */
"cpio", 5120, sizeof(HD_CPIO
), 1, 0, 0, 1, cpio_id
, cpio_strd
,
cpio_rd
, cpio_endrd
, cpio_stwr
, cpio_wr
, cpio_endwr
, cpio_trail
,
rd_wrfile
, wr_rdfile
, bad_opt
,
"sv4cpio", 5120, sizeof(HD_VCPIO
), 1, 0, 0, 1, vcpio_id
, cpio_strd
,
vcpio_rd
, vcpio_endrd
, cpio_stwr
, vcpio_wr
, cpio_endwr
, cpio_trail
,
rd_wrfile
, wr_rdfile
, bad_opt
,
/* 3: SVR4 HEX CPIO WITH CRC */
"sv4crc", 5120, sizeof(HD_VCPIO
), 1, 0, 0, 1, crc_id
, crc_strd
,
vcpio_rd
, vcpio_endrd
, crc_stwr
, vcpio_wr
, cpio_endwr
, cpio_trail
,
rd_wrfile
, wr_rdfile
, bad_opt
,
"tar", 10240, BLKMULT
, 0, 1, BLKMULT
, 0, tar_id
, no_op
,
tar_rd
, tar_endrd
, no_op
, tar_wr
, tar_endwr
, tar_trail
,
rd_wrfile
, wr_rdfile
, tar_opt
,
"ustar", 10240, BLKMULT
, 0, 1, BLKMULT
, 0, ustar_id
, ustar_strd
,
ustar_rd
, tar_endrd
, ustar_stwr
, ustar_wr
, tar_endwr
, tar_trail
,
rd_wrfile
, wr_rdfile
, bad_opt
,
#define DEFLT 5 /* default write format from list above */
* ford is the archive search order used by get_arc() to determine what kind
* of archive we are dealing with. This helps to properly id archive formats
* some formats may be subsets of others....
int ford
[] = {5, 4, 3, 2, 1, 0, -1 };
* look at the user specified flags. set globals as required and check if
* the user specified a legal set of flags. If not, complain and exit
options(register int argc
, register char **argv
)
while ((c
=getopt(argc
,argv
,"ab:cdf:iklno:p:rs:tuvwx:B:DE:G:HLT:U:XYZ"))
* specify blocksize on write
if ((wrblksz
= (int)str_offt(optarg
)) <= 0) {
warn(1, "Invalid block size %s", optarg
);
* inverse match on patterns
* match only dir on extract, not the subtree at dir
* filename where the archive is stored
* interactive file rename
* do not clobber files that exist
* try to link src to dest with copy (-rw)
* select first match for a pattern only
* pass format specific options
* specify file characteristic options
for (pt
= optarg
; *pt
!= '\0'; ++pt
) {
* do not preserve access time
* preserve user id, group id, file
* mode, access/modification times
* do not preserve modification time
* preserver file mode bits
warn(1, "Invalid -p string: %c", *pt
);
* file name substitution name pattern
if (rep_add(optarg
) < 0) {
* preserve access time on filesystem nodes we read
* ignore those older files
* specify an archive format on write
if (frmt
= (FSUB
*)bsearch((void *)&tmp
, (void *)fsub
,
sizeof(fsub
)/sizeof(FSUB
), sizeof(FSUB
), c_frmt
)) {
warn(1, "Unknown -x format: %s", optarg
);
(void)fputs("pax: Known -x formats are:", stderr
);
for (i
= 0; i
< (sizeof(fsub
)/sizeof(FSUB
)); ++i
)
(void)fprintf(stderr
, " %s", fsub
[i
].name
);
(void)fputs("\n\n", stderr
);
* non-standard option on number of bytes written on a
if ((wrlimit
= str_offt(optarg
)) <= 0) {
warn(1, "Invalid write limit %s", optarg
);
warn(1, "Write limit is not a %d byte multiple",
* On extraction check file inode change time before the
* modification of the file name. Non standard option.
* non-standard limit on read faults
* 0 indicates stop after first error, values
* indicate a limit, "NONE" try forever
if (strcmp(NONE
, optarg
) == 0)
else if ((maxflt
= atoi(optarg
)) < 0) {
warn(1, "Error count value must be positive");
* non-standard option for selecting files within an
* archive by group (gid or name)
if (grp_add(optarg
) < 0) {
* follow command line symlinks only
* non-standard option for selecting files within an
* archive by modification time range (lower,upper)
if (trng_add(optarg
) < 0) {
* non-standard option for selecting files within an
* archive by user (uid or name)
if (usr_add(optarg
) < 0) {
* do not pass over mount points in the file system
* On extraction check file inode change time after the
* modification of the file name. Non standard option.
* On extraction check modification time after the
* modification of the file name. Non standard option.
* figure out the operation mode of pax read,write,extract,copy,append
* or list. check that we have not been given a bogus set of flags
* for the operation mode.
} else if (ISEXTRACT(flg
)) {
} else if (ISARCHIVE(flg
)) {
} else if (ISAPPND(flg
)) {
} else if (ISCOPY(flg
)) {
* if we are writing (ARCHIVE) we use the default format if the user
* did not specify a format. when we write during an APPEND, we will
* adopt the format of the existing archive if none was supplied.
if (!(flg
& XF
) && (act
== ARCHIVE
))
* process the args as they are interpreted by the operation mode
for (; optind
< argc
; optind
++)
if (pat_add(argv
[optind
]) < 0)
warn(0, "Destination directory was not supplied");
for (; optind
< argc
; optind
++)
if (ftree_add(argv
[optind
]) < 0)
* no read errors allowed on updates/append operation!
* print out those invalid flag sets found to the user
printflg(unsigned int flg
)
(void)fputs("pax: Invalid combination of options:", stderr
);
(void)fprintf(stderr
, " -%c", flgch
[pos
-1]);
(void)putc('\n', stderr
);
* comparison routine used by bsearch to find the format specified
c_frmt(const void *a
, const void *b
)
return(strcmp(((FSUB
*)a
)->name
, ((FSUB
*)b
)->name
));
* called by format specific options routines to get each format specific
* flag and value specified with -o
* pointer to next OPLIST entry or NULL (end of list).
if ((opt
= ophead
) != NULL
)
* generic routine used to complain about a format specific options
* when the format does not support options.
* print all we were given
warn(1,"These format options are not supported");
while ((opt
= opt_next()) != NULL
)
(void)fprintf(stderr
, "\t%s = %s\n", opt
->name
, opt
->value
);
* breaks the value supplied to -o into a option name and value. options
* are given to -o in the form -o name-value,name=value
* mulltiple -o may be specified.
* 0 if format in name=value format, -1 if -o is passed junk
opt_add(register char *str
)
if ((str
== NULL
) || (*str
== '\0')) {
warn(0, "Invalid option name");
* break into name and values pieces and stuff each one into a
* OPLIST structure. When we know the format, the format specific
* option function will go through this list
while ((frpt
!= NULL
) && (*frpt
!= '\0')) {
if ((endpt
= strchr(frpt
, ',')) != NULL
)
if ((pt
= strchr(frpt
, '=')) == NULL
) {
warn(0, "Invalid options format");
if ((opt
= (OPLIST
*)malloc(sizeof(OPLIST
))) == NULL
) {
warn(0, "Unable to allocate space for option list");
* Convert an expression of the following forms to an off_t > 0.
* 1) A positive decimal number.
* 2) A positive decimal number followed by a b (mult by 512).
* 3) A positive decimal number followed by a k (mult by 1024).
* 4) A positive decimal number followed by a m (mult by 512).
* 5) A positive decimal number followed by a w (mult by sizeof int)
* 6) Two or more positive decimal numbers (with/without k,b or w).
* seperated by x (also * for backwards compatibility), specifying
* the product of the indicated values.
* 0 for an error, a positive value o.w.
num
= strtol(val
, &expr
, 0);
if ((num
== LONG_MAX
) || (num
<= 0) || (expr
== val
))
num
= strtoq(val
, &expr
, 0);
if ((num
== QUAD_MAX
) || (num
<= 0) || (expr
== val
))
num
*= str_offt(expr
+ 1);
* for those option functions where the archive format has nothing to do.