xref: /openbsd-src/usr.sbin/cron/env.c (revision 47911bd667ac77dc523b8a13ef40b012dbffa741)
1 /*	$OpenBSD: env.c,v 1.13 2002/07/11 20:15:40 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 const rcsid[] = "$OpenBSD: env.c,v 1.13 2002/07/11 20:15:40 millert Exp $";
25 #endif
26 
27 #include "cron.h"
28 
29 char **
30 env_init(void) {
31 	char **p = (char **) malloc(sizeof(char **));
32 
33 	if (p != NULL)
34 		p[0] = NULL;
35 	return (p);
36 }
37 
38 void
39 env_free(char **envp) {
40 	char **p;
41 
42 	for (p = envp; *p != NULL; p++)
43 		free(*p);
44 	free(envp);
45 }
46 
47 char **
48 env_copy(char **envp) {
49 	int count, i, save_errno;
50 	char **p;
51 
52 	for (count = 0; envp[count] != NULL; count++)
53 		continue;
54 	p = (char **) malloc((count+1) * sizeof(char *));  /* 1 for the NULL */
55 	if (p != NULL) {
56 		for (i = 0; i < count; i++)
57 			if ((p[i] = strdup(envp[i])) == NULL) {
58 				save_errno = errno;
59 				while (--i >= 0)
60 					free(p[i]);
61 				free(p);
62 				errno = save_errno;
63 				return (NULL);
64 			}
65 		p[count] = NULL;
66 	}
67 	return (p);
68 }
69 
70 char **
71 env_set(char **envp, char *envstr) {
72 	int count, found;
73 	char **p, *envtmp;
74 
75 	/*
76 	 * count the number of elements, including the null pointer;
77 	 * also set 'found' to -1 or index of entry if already in here.
78 	 */
79 	found = -1;
80 	for (count = 0; envp[count] != NULL; count++) {
81 		if (!strcmp_until(envp[count], envstr, '='))
82 			found = count;
83 	}
84 	count++;	/* for the NULL */
85 
86 	if (found != -1) {
87 		/*
88 		 * it exists already, so just free the existing setting,
89 		 * save our new one there, and return the existing array.
90 		 */
91 		if ((envtmp = strdup(envstr)) == NULL)
92 			return (NULL);
93 		free(envp[found]);
94 		envp[found] = envtmp;
95 		return (envp);
96 	}
97 
98 	/*
99 	 * it doesn't exist yet, so resize the array, move null pointer over
100 	 * one, save our string over the old null pointer, and return resized
101 	 * array.
102 	 */
103 	if ((envtmp = strdup(envstr)) == NULL)
104 		return (NULL);
105 	p = (char **) realloc((void *) envp,
106 			      (size_t) ((count+1) * sizeof(char **)));
107 	if (p == NULL) {
108 		free(envtmp);
109 		return (NULL);
110 	}
111 	p[count] = p[count-1];
112 	p[count-1] = envtmp;
113 	return (p);
114 }
115 
116 /* return	ERR = end of file
117  *		FALSE = not an env setting (file was repositioned)
118  *		TRUE = was an env setting
119  */
120 int
121 load_env(char *envstr, FILE *f) {
122 	long filepos;
123 	int fileline;
124 	char name[MAX_ENVSTR], val[MAX_ENVSTR];
125 	int fields;
126 
127 	filepos = ftell(f);
128 	fileline = LineNumber;
129 	skip_comments(f);
130 	if (EOF == get_string(envstr, MAX_ENVSTR, f, "\n"))
131 		return (ERR);
132 
133 	Debug(DPARS, ("load_env, read <%s>\n", envstr))
134 
135 	name[0] = val[0] = '\0';
136 	fields = sscanf(envstr, "%[^ =] = %[^\n#]", name, val);
137 	if (fields != 2) {
138 		Debug(DPARS, ("load_env, not 2 fields (%d)\n", fields))
139 		fseek(f, filepos, 0);
140 		Set_LineNum(fileline);
141 		return (FALSE);
142 	}
143 
144 	/*
145 	 * 2 fields from scanf; looks like an env setting.
146 	 */
147 
148 	/*
149 	 * process value string
150 	 */
151 	/*local*/{
152 		int	len = strdtb(val);
153 
154 		if (len >= 2) {
155 			if (val[0] == '\'' || val[0] == '"') {
156 				if (val[len-1] == val[0]) {
157 					val[len-1] = '\0';
158 					memmove(val, val+1, len);
159 				}
160 			}
161 		}
162 	}
163 
164 	/*
165 	 * This can't overflow because get_string() limited the size of the
166 	 * name and val fields.  Still, it doesn't hurt...
167 	 */
168 	(void) snprintf(envstr, MAX_ENVSTR, "%s=%s", name, val);
169 	Debug(DPARS, ("load_env, <%s> <%s> -> <%s>\n", name, val, envstr))
170 	return (TRUE);
171 }
172 
173 char *
174 env_get(char *name, char **envp) {
175 	int len = strlen(name);
176 	char *p, *q;
177 
178 	while ((p = *envp++) != NULL) {
179 		if (!(q = strchr(p, '=')))
180 			continue;
181 		if ((q - p) == len && !strncmp(p, name, len))
182 			return (q+1);
183 	}
184 	return (NULL);
185 }
186