which included commits to RCS files with non-trunk default branches. git-svn-id: svn://10.65.10.50/trunk@5403 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			313 lines
		
	
	
		
			9.1 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			313 lines
		
	
	
		
			9.1 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
| /*----------------------------------------------------------------*
 | |
|  | 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__          /* emx isspace() returns TRUE on extended ASCII !! */
 | |
| #  define ISspace(c) ((c) & 0x80 ? 0 : isspace(c))
 | |
| #else
 | |
| #  define ISspace(c) isspace(c)
 | |
| #endif /* ?__EMX__ */
 | |
| 
 | |
| static int count_args OF((char *));
 | |
| static void mem_err OF((__GPRO));
 | |
| 
 | |
| static char Far NoMemArguments[] = "envargs:  can't get memory for arguments";
 | |
| 
 | |
| 
 | |
| void envargs(__G__ Pargc, Pargv, envstr, envstr2)
 | |
|     __GDEF
 | |
|     int *Pargc;
 | |
|     char ***Pargv, *envstr, *envstr2;
 | |
| {
 | |
| #ifndef RISCOS
 | |
|     char *getenv();
 | |
| #endif
 | |
|     char *envptr;       /* value returned by getenv */
 | |
|     char *bufptr;       /* copy of env info */
 | |
|     int argc = 0;       /* internal arg count */
 | |
|     register int ch;    /* spare temp value */
 | |
|     char **argv;        /* internal arg vector */
 | |
|     char **argvect;     /* copy of vector address */
 | |
| 
 | |
|     /* see if anything in the environment */
 | |
|     if ((envptr = getenv(envstr)) != (char *)NULL)        /* usual var */
 | |
|         while (ISspace(*envptr))        /* must discard leading spaces */
 | |
|             envptr++;
 | |
|     if (envptr == (char *)NULL || *envptr == '\0')
 | |
|         if ((envptr = getenv(envstr2)) != (char *)NULL)   /* alternate var */
 | |
|             while (ISspace(*envptr))
 | |
|                 envptr++;
 | |
|     if (envptr == (char *)NULL || *envptr == '\0')
 | |
|         return;
 | |
| 
 | |
|     bufptr = malloc(1 + strlen(envptr));
 | |
|     if (bufptr == (char *)NULL)
 | |
|         mem_err(__G);
 | |
| #if (defined(WIN32) || defined(WINDLL))
 | |
| # ifdef WIN32
 | |
|     if (IsWinNT()) {
 | |
|         /* SPC: don't know codepage of 'real' WinNT console */
 | |
|         strcpy(bufptr, envptr);
 | |
|     } else {
 | |
|         /* Win95 environment is DOS and uses OEM character coding */
 | |
|         OEM_TO_INTERN(envptr, bufptr);
 | |
|     }
 | |
| # else /* !WIN32 */
 | |
|     /* DOS environment uses OEM codepage */
 | |
|     OEM_TO_INTERN(envptr, bufptr);
 | |
| # endif
 | |
| #else /* !(WIN32 || WINDLL) */
 | |
|     strcpy(bufptr, envptr);
 | |
| #endif /* ?(WIN32 || WINDLL) */
 | |
| 
 | |
|     /* count the args so we can allocate room for them */
 | |
|     argc = count_args(bufptr);
 | |
|     /* allocate a vector large enough for all args */
 | |
|     argv = (char **)malloc((argc + *Pargc + 1) * sizeof(char *));
 | |
|     if (argv == (char **)NULL) {
 | |
|         free(bufptr);
 | |
|         mem_err(__G);
 | |
|     }
 | |
|     argvect = argv;
 | |
| 
 | |
|     /* copy the program name first, that's always true */
 | |
|     *(argv++) = *((*Pargv)++);
 | |
| 
 | |
|     /* copy the environment args next, may be changed */
 | |
|     do {
 | |
| #if defined(AMIGA) || defined(UNIX)
 | |
|         if (*bufptr == '"') {
 | |
|             char *argstart = ++bufptr;
 | |
| 
 | |
|             *(argv++) = argstart;
 | |
|             for (ch = *bufptr; ch != '\0' && ch != '\"'; ch = *(++bufptr))
 | |
|                 if (ch == '\\' && bufptr[1] != '\0')
 | |
|                     ++bufptr;           /* skip char after backslash */
 | |
|             if (ch != '\0')
 | |
|                 *(bufptr++) = '\0';     /* overwrite trailing " */
 | |
| 
 | |
|             /* remove escape characters */
 | |
|             while ((argstart = strchr(argstart, '\\')) != (char *)NULL) {
 | |
|                 strcpy(argstart, argstart + 1);
 | |
|                 if (*argstart)
 | |
|                     ++argstart;
 | |
|             }
 | |
|         } else {
 | |
|             *(argv++) = bufptr;
 | |
|             while ((ch = *bufptr) != '\0' && !ISspace(ch))
 | |
|                 ++bufptr;
 | |
|             if (ch != '\0')
 | |
|                 *(bufptr++) = '\0';
 | |
|         }
 | |
| #else
 | |
| #ifdef DOS_OS2_W32
 | |
|         /* we do not support backslash-quoting of quotes in quoted
 | |
|          * strings under DOS_OS2_W32, because backslashes are directory
 | |
|          * separators and double quotes are illegal in filenames */
 | |
|         if (*bufptr == '"') {
 | |
|             *(argv++) = ++bufptr;
 | |
|             while ((ch = *bufptr) != '\0' && ch != '\"')
 | |
|                 ++bufptr;
 | |
|             if (ch != '\0')
 | |
|                 *(bufptr++) = '\0';
 | |
|         } else {
 | |
|             *(argv++) = bufptr;
 | |
|             while ((ch = *bufptr) != '\0' && !ISspace(ch))
 | |
|                 ++bufptr;
 | |
|             if (ch != '\0')
 | |
|                 *(bufptr++) = '\0';
 | |
|         }
 | |
| #else
 | |
|         *(argv++) = bufptr;
 | |
|         while ((ch = *bufptr) != '\0' && !ISspace(ch))
 | |
|             ++bufptr;
 | |
|         if (ch != '\0')
 | |
|             *(bufptr++) = '\0';
 | |
| #endif /* ?DOS_OS2_W32 */
 | |
| #endif /* ?(AMIGA || UNIX) */
 | |
|         while ((ch = *bufptr) != '\0' && ISspace(ch))
 | |
|             ++bufptr;
 | |
|     } while (ch);
 | |
| 
 | |
|     /* now save old argc and copy in the old args */
 | |
|     argc += *Pargc;
 | |
|     while (--(*Pargc))
 | |
|         *(argv++) = *((*Pargv)++);
 | |
| 
 | |
|     /* finally, add a NULL after the last arg, like Unix */
 | |
|     *argv = (char *)NULL;
 | |
| 
 | |
|     /* save the values and return */
 | |
|     *Pargv = argvect;
 | |
|     *Pargc = argc;
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| static int count_args(s)
 | |
|     char *s;
 | |
| {
 | |
|     int count = 0;
 | |
|     char ch;
 | |
| 
 | |
|     do {
 | |
|         /* count and skip args */
 | |
|         ++count;
 | |
| #if defined(AMIGA) || defined(UNIX)
 | |
|         if (*s == '\"') {
 | |
|             for (ch = *(++s);  ch != '\0' && ch != '\"';  ch = *(++s))
 | |
|                 if (ch == '\\' && s[1] != '\0')
 | |
|                     ++s;
 | |
|             if (*s)
 | |
|                 ++s;        /* trailing quote */
 | |
|         } else
 | |
| #else
 | |
| #ifdef DOS_OS2_W32
 | |
|         if (*s == '\"') {
 | |
|             ++s;                /* leading quote */
 | |
|             while ((ch = *s) != '\0' && ch != '\"')
 | |
|                 ++s;
 | |
|             if (*s)
 | |
|                 ++s;        /* trailing quote */
 | |
|         } else
 | |
| #endif /* DOS_OS2_W32 */
 | |
| #endif /* ?(AMIGA || UNIX) */
 | |
|         while ((ch = *s) != '\0' && !ISspace(ch))  /* note else-clauses above */
 | |
|             ++s;
 | |
|         while ((ch = *s) != '\0' && ISspace(ch))
 | |
|             ++s;
 | |
|     } while (ch);
 | |
| 
 | |
|     return count;
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| static void mem_err(__G)
 | |
|     __GDEF
 | |
| {
 | |
|     perror(LoadFarString(NoMemArguments));
 | |
|     DESTROYGLOBALS()
 | |
|     EXIT(PK_MEM);
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| #ifdef TEST
 | |
| 
 | |
| main(argc, argv)
 | |
|     int argc;
 | |
|     char **argv;
 | |
| {
 | |
|     int i;
 | |
| 
 | |
|     printf("Orig argv: %p\n", argv);
 | |
|     dump_args(argc, argv);
 | |
|     envargs(__G__ &argc, &argv, "ENVTEST");
 | |
|     printf(" New argv: %p\n", argv);
 | |
|     dump_args(argc, argv);
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| 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 /* TEST */
 | |
| 
 | |
| 
 | |
| 
 | |
| #ifdef MSDOS   /* DOS_OS2?  DOS_OS2_W32? */
 | |
| 
 | |
| /*
 | |
|  * 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 /* declared differently in MSC 7.0 headers, at least */
 | |
| #ifndef __WATCOMC__
 | |
|     extern char **environ;          /* environment */
 | |
| #endif
 | |
| #endif
 | |
|     char        **envp;             /* pointer into environment */
 | |
|     char        **newargv;          /* new argument list */
 | |
|     char        **argp;             /* pointer into new arg list */
 | |
|     int         newargc;            /* new argument count */
 | |
| 
 | |
|     /* sanity check */
 | |
|     if (environ == NULL || argcp == NULL || argvp == NULL || *argvp == NULL)
 | |
|         return;
 | |
| 
 | |
|     /* find out how many environment arguments there are */
 | |
|     for (envp = environ, newargc = 0; *envp != NULL && (*envp)[0] == '~';
 | |
|          envp++, newargc++)
 | |
|         ;
 | |
|     if (newargc == 0)
 | |
|         return;     /* no environment arguments */
 | |
| 
 | |
|     /* set up new argument list */
 | |
|     newargv = (char **) malloc(sizeof(char **) * (newargc+1));
 | |
|     if (newargv == NULL)
 | |
|         return;     /* malloc failed */
 | |
| 
 | |
|     for (argp = newargv, envp = environ; *envp != NULL && (*envp)[0] == '~';
 | |
|          *argp++ = &(*envp++)[1])
 | |
|         ;
 | |
|     *argp = NULL;   /* null-terminate the list */
 | |
| 
 | |
|     /* substitute new argument list in place of old one */
 | |
|     *argcp = newargc;
 | |
|     *argvp = newargv;
 | |
| }
 | |
| 
 | |
| #endif /* MSDOS */
 |