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