xref: /dflybsd-src/contrib/bmake/setenv.c (revision 01e196c8756b7c1bc7ca62d0d9870afee6a0015d)
1*01e196c8SJohn Marino /*
2*01e196c8SJohn Marino  * Copyright (c) 1987 Regents of the University of California.
3*01e196c8SJohn Marino  * All rights reserved.
4*01e196c8SJohn Marino  *
5*01e196c8SJohn Marino  * Redistribution and use in source and binary forms, with or without
6*01e196c8SJohn Marino  * modification, are permitted provided that the following conditions
7*01e196c8SJohn Marino  * are met:
8*01e196c8SJohn Marino  * 1. Redistributions of source code must retain the above copyright
9*01e196c8SJohn Marino  *    notice, this list of conditions and the following disclaimer.
10*01e196c8SJohn Marino  * 2. Redistributions in binary form must reproduce the above copyright
11*01e196c8SJohn Marino  *    notice, this list of conditions and the following disclaimer in the
12*01e196c8SJohn Marino  *    documentation and/or other materials provided with the distribution.
13*01e196c8SJohn Marino  * 3. All advertising materials mentioning features or use of this software
14*01e196c8SJohn Marino  *    must display the following acknowledgement:
15*01e196c8SJohn Marino  *	This product includes software developed by the University of
16*01e196c8SJohn Marino  *	California, Berkeley and its contributors.
17*01e196c8SJohn Marino  * 4. Neither the name of the University nor the names of its contributors
18*01e196c8SJohn Marino  *    may be used to endorse or promote products derived from this software
19*01e196c8SJohn Marino  *    without specific prior written permission.
20*01e196c8SJohn Marino  *
21*01e196c8SJohn Marino  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22*01e196c8SJohn Marino  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23*01e196c8SJohn Marino  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24*01e196c8SJohn Marino  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25*01e196c8SJohn Marino  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26*01e196c8SJohn Marino  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27*01e196c8SJohn Marino  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28*01e196c8SJohn Marino  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29*01e196c8SJohn Marino  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30*01e196c8SJohn Marino  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31*01e196c8SJohn Marino  * SUCH DAMAGE.
32*01e196c8SJohn Marino  */
33*01e196c8SJohn Marino 
34*01e196c8SJohn Marino #ifdef HAVE_CONFIG_H
35*01e196c8SJohn Marino # include "config.h"
36*01e196c8SJohn Marino #endif
37*01e196c8SJohn Marino #ifndef HAVE_SETENV
38*01e196c8SJohn Marino 
39*01e196c8SJohn Marino #if defined(LIBC_SCCS) && !defined(lint)
40*01e196c8SJohn Marino /*static char *sccsid = "from: @(#)setenv.c	5.6 (Berkeley) 6/4/91";*/
41*01e196c8SJohn Marino static char *rcsid = "$Id: setenv.c,v 1.5 1996/09/04 22:10:42 sjg Exp $";
42*01e196c8SJohn Marino #endif /* LIBC_SCCS and not lint */
43*01e196c8SJohn Marino 
44*01e196c8SJohn Marino #include <stddef.h>
45*01e196c8SJohn Marino #include <stdlib.h>
46*01e196c8SJohn Marino #include <string.h>
47*01e196c8SJohn Marino 
48*01e196c8SJohn Marino /*
49*01e196c8SJohn Marino  * __findenv --
50*01e196c8SJohn Marino  *	Returns pointer to value associated with name, if any, else NULL.
51*01e196c8SJohn Marino  *	Sets offset to be the offset of the name/value combination in the
52*01e196c8SJohn Marino  *	environmental array, for use by setenv(3) and unsetenv(3).
53*01e196c8SJohn Marino  *	Explicitly removes '=' in argument name.
54*01e196c8SJohn Marino  *
55*01e196c8SJohn Marino  *	This routine *should* be a static; don't use it.
56*01e196c8SJohn Marino  */
57*01e196c8SJohn Marino static char *
__findenv(name,offset)58*01e196c8SJohn Marino __findenv(name, offset)
59*01e196c8SJohn Marino 	register char *name;
60*01e196c8SJohn Marino 	int *offset;
61*01e196c8SJohn Marino {
62*01e196c8SJohn Marino 	extern char **environ;
63*01e196c8SJohn Marino 	register int len;
64*01e196c8SJohn Marino 	register char **P, *C;
65*01e196c8SJohn Marino 
66*01e196c8SJohn Marino 	for (C = name, len = 0; *C && *C != '='; ++C, ++len);
67*01e196c8SJohn Marino 	for (P = environ; *P; ++P)
68*01e196c8SJohn Marino 		if (!strncmp(*P, name, len))
69*01e196c8SJohn Marino 			if (*(C = *P + len) == '=') {
70*01e196c8SJohn Marino 				*offset = P - environ;
71*01e196c8SJohn Marino 				return(++C);
72*01e196c8SJohn Marino 			}
73*01e196c8SJohn Marino 	return(NULL);
74*01e196c8SJohn Marino }
75*01e196c8SJohn Marino 
76*01e196c8SJohn Marino /*
77*01e196c8SJohn Marino  * setenv --
78*01e196c8SJohn Marino  *	Set the value of the environmental variable "name" to be
79*01e196c8SJohn Marino  *	"value".  If rewrite is set, replace any current value.
80*01e196c8SJohn Marino  */
setenv(name,value,rewrite)81*01e196c8SJohn Marino setenv(name, value, rewrite)
82*01e196c8SJohn Marino 	register const char *name;
83*01e196c8SJohn Marino 	register const char *value;
84*01e196c8SJohn Marino 	int rewrite;
85*01e196c8SJohn Marino {
86*01e196c8SJohn Marino 	extern char **environ;
87*01e196c8SJohn Marino 	static int alloced;			/* if allocated space before */
88*01e196c8SJohn Marino 	register char *C;
89*01e196c8SJohn Marino 	int l_value, offset;
90*01e196c8SJohn Marino 	char *__findenv();
91*01e196c8SJohn Marino 
92*01e196c8SJohn Marino 	if (*value == '=')			/* no `=' in value */
93*01e196c8SJohn Marino 		++value;
94*01e196c8SJohn Marino 	l_value = strlen(value);
95*01e196c8SJohn Marino 	if ((C = __findenv(name, &offset))) {	/* find if already exists */
96*01e196c8SJohn Marino 		if (!rewrite)
97*01e196c8SJohn Marino 			return (0);
98*01e196c8SJohn Marino 		if (strlen(C) >= l_value) {	/* old larger; copy over */
99*01e196c8SJohn Marino 			while (*C++ = *value++);
100*01e196c8SJohn Marino 			return (0);
101*01e196c8SJohn Marino 		}
102*01e196c8SJohn Marino 	} else {					/* create new slot */
103*01e196c8SJohn Marino 		register int	cnt;
104*01e196c8SJohn Marino 		register char	**P;
105*01e196c8SJohn Marino 
106*01e196c8SJohn Marino 		for (P = environ, cnt = 0; *P; ++P, ++cnt);
107*01e196c8SJohn Marino 		if (alloced) {			/* just increase size */
108*01e196c8SJohn Marino 			environ = (char **)realloc((char *)environ,
109*01e196c8SJohn Marino 			    (size_t)(sizeof(char *) * (cnt + 2)));
110*01e196c8SJohn Marino 			if (!environ)
111*01e196c8SJohn Marino 				return (-1);
112*01e196c8SJohn Marino 		}
113*01e196c8SJohn Marino 		else {				/* get new space */
114*01e196c8SJohn Marino 			alloced = 1;		/* copy old entries into it */
115*01e196c8SJohn Marino 			P = (char **)malloc((size_t)(sizeof(char *) *
116*01e196c8SJohn Marino 			    (cnt + 2)));
117*01e196c8SJohn Marino 			if (!P)
118*01e196c8SJohn Marino 				return (-1);
119*01e196c8SJohn Marino 			bcopy(environ, P, cnt * sizeof(char *));
120*01e196c8SJohn Marino 			environ = P;
121*01e196c8SJohn Marino 		}
122*01e196c8SJohn Marino 		environ[cnt + 1] = NULL;
123*01e196c8SJohn Marino 		offset = cnt;
124*01e196c8SJohn Marino 	}
125*01e196c8SJohn Marino 	for (C = (char *)name; *C && *C != '='; ++C);	/* no `=' in name */
126*01e196c8SJohn Marino 	if (!(environ[offset] =			/* name + `=' + value */
127*01e196c8SJohn Marino 	    malloc((size_t)((int)(C - name) + l_value + 2))))
128*01e196c8SJohn Marino 		return (-1);
129*01e196c8SJohn Marino 	for (C = environ[offset]; (*C = *name++) && *C != '='; ++C)
130*01e196c8SJohn Marino 		;
131*01e196c8SJohn Marino 	for (*C++ = '='; *C++ = *value++; )
132*01e196c8SJohn Marino 		;
133*01e196c8SJohn Marino 	return (0);
134*01e196c8SJohn Marino }
135*01e196c8SJohn Marino 
136*01e196c8SJohn Marino /*
137*01e196c8SJohn Marino  * unsetenv(name) --
138*01e196c8SJohn Marino  *	Delete environmental variable "name".
139*01e196c8SJohn Marino  */
140*01e196c8SJohn Marino void
unsetenv(name)141*01e196c8SJohn Marino unsetenv(name)
142*01e196c8SJohn Marino 	const char	*name;
143*01e196c8SJohn Marino {
144*01e196c8SJohn Marino 	extern char **environ;
145*01e196c8SJohn Marino 	register char **P;
146*01e196c8SJohn Marino 	int offset;
147*01e196c8SJohn Marino 	char *__findenv();
148*01e196c8SJohn Marino 
149*01e196c8SJohn Marino 	while (__findenv(name, &offset))		/* if set multiple times */
150*01e196c8SJohn Marino 		for (P = &environ[offset];; ++P)
151*01e196c8SJohn Marino 			if (!(*P = *(P + 1)))
152*01e196c8SJohn Marino 				break;
153*01e196c8SJohn Marino }
154*01e196c8SJohn Marino #endif
155