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