This source file includes following definitions.
- env_init
- env_free
- env_copy
- env_set
- env_set_from_environ
- load_env
- env_get
- env_update_home
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 #include "config.h"
23
24 #include <ctype.h>
25 #include <errno.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <sys/types.h>
29 #include <unistd.h>
30
31 #include "globals.h"
32 #include "funcs.h"
33
34 #if defined(BSD)
35 extern char **environ;
36 #endif
37
38 char **env_init(void) {
39 char **p = (char **) malloc(sizeof (char *));
40
41 if (p != NULL)
42 p[0] = NULL;
43 return (p);
44 }
45
46 void env_free(char **envp) {
47 char **p;
48
49 for (p = envp; *p != NULL; p++)
50 free(*p);
51 free(envp);
52 }
53
54 char **env_copy(char **envp) {
55 int save_errno;
56 size_t count, i;
57 char **p;
58
59 for (count = 0; envp[count] != NULL; count++) ;
60
61 p = (char **) malloc((count + 1) * sizeof (char *));
62 if (p != NULL) {
63 for (i = 0; i < count; i++)
64 if ((p[i] = strdup(envp[i])) == NULL) {
65 save_errno = errno;
66 while (i-- > 0)
67 free(p[i]);
68 free(p);
69 errno = save_errno;
70 return (NULL);
71 }
72 p[count] = NULL;
73 }
74 return (p);
75 }
76
77 char **env_set(char **envp, const char *envstr) {
78 size_t count, found;
79 char **p, *envtmp;
80
81
82
83
84
85 found = (size_t)-1;
86 for (count = 0; envp[count] != NULL; count++) {
87 if (!strcmp_until(envp[count], envstr, '='))
88 found = count;
89 }
90 count++;
91
92 if (found != (size_t)-1) {
93
94
95
96
97 if ((envtmp = strdup(envstr)) == NULL)
98 return (NULL);
99 free(envp[found]);
100 envp[found] = envtmp;
101 return (envp);
102 }
103
104
105
106
107
108
109 if ((envtmp = strdup(envstr)) == NULL)
110 return (NULL);
111 p = (char **) realloc((void *) envp,
112 (count + 1) * sizeof (char *));
113 if (p == NULL) {
114 free(envtmp);
115 return (NULL);
116 }
117 p[count] = p[count - 1];
118 p[count - 1] = envtmp;
119 return (p);
120 }
121
122 int env_set_from_environ(char ***envpp) {
123 static const char *names[] = {
124 "LANG",
125 "LC_CTYPE",
126 "LC_NUMERIC",
127 "LC_TIME",
128 "LC_COLLATE",
129 "LC_MONETARY",
130 "LC_MESSAGES",
131 "LC_PAPER",
132 "LC_NAME",
133 "LC_ADDRESS",
134 "LC_TELEPHONE",
135 "LC_MEASUREMENT",
136 "LC_IDENTIFICATION",
137 "LC_ALL",
138 "LANGUAGE",
139 "RANDOM_DELAY",
140 NULL
141 };
142 const char **name;
143 char **procenv;
144
145 for (procenv = environ; *procenv != NULL; ++procenv) {
146 for (name = names; *name != NULL; ++name) {
147 size_t namelen;
148
149 namelen = strlen(*name);
150 if (strncmp(*name, *procenv, namelen) == 0
151 && (*procenv)[namelen] == '=') {
152 char **tmpenv;
153
154 tmpenv = env_set(*envpp, *procenv);
155 if (tmpenv == NULL)
156 return FALSE;
157 *envpp = tmpenv;
158 }
159 }
160 }
161 return TRUE;
162 }
163
164
165 enum env_state {
166 NAMEI,
167 NAME,
168 EQ1,
169 EQ2,
170 VALUEI,
171 VALUE,
172 FINI,
173 ERROR,
174 };
175
176
177
178
179
180 int load_env(char *envstr, FILE * f) {
181 long filepos;
182 int fileline;
183 enum env_state state;
184 char name[MAX_ENVSTR], val[MAX_ENVSTR];
185 char quotechar, *c, *str;
186
187 filepos = ftell(f);
188 fileline = LineNumber;
189 skip_comments(f);
190 if (EOF == get_string(envstr, MAX_ENVSTR, f, "\n"))
191 return (ERR);
192
193 Debug(DPARS, ("load_env, read <%s>\n", envstr));
194
195 memset(name, 0, sizeof name);
196 memset(val, 0, sizeof val);
197
198 str = name;
199 state = NAMEI;
200 quotechar = '\0';
201 c = envstr;
202 while (state != ERROR && *c) {
203 switch (state) {
204 case NAMEI:
205 case VALUEI:
206 if (*c == '\'' || *c == '"')
207 quotechar = *c++;
208 state++;
209
210 case NAME:
211 case VALUE:
212 if (quotechar) {
213 if (*c == quotechar) {
214 state++;
215 c++;
216 break;
217 }
218 if (state == NAME && *c == '=') {
219 state = ERROR;
220 break;
221 }
222 }
223 else {
224 if (state == NAME) {
225 if (isspace((unsigned char) *c)) {
226 c++;
227 state++;
228 break;
229 }
230 if (*c == '=') {
231 state++;
232 break;
233 }
234 }
235 }
236 *str++ = *c++;
237 break;
238
239 case EQ1:
240 if (*c == '=') {
241 state++;
242 str = val;
243 quotechar = '\0';
244 }
245 else {
246 if (!isspace((unsigned char) *c))
247 state = ERROR;
248 }
249 c++;
250 break;
251
252 case EQ2:
253 case FINI:
254 if (isspace((unsigned char) *c))
255 c++;
256 else
257 state++;
258 break;
259
260 default:
261 abort();
262 }
263 }
264 if (state != FINI && state != EQ2 && !(state == VALUE && !quotechar)) {
265 Debug(DPARS, ("load_env, not an env var, state = %d\n", state));
266 if (fseek(f, filepos, 0)) {
267 return ERR;
268 }
269 Set_LineNum(fileline);
270 return (FALSE);
271 }
272 if (state == VALUE) {
273
274 c = val + strlen(val);
275 while (c > val && isspace((unsigned char) c[-1]))
276 *(--c) = '\0';
277 }
278
279
280
281
282
283
284
285 if (!glue_strings(envstr, MAX_ENVSTR, name, val, '='))
286 return (FALSE);
287 Debug(DPARS, ("load_env, <%s> <%s> -> <%s>\n", name, val, envstr));
288 return (TRUE);
289 }
290
291 char *env_get(const char *name, char **envp) {
292 size_t len = strlen(name);
293 char *p, *q;
294
295 while ((p = *envp++) != NULL) {
296 if (!(q = strchr(p, '=')))
297 continue;
298 if ((q - p) == len && !strncmp(p, name, len))
299 return (q + 1);
300 }
301 return (NULL);
302 }
303
304 char **env_update_home(char **envp, const char *dir) {
305 char envstr[MAX_ENVSTR];
306
307 if (dir == NULL || *dir == '\0' || env_get("HOME", envp)) {
308 return envp;
309 }
310
311 if (glue_strings(envstr, sizeof envstr, "HOME", dir, '=')) {
312 envp = env_set(envp, envstr);
313 }
314 else
315 log_it("CRON", getpid(), "ERROR", "can't set HOME", 0);
316
317 return envp;
318 }