1 /* Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #define APR_WANT_STRFUNC
18 #include "apr_want.h"
19 #include "apr.h"
20 #include "apr_arch_misc.h"
21 #include "apr_arch_utf8.h"
22 #include "apr_env.h"
23 #include "apr_errno.h"
24 #include "apr_pools.h"
25 #include "apr_strings.h"
26
27 #if APR_HAS_UNICODE_FS && !defined(_WIN32_WCE)
widen_envvar_name(apr_wchar_t * buffer,apr_size_t bufflen,const char * envvar)28 static apr_status_t widen_envvar_name (apr_wchar_t *buffer,
29 apr_size_t bufflen,
30 const char *envvar)
31 {
32 apr_size_t inchars;
33 apr_status_t status;
34
35 inchars = strlen(envvar) + 1;
36 status = apr_conv_utf8_to_ucs2(envvar, &inchars, buffer, &bufflen);
37 if (status == APR_INCOMPLETE)
38 status = APR_ENAMETOOLONG;
39
40 return status;
41 }
42 #endif
43
44
apr_env_get(char ** value,const char * envvar,apr_pool_t * pool)45 APR_DECLARE(apr_status_t) apr_env_get(char **value,
46 const char *envvar,
47 apr_pool_t *pool)
48 {
49 #if defined(_WIN32_WCE)
50 return APR_ENOTIMPL;
51 #else
52 char *val = NULL;
53 DWORD size;
54
55 #if APR_HAS_UNICODE_FS
56 IF_WIN_OS_IS_UNICODE
57 {
58 apr_wchar_t wenvvar[APR_PATH_MAX];
59 apr_size_t inchars, outchars;
60 apr_wchar_t *wvalue, dummy;
61 apr_status_t status;
62
63 status = widen_envvar_name(wenvvar, APR_PATH_MAX, envvar);
64 if (status)
65 return status;
66
67 SetLastError(0);
68 size = GetEnvironmentVariableW(wenvvar, &dummy, 0);
69 if (GetLastError() == ERROR_ENVVAR_NOT_FOUND)
70 /* The environment variable doesn't exist. */
71 return APR_ENOENT;
72
73 if (size == 0) {
74 /* The environment value exists, but is zero-length. */
75 *value = apr_pstrdup(pool, "");
76 return APR_SUCCESS;
77 }
78
79 wvalue = apr_palloc(pool, size * sizeof(*wvalue));
80 size = GetEnvironmentVariableW(wenvvar, wvalue, size);
81
82 inchars = wcslen(wvalue) + 1;
83 outchars = 3 * inchars; /* Enough for any UTF-8 representation */
84 val = apr_palloc(pool, outchars);
85 status = apr_conv_ucs2_to_utf8(wvalue, &inchars, val, &outchars);
86 if (status)
87 return status;
88 }
89 #endif
90 #if APR_HAS_ANSI_FS
91 ELSE_WIN_OS_IS_ANSI
92 {
93 char dummy;
94
95 SetLastError(0);
96 size = GetEnvironmentVariableA(envvar, &dummy, 0);
97 if (GetLastError() == ERROR_ENVVAR_NOT_FOUND)
98 /* The environment variable doesn't exist. */
99 return APR_ENOENT;
100
101 if (size == 0) {
102 /* The environment value exists, but is zero-length. */
103 *value = apr_pstrdup(pool, "");
104 return APR_SUCCESS;
105 }
106
107 val = apr_palloc(pool, size);
108 size = GetEnvironmentVariableA(envvar, val, size);
109 if (size == 0)
110 /* Mid-air collision?. Somebody must've changed the env. var. */
111 return APR_INCOMPLETE;
112 }
113 #endif
114
115 *value = val;
116 return APR_SUCCESS;
117 #endif
118 }
119
120
apr_env_set(const char * envvar,const char * value,apr_pool_t * pool)121 APR_DECLARE(apr_status_t) apr_env_set(const char *envvar,
122 const char *value,
123 apr_pool_t *pool)
124 {
125 #if defined(_WIN32_WCE)
126 return APR_ENOTIMPL;
127 #else
128 #if APR_HAS_UNICODE_FS
129 IF_WIN_OS_IS_UNICODE
130 {
131 apr_wchar_t wenvvar[APR_PATH_MAX];
132 apr_wchar_t *wvalue;
133 apr_size_t inchars, outchars;
134 apr_status_t status;
135
136 status = widen_envvar_name(wenvvar, APR_PATH_MAX, envvar);
137 if (status)
138 return status;
139
140 outchars = inchars = strlen(value) + 1;
141 wvalue = apr_palloc(pool, outchars * sizeof(*wvalue));
142 status = apr_conv_utf8_to_ucs2(value, &inchars, wvalue, &outchars);
143 if (status)
144 return status;
145
146 if (!SetEnvironmentVariableW(wenvvar, wvalue))
147 return apr_get_os_error();
148 }
149 #endif
150 #if APR_HAS_ANSI_FS
151 ELSE_WIN_OS_IS_ANSI
152 {
153 if (!SetEnvironmentVariableA(envvar, value))
154 return apr_get_os_error();
155 }
156 #endif
157
158 return APR_SUCCESS;
159 #endif
160 }
161
162
apr_env_delete(const char * envvar,apr_pool_t * pool)163 APR_DECLARE(apr_status_t) apr_env_delete(const char *envvar, apr_pool_t *pool)
164 {
165 #if defined(_WIN32_WCE)
166 return APR_ENOTIMPL;
167 #else
168 #if APR_HAS_UNICODE_FS
169 IF_WIN_OS_IS_UNICODE
170 {
171 apr_wchar_t wenvvar[APR_PATH_MAX];
172 apr_status_t status;
173
174 status = widen_envvar_name(wenvvar, APR_PATH_MAX, envvar);
175 if (status)
176 return status;
177
178 if (!SetEnvironmentVariableW(wenvvar, NULL))
179 return apr_get_os_error();
180 }
181 #endif
182 #if APR_HAS_ANSI_FS
183 ELSE_WIN_OS_IS_ANSI
184 {
185 if (!SetEnvironmentVariableA(envvar, NULL))
186 return apr_get_os_error();
187 }
188 #endif
189
190 return APR_SUCCESS;
191 #endif
192 }
193