0,0 → 1,3476 |
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; |
|