xref: /openbsd-src/usr.sbin/cron/env.c (revision b2ea75c1b17e1a9a339660e7ed45cd24946b230e)
1 /*	$OpenBSD: env.c,v 1.9 2001/02/18 20:17:20 millert Exp $	*/
2 /* Copyright 1988,1990,1993,1994 by Paul Vixie
3  * All rights reserved
4  */
5 
6 /*
7  * Copyright (c) 1997,2000 by Internet Software Consortium, Inc.
8  *
9  * Permission to use, copy, modify, and distribute this software for any
10  * purpose with or without fee is hereby granted, provided that the above
11  * copyright notice and this permission notice appear in all copies.
12  *
13  * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
14  * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
15  * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
16  * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
17  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
18  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
19  * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
20  * SOFTWARE.
21  */
22 
23 #if !defined(lint) && !defined(LINT)
24 static char rcsid[] = "$OpenBSD: env.c,v 1.9 2001/02/18 20:17:20 millert Exp $";
25 #endif
26 
27 
28 #include "cron.h"
29 
30 
31 char **
32 env_init()
33 {
34 	char	**p = (char **) malloc(sizeof(char **));
35 
36 	if (p != NULL)
37 		p[0] = NULL;
38 	return (p);
39 }
40 
41 
42 void
43 env_free(envp)
44 	char	**envp;
45 {
46 	char	**p;
47 
48 	for (p = envp;  *p;  p++)
49 		free(*p);
50 	free(envp);
51 }
52 
53 
54 char **
55 env_copy(envp)
56 	char	**envp;
57 {
58 	int	count, i, save_errno;
59 	char	**p;
60 
61 	for (count = 0;  envp[count] != NULL;  count++)
62 		;
63 	p = (char **) malloc((count+1) * sizeof(char *));  /* 1 for the NULL */
64 	if (p != NULL) {
65 		for (i = 0;  i < count;  i++)
66 			if ((p[i] = strdup(envp[i])) == NULL) {
67 				save_errno = errno;
68 				while (--i >= 0)
69 					free(p[i]);
70 				free(p);
71 				errno = save_errno;
72 				return (NULL);
73 			}
74 		p[count] = NULL;
75 	}
76 	return (p);
77 }
78 
79 
80 char **
81 env_set(envp, envstr)
82 	char	**envp;
83 	char	*envstr;
84 {
85 	int	count, found;
86 	char	**p, *cp;
87 
88 	/*
89 	 * count the number of elements, including the null pointer;
90 	 * also set 'found' to -1 or index of entry if already in here.
91 	 */
92 	found = -1;
93 	for (count = 0;  envp[count] != NULL;  count++) {
94 		if (!strcmp_until(envp[count], envstr, '='))
95 			found = count;
96 	}
97 	count++;	/* for the NULL */
98 
99 	if (found != -1) {
100 		/*
101 		 * it exists already, so just free the existing setting,
102 		 * save our new one there, and return the existing array.
103 		 */
104 		free(envp[found]);
105 		if ((envp[found] = strdup(envstr)) == NULL) {
106 			envp[found] = "";
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 			      (size_t) ((count+1) * sizeof(char **)));
119 	if (p == NULL)
120 		return (NULL);
121 	cp = strdup(envstr);
122 	if (cp == NULL)
123 		return(NULL);
124 	p[count] = p[count-1];
125 	p[count-1] = cp;
126 	return (p);
127 }
128 
129 
130 /* return	ERR = end of file
131  *		FALSE = not an env setting (file was repositioned)
132  *		TRUE = was an env setting
133  */
134 int
135 load_env(envstr, f)
136 	char	*envstr;
137 	FILE	*f;
138 {
139 	long	filepos;
140 	int	fileline;
141 	char	name[MAX_ENVSTR], val[MAX_ENVSTR];
142 	int	fields;
143 
144 	filepos = ftell(f);
145 	fileline = LineNumber;
146 	skip_comments(f);
147 	if (EOF == get_string(envstr, MAX_ENVSTR, f, "\n"))
148 		return (ERR);
149 
150 	Debug(DPARS, ("load_env, read <%s>\n", envstr))
151 
152 	name[0] = val[0] = '\0';
153 	fields = sscanf(envstr, "%[^ =] = %[^\n#]", name, val);
154 	if (fields != 2) {
155 		Debug(DPARS, ("load_env, not 2 fields (%d)\n", fields))
156 		fseek(f, filepos, 0);
157 		Set_LineNum(fileline);
158 		return (FALSE);
159 	}
160 
161 	/*
162 	 * 2 fields from scanf; looks like an env setting.
163 	 */
164 
165 	/*
166 	 * process value string
167 	 */
168 	/*local*/{
169 		int	len = strdtb(val);
170 
171 		if (len >= 2) {
172 			if (val[0] == '\'' || val[0] == '"') {
173 				if (val[len-1] == val[0]) {
174 					val[len-1] = '\0';
175 					memmove(val, val+1, len);
176 				}
177 			}
178 		}
179 	}
180 
181 	/*
182 	 * This can't overflow because get_string() limited the size of the
183 	 * name and val fields.  Still, it doesn't hurt...
184 	 */
185 	(void) snprintf(envstr, MAX_ENVSTR, "%s=%s", name, val);
186 	Debug(DPARS, ("load_env, <%s> <%s> -> <%s>\n", name, val, envstr))
187 	return (TRUE);
188 }
189 
190 
191 char *
192 env_get(name, envp)
193 	char	*name;
194 	char	**envp;
195 {
196 	int	len = strlen(name);
197 	char	*p, *q;
198 
199 	while ((p = *envp++) != NULL) {
200 		if (!(q = strchr(p, '=')))
201 			continue;
202 		if ((q - p) == len && !strncmp(p, name, len))
203 			return (q+1);
204 	}
205 	return (NULL);
206 }
207