/[pdpsoft]/trunk/grid-mw-security/cgul/environ/environ.c
ViewVC logotype

Contents of /trunk/grid-mw-security/cgul/environ/environ.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1446 - (show annotations) (download) (as text)
Sun Jan 31 11:10:18 2010 UTC (11 years, 11 months ago) by msalle
File MIME type: text/x-chdr
File size: 11189 byte(s)
No copyright text for us, only EGEE allowed (instructions from Francesco).


1 /**
2 * Copyright (c) Members of the EGEE Collaboration. 2004.
3 * See http://www.eu-egee.org/partners/ for details on the copyright
4 * holders.
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 * Authors: Oscar Koeroo, Mischa Sall\'e, Aram Verstegen
19 * NIKHEF Amsterdam, the Netherlands
20 * <grid-mw-security@nikhef.nl>
21 */
22
23 #include <unistd.h>
24 #include <stdlib.h>
25 #include <string.h>
26
27 #include "environ.h"
28
29 /**
30 * returns number of entries in NULL terminated string array, such as argv and
31 * environ(7). In case list is NULL it also returns 0.
32 */
33 int strarrlen(const char **list) {
34 int entries;
35 /* Check if list exists: prevents common segfault situation */
36 if (!list) return 0;
37 /* Now loop over its entries */
38 for(entries=0; list[entries]; entries++);
39 return entries;
40 }
41
42 /**
43 * Returns the length of the name part of the var=value pair or -1 when there is
44 * no '=' sign.
45 */
46 int getvarnamelen(const char *varname) {
47 char *pos;
48 /* find first '=' */
49 pos=strchr(varname,'=');
50 if (pos==NULL) /* not var=value */
51 return -1;
52 return strlen(varname)-strlen(pos); /* no pointer arithmetics */
53 }
54
55
56 /**
57 * Finds name for given var=value pair in namevalue. varname is a buffer
58 * which will contain the result and has space for maxvarnamelen chars.
59 * Returns integer, negative on error, -1 on no '=' sign, -2 name too long;
60 * 0 success
61 */
62 int getvarname(char *varname,const int maxvarnamelen, const char *namevalue) {
63 int varnamelen;
64
65 if ((varnamelen=getvarnamelen(namevalue))==-1)
66 return -1;
67 if (varnamelen>maxvarnamelen)
68 return -2;
69 strncpy(varname,namevalue,varnamelen);
70 varname[varnamelen]='\0';
71
72 return 0;
73 }
74
75 /**
76 * Finds index in **src matching variable name, in case of no match (including
77 * env==NULL) returns -1
78 */
79 int getvarindex(const char **src, const char *varname) {
80 int i,len;
81
82 if (src==NULL || varname==NULL)
83 return -1;
84
85 len=strlen(varname);
86 /* Loop over env */
87 for (i=0; src[i]; i++) {
88 if (strncmp(src[i],varname,len)==0 && src[i][len]=='=')
89 /* Found match */
90 return i;
91 }
92 /* NO match found */
93 return -1;
94 }
95
96 /**
97 * Finds the value of varname in src list. Returns NULL when no match, incl.
98 * NULL valued src or varname.
99 */
100 char *getenv_src(const char **src, char *varname) {
101 int i,len;
102
103 /* Don't use getvarindex, since this saves us one strlen (-: */
104 if (src==NULL || varname==NULL)
105 return NULL;
106
107 len=strlen(varname);
108 /* Loop over env */
109 for (i=0; src[i]; i++) {
110 if (strncmp(src[i],varname,len)==0 && src[i][len]=='=')
111 /* Found match */
112 return (char *)&(src[i][len+1]);
113 }
114 /* NO match found */
115 return NULL;
116 }
117
118 /**
119 * As unsetenv(3) but using var=value pair, specified in namevalue. The maximum
120 * var length is MAXVARNAMELEN. See also putenv(3).
121 * Returns integer, 0 on success, negative on error.
122 */
123 int unsetenvpair(const char *namevalue) {
124 char varname[MAXENVVARNAMELEN];
125 int rc;
126
127 /* Get variable name for var=value pair */
128 if ((rc=getvarname(varname,MAXENVVARNAMELEN,namevalue))!=0)
129 return rc;
130 /* Unset variable */
131 if (unsetenv(varname))
132 return -1;
133
134 return 0;
135 }
136
137 /**
138 * Clears the entire environment
139 * Returns integer, -1 on error, 0 on success
140 */
141 int clear_env(void) {
142 while(environ[0])
143 if (unsetenvpair(environ[0]))
144 return -1;
145 return 0;
146 }
147
148 /*
149 * Clears the environment of all variables starting with pattern, case
150 * INsensitive.
151 * Returns number of cleaned entries, -1 on error.
152 */
153 int clear_env_pattern(const char *pattern) {
154 int i=0,match=0,patlen=strlen(pattern),rc;
155
156 while(environ[i]) {
157 if (strncasecmp(pattern,environ[i],patlen)==0) {
158 if ((rc=unsetenvpair(environ[i])))
159 return rc;
160 match++;
161 } else
162 i++; /* only increase when we haven't just removed an entry... */
163 }
164 return match;
165 }
166
167
168 /**
169 * Returns a duplicate of src. In case dst!=NULL it will be used and should be
170 * big enough. Otherwise space is malloced.
171 */
172 char **copy_env(char **dst,const char **src) {
173 int i,j,envlen;
174 char **newenv;
175
176 /* If no dst exists, malloc it. */
177 if (dst==NULL) {
178 envlen=strarrlen(src);
179 if ( (newenv=(char **)malloc((envlen+1)*sizeof(char*)))==NULL )
180 return NULL;
181 } else
182 newenv=dst;
183
184 /* Copy src to newenv */
185 for (i=0; src[i]; i++) {
186 if ( (newenv[i]=strdup(src[i]))==NULL ) {
187 /* Error: cleanup memory and reset */
188 for (j=0; j<i; j++)
189 free(newenv[j]);
190 if (dst==NULL)
191 free(newenv);
192 return NULL;
193 }
194 }
195 /* Finalize the new environ */
196 newenv[i]=NULL;
197
198 return newenv;
199 }
200
201 /**
202 * Same as copy_env() but first unsets all environment variables starting with
203 * MALLOC, case INsensitive.
204 */
205 char **safe_copy_env(char **dst,const char **src) {
206 /* Clean all MALLOC* variables */
207 if (clear_env_pattern("MALLOC"))
208 return NULL;
209
210 return copy_env(dst,src);
211 }
212
213 /**
214 * Creates a list of the var=value pairs from src which have varname in list.
215 * If it fails NULL is returned. This can also be done using add_src_list()
216 * using dst==NULL, but this is more efficiently coded. All new entries are
217 * strdup-ed from those in src.
218 */
219 char **copy_src_list(const char **src,const char **list) {
220 /* Create target space */
221 int i,j,src_idx,match=0,listlen=strarrlen(list);
222 char **newenv;
223
224 if ((newenv=(char **)malloc((listlen+1)*sizeof(char*)))==NULL)
225 return NULL;
226 /* IMPORTANT: list must be NULL terminated! */
227 newenv[0]=NULL;
228 /* loop over list: Note we can have unmatched entries: match counts */
229 for (i=0; list[i]; i++) {
230 /* Look if list[i] is in src */
231 if ((src_idx=getvarindex(src,list[i]))>=0) {
232 /* Don't! check for duplicates... */
233 /* substitute existing: first try strdup */
234 if ((newenv[match]=strdup(src[src_idx]))==NULL) {
235 /* error: cleanup */
236 for (j=0; j<match; j++) {
237 free(newenv[j]); newenv[j]=NULL;
238 }
239 free(newenv);
240 return NULL;
241 }
242 match++;
243 /* Don't forget the final NULL pointer! */
244 newenv[match]=NULL;
245 }
246 }
247 return newenv;
248 }
249
250 /**
251 * Adds to dst the var=value pairs from src which have varname in list.
252 * All entries will be strdup-ed from those in src.
253 * If dst is NULL, it will create a new one. dst will be realloc-ed. If it fails
254 * NULL is returned, when failure occurs later on, dst will be returned, being
255 * equal to the original src but at a different memory location.
256 * See also copy_src_list() which is more efficient when dst is NULL !
257 */
258 char **add_src_list(char **dst,const char **src,const char **list) {
259 int i,j,src_idx,dst_idx,match=0;
260 int dstlen=strarrlen((const char**)dst),listlen=strarrlen(list);
261 char **newenv,*dummy;
262
263 /* Create space for combined array, might be too much if list is not fully
264 * used or partially replaces old entries, but more efficient (single
265 * realloc() call) */
266 if (dst==NULL) {
267 newenv=(char **)malloc((listlen+1)*sizeof(char*));
268 if (newenv==NULL)
269 return NULL;
270 /* IMPORTANT: list must be NULL terminated! */
271 newenv[0]=NULL;
272 } else {
273 newenv=(char **)realloc(dst,(dstlen+listlen+1)*sizeof(char*));
274 if (newenv==NULL)
275 return NULL;
276 }
277
278 /* loop over list: Note we can have unmatched entries: match counts */
279 for (i=0; list[i]; i++) {
280 /* Look if list[i] is in src */
281 if ((src_idx=getvarindex(src,list[i]))>=0) {
282 /* Look for list[i] in dst/newenv: we might have it already. Note
283 * that this is not checked when using copy_src_list() */
284 if ((dst_idx=getvarindex((const char**)newenv,list[i]))>=0) {
285 /* substitute existing: first try strdup */
286 if ((dummy=strdup(src[src_idx]))==NULL) { /* error: cleanup */
287 for (j=dstlen; j<dstlen+match; j++) {
288 free(newenv[j]); newenv[j]=NULL;
289 }
290 return newenv;
291 }
292 /* Now substitute: free old entry in newenv and link to new
293 * entry */
294 free(newenv[dst_idx]);
295 newenv[dst_idx]=dummy;
296 } else {
297 /* create new one */
298 if ((newenv[dstlen+match]=strdup(src[src_idx]))==NULL) {
299 /* Error: cleanup */
300 for (j=dstlen; j<dstlen+match; j++) {
301 free(newenv[j]); newenv[j]=NULL;
302 }
303 return newenv;
304 }
305 /* We created a new entry, increase match */
306 match++;
307 /* Don't forget the final NULL pointer! */
308 newenv[dstlen+match]=NULL;
309 }
310 }
311 }
312 return newenv;
313 }
314
315 /**
316 * adds var=value pair to dst. If the variable already exists, it's entry is
317 * replaced. Otherwise dst is realloc-ed and a new entry is added, the resulting
318 * array is returned. In case of error NULL is returned and dst is unchanged.
319 * namevalue is strdup-ed into dst and hence can be freed by the caller (unlike
320 * putenv(3p) )
321 */
322 char **add_namevalue(char **dst,const char *namevalue) {
323 int i,namelen,dstlen;
324 char *dummy, **newenv;
325
326 /* Look for length of name part (no = means no name) */
327 if ((namelen=getvarnamelen(namevalue))<0)
328 return NULL;
329 /* look for existing entry */
330 for (i=0; dst[i]; i++) {
331 if (strncmp(namevalue,dst[i],namelen)==0 && dst[i][namelen]=='=') {
332 if ((dummy=strdup(namevalue))==NULL)
333 return NULL;
334 free(dst[i]);
335 dst[i]=dummy;
336 return dst;
337 }
338 }
339 /* No old match, make a new entry, add two, because strarrlen doesn't count
340 * the NULL string at the end. First create new entry, since that's easier
341 * to undo. */
342 if ((dummy=strdup(namevalue))==NULL)
343 return NULL;
344 dstlen=strarrlen((const char **)dst);
345 if ((newenv=(char **)realloc(dst,(dstlen+2)*sizeof(char*)))==NULL)
346 return NULL;
347 newenv[dstlen]=dummy;
348 newenv[dstlen+1]=NULL;
349
350 return newenv;
351 }
352
353 /**
354 * Adds to the current environment the var=value pairs from src which have
355 * varname in list. Returns number of entries added or -1 on error.
356 * NOTE: putenv doesn't reserve new memory so src should NOT be
357 * free()d.
358 */
359 int putenv_src_list(char **src,const char **list) {
360 int i,src_idx,match=0;
361
362 /* loop over list */
363 for (i=0; list[i]; i++) {
364 if ((src_idx=getvarindex((const char **)src,list[i]))>=0) {
365 /* Found match */
366 if (putenv(src[src_idx]))
367 return -1;
368 match++;
369 }
370 }
371 return match;
372 }
373
374 /**
375 * Adds to the current environment the var=value pairs from src which start with
376 * pattern. Returns number of entries added or -1 on error.
377 * NOTE: putenv doesn't reserve new memory so src should NOT be
378 * free()d.
379 */
380 int putenv_src_pattern(char **src,const char *pattern) {
381 int i,len=strlen(pattern),match=0;
382
383 /* loop over src environ */
384 for (i=0; src[i]; i++) {
385 if (strncmp(src[i],pattern,len)==0) {
386 /* Found match */
387 if (putenv(src[i]))
388 return -1;
389 match++;
390 }
391 }
392 return match;
393 }
394

grid.support@nikhef.nl
ViewVC Help
Powered by ViewVC 1.1.28