Copyright (c) 1990-2000 Info-ZIP. All rights reserved.
See the accompanying file LICENSE, version 2000-Apr-09 or later
(the contents of which are also included in unzip.h) for terms of use.
If, for some reason, all these files are missing, the Info-ZIP license
also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
*/
| envargs - add default options from environment to command line
|----------------------------------------------------------------
| Author: Bill Davidsen, original 10/13/91, revised 23 Oct 1991.
| This program is in the public domain.
|----------------------------------------------------------------
| Minor program notes:
| 1. Yes, the indirection is a tad complex
| 2. Parentheses were added where not needed in some cases
| to make the action of the code less obscure.
|----------------------------------------------------------------
| UnZip notes: 24 May 92 ("v1.4"):
| 1. #include "unzip.h" for prototypes (24 May 92)
| 2. changed ch to type char (24 May 92)
| 3. added an ifdef to avoid Borland warnings (24 May 92)
| 4. included Rich Wales' mksargs() routine (for MS-DOS, maybe
| OS/2? NT?) (4 Dec 93)
| 5. added alternate-variable string envstr2 (21 Apr 94)
| 6. added support for quoted arguments (6 Jul 96)
*----------------------------------------------------------------*/
#define __ENVARGS_C
#define UNZIP_INTERNAL
#include "unzip.h"
#ifdef __EMX__
# define ISspace(c) ((c) & 0x80 ? 0 : isspace((unsigned)c))
#else
# define ISspace(c) isspace((unsigned)c)
#endif
static int count_args OF((ZCONST char *));
int envargs(Pargc, Pargv, envstr, envstr2)
int *Pargc;
char ***Pargv;
ZCONST char *envstr, *envstr2;
{
#ifndef RISCOS
char *getenv();
#endif
char *envptr;
char *bufptr;
int argc = 0;
register int ch;
char **argv;
char **argvect;
if ((envptr = getenv(envstr)) != (char *)NULL)
while (ISspace(*envptr))
envptr++;
if (envptr == (char *)NULL || *envptr == '\0')
if ((envptr = getenv(envstr2)) != (char *)NULL)
while (ISspace(*envptr))
envptr++;
if (envptr == (char *)NULL || *envptr == '\0')
return PK_OK;
bufptr = malloc(1 + strlen(envptr));
if (bufptr == (char *)NULL)
return PK_MEM;
#if (defined(WIN32) || defined(WINDLL))
# ifdef WIN32
if (IsWinNT()) {
strcpy(bufptr, envptr);
} else {
OEM_TO_INTERN(envptr, bufptr);
}
# else
OEM_TO_INTERN(envptr, bufptr);
# endif
#else
strcpy(bufptr, envptr);
#endif
argc = count_args(bufptr);
argv = (char **)malloc((argc + *Pargc + 1) * sizeof(char *));
if (argv == (char **)NULL) {
free(bufptr);
return PK_MEM;
}
argvect = argv;
*(argv++) = *((*Pargv)++);
do {
#if defined(AMIGA) || defined(UNIX)
if (*bufptr == '"') {
char *argstart = ++bufptr;
*(argv++) = argstart;
for (ch = *bufptr; ch != '\0' && ch != '\"';
ch = *PREINCSTR(bufptr))
if (ch == '\\' && bufptr[1] != '\0')
++bufptr;
if (ch != '\0')
*(bufptr++) = '\0';
while ((argstart = MBSCHR(argstart, '\\')) != (char *)NULL) {
strcpy(argstart, argstart + 1);
if (*argstart)
++argstart;
}
} else {
*(argv++) = bufptr;
while ((ch = *bufptr) != '\0' && !ISspace(ch))
INCSTR(bufptr);
if (ch != '\0')
*(bufptr++) = '\0';
}
#else
#ifdef DOS_FLX_NLM_OS2_W32
* strings under DOS_FLX_NLM_OS2_W32, because backslashes are
* directory separators and double quotes are illegal in filenames */
if (*bufptr == '"') {
*(argv++) = ++bufptr;
while ((ch = *bufptr) != '\0' && ch != '\"')
INCSTR(bufptr);
if (ch != '\0')
*(bufptr++) = '\0';
} else {
*(argv++) = bufptr;
while ((ch = *bufptr) != '\0' && !ISspace(ch))
INCSTR(bufptr);
if (ch != '\0')
*(bufptr++) = '\0';
}
#else
*(argv++) = bufptr;
while ((ch = *bufptr) != '\0' && !ISspace(ch))
INCSTR(bufptr);
if (ch != '\0')
*(bufptr++) = '\0';
#endif
#endif
while ((ch = *bufptr) != '\0' && ISspace(ch))
INCSTR(bufptr);
} while (ch);
argc += *Pargc;
while (--(*Pargc))
*(argv++) = *((*Pargv)++);
*argv = (char *)NULL;
*Pargv = argvect;
*Pargc = argc;
return PK_OK;
}
static int count_args(s)
ZCONST char *s;
{
int count = 0;
char ch;
do {
++count;
#if defined(AMIGA) || defined(UNIX)
if (*s == '\"') {
for (ch = *PREINCSTR(s); ch != '\0' && ch != '\"';
ch = *PREINCSTR(s))
if (ch == '\\' && s[1] != '\0')
++s;
if (*s)
++s;
} else
#else
#ifdef DOS_FLX_NLM_OS2_W32
if (*s == '\"') {
++s;
while ((ch = *s) != '\0' && ch != '\"')
INCSTR(s);
if (*s)
++s;
} else
#endif
#endif
while ((ch = *s) != '\0' && !ISspace(ch))
INCSTR(s);
while ((ch = *s) != '\0' && ISspace(ch))
INCSTR(s);
} while (ch);
return count;
}
#ifdef TEST
int main(argc, argv)
int argc;
char **argv;
{
int err;
printf("Orig argv: %p\n", argv);
dump_args(argc, argv);
if ((err = envargs(&argc, &argv, "ENVTEST")) != PK_OK) {
perror("envargs: cannot get memory for arguments");
EXIT(err);
}
printf(" New argv: %p\n", argv);
dump_args(argc, argv);
}
void dump_args(argc, argv)
int argc;
char *argv[];
{
int i;
printf("\nDump %d args:\n", argc);
for (i = 0; i < argc; ++i)
printf("%3d %s\n", i, argv[i]);
}
#endif
#ifdef MSDOS
* void mksargs(int *argcp, char ***argvp)
*
* Substitutes the extended command line argument list produced by
* the MKS Korn Shell in place of the command line info from DOS.
*
* The MKS shell gets around DOS's 128-byte limit on the length of
* a command line by passing the "real" command line in the envi-
* ronment. The "real" arguments are flagged by prepending a tilde
* (~) to each one.
*
* This "mksargs" routine creates a new argument list by scanning
* the environment from the beginning, looking for strings begin-
* ning with a tilde character. The new list replaces the original
* "argv" (pointed to by "argvp"), and the number of arguments
* in the new list replaces the original "argc" (pointed to by
* "argcp").
*
* Rich Wales
*/
void mksargs(argcp, argvp)
int *argcp;
char ***argvp;
{
#ifndef MSC
#ifndef __WATCOMC__
extern char **environ;
#endif
#endif
char **envp;
char **newargv;
char **argp;
int newargc;
if (environ == NULL || argcp == NULL || argvp == NULL || *argvp == NULL)
return;
for (envp = environ, newargc = 0;
*envp != NULL && (*envp)[0] == '~';
envp++, newargc++)
;
if (newargc == 0)
return;
newargv = (char **) malloc(sizeof(char **) * (newargc+1));
if (newargv == NULL)
return;
for (argp = newargv, envp = environ; *envp != NULL && (*envp)[0] == '~';
*argp++ = &(*envp++)[1])
;
*argp = NULL;
*argcp = newargc;
*argvp = newargv;
}
#endif