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