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