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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1446 - (hide annotations) (download) (as text)
Sun Jan 31 11:10:18 2010 UTC (12 years, 3 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 msalle 1446 /**
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 msalle 1420 #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 msalle 1429 * environ(7). In case list is NULL it also returns 0.
32 msalle 1420 */
33     int strarrlen(const char **list) {
34     int entries;
35 msalle 1436 /* Check if list exists: prevents common segfault situation */
36 msalle 1429 if (!list) return 0;
37 msalle 1436 /* Now loop over its entries */
38 msalle 1420 for(entries=0; list[entries]; entries++);
39     return entries;
40     }
41    
42     /**
43 msalle 1436 * 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 msalle 1441 return strlen(varname)-strlen(pos); /* no pointer arithmetics */
53 msalle 1436 }
54    
55    
56     /**
57 msalle 1420 * 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 msalle 1436 if ((varnamelen=getvarnamelen(namevalue))==-1)
66 msalle 1420 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 msalle 1439 * Finds index in **src matching variable name, in case of no match (including
77 msalle 1436 * env==NULL) returns -1
78     */
79 msalle 1441 int getvarindex(const char **src, const char *varname) {
80 msalle 1436 int i,len;
81    
82 msalle 1441 if (src==NULL || varname==NULL)
83 msalle 1436 return -1;
84    
85 msalle 1441 len=strlen(varname);
86 msalle 1436 /* Loop over env */
87     for (i=0; src[i]; i++) {
88 msalle 1441 if (strncmp(src[i],varname,len)==0 && src[i][len]=='=')
89     /* Found match */
90 msalle 1436 return i;
91     }
92     /* NO match found */
93     return -1;
94     }
95    
96     /**
97 msalle 1441 * 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 msalle 1420 * 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 msalle 1436 /* Get variable name for var=value pair */
128 msalle 1420 if ((rc=getvarname(varname,MAXENVVARNAMELEN,namevalue))!=0)
129     return rc;
130 msalle 1436 /* Unset variable */
131 msalle 1420 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 msalle 1436 * Creates a list of the var=value pairs from src which have varname in list.
215 msalle 1441 * 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 msalle 1436 */
219     char **copy_src_list(const char **src,const char **list) {
220     /* Create target space */
221 msalle 1439 int i,j,src_idx,match=0,listlen=strarrlen(list);
222 msalle 1436 char **newenv;
223    
224     if ((newenv=(char **)malloc((listlen+1)*sizeof(char*)))==NULL)
225     return NULL;
226 msalle 1439 /* IMPORTANT: list must be NULL terminated! */
227     newenv[0]=NULL;
228 msalle 1436 /* 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 msalle 1439 /* Don't forget the final NULL pointer! */
244     newenv[match]=NULL;
245 msalle 1436 }
246     }
247     return newenv;
248     }
249    
250     /**
251 msalle 1420 * Adds to dst the var=value pairs from src which have varname in list.
252 msalle 1439 * All entries will be strdup-ed from those in src.
253 msalle 1420 * 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 msalle 1436 * See also copy_src_list() which is more efficient when dst is NULL !
257 msalle 1420 */
258     char **add_src_list(char **dst,const char **src,const char **list) {
259 msalle 1436 int i,j,src_idx,dst_idx,match=0;
260 msalle 1420 int dstlen=strarrlen((const char**)dst),listlen=strarrlen(list);
261 msalle 1436 char **newenv,*dummy;
262 msalle 1420
263     /* Create space for combined array, might be too much if list is not fully
264 msalle 1436 * 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 msalle 1420
278 msalle 1436 /* 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 msalle 1420 /* Error: cleanup */
300 msalle 1436 for (j=dstlen; j<dstlen+match; j++) {
301     free(newenv[j]); newenv[j]=NULL;
302 msalle 1420 }
303     return newenv;
304     }
305 msalle 1436 /* We created a new entry, increase match */
306 msalle 1420 match++;
307 msalle 1436 /* Don't forget the final NULL pointer! */
308     newenv[dstlen+match]=NULL;
309 msalle 1420 }
310     }
311     }
312     return newenv;
313     }
314    
315     /**
316 msalle 1436 * 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 msalle 1439 * namevalue is strdup-ed into dst and hence can be freed by the caller (unlike
320     * putenv(3p) )
321 msalle 1436 */
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 msalle 1420 * 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 msalle 1436 int i,src_idx,match=0;
361 msalle 1420
362 msalle 1436 /* 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 msalle 1420 }
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