libroot/posix/stdio: Remove unused portions.
[haiku.git] / src / bin / unzip / envargs.c
blobf00628294d69aac9d71c3750b5bb1f11eff1f599
1 /*
2 Copyright (c) 1990-2000 Info-ZIP. All rights reserved.
4 See the accompanying file LICENSE, version 2000-Apr-09 or later
5 (the contents of which are also included in unzip.h) for terms of use.
6 If, for some reason, all these files are missing, the Info-ZIP license
7 also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
8 */
9 /*----------------------------------------------------------------*
10 | envargs - add default options from environment to command line
11 |----------------------------------------------------------------
12 | Author: Bill Davidsen, original 10/13/91, revised 23 Oct 1991.
13 | This program is in the public domain.
14 |----------------------------------------------------------------
15 | Minor program notes:
16 | 1. Yes, the indirection is a tad complex
17 | 2. Parentheses were added where not needed in some cases
18 | to make the action of the code less obscure.
19 |----------------------------------------------------------------
20 | UnZip notes: 24 May 92 ("v1.4"):
21 | 1. #include "unzip.h" for prototypes (24 May 92)
22 | 2. changed ch to type char (24 May 92)
23 | 3. added an ifdef to avoid Borland warnings (24 May 92)
24 | 4. included Rich Wales' mksargs() routine (for MS-DOS, maybe
25 | OS/2? NT?) (4 Dec 93)
26 | 5. added alternate-variable string envstr2 (21 Apr 94)
27 | 6. added support for quoted arguments (6 Jul 96)
28 *----------------------------------------------------------------*/
31 #define __ENVARGS_C /* identifies this source module */
32 #define UNZIP_INTERNAL
33 #include "unzip.h"
35 #ifdef __EMX__ /* emx isspace() returns TRUE on extended ASCII !! */
36 # define ISspace(c) ((c) & 0x80 ? 0 : isspace((unsigned)c))
37 #else
38 # define ISspace(c) isspace((unsigned)c)
39 #endif /* ?__EMX__ */
41 static int count_args OF((ZCONST char *));
44 /* envargs() returns PK-style error code */
46 int envargs(Pargc, Pargv, envstr, envstr2)
47 int *Pargc;
48 char ***Pargv;
49 ZCONST char *envstr, *envstr2;
51 #ifndef RISCOS
52 char *getenv();
53 #endif
54 char *envptr; /* value returned by getenv */
55 char *bufptr; /* copy of env info */
56 int argc = 0; /* internal arg count */
57 register int ch; /* spare temp value */
58 char **argv; /* internal arg vector */
59 char **argvect; /* copy of vector address */
61 /* see if anything in the environment */
62 if ((envptr = getenv(envstr)) != (char *)NULL) /* usual var */
63 while (ISspace(*envptr)) /* must discard leading spaces */
64 envptr++;
65 if (envptr == (char *)NULL || *envptr == '\0')
66 if ((envptr = getenv(envstr2)) != (char *)NULL) /* alternate var */
67 while (ISspace(*envptr))
68 envptr++;
69 if (envptr == (char *)NULL || *envptr == '\0')
70 return PK_OK;
72 bufptr = malloc(1 + strlen(envptr));
73 if (bufptr == (char *)NULL)
74 return PK_MEM;
75 #if (defined(WIN32) || defined(WINDLL))
76 # ifdef WIN32
77 if (IsWinNT()) {
78 /* SPC: don't know codepage of 'real' WinNT console */
79 strcpy(bufptr, envptr);
80 } else {
81 /* Win95 environment is DOS and uses OEM character coding */
82 OEM_TO_INTERN(envptr, bufptr);
84 # else /* !WIN32 */
85 /* DOS environment uses OEM codepage */
86 OEM_TO_INTERN(envptr, bufptr);
87 # endif
88 #else /* !(WIN32 || WINDLL) */
89 strcpy(bufptr, envptr);
90 #endif /* ?(WIN32 || WINDLL) */
92 /* count the args so we can allocate room for them */
93 argc = count_args(bufptr);
94 /* allocate a vector large enough for all args */
95 argv = (char **)malloc((argc + *Pargc + 1) * sizeof(char *));
96 if (argv == (char **)NULL) {
97 free(bufptr);
98 return PK_MEM;
100 argvect = argv;
102 /* copy the program name first, that's always true */
103 *(argv++) = *((*Pargv)++);
105 /* copy the environment args next, may be changed */
106 do {
107 #if defined(AMIGA) || defined(UNIX)
108 if (*bufptr == '"') {
109 char *argstart = ++bufptr;
111 *(argv++) = argstart;
112 for (ch = *bufptr; ch != '\0' && ch != '\"';
113 ch = *PREINCSTR(bufptr))
114 if (ch == '\\' && bufptr[1] != '\0')
115 ++bufptr; /* advance to char after backslash */
116 if (ch != '\0')
117 *(bufptr++) = '\0'; /* overwrite trailing " */
119 /* remove escape characters */
120 while ((argstart = MBSCHR(argstart, '\\')) != (char *)NULL) {
121 strcpy(argstart, argstart + 1);
122 if (*argstart)
123 ++argstart;
125 } else {
126 *(argv++) = bufptr;
127 while ((ch = *bufptr) != '\0' && !ISspace(ch))
128 INCSTR(bufptr);
129 if (ch != '\0')
130 *(bufptr++) = '\0';
132 #else
133 #ifdef DOS_FLX_NLM_OS2_W32
134 /* we do not support backslash-quoting of quotes in quoted
135 * strings under DOS_FLX_NLM_OS2_W32, because backslashes are
136 * directory separators and double quotes are illegal in filenames */
137 if (*bufptr == '"') {
138 *(argv++) = ++bufptr;
139 while ((ch = *bufptr) != '\0' && ch != '\"')
140 INCSTR(bufptr);
141 if (ch != '\0')
142 *(bufptr++) = '\0';
143 } else {
144 *(argv++) = bufptr;
145 while ((ch = *bufptr) != '\0' && !ISspace(ch))
146 INCSTR(bufptr);
147 if (ch != '\0')
148 *(bufptr++) = '\0';
150 #else
151 *(argv++) = bufptr;
152 while ((ch = *bufptr) != '\0' && !ISspace(ch))
153 INCSTR(bufptr);
154 if (ch != '\0')
155 *(bufptr++) = '\0';
156 #endif /* ?DOS_FLX_NLM_OS2_W32 */
157 #endif /* ?(AMIGA || UNIX) */
158 while ((ch = *bufptr) != '\0' && ISspace(ch))
159 INCSTR(bufptr);
160 } while (ch);
162 /* now save old argc and copy in the old args */
163 argc += *Pargc;
164 while (--(*Pargc))
165 *(argv++) = *((*Pargv)++);
167 /* finally, add a NULL after the last arg, like Unix */
168 *argv = (char *)NULL;
170 /* save the values and return, indicating succes */
171 *Pargv = argvect;
172 *Pargc = argc;
174 return PK_OK;
179 static int count_args(s)
180 ZCONST char *s;
182 int count = 0;
183 char ch;
185 do {
186 /* count and skip args */
187 ++count;
188 #if defined(AMIGA) || defined(UNIX)
189 if (*s == '\"') {
190 for (ch = *PREINCSTR(s); ch != '\0' && ch != '\"';
191 ch = *PREINCSTR(s))
192 if (ch == '\\' && s[1] != '\0')
193 ++s;
194 if (*s)
195 ++s; /* trailing quote */
196 } else
197 #else
198 #ifdef DOS_FLX_NLM_OS2_W32
199 if (*s == '\"') {
200 ++s; /* leading quote */
201 while ((ch = *s) != '\0' && ch != '\"')
202 INCSTR(s);
203 if (*s)
204 ++s; /* trailing quote */
205 } else
206 #endif /* DOS_FLX_NLM_OS2_W32 */
207 #endif /* ?(AMIGA || UNIX) */
208 while ((ch = *s) != '\0' && !ISspace(ch)) /* note else-clauses above */
209 INCSTR(s);
210 while ((ch = *s) != '\0' && ISspace(ch))
211 INCSTR(s);
212 } while (ch);
214 return count;
219 #ifdef TEST
221 int main(argc, argv)
222 int argc;
223 char **argv;
225 int err;
227 printf("Orig argv: %p\n", argv);
228 dump_args(argc, argv);
229 if ((err = envargs(&argc, &argv, "ENVTEST")) != PK_OK) {
230 perror("envargs: cannot get memory for arguments");
231 EXIT(err);
233 printf(" New argv: %p\n", argv);
234 dump_args(argc, argv);
239 void dump_args(argc, argv)
240 int argc;
241 char *argv[];
243 int i;
245 printf("\nDump %d args:\n", argc);
246 for (i = 0; i < argc; ++i)
247 printf("%3d %s\n", i, argv[i]);
250 #endif /* TEST */
254 #ifdef MSDOS /* DOS_OS2? DOS_OS2_W32? */
257 * void mksargs(int *argcp, char ***argvp)
259 * Substitutes the extended command line argument list produced by
260 * the MKS Korn Shell in place of the command line info from DOS.
262 * The MKS shell gets around DOS's 128-byte limit on the length of
263 * a command line by passing the "real" command line in the envi-
264 * ronment. The "real" arguments are flagged by prepending a tilde
265 * (~) to each one.
267 * This "mksargs" routine creates a new argument list by scanning
268 * the environment from the beginning, looking for strings begin-
269 * ning with a tilde character. The new list replaces the original
270 * "argv" (pointed to by "argvp"), and the number of arguments
271 * in the new list replaces the original "argc" (pointed to by
272 * "argcp").
274 * Rich Wales
276 void mksargs(argcp, argvp)
277 int *argcp;
278 char ***argvp;
280 #ifndef MSC /* declared differently in MSC 7.0 headers, at least */
281 #ifndef __WATCOMC__
282 extern char **environ; /* environment */
283 #endif
284 #endif
285 char **envp; /* pointer into environment */
286 char **newargv; /* new argument list */
287 char **argp; /* pointer into new arg list */
288 int newargc; /* new argument count */
290 /* sanity check */
291 if (environ == NULL || argcp == NULL || argvp == NULL || *argvp == NULL)
292 return;
294 /* find out how many environment arguments there are */
295 for (envp = environ, newargc = 0;
296 *envp != NULL && (*envp)[0] == '~';
297 envp++, newargc++)
299 if (newargc == 0)
300 return; /* no environment arguments */
302 /* set up new argument list */
303 newargv = (char **) malloc(sizeof(char **) * (newargc+1));
304 if (newargv == NULL)
305 return; /* malloc failed */
307 for (argp = newargv, envp = environ; *envp != NULL && (*envp)[0] == '~';
308 *argp++ = &(*envp++)[1])
310 *argp = NULL; /* null-terminate the list */
312 /* substitute new argument list in place of old one */
313 *argcp = newargc;
314 *argvp = newargv;
317 #endif /* MSDOS */