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