aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Config.in10
-rw-r--r--configs/mingw32_defconfig1
-rw-r--r--configs/mingw64_defconfig1
-rw-r--r--include/mingw.h6
-rw-r--r--win32/env.c126
5 files changed, 26 insertions, 118 deletions
diff --git a/Config.in b/Config.in
index ba7ba1026..dc3a6e09a 100644
--- a/Config.in
+++ b/Config.in
@@ -134,16 +134,6 @@ config GLOBBING
134 the BusyBox binary to handle wildcard expansion using the C runtime 134 the BusyBox binary to handle wildcard expansion using the C runtime
135 set this to 'Y'. 135 set this to 'Y'.
136 136
137config SAFE_ENV
138 bool "Manipulate the environment through safe API calls"
139 default n
140 depends on PLATFORM_MINGW32
141 help
142 Enable this option to use safe API calls when clearing environment
143 variables. This is necessary if BusyBox is to run on ReactOS or
144 64-bit Windows. The default is 'N', which must be used if BusyBox
145 is to run on Windows XP.
146
147config PAM 137config PAM
148 bool "Support PAM (Pluggable Authentication Modules)" 138 bool "Support PAM (Pluggable Authentication Modules)"
149 default n 139 default n
diff --git a/configs/mingw32_defconfig b/configs/mingw32_defconfig
index 4adc4471e..5ed8cd41f 100644
--- a/configs/mingw32_defconfig
+++ b/configs/mingw32_defconfig
@@ -20,7 +20,6 @@ CONFIG_FEATURE_VERBOSE_USAGE=y
20CONFIG_FEATURE_COMPRESS_USAGE=y 20CONFIG_FEATURE_COMPRESS_USAGE=y
21CONFIG_LFS=y 21CONFIG_LFS=y
22# CONFIG_GLOBBING is not set 22# CONFIG_GLOBBING is not set
23# CONFIG_SAFE_ENV is not set
24# CONFIG_PAM is not set 23# CONFIG_PAM is not set
25# CONFIG_FEATURE_DEVPTS is not set 24# CONFIG_FEATURE_DEVPTS is not set
26# CONFIG_FEATURE_UTMP is not set 25# CONFIG_FEATURE_UTMP is not set
diff --git a/configs/mingw64_defconfig b/configs/mingw64_defconfig
index fdc755d93..2c189700a 100644
--- a/configs/mingw64_defconfig
+++ b/configs/mingw64_defconfig
@@ -20,7 +20,6 @@ CONFIG_FEATURE_VERBOSE_USAGE=y
20CONFIG_FEATURE_COMPRESS_USAGE=y 20CONFIG_FEATURE_COMPRESS_USAGE=y
21CONFIG_LFS=y 21CONFIG_LFS=y
22# CONFIG_GLOBBING is not set 22# CONFIG_GLOBBING is not set
23CONFIG_SAFE_ENV=y
24# CONFIG_PAM is not set 23# CONFIG_PAM is not set
25# CONFIG_FEATURE_DEVPTS is not set 24# CONFIG_FEATURE_DEVPTS is not set
26# CONFIG_FEATURE_UTMP is not set 25# CONFIG_FEATURE_UTMP is not set
diff --git a/include/mingw.h b/include/mingw.h
index 87abd077b..6f69913d6 100644
--- a/include/mingw.h
+++ b/include/mingw.h
@@ -195,16 +195,10 @@ char *mingw_mktemp(char *template);
195int mkstemp(char *template); 195int mkstemp(char *template);
196char *realpath(const char *path, char *resolved_path); 196char *realpath(const char *path, char *resolved_path);
197int setenv(const char *name, const char *value, int replace); 197int setenv(const char *name, const char *value, int replace);
198#if ENABLE_SAFE_ENV
199int unsetenv(const char *env); 198int unsetenv(const char *env);
200#else
201void unsetenv(const char *env);
202#endif
203 199
204#define getenv mingw_getenv 200#define getenv mingw_getenv
205#if ENABLE_SAFE_ENV
206#define putenv mingw_putenv 201#define putenv mingw_putenv
207#endif
208#define mktemp mingw_mktemp 202#define mktemp mingw_mktemp
209 203
210/* 204/*
diff --git a/win32/env.c b/win32/env.c
index eab3c1708..2837c0720 100644
--- a/win32/env.c
+++ b/win32/env.c
@@ -1,19 +1,8 @@
1#include "libbb.h" 1#include "libbb.h"
2 2
3static int lookup_env(char **env, const char *name, size_t nmln)
4{
5 int i;
6
7 for (i = 0; env[i]; i++) {
8 if (0 == strncmp(env[i], name, nmln)
9 && '=' == env[i][nmln])
10 /* matches */
11 return i;
12 }
13 return -1;
14}
15
16#undef getenv 3#undef getenv
4#undef putenv
5
17char *mingw_getenv(const char *name) 6char *mingw_getenv(const char *name)
18{ 7{
19 char *result = getenv(name); 8 char *result = getenv(name);
@@ -29,70 +18,21 @@ char *mingw_getenv(const char *name)
29int setenv(const char *name, const char *value, int replace) 18int setenv(const char *name, const char *value, int replace)
30{ 19{
31 int out; 20 int out;
32 size_t namelen, valuelen;
33 char *envstr; 21 char *envstr;
34 22
35 if (!name || !value) return -1; 23 if (!name || !*name || strchr(name, '=') || !value) return -1;
36 if (!replace) { 24 if (!replace) {
37 char *oldval = NULL; 25 if (getenv(name)) return 0;
38 oldval = getenv(name);
39 if (oldval) return 0;
40 } 26 }
41 27
42 namelen = strlen(name); 28 envstr = xasprintf("%s=%s", name, value);
43 valuelen = strlen(value); 29 out = mingw_putenv(envstr);
44 envstr = malloc((namelen + valuelen + 2)); 30 free(envstr);
45 if (!envstr) return -1;
46
47 memcpy(envstr, name, namelen);
48 envstr[namelen] = '=';
49 memcpy(envstr + namelen + 1, value, valuelen);
50 envstr[namelen + valuelen + 1] = 0;
51
52 out = putenv(envstr);
53 /* putenv(3) makes the argument string part of the environment,
54 * and changing that string modifies the environment --- which
55 * means we do not own that storage anymore. Do not free
56 * envstr.
57 */
58 31
59 return out; 32 return out;
60} 33}
61 34
62/* 35/*
63 * If name contains '=', then sets the variable, otherwise it unsets it
64 */
65char **env_setenv(char **env, const char *name)
66{
67 char *eq = strchrnul(name, '=');
68 int i = lookup_env(env, name, eq-name);
69
70 if (i < 0) {
71 if (*eq) {
72 for (i = 0; env[i]; i++)
73 ;
74 env = xrealloc(env, (i+2)*sizeof(*env));
75 env[i] = xstrdup(name);
76 env[i+1] = NULL;
77 }
78 }
79 else {
80 free(env[i]);
81 if (*eq)
82 env[i] = xstrdup(name);
83 else {
84 for (; env[i]; i++)
85 env[i] = env[i+1];
86#if !ENABLE_SAFE_ENV
87 SetEnvironmentVariable(name, NULL);
88#endif
89 }
90 }
91 return env;
92}
93
94#if ENABLE_SAFE_ENV
95/*
96 * Removing an environment variable with WIN32 putenv requires an argument 36 * Removing an environment variable with WIN32 putenv requires an argument
97 * like "NAME="; glibc omits the '='. The implementations of unsetenv and 37 * like "NAME="; glibc omits the '='. The implementations of unsetenv and
98 * clearenv allow for this. 38 * clearenv allow for this.
@@ -100,28 +40,34 @@ char **env_setenv(char **env, const char *name)
100 * It isn't possible to create an environment variable with an empty value 40 * It isn't possible to create an environment variable with an empty value
101 * using WIN32 putenv. 41 * using WIN32 putenv.
102 */ 42 */
103#undef putenv 43int unsetenv(const char *name)
104int unsetenv(const char *env)
105{ 44{
106 char *name; 45 char *envstr;
107 int ret; 46 int ret;
108 47
109 name = xmalloc(strlen(env)+2); 48 if (!name || !*name || strchr(name, '=') ) {
110 strcat(strcpy(name, env), "="); 49 return -1;
111 ret = putenv(name); 50 }
112 free(name); 51
52 envstr = xmalloc(strlen(name)+2);
53 strcat(strcpy(envstr, name), "=");
54 ret = putenv(envstr);
55 free(envstr);
113 56
114 return ret; 57 return ret;
115} 58}
116 59
117int clearenv(void) 60int clearenv(void)
118{ 61{
119 char *name, *s; 62 char *envp, *name, *s;
120 63
121 while ( environ && *environ ) { 64 while ( environ && (envp=*environ) ) {
122 if ( (s=strchr(*environ, '=')) != NULL ) { 65 if ( (s=strchr(envp, '=')) != NULL ) {
123 name = xstrndup(*environ, s-*environ+1); 66 name = xstrndup(envp, s-envp+1);
124 putenv(name); 67 if ( putenv(name) == -1 ) {
68 free(name);
69 return -1;
70 }
125 free(name); 71 free(name);
126 } 72 }
127 else { 73 else {
@@ -146,23 +92,3 @@ int mingw_putenv(const char *env)
146 /* can't set empty value */ 92 /* can't set empty value */
147 return 0; 93 return 0;
148} 94}
149#else
150void unsetenv(const char *env)
151{
152 env_setenv(environ, env);
153}
154
155int clearenv(void)
156{
157 char **env = environ;
158 if (!env)
159 return 0;
160 while (*env) {
161 free(*env);
162 env++;
163 }
164 free(env);
165 environ = NULL;
166 return 0;
167}
168#endif