/[pkg-cron]/branches/proposal-112/env.c
ViewVC logotype

Contents of /branches/proposal-112/env.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 514 - (show annotations) (download)
Wed May 5 22:18:51 2010 UTC (3 years, 1 month ago) by jfs
Original Path: tags/debian_version_3.0pl1-110/env.c
File MIME type: text/plain
File size: 6023 byte(s)
Debian package version 3.0pl1-110
1 /* Copyright 1988,1990,1993,1994 by Paul Vixie
2 * All rights reserved
3 *
4 * Distribute freely, except: don't remove my name from the source or
5 * documentation (don't take credit for my work), mark your changes (don't
6 * get me blamed for your possible bugs), don't alter or remove this
7 * notice. May be sold if buildable source is provided to buyer. No
8 * warrantee of any kind, express or implied, is included with this
9 * software; use at your own risk, responsibility for damages (if any) to
10 * anyone resulting from the use of this software rests entirely with the
11 * user.
12 *
13 * Send bug reports, bug fixes, enhancements, requests, flames, etc., and
14 * I'll try to keep a version up to date. I can be reached as follows:
15 * Paul Vixie <paul@vix.com> uunet!decwrl!vixie!paul
16 */
17
18 #if !defined(lint) && !defined(LINT)
19 static char rcsid[] = "$Id: env.c,v 2.7 1994/01/26 02:25:50 vixie Exp vixie $";
20 #endif
21
22
23 #include "cron.h"
24
25
26 char **
27 env_init()
28 {
29 register char **p = (char **) malloc(sizeof(char **));
30
31 if (p)
32 p[0] = NULL;
33 return (p);
34 }
35
36
37 void
38 env_free(envp)
39 char **envp;
40 {
41 char **p;
42
43 if(!envp)
44 return;
45
46 for (p = envp; *p; p++)
47 free(*p);
48 free(envp);
49 }
50
51
52 char **
53 env_copy(envp)
54 register char **envp;
55 {
56 register int count, i;
57 register char **p;
58
59 for (count = 0; envp[count] != NULL; count++)
60 ;
61 p = (char **) malloc((count+1) * sizeof(char *)); /* 1 for the NULL */
62 if (p == NULL) {
63 errno = ENOMEM;
64 return NULL;
65 }
66 for (i = 0; i < count; i++)
67 if ((p[i] = strdup(envp[i])) == NULL) {
68 while (--i >= 0)
69 (void) free(p[i]);
70 free(p);
71 errno = ENOMEM;
72 return NULL;
73 }
74 p[count] = NULL;
75 return (p);
76 }
77
78
79 char **
80 env_set(envp, envstr)
81 char **envp;
82 char *envstr;
83 {
84 register int count, found;
85 register char **p;
86
87 /*
88 * count the number of elements, including the null pointer;
89 * also set 'found' to -1 or index of entry if already in here.
90 */
91 found = -1;
92 for (count = 0; envp[count] != NULL; count++) {
93 if (!strcmp_until(envp[count], envstr, '='))
94 found = count;
95 }
96 count++; /* for the NULL */
97
98 if (found != -1) {
99 /*
100 * it exists already, so just free the existing setting,
101 * save our new one there, and return the existing array.
102 */
103 free(envp[found]);
104 if ((envp[found] = strdup(envstr)) == NULL) {
105 envp[found] = "";
106 errno = ENOMEM;
107 return NULL;
108 }
109 return (envp);
110 }
111
112 /*
113 * it doesn't exist yet, so resize the array, move null pointer over
114 * one, save our string over the old null pointer, and return resized
115 * array.
116 */
117 p = (char **) realloc((void *) envp,
118 (unsigned) ((count+1) * sizeof(char **)));
119 if (p == NULL) {
120 errno = ENOMEM;
121 return NULL;
122 }
123 p[count] = p[count-1];
124 if ((p[count-1] = strdup(envstr)) == NULL) {
125 errno = ENOMEM;
126 return NULL;
127 }
128 return (p);
129 }
130
131 /* The following states are used by load_env(), traversed in order: */
132 enum env_state {
133 NAMEI, /* First char of NAME, may be quote */
134 NAME, /* Subsequent chars of NAME */
135 EQ1, /* After end of name, looking for '=' sign */
136 EQ2, /* After '=', skipping whitespace */
137 VALUEI, /* First char of VALUE, may be quote */
138 VALUE, /* Subsequent chars of VALUE */
139 FINI, /* All done, skipping trailing whitespace */
140 ERROR, /* Error */
141 };
142
143 /* return ERR = end of file
144 * FALSE = not an env setting (file was repositioned)
145 * TRUE = was an env setting
146 */
147 int
148 load_env(envstr, f)
149 char *envstr;
150 FILE *f;
151 {
152 long filepos;
153 int fileline;
154 enum env_state state;
155 char name[MAX_ENVSTR], val[MAX_ENVSTR];
156 char quotechar, *c, *str;
157
158 filepos = ftell(f);
159 fileline = LineNumber;
160 skip_comments(f);
161 if (EOF == get_string(envstr, MAX_ENVSTR - 1, f, "\n"))
162 return (ERR);
163
164 envstr[MAX_ENVSTR - 1] = '\0';
165
166 Debug(DPARS, ("load_env, read <%s>\n", envstr))
167
168 bzero(name, sizeof name);
169 bzero(val, sizeof val);
170 str = name;
171 state = NAMEI;
172 quotechar = '\0';
173 c = envstr;
174 while (state != ERROR && *c) {
175 switch (state) {
176 case NAMEI:
177 case VALUEI:
178 if (*c == '\'' || *c == '"')
179 quotechar = *c++;
180 state++;
181 /* FALLTHROUGH */
182 case NAME:
183 case VALUE:
184 if (quotechar) {
185 if (*c == quotechar) {
186 state++;
187 c++;
188 break;
189 }
190 if (state == NAME && *c == '=') {
191 state = ERROR;
192 break;
193 }
194 } else {
195 if (state == NAME) {
196 if (isspace((unsigned char)*c)) {
197 c++;
198 state++;
199 break;
200 }
201 if (*c == '=') {
202 state++;
203 break;
204 }
205 }
206 }
207 *str++ = *c++;
208 break;
209
210 case EQ1:
211 if (*c == '=') {
212 state++;
213 str = val;
214 quotechar = '\0';
215 } else {
216 if (!isspace((unsigned char)*c))
217 state = ERROR;
218 }
219 c++;
220 break;
221
222 case EQ2:
223 case FINI:
224 if (isspace((unsigned char)*c))
225 c++;
226 else
227 state++;
228 break;
229
230 default:
231 abort();
232 }
233 }
234 if (state != FINI && !(state == VALUE && !quotechar)) {
235 Debug(DPARS, ("load_env, not an env var, state = %d\n", state))
236 fseek(f, filepos, 0);
237 Set_LineNum(fileline);
238 return (FALSE);
239 }
240 if (state == VALUE) {
241 /* End of unquoted value: trim trailing whitespace */
242 c = val + strlen(val);
243 while (c > val && isspace((unsigned char)c[-1]))
244 *(--c) = '\0';
245 }
246
247 /* 2 fields from parser; looks like an env setting */
248
249 /*
250 * This can't overflow because get_string() limited the size of the
251 * name and val fields. Still, it doesn't hurt to be careful...
252 */
253 /*local*/{
254 int len = strdtb(val);
255
256 if (len >= 2) {
257 if (val[0] == '\'' || val[0] == '"') {
258 if (val[len-1] == val[0]) {
259 val[len-1] = '\0';
260 (void) strcpy(val, val+1);
261 }
262 }
263 }
264 }
265
266 if (strlen(name) + 1 + strlen(val) >= MAX_ENVSTR-1)
267 return (FALSE);
268 (void) sprintf(envstr, "%s=%s", name, val);
269 Debug(DPARS, ("load_env, <%s> <%s> -> <%s>\n", name, val, envstr))
270 return (TRUE);
271 }
272
273 char *
274 env_get(name, envp)
275 register char *name;
276 register char **envp;
277 {
278 register int len = strlen(name);
279 register char *p, *q;
280
281 while ((p = *envp++)) {
282 if (!(q = strchr(p, '=')))
283 continue;
284 if ((q - p) == len && !strncmp(p, name, len))
285 return (q+1);
286 }
287 return (NULL);
288 }

Properties

Name Value
svn:eol-style native

  ViewVC Help
Powered by ViewVC 1.1.5