1 /* Copyright 1988,1990,1993,1994 by Paul Vixie
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
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
18 #if !defined(lint) && !defined(LINT)
19 static const char rcsid[] =
30 register char **p = (char **) malloc(sizeof(char *));
55 register int count, i;
58 for (count = 0; envp[count] != NULL; count++)
60 p = (char **) malloc((count+1) * sizeof(char *)); /* 1 for the NULL */
65 for (i = 0; i < count; i++)
66 if ((p[i] = strdup(envp[i])) == NULL) {
83 register int count, found;
88 * count the number of elements, including the null pointer;
89 * also set 'found' to -1 or index of entry if already in here.
92 for (count = 0; envp[count] != NULL; count++) {
93 if (!strcmp_until(envp[count], envstr, '='))
96 count++; /* for the NULL */
100 * it exists already, so just free the existing setting,
101 * save our new one there, and return the existing array.
104 if ((envp[found] = strdup(envstr)) == NULL) {
106 /* XXX env_free(envp); */
115 * it doesn't exist yet, so resize the array, move null pointer over
116 * one, save our string over the old null pointer, and return resized
119 p = (char **) realloc((void *) envp,
120 (unsigned) ((count+1) * sizeof(char *)));
122 /* XXX env_free(envp); */
126 p[count] = p[count-1];
127 if ((p[count-1] = strdup(envstr)) == NULL) {
136 /* return ERR = end of file
137 * FALSE = not an env setting (file was repositioned)
138 * TRUE = was an env setting
147 char name[MAX_ENVSTR], val[MAX_ENVSTR];
148 char quotechar, *c, *str;
151 /* The following states are traversed in order: */
152 #define NAMEI 0 /* First char of NAME, may be quote */
153 #define NAME 1 /* Subsequent chars of NAME */
154 #define EQ1 2 /* After end of name, looking for '=' sign */
155 #define EQ2 3 /* After '=', skipping whitespace */
156 #define VALUEI 4 /* First char of VALUE, may be quote */
157 #define VALUE 5 /* Subsequent chars of VALUE */
158 #define FINI 6 /* All done, skipping trailing whitespace */
159 #define ERROR 7 /* Error */
162 fileline = LineNumber;
164 if (EOF == get_string(envstr, MAX_ENVSTR, f, "\n"))
167 Debug(DPARS, ("load_env, read <%s>\n", envstr));
169 bzero (name, sizeof name);
170 bzero (val, sizeof val);
175 while (state != ERROR && *c) {
179 if (*c == '\'' || *c == '"')
186 if (*c == quotechar) {
191 if (state == NAME && *c == '=') {
231 if (state != FINI && !(state == VALUE && !quotechar)) {
232 Debug(DPARS, ("load_env, parse error, state = %d\n", state))
233 fseek(f, filepos, 0);
234 Set_LineNum(fileline);
237 if (state == VALUE) {
238 /* End of unquoted value: trim trailing whitespace */
239 c = val + strlen (val);
240 while (c > val && isspace (*(c - 1)))
244 /* 2 fields from parser; looks like an env setting */
246 if (strlen(name) + 1 + strlen(val) >= MAX_ENVSTR-1)
248 (void) sprintf(envstr, "%s=%s", name, val);
249 Debug(DPARS, ("load_env, <%s> <%s> -> <%s>\n", name, val, envstr))
257 register char **envp;
259 register int len = strlen(name);
260 register char *p, *q;
262 while ((p = *envp++)) {
263 if (!(q = strchr(p, '=')))
265 if ((q - p) == len && !strncmp(p, name, len))