]> granicus.if.org Git - fcron/blob - env_list.c
updated changes/todo
[fcron] / env_list.c
1 /*
2  * FCRON - periodic command scheduler
3  *
4  *  Copyright 2000-2012 Thibault Godouet <fcron@free.fr>
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 2 of the License, or
9  *  (at your option) any later version.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  *  The GNU General Public License can also be found in the file
21  *  `LICENSE' that comes with the fcron source distribution.
22  */
23
24
25 /* List of jobs currently being executed.
26  * This is a wrapper for an u_list (unordered list) (see u_list.h and u_list.c),
27  * to make the rest of the code clearer and as a way to ensure the compiler can checks
28  * the type in the rest of the code (u_list extensively uses the void type) */
29
30 #include "global.h"
31 #include "fcron.h"
32 #include "env_list.h"
33
34 env_list_t *env_list_init(void)
35 {
36     return (env_list_t *) u_list_init(sizeof(env_t),
37             ENVVAR_INITIAL_SIZE, ENVVAR_GROW_SIZE);
38 }
39
40 env_list_t *
41 env_list_copy(env_list_t *list)
42 {
43     env_list_t *new_list = NULL;
44     env_t *e = NULL;
45
46     /* copy the list structure */
47     new_list = (env_list_t *) u_list_copy( (u_list_t *) list);
48
49     /* for now the new list points to the same data strings - duplicate them */
50     for ( e = env_list_first(new_list) ; e != NULL ; e = env_list_next(new_list) ) {
51         e->e_envvar = strdup2(e->e_envvar);
52     }
53
54     return new_list;
55
56 }
57
58 env_t *
59 env_list_setenv(env_list_t *list, char *name, char *value, int overwrite)
60 {
61     env_t e = { NULL };
62     env_t *c = NULL;
63     size_t len = strlen(name)+1+strlen(value)+1; /* 1 for '=', 1 for '\0' */
64
65     /* sanity check */
66     if ( name == NULL || name[0] == '\0' )
67         return NULL;
68
69     /* check if a var 'name' already exists */
70     for ( c = env_list_first(list) ; c != NULL ; c = env_list_next(list) ) {
71         if ( strcmp_until(name, c->e_envvar, '=') == 0 ) {
72             /* variable already set: overwrite the value if asked
73              * and return that entry */
74             if ( overwrite == 1 ) {
75                 c->e_envvar = realloc_safe(c->e_envvar, len, "new env var value");
76                 snprintf(c->e_envvar, len, "%s=%s", name, value);
77             }
78             env_list_end_iteration(list);
79             return c;
80             }
81     }
82
83     /* if we're here we didn't find a var called 'name': add it */
84     e.e_envvar = alloc_safe(len, "new env var");
85     snprintf(e.e_envvar, len, "%s=%s", name, value);
86     return (env_t *) u_list_add( (u_list_t *) list, (u_list_entry_t *) &e);
87 }
88
89 env_t *
90 env_list_putenv(env_list_t *list, char *envvar, int overwrite)
91 {
92     env_t e = { NULL };
93     env_t *c = NULL;
94     size_t len = strlen(envvar) + 1; /* +1 for the terminating '\0' */
95
96     /* sanity check */
97     if ( envvar == NULL || envvar[0] == '\0' )
98         return NULL;
99
100     /* check if a var 'name' already exists */
101     for ( c = env_list_first(list) ; c != NULL ; c = env_list_next(list) ) {
102         if ( strcmp_until(envvar, c->e_envvar, '=') == 0 ) {
103             /* variable already set: overwrite the value if asked
104              * and return that entry */
105             if ( overwrite == 1 ) {
106                 c->e_envvar = realloc_safe(c->e_envvar, len, "new env var value");
107                 memcpy(c->e_envvar, envvar, len); /* includes the final '\0' */
108             }
109             env_list_end_iteration(list);
110             return c;
111             }
112     }
113
114     /* if we're here we didn't find a var called 'name': add it */
115     e.e_envvar = strdup2(envvar);
116     return (env_t *) u_list_add( (u_list_t *) list, (u_list_entry_t *) &e);
117 }
118
119 char *
120 env_list_getenv(env_list_t *list, char *name)
121 {
122     env_t *c = NULL;
123
124     /* sanity check */
125     if ( name == NULL || name[0] == '\0' )
126         return NULL;
127
128     for ( c = env_list_first(list) ; c != NULL ; c = env_list_next(list) ) {
129         if ( strcmp_until(name, c->e_envvar, '=') == 0 ) {
130             /* found the var: return the pointer to the value */
131             env_list_end_iteration(list);
132             return (c->e_envvar+strlen(name)+1); /* +1 for '=' */
133         }
134     }
135
136     /* var 'name' not found */
137     return NULL;
138 }
139
140 env_t *
141 env_list_first(env_list_t *list)
142 {
143     return (env_t *) u_list_first((u_list_t *) list);
144 }
145
146 env_t *
147 env_list_next(env_list_t *list)
148 {
149     return (env_t *) u_list_next((u_list_t *) list);
150 }
151
152 void
153 env_list_end_iteration(env_list_t *list)
154 {
155     u_list_end_iteration((u_list_t *) list);
156 }
157
158 env_list_t *
159 env_list_destroy(env_list_t *list)
160     /* free() the memory allocated for list and returns NULL */
161 {
162     env_t *c = NULL;
163
164     /* make sure the iteration below won't fail in case one was already iterating */
165     env_list_end_iteration(list);
166     /* free the data in the env_t entries */
167     for ( c = env_list_first(list) ; c != NULL ; c = env_list_next(list) ) {
168         Free_safe(c->e_envvar);
169     }
170     /* free the actual list structure */
171     return (env_list_t *) u_list_destroy((u_list_t *) list);
172 }
173
174 char **
175 env_list_export_envp(env_list_t *list)
176 /* export list data as a char **envp structure to use as an argument of execle() */
177 {
178     env_t *c = NULL;
179     int i = 0;
180     char **envp = NULL;
181
182     /* +1 for the end-of-list NULL */
183     envp = alloc_safe((list->num_entries + 1)*sizeof(char *), "environment export");
184
185     for ( c=env_list_first(list), i=0 ; c != NULL && i < list->num_entries ;
186             c=env_list_next(list), i++ ) {
187         envp[i] = strdup2(c->e_envvar);
188     }
189     /* add a NULL as a end-of-list marker */
190     envp[ (list->num_entries + 1 ) - 1] = NULL;
191
192     return envp;
193 }
194
195 void
196 env_list_free_envp(char **envp)
197 {
198     char *p = NULL;
199
200     for ( p = envp[0] ; p != NULL ; p++ ) {
201         Free_safe(p);
202     }
203     Free_safe(envp);
204
205 }
206