xref: /dragonfly/usr.sbin/cron/lib/env.c (revision 86d7f5d3)
1*86d7f5d3SJohn Marino /* Copyright 1988,1990,1993,1994 by Paul Vixie
2*86d7f5d3SJohn Marino  * All rights reserved
3*86d7f5d3SJohn Marino  *
4*86d7f5d3SJohn Marino  * Distribute freely, except: don't remove my name from the source or
5*86d7f5d3SJohn Marino  * documentation (don't take credit for my work), mark your changes (don't
6*86d7f5d3SJohn Marino  * get me blamed for your possible bugs), don't alter or remove this
7*86d7f5d3SJohn Marino  * notice.  May be sold if buildable source is provided to buyer.  No
8*86d7f5d3SJohn Marino  * warrantee of any kind, express or implied, is included with this
9*86d7f5d3SJohn Marino  * software; use at your own risk, responsibility for damages (if any) to
10*86d7f5d3SJohn Marino  * anyone resulting from the use of this software rests entirely with the
11*86d7f5d3SJohn Marino  * user.
12*86d7f5d3SJohn Marino  *
13*86d7f5d3SJohn Marino  * Send bug reports, bug fixes, enhancements, requests, flames, etc., and
14*86d7f5d3SJohn Marino  * I'll try to keep a version up to date.  I can be reached as follows:
15*86d7f5d3SJohn Marino  * Paul Vixie          <paul@vix.com>          uunet!decwrl!vixie!paul
16*86d7f5d3SJohn Marino  *
17*86d7f5d3SJohn Marino  * $FreeBSD: src/usr.sbin/cron/lib/env.c,v 1.7.2.1 2000/07/01 10:35:07 ps Exp $
18*86d7f5d3SJohn Marino  * $DragonFly: src/usr.sbin/cron/lib/env.c,v 1.5 2004/12/18 22:48:03 swildner Exp $
19*86d7f5d3SJohn Marino  */
20*86d7f5d3SJohn Marino 
21*86d7f5d3SJohn Marino #include "cron.h"
22*86d7f5d3SJohn Marino 
23*86d7f5d3SJohn Marino 
24*86d7f5d3SJohn Marino char **
env_init(void)25*86d7f5d3SJohn Marino env_init(void)
26*86d7f5d3SJohn Marino {
27*86d7f5d3SJohn Marino 	char **p;
28*86d7f5d3SJohn Marino 
29*86d7f5d3SJohn Marino 	p = malloc(sizeof(char *));
30*86d7f5d3SJohn Marino 	if (p)
31*86d7f5d3SJohn Marino 		p[0] = NULL;
32*86d7f5d3SJohn Marino 	return (p);
33*86d7f5d3SJohn Marino }
34*86d7f5d3SJohn Marino 
35*86d7f5d3SJohn Marino 
36*86d7f5d3SJohn Marino void
env_free(char ** envp)37*86d7f5d3SJohn Marino env_free(char **envp)
38*86d7f5d3SJohn Marino {
39*86d7f5d3SJohn Marino 	char	**p;
40*86d7f5d3SJohn Marino 
41*86d7f5d3SJohn Marino 	for (p = envp;  *p;  p++)
42*86d7f5d3SJohn Marino 		free(*p);
43*86d7f5d3SJohn Marino 	free(envp);
44*86d7f5d3SJohn Marino }
45*86d7f5d3SJohn Marino 
46*86d7f5d3SJohn Marino 
47*86d7f5d3SJohn Marino char **
env_copy(char ** envp)48*86d7f5d3SJohn Marino env_copy(char **envp)
49*86d7f5d3SJohn Marino {
50*86d7f5d3SJohn Marino 	int count, i;
51*86d7f5d3SJohn Marino 	char **p;
52*86d7f5d3SJohn Marino 
53*86d7f5d3SJohn Marino 	for (count = 0;  envp[count] != NULL;  count++)
54*86d7f5d3SJohn Marino 		;
55*86d7f5d3SJohn Marino 	p = (char **) malloc((count+1) * sizeof(char *)); /* 1 for the NULL */
56*86d7f5d3SJohn Marino 	if (p == NULL) {
57*86d7f5d3SJohn Marino 		errno = ENOMEM;
58*86d7f5d3SJohn Marino 		return NULL;
59*86d7f5d3SJohn Marino 	}
60*86d7f5d3SJohn Marino 	for (i = 0;  i < count;  i++)
61*86d7f5d3SJohn Marino 		if ((p[i] = strdup(envp[i])) == NULL) {
62*86d7f5d3SJohn Marino 			while (--i >= 0)
63*86d7f5d3SJohn Marino 				free(p[i]);
64*86d7f5d3SJohn Marino 			free(p);
65*86d7f5d3SJohn Marino 			errno = ENOMEM;
66*86d7f5d3SJohn Marino 			return NULL;
67*86d7f5d3SJohn Marino 		}
68*86d7f5d3SJohn Marino 	p[count] = NULL;
69*86d7f5d3SJohn Marino 	return (p);
70*86d7f5d3SJohn Marino }
71*86d7f5d3SJohn Marino 
72*86d7f5d3SJohn Marino 
73*86d7f5d3SJohn Marino char **
env_set(char ** envp,char * envstr)74*86d7f5d3SJohn Marino env_set(char **envp, char *envstr)
75*86d7f5d3SJohn Marino {
76*86d7f5d3SJohn Marino 	int count, found;
77*86d7f5d3SJohn Marino 	char **p;
78*86d7f5d3SJohn Marino 	char *q;
79*86d7f5d3SJohn Marino 
80*86d7f5d3SJohn Marino 	/*
81*86d7f5d3SJohn Marino 	 * count the number of elements, including the null pointer;
82*86d7f5d3SJohn Marino 	 * also set 'found' to -1 or index of entry if already in here.
83*86d7f5d3SJohn Marino 	 */
84*86d7f5d3SJohn Marino 	found = -1;
85*86d7f5d3SJohn Marino 	for (count = 0;  envp[count] != NULL;  count++) {
86*86d7f5d3SJohn Marino 		if (!strcmp_until(envp[count], envstr, '='))
87*86d7f5d3SJohn Marino 			found = count;
88*86d7f5d3SJohn Marino 	}
89*86d7f5d3SJohn Marino 	count++;	/* for the NULL */
90*86d7f5d3SJohn Marino 
91*86d7f5d3SJohn Marino 	if (found != -1) {
92*86d7f5d3SJohn Marino 		/*
93*86d7f5d3SJohn Marino 		 * it exists already, so just free the existing setting,
94*86d7f5d3SJohn Marino 		 * save our new one there, and return the existing array.
95*86d7f5d3SJohn Marino 		 */
96*86d7f5d3SJohn Marino 		q = envp[found];
97*86d7f5d3SJohn Marino 		if ((envp[found] = strdup(envstr)) == NULL) {
98*86d7f5d3SJohn Marino 			envp[found] = q;
99*86d7f5d3SJohn Marino 			/* XXX env_free(envp); */
100*86d7f5d3SJohn Marino 			errno = ENOMEM;
101*86d7f5d3SJohn Marino 			return NULL;
102*86d7f5d3SJohn Marino 		}
103*86d7f5d3SJohn Marino 		free(q);
104*86d7f5d3SJohn Marino 		return (envp);
105*86d7f5d3SJohn Marino 	}
106*86d7f5d3SJohn Marino 
107*86d7f5d3SJohn Marino 	/*
108*86d7f5d3SJohn Marino 	 * it doesn't exist yet, so resize the array, move null pointer over
109*86d7f5d3SJohn Marino 	 * one, save our string over the old null pointer, and return resized
110*86d7f5d3SJohn Marino 	 * array.
111*86d7f5d3SJohn Marino 	 */
112*86d7f5d3SJohn Marino 	p = (char **) realloc((void *) envp,
113*86d7f5d3SJohn Marino 			      (unsigned) ((count+1) * sizeof(char *)));
114*86d7f5d3SJohn Marino 	if (p == NULL) 	{
115*86d7f5d3SJohn Marino 		/* XXX env_free(envp); */
116*86d7f5d3SJohn Marino 		errno = ENOMEM;
117*86d7f5d3SJohn Marino 		return NULL;
118*86d7f5d3SJohn Marino 	}
119*86d7f5d3SJohn Marino 	p[count] = p[count-1];
120*86d7f5d3SJohn Marino 	if ((p[count-1] = strdup(envstr)) == NULL) {
121*86d7f5d3SJohn Marino 		env_free(p);
122*86d7f5d3SJohn Marino 		errno = ENOMEM;
123*86d7f5d3SJohn Marino 		return NULL;
124*86d7f5d3SJohn Marino 	}
125*86d7f5d3SJohn Marino 	return (p);
126*86d7f5d3SJohn Marino }
127*86d7f5d3SJohn Marino 
128*86d7f5d3SJohn Marino 
129*86d7f5d3SJohn Marino /* return	ERR = end of file
130*86d7f5d3SJohn Marino  *		FALSE = not an env setting (file was repositioned)
131*86d7f5d3SJohn Marino  *		TRUE = was an env setting
132*86d7f5d3SJohn Marino  */
133*86d7f5d3SJohn Marino int
load_env(char * envstr,FILE * f)134*86d7f5d3SJohn Marino load_env(char *envstr, FILE *f)
135*86d7f5d3SJohn Marino {
136*86d7f5d3SJohn Marino 	long	filepos;
137*86d7f5d3SJohn Marino 	int	fileline;
138*86d7f5d3SJohn Marino 	char	name[MAX_ENVSTR], val[MAX_ENVSTR];
139*86d7f5d3SJohn Marino 	int	fields;
140*86d7f5d3SJohn Marino 
141*86d7f5d3SJohn Marino 	filepos = ftell(f);
142*86d7f5d3SJohn Marino 	fileline = LineNumber;
143*86d7f5d3SJohn Marino 	skip_comments(f);
144*86d7f5d3SJohn Marino 	if (EOF == get_string(envstr, MAX_ENVSTR, f, "\n"))
145*86d7f5d3SJohn Marino 		return (ERR);
146*86d7f5d3SJohn Marino 
147*86d7f5d3SJohn Marino 	Debug(DPARS, ("load_env, read <%s>\n", envstr))
148*86d7f5d3SJohn Marino 
149*86d7f5d3SJohn Marino 	name[0] = val[0] = '\0';
150*86d7f5d3SJohn Marino 	fields = sscanf(envstr, "%[^ =] = %[^\n#]", name, val);
151*86d7f5d3SJohn Marino 	if (fields != 2) {
152*86d7f5d3SJohn Marino 		Debug(DPARS, ("load_env, not 2 fields (%d)\n", fields))
153*86d7f5d3SJohn Marino 		fseek(f, filepos, 0);
154*86d7f5d3SJohn Marino 		Set_LineNum(fileline);
155*86d7f5d3SJohn Marino 		return (FALSE);
156*86d7f5d3SJohn Marino 	}
157*86d7f5d3SJohn Marino 
158*86d7f5d3SJohn Marino 	/* 2 fields from scanf; looks like an env setting
159*86d7f5d3SJohn Marino 	 */
160*86d7f5d3SJohn Marino 
161*86d7f5d3SJohn Marino 	/*
162*86d7f5d3SJohn Marino 	 * process value string
163*86d7f5d3SJohn Marino 	 */
164*86d7f5d3SJohn Marino 	/*local*/{
165*86d7f5d3SJohn Marino 		int	len = strdtb(val);
166*86d7f5d3SJohn Marino 
167*86d7f5d3SJohn Marino 		if (len >= 2) {
168*86d7f5d3SJohn Marino 			if (val[0] == '\'' || val[0] == '"') {
169*86d7f5d3SJohn Marino 				if (val[len-1] == val[0]) {
170*86d7f5d3SJohn Marino 					val[len-1] = '\0';
171*86d7f5d3SJohn Marino 					strcpy(val, val+1);
172*86d7f5d3SJohn Marino 				}
173*86d7f5d3SJohn Marino 			}
174*86d7f5d3SJohn Marino 		}
175*86d7f5d3SJohn Marino 	}
176*86d7f5d3SJohn Marino 
177*86d7f5d3SJohn Marino 	if (strlen(name) + 1 + strlen(val) >= MAX_ENVSTR-1)
178*86d7f5d3SJohn Marino 		return (FALSE);
179*86d7f5d3SJohn Marino 	sprintf(envstr, "%s=%s", name, val);
180*86d7f5d3SJohn Marino 	Debug(DPARS, ("load_env, <%s> <%s> -> <%s>\n", name, val, envstr))
181*86d7f5d3SJohn Marino 	return (TRUE);
182*86d7f5d3SJohn Marino }
183*86d7f5d3SJohn Marino 
184*86d7f5d3SJohn Marino 
185*86d7f5d3SJohn Marino char *
env_get(char * name,char ** envp)186*86d7f5d3SJohn Marino env_get(char *name, char **envp)
187*86d7f5d3SJohn Marino {
188*86d7f5d3SJohn Marino 	int len;
189*86d7f5d3SJohn Marino 	char *p, *q;
190*86d7f5d3SJohn Marino 
191*86d7f5d3SJohn Marino 	len = strlen(name);
192*86d7f5d3SJohn Marino 	while ((p = *envp++)) {
193*86d7f5d3SJohn Marino 		if (!(q = strchr(p, '=')))
194*86d7f5d3SJohn Marino 			continue;
195*86d7f5d3SJohn Marino 		if ((q - p) == len && !strncmp(p, name, len))
196*86d7f5d3SJohn Marino 			return (q+1);
197*86d7f5d3SJohn Marino 	}
198*86d7f5d3SJohn Marino 	return (NULL);
199*86d7f5d3SJohn Marino }
200