e9b1c1bac6
git-svn-id: svn://kolibrios.org@6725 a494cfbc-eb01-0410-851d-a64ba20cac60
3477 lines
122 KiB
Plaintext
3477 lines
122 KiB
Plaintext
diff -ru2 unz60e03/unzip.c u6e3_np/unzip.c
|
|
--- unz60e03/unzip.c Wed Mar 19 13:08:38 2008
|
|
+++ u6e3_np/unzip.c Mon Mar 24 14:16:58 2008
|
|
@@ -128,4 +128,6 @@
|
|
"error: command line parameter #%d exceeds internal size limit\n";
|
|
#endif /* !SFX */
|
|
+static ZCONST char Far NoMemArgsList[] =
|
|
+ "error: no memory for arguments list";
|
|
|
|
#if (defined(REENTRANT) && !defined(NO_EXCEPT_SIGNALS))
|
|
@@ -245,5 +247,5 @@
|
|
static ZCONST char Far local3[] = "\
|
|
-Y treat \".nnn\" as \";nnn\" version -2 force ODS2 names\n\
|
|
- --D restore dir (-D: no) timestamps -M pipe through \"more\" pager\n\
|
|
+ -D- restore dir (-D: no) timestamps -M pipe through \"more\" pager\n\
|
|
(Must quote upper-case options, like \"-V\", unless SET PROC/PARSE=EXTEND.)\
|
|
\n\n";
|
|
@@ -251,5 +253,5 @@
|
|
static ZCONST char Far local3[] = "\n\
|
|
-Y treat \".nnn\" as \";nnn\" version -2 force ODS2 names\n\
|
|
- --D restore dir (-D: no) timestamps\n\
|
|
+ -D- restore dir (-D: no) timestamps\n\
|
|
(Must quote upper-case options, like \"-V\", unless SET PROC/PARSE=EXTEND.)\
|
|
\n\n";
|
|
@@ -694,5 +696,5 @@
|
|
char *p;
|
|
#endif
|
|
-#if (defined(DOS_FLX_H68_NLM_OS2_W32) || !defined(SFX))
|
|
+#if ((defined(WIN32) && defined(__RSXNT__)) || !defined(SFX))
|
|
int i;
|
|
#endif
|
|
@@ -1053,4 +1055,45 @@
|
|
* 'forward slashes' for user's convenience (include zipfile name itself)
|
|
*/
|
|
+ {
|
|
+ /* pfnames */
|
|
+
|
|
+ char **names;
|
|
+
|
|
+ for (names = G.pfnames; *names; names++) {
|
|
+#ifdef __human68k__
|
|
+ extern char *_toslash(char *);
|
|
+ _toslash(*names);
|
|
+#else /* !__human68k__ */
|
|
+ char *q = *names;
|
|
+
|
|
+ while (*q != '\0') {
|
|
+ if (*q == '\\')
|
|
+ *q = '/';
|
|
+ INCSTR(q);
|
|
+ }
|
|
+#endif /* ?__human68k__ */
|
|
+ }
|
|
+ }
|
|
+ {
|
|
+ /* G.wildzipfn */
|
|
+
|
|
+#ifdef __human68k__
|
|
+ extern char *_toslash(char *);
|
|
+ _toslash(*G.wildzipfn);
|
|
+#else /* !__human68k__ */
|
|
+ char *q = G.wildzipfn;
|
|
+
|
|
+ while (*q != '\0') {
|
|
+ if (*q == '\\')
|
|
+ *q = '/';
|
|
+ INCSTR(q);
|
|
+ }
|
|
+#endif /* ?__human68k__ */
|
|
+ }
|
|
+#endif /* DOS_FLX_H68_NLM_OS2_W32 */
|
|
+
|
|
+
|
|
+#if 0
|
|
+#ifdef DOS_FLX_H68_NLM_OS2_W32
|
|
#ifdef SFX
|
|
for (G.pfnames = argv, i = argc; i > 0; --i) {
|
|
@@ -1074,11 +1117,18 @@
|
|
}
|
|
#endif /* DOS_FLX_H68_NLM_OS2_W32 */
|
|
+#endif /* 0 */
|
|
|
|
+/*
|
|
#ifndef SFX
|
|
G.wildzipfn = *argv++;
|
|
#endif
|
|
+*/
|
|
|
|
#if (defined(SFX) && !defined(SFX_EXDIR)) /* only check for -x */
|
|
|
|
+# if 0
|
|
+ /* all this should be done in the options call now */
|
|
+
|
|
+
|
|
G.filespecs = argc;
|
|
G.xfilespecs = 0;
|
|
@@ -1104,7 +1154,10 @@
|
|
} else
|
|
G.process_all_files = TRUE; /* for speed */
|
|
+# endif
|
|
|
|
#else /* !SFX || SFX_EXDIR */ /* check for -x or -d */
|
|
|
|
+# if 0
|
|
+
|
|
G.filespecs = argc;
|
|
G.xfilespecs = 0;
|
|
@@ -1118,9 +1171,9 @@
|
|
while (*++pp) {
|
|
Trace((stderr, "pp - argv = %d\n", pp-argv));
|
|
-#ifdef CMS_MVS
|
|
+# ifdef CMS_MVS
|
|
if (!uO.exdir && STRNICMP(*pp, "-d", 2) == 0) {
|
|
-#else
|
|
+# else
|
|
if (!uO.exdir && strncmp(*pp, "-d", 2) == 0) {
|
|
-#endif
|
|
+# endif
|
|
int firstarg = (pp == argv);
|
|
|
|
@@ -1177,4 +1230,5 @@
|
|
} else
|
|
G.process_all_files = TRUE; /* for speed */
|
|
+# endif
|
|
|
|
if (uO.exdir != (char *)NULL && !G.extract_flag) /* -d ignored */
|
|
@@ -1260,4 +1314,269 @@
|
|
|
|
|
|
+/*
|
|
+ -------------------------------------------------------
|
|
+ Command Line Options
|
|
+ -------------------------------------------------------
|
|
+
|
|
+ Valid command line options.
|
|
+
|
|
+ The function get_option() uses this table to check if an
|
|
+ option is valid and if it takes a value (also called an
|
|
+ option parameter). To add an option to unzip just add it
|
|
+ to this table and add a case in the main switch to handle
|
|
+ it. If either shortopt or longopt not used set to "".
|
|
+
|
|
+ The fields:
|
|
+ option_group - UZO for UnZip option, ZIO for ZipInfo option
|
|
+ shortopt - short option name (1 or 2 chars)
|
|
+ longopt - long option name
|
|
+ value_type - see zip.h for constants
|
|
+ negatable - option is negatable with trailing -
|
|
+ ID - unsigned long int returned for option
|
|
+ name - short description of option which is
|
|
+ returned on some errors and when options
|
|
+ are listed with -so option, can be NULL
|
|
+*/
|
|
+
|
|
+/* Most option IDs are set to the shortopt char. For
|
|
+ multichar short options set to arbitrary unused constant. */
|
|
+#define o_so 0x101
|
|
+
|
|
+
|
|
+/* The below is from the old main command line code with a few changes.
|
|
+ Note that UnZip and ZipInfo filter out their own options based on the
|
|
+ option_group value, so the same option letter can be used for both. */
|
|
+
|
|
+static struct option_struct far options[] = {
|
|
+
|
|
+ /* UnZip options */
|
|
+
|
|
+ /* short longopt value_type negatable
|
|
+ ID name */
|
|
+#ifdef RISCOS
|
|
+ {UZO, "/", "", o_REQUIRED_VALUE, o_NEGATABLE,
|
|
+ '/', "override Unzip$Exts"},
|
|
+#endif
|
|
+ {UZO, "a", "", o_NO_VALUE, o_NEGATABLE,
|
|
+ 'a', "text conv (EOL char, ASCII->EBCDIC"},
|
|
+#if (defined(DLL) && defined(API_DOC))
|
|
+ {UZO, "A", "", o_NO_VALUE, o_NEGATABLE,
|
|
+ 'A', "extended help for API"},
|
|
+#endif
|
|
+ {UZO, "b", "", o_NO_VALUE, o_NEGATABLE,
|
|
+ 'b', "binary, no ASCII conversions"},
|
|
+#ifdef UNIXBACKUP
|
|
+ {UZO, "B", "", o_NO_VALUE, o_NEGATABLE,
|
|
+ 'B', "back up existing files"},
|
|
+#endif
|
|
+#ifdef CMS_MVS
|
|
+ {UZO, "B", "", o_NO_VALUE, o_NEGATABLE,
|
|
+ 'b', "CMS/MVS binary"},
|
|
+#endif
|
|
+ {UZO, "c", "", o_NO_VALUE, o_NEGATABLE,
|
|
+ 'c', "output to stdout"},
|
|
+#ifdef CMS_MVS
|
|
+ /* for CMS_MVS map to lower case */
|
|
+ {UZO, "C", "", o_NO_VALUE, o_NEGATABLE,
|
|
+ 'C', "CMS/MVS lower case"},
|
|
+#endif
|
|
+#if (!defined(SFX) || defined(SFX_EXDIR))
|
|
+ {UZO, "d", "", o_REQUIRED_VALUE, o_NEGATABLE,
|
|
+ 'd', "extraction root directory"},
|
|
+#endif
|
|
+#if (!defined(NO_TIMESTAMPS))
|
|
+ {UZO, "D", "", o_NO_VALUE, o_NEGATABLE,
|
|
+ 'D', "don't restore dir (-DD: any) timestamps"},
|
|
+#endif
|
|
+ {UZO, "e", "", o_NO_VALUE, o_NEGATABLE,
|
|
+ 'e', "extract (not used?)"},
|
|
+#ifdef MACOS
|
|
+ {UZO, "E", "", o_NO_VALUE, o_NEGATABLE,
|
|
+ 'E', "display Mac e.f. when restoring"},
|
|
+#endif
|
|
+ {UZO, "f", "", o_NO_VALUE, o_NEGATABLE,
|
|
+ 'f', "freshen (extract only newer files)"},
|
|
+#if (defined(RISCOS) || defined(ACORN_FTYPE_NFS))
|
|
+ {UZO, "F", "", o_NO_VALUE, o_NEGATABLE,
|
|
+ 'F', "Acorn filetype & NFS extension handling"},
|
|
+#endif
|
|
+ {UZO, "h", "", o_NO_VALUE, o_NOT_NEGATABLE,
|
|
+ 'h', "help"},
|
|
+#ifdef MACOS
|
|
+ {UZO, "i", "", o_NO_VALUE, o_NEGATABLE,
|
|
+ 'i', "ignore filenames stored in Mac ef"},
|
|
+#endif
|
|
+ {UZO, "j", "", o_NO_VALUE, o_NEGATABLE,
|
|
+ 'j', "junk directories, extract names only"},
|
|
+#if (defined(ATH_BEO) || defined(MACOS))
|
|
+ {UZO, "J", "", o_NO_VALUE, o_NEGATABLE,
|
|
+ 'J', "Junk AtheOS, BeOS or MacOS file attrs"},
|
|
+#endif
|
|
+#ifdef ATH_BEO_UNX
|
|
+ {UZO, "K", "", o_NO_VALUE, o_NEGATABLE,
|
|
+ 'K', "retain SUID/SGID/Tacky attrs"},
|
|
+#endif
|
|
+#ifndef SFX
|
|
+ {UZO, "l", "", o_NO_VALUE, o_NEGATABLE,
|
|
+ 'l', "listing verbosity"},
|
|
+#endif
|
|
+#ifndef CMS_MVS
|
|
+ {UZO, "L", "", o_NO_VALUE, o_NEGATABLE,
|
|
+ 'L', "convert (some) names to lower"},
|
|
+#endif
|
|
+#ifdef MORE
|
|
+# ifdef CMS_MVS
|
|
+ {UZO, "m", "", o_NO_VALUE, o_NEGATABLE,
|
|
+ 'm', "pipe output through more"},
|
|
+# endif
|
|
+ {UZO, "M", "", o_NO_VALUE, o_NEGATABLE,
|
|
+ 'M', "pipe output through more"},
|
|
+#endif /* MORE */
|
|
+ {UZO, "n", "", o_NO_VALUE, o_NEGATABLE,
|
|
+ 'n', "never overwrite files (no prompting)"},
|
|
+#ifdef AMIGA
|
|
+ {UZO, "N", "", o_NO_VALUE, o_NEGATABLE,
|
|
+ 'N', "restore comments as filenotes"},
|
|
+#endif
|
|
+ {UZO, "o", "", o_NO_VALUE, o_NEGATABLE,
|
|
+ 'o', "overwrite files without prompting"},
|
|
+ {UZO, "p", "", o_NO_VALUE, o_NEGATABLE,
|
|
+ 'p', "pipe extraction to stdout, no messages"},
|
|
+#if CRYPT
|
|
+ {UZO, "P", "", o_REQUIRED_VALUE, o_NEGATABLE,
|
|
+ 'P', "password"},
|
|
+#endif
|
|
+ {UZO, "q", "", o_NO_VALUE, o_NEGATABLE,
|
|
+ 'q', "quiet"},
|
|
+#ifdef QDOS
|
|
+ {UZO, "Q", "", o_NO_VALUE, o_NEGATABLE,
|
|
+ 'Q', "QDOS flags"},
|
|
+#endif
|
|
+#ifdef TANDEM
|
|
+ {UZO, "r", "", o_NO_VALUE, o_NEGATABLE,
|
|
+ 'r', "remove file extensions"},
|
|
+#endif
|
|
+#ifdef DOS_FLX_NLM_OS2_W32
|
|
+ {UZO, "s", "", o_NO_VALUE, o_NEGATABLE,
|
|
+ 's', "spaces to underscores"},
|
|
+#endif
|
|
+#ifdef VMS
|
|
+ {UZO, "S", "", o_NO_VALUE, o_NEGATABLE,
|
|
+ 'S', "VMS extract text as Stream LF"},
|
|
+#endif
|
|
+ {UZO, "t", "", o_NO_VALUE, o_NEGATABLE,
|
|
+ 't', "test"},
|
|
+#ifdef TIMESTAMP
|
|
+ {UZO, "T", "", o_NO_VALUE, o_NEGATABLE,
|
|
+ 'T', "timestamps"},
|
|
+#endif
|
|
+ {UZO, "u", "", o_NO_VALUE, o_NEGATABLE,
|
|
+ 'u', "update (extract only new/newer files)"},
|
|
+#ifdef UNICODE_SUPPORT
|
|
+ {UZO, "U", "", o_NO_VALUE, o_NEGATABLE,
|
|
+ 'U', "escape non-ASCII Unicode, disable Unicode"},
|
|
+#else /* !UNICODE_SUPPORT */
|
|
+# ifndef CMS_MVS
|
|
+ {UZO, "U", "", o_NO_VALUE, o_NEGATABLE,
|
|
+ 'U', "names to lower case"},
|
|
+# endif /* !CMS_MVS */
|
|
+#endif /* ?UNICODE_SUPPORT */
|
|
+#ifndef SFX
|
|
+ {UZO, "v", "", o_NO_VALUE, o_NEGATABLE,
|
|
+ 'v', "verbose"},
|
|
+#endif
|
|
+#ifndef CMS_MVS
|
|
+ {UZO, "V", "", o_NO_VALUE, o_NEGATABLE,
|
|
+ 'V', "don't strip VMS version numbers"},
|
|
+#endif
|
|
+#ifdef WILD_STOP_AT_DIR
|
|
+ {UZO, "W", "", o_NO_VALUE, o_NEGATABLE,
|
|
+ 'W', "wildcard * doesn't span /"},
|
|
+#endif
|
|
+ {UZO, "x", "", o_VALUE_LIST, o_NOT_NEGATABLE,
|
|
+ 'x', "exclude this list of files"},
|
|
+#if (defined(RESTORE_UIDGID) || defined(RESTORE_ACL))
|
|
+ {UZO, "X", "", o_NO_VALUE, o_NEGATABLE,
|
|
+ 'X', "restore owner/prot or UID/GID or ACLs"},
|
|
+#endif
|
|
+#ifdef VMS
|
|
+ {UZO, "Y", "", o_NO_VALUE, o_NEGATABLE,
|
|
+ 'Y', "VMS treat .nnn as ;nnn version"},
|
|
+#endif
|
|
+ {UZO, "z", "", o_NO_VALUE, o_NEGATABLE,
|
|
+ 'z', "display zipfile comment"},
|
|
+#ifndef SFX
|
|
+ {UZO, "Z", "", o_NO_VALUE, o_NOT_NEGATABLE,
|
|
+ 'Z', "ZipInfo mode"},
|
|
+#endif
|
|
+#ifdef VMS
|
|
+ {UZO, "2", "", o_NO_VALUE, o_NEGATABLE,
|
|
+ '2', "Force ODS2-compliant names."},
|
|
+#endif
|
|
+#ifdef DOS_H68_OS2_W32
|
|
+ {UZO, "$", "", o_NO_VALUE, o_NEGATABLE,
|
|
+ '$', "extract volume labels"},
|
|
+#endif
|
|
+#if (!defined(RISCOS) && !defined(CMS_MVS) && !defined(TANDEM))
|
|
+ {UZO, ":", "", o_NO_VALUE, o_NEGATABLE,
|
|
+ ':', "don't skip ../ path elements"},
|
|
+#endif
|
|
+#ifdef UNIX
|
|
+ {UZO, "^", "", o_NO_VALUE, o_NEGATABLE,
|
|
+ '^', "allow control chars in filenames"},
|
|
+#endif
|
|
+
|
|
+#ifndef NO_ZIPINFO
|
|
+ /* ZipInfo options */
|
|
+
|
|
+ /* short longopt value_type negatable
|
|
+ ID name (help text) */
|
|
+ {ZIO, "1", "", o_NO_VALUE, o_NEGATABLE,
|
|
+ '1', "shortest list"},
|
|
+ {ZIO, "2", "", o_NO_VALUE, o_NEGATABLE,
|
|
+ '2', "names and headers"},
|
|
+#ifndef CMS_MVS
|
|
+ {ZIO, "C", "", o_NO_VALUE, o_NEGATABLE,
|
|
+ 'C', "ignore case"},
|
|
+#endif
|
|
+ {ZIO, "h", "", o_NO_VALUE, o_NEGATABLE,
|
|
+ 'h', "header line"},
|
|
+ {ZIO, "l", "", o_NO_VALUE, o_NEGATABLE,
|
|
+ 'l', "longer listing"},
|
|
+ {ZIO, "m", "", o_NO_VALUE, o_NEGATABLE,
|
|
+ 'm', "medium listing"},
|
|
+#ifdef MORE
|
|
+ {ZIO, "M", "", o_NO_VALUE, o_NEGATABLE,
|
|
+ 'M', "output like more"},
|
|
+#endif
|
|
+ {ZIO, "s", "", o_NO_VALUE, o_NEGATABLE,
|
|
+ 's', "shorter list"},
|
|
+ {ZIO, "t", "", o_NO_VALUE, o_NEGATABLE,
|
|
+ 't', "totals line"},
|
|
+ {ZIO, "T", "", o_NO_VALUE, o_NEGATABLE,
|
|
+ 'T', "decimal time format"},
|
|
+#ifdef UNICODE_SUPPORT
|
|
+ {ZIO, "U", "", o_NO_VALUE, o_NEGATABLE,
|
|
+ 'U', "escape non-ASCII Unicode, disable Unicode"},
|
|
+#endif
|
|
+ {ZIO, "v", "", o_NO_VALUE, o_NEGATABLE,
|
|
+ 'v', "turbo-verbose listing"},
|
|
+#ifdef WILD_STOP_AT_DIR
|
|
+ {ZIO, "W", "", o_NO_VALUE, o_NEGATABLE,
|
|
+ 'W', "wild stop at /"},
|
|
+#endif
|
|
+ {ZIO, "x", "", o_VALUE_LIST, o_NOT_NEGATABLE,
|
|
+ 'x', "exclude this list of files"},
|
|
+ {ZIO, "z", "", o_NO_VALUE, o_NEGATABLE,
|
|
+ 'z', "print zipfile comment"},
|
|
+ {ZIO, "Z", "", o_NO_VALUE, o_NEGATABLE,
|
|
+ 'Z', "ZipInfo mode"},
|
|
+#endif /* !NO_ZIPINFO */
|
|
+
|
|
+ /* the end of the list */
|
|
+ {0, NULL, NULL, o_NO_VALUE, o_NOT_NEGATABLE,
|
|
+ 0, NULL} /* end has option_ID = 0 */
|
|
+ };
|
|
+
|
|
|
|
|
|
@@ -1271,502 +1590,649 @@
|
|
char ***pargv;
|
|
{
|
|
- char **argv, *s;
|
|
- int argc, c, error=FALSE, negative=0;
|
|
+ char **args;
|
|
+ int argc, error=FALSE;
|
|
|
|
+ /* used by get_option */
|
|
+ unsigned long option; /* option ID returned by get_option */
|
|
+ int argcnt = 0; /* current argcnt in args */
|
|
+ int argnum = 0; /* arg number */
|
|
+ int optchar = 0; /* option state */
|
|
+ char *value = NULL; /* non-option arg, option value or NULL */
|
|
+ int negative = 0; /* 1 = option negated */
|
|
+ int fna = 0; /* current first non-opt arg */
|
|
+ int optnum = 0; /* index in table */
|
|
|
|
- argc = *pargc;
|
|
- argv = *pargv;
|
|
|
|
- while (++argv, (--argc > 0 && *argv != NULL && **argv == '-')) {
|
|
- s = *argv + 1;
|
|
- while ((c = *s++) != 0) { /* "!= 0": prevent Turbo C warning */
|
|
-#ifdef CMS_MVS
|
|
- switch (tolower(c))
|
|
-#else
|
|
- switch (c)
|
|
-#endif
|
|
- {
|
|
- case ('-'):
|
|
- ++negative;
|
|
- break;
|
|
+ /* since get_option() returns xfiles and files one at a time, store them
|
|
+ in linked lists until have them all */
|
|
+
|
|
+ int file_count = 0;
|
|
+ struct file_list *next_file;
|
|
+
|
|
+ /* files to extract */
|
|
+ int in_files_count = 0;
|
|
+ struct file_list *in_files = NULL;
|
|
+ struct file_list *next_in_files = NULL;
|
|
+
|
|
+ /* files to exclude in -x list */
|
|
+ int in_xfiles_count = 0;
|
|
+ struct file_list *in_xfiles = NULL;
|
|
+ struct file_list *next_in_xfiles = NULL;
|
|
+
|
|
+ G.wildzipfn = NULL;
|
|
+
|
|
+ /* make copy of args that can use with insert_arg() used by get_option() */
|
|
+ args = copy_args(*pargv, 0);
|
|
+
|
|
+
|
|
+ /* Initialize lists */
|
|
+ G.filespecs = 0;
|
|
+ G.xfilespecs = 0;
|
|
+
|
|
+
|
|
+ /*
|
|
+ -------------------------------------------
|
|
+ Process command line using get_option
|
|
+ -------------------------------------------
|
|
+
|
|
+ Each call to get_option() returns either a command
|
|
+ line option and possible value or a non-option argument.
|
|
+ Arguments are permuted so that all options (-r, -b temp)
|
|
+ are returned before non-option arguments (zipfile).
|
|
+ Returns 0 when nothing left to read.
|
|
+ */
|
|
+
|
|
+ /* set argnum = 0 on first call to init get_option */
|
|
+ argnum = 0;
|
|
+
|
|
+ /* get_option returns the option ID and updates parameters:
|
|
+ args - usually same as argv if no argument file support
|
|
+ argcnt - current argc for args
|
|
+ value - char* to value (free() when done with it) or NULL if none
|
|
+ negated - option was negated with trailing -
|
|
+ */
|
|
+
|
|
+ while ((option = get_option(UZO, &args, &argcnt, &argnum,
|
|
+ &optchar, &value, &negative,
|
|
+ &fna, &optnum, 0)))
|
|
+ {
|
|
+ if(option == o_BAD_ERR) {
|
|
+ return(PK_PARAM);
|
|
+ }
|
|
+
|
|
+ switch (option)
|
|
+ {
|
|
#ifdef RISCOS
|
|
- case ('/'):
|
|
- if (negative) { /* negative not allowed with -/ swap */
|
|
- Info(slide, 0x401, ((char *)slide,
|
|
- "error: must give extensions list"));
|
|
- return(PK_PARAM); /* don't extract here by accident */
|
|
- }
|
|
- exts2swap = s; /* override Unzip$Exts */
|
|
- s += strlen(s);
|
|
- break;
|
|
-#endif
|
|
- case ('a'):
|
|
- if (negative) {
|
|
- uO.aflag = MAX(uO.aflag-negative,0);
|
|
- negative = 0;
|
|
- } else
|
|
- ++uO.aflag;
|
|
- break;
|
|
+ case ('/'):
|
|
+ if (negative) { /* negative not allowed with -/ swap */
|
|
+ Info(slide, 0x401, ((char *)slide,
|
|
+ "error: must give extensions list"));
|
|
+ return(PK_PARAM); /* don't extract here by accident */
|
|
+ }
|
|
+ exts2swap = value; /* override Unzip$Exts */
|
|
+ break;
|
|
+#endif
|
|
+ case ('a'):
|
|
+ if (negative) {
|
|
+ uO.aflag = MAX(uO.aflag-negative,0);
|
|
+ negative = 0;
|
|
+ } else
|
|
+ ++uO.aflag;
|
|
+ break;
|
|
#if (defined(DLL) && defined(API_DOC))
|
|
- case ('A'): /* extended help for API */
|
|
- APIhelp(__G__ argc, argv);
|
|
- *pargc = -1; /* signal to exit successfully */
|
|
- return 0;
|
|
+ case ('A'): /* extended help for API */
|
|
+ APIhelp(__G__ argc, args);
|
|
+ *pargc = -1; /* signal to exit successfully */
|
|
+ return 0;
|
|
#endif
|
|
- case ('b'):
|
|
- if (negative) {
|
|
+ case ('b'):
|
|
+ if (negative) {
|
|
#if (defined(TANDEM) || defined(VMS))
|
|
- uO.bflag = MAX(uO.bflag-negative,0);
|
|
+ uO.bflag = MAX(uO.bflag-negative,0);
|
|
#endif
|
|
- negative = 0; /* do nothing: "-b" is default */
|
|
- } else {
|
|
+ negative = 0; /* do nothing: "-b" is default */
|
|
+ } else {
|
|
#ifdef VMS
|
|
- if (uO.aflag == 0)
|
|
- ++uO.bflag;
|
|
+ if (uO.aflag == 0)
|
|
+ ++uO.bflag;
|
|
#endif
|
|
#ifdef TANDEM
|
|
- ++uO.bflag;
|
|
+ ++uO.bflag;
|
|
#endif
|
|
- uO.aflag = 0;
|
|
- }
|
|
- break;
|
|
+ uO.aflag = 0;
|
|
+ }
|
|
+ break;
|
|
#ifdef UNIXBACKUP
|
|
- case ('B'): /* -B: back up existing files */
|
|
- if (negative)
|
|
- uO.B_flag = FALSE, negative = 0;
|
|
- else
|
|
- uO.B_flag = TRUE;
|
|
- break;
|
|
-#endif
|
|
- case ('c'):
|
|
- if (negative) {
|
|
- uO.cflag = FALSE, negative = 0;
|
|
+ case ('B'): /* -B: back up existing files */
|
|
+ if (negative)
|
|
+ uO.B_flag = FALSE, negative = 0;
|
|
+ else
|
|
+ uO.B_flag = TRUE;
|
|
+ break;
|
|
+#endif
|
|
+ case ('c'):
|
|
+ if (negative) {
|
|
+ uO.cflag = FALSE, negative = 0;
|
|
#ifdef NATIVE
|
|
- uO.aflag = 0;
|
|
+ uO.aflag = 0;
|
|
#endif
|
|
- } else {
|
|
- uO.cflag = TRUE;
|
|
+ } else {
|
|
+ uO.cflag = TRUE;
|
|
#ifdef NATIVE
|
|
- uO.aflag = 2; /* so you can read it on the screen */
|
|
+ uO.aflag = 2; /* so you can read it on the screen */
|
|
#endif
|
|
#ifdef DLL
|
|
- if (G.redirect_text)
|
|
- G.redirect_data = 2;
|
|
+ if (G.redirect_text)
|
|
+ G.redirect_data = 2;
|
|
#endif
|
|
- }
|
|
- break;
|
|
+ }
|
|
+ break;
|
|
#ifndef CMS_MVS
|
|
- case ('C'): /* -C: match filenames case-insensitively */
|
|
- if (negative)
|
|
- uO.C_flag = FALSE, negative = 0;
|
|
- else
|
|
- uO.C_flag = TRUE;
|
|
- break;
|
|
+ case ('C'): /* -C: match filenames case-insensitively */
|
|
+ if (negative)
|
|
+ uO.C_flag = FALSE, negative = 0;
|
|
+ else
|
|
+ uO.C_flag = TRUE;
|
|
+ break;
|
|
#endif /* !CMS_MVS */
|
|
#if (!defined(SFX) || defined(SFX_EXDIR))
|
|
- case ('d'):
|
|
- if (negative) { /* negative not allowed with -d exdir */
|
|
+ case ('d'):
|
|
+ if (negative) { /* negative not allowed with -d exdir */
|
|
+ Info(slide, 0x401, ((char *)slide,
|
|
+ LoadFarString(MustGiveExdir)));
|
|
+ return(PK_PARAM); /* don't extract here by accident */
|
|
+ }
|
|
+ if (uO.exdir != (char *)NULL) {
|
|
+ Info(slide, 0x401, ((char *)slide,
|
|
+ LoadFarString(OnlyOneExdir)));
|
|
+ return(PK_PARAM); /* GRR: stupid restriction? */
|
|
+ } else {
|
|
+ /* first check for "-dexdir", then for "-d exdir" */
|
|
+ uO.exdir = value;
|
|
+ if (uO.exdir == NULL || *uO.exdir == '\0') {
|
|
Info(slide, 0x401, ((char *)slide,
|
|
LoadFarString(MustGiveExdir)));
|
|
- return(PK_PARAM); /* don't extract here by accident */
|
|
- }
|
|
- if (uO.exdir != (char *)NULL) {
|
|
- Info(slide, 0x401, ((char *)slide,
|
|
- LoadFarString(OnlyOneExdir)));
|
|
- return(PK_PARAM); /* GRR: stupid restriction? */
|
|
- } else {
|
|
- /* first check for "-dexdir", then for "-d exdir" */
|
|
- uO.exdir = s;
|
|
- if (*uO.exdir == '\0') {
|
|
- if (argc > 1) {
|
|
- --argc;
|
|
- uO.exdir = *++argv;
|
|
- if (*uO.exdir == '-') {
|
|
- Info(slide, 0x401, ((char *)slide,
|
|
- LoadFarString(MustGiveExdir)));
|
|
- return(PK_PARAM);
|
|
- }
|
|
- /* else uO.exdir points at extraction dir */
|
|
- } else {
|
|
- Info(slide, 0x401, ((char *)slide,
|
|
- LoadFarString(MustGiveExdir)));
|
|
- return(PK_PARAM);
|
|
- }
|
|
- }
|
|
- /* uO.exdir now points at extraction dir (-dexdir or
|
|
- * -d exdir); point s at end of exdir to avoid mis-
|
|
- * interpretation of exdir characters as more options
|
|
- */
|
|
- if (*s != 0)
|
|
- while (*++s != 0)
|
|
- ;
|
|
+ return(PK_PARAM);
|
|
}
|
|
- break;
|
|
+ /* else uO.exdir points at extraction dir */
|
|
+ }
|
|
+ break;
|
|
#endif /* !SFX || SFX_EXDIR */
|
|
#if (!defined(NO_TIMESTAMPS))
|
|
- case ('D'): /* -D: Skip restoring dir (or any) timestamp. */
|
|
- if (negative) {
|
|
- uO.D_flag = MAX(uO.D_flag-negative,0);
|
|
- negative = 0;
|
|
- } else
|
|
- uO.D_flag++;
|
|
- break;
|
|
+ case ('D'): /* -D: Skip restoring dir (or any) timestamp. */
|
|
+ if (negative) {
|
|
+ uO.D_flag = MAX(uO.D_flag-negative,0);
|
|
+ negative = 0;
|
|
+ } else
|
|
+ uO.D_flag++;
|
|
+ break;
|
|
#endif /* (!NO_TIMESTAMPS) */
|
|
- case ('e'): /* just ignore -e, -x options (extract) */
|
|
- break;
|
|
+ case ('e'): /* just ignore -e, -x options (extract) */
|
|
+ break;
|
|
#ifdef MACOS
|
|
- case ('E'): /* -E [MacOS] display Mac e.f. when restoring */
|
|
- if( negative ) {
|
|
- uO.E_flag = FALSE, negative = 0;
|
|
- } else {
|
|
- uO.E_flag = TRUE;
|
|
- }
|
|
- break;
|
|
+ case ('E'): /* -E [MacOS] display Mac e.f. when restoring */
|
|
+ if( negative ) {
|
|
+ uO.E_flag = FALSE, negative = 0;
|
|
+ } else {
|
|
+ uO.E_flag = TRUE;
|
|
+ }
|
|
+ break;
|
|
#endif /* MACOS */
|
|
- case ('f'): /* "freshen" (extract only newer files) */
|
|
- if (negative)
|
|
- uO.fflag = uO.uflag = FALSE, negative = 0;
|
|
- else
|
|
- uO.fflag = uO.uflag = TRUE;
|
|
- break;
|
|
+ case ('f'): /* "freshen" (extract only newer files) */
|
|
+ if (negative)
|
|
+ uO.fflag = uO.uflag = FALSE, negative = 0;
|
|
+ else
|
|
+ uO.fflag = uO.uflag = TRUE;
|
|
+ break;
|
|
#if (defined(RISCOS) || defined(ACORN_FTYPE_NFS))
|
|
- case ('F'): /* Acorn filetype & NFS extension handling */
|
|
- if (negative)
|
|
- uO.acorn_nfs_ext = FALSE, negative = 0;
|
|
- else
|
|
- uO.acorn_nfs_ext = TRUE;
|
|
- break;
|
|
+ case ('F'): /* Acorn filetype & NFS extension handling */
|
|
+ if (negative)
|
|
+ uO.acorn_nfs_ext = FALSE, negative = 0;
|
|
+ else
|
|
+ uO.acorn_nfs_ext = TRUE;
|
|
+ break;
|
|
#endif /* RISCOS || ACORN_FTYPE_NFS */
|
|
- case ('h'): /* just print help message and quit */
|
|
- *pargc = -1;
|
|
- return USAGE(PK_OK);
|
|
+ case ('h'): /* just print help message and quit */
|
|
+ *pargc = -1;
|
|
+ return USAGE(PK_OK);
|
|
#ifdef MACOS
|
|
- case ('i'): /* -i [MacOS] ignore filenames stored in Mac ef */
|
|
- if( negative ) {
|
|
- uO.i_flag = FALSE, negative = 0;
|
|
- } else {
|
|
- uO.i_flag = TRUE;
|
|
- }
|
|
- break;
|
|
+ case ('i'): /* -i [MacOS] ignore filenames stored in Mac ef */
|
|
+ if( negative ) {
|
|
+ uO.i_flag = FALSE, negative = 0;
|
|
+ } else {
|
|
+ uO.i_flag = TRUE;
|
|
+ }
|
|
+ break;
|
|
#endif /* MACOS */
|
|
- case ('j'): /* junk pathnames/directory structure */
|
|
- if (negative)
|
|
- uO.jflag = FALSE, negative = 0;
|
|
- else
|
|
- uO.jflag = TRUE;
|
|
- break;
|
|
+ case ('j'): /* junk pathnames/directory structure */
|
|
+ if (negative)
|
|
+ uO.jflag = FALSE, negative = 0;
|
|
+ else
|
|
+ uO.jflag = TRUE;
|
|
+ break;
|
|
#if (defined(ATH_BEO) || defined(MACOS))
|
|
- case ('J'): /* Junk AtheOS, BeOS or MacOS file attributes */
|
|
- if( negative ) {
|
|
- uO.J_flag = FALSE, negative = 0;
|
|
- } else {
|
|
- uO.J_flag = TRUE;
|
|
- }
|
|
- break;
|
|
+ case ('J'): /* Junk AtheOS, BeOS or MacOS file attributes */
|
|
+ if( negative ) {
|
|
+ uO.J_flag = FALSE, negative = 0;
|
|
+ } else {
|
|
+ uO.J_flag = TRUE;
|
|
+ }
|
|
+ break;
|
|
#endif /* ATH_BEO || MACOS */
|
|
#ifdef ATH_BEO_UNX
|
|
- case ('K'):
|
|
- if (negative) {
|
|
- uO.K_flag = FALSE, negative = 0;
|
|
- } else {
|
|
- uO.K_flag = TRUE;
|
|
- }
|
|
- break;
|
|
+ case ('K'):
|
|
+ if (negative) {
|
|
+ uO.K_flag = FALSE, negative = 0;
|
|
+ } else {
|
|
+ uO.K_flag = TRUE;
|
|
+ }
|
|
+ break;
|
|
#endif /* ATH_BEO_UNX */
|
|
#ifndef SFX
|
|
- case ('l'):
|
|
- if (negative) {
|
|
- uO.vflag = MAX(uO.vflag-negative,0);
|
|
- negative = 0;
|
|
- } else
|
|
- ++uO.vflag;
|
|
- break;
|
|
+ case ('l'):
|
|
+ if (negative) {
|
|
+ uO.vflag = MAX(uO.vflag-negative,0);
|
|
+ negative = 0;
|
|
+ } else
|
|
+ ++uO.vflag;
|
|
+ break;
|
|
#endif /* !SFX */
|
|
#ifndef CMS_MVS
|
|
- case ('L'): /* convert (some) filenames to lowercase */
|
|
- if (negative) {
|
|
- uO.L_flag = MAX(uO.L_flag-negative,0);
|
|
- negative = 0;
|
|
- } else
|
|
- ++uO.L_flag;
|
|
- break;
|
|
+ case ('L'): /* convert (some) filenames to lowercase */
|
|
+ if (negative) {
|
|
+ uO.L_flag = MAX(uO.L_flag-negative,0);
|
|
+ negative = 0;
|
|
+ } else
|
|
+ ++uO.L_flag;
|
|
+ break;
|
|
#endif /* !CMS_MVS */
|
|
#ifdef MORE
|
|
#ifdef CMS_MVS
|
|
- case ('m'):
|
|
+ case ('m'):
|
|
#endif
|
|
- case ('M'): /* send all screen output through "more" fn. */
|
|
+ case ('M'): /* send all screen output through "more" fn. */
|
|
/* GRR: eventually check for numerical argument => height */
|
|
- if (negative)
|
|
- G.M_flag = FALSE, negative = 0;
|
|
- else
|
|
- G.M_flag = TRUE;
|
|
- break;
|
|
+ if (negative)
|
|
+ G.M_flag = FALSE, negative = 0;
|
|
+ else
|
|
+ G.M_flag = TRUE;
|
|
+ break;
|
|
#endif /* MORE */
|
|
- case ('n'): /* don't overwrite any files */
|
|
- if (negative)
|
|
- uO.overwrite_none = FALSE, negative = 0;
|
|
- else
|
|
- uO.overwrite_none = TRUE;
|
|
- break;
|
|
+ case ('n'): /* don't overwrite any files */
|
|
+ if (negative)
|
|
+ uO.overwrite_none = FALSE, negative = 0;
|
|
+ else
|
|
+ uO.overwrite_none = TRUE;
|
|
+ break;
|
|
#ifdef AMIGA
|
|
- case ('N'): /* restore comments as filenotes */
|
|
- if (negative)
|
|
- uO.N_flag = FALSE, negative = 0;
|
|
- else
|
|
- uO.N_flag = TRUE;
|
|
- break;
|
|
+ case ('N'): /* restore comments as filenotes */
|
|
+ if (negative)
|
|
+ uO.N_flag = FALSE, negative = 0;
|
|
+ else
|
|
+ uO.N_flag = TRUE;
|
|
+ break;
|
|
#endif /* AMIGA */
|
|
- case ('o'): /* OK to overwrite files without prompting */
|
|
- if (negative) {
|
|
- uO.overwrite_all = MAX(uO.overwrite_all-negative,0);
|
|
- negative = 0;
|
|
- } else
|
|
- ++uO.overwrite_all;
|
|
- break;
|
|
- case ('p'): /* pipes: extract to stdout, no messages */
|
|
- if (negative) {
|
|
- uO.cflag = FALSE;
|
|
- uO.qflag = MAX(uO.qflag-999,0);
|
|
- negative = 0;
|
|
- } else {
|
|
- uO.cflag = TRUE;
|
|
- uO.qflag += 999;
|
|
- }
|
|
- break;
|
|
+ case ('o'): /* OK to overwrite files without prompting */
|
|
+ if (negative) {
|
|
+ uO.overwrite_all = MAX(uO.overwrite_all-negative,0);
|
|
+ negative = 0;
|
|
+ } else
|
|
+ ++uO.overwrite_all;
|
|
+ break;
|
|
+ case ('p'): /* pipes: extract to stdout, no messages */
|
|
+ if (negative) {
|
|
+ uO.cflag = FALSE;
|
|
+ uO.qflag = MAX(uO.qflag-999,0);
|
|
+ negative = 0;
|
|
+ } else {
|
|
+ uO.cflag = TRUE;
|
|
+ uO.qflag += 999;
|
|
+ }
|
|
+ break;
|
|
#if CRYPT
|
|
- /* GRR: yes, this is highly insecure, but dozens of people
|
|
- * have pestered us for this, so here we go... */
|
|
- case ('P'):
|
|
- if (negative) { /* negative not allowed with -P passwd */
|
|
- Info(slide, 0x401, ((char *)slide,
|
|
- LoadFarString(MustGivePasswd)));
|
|
- return(PK_PARAM); /* don't extract here by accident */
|
|
- }
|
|
- if (uO.pwdarg != (char *)NULL) {
|
|
+ /* GRR: yes, this is highly insecure, but dozens of people
|
|
+ * have pestered us for this, so here we go... */
|
|
+ case ('P'):
|
|
+ if (negative) { /* negative not allowed with -P passwd */
|
|
+ Info(slide, 0x401, ((char *)slide,
|
|
+ LoadFarString(MustGivePasswd)));
|
|
+ return(PK_PARAM); /* don't extract here by accident */
|
|
+ }
|
|
+ if (uO.pwdarg != (char *)NULL) {
|
|
/*
|
|
- GRR: eventually support multiple passwords?
|
|
+ GRR: eventually support multiple passwords?
|
|
+ Info(slide, 0x401, ((char *)slide,
|
|
+ LoadFarString(OnlyOnePasswd)));
|
|
+ return(PK_PARAM);
|
|
+*/
|
|
+ } else {
|
|
+ /* first check for "-Ppasswd", then for "-P passwd" */
|
|
+ uO.pwdarg = value;
|
|
+ if (uO.pwdarg == NULL || *uO.pwdarg == '\0') {
|
|
Info(slide, 0x401, ((char *)slide,
|
|
- LoadFarString(OnlyOnePasswd)));
|
|
+ LoadFarString(MustGivePasswd)));
|
|
return(PK_PARAM);
|
|
- */
|
|
- } else {
|
|
- /* first check for "-Ppasswd", then for "-P passwd" */
|
|
- uO.pwdarg = s;
|
|
- if (*uO.pwdarg == '\0') {
|
|
- if (argc > 1) {
|
|
- --argc;
|
|
- uO.pwdarg = *++argv;
|
|
- if (*uO.pwdarg == '-') {
|
|
- Info(slide, 0x401, ((char *)slide,
|
|
- LoadFarString(MustGivePasswd)));
|
|
- return(PK_PARAM);
|
|
- }
|
|
- /* else pwdarg points at decryption password */
|
|
- } else {
|
|
- Info(slide, 0x401, ((char *)slide,
|
|
- LoadFarString(MustGivePasswd)));
|
|
- return(PK_PARAM);
|
|
- }
|
|
- }
|
|
- /* pwdarg now points at decryption password (-Ppasswd or
|
|
- * -P passwd); point s at end of passwd to avoid mis-
|
|
- * interpretation of passwd characters as more options
|
|
- */
|
|
- if (*s != 0)
|
|
- while (*++s != 0)
|
|
- ;
|
|
+ /* else pwdarg points at decryption password */
|
|
}
|
|
- break;
|
|
+ }
|
|
+ break;
|
|
#endif /* CRYPT */
|
|
- case ('q'): /* quiet: fewer comments/messages */
|
|
- if (negative) {
|
|
- uO.qflag = MAX(uO.qflag-negative,0);
|
|
- negative = 0;
|
|
- } else
|
|
- ++uO.qflag;
|
|
- break;
|
|
+ case ('q'): /* quiet: fewer comments/messages */
|
|
+ if (negative) {
|
|
+ uO.qflag = MAX(uO.qflag-negative,0);
|
|
+ negative = 0;
|
|
+ } else
|
|
+ ++uO.qflag;
|
|
+ break;
|
|
#ifdef QDOS
|
|
- case ('Q'): /* QDOS flags */
|
|
- qlflag ^= strtol(s, &s, 10);
|
|
- break; /* we XOR this as we can config qlflags */
|
|
+ case ('Q'): /* QDOS flags */
|
|
+ qlflag ^= strtol(value, &value, 10);
|
|
+ break; /* we XOR this as we can config qlflags */
|
|
#endif
|
|
#ifdef TANDEM
|
|
- case ('r'): /* remove file extensions */
|
|
- if (negative)
|
|
- uO.rflag = FALSE, negative = 0;
|
|
- else
|
|
- uO.rflag = TRUE;
|
|
- break;
|
|
+ case ('r'): /* remove file extensions */
|
|
+ if (negative)
|
|
+ uO.rflag = FALSE, negative = 0;
|
|
+ else
|
|
+ uO.rflag = TRUE;
|
|
+ break;
|
|
#endif /* TANDEM */
|
|
#ifdef DOS_FLX_NLM_OS2_W32
|
|
- case ('s'): /* spaces in filenames: allow by default */
|
|
- if (negative)
|
|
- uO.sflag = FALSE, negative = 0;
|
|
- else
|
|
- uO.sflag = TRUE;
|
|
- break;
|
|
+ case ('s'): /* spaces in filenames: allow by default */
|
|
+ if (negative)
|
|
+ uO.sflag = FALSE, negative = 0;
|
|
+ else
|
|
+ uO.sflag = TRUE;
|
|
+ break;
|
|
#endif /* DOS_FLX_NLM_OS2_W32 */
|
|
#ifdef VMS
|
|
- /* VMS: extract "text" files in Stream_LF format (-a[a]) */
|
|
- case ('S'):
|
|
- if (negative)
|
|
- uO.S_flag = FALSE, negative = 0;
|
|
- else
|
|
- uO.S_flag = TRUE;
|
|
- break;
|
|
+ /* VMS: extract "text" files in Stream_LF format (-a[a]) */
|
|
+ case ('S'):
|
|
+ if (negative)
|
|
+ uO.S_flag = FALSE, negative = 0;
|
|
+ else
|
|
+ uO.S_flag = TRUE;
|
|
+ break;
|
|
#endif /* VMS */
|
|
- case ('t'):
|
|
- if (negative)
|
|
- uO.tflag = FALSE, negative = 0;
|
|
- else
|
|
- uO.tflag = TRUE;
|
|
- break;
|
|
+ case ('t'):
|
|
+ if (negative)
|
|
+ uO.tflag = FALSE, negative = 0;
|
|
+ else
|
|
+ uO.tflag = TRUE;
|
|
+ break;
|
|
#ifdef TIMESTAMP
|
|
- case ('T'):
|
|
- if (negative)
|
|
- uO.T_flag = FALSE, negative = 0;
|
|
- else
|
|
- uO.T_flag = TRUE;
|
|
- break;
|
|
-#endif
|
|
- case ('u'): /* update (extract only new and newer files) */
|
|
- if (negative)
|
|
- uO.uflag = FALSE, negative = 0;
|
|
- else
|
|
- uO.uflag = TRUE;
|
|
- break;
|
|
+ case ('T'):
|
|
+ if (negative)
|
|
+ uO.T_flag = FALSE, negative = 0;
|
|
+ else
|
|
+ uO.T_flag = TRUE;
|
|
+ break;
|
|
+#endif
|
|
+ case ('u'): /* update (extract only new and newer files) */
|
|
+ if (negative)
|
|
+ uO.uflag = FALSE, negative = 0;
|
|
+ else
|
|
+ uO.uflag = TRUE;
|
|
+ break;
|
|
#ifdef UNICODE_SUPPORT
|
|
- case ('U'): /* escape UTF-8, or disable UTF-8 support */
|
|
- if (negative) {
|
|
- uO.U_flag = MAX(uO.U_flag-negative,0);
|
|
- negative = 0;
|
|
- } else
|
|
- uO.U_flag++;
|
|
- break;
|
|
+ case ('U'): /* escape UTF-8, or disable UTF-8 support */
|
|
+ if (negative)
|
|
+ uO.U_flag = MAX(uO.U_flag - 1, 0);
|
|
+ else
|
|
+ uO.U_flag++;
|
|
+ break;
|
|
#else /* !UNICODE_SUPPORT */
|
|
#ifndef CMS_MVS
|
|
- case ('U'): /* obsolete; to be removed in version 6.0 */
|
|
- if (negative)
|
|
- uO.L_flag = TRUE, negative = 0;
|
|
- else
|
|
- uO.L_flag = FALSE;
|
|
- break;
|
|
+ case ('U'): /* obsolete; to be removed in version 6.0 */
|
|
+ if (negative)
|
|
+ uO.L_flag = TRUE, negative = 0;
|
|
+ else
|
|
+ uO.L_flag = FALSE;
|
|
+ break;
|
|
#endif /* !CMS_MVS */
|
|
#endif /* ?UNICODE_SUPPORT */
|
|
#ifndef SFX
|
|
- case ('v'): /* verbose */
|
|
- if (negative) {
|
|
- uO.vflag = MAX(uO.vflag-negative,0);
|
|
- negative = 0;
|
|
- } else if (uO.vflag)
|
|
- ++uO.vflag;
|
|
- else
|
|
- uO.vflag = 2;
|
|
- break;
|
|
+ case ('v'): /* verbose */
|
|
+ if (negative) {
|
|
+ uO.vflag = MAX(uO.vflag-negative,0);
|
|
+ negative = 0;
|
|
+ } else if (uO.vflag)
|
|
+ ++uO.vflag;
|
|
+ else
|
|
+ uO.vflag = 2;
|
|
+ break;
|
|
#endif /* !SFX */
|
|
#ifndef CMS_MVS
|
|
- case ('V'): /* Version (retain VMS/DEC-20 file versions) */
|
|
- if (negative)
|
|
- uO.V_flag = FALSE, negative = 0;
|
|
- else
|
|
- uO.V_flag = TRUE;
|
|
- break;
|
|
+ case ('V'): /* Version (retain VMS/DEC-20 file versions) */
|
|
+ if (negative)
|
|
+ uO.V_flag = FALSE, negative = 0;
|
|
+ else
|
|
+ uO.V_flag = TRUE;
|
|
+ break;
|
|
#endif /* !CMS_MVS */
|
|
#ifdef WILD_STOP_AT_DIR
|
|
- case ('W'): /* Wildcard interpretation (stop at '/'?) */
|
|
- if (negative)
|
|
- uO.W_flag = FALSE, negative = 0;
|
|
- else
|
|
- uO.W_flag = TRUE;
|
|
- break;
|
|
+ case ('W'): /* Wildcard interpretation (stop at '/'?) */
|
|
+ if (negative)
|
|
+ uO.W_flag = FALSE, negative = 0;
|
|
+ else
|
|
+ uO.W_flag = TRUE;
|
|
+ break;
|
|
#endif /* WILD_STOP_AT_DIR */
|
|
- case ('x'): /* extract: default */
|
|
-#ifdef SFX
|
|
- /* when 'x' is the only option in this argument, and the
|
|
- * next arg is not an option, assume this initiates an
|
|
- * exclusion list (-x xlist): terminate option-scanning
|
|
- * and leave uz_opts with argv still pointing to "-x";
|
|
- * the xlist is processed later
|
|
- */
|
|
- if (s - argv[0] == 2 && *s == '\0' &&
|
|
- argc > 1 && argv[1][0] != '-') {
|
|
- /* break out of nested loops without "++argv;--argc" */
|
|
- goto opts_done;
|
|
+ case ('x'): /* extract: default */
|
|
+ /* add -x file to linked list */
|
|
+
|
|
+ if (in_xfiles_count == 0) {
|
|
+ /* first entry */
|
|
+ if ((in_xfiles = (struct file_list *)
|
|
+ malloc(sizeof(struct file_list))
|
|
+ ) == NULL) {
|
|
+ Info(slide, 0x401, ((char *)slide,
|
|
+ LoadFarString(NoMemArgsList)));
|
|
+ return PK_MEM;
|
|
+ }
|
|
+ in_xfiles->name = value;
|
|
+ in_xfiles->next = NULL;
|
|
+ next_in_xfiles = in_xfiles;
|
|
+ } else {
|
|
+ /* add next entry */
|
|
+ if ((next_file = (struct file_list *)
|
|
+ malloc(sizeof(struct file_list))
|
|
+ ) == NULL) {
|
|
+ Info(slide, 0x401, ((char *)slide,
|
|
+ LoadFarString(NoMemArgsList)));
|
|
+ return PK_MEM;
|
|
}
|
|
+ next_in_xfiles->next = next_file;
|
|
+ next_file->name = value;
|
|
+ next_file->next = NULL;
|
|
+ next_in_xfiles = next_file;
|
|
+ }
|
|
+ in_xfiles_count++;
|
|
+
|
|
+#if 0
|
|
+#ifdef SFX
|
|
+ /* now get -x list one entry at a time */
|
|
+
|
|
+
|
|
+
|
|
+ /* when 'x' is the only option in this argument, and the
|
|
+ * next arg is not an option, assume this initiates an
|
|
+ * exclusion list (-x xlist): terminate option-scanning
|
|
+ * and leave uz_opts with argv still pointing to "-x";
|
|
+ * the xlist is processed later
|
|
+ */
|
|
+ if (s - argv[0] == 2 && *s == '\0' &&
|
|
+ argc > 1 && argv[1][0] != '-') {
|
|
+ /* break out of nested loops without "++argv;--argc" */
|
|
+ goto opts_done;
|
|
+ }
|
|
#endif /* SFX */
|
|
- break;
|
|
+#endif
|
|
+ break;
|
|
#if (defined(RESTORE_UIDGID) || defined(RESTORE_ACL))
|
|
- case ('X'): /* restore owner/protection info (need privs?) */
|
|
- if (negative) {
|
|
- uO.X_flag = MAX(uO.X_flag-negative,0);
|
|
- negative = 0;
|
|
- } else
|
|
- ++uO.X_flag;
|
|
- break;
|
|
+ case ('X'): /* restore owner/protection info (need privs?) */
|
|
+ if (negative) {
|
|
+ uO.X_flag = MAX(uO.X_flag-negative,0);
|
|
+ negative = 0;
|
|
+ } else
|
|
+ ++uO.X_flag;
|
|
+ break;
|
|
#endif /* RESTORE_UIDGID || RESTORE_ACL */
|
|
#ifdef VMS
|
|
- case ('Y'): /* Treat ".nnn" as ";nnn" version. */
|
|
- if (negative)
|
|
- uO.Y_flag = FALSE, negative = 0;
|
|
- else
|
|
- uO.Y_flag = TRUE;
|
|
- break;
|
|
+ case ('Y'): /* Treat ".nnn" as ";nnn" version. */
|
|
+ if (negative)
|
|
+ uO.Y_flag = FALSE, negative = 0;
|
|
+ else
|
|
+ uO.Y_flag = TRUE;
|
|
+ break;
|
|
#endif /* VMS */
|
|
- case ('z'): /* display only the archive comment */
|
|
- if (negative) {
|
|
- uO.zflag = MAX(uO.zflag-negative,0);
|
|
- negative = 0;
|
|
- } else
|
|
- ++uO.zflag;
|
|
- break;
|
|
+ case ('z'): /* display only the archive comment */
|
|
+ if (negative) {
|
|
+ uO.zflag = MAX(uO.zflag-negative,0);
|
|
+ negative = 0;
|
|
+ } else
|
|
+ ++uO.zflag;
|
|
+ break;
|
|
#ifndef SFX
|
|
- case ('Z'): /* should have been first option (ZipInfo) */
|
|
- Info(slide, 0x401, ((char *)slide, LoadFarString(Zfirst)));
|
|
- error = TRUE;
|
|
- break;
|
|
+ case ('Z'): /* should have been first option (ZipInfo) */
|
|
+ Info(slide, 0x401, ((char *)slide, LoadFarString(Zfirst)));
|
|
+ error = TRUE;
|
|
+ break;
|
|
#endif /* !SFX */
|
|
#ifdef VMS
|
|
- case ('2'): /* Force ODS2-compliant names. */
|
|
- if (negative)
|
|
- uO.ods2_flag = FALSE, negative = 0;
|
|
- else
|
|
- uO.ods2_flag = TRUE;
|
|
- break;
|
|
+ case ('2'): /* Force ODS2-compliant names. */
|
|
+ if (negative)
|
|
+ uO.ods2_flag = FALSE, negative = 0;
|
|
+ else
|
|
+ uO.ods2_flag = TRUE;
|
|
+ break;
|
|
#endif /* VMS */
|
|
#ifdef DOS_H68_OS2_W32
|
|
- case ('$'):
|
|
- if (negative) {
|
|
- uO.volflag = MAX(uO.volflag-negative,0);
|
|
- negative = 0;
|
|
- } else
|
|
- ++uO.volflag;
|
|
- break;
|
|
+ case ('$'):
|
|
+ if (negative) {
|
|
+ uO.volflag = MAX(uO.volflag-negative,0);
|
|
+ negative = 0;
|
|
+ } else
|
|
+ ++uO.volflag;
|
|
+ break;
|
|
#endif /* DOS_H68_OS2_W32 */
|
|
#if (!defined(RISCOS) && !defined(CMS_MVS) && !defined(TANDEM))
|
|
- case (':'): /* allow "parent dir" path components */
|
|
- if (negative) {
|
|
- uO.ddotflag = MAX(uO.ddotflag-negative,0);
|
|
- negative = 0;
|
|
- } else
|
|
- ++uO.ddotflag;
|
|
- break;
|
|
+ case (':'): /* allow "parent dir" path components */
|
|
+ if (negative) {
|
|
+ uO.ddotflag = MAX(uO.ddotflag-negative,0);
|
|
+ negative = 0;
|
|
+ } else
|
|
+ ++uO.ddotflag;
|
|
+ break;
|
|
#endif /* !RISCOS && !CMS_MVS && !TANDEM */
|
|
#ifdef UNIX
|
|
- case ('^'): /* allow control chars in filenames */
|
|
- if (negative) {
|
|
- uO.cflxflag = MAX(uO.cflxflag-negative,0);
|
|
- negative = 0;
|
|
- } else
|
|
- ++uO.cflxflag;
|
|
- break;
|
|
+ case ('^'): /* allow control chars in filenames */
|
|
+ if (negative) {
|
|
+ uO.cflxflag = MAX(uO.cflxflag-negative,0);
|
|
+ negative = 0;
|
|
+ } else
|
|
+ ++uO.cflxflag;
|
|
+ break;
|
|
#endif /* UNIX */
|
|
- default:
|
|
- error = TRUE;
|
|
- break;
|
|
-
|
|
- } /* end switch */
|
|
- } /* end while (not end of argument string) */
|
|
- } /* end while (not done with switches) */
|
|
+ case o_NON_OPTION_ARG:
|
|
+ /* not an option */
|
|
+ /* no more options as permuting */
|
|
+
|
|
+
|
|
+ if (G.wildzipfn == NULL) {
|
|
+ /* first non-option argument is zip file */
|
|
+ G.wildzipfn = value;
|
|
+
|
|
+ } else {
|
|
+ /* add include file to list */
|
|
+ if (in_files_count == 0) {
|
|
+ /* first entry */
|
|
+ if ((next_file = (struct file_list *)
|
|
+ malloc(sizeof(struct file_list))
|
|
+ ) == NULL) {
|
|
+ Info(slide, 0x401, ((char *)slide,
|
|
+ LoadFarString(NoMemArgsList)));
|
|
+ return PK_MEM;
|
|
+ }
|
|
+ next_file->name = value;
|
|
+ next_file->next = NULL;
|
|
+ in_files = next_file;
|
|
+ next_in_files = next_file;
|
|
+ } else {
|
|
+ /* add next entry */
|
|
+ if ((next_file = (struct file_list *)
|
|
+ malloc(sizeof(struct file_list))
|
|
+ ) == NULL) {
|
|
+ Info(slide, 0x401, ((char *)slide,
|
|
+ LoadFarString(NoMemArgsList)));
|
|
+ return PK_MEM;
|
|
+ }
|
|
+ next_in_files->next = next_file;
|
|
+ next_file->name = value;
|
|
+ next_file->next = NULL;
|
|
+ next_in_files = next_file;
|
|
+ }
|
|
+ in_files_count++;
|
|
+ }
|
|
+ break;
|
|
+ default:
|
|
+ error = TRUE;
|
|
+ break;
|
|
+
|
|
+ } /* end switch */
|
|
+ } /* get_option() */
|
|
+
|
|
+
|
|
+ /* convert files and xfiles lists to arrays */
|
|
+
|
|
+ /* convert files list to array */
|
|
+ if (in_files_count) {
|
|
+ if ((G.pfnames = (char **) malloc((in_files_count + 1) * sizeof(char *))
|
|
+ ) == NULL) {
|
|
+ Info(slide, 0x401, ((char *)slide, LoadFarString(NoMemArgsList)));
|
|
+ return PK_MEM;
|
|
+ }
|
|
+ file_count = 0;
|
|
+ for (next_file = in_files; next_file;) {
|
|
+ G.pfnames[file_count] = next_file->name;
|
|
+ in_files = next_file;
|
|
+ next_file = next_file->next;
|
|
+ free(in_files);
|
|
+ file_count++;
|
|
+ }
|
|
+ G.pfnames[file_count] = NULL;
|
|
+ G.filespecs = in_files_count;
|
|
+ }
|
|
+
|
|
+ /* convert xfiles list to array */
|
|
+ if (in_xfiles_count) {
|
|
+ if ((G.pxnames = (char **) malloc((in_xfiles_count + 1) * sizeof(char *))
|
|
+ ) == NULL) {
|
|
+ Info(slide, 0x401, ((char *)slide, LoadFarString(NoMemArgsList)));
|
|
+ return PK_MEM;
|
|
+ }
|
|
+ file_count = 0;
|
|
+ for (next_file = in_xfiles; next_file;) {
|
|
+ G.pxnames[file_count] = next_file->name;
|
|
+ in_xfiles = next_file;
|
|
+ next_file = next_file->next;
|
|
+ free(in_xfiles);
|
|
+ file_count++;
|
|
+ }
|
|
+ G.pxnames[file_count] = NULL;
|
|
+ G.xfilespecs = in_xfiles_count;
|
|
+ }
|
|
+
|
|
+ if (in_files_count || in_xfiles_count) {
|
|
+ G.process_all_files = FALSE;
|
|
+ } else {
|
|
+ G.process_all_files = TRUE; /* for speed */
|
|
+ }
|
|
+
|
|
+
|
|
+ /* it's possible the arg count could have been changed by get_option() */
|
|
+ argc = arg_count(args);
|
|
+
|
|
+
|
|
|
|
/*---------------------------------------------------------------------------
|
|
@@ -1774,7 +2240,77 @@
|
|
---------------------------------------------------------------------------*/
|
|
|
|
+ if ((uO.cflag && (uO.tflag || uO.uflag)) ||
|
|
+ (uO.tflag && uO.uflag) || (uO.fflag && uO.overwrite_none))
|
|
+ {
|
|
+ Info(slide, 0x401, ((char *)slide, LoadFarString(InvalidOptionsMsg)));
|
|
+ error = TRUE;
|
|
+ }
|
|
+ if (uO.aflag > 2)
|
|
+ uO.aflag = 2;
|
|
+#ifdef VMS
|
|
+ if (uO.bflag > 2)
|
|
+ uO.bflag = 2;
|
|
+ /* Clear -s flag when converting text files. */
|
|
+ if (uO.aflag <= 0)
|
|
+ uO.S_flag = 0;
|
|
+#endif /* VMS */
|
|
+ if (uO.overwrite_all && uO.overwrite_none) {
|
|
+ Info(slide, 0x401, ((char *)slide, LoadFarString(IgnoreOOptionMsg)));
|
|
+ uO.overwrite_all = FALSE;
|
|
+ }
|
|
+#ifdef MORE
|
|
+ if (G.M_flag && !isatty(1)) /* stdout redirected: "more" func. useless */
|
|
+ G.M_flag = 0;
|
|
+#endif
|
|
+
|
|
+#ifdef SFX
|
|
+ if (error)
|
|
+#else
|
|
+ if ((G.wildzipfn == NULL) || error)
|
|
+#endif
|
|
+ {
|
|
+ /* tell caller to exit */
|
|
+ if (argc <= 2)
|
|
+ argc = -1;
|
|
+
|
|
+ *pargc = argc;
|
|
+ *pargv = args;
|
|
+#ifndef SFX
|
|
+ if (uO.vflag >= 2 && argc == -1) { /* "unzip -v" */
|
|
+ show_version_info(__G);
|
|
+ return PK_OK;
|
|
+ }
|
|
+ if (!G.noargs && !error)
|
|
+ error = TRUE; /* had options (not -h or -v) but no zipfile */
|
|
+#endif /* !SFX */
|
|
+ return USAGE(error);
|
|
+ }
|
|
+
|
|
#ifdef SFX
|
|
-opts_done: /* yes, very ugly...but only used by UnZipSFX with -x xlist */
|
|
+ /* print our banner unless we're being fairly quiet */
|
|
+ if (uO.qflag < 2)
|
|
+ Info(slide, error? 1 : 0, ((char *)slide, LoadFarString(UnzipSFXBanner),
|
|
+ UZ_MAJORVER, UZ_MINORVER, UZ_PATCHLEVEL, UZ_BETALEVEL,
|
|
+ LoadFarStringSmall(VersionDate)));
|
|
+#ifdef BETA
|
|
+ /* always print the beta warning: no unauthorized distribution!! */
|
|
+ Info(slide, error? 1 : 0, ((char *)slide, LoadFarString(BetaVersion), "\n",
|
|
+ "SFX"));
|
|
+#endif
|
|
+#endif /* SFX */
|
|
+
|
|
+ if (uO.cflag || uO.tflag || uO.vflag || uO.zflag
|
|
+#ifdef TIMESTAMP
|
|
+ || uO.T_flag
|
|
#endif
|
|
+ )
|
|
+ G.extract_flag = FALSE;
|
|
+ else
|
|
+ G.extract_flag = TRUE;
|
|
+
|
|
+#if 0
|
|
+# ifdef SFX
|
|
+opts_done: /* yes, very ugly...but only used by UnZipSFX with -x xlist */
|
|
+# endif
|
|
|
|
if ((uO.cflag && (uO.tflag || uO.uflag)) ||
|
|
@@ -1786,5 +2322,5 @@
|
|
if (uO.aflag > 2)
|
|
uO.aflag = 2;
|
|
-#ifdef VMS
|
|
+# ifdef VMS
|
|
if (uO.bflag > 2)
|
|
uO.bflag = 2;
|
|
@@ -1792,23 +2328,23 @@
|
|
if (uO.aflag <= 0)
|
|
uO.S_flag = 0;
|
|
-#endif /* VMS */
|
|
+# endif /* VMS */
|
|
if (uO.overwrite_all && uO.overwrite_none) {
|
|
Info(slide, 0x401, ((char *)slide, LoadFarString(IgnoreOOptionMsg)));
|
|
uO.overwrite_all = FALSE;
|
|
}
|
|
-#ifdef MORE
|
|
+# ifdef MORE
|
|
if (G.M_flag && !isatty(1)) /* stdout redirected: "more" func. useless */
|
|
G.M_flag = 0;
|
|
-#endif
|
|
+# endif
|
|
|
|
-#ifdef SFX
|
|
+# ifdef SFX
|
|
if (error)
|
|
-#else
|
|
+# else
|
|
if ((argc-- == 0) || error)
|
|
-#endif
|
|
+# endif
|
|
{
|
|
*pargc = argc;
|
|
- *pargv = argv;
|
|
-#ifndef SFX
|
|
+ *pargv = args;
|
|
+# ifndef SFX
|
|
if (uO.vflag >= 2 && argc == -1) { /* "unzip -v" */
|
|
show_version_info(__G);
|
|
@@ -1817,9 +2353,9 @@
|
|
if (!G.noargs && !error)
|
|
error = TRUE; /* had options (not -h or -v) but no zipfile */
|
|
-#endif /* !SFX */
|
|
+# endif /* !SFX */
|
|
return USAGE(error);
|
|
}
|
|
|
|
-#ifdef SFX
|
|
+# ifdef SFX
|
|
/* print our banner unless we're being fairly quiet */
|
|
if (uO.qflag < 2)
|
|
@@ -1827,22 +2363,23 @@
|
|
UZ_MAJORVER, UZ_MINORVER, UZ_PATCHLEVEL, UZ_BETALEVEL,
|
|
LoadFarStringSmall(VersionDate)));
|
|
-#ifdef BETA
|
|
+# ifdef BETA
|
|
/* always print the beta warning: no unauthorized distribution!! */
|
|
Info(slide, error? 1 : 0, ((char *)slide, LoadFarString(BetaVersion), "\n",
|
|
"SFX"));
|
|
-#endif
|
|
-#endif /* SFX */
|
|
+# endif
|
|
+# endif /* SFX */
|
|
|
|
if (uO.cflag || uO.tflag || uO.vflag || uO.zflag
|
|
-#ifdef TIMESTAMP
|
|
+# ifdef TIMESTAMP
|
|
|| uO.T_flag
|
|
-#endif
|
|
+# endif
|
|
)
|
|
G.extract_flag = FALSE;
|
|
else
|
|
G.extract_flag = TRUE;
|
|
+#endif
|
|
|
|
*pargc = argc;
|
|
- *pargv = argv;
|
|
+ *pargv = args;
|
|
return PK_OK;
|
|
|
|
@@ -2314,2 +2851,1366 @@
|
|
#endif /* !SFX */
|
|
#endif /* !WINDLL */
|
|
+
|
|
+
|
|
+
|
|
+
|
|
+
|
|
+
|
|
+/*---------------------------------------------------------------
|
|
+ * Long option support
|
|
+ * 8/23/2003
|
|
+ * Updated 3/1/2008 to support UnZip
|
|
+ *
|
|
+ * Defines function get_option() to get and process the command
|
|
+ * line options and arguments from argv[]. The caller calls
|
|
+ * get_option() in a loop to get either one option and possible
|
|
+ * value or a non-option argument each loop.
|
|
+ *
|
|
+ * This version has been modified to work with UnZip and ZipInfo.
|
|
+ * the major changes are removing the error returns, instead
|
|
+ * passing back error codes for errors, and supporting separate
|
|
+ * groups of options for UnZip and ZipInfo and selecting the option
|
|
+ * group by an argument.
|
|
+ *
|
|
+ * This version does not include argument file support and can
|
|
+ * work directly on argv. The argument file code complicates things and
|
|
+ * it seemed best to leave it out for now. If argument file support
|
|
+ * (reading in command line arguments stored in a file and inserting into
|
|
+ * command line where @filename is found) is added later the arguments
|
|
+ * can change and a freeable copy of argv will be needed and can be
|
|
+ * created using copy_args in the left out code.
|
|
+ *
|
|
+ * Supports short and long options as defined in the array options[]
|
|
+ * in zip.c, multiple short options in an argument (like -jlv), long
|
|
+ * option abbreviation (like --te for --temp-file if --te unique),
|
|
+ * short and long option values (like -b filename or --temp-file filename
|
|
+ * or --temp-file=filename), optional and required values, option negation
|
|
+ * by trailing - (like -S- to not include hidden and system files in MSDOS),
|
|
+ * value lists (like -x a b c), argument permuting (returning all options
|
|
+ * and values before any non-option arguments), and argument files (where
|
|
+ * any non-option non-value argument in form @path gets substituted with
|
|
+ * the white space separated arguments in the text file at path). In this
|
|
+ * version argument file support has been removed to simplify development
|
|
+ * but may be added later.
|
|
+ *
|
|
+ * E. Gordon
|
|
+ */
|
|
+
|
|
+
|
|
+/* message output - char casts are needed to handle constants */
|
|
+#define oWARN(message) Info(slide, 0x401, ((char *)slide, (char *)message))
|
|
+
|
|
+
|
|
+
|
|
+/* Although the below provides some support for multibyte characters
|
|
+ the proper thing to do may be to use wide characters and support
|
|
+ Unicode. May get to it soon. Wide support would likely require
|
|
+ the ability to convert the command line to wide strings, which most
|
|
+ modern OS should support now. EG
|
|
+ */
|
|
+
|
|
+/* For now stay with multi-byte characters. May support wide characters
|
|
+ in Zip 3.1 and UnZip 6.1.
|
|
+ */
|
|
+
|
|
+/* multibyte character set support
|
|
+ Multibyte characters use typically two or more sequential bytes
|
|
+ to represent additional characters than can fit in a single byte
|
|
+ character set. The code used here is based on the ANSI mblen function. */
|
|
+#define MB_CLEN(ptr) CLEN(ptr)
|
|
+#define MB_NEXTCHAR(ptr) PREINCSTR(ptr)
|
|
+
|
|
+
|
|
+/* constants */
|
|
+
|
|
+/* function get_args_from_arg_file() can return this in depth parameter */
|
|
+#define ARG_FILE_ERR -1
|
|
+
|
|
+/* internal settings for optchar */
|
|
+#define SKIP_VALUE_ARG -1
|
|
+#define THIS_ARG_DONE -2
|
|
+#define START_VALUE_LIST -3
|
|
+#define IN_VALUE_LIST -4
|
|
+#define NON_OPTION_ARG -5
|
|
+#define STOP_VALUE_LIST -6
|
|
+/* 7/25/04 EG */
|
|
+#define READ_REST_ARGS_VERBATIM -7
|
|
+
|
|
+
|
|
+/* global veriables */
|
|
+
|
|
+int enable_permute = 1; /* yes - return options first */
|
|
+/* 7/25/04 EG */
|
|
+int doubledash_ends_options = 1; /* when -- what follows are not options */
|
|
+
|
|
+/* buffer for error messages (this sizing is a guess but must hold 2 paths) */
|
|
+#define OPTIONERR_BUF_SIZE (80+ 2*FILENAME_MAX)
|
|
+char optionerrbuf[OPTIONERR_BUF_SIZE + 1];
|
|
+
|
|
+/* error messages */
|
|
+static ZCONST char Far op_not_neg_err[] =
|
|
+ "option %s not negatable";
|
|
+static ZCONST char Far op_req_val_err[] =
|
|
+ "option %s requires a value";
|
|
+static ZCONST char Far op_no_allow_val_err[] =
|
|
+ "option %s does not allow a value";
|
|
+static ZCONST char Far sh_op_not_sup_err[] =
|
|
+ "short option '%c' not supported";
|
|
+static ZCONST char Far oco_req_val_err[] =
|
|
+ "option %s requires one character value";
|
|
+static ZCONST char Far oco_no_mbc_err[] =
|
|
+ "option %s does not support multibyte values";
|
|
+static ZCONST char Far num_req_val_err[] =
|
|
+ "option %s requires number value";
|
|
+static ZCONST char Far long_op_ambig_err[] =
|
|
+ "long option '%s' ambiguous";
|
|
+static ZCONST char Far long_op_not_sup_err[] =
|
|
+ "long option '%s' not supported";
|
|
+
|
|
+static ZCONST char Far no_arg_files_err[] = "argument files not enabled\n";
|
|
+
|
|
+
|
|
+/* below removed as only used for processing argument files */
|
|
+
|
|
+/* get_nextarg */
|
|
+/* get_args_from_string */
|
|
+/* get_args_from_arg_file */
|
|
+
|
|
+
|
|
+/* copy error, option name, and option description if any to buf */
|
|
+static int optionerr(options, buf, err, optind, islong)
|
|
+ struct option_struct *options;
|
|
+ char *buf;
|
|
+ ZCONST char Far *err;
|
|
+ int optind;
|
|
+ int islong;
|
|
+{
|
|
+ char optname[50];
|
|
+
|
|
+ if (options[optind].name && options[optind].name[0] != '\0') {
|
|
+ sprintf(optname, "'%s' (%s)",
|
|
+ LoadFarStringSmall2(islong ? options[optind].longopt
|
|
+ : options[optind].shortopt),
|
|
+ LoadFarStringSmall(options[optind].name));
|
|
+ } else {
|
|
+ sprintf(optname, "'%s'",
|
|
+ LoadFarStringSmall2(islong ? options[optind].longopt
|
|
+ : options[optind].shortopt));
|
|
+ }
|
|
+ sprintf(buf, LoadFarStringSmall(err), optname);
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+
|
|
+/* copy_args
|
|
+ *
|
|
+ * Copy arguments in args, allocating storage with malloc.
|
|
+ * Copies until a NULL argument is found or until max_args args
|
|
+ * including args[0] are copied. Set max_args to 0 to copy
|
|
+ * until NULL. Always terminates returned args[] with NULL arg.
|
|
+ *
|
|
+ * Any argument in the returned args can be freed with free(). Any
|
|
+ * freed argument should be replaced with either another string
|
|
+ * allocated with malloc or by NULL if last argument so that free_args
|
|
+ * will properly work.
|
|
+ */
|
|
+char **copy_args(args, max_args)
|
|
+ char **args;
|
|
+ int max_args;
|
|
+{
|
|
+ int j;
|
|
+ char **new_args;
|
|
+
|
|
+ if (args == NULL) {
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ /* count args */
|
|
+ for (j = 0; args[j] && (max_args == 0 || j < max_args); j++) ;
|
|
+
|
|
+ if ((new_args = (char **) malloc((j + 1) * sizeof(char *))) == NULL) {
|
|
+ oWARN("memory - ca");
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ for (j = 0; args[j] && (max_args == 0 || j < max_args); j++) {
|
|
+ if (args[j] == NULL) {
|
|
+ /* null argument is end of args */
|
|
+ new_args[j] = NULL;
|
|
+ break;
|
|
+ }
|
|
+ if ((new_args[j] = malloc(strlen(args[j]) + 1)) == NULL) {
|
|
+ free_args(new_args);
|
|
+ oWARN("memory - ca");
|
|
+ return NULL;
|
|
+ }
|
|
+ strcpy(new_args[j], args[j]);
|
|
+ }
|
|
+ new_args[j] = NULL;
|
|
+
|
|
+ return new_args;
|
|
+}
|
|
+
|
|
+
|
|
+/* count args - count args in argv like array */
|
|
+int arg_count(args)
|
|
+ char **args;
|
|
+{
|
|
+ int i;
|
|
+
|
|
+ if (args == NULL) {
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ for (i = 0; args[i]; i++) {
|
|
+ }
|
|
+ return i;
|
|
+}
|
|
+
|
|
+
|
|
+/* free args - free args created with one of these functions */
|
|
+int free_args(args)
|
|
+ char **args;
|
|
+{
|
|
+ int i;
|
|
+
|
|
+ if (args == NULL) {
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ for (i = 0; args[i]; i++) {
|
|
+ free(args[i]);
|
|
+ }
|
|
+ free(args);
|
|
+ return i;
|
|
+}
|
|
+
|
|
+
|
|
+/* insert_arg
|
|
+ *
|
|
+ * Insert the argument arg into the array args before argument at_arg.
|
|
+ * If at_arg = -1 then append to end.
|
|
+ * Return the new count of arguments (argc).
|
|
+ *
|
|
+ * If free_args is true, this function frees the old args array
|
|
+ * (but not the component strings). DO NOT set free_args on original
|
|
+ * argv but only on args allocated with malloc.
|
|
+ */
|
|
+
|
|
+int insert_arg(pargs, arg, at_arg, free_args)
|
|
+ char ***pargs;
|
|
+ ZCONST char *arg;
|
|
+ int at_arg;
|
|
+ int free_args;
|
|
+{
|
|
+ char *newarg = NULL;
|
|
+ char **args;
|
|
+ char **newargs = NULL;
|
|
+ int argnum;
|
|
+ int newargnum;
|
|
+ int argcnt;
|
|
+ int newargcnt;
|
|
+
|
|
+ if (pargs == NULL) {
|
|
+ return 0;
|
|
+ }
|
|
+ args = *pargs;
|
|
+
|
|
+ /* count args */
|
|
+ if (args == NULL) {
|
|
+ argcnt = 0;
|
|
+ } else {
|
|
+ for (argcnt = 0; args[argcnt]; argcnt++) ;
|
|
+ }
|
|
+ if (arg == NULL) {
|
|
+ /* done */
|
|
+ return argcnt;
|
|
+ }
|
|
+ if (at_arg == -1) {
|
|
+ at_arg = argcnt;
|
|
+ }
|
|
+ newargcnt = argcnt + 1;
|
|
+
|
|
+ /* get storage for new args */
|
|
+ if ((newargs = (char **) malloc((newargcnt + 1) * sizeof(char *))) == NULL)
|
|
+ {
|
|
+ oWARN("memory - ia");
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ /* copy argument pointers from args to position at_arg, copy the new arg,
|
|
+ then copy the rest of the args */
|
|
+ argnum = 0;
|
|
+ newargnum = 0;
|
|
+ if (args) {
|
|
+ for (; args[argnum] && argnum < at_arg; argnum++) {
|
|
+ newargs[newargnum++] = args[argnum];
|
|
+ }
|
|
+ }
|
|
+ /* copy new arg */
|
|
+ if ((newarg = (char *) malloc(strlen(arg) + 1)) == NULL) {
|
|
+ oWARN("memory - ia");
|
|
+ return 0;
|
|
+ }
|
|
+ strcpy(newarg, arg);
|
|
+
|
|
+ newargs[newargnum++] = newarg;
|
|
+ if (args) {
|
|
+ for ( ; args[argnum]; argnum++) {
|
|
+ newargs[newargnum++] = args[argnum];
|
|
+ }
|
|
+ }
|
|
+ newargs[newargnum] = NULL;
|
|
+
|
|
+ /* free old args array but not component strings - this assumes that
|
|
+ args was allocated with malloc as copy_args does. DO NOT DO THIS
|
|
+ on the original argv.
|
|
+ */
|
|
+ if (free_args)
|
|
+ free(args);
|
|
+
|
|
+ *pargs = newargs;
|
|
+
|
|
+ return newargnum;
|
|
+}
|
|
+
|
|
+/* ------------------------------------- */
|
|
+
|
|
+/* get_shortopt
|
|
+ *
|
|
+ * Get next short option from arg. The state is stored in argnum, optchar, and
|
|
+ * option_num so no static storage is used. Returns the option_ID.
|
|
+ *
|
|
+ * parameters:
|
|
+ * option_group - either UZO for UnZip options or ZIO for ZipInfo options
|
|
+ * args - argv array of arguments
|
|
+ * argnum - index of current arg in args
|
|
+ * optchar - pointer to index of next char to process. Can be 0 or
|
|
+ * const defined at top of this file like THIS_ARG_DONE
|
|
+ * negated - on return pointer to int set to 1 if option negated
|
|
+ * or 0 otherwise
|
|
+ * value - on return pointer to string set to value of option if any
|
|
+ * or NULL if none. If value is returned then the caller
|
|
+ * should free() it when not needed anymore.
|
|
+ * option_num - pointer to index in options[] of returned option or
|
|
+ * o_NO_OPTION_MATCH if none. Do not change as used by
|
|
+ * value lists.
|
|
+ * depth - recursion depth (0 at top level, 1 or more in arg files)
|
|
+ */
|
|
+static unsigned long get_shortopt(option_group, args, argnum, optchar, negated,
|
|
+ value, option_num, depth)
|
|
+ int option_group;
|
|
+ ZCONST char **args;
|
|
+ int argnum;
|
|
+ int *optchar;
|
|
+ int *negated;
|
|
+ char **value;
|
|
+ int *option_num;
|
|
+ int depth;
|
|
+{
|
|
+ ZCONST char *shortopt;
|
|
+ int clen;
|
|
+ ZCONST char *nextchar;
|
|
+ ZCONST char *s;
|
|
+ ZCONST char *start;
|
|
+ int op;
|
|
+ ZCONST char *arg;
|
|
+ int match = -1;
|
|
+
|
|
+
|
|
+ /* get arg */
|
|
+ arg = args[argnum];
|
|
+ /* current char in arg */
|
|
+ nextchar = arg + (*optchar);
|
|
+ clen = MB_CLEN(nextchar);
|
|
+ /* next char in arg */
|
|
+ (*optchar) += clen;
|
|
+ /* get first char of short option */
|
|
+ shortopt = arg + (*optchar);
|
|
+ /* no value */
|
|
+ *value = NULL;
|
|
+
|
|
+ if (*shortopt == '\0') {
|
|
+ /* no more options in arg */
|
|
+ *optchar = 0;
|
|
+ *option_num = o_NO_OPTION_MATCH;
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ /* look for match in options */
|
|
+ clen = MB_CLEN(shortopt);
|
|
+ for (op = 0; options[op].option_ID; op++) {
|
|
+ /* Only look at options in this option group */
|
|
+ if (options[op].option_group == option_group) {
|
|
+ s = options[op].shortopt;
|
|
+ if (s && s[0] == shortopt[0]) {
|
|
+ if (s[1] == '\0' && clen == 1) {
|
|
+ /* single char match */
|
|
+ match = op;
|
|
+ } else {
|
|
+ /* 2 wide short opt. Could support more chars but should use long opts instead */
|
|
+ if (s[1] == shortopt[1]) {
|
|
+ /* match 2 char short opt or 2 byte char */
|
|
+ match = op;
|
|
+ if (clen == 1) (*optchar)++;
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (match > -1) {
|
|
+ /* match */
|
|
+ clen = MB_CLEN(shortopt);
|
|
+ nextchar = arg + (*optchar) + clen;
|
|
+ /* check for trailing dash negating option */
|
|
+ if (*nextchar == '-') {
|
|
+ /* negated */
|
|
+ if (options[match].negatable == o_NOT_NEGATABLE) {
|
|
+ if (options[match].value_type == o_NO_VALUE) {
|
|
+ optionerr(options, optionerrbuf, op_not_neg_err, match, 0);
|
|
+ if (depth > 0) {
|
|
+ /* unwind */
|
|
+ oWARN(optionerrbuf);
|
|
+ return o_ARG_FILE_ERR;
|
|
+ } else {
|
|
+ oWARN(optionerrbuf);
|
|
+ return o_BAD_ERR;
|
|
+ }
|
|
+ }
|
|
+ } else {
|
|
+ *negated = 1;
|
|
+ /* set up to skip negating dash */
|
|
+ (*optchar) += clen;
|
|
+ clen = 1;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /* value */
|
|
+ clen = MB_CLEN(arg + (*optchar));
|
|
+ /* optional value, one char value, and number value must follow option */
|
|
+ if (options[match].value_type == o_ONE_CHAR_VALUE) {
|
|
+ /* one char value */
|
|
+ if (arg[(*optchar) + clen]) {
|
|
+ /* has value */
|
|
+ if (MB_CLEN(arg + (*optchar) + clen) > 1) {
|
|
+ /* multibyte value not allowed for now */
|
|
+ optionerr(options, optionerrbuf, oco_no_mbc_err, match, 0);
|
|
+ if (depth > 0) {
|
|
+ /* unwind */
|
|
+ oWARN(optionerrbuf);
|
|
+ return o_ARG_FILE_ERR;
|
|
+ } else {
|
|
+ oWARN(optionerrbuf);
|
|
+ return o_BAD_ERR;
|
|
+ }
|
|
+ }
|
|
+ if ((*value = (char *) malloc(2)) == NULL) {
|
|
+ oWARN("memory - gso");
|
|
+ return o_BAD_ERR;
|
|
+ }
|
|
+ (*value)[0] = *(arg + (*optchar) + clen);
|
|
+ (*value)[1] = '\0';
|
|
+ *optchar += clen;
|
|
+ clen = 1;
|
|
+ } else {
|
|
+ /* one char values require a value */
|
|
+ optionerr(options, optionerrbuf, oco_req_val_err, match, 0);
|
|
+ if (depth > 0) {
|
|
+ oWARN(optionerrbuf);
|
|
+ return o_ARG_FILE_ERR;
|
|
+ } else {
|
|
+ oWARN(optionerrbuf);
|
|
+ return o_BAD_ERR;
|
|
+ }
|
|
+ }
|
|
+ } else if (options[match].value_type == o_NUMBER_VALUE) {
|
|
+ /* read chars until end of number */
|
|
+ start = arg + (*optchar) + clen;
|
|
+ if (*start == '+' || *start == '-') {
|
|
+ start++;
|
|
+ }
|
|
+ s = start;
|
|
+ for (; isdigit(*s); MB_NEXTCHAR(s)) ;
|
|
+ if (s == start) {
|
|
+ /* no digits */
|
|
+ optionerr(options, optionerrbuf, num_req_val_err, match, 0);
|
|
+ if (depth > 0) {
|
|
+ oWARN(optionerrbuf);
|
|
+ return o_ARG_FILE_ERR;
|
|
+ } else {
|
|
+ oWARN(optionerrbuf);
|
|
+ return o_BAD_ERR;
|
|
+ }
|
|
+ }
|
|
+ start = arg + (*optchar) + clen;
|
|
+ if ((*value = (char *) malloc((int)(s - start) + 1)) == NULL) {
|
|
+ oWARN("memory - gso");
|
|
+ return o_BAD_ERR;
|
|
+ }
|
|
+ *optchar += (int)(s - start);
|
|
+ strncpy(*value, start, (int)(s - start));
|
|
+ (*value)[(int)(s - start)] = '\0';
|
|
+ clen = MB_CLEN(s);
|
|
+ } else if (options[match].value_type == o_OPTIONAL_VALUE) {
|
|
+ /* optional value */
|
|
+ /* This seemed inconsistent so now if no value attached to argument look
|
|
+ to the next argument if that argument is not an option for option
|
|
+ value - 11/12/04 EG */
|
|
+ if (arg[(*optchar) + clen]) {
|
|
+ /* has value */
|
|
+ /* add support for optional = - 2/6/05 EG */
|
|
+ if (arg[(*optchar) + clen] == '=') {
|
|
+ /* skip = */
|
|
+ clen++;
|
|
+ }
|
|
+ if (arg[(*optchar) + clen]) {
|
|
+ if ((*value = (char *)malloc(strlen(arg + (*optchar) + clen) + 1))
|
|
+ == NULL) {
|
|
+ oWARN("memory - gso");
|
|
+ return o_BAD_ERR;
|
|
+ }
|
|
+ strcpy(*value, arg + (*optchar) + clen);
|
|
+ }
|
|
+ *optchar = THIS_ARG_DONE;
|
|
+ } else if (args[argnum + 1] && args[argnum + 1][0] != '-') {
|
|
+ /* use next arg for value */
|
|
+ if ((*value = (char *)malloc(strlen(args[argnum + 1]) + 1)) == NULL) {
|
|
+ oWARN("memory - gso");
|
|
+ return o_BAD_ERR;
|
|
+ }
|
|
+ /* using next arg as value */
|
|
+ strcpy(*value, args[argnum + 1]);
|
|
+ *optchar = SKIP_VALUE_ARG;
|
|
+ }
|
|
+ } else if (options[match].value_type == o_REQUIRED_VALUE ||
|
|
+ options[match].value_type == o_VALUE_LIST) {
|
|
+ /* see if follows option */
|
|
+ if (arg[(*optchar) + clen]) {
|
|
+ /* has value following option as -ovalue */
|
|
+ /* add support for optional = - 6/5/05 EG */
|
|
+ if (arg[(*optchar) + clen] == '=') {
|
|
+ /* skip = */
|
|
+ clen++;
|
|
+ }
|
|
+ if ((*value = (char *)malloc(strlen(arg + (*optchar) + clen) + 1))
|
|
+ == NULL) {
|
|
+ oWARN("memory - gso");
|
|
+ return o_BAD_ERR;
|
|
+ }
|
|
+ strcpy(*value, arg + (*optchar) + clen);
|
|
+ *optchar = THIS_ARG_DONE;
|
|
+ } else {
|
|
+ /* use next arg for value */
|
|
+ if (args[argnum + 1]) {
|
|
+ if ((*value = (char *)malloc(strlen(args[argnum + 1]) + 1))
|
|
+ == NULL) {
|
|
+ oWARN("memory - gso");
|
|
+ return o_BAD_ERR;
|
|
+ }
|
|
+ strcpy(*value, args[argnum + 1]);
|
|
+ if (options[match].value_type == o_VALUE_LIST) {
|
|
+ *optchar = START_VALUE_LIST;
|
|
+ } else {
|
|
+ *optchar = SKIP_VALUE_ARG;
|
|
+ }
|
|
+ } else {
|
|
+ /* no value found */
|
|
+ optionerr(options, optionerrbuf, op_req_val_err, match, 0);
|
|
+ if (depth > 0) {
|
|
+ oWARN(optionerrbuf);
|
|
+ return o_ARG_FILE_ERR;
|
|
+ } else {
|
|
+ oWARN(optionerrbuf);
|
|
+ return o_BAD_ERR;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ *option_num = match;
|
|
+ return options[match].option_ID;
|
|
+ }
|
|
+ sprintf(optionerrbuf, LoadFarStringSmall(sh_op_not_sup_err), *shortopt);
|
|
+ if (depth > 0) {
|
|
+ /* unwind */
|
|
+ oWARN(optionerrbuf);
|
|
+ return o_ARG_FILE_ERR;
|
|
+ } else {
|
|
+ oWARN(optionerrbuf);
|
|
+ return o_BAD_ERR;
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+
|
|
+/* get_longopt
|
|
+ *
|
|
+ * Get the long option in args array at argnum.
|
|
+ * Parameters same as for get_shortopt.
|
|
+ */
|
|
+
|
|
+static unsigned long get_longopt(option_group, args, argnum, optchar, negated,
|
|
+ value, option_num, depth)
|
|
+ int option_group;
|
|
+ ZCONST char **args;
|
|
+ int argnum;
|
|
+ int *optchar;
|
|
+ int *negated;
|
|
+ char **value;
|
|
+ int *option_num;
|
|
+ int depth;
|
|
+{
|
|
+ char *longopt;
|
|
+ char *lastchr;
|
|
+ char *valuestart;
|
|
+ int op;
|
|
+ char *arg;
|
|
+ int match = -1;
|
|
+ *value = NULL;
|
|
+
|
|
+ if (args == NULL) {
|
|
+ *option_num = o_NO_OPTION_MATCH;
|
|
+ return 0;
|
|
+ }
|
|
+ if (args[argnum] == NULL) {
|
|
+ *option_num = o_NO_OPTION_MATCH;
|
|
+ return 0;
|
|
+ }
|
|
+ /* copy arg so can chop end if value */
|
|
+ if ((arg = (char *)malloc(strlen(args[argnum]) + 1)) == NULL) {
|
|
+ oWARN("memory - glo");
|
|
+ return o_BAD_ERR;
|
|
+ }
|
|
+ strcpy(arg, args[argnum]);
|
|
+
|
|
+ /* get option */
|
|
+ longopt = arg + 2;
|
|
+ /* no value */
|
|
+ *value = NULL;
|
|
+
|
|
+ /* find = */
|
|
+ for (lastchr = longopt, valuestart = longopt;
|
|
+ *valuestart && *valuestart != '=';
|
|
+ lastchr = valuestart, MB_NEXTCHAR(valuestart)) ;
|
|
+ if (*valuestart) {
|
|
+ /* found =value */
|
|
+ *valuestart = '\0';
|
|
+ valuestart++;
|
|
+ } else {
|
|
+ valuestart = NULL;
|
|
+ }
|
|
+
|
|
+ if (*lastchr == '-') {
|
|
+ /* option negated */
|
|
+ *negated = 1;
|
|
+ *lastchr = '\0';
|
|
+ } else {
|
|
+ *negated = 0;
|
|
+ }
|
|
+
|
|
+ /* look for long option match */
|
|
+ for (op = 0; options[op].option_ID; op++) {
|
|
+ /* Only look at options in the option group */
|
|
+ if (options[op].option_group == option_group) {
|
|
+ if (options[op].longopt &&
|
|
+ strcmp(LoadFarStringSmall(options[op].longopt), longopt) == 0) {
|
|
+ /* exact match */
|
|
+ match = op;
|
|
+ break;
|
|
+ }
|
|
+ if (options[op].longopt &&
|
|
+ strncmp(LoadFarStringSmall(options[op].longopt),
|
|
+ longopt, strlen(longopt)) == 0) {
|
|
+ if (match > -1) {
|
|
+ sprintf(optionerrbuf, LoadFarStringSmall(long_op_ambig_err),
|
|
+ longopt);
|
|
+ free(arg);
|
|
+ if (depth > 0) {
|
|
+ /* unwind */
|
|
+ oWARN(optionerrbuf);
|
|
+ return o_ARG_FILE_ERR;
|
|
+ } else {
|
|
+ oWARN(optionerrbuf);
|
|
+ return o_BAD_ERR;
|
|
+ }
|
|
+ }
|
|
+ match = op;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (match == -1) {
|
|
+ sprintf(optionerrbuf, LoadFarStringSmall(long_op_not_sup_err), longopt);
|
|
+ free(arg);
|
|
+ if (depth > 0) {
|
|
+ oWARN(optionerrbuf);
|
|
+ return o_ARG_FILE_ERR;
|
|
+ } else {
|
|
+ oWARN(optionerrbuf);
|
|
+ return o_BAD_ERR;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /* one long option an arg */
|
|
+ *optchar = THIS_ARG_DONE;
|
|
+
|
|
+ /* if negated then see if allowed */
|
|
+ if (*negated && options[match].negatable == o_NOT_NEGATABLE) {
|
|
+ optionerr(options, optionerrbuf, op_not_neg_err, match, 1);
|
|
+ free(arg);
|
|
+ if (depth > 0) {
|
|
+ /* unwind */
|
|
+ oWARN(optionerrbuf);
|
|
+ return o_ARG_FILE_ERR;
|
|
+ } else {
|
|
+ oWARN(optionerrbuf);
|
|
+ return o_BAD_ERR;
|
|
+ }
|
|
+ }
|
|
+ /* get value */
|
|
+ if (options[match].value_type == o_OPTIONAL_VALUE) {
|
|
+ /* optional value in form option=value */
|
|
+ if (valuestart) {
|
|
+ /* option=value */
|
|
+ if ((*value = (char *)malloc(strlen(valuestart) + 1)) == NULL) {
|
|
+ free(arg);
|
|
+ oWARN("memory - glo");
|
|
+ return o_BAD_ERR;
|
|
+ }
|
|
+ strcpy(*value, valuestart);
|
|
+ }
|
|
+ } else if (options[match].value_type == o_REQUIRED_VALUE ||
|
|
+ options[match].value_type == o_NUMBER_VALUE ||
|
|
+ options[match].value_type == o_ONE_CHAR_VALUE ||
|
|
+ options[match].value_type == o_VALUE_LIST) {
|
|
+ /* handle long option one char and number value as required value */
|
|
+ if (valuestart) {
|
|
+ /* option=value */
|
|
+ if ((*value = (char *)malloc(strlen(valuestart) + 1)) == NULL) {
|
|
+ free(arg);
|
|
+ oWARN("memory - glo");
|
|
+ return o_BAD_ERR;
|
|
+ }
|
|
+ strcpy(*value, valuestart);
|
|
+ } else {
|
|
+ /* use next arg */
|
|
+ if (args[argnum + 1]) {
|
|
+ if ((*value = (char *)malloc(strlen(args[argnum + 1]) + 1)) == NULL) {
|
|
+ free(arg);
|
|
+ oWARN("memory - glo");
|
|
+ return o_BAD_ERR;
|
|
+ }
|
|
+ /* using next arg as value */
|
|
+ strcpy(*value, args[argnum + 1]);
|
|
+ if (options[match].value_type == o_VALUE_LIST) {
|
|
+ *optchar = START_VALUE_LIST;
|
|
+ } else {
|
|
+ *optchar = SKIP_VALUE_ARG;
|
|
+ }
|
|
+ } else {
|
|
+ /* no value found */
|
|
+ optionerr(options, optionerrbuf, op_req_val_err, match, 1);
|
|
+ free(arg);
|
|
+ if (depth > 0) {
|
|
+ /* unwind */
|
|
+ oWARN(optionerrbuf);
|
|
+ return o_ARG_FILE_ERR;
|
|
+ } else {
|
|
+ oWARN(optionerrbuf);
|
|
+ return o_BAD_ERR;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ } else if (options[match].value_type == o_NO_VALUE) {
|
|
+ /* this option does not accept a value */
|
|
+ if (valuestart) {
|
|
+ /* --option=value */
|
|
+ optionerr(options, optionerrbuf, op_no_allow_val_err, match, 1);
|
|
+ free(arg);
|
|
+ if (depth > 0) {
|
|
+ oWARN(optionerrbuf);
|
|
+ return o_ARG_FILE_ERR;
|
|
+ } else {
|
|
+ oWARN(optionerrbuf);
|
|
+ return o_BAD_ERR;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ free(arg);
|
|
+
|
|
+ *option_num = match;
|
|
+ return options[match].option_ID;
|
|
+}
|
|
+
|
|
+
|
|
+
|
|
+/* get_option
|
|
+ *
|
|
+ * Main interface for user. Use this function to get options, values and
|
|
+ * non-option arguments from a command line provided in argv form.
|
|
+ *
|
|
+ * To use get_option() first define valid options by setting
|
|
+ * the global variable options[] to an array of option_struct. Also
|
|
+ * either change defaults below or make variables global and set elsewhere.
|
|
+ * Zip uses below defaults.
|
|
+ *
|
|
+ * Call get_option() to get an option (like -b or --temp-file) and any
|
|
+ * value for that option (like filename for -b) or a non-option argument
|
|
+ * (like archive name) each call. If *value* is not NULL after calling
|
|
+ * get_option() it is a returned value and the caller should either store
|
|
+ * the char pointer or free() it before calling get_option() again to avoid
|
|
+ * leaking memory. If a non-option non-value argument is returned get_option()
|
|
+ * returns o_NON_OPTION_ARG and value is set to the entire argument.
|
|
+ * When there are no more arguments get_option() returns 0.
|
|
+ *
|
|
+ * The parameters argnum (after set to 0 on initial call),
|
|
+ * optchar, first_nonopt_arg, option_num, and depth (after initial
|
|
+ * call) are set and maintained by get_option() and should not be
|
|
+ * changed. The parameters argc, negated, and value are outputs and
|
|
+ * can be used by the calling program. get_option() returns either the
|
|
+ * option_ID for the current option, a special value defined in
|
|
+ * zip.h, or 0 when no more arguments.
|
|
+ *
|
|
+ * The value returned by get_option() is the ID value in the options
|
|
+ * table. This value can be duplicated in the table if different
|
|
+ * options are really the same option. The index into the options[]
|
|
+ * table is given by option_num, though the ID should be used as
|
|
+ * option numbers change when the table is changed. The ID must
|
|
+ * not be 0 for any option as this ends the table. If get_option()
|
|
+ * finds an option not in the table it calls oERR to post an
|
|
+ * error and exit. Errors also result if the option requires a
|
|
+ * value that is missing, a value is present but the option does
|
|
+ * not take one, and an option is negated but is not
|
|
+ * negatable. Non-option arguments return o_NON_OPTION_ARG
|
|
+ * with the entire argument in value.
|
|
+ *
|
|
+ * For Zip and UnZip, permuting is on and all options and their values
|
|
+ * are returned before any non-option arguments like archive name.
|
|
+ *
|
|
+ * The arguments "-" alone and "--" alone return as non-option arguments.
|
|
+ * Note that "-" should not be used as part of a short option
|
|
+ * entry in the table but can be used in the middle of long
|
|
+ * options such as in the long option "a-long-option". Now "--" alone
|
|
+ * stops option processing, returning any arguments following "--" as
|
|
+ * non-option arguments instead of options.
|
|
+ *
|
|
+ * Argument file support is removed from this version. It may be added later.
|
|
+ *
|
|
+ * After each call:
|
|
+ * argc is set to the current size of args[] but should not change
|
|
+ * with argument file support removed,
|
|
+ * argnum is the index of the current arg,
|
|
+ * value is either the value of the returned option or non-option
|
|
+ * argument or NULL if option with no value,
|
|
+ * negated is set if the option was negated by a trailing dash (-)
|
|
+ * option_num is set to either the index in options[] for the option or
|
|
+ * o_NO_OPTION_MATCH if no match.
|
|
+ * Negation is checked before the value is read if the option is negatable so
|
|
+ * that the - is not included in the value. If the option is not negatable
|
|
+ * but takes a value then the - will start the value. If permuting then
|
|
+ * argnum and first_nonopt_arg are unreliable and should not be used.
|
|
+ *
|
|
+ * Command line is read from left to right. As get_option() finds non-option
|
|
+ * arguments (arguments not starting with - and that are not values to options)
|
|
+ * it moves later options and values in front of the non-option arguments.
|
|
+ * This permuting is turned off by setting enable_permute to 0. Then
|
|
+ * get_option() will return options and non-option arguments in the order
|
|
+ * found. Currently permuting is only done after an argument is completely
|
|
+ * processed so that any value can be moved with options they go with. All
|
|
+ * state information is stored in the parameters argnum, optchar,
|
|
+ * first_nonopt_arg and option_num. You should not change these after the
|
|
+ * first call to get_option(). If you need to back up to a previous arg then
|
|
+ * set argnum to that arg (remembering that args may have been permuted) and
|
|
+ * set optchar = 0 and first_nonopt_arg to the first non-option argument if
|
|
+ * permuting. After all arguments are returned the next call to get_option()
|
|
+ * returns 0. The caller can then call free_args(args) if appropriate.
|
|
+ *
|
|
+ * get_option() accepts arguments in the following forms:
|
|
+ * short options
|
|
+ * of 1 and 2 characters, e.g. a, b, cc, d, and ba, after a single
|
|
+ * leading -, as in -abccdba. In this example if 'b' is followed by 'a'
|
|
+ * it matches short option 'ba' else it is interpreted as short option
|
|
+ * b followed by another option. The character - is not legal as a
|
|
+ * short option or as part of a 2 character short option.
|
|
+ *
|
|
+ * If a short option has a value it immediately follows the option or
|
|
+ * if that option is the end of the arg then the next arg is used as
|
|
+ * the value. So if short option e has a value, it can be given as
|
|
+ * -evalue
|
|
+ * or
|
|
+ * -e value
|
|
+ * and now
|
|
+ * -e=value
|
|
+ * but now that = is optional a leading = is stripped for the first.
|
|
+ * This change allows optional short option values to be defaulted as
|
|
+ * -e=
|
|
+ * Either optional or required values can be specified. Optional values
|
|
+ * now use both forms as ignoring the later got confusing. Any
|
|
+ * non-value short options can preceed a valued short option as in
|
|
+ * -abevalue
|
|
+ * Some value types (one_char and number) allow options after the value
|
|
+ * so if oc is an option that takes a character and n takes a number
|
|
+ * then
|
|
+ * -abocVccn42evalue
|
|
+ * returns value V for oc and value 42 for n. All values are strings
|
|
+ * so programs may have to convert the "42" to a number. See long
|
|
+ * options below for how value lists are handled.
|
|
+ *
|
|
+ * Any short option can be negated by following it with -. Any - is
|
|
+ * handled and skipped over before any value is read unless the option
|
|
+ * is not negatable but takes a value and then - starts the value.
|
|
+ *
|
|
+ * If the value for an optional value is just =, then treated as no
|
|
+ * value.
|
|
+ *
|
|
+ * long options
|
|
+ * of arbitrary length are assumed if an arg starts with -- but is not
|
|
+ * exactly --. Long options are given one per arg and can be abbreviated
|
|
+ * if the abbreviation uniquely matches one of the long options.
|
|
+ * Exact matches always match before partial matches. If ambiguous an
|
|
+ * error is generated.
|
|
+ *
|
|
+ * Values are specified either in the form
|
|
+ * --longoption=value
|
|
+ * or can be the following arg if the value is required as in
|
|
+ * --longoption value
|
|
+ * Optional values to long options must be in the first form.
|
|
+ *
|
|
+ * Value lists are specified by o_VALUE_LIST and consist of an option
|
|
+ * that takes a value followed by one or more value arguments.
|
|
+ * The two forms are
|
|
+ * --option=value
|
|
+ * or
|
|
+ * -ovalue
|
|
+ * for a single value or
|
|
+ * --option value1 value2 value3 ... --option2
|
|
+ * or
|
|
+ * -o value1 value2 value3 ...
|
|
+ * for a list of values. The list ends at the next option, the
|
|
+ * end of the command line, or at a single "@" argument.
|
|
+ * Each value is treated as if it was preceeded by the option, so
|
|
+ * --option1 val1 val2
|
|
+ * with option1 value_type set to o_VALUE_LIST is the same as
|
|
+ * --option1=val1 --option1=val2
|
|
+ *
|
|
+ * Long options can be negated by following the option with - as in
|
|
+ * --longoption-
|
|
+ * Long options with values can also be negated if this makes sense for
|
|
+ * the caller as:
|
|
+ * --longoption-=value
|
|
+ * If = is not followed by anything it is treated as no value.
|
|
+ *
|
|
+ * @path
|
|
+ * Argument files support removed from this version. It may be added
|
|
+ * back later.
|
|
+ *
|
|
+ * non-option argument
|
|
+ * is any argument not given above. If enable_permute is 1 then
|
|
+ * these are returned after all options, otherwise all options and
|
|
+ * args are returned in order. Returns option ID o_NON_OPTION_ARG
|
|
+ * and sets value to the argument.
|
|
+ *
|
|
+ *
|
|
+ * Arguments to get_option:
|
|
+ * int option_group - either UZO for UnZip or ZIO for ZipInfo
|
|
+ * char ***pargs - pointer to arg array in the argv form
|
|
+ * int *argc - returns the current argc for args incl. args[0]
|
|
+ * int *argnum - the index of the current argument (caller
|
|
+ * should set = 0 on first call and not change
|
|
+ * after that)
|
|
+ * int *optchar - index of next short opt in arg or special
|
|
+ * int *first_nonopt_arg - used by get_option to permute args
|
|
+ * int *negated - option was negated (had trailing -)
|
|
+ * char *value - value of option if any (free when done with it)
|
|
+ * or NULL
|
|
+ * int *option_num - the index in options of the last option returned
|
|
+ * (can be o_NO_OPTION_MATCH)
|
|
+ * int recursion_depth - current depth of recursion
|
|
+ * (always set to 0 by caller)
|
|
+ * (always 0 with argument files support removed)
|
|
+ *
|
|
+ * Caller should only read the returned option ID and the value, negated,
|
|
+ * and option_num (if required) parameters after each call.
|
|
+ *
|
|
+ * Ed Gordon
|
|
+ * 8/24/2003 (last updated 3/1/2008 EG)
|
|
+ *
|
|
+ */
|
|
+
|
|
+unsigned long get_option(option_group, pargs, argc, argnum, optchar, value,
|
|
+ negated, first_nonopt_arg, option_num, recursion_depth)
|
|
+ int option_group;
|
|
+ char ***pargs;
|
|
+ int *argc;
|
|
+ int *argnum;
|
|
+ int *optchar;
|
|
+ char **value;
|
|
+ int *negated;
|
|
+ int *first_nonopt_arg;
|
|
+ int *option_num;
|
|
+ int recursion_depth;
|
|
+{
|
|
+ char **args;
|
|
+ unsigned long option_ID;
|
|
+
|
|
+ int argcnt;
|
|
+ int first_nonoption_arg;
|
|
+ char *arg = NULL;
|
|
+ int h;
|
|
+ int optc;
|
|
+ int argn;
|
|
+ int j;
|
|
+ int v;
|
|
+ int read_rest_args_verbatim = 0; /* 7/25/04 - ignore options and arg files for rest args */
|
|
+
|
|
+ /* caller should free value or assign it to another
|
|
+ variable before calling get_option again. */
|
|
+ *value = NULL;
|
|
+
|
|
+ /* if args is NULL then done */
|
|
+ if (pargs == NULL) {
|
|
+ *argc = 0;
|
|
+ return 0;
|
|
+ }
|
|
+ args = *pargs;
|
|
+ if (args == NULL) {
|
|
+ *argc = 0;
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ /* count args */
|
|
+ for (argcnt = 0; args[argcnt]; argcnt++) ;
|
|
+
|
|
+ /* if no provided args then nothing to do */
|
|
+ if (argcnt < 1 || (recursion_depth == 0 && argcnt < 2)) {
|
|
+ *argc = argcnt;
|
|
+ /* return 0 to note that no args are left */
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ *negated = 0;
|
|
+ first_nonoption_arg = *first_nonopt_arg;
|
|
+ argn = *argnum;
|
|
+ optc = *optchar;
|
|
+
|
|
+ if (optc == READ_REST_ARGS_VERBATIM) {
|
|
+ read_rest_args_verbatim = 1;
|
|
+ }
|
|
+
|
|
+ if (argn == -1 || (recursion_depth == 0 && argn == 0)) {
|
|
+ /* first call */
|
|
+ /* if depth = 0 then args[0] is argv[0] so skip */
|
|
+ *option_num = o_NO_OPTION_MATCH;
|
|
+ optc = THIS_ARG_DONE;
|
|
+ first_nonoption_arg = -1;
|
|
+ }
|
|
+
|
|
+ /* if option_num is set then restore last option_ID in case continuing
|
|
+ value list */
|
|
+ option_ID = 0;
|
|
+ if (*option_num != o_NO_OPTION_MATCH) {
|
|
+ option_ID = options[*option_num].option_ID;
|
|
+ }
|
|
+
|
|
+ /* get next option if any */
|
|
+ for (;;) {
|
|
+ if (read_rest_args_verbatim) {
|
|
+ /* rest of args after "--" are non-option args if doubledash_ends_options
|
|
+ set */
|
|
+ argn++;
|
|
+ if (argn > argcnt || args[argn] == NULL) {
|
|
+ /* done */
|
|
+ option_ID = 0;
|
|
+ break;
|
|
+ }
|
|
+ arg = args[argn];
|
|
+ if ((*value = (char *)malloc(strlen(arg) + 1)) == NULL) {
|
|
+ oWARN("memory - go");
|
|
+ return o_BAD_ERR;
|
|
+ }
|
|
+ strcpy(*value, arg);
|
|
+ *option_num = o_NO_OPTION_MATCH;
|
|
+ option_ID = o_NON_OPTION_ARG;
|
|
+ break;
|
|
+
|
|
+ /* permute non-option args after option args so options are returned
|
|
+ first */
|
|
+ } else if (enable_permute) {
|
|
+ if (optc == SKIP_VALUE_ARG || optc == THIS_ARG_DONE ||
|
|
+ optc == START_VALUE_LIST || optc == IN_VALUE_LIST ||
|
|
+ optc == STOP_VALUE_LIST) {
|
|
+ /* moved to new arg */
|
|
+ if (first_nonoption_arg > -1 && args[first_nonoption_arg]) {
|
|
+ /* do the permuting - move non-options after this option */
|
|
+ /* if option and value separate args or starting list skip option */
|
|
+ if (optc == SKIP_VALUE_ARG || optc == START_VALUE_LIST) {
|
|
+ v = 1;
|
|
+ } else {
|
|
+ v = 0;
|
|
+ }
|
|
+ for (h = first_nonoption_arg; h < argn; h++) {
|
|
+ arg = args[first_nonoption_arg];
|
|
+ for (j = first_nonoption_arg; j < argn + v; j++) {
|
|
+ args[j] = args[j + 1];
|
|
+ }
|
|
+ args[j] = arg;
|
|
+ }
|
|
+ first_nonoption_arg += 1 + v;
|
|
+ }
|
|
+ }
|
|
+ } else if (optc == NON_OPTION_ARG) {
|
|
+ /* if not permuting then already returned arg */
|
|
+ optc = THIS_ARG_DONE;
|
|
+ }
|
|
+
|
|
+ /* value lists */
|
|
+ if (optc == STOP_VALUE_LIST) {
|
|
+ optc = THIS_ARG_DONE;
|
|
+ }
|
|
+
|
|
+ if (optc == START_VALUE_LIST || optc == IN_VALUE_LIST) {
|
|
+ if (optc == START_VALUE_LIST) {
|
|
+ /* already returned first value */
|
|
+ argn++;
|
|
+ optc = IN_VALUE_LIST;
|
|
+ }
|
|
+ argn++;
|
|
+ arg = args[argn];
|
|
+ /* if end of args and still in list and there are non-option args then
|
|
+ terminate list */
|
|
+ if (arg == NULL && (optc == START_VALUE_LIST || optc == IN_VALUE_LIST)
|
|
+ && first_nonoption_arg > -1) {
|
|
+ /* terminate value list with @ */
|
|
+ /* this is only needed for argument files */
|
|
+ /* but is also good for show command line so command lines with lists
|
|
+ can always be read back in */
|
|
+ argcnt = insert_arg(&args, "@", first_nonoption_arg, 1);
|
|
+ argn++;
|
|
+ if (first_nonoption_arg > -1) {
|
|
+ first_nonoption_arg++;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ arg = args[argn];
|
|
+ if (arg && arg[0] == '@' && arg[1] == '\0') {
|
|
+ /* inserted arguments terminator */
|
|
+ optc = STOP_VALUE_LIST;
|
|
+ continue;
|
|
+ } else if (arg && arg[0] != '-') { /* not option */
|
|
+ /* - and -- are not allowed in value lists unless escaped */
|
|
+ /* another value in value list */
|
|
+ if ((*value = (char *)malloc(strlen(args[argn]) + 1)) == NULL) {
|
|
+ oWARN("memory - go");
|
|
+ return o_BAD_ERR;
|
|
+ }
|
|
+ strcpy(*value, args[argn]);
|
|
+ break;
|
|
+
|
|
+ } else {
|
|
+ argn--;
|
|
+ optc = THIS_ARG_DONE;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /* move to next arg */
|
|
+ if (optc == SKIP_VALUE_ARG) {
|
|
+ argn += 2;
|
|
+ optc = 0;
|
|
+ } else if (optc == THIS_ARG_DONE) {
|
|
+ argn++;
|
|
+ optc = 0;
|
|
+ }
|
|
+ if (argn > argcnt) {
|
|
+ break;
|
|
+ }
|
|
+ if (args[argn] == NULL) {
|
|
+ /* done unless permuting and non-option args */
|
|
+ if (first_nonoption_arg > -1 && args[first_nonoption_arg]) {
|
|
+ /* return non-option arguments at end */
|
|
+ if (optc == NON_OPTION_ARG) {
|
|
+ first_nonoption_arg++;
|
|
+ }
|
|
+ /* after first pass args are permuted but skipped over non-option
|
|
+ args */
|
|
+ /* swap so argn points to first non-option arg */
|
|
+ j = argn;
|
|
+ argn = first_nonoption_arg;
|
|
+ first_nonoption_arg = j;
|
|
+ }
|
|
+ if (argn > argcnt || args[argn] == NULL) {
|
|
+ /* done */
|
|
+ option_ID = 0;
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /* after swap first_nonoption_arg points to end which is NULL */
|
|
+ if (first_nonoption_arg > -1 && (args[first_nonoption_arg] == NULL)) {
|
|
+ /* only non-option args left */
|
|
+ if (optc == NON_OPTION_ARG) {
|
|
+ argn++;
|
|
+ }
|
|
+ if (argn > argcnt || args[argn] == NULL) {
|
|
+ /* done */
|
|
+ option_ID = 0;
|
|
+ break;
|
|
+ }
|
|
+ if ((*value = (char *)malloc(strlen(args[argn]) + 1)) == NULL) {
|
|
+ oWARN("memory - go");
|
|
+ return o_BAD_ERR;
|
|
+ }
|
|
+ strcpy(*value, args[argn]);
|
|
+ optc = NON_OPTION_ARG;
|
|
+ option_ID = o_NON_OPTION_ARG;
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ arg = args[argn];
|
|
+
|
|
+ /* is it an option */
|
|
+ if (arg[0] == '-') {
|
|
+ /* option */
|
|
+ if (arg[1] == '\0') {
|
|
+ /* arg = - */
|
|
+ /* treat like non-option arg */
|
|
+ *option_num = o_NO_OPTION_MATCH;
|
|
+ if (enable_permute) {
|
|
+ /* permute args to move all non-option args to end */
|
|
+ if (first_nonoption_arg < 0) {
|
|
+ first_nonoption_arg = argn;
|
|
+ }
|
|
+ argn++;
|
|
+ } else {
|
|
+ /* not permute args so return non-option args when found */
|
|
+ if ((*value = (char *)malloc(strlen(arg) + 1)) == NULL) {
|
|
+ oWARN("memory - go");
|
|
+ return o_BAD_ERR;
|
|
+ }
|
|
+ strcpy(*value, arg);
|
|
+ optc = NON_OPTION_ARG;
|
|
+ option_ID = o_NON_OPTION_ARG;
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ } else if (arg[1] == '-') {
|
|
+ /* long option */
|
|
+ if (arg[2] == '\0') {
|
|
+ /* arg = -- */
|
|
+ if (doubledash_ends_options) {
|
|
+ /* Now -- stops permuting and forces the rest of
|
|
+ the command line to be read verbatim - 7/25/04 EG */
|
|
+
|
|
+ /* never permute args after -- and return as non-option args */
|
|
+ if (first_nonoption_arg < 1) {
|
|
+ /* -- is first non-option argument - 8/7/04 EG */
|
|
+ argn--;
|
|
+ } else {
|
|
+ /* go back to start of non-option args - 8/7/04 EG */
|
|
+ argn = first_nonoption_arg - 1;
|
|
+ }
|
|
+
|
|
+ /* disable permuting and treat remaining arguments as not
|
|
+ options */
|
|
+ read_rest_args_verbatim = 1;
|
|
+ optc = READ_REST_ARGS_VERBATIM;
|
|
+
|
|
+ } else {
|
|
+ /* treat like non-option arg */
|
|
+ *option_num = o_NO_OPTION_MATCH;
|
|
+ if (enable_permute) {
|
|
+ /* permute args to move all non-option args to end */
|
|
+ if (first_nonoption_arg < 0) {
|
|
+ first_nonoption_arg = argn;
|
|
+ }
|
|
+ argn++;
|
|
+ } else {
|
|
+ /* not permute args so return non-option args when found */
|
|
+ if ((*value = (char *)malloc(strlen(arg) + 1)) == NULL) {
|
|
+ oWARN("memory - go");
|
|
+ return o_BAD_ERR;
|
|
+ }
|
|
+ strcpy(*value, arg);
|
|
+ optc = NON_OPTION_ARG;
|
|
+ option_ID = o_NON_OPTION_ARG;
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ } else {
|
|
+ option_ID = get_longopt(option_group, (ZCONST char **)args, argn,
|
|
+ &optc, negated,
|
|
+ value, option_num, recursion_depth);
|
|
+ if (option_ID == o_BAD_ERR) {
|
|
+ return o_BAD_ERR;
|
|
+ } else if (option_ID == o_ARG_FILE_ERR) {
|
|
+ /* unwind as only get this if recursion_depth > 0 */
|
|
+ return option_ID;
|
|
+ }
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ } else {
|
|
+ /* short option */
|
|
+ option_ID = get_shortopt(option_group, (ZCONST char **)args, argn,
|
|
+ &optc, negated,
|
|
+ value, option_num, recursion_depth);
|
|
+
|
|
+ if (option_ID == o_BAD_ERR) {
|
|
+ return o_BAD_ERR;
|
|
+ } else if (option_ID == o_ARG_FILE_ERR) {
|
|
+ /* unwind as only get this if recursion_depth > 0 */
|
|
+ return option_ID;
|
|
+ }
|
|
+
|
|
+ if (optc == 0) {
|
|
+ /* if optc = 0 then ran out of short opts this arg */
|
|
+ optc = THIS_ARG_DONE;
|
|
+ } else {
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+
|
|
+#if 0
|
|
+ /* argument file code left out
|
|
+ so for now let filenames start with @
|
|
+ */
|
|
+
|
|
+ } else if (allow_arg_files && arg[0] == '@') {
|
|
+ /* arg file */
|
|
+ oERR(PK_PARMS, no_arg_files_err);
|
|
+#endif
|
|
+
|
|
+ } else {
|
|
+ /* non-option */
|
|
+ if (enable_permute) {
|
|
+ /* permute args to move all non-option args to end */
|
|
+ if (first_nonoption_arg < 0) {
|
|
+ first_nonoption_arg = argn;
|
|
+ }
|
|
+ argn++;
|
|
+ } else {
|
|
+ /* no permute args so return non-option args when found */
|
|
+ if ((*value = (char *)malloc(strlen(arg) + 1)) == NULL) {
|
|
+ oWARN("memory - go");
|
|
+ return o_BAD_ERR;
|
|
+ }
|
|
+ strcpy(*value, arg);
|
|
+ *option_num = o_NO_OPTION_MATCH;
|
|
+ optc = NON_OPTION_ARG;
|
|
+ option_ID = o_NON_OPTION_ARG;
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ }
|
|
+ }
|
|
+
|
|
+ *pargs = args;
|
|
+ *argc = argcnt;
|
|
+ *first_nonopt_arg = first_nonoption_arg;
|
|
+ *argnum = argn;
|
|
+ *optchar = optc;
|
|
+
|
|
+ return option_ID;
|
|
+}
|
|
diff -ru2 unz60e03/unzpriv.h u6e3_np/unzpriv.h
|
|
--- unz60e03/unzpriv.h Mon Mar 24 11:53:24 2008
|
|
+++ u6e3_np/unzpriv.h Mon Mar 24 14:13:02 2008
|
|
@@ -1271,4 +1271,89 @@
|
|
#endif
|
|
|
|
+
|
|
+/*--------------------------------------------------------------------
|
|
+ Long option support
|
|
+ 23 August 2003
|
|
+ Updated for UnZip 1 March 2008
|
|
+ See unzip.c
|
|
+ --------------------------------------------------------------------*/
|
|
+
|
|
+/* The below is for use in the caller-provided options table */
|
|
+
|
|
+/* option groups */
|
|
+#define UZO 1 /* UnZip option */
|
|
+#define ZIO 2 /* ZipInfo option */
|
|
+
|
|
+
|
|
+/* value_type - value is always returned as a string. */
|
|
+#define o_NO_VALUE 0 /* this option does not take a value */
|
|
+#define o_REQUIRED_VALUE 1 /* this option requires a value */
|
|
+#define o_OPTIONAL_VALUE 2 /* value is optional (see get_option() for details) */
|
|
+#define o_VALUE_LIST 3 /* this option takes a list of values */
|
|
+#define o_ONE_CHAR_VALUE 4 /* next char is value (does not end short opt string) */
|
|
+#define o_NUMBER_VALUE 5 /* value is integer (does not end short opt string) */
|
|
+
|
|
+
|
|
+/* negatable - a dash following the option (but before any value) sets negated. */
|
|
+#define o_NOT_NEGATABLE 0 /* trailing '-' to negate either starts value or generates error */
|
|
+#define o_NEGATABLE 1 /* trailing '-' sets negated to TRUE */
|
|
+
|
|
+
|
|
+/* option_num can be this when option not in options table */
|
|
+#define o_NO_OPTION_MATCH -1
|
|
+
|
|
+/* special values returned by get_option - do not use these as option IDs */
|
|
+#define o_NON_OPTION_ARG ((unsigned long) 0xFFFF) /* returned for non-option
|
|
+ args */
|
|
+#define o_ARG_FILE_ERR ((unsigned long) 0xFFFE) /* internal recursion
|
|
+ return (user never sees) */
|
|
+#define o_BAD_ERR ((unsigned long) 0xFFFD) /* bad error */
|
|
+
|
|
+/* options array is set in unzip.c */
|
|
+struct option_struct {
|
|
+ int option_group; /* either UZO for UnZip or ZIO for ZipInfo syntax */
|
|
+ char Far *shortopt; /* pointer to short option string */
|
|
+ char Far *longopt; /* pointer to long option string */
|
|
+ int value_type; /* from above */
|
|
+ int negatable; /* from above */
|
|
+ unsigned long option_ID; /* value returned by get_option when this option
|
|
+ is found */
|
|
+ char Far *name; /* optional string for option returned on some
|
|
+ errors */
|
|
+};
|
|
+
|
|
+/* structure used to create -x and include file lists */
|
|
+struct file_list {
|
|
+ char *name;
|
|
+ struct file_list *next;
|
|
+};
|
|
+
|
|
+
|
|
+/* function prototypes */
|
|
+
|
|
+/* get the next option from args */
|
|
+unsigned long get_option OF((int option_group,
|
|
+ char ***pargs, int *argc, int *argnum,
|
|
+ int *optchar,
|
|
+ char **value, int *negated, int *first_nonopt_arg,
|
|
+ int *option_num, int recursion_depth));
|
|
+
|
|
+/* copy args - copy an args array, allocating space as needed */
|
|
+char **copy_args OF((char **args, int max_args));
|
|
+
|
|
+/* arg count - count args in argv like array */
|
|
+int arg_count OF((char **args));
|
|
+
|
|
+/* free args - free args created with one of these functions */
|
|
+int free_args OF((char **args));
|
|
+
|
|
+/* insert arg - copy an arg into args */
|
|
+int insert_arg OF((char ***args, ZCONST char *arg, int insert_at,
|
|
+ int free_args));
|
|
+
|
|
+/*--------------------------------------------------------------------
|
|
+ End of Long option support
|
|
+ --------------------------------------------------------------------*/
|
|
+
|
|
/***********************************/
|
|
/* LARGE_FILE_SUPPORT */
|
|
diff -ru2 unz60e03/vms/cmdline.c u6e3_np/vms/cmdline.c
|
|
--- unz60e03/vms/cmdline.c Tue Feb 12 01:37:42 2008
|
|
+++ u6e3_np/vms/cmdline.c Mon Mar 24 14:13:10 2008
|
|
@@ -34,4 +34,6 @@
|
|
** Modified by:
|
|
**
|
|
+** 02-014 E. Gordon 10-Mar-2008 03:12
|
|
+** Modified to work with get_options().
|
|
** 02-013 S. Schweda, C. Spieler 29-Dec-2007 03:34
|
|
** Extended /RESTORE qualifier to support timestamp restoration
|
|
@@ -172,10 +174,10 @@
|
|
$DESCRIPTOR(cli_text_auto, "TEXT.AUTO"); /* -a */
|
|
$DESCRIPTOR(cli_text_all, "TEXT.ALL"); /* -aa */
|
|
-$DESCRIPTOR(cli_text_none, "TEXT.NONE"); /* ---a */
|
|
+$DESCRIPTOR(cli_text_none, "TEXT.NONE"); /* -a- */
|
|
$DESCRIPTOR(cli_text_stmlf, "TEXT.STMLF"); /* -S */
|
|
$DESCRIPTOR(cli_binary, "BINARY"); /* -b[b] */
|
|
$DESCRIPTOR(cli_binary_auto, "BINARY.AUTO"); /* -b */
|
|
$DESCRIPTOR(cli_binary_all, "BINARY.ALL"); /* -bb */
|
|
-$DESCRIPTOR(cli_binary_none, "BINARY.NONE"); /* ---b */
|
|
+$DESCRIPTOR(cli_binary_none, "BINARY.NONE"); /* -b- */
|
|
$DESCRIPTOR(cli_case_insensitive,"CASE_INSENSITIVE"); /* -C */
|
|
$DESCRIPTOR(cli_screen, "SCREEN"); /* -c */
|
|
@@ -202,5 +204,5 @@
|
|
$DESCRIPTOR(cli_restore_own, "RESTORE.OWNER_PROT"); /* -X */
|
|
$DESCRIPTOR(cli_restore_date, "RESTORE.DATE"); /* -DD */
|
|
-$DESCRIPTOR(cli_restore_date_all, "RESTORE.DATE.ALL"); /* --D */
|
|
+$DESCRIPTOR(cli_restore_date_all, "RESTORE.DATE.ALL"); /* -D- */
|
|
$DESCRIPTOR(cli_restore_date_files, "RESTORE.DATE.FILES"); /* -D */
|
|
$DESCRIPTOR(cli_dot_version, "DOT_VERSION"); /* -Y */
|
|
@@ -299,4 +301,6 @@
|
|
** SS$_ABORT - Bad time value
|
|
**
|
|
+** Modified to work with the get_option() command line parser. 10 March 2008
|
|
+**
|
|
*/
|
|
register unsigned long status;
|
|
@@ -419,5 +423,4 @@
|
|
if (status != CLI$_ABSENT) {
|
|
*ptr++ = '-';
|
|
- *ptr++ = '-';
|
|
*ptr++ = 'b';
|
|
if ((status & 1) &&
|
|
@@ -427,4 +430,5 @@
|
|
*ptr++ = 'b';
|
|
}
|
|
+ *ptr++ = '-';
|
|
}
|
|
|
|
@@ -436,5 +440,4 @@
|
|
if (status != CLI$_ABSENT) {
|
|
*ptr++ = '-';
|
|
- *ptr++ = '-';
|
|
*ptr++ = 'a';
|
|
if ((status & 1) &&
|
|
@@ -446,4 +449,5 @@
|
|
*ptr++ = 'S';
|
|
}
|
|
+ *ptr++ = '-';
|
|
}
|
|
|
|
diff -ru2 unz60e03/zipinfo.c u6e3_np/zipinfo.c
|
|
--- unz60e03/zipinfo.c Mon Mar 24 14:23:54 2008
|
|
+++ u6e3_np/zipinfo.c Mon Mar 24 14:25:24 2008
|
|
@@ -171,4 +171,6 @@
|
|
static ZCONST char Far ZipfileCommTruncMsg[] =
|
|
"\ncaution: zipfile comment truncated\n";
|
|
+static ZCONST char Far NoMemArguments[] =
|
|
+ "envargs: cannot get memory for arguments";
|
|
|
|
static ZCONST char Far CentralDirEntry[] =
|
|
@@ -459,10 +461,48 @@
|
|
__GDEF
|
|
{
|
|
- char **argv, *s;
|
|
- int argc, c, error=FALSE, negative=0;
|
|
+ int argc, error=FALSE;
|
|
int hflag_slmv=TRUE, hflag_2=FALSE; /* diff options => diff defaults */
|
|
int tflag_slm=TRUE, tflag_2v=FALSE;
|
|
int explicit_h=FALSE, explicit_t=FALSE;
|
|
|
|
+ char **args;
|
|
+
|
|
+
|
|
+ /* used by get_option */
|
|
+ unsigned long option; /* option ID returned by get_option */
|
|
+ int argcnt = 0; /* current argcnt in args */
|
|
+ int argnum = 0; /* arg number */
|
|
+ int optchar = 0; /* option state */
|
|
+ char *value = NULL; /* non-option arg, option value or NULL */
|
|
+ int negative = 0; /* 1 = option negated */
|
|
+ int fna = 0; /* current first non-opt arg */
|
|
+ int optnum = 0; /* index in table */
|
|
+
|
|
+
|
|
+ /* since get_option() returns xfiles and files one at a time, store them in
|
|
+ linked lists until have them all */
|
|
+
|
|
+ int file_count;
|
|
+ struct file_list *next_file;
|
|
+
|
|
+ /* files to extract */
|
|
+ int in_files_count = 0;
|
|
+ struct file_list *in_files = NULL;
|
|
+ struct file_list *next_in_files = NULL;
|
|
+
|
|
+ /* files to exclude in -x list */
|
|
+ int in_xfiles_count = 0;
|
|
+ struct file_list *in_xfiles = NULL;
|
|
+ struct file_list *next_in_xfiles = NULL;
|
|
+
|
|
+ G.wildzipfn = NULL;
|
|
+
|
|
+ /* make copy of args that can use with insert_arg() used by get_option() */
|
|
+ args = copy_args(*pargv, 0);
|
|
+
|
|
+
|
|
+ /* Initialize lists */
|
|
+ G.filespecs = 0;
|
|
+ G.xfilespecs = 0;
|
|
|
|
#ifdef MACOS
|
|
@@ -470,17 +510,41 @@
|
|
#endif
|
|
G.extract_flag = FALSE; /* zipinfo does not extract to disk */
|
|
- argc = *pargc;
|
|
- argv = *pargv;
|
|
|
|
- while (--argc > 0 && (*++argv)[0] == '-') {
|
|
- s = argv[0] + 1;
|
|
- while ((c = *s++) != 0) { /* "!= 0": prevent Turbo C warning */
|
|
- switch (c) {
|
|
- case '-':
|
|
- ++negative;
|
|
- break;
|
|
+
|
|
+ /*
|
|
+ -------------------------------------------
|
|
+ Process command line using get_option
|
|
+ -------------------------------------------
|
|
+
|
|
+ Each call to get_option() returns either a command
|
|
+ line option and possible value or a non-option argument.
|
|
+ Arguments are permuted so that all options (-r, -b temp)
|
|
+ are returned before non-option arguments (zipfile).
|
|
+ Returns 0 when nothing left to read.
|
|
+ */
|
|
+
|
|
+ /* set argnum = 0 on first call to init get_option */
|
|
+ argnum = 0;
|
|
+
|
|
+ /* get_option returns the option ID and updates parameters:
|
|
+ args - usually same as argv if no argument file support
|
|
+ argcnt - current argc for args
|
|
+ value - char* to value (free() when done with it) or NULL if no value
|
|
+ negated - option was negated with trailing -
|
|
+ */
|
|
+
|
|
+ while ((option = get_option(ZIO, &args, &argcnt, &argnum,
|
|
+ &optchar, &value, &negative,
|
|
+ &fna, &optnum, 0)))
|
|
+ {
|
|
+ if(option == o_BAD_ERR) {
|
|
+ return(PK_PARAM);
|
|
+ }
|
|
+
|
|
+ switch (option)
|
|
+ {
|
|
case '1': /* shortest listing: JUST filenames */
|
|
if (negative)
|
|
- uO.lflag = -2, negative = 0;
|
|
+ uO.lflag = -2;
|
|
else
|
|
uO.lflag = 1;
|
|
@@ -488,5 +552,5 @@
|
|
case '2': /* just filenames, plus headers if specified */
|
|
if (negative)
|
|
- uO.lflag = -2, negative = 0;
|
|
+ uO.lflag = -2;
|
|
else
|
|
uO.lflag = 2;
|
|
@@ -495,5 +559,5 @@
|
|
case ('C'): /* -C: match filenames case-insensitively */
|
|
if (negative)
|
|
- uO.C_flag = FALSE, negative = 0;
|
|
+ uO.C_flag = FALSE;
|
|
else
|
|
uO.C_flag = TRUE;
|
|
@@ -502,5 +566,5 @@
|
|
case 'h': /* header line */
|
|
if (negative)
|
|
- hflag_2 = hflag_slmv = FALSE, negative = 0;
|
|
+ hflag_2 = hflag_slmv = FALSE;
|
|
else {
|
|
hflag_2 = hflag_slmv = explicit_h = TRUE;
|
|
@@ -511,5 +575,5 @@
|
|
case 'l': /* longer form of "ls -l" type listing */
|
|
if (negative)
|
|
- uO.lflag = -2, negative = 0;
|
|
+ uO.lflag = -2;
|
|
else
|
|
uO.lflag = 5;
|
|
@@ -517,5 +581,5 @@
|
|
case 'm': /* medium form of "ls -l" type listing */
|
|
if (negative)
|
|
- uO.lflag = -2, negative = 0;
|
|
+ uO.lflag = -2;
|
|
else
|
|
uO.lflag = 4;
|
|
@@ -524,5 +588,5 @@
|
|
case 'M': /* send output through built-in "more" */
|
|
if (negative)
|
|
- G.M_flag = FALSE, negative = 0;
|
|
+ G.M_flag = FALSE;
|
|
else
|
|
G.M_flag = TRUE;
|
|
@@ -531,5 +595,5 @@
|
|
case 's': /* default: shorter "ls -l" type listing */
|
|
if (negative)
|
|
- uO.lflag = -2, negative = 0;
|
|
+ uO.lflag = -2;
|
|
else
|
|
uO.lflag = 3;
|
|
@@ -537,5 +601,5 @@
|
|
case 't': /* totals line */
|
|
if (negative)
|
|
- tflag_2v = tflag_slm = FALSE, negative = 0;
|
|
+ tflag_2v = tflag_slm = FALSE;
|
|
else {
|
|
tflag_2v = tflag_slm = explicit_t = TRUE;
|
|
@@ -546,5 +610,5 @@
|
|
case ('T'): /* use (sortable) decimal time format */
|
|
if (negative)
|
|
- uO.T_flag = FALSE, negative = 0;
|
|
+ uO.T_flag = FALSE;
|
|
else
|
|
uO.T_flag = TRUE;
|
|
@@ -552,8 +616,7 @@
|
|
#ifdef UNICODE_SUPPORT
|
|
case ('U'): /* escape UTF-8, or disable UTF-8 support */
|
|
- if (negative) {
|
|
- uO.U_flag = MAX(uO.U_flag-negative,0);
|
|
- negative = 0;
|
|
- } else
|
|
+ if (negative)
|
|
+ uO.U_flag = MAX(uO.U_flag - 1, 0);
|
|
+ else
|
|
uO.U_flag++;
|
|
break;
|
|
@@ -561,5 +624,5 @@
|
|
case 'v': /* turbo-verbose listing */
|
|
if (negative)
|
|
- uO.lflag = -2, negative = 0;
|
|
+ uO.lflag = -2;
|
|
else
|
|
uO.lflag = 10;
|
|
@@ -568,12 +631,36 @@
|
|
case ('W'): /* Wildcard interpretation (stop at '/'?) */
|
|
if (negative)
|
|
- uO.W_flag = FALSE, negative = 0;
|
|
+ uO.W_flag = FALSE;
|
|
else
|
|
uO.W_flag = TRUE;
|
|
break;
|
|
#endif /* WILD_STOP_AT_DIR */
|
|
+ case ('x'): /* extract: default */
|
|
+ /* add -x file to linked list */
|
|
+
|
|
+ if (in_xfiles_count == 0) {
|
|
+ /* first entry */
|
|
+ if ((in_xfiles = (struct file_list *) malloc(sizeof(struct file_list))) == NULL) {
|
|
+ Info(slide, 0x401, ((char *)slide, LoadFarString(NoMemArguments)));
|
|
+ return PK_MEM;
|
|
+ }
|
|
+ in_xfiles->name = value;
|
|
+ in_xfiles->next = NULL;
|
|
+ next_in_xfiles = in_xfiles;
|
|
+ } else {
|
|
+ /* add next entry */
|
|
+ if ((next_file = (struct file_list *) malloc(sizeof(struct file_list))) == NULL) {
|
|
+ Info(slide, 0x401, ((char *)slide, LoadFarString(NoMemArguments)));
|
|
+ return PK_MEM;
|
|
+ }
|
|
+ next_in_xfiles->next = next_file;
|
|
+ next_file->name = value;
|
|
+ next_file->next = NULL;
|
|
+ next_in_xfiles = next_file;
|
|
+ }
|
|
+ in_xfiles_count++;
|
|
case 'z': /* print zipfile comment */
|
|
if (negative)
|
|
- uO.zflag = negative = 0;
|
|
+ uO.zflag = 0;
|
|
else
|
|
uO.zflag = 1;
|
|
@@ -581,13 +668,96 @@
|
|
case 'Z': /* ZipInfo mode: ignore */
|
|
break;
|
|
+ case o_NON_OPTION_ARG:
|
|
+ /* not an option */
|
|
+ /* no more options as permuting */
|
|
+
|
|
+
|
|
+ if (G.wildzipfn == NULL) {
|
|
+ /* first non-option argument is zip file */
|
|
+ G.wildzipfn = value;
|
|
+
|
|
+ } else {
|
|
+ /* add include file to list */
|
|
+ if (in_files_count == 0) {
|
|
+ /* first entry */
|
|
+ if ((next_file = (struct file_list *) malloc(sizeof(struct file_list))) == NULL) {
|
|
+ Info(slide, 0x401, ((char *)slide, LoadFarString(NoMemArguments)));
|
|
+ return PK_MEM;
|
|
+ }
|
|
+ next_file->name = value;
|
|
+ next_file->next = NULL;
|
|
+ in_files = next_file;
|
|
+ next_in_files = next_file;
|
|
+ } else {
|
|
+ /* add next entry */
|
|
+ if ((next_file = (struct file_list *) malloc(sizeof(struct file_list))) == NULL) {
|
|
+ Info(slide, 0x401, ((char *)slide, LoadFarString(NoMemArguments)));
|
|
+ return PK_MEM;
|
|
+ }
|
|
+ next_in_files->next = next_file;
|
|
+ next_file->name = value;
|
|
+ next_file->next = NULL;
|
|
+ next_in_files = next_file;
|
|
+ }
|
|
+ in_files_count++;
|
|
+ }
|
|
+ break;
|
|
default:
|
|
error = TRUE;
|
|
break;
|
|
- }
|
|
- }
|
|
+ } /* switch */
|
|
+ } /* get_option() */
|
|
+
|
|
+ /* convert files and xfiles lists to arrays */
|
|
+
|
|
+ /* convert files list to array */
|
|
+ if (in_files_count) {
|
|
+ if ((G.pfnames = (char **) malloc((in_files_count + 1) * sizeof(char *))) == NULL) {
|
|
+ Info(slide, 0x401, ((char *)slide, LoadFarString(NoMemArguments)));
|
|
+ return PK_MEM;
|
|
+ }
|
|
+ file_count = 0;
|
|
+ for (next_file = in_files; next_file;) {
|
|
+ G.pfnames[file_count] = next_file->name;
|
|
+ in_files = next_file;
|
|
+ next_file = next_file->next;
|
|
+ free(in_files);
|
|
+ file_count++;
|
|
+ }
|
|
+ G.pfnames[file_count] = NULL;
|
|
+ G.filespecs = in_files_count;
|
|
+ }
|
|
+
|
|
+ /* convert xfiles list to array */
|
|
+ if (in_xfiles_count) {
|
|
+ if ((G.pxnames = (char **) malloc((in_xfiles_count + 1) * sizeof(char *))) == NULL) {
|
|
+ Info(slide, 0x401, ((char *)slide, LoadFarString(NoMemArguments)));
|
|
+ return PK_MEM;
|
|
+ }
|
|
+ file_count = 0;
|
|
+ for (next_file = in_xfiles; next_file;) {
|
|
+ G.pxnames[file_count] = next_file->name;
|
|
+ in_xfiles = next_file;
|
|
+ next_file = next_file->next;
|
|
+ free(in_xfiles);
|
|
+ file_count++;
|
|
+ }
|
|
+ G.pxnames[file_count] = NULL;
|
|
+ G.xfilespecs = in_xfiles_count;
|
|
}
|
|
- if ((argc-- == 0) || error) {
|
|
+
|
|
+ if (in_files_count || in_xfiles_count) {
|
|
+ G.process_all_files = FALSE;
|
|
+ } else {
|
|
+ G.process_all_files = TRUE; /* for speed */
|
|
+ }
|
|
+
|
|
+ /* it's possible the arg count could have been changed by get_option() */
|
|
+ argc = arg_count(args);
|
|
+
|
|
+ if ((G.wildzipfn == NULL) || error) {
|
|
+ argc = -1; /* tell the caller to stop processing */
|
|
*pargc = argc;
|
|
- *pargv = argv;
|
|
+ *pargv = args;
|
|
return USAGE(error);
|
|
}
|
|
@@ -628,5 +798,5 @@
|
|
|
|
*pargc = argc;
|
|
- *pargv = argv;
|
|
+ *pargv = args;
|
|
return 0;
|
|
|