-/* $OpenBSD: options.c,v 1.31 1998/01/22 06:21:29 millert Exp $ */
+/* $OpenBSD: options.c,v 1.70 2008/06/11 00:49:08 pvalchev Exp $ */
/* $NetBSD: options.c,v 1.6 1996/03/26 23:54:18 mrg Exp $ */
/*-
* 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
+ * 3. 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.
*
* SUCH DAMAGE.
*/
+#include <sys/cdefs.h>
#ifndef lint
#if 0
-static char sccsid[] = "@(#)options.c 8.2 (Berkeley) 4/18/94";
+static const char sccsid[] = "@(#)options.c 8.2 (Berkeley) 4/18/94";
#else
-static char rcsid[] __attribute__((__unused__)) = "$OpenBSD: options.c,v 1.31 1998/01/22 06:21:29 millert Exp $";
+__used static const char rcsid[] = "$OpenBSD: options.c,v 1.70 2008/06/11 00:49:08 pvalchev Exp $";
#endif
#endif /* not lint */
#include <sys/types.h>
#include <sys/time.h>
#include <sys/stat.h>
+#include <search.h>
+#ifndef __APPLE__
#include <sys/mtio.h>
+#endif /* __APPLE__ */
#include <sys/param.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <limits.h>
#include <paths.h>
+#include <getopt.h>
#include "pax.h"
#include "options.h"
#include "cpio.h"
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 *));
-static void pax_options __P((register int, register char **));
-static void pax_usage __P((void));
-static void tar_options __P((register int, register char **));
-static void tar_usage __P((void));
-static void cpio_options __P((register int, register char **));
-static void cpio_usage __P((void));
+static int no_op(void);
+static void printflg(unsigned int);
+static int c_frmt(const void *, const void *);
+static off_t str_offt(char *);
+static char *pax_getline(FILE *fp);
+static void pax_options(int, char **);
+void pax_usage(void);
+static void tar_options(int, char **);
+static void tar_usage(void);
+static void cpio_options(int, char **);
+static void cpio_usage(void);
+
+/* errors from getline */
+#define GETLINE_FILE_CORRUPT 1
+#define GETLINE_OUT_OF_MEM 2
+static int getline_error;
+
#define GZIP_CMD "gzip" /* command to run as gzip */
#define COMPRESS_CMD "compress" /* command to run as compress */
+#define BZIP2_CMD "bzip2" /* command to run as bzip2 */
/*
* Format specific routine table - MUST BE IN SORTED ORDER BY NAME
* rd_data, wr_data, options
*/
-FSUB fsub[] = {
-/* 0: OLD BINARY CPIO */
+const FSUB fsub[] = {
+/* OLD BINARY CPIO */
{"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 */
+/* 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},
-/* 2: SVR4 HEX CPIO */
+/* POSIX 3 PAX */
+ {"pax", 5120, BLKMULT, 0, 1, BLKMULT, 0, pax_id, ustar_strd,
+ pax_rd, tar_endrd, ustar_stwr, pax_wr, tar_endwr, tar_trail,
+ rd_wrfile, wr_rdfile, pax_opt},
+
+/* SVR4 HEX CPIO */
{"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 */
+/* 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},
-/* 4: OLD TAR */
+/* OLD TAR */
{"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},
-/* 5: POSIX USTAR */
+/* POSIX USTAR */
{"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 F_OCPIO 0 /* format when called as cpio -6 */
-#define F_ACPIO 1 /* format when called as cpio -c */
-#define F_CPIO 3 /* format when called as cpio */
-#define F_OTAR 4 /* format when called as tar -o */
-#define F_TAR 5 /* format when called as tar */
-#define DEFLT 5 /* default write format from list above */
+#define F_OCPIO 0 /* format when called as cpio -6 */
+#define F_ACPIO 1 /* format when called as cpio -c */
+#define F_PAX 2 /* -x pax */
+#define F_SCPIO 3 /* -x sv4cpio */
+#define F_CPIO 4 /* format when called as cpio */
+#define F_OTAR 5 /* format when called as tar -o */
+#define F_TAR 6 /* format when called as tar */
+#define DEFLT F_TAR /* 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
+ * 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 };
+int ford[] = {F_PAX, F_TAR, F_OTAR, F_CPIO, F_SCPIO, F_ACPIO, F_OCPIO, -1 };
+
+/*
+ * Do we have -C anywhere?
+ */
+int havechd = 0;
/*
* options()
* parser
*/
-#ifdef __STDC__
-void
-options(register int argc, register char **argv)
-#else
void
-options(argc, argv)
- register int argc;
- register char **argv;
-#endif
+options(int argc, char **argv)
{
/*
else
argv0 = argv[0];
- if (strcmp(NM_TAR, argv0) == 0)
- return(tar_options(argc, argv));
- else if (strcmp(NM_CPIO, argv0) == 0)
- return(cpio_options(argc, argv));
+ if (strcmp(NM_TAR, argv0) == 0) {
+ tar_options(argc, argv);
+ return;
+ } else if (strcmp(NM_CPIO, argv0) == 0) {
+ cpio_options(argc, argv);
+ return;
+ }
/*
* assume pax as the default
*/
argv0 = NM_PAX;
- return(pax_options(argc, argv));
+ pax_options(argc, argv);
}
+#define OPT_INSECURE 1
+struct option pax_longopts[] = {
+ { "insecure", no_argument, 0, OPT_INSECURE },
+ { 0, 0, 0, 0 },
+};
+
/*
* pax_options()
* 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
*/
-#ifdef __STDC__
-static void
-pax_options(register int argc, register char **argv)
-#else
static void
-pax_options(argc, argv)
- register int argc;
- register char **argv;
-#endif
+pax_options(int argc, char **argv)
{
- register int c;
- register int i;
+ int c;
+ size_t i;
unsigned int flg = 0;
unsigned int bflg = 0;
- register char *pt;
+ char *pt;
FSUB tmp;
- extern char *optarg;
- extern int optind;
+ size_t n_fsub;
+ char * tmp_name;
+ listf = stderr;
/*
* process option flags
*/
- while ((c=getopt(argc,argv,"ab:cdf:iklno:p:rs:tuvwx:zB:DE:G:HLPT:U:XYZ"))
- != EOF) {
+ while ((c=getopt_long(argc,argv,"0ab:cdf:ijklno:p:rs:tuvwx:zB:DE:G:HLOPT:U:XYZ", pax_longopts, NULL)) != -1) {
switch (c) {
+ case '0':
+ /*
+ * Use \0 as pathname terminator.
+ * (For use with the -print0 option of find(1).)
+ */
+ zeroflag = 1;
+ flg |= C0F;
+ break;
case 'a':
/*
* append
/*
* filename where the archive is stored
*/
+ if ((optarg[0] == '-') && (optarg[1]== '\0')) {
+ /*
+ * treat a - as stdin (like tar)
+ */
+ arcname = NULL;
+ break;
+ }
arcname = optarg;
flg |= FF;
break;
iflag = 1;
flg |= IF;
break;
+ case 'j':
+ /*
+ * use bzip2. Non standard option.
+ */
+ gzip_program = BZIP2_CMD;
+ break;
case 'k':
/*
* do not clobber files that exist
* pass format specific options
*/
flg |= OF;
- if (opt_add(optarg) < 0)
+ if (pax_format_opt_add(optarg) < 0)
pax_usage();
break;
case 'p':
* specify file characteristic options
*/
for (pt = optarg; *pt != '\0'; ++pt) {
- switch(*pt) {
+ switch (*pt) {
case 'a':
/*
* do not preserve access time
break;
case 'p':
/*
- * preserver file mode bits
+ * preserve file mode bits
*/
pmode = 1;
break;
/*
* read the archive
*/
+ pax_read_or_list_mode=1;
flg |= RF;
break;
case 's':
* specify an archive format on write
*/
tmp.name = optarg;
- if (0 == strcmp("pax", optarg)) { /* alias for ustar */
- tmp.name = "ustar";
- }
- if ((frmt = (FSUB *)bsearch((void *)&tmp, (void *)fsub,
- sizeof(fsub)/sizeof(FSUB), sizeof(FSUB), c_frmt)) != NULL) {
+ n_fsub = sizeof(fsub)/sizeof(FSUB);
+ if ((frmt = (FSUB *)bsearch(&tmp, fsub, n_fsub, sizeof(FSUB),
+ c_frmt)) != NULL) {
flg |= XF;
break;
}
/*
* use gzip. Non standard option.
*/
- zflag = 1;
gzip_program = GZIP_CMD;
break;
case 'B':
*/
Hflag = 1;
flg |= CHF;
+ Lflag = 0; /* -H and -L are mutually exclusive */
+ flg &= ~CLF; /* only use the last one seen */
break;
case 'L':
/*
*/
Lflag = 1;
flg |= CLF;
+ Hflag = 0; /* -H and -L are mutually exclusive */
+ flg &= ~CHF; /* only use the last one seen */
+ break;
+ case 'O':
+ /*
+ * Force one volume. Non standard option.
+ */
+ force_one_volume = 1;
break;
case 'P':
/*
Zflag = 1;
flg |= CZF;
break;
+ case OPT_INSECURE:
+ secure = 0;
+ break;
default:
pax_usage();
break;
}
}
+ /*
+ * Fix for POSIX.cmd/pax/pax.ex test 132: force -wu options to look
+ * like -wua options were specified.
+ */
+ if (uflag && (flg & WF) && !(flg & RF)) { /* -w but not -r -w */
+ flg |= AF;
+ }
+
/*
* 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
*/
if (ISLIST(flg)) {
act = LIST;
+ pax_read_or_list_mode=1;
+ listf = stdout;
bflg = flg & BDLIST;
} else if (ISEXTRACT(flg)) {
act = EXTRACT;
if (!(flg & XF) && (act == ARCHIVE))
frmt = &(fsub[DEFLT]);
+ /*
+ * if copying (-r and -w) and there is no -x specified, we act as
+ * if -x pax was specified.
+ */
+ if (!(flg & XF) && (act == COPY))
+ frmt = &(fsub[F_PAX]);
+
+ /*
+ * Initialize the global extended header template.
+ */
+ tmp_name = getenv("TMPDIR");
+ if (tmp_name) {
+ asprintf(&header_name_g, "%s%s", tmp_name, "/GlobalHead.%p.%n");
+ } else {
+ header_name_g = "/tmp/GlobalHead.%p.%n";
+ }
+
/*
* process the args as they are interpreted by the operation mode
*/
* the user specified a legal set of flags. If not, complain and exit
*/
-#ifdef __STDC__
-static void
-tar_options(register int argc, register char **argv)
-#else
static void
-tar_options(argc, argv)
- register int argc;
- register char **argv;
-#endif
+tar_options(int argc, char **argv)
{
- register int c;
+ int c;
int fstdin = 0;
int Oflag = 0;
+ int nincfiles = 0;
+ int incfiles_max = 0;
+ struct incfile {
+ char *file;
+ char *dir;
+ };
+ struct incfile *incfiles = NULL;
/*
* Set default values.
* process option flags
*/
while ((c = getoldopt(argc, argv,
- "b:cef:hmopruts:vwxzBC:HLOPXZ014578"))
- != EOF) {
- switch(c) {
+ "b:cef:hjmopqruts:vwxzBC:HI:LOPXZ014578")) != -1) {
+ switch (c) {
case 'b':
/*
* specify blocksize in 512-byte blocks
*/
Lflag = 1;
break;
+ case 'j':
+ /*
+ * use bzip2. Non standard option.
+ */
+ gzip_program = BZIP2_CMD;
+ break;
case 'm':
/*
* do not preserve modification time
*/
pmtime = 0;
break;
- case 'o':
- if (opt_add("write_opt=nodir") < 0)
- tar_usage();
case 'O':
Oflag = 1;
break;
+ case 'o':
+ Oflag = 2;
+ break;
case 'p':
/*
- * preserve user id, group id, file
- * mode, access/modification times
+ * preserve uid/gid and file mode, regardless of umask
*/
- pids = 1;
pmode = 1;
- patime = 1;
- pmtime = 1;
+ pids = 1;
+ break;
+ case 'q':
+ /*
+ * select first match for a pattern only
+ */
+ nflag = 1;
break;
case 'r':
case 'u':
break;
case 'x':
/*
- * write an archive, preserve ids if root
+ * extract an archive, preserving mode,
+ * and mtime if possible.
*/
act = EXTRACT;
- if (geteuid() == 0)
- pids = 1;
+ pmtime = 1;
break;
case 'z':
/*
* use gzip. Non standard option.
*/
- zflag = 1;
gzip_program = GZIP_CMD;
break;
case 'B':
*/
break;
case 'C':
+ havechd++;
chdname = optarg;
break;
case 'H':
*/
Hflag = 1;
break;
+ case 'I':
+ if (++nincfiles > incfiles_max) {
+ incfiles_max = nincfiles + 3;
+ incfiles = realloc(incfiles,
+ sizeof(*incfiles) * incfiles_max);
+ if (incfiles == NULL) {
+ paxwarn(0, "Unable to allocate space "
+ "for option list");
+ exit(1);
+ }
+ }
+ incfiles[nincfiles - 1].file = optarg;
+ incfiles[nincfiles - 1].dir = chdname;
+ break;
case 'L':
/*
* follow symlinks
/*
* use compress.
*/
- zflag = 1;
gzip_program = COMPRESS_CMD;
break;
case '0':
argc -= optind;
argv += optind;
- /* Traditional tar behaviour (pax wants to read filelist from stdin) */
- if ((act == ARCHIVE || act == APPND) && argc == 0)
- exit(0);
+ /* Traditional tar behaviour (pax uses stderr unless in list mode) */
+ if (fstdin == 1 && act == ARCHIVE)
+ listf = stderr;
+ else
+ listf = stdout;
- /*
- * if we are writing (ARCHIVE) specify tar, otherwise run like pax
- * (unless -o specified)
- */
- if (act == ARCHIVE || act == APPND)
- frmt = &(fsub[Oflag ? F_OTAR : F_TAR]);
- else if (Oflag) {
- paxwarn(1, "The -O/-o options are only valid when writing an archive");
- tar_usage(); /* only valid when writing */
- }
+ /* Traditional tar behaviour (pax wants to read file list from stdin) */
+ if ((act == ARCHIVE || act == APPND) && argc == 0 && nincfiles == 0)
+ exit(0);
/*
* process the args as they are interpreted by the operation mode
default:
{
int sawpat = 0;
+ char *file, *dir = NULL;
- while (*argv != NULL) {
- if (strcmp(*argv, "-C") == 0) {
- if(*++argv == NULL)
+ while (nincfiles || *argv != NULL) {
+ /*
+ * If we queued up any include files,
+ * pull them in now. Otherwise, check
+ * for -I and -C positional flags.
+ * Anything else must be a file to
+ * extract.
+ */
+ if (nincfiles) {
+ file = incfiles->file;
+ dir = incfiles->dir;
+ incfiles++;
+ nincfiles--;
+ } else if (strcmp(*argv, "-I") == 0) {
+ if (*++argv == NULL)
+ break;
+ file = *argv++;
+ dir = chdname;
+ } else
+ file = NULL;
+ if (file != NULL) {
+ FILE *fp;
+ char *str;
+
+ if (strcmp(file, "-") == 0)
+ fp = stdin;
+ else if ((fp = fopen(file, "r")) == NULL) {
+ paxwarn(1, "Unable to open file '%s' for read", file);
+ tar_usage();
+ }
+ while ((str = pax_getline(fp)) != NULL) {
+ if (pat_add(str, dir) < 0)
+ tar_usage();
+ sawpat = 1;
+ }
+ if (strcmp(file, "-") != 0)
+ fclose(fp);
+ if (getline_error) {
+ paxwarn(1, "Problem with file '%s'", file);
+ tar_usage();
+ }
+ } else if (strcmp(*argv, "-C") == 0) {
+ if (*++argv == NULL)
break;
chdname = *argv++;
-
- continue;
- }
- if (pat_add(*argv++, chdname) < 0)
+ havechd++;
+ } else if (pat_add(*argv++, chdname) < 0)
tar_usage();
- sawpat++;
+ else
+ sawpat = 1;
}
/*
* if patterns were added, we are doing chdir()
- * on a file-by-file basis, else, just one
+ * on a file-by-file basis, else, just one
* global chdir (if any) after opening input.
*/
if (sawpat > 0)
break;
case ARCHIVE:
case APPND:
+ frmt = &(fsub[Oflag ? F_OTAR : F_TAR]);
+
+ if (Oflag == 2 && opt_add("write_opt=nodir") < 0)
+ tar_usage();
+
if (chdname != NULL) { /* initial chdir() */
if (ftree_add(chdname, 1) < 0)
tar_usage();
}
- while (*argv != NULL) {
- if (!strcmp(*argv, "-C")) {
+ while (nincfiles || *argv != NULL) {
+ char *file, *dir = NULL;
+
+ /*
+ * If we queued up any include files, pull them in
+ * now. Otherwise, check for -I and -C positional
+ * flags. Anything else must be a file to include
+ * in the archive.
+ */
+ if (nincfiles) {
+ file = incfiles->file;
+ dir = incfiles->dir;
+ incfiles++;
+ nincfiles--;
+ } else if (strcmp(*argv, "-I") == 0) {
if (*++argv == NULL)
break;
- if (ftree_add(*argv++, 1) < 0)
+ file = *argv++;
+ dir = NULL;
+ } else
+ file = NULL;
+ if (file != NULL) {
+ FILE *fp;
+ char *str;
+
+ /* Set directory if needed */
+ if (dir) {
+ if (ftree_add(dir, 1) < 0)
+ tar_usage();
+ }
+
+ if (strcmp(file, "-") == 0)
+ fp = stdin;
+ else if ((fp = fopen(file, "r")) == NULL) {
+ paxwarn(1, "Unable to open file '%s' for read", file);
tar_usage();
- } else {
- if (ftree_add(*argv++, 0) < 0)
+ }
+ while ((str = pax_getline(fp)) != NULL) {
+ if (ftree_add(str, 0) < 0)
+ tar_usage();
+ }
+ if (strcmp(file, "-") != 0)
+ fclose(fp);
+ if (getline_error) {
+ paxwarn(1, "Problem with file '%s'",
+ file);
tar_usage();
- }
+ }
+ } else if (strcmp(*argv, "-C") == 0) {
+ if (*++argv == NULL)
+ break;
+ if (ftree_add(*argv++, 1) < 0)
+ tar_usage();
+ havechd++;
+ } else if (ftree_add(*argv++, 0) < 0)
+ tar_usage();
}
/*
* no read errors allowed on updates/append operation!
}
}
+int mkpath(char *);
+
int
mkpath(path)
char *path;
{
struct stat sb;
- register char *slash;
+ char *slash;
int done = 0;
slash = path;
* the user specified a legal set of flags. If not, complain and exit
*/
-#ifdef __STDC__
static void
-cpio_options(register int argc, register char **argv)
-#else
-static void
-cpio_options(argc, argv)
- register int argc;
- register char **argv;
-#endif
+cpio_options(int argc, char **argv)
{
- register int c, i;
- size_t len;
+ int c, i;
char *str;
FSUB tmp;
FILE *fp;
+ size_t n_fsub;
kflag = 1;
pids = 1;
dflag = 1;
act = -1;
nodirs = 1;
- while ((c=getopt(argc,argv,"abcdfiklmoprstuvzABC:E:F:H:I:LO:SZ6")) != EOF)
+ while ((c=getopt(argc,argv,"abcdfijklmoprstuvzABC:E:F:H:I:LO:SZ6")) != -1)
switch (c) {
case 'a':
/*
*/
act = EXTRACT;
break;
+ case 'j':
+ /*
+ * use bzip2. Non standard option.
+ */
+ gzip_program = BZIP2_CMD;
+ break;
case 'k':
break;
case 'l':
* list contents of archive
*/
act = LIST;
+ listf = stdout;
break;
case 'u':
/*
/*
* use gzip. Non standard option.
*/
- zflag = 1;
gzip_program = GZIP_CMD;
break;
case 'A':
paxwarn(1, "Unable to open file '%s' for read", optarg);
cpio_usage();
}
- while ((str = fgetln(fp, &len)) != NULL) {
- str[len - 1] = '\0';
+ while ((str = pax_getline(fp)) != NULL) {
pat_add(str, NULL);
}
fclose(fp);
+ if (getline_error) {
+ paxwarn(1, "Problem with file '%s'", optarg);
+ cpio_usage();
+ }
break;
case 'F':
case 'I':
* specify an archive format on write
*/
tmp.name = optarg;
+ n_fsub = sizeof(fsub)/sizeof(FSUB);
if ((frmt = (FSUB *)bsearch((void *)&tmp, (void *)fsub,
- sizeof(fsub)/sizeof(FSUB), sizeof(FSUB), c_frmt)) != NULL)
+ n_fsub, sizeof(FSUB), c_frmt)) != NULL)
break;
paxwarn(1, "Unknown -H format: %s", optarg);
(void)fputs("cpio: Known -H formats are:", stderr);
/*
* use compress. Non standard option.
*/
- zflag = 1;
gzip_program = COMPRESS_CMD;
break;
case '6':
* no read errors allowed on updates/append operation!
*/
maxflt = 0;
- while ((str = fgetln(stdin, &len)) != NULL) {
- str[len - 1] = '\0';
- ftree_add(strdup(str), NULL);
+ while ((str = pax_getline(stdin)) != NULL) {
+ ftree_add(str, 0);
+ }
+ if (getline_error) {
+ paxwarn(1, "Problem while reading stdin");
+ cpio_usage();
}
break;
default:
* print out those invalid flag sets found to the user
*/
-#ifdef __STDC__
static void
printflg(unsigned int flg)
-#else
-static void
-printflg(flg)
- unsigned int flg;
-#endif
{
int nxt;
int pos = 0;
* by the user
*/
-#ifdef __STDC__
static int
c_frmt(const void *a, const void *b)
-#else
-static int
-c_frmt(a, b)
- void *a;
- void *b;
-#endif
{
- return(strcmp(((FSUB *)a)->name, ((FSUB *)b)->name));
+ return(strcmp(((const FSUB *)a)->name, ((const FSUB *)b)->name));
}
/*
* pointer to next OPLIST entry or NULL (end of list).
*/
-#ifdef __STDC__
OPLIST *
opt_next(void)
-#else
-OPLIST *
-opt_next()
-#endif
{
OPLIST *opt;
* when the format does not support options.
*/
-#ifdef __STDC__
int
bad_opt(void)
-#else
-int
-bad_opt()
-#endif
{
- register OPLIST *opt;
+ OPLIST *opt;
if (ophead == NULL)
return(0);
* print all we were given
*/
paxwarn(1,"These format options are not supported");
- while ((opt = opt_next()) != NULL)
- (void)fprintf(stderr, "\t%s = %s\n", opt->name, opt->value);
+ while ((opt = opt_next()) != NULL) {
+ if (opt->separator == SEP_EQ) {
+ (void)fprintf(stderr, "\t%s = %s\n", opt->name, opt->value);
+ } else if (opt->separator == SEP_COLONEQ ) {
+ (void)fprintf(stderr, "\t%s := %s\n", opt->name, opt->value);
+ } else { /* SEP_NONE */
+ (void)fprintf(stderr, "\t%s\n", opt->name);
+ }
+ }
pax_usage();
return(0);
}
/*
* opt_add()
+ * breaks the value supplied to -o into an option name and value. Options
+ * are given to -o in the form -o name-value,name=value
+ * multiple -o may be specified.
+ * Return:
+ * 0 if format in name=value format, -1 if -o is passed junk.
+ */
+
+int
+opt_add(const char *str)
+{
+ OPLIST *opt;
+ char *frpt;
+ char *pt;
+ char *dstr;
+ char *endpt;
+
+ if ((str == NULL) || (*str == '\0')) {
+ paxwarn(0, "Invalid option name");
+ return(-1);
+ }
+ if ((dstr = strdup(str)) == NULL) {
+ paxwarn(0, "Unable to allocate space for option list");
+ return(-1);
+ }
+ frpt = dstr;
+
+ /*
+ * 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)
+ *endpt = '\0';
+ if ((pt = strchr(frpt, '=')) == NULL) {
+ paxwarn(0, "Invalid options format");
+ free(dstr);
+ return(-1);
+ }
+ if ((opt = (OPLIST *)malloc(sizeof(OPLIST))) == NULL) {
+ paxwarn(0, "Unable to allocate space for option list");
+ free(dstr);
+ return(-1);
+ }
+ *pt++ = '\0';
+ opt->name = frpt;
+ opt->value = pt;
+ opt->separator = SEP_EQ;
+ opt->fow = NULL;
+ if (endpt != NULL)
+ frpt = endpt + 1;
+ else
+ frpt = NULL;
+ if (ophead == NULL) {
+ optail = ophead = opt;
+ continue;
+ }
+ optail->fow = opt;
+ optail = opt;
+ }
+ return(0);
+}
+
+/*
+ * pax_format_opt_add()
* 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.
+ * multiple -o may be specified.
* Return:
* 0 if format in name=value format, -1 if -o is passed junk
*/
-#ifdef __STDC__
int
-opt_add(register char *str)
-#else
-int
-opt_add(str)
- register char *str;
-#endif
+pax_format_opt_add(register char *str)
{
register OPLIST *opt;
register char *frpt;
register char *pt;
register char *endpt;
+ register int separator;
if ((str == NULL) || (*str == '\0')) {
paxwarn(0, "Invalid option name");
paxwarn(0, "Unable to allocate space for option list");
return(-1);
}
- frpt = endpt = str;
+ frpt = str;
/*
* break into name and values pieces and stuff each one into a
while ((frpt != NULL) && (*frpt != '\0')) {
if ((endpt = strchr(frpt, ',')) != NULL)
*endpt = '\0';
- if ((pt = strchr(frpt, '=')) == NULL) {
- paxwarn(0, "Invalid options format");
- free(str);
- return(-1);
+ if ((pt = strstr(frpt, ":=")) != NULL) {
+ *pt++ = '\0';
+ pt++; /* beyond the := */
+ separator = SEP_COLONEQ;
+ } else if ((pt = strchr(frpt, '=')) != NULL) {
+ *pt++ = '\0';
+ separator = SEP_EQ;
+ } else {
+ /* keyword with no value */
+ separator = SEP_NONE;
}
if ((opt = (OPLIST *)malloc(sizeof(OPLIST))) == NULL) {
paxwarn(0, "Unable to allocate space for option list");
free(str);
return(-1);
}
- *pt++ = '\0';
opt->name = frpt;
opt->value = pt;
+ opt->separator = separator;
opt->fow = NULL;
if (endpt != NULL)
frpt = endpt + 1;
* 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
+ * separated by x (also * for backwards compatibility), specifying
* the product of the indicated values.
* Return:
* 0 for an error, a positive value o.w.
*/
-#ifdef __STDC__
static off_t
str_offt(char *val)
-#else
-static off_t
-str_offt(val)
- char *val;
-#endif
{
char *expr;
off_t num, t;
-# ifdef NET2_STAT
+# ifdef LONG_OFF_T
num = strtol(val, &expr, 0);
if ((num == LONG_MAX) || (num <= 0) || (expr == val))
# else
# endif
return(0);
- switch(*expr) {
+ switch (*expr) {
case 'b':
t = num;
num *= 512;
break;
}
- switch(*expr) {
+ switch (*expr) {
case '\0':
break;
case '*':
return(num);
}
+char *
+pax_getline(FILE *f)
+{
+ char *name, *temp;
+ size_t len;
+
+ name = fgetln(f, &len);
+ if (!name) {
+ getline_error = ferror(f) ? GETLINE_FILE_CORRUPT : 0;
+ return(0);
+ }
+ if (name[len-1] != '\n')
+ len++;
+ temp = malloc(len);
+ if (!temp) {
+ getline_error = GETLINE_OUT_OF_MEM;
+ return(0);
+ }
+ memcpy(temp, name, len-1);
+ temp[len-1] = 0;
+ return(temp);
+}
+
/*
* no_op()
* for those option functions where the archive format has nothing to do.
* 0
*/
-#ifdef __STDC__
static int
no_op(void)
-#else
-static int
-no_op()
-#endif
{
return(0);
}
* print the usage summary to the user
*/
-#ifdef __STDC__
void
pax_usage(void)
-#else
-void
-pax_usage()
-#endif
{
- (void)fputs("usage: pax [-cdnv] [-E limit] [-f archive] ", stderr);
- (void)fputs("[-s replstr] ... [-U user] ...", stderr);
- (void)fputs("\n [-G group] ... ", stderr);
- (void)fputs("[-T [from_date][,to_date]] ... ", stderr);
- (void)fputs("[pattern ...]\n", stderr);
- (void)fputs(" pax -r [-cdiknuvDYZ] [-E limit] ", stderr);
- (void)fputs("[-f archive] [-o options] ... \n", stderr);
- (void)fputs(" [-p string] ... [-s replstr] ... ", stderr);
- (void)fputs("[-U user] ... [-G group] ...\n ", stderr);
- (void)fputs("[-T [from_date][,to_date]] ... ", stderr);
- (void)fputs(" [pattern ...]\n", stderr);
- (void)fputs(" pax -w [-dituvHLPX] [-b blocksize] ", stderr);
- (void)fputs("[ [-a] [-f archive] ] [-x format] \n", stderr);
- (void)fputs(" [-B bytes] [-s replstr] ... ", stderr);
- (void)fputs("[-o options] ... [-U user] ...", stderr);
- (void)fputs("\n [-G group] ... ", stderr);
- (void)fputs("[-T [from_date][,to_date][/[c][m]]] ... ", stderr);
- (void)fputs("[file ...]\n", stderr);
- (void)fputs(" pax -r -w [-diklntuvDHLPXYZ] ", stderr);
- (void)fputs("[-p string] ... [-s replstr] ...", stderr);
- (void)fputs("\n [-U user] ... [-G group] ... ", stderr);
- (void)fputs("[-T [from_date][,to_date][/[c][m]]] ... ", stderr);
- (void)fputs("\n [file ...] directory\n", stderr);
+ (void)fputs(
+ "usage: pax [-0cdjnOvz] [-E limit] [-f archive] [-G group] [-s replstr]\n"
+ " [-T range] [-U user] [--insecure] [pattern ...]\n"
+ " pax -r [-0cDdijknOuvYZz] [-E limit] [-f archive] [-G group] [-o options]\n"
+ " [-p string] [-s replstr] [-T range] [-U user] [--insecure] [pattern ...]\n"
+ " pax -w [-0adHijLOPtuvXz] [-B bytes] [-b blocksize] [-f archive]\n"
+ " [-G group] [-o options] [-s replstr] [-T range] [-U user]\n"
+ " [-x format] [--insecure] [file ...]\n"
+ " pax -rw [-0DdHikLlnOPtuvXYZ] [-G group] [-p string] [-s replstr]\n"
+ " [-T range] [-U user] [--insecure] [file ...] directory\n",
+ stderr);
exit(1);
}
* print the usage summary to the user
*/
-#ifdef __STDC__
void
tar_usage(void)
-#else
-void
-tar_usage()
-#endif
{
- (void)fputs("usage: tar -{txru}[cevfbmopswzBHLPXZ014578] [tapefile] ",
- stderr);
- (void)fputs("[blocksize] [replstr] [-C directory] file1 file2...\n",
+ (void)fputs(
+ "usage: tar {crtux}[014578befHhjLmOoPpqsvwXZz]\n"
+ " [blocking-factor | archive | replstr] [-C directory] [-I file]\n"
+ " [file ...]\n"
+ " tar {-crtux} [-014578eHhjLmOoPpqvwXZz] [-b blocking-factor]\n"
+ " [-C directory] [-f archive] [-I file] [-s replstr] [file ...]\n",
stderr);
exit(1);
}
* print the usage summary to the user
*/
-#ifdef __STDC__
void
cpio_usage(void)
-#else
-void
-cpio_usage()
-#endif
{
- (void)fputs("usage: cpio -o [-aABcLvVzZ] [-C bytes] [-H format] [-O archive]\n", stderr);
- (void)fputs(" [-F archive] < name-list [> archive]\n", stderr);
- (void)fputs(" cpio -i [-bBcdfmnrsStuvVzZ6] [-C bytes] [-E file] [-H format]\n", stderr);
- (void)fputs(" [-I archive] [-F archive] [pattern...] [< archive]\n", stderr);
- (void)fputs(" cpio -p [-adlLmuvV] destination-directory < name-list\n", stderr);
+ (void)fputs(
+ "usage: cpio -o [-AaBcjLvZz] [-C bytes] [-F archive] [-H format]\n"
+ " [-O archive] < name-list [> archive]\n"
+ " cpio -i [-6BbcdfjmrSstuvZz] [-C bytes] [-E file] [-F archive] [-H format]\n"
+ " [-I archive] [pattern ...] [< archive]\n"
+ " cpio -p [-adLlmuv] destination-directory < name-list\n",
+ stderr);
exit(1);
}