summaryrefslogtreecommitdiff
path: root/openbsd-compat/setenv.c
diff options
context:
space:
mode:
Diffstat (limited to 'openbsd-compat/setenv.c')
-rw-r--r--openbsd-compat/setenv.c123
1 files changed, 102 insertions, 21 deletions
diff --git a/openbsd-compat/setenv.c b/openbsd-compat/setenv.c
index e2a8b6dd3..373b701d9 100644
--- a/openbsd-compat/setenv.c
+++ b/openbsd-compat/setenv.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: setenv.c,v 1.9 2005/08/08 08:05:37 espie Exp $ */ 1/* $OpenBSD: setenv.c,v 1.13 2010/08/23 22:31:50 millert Exp $ */
2/* 2/*
3 * Copyright (c) 1987 Regents of the University of California. 3 * Copyright (c) 1987 Regents of the University of California.
4 * All rights reserved. 4 * All rights reserved.
@@ -31,35 +31,38 @@
31/* OPENBSD ORIGINAL: lib/libc/stdlib/setenv.c */ 31/* OPENBSD ORIGINAL: lib/libc/stdlib/setenv.c */
32 32
33#include "includes.h" 33#include "includes.h"
34
34#if !defined(HAVE_SETENV) || !defined(HAVE_UNSETENV) 35#if !defined(HAVE_SETENV) || !defined(HAVE_UNSETENV)
35 36
37#include <errno.h>
36#include <stdlib.h> 38#include <stdlib.h>
37#include <string.h> 39#include <string.h>
38 40
39extern char **environ; 41extern char **environ;
42static char **lastenv; /* last value of environ */
40 43
41/* OpenSSH Portable: __findenv is from getenv.c rev 1.8, made static */ 44/* OpenSSH Portable: __findenv is from getenv.c rev 1.8, made static */
42/* 45/*
43 * __findenv -- 46 * __findenv --
44 * Returns pointer to value associated with name, if any, else NULL. 47 * Returns pointer to value associated with name, if any, else NULL.
48 * Starts searching within the environmental array at offset.
45 * Sets offset to be the offset of the name/value combination in the 49 * Sets offset to be the offset of the name/value combination in the
46 * environmental array, for use by setenv(3) and unsetenv(3). 50 * environmental array, for use by putenv(3), setenv(3) and unsetenv(3).
47 * Explicitly removes '=' in argument name. 51 * Explicitly removes '=' in argument name.
52 *
53 * This routine *should* be a static; don't use it.
48 */ 54 */
49static char * 55static char *
50__findenv(const char *name, size_t *offset) 56__findenv(const char *name, int len, int *offset)
51{ 57{
52 extern char **environ; 58 extern char **environ;
53 int len, i; 59 int i;
54 const char *np; 60 const char *np;
55 char **p, *cp; 61 char **p, *cp;
56 62
57 if (name == NULL || environ == NULL) 63 if (name == NULL || environ == NULL)
58 return (NULL); 64 return (NULL);
59 for (np = name; *np && *np != '='; ++np) 65 for (p = environ + *offset; (cp = *p) != NULL; ++p) {
60 ;
61 len = np - name;
62 for (p = environ; (cp = *p) != NULL; ++p) {
63 for (np = name, i = len; i && *cp; i--) 66 for (np = name, i = len; i && *cp; i--)
64 if (*cp++ != *np++) 67 if (*cp++ != *np++)
65 break; 68 break;
@@ -71,6 +74,54 @@ __findenv(const char *name, size_t *offset)
71 return (NULL); 74 return (NULL);
72} 75}
73 76
77#if 0 /* nothing uses putenv */
78/*
79 * putenv --
80 * Add a name=value string directly to the environmental, replacing
81 * any current value.
82 */
83int
84putenv(char *str)
85{
86 char **P, *cp;
87 size_t cnt;
88 int offset = 0;
89
90 for (cp = str; *cp && *cp != '='; ++cp)
91 ;
92 if (*cp != '=') {
93 errno = EINVAL;
94 return (-1); /* missing `=' in string */
95 }
96
97 if (__findenv(str, (int)(cp - str), &offset) != NULL) {
98 environ[offset++] = str;
99 /* could be set multiple times */
100 while (__findenv(str, (int)(cp - str), &offset)) {
101 for (P = &environ[offset];; ++P)
102 if (!(*P = *(P + 1)))
103 break;
104 }
105 return (0);
106 }
107
108 /* create new slot for string */
109 for (P = environ; *P != NULL; P++)
110 ;
111 cnt = P - environ;
112 P = (char **)realloc(lastenv, sizeof(char *) * (cnt + 2));
113 if (!P)
114 return (-1);
115 if (lastenv != environ)
116 memcpy(P, environ, cnt * sizeof(char *));
117 lastenv = environ = P;
118 environ[cnt] = str;
119 environ[cnt + 1] = NULL;
120 return (0);
121}
122
123#endif
124
74#ifndef HAVE_SETENV 125#ifndef HAVE_SETENV
75/* 126/*
76 * setenv -- 127 * setenv --
@@ -80,24 +131,39 @@ __findenv(const char *name, size_t *offset)
80int 131int
81setenv(const char *name, const char *value, int rewrite) 132setenv(const char *name, const char *value, int rewrite)
82{ 133{
83 static char **lastenv; /* last value of environ */ 134 char *C, **P;
84 char *C; 135 const char *np;
85 size_t l_value, offset; 136 int l_value, offset = 0;
137
138 for (np = name; *np && *np != '='; ++np)
139 ;
140#ifdef notyet
141 if (*np) {
142 errno = EINVAL;
143 return (-1); /* has `=' in name */
144 }
145#endif
86 146
87 if (*value == '=') /* no `=' in value */
88 ++value;
89 l_value = strlen(value); 147 l_value = strlen(value);
90 if ((C = __findenv(name, &offset))) { /* find if already exists */ 148 if ((C = __findenv(name, (int)(np - name), &offset)) != NULL) {
149 int tmpoff = offset + 1;
91 if (!rewrite) 150 if (!rewrite)
92 return (0); 151 return (0);
152#if 0 /* XXX - existing entry may not be writable */
93 if (strlen(C) >= l_value) { /* old larger; copy over */ 153 if (strlen(C) >= l_value) { /* old larger; copy over */
94 while ((*C++ = *value++)) 154 while ((*C++ = *value++))
95 ; 155 ;
96 return (0); 156 return (0);
97 } 157 }
158#endif
159 /* could be set multiple times */
160 while (__findenv(name, (int)(np - name), &tmpoff)) {
161 for (P = &environ[tmpoff];; ++P)
162 if (!(*P = *(P + 1)))
163 break;
164 }
98 } else { /* create new slot */ 165 } else { /* create new slot */
99 size_t cnt; 166 size_t cnt;
100 char **P;
101 167
102 for (P = environ; *P != NULL; P++) 168 for (P = environ; *P != NULL; P++)
103 ; 169 ;
@@ -111,10 +177,8 @@ setenv(const char *name, const char *value, int rewrite)
111 offset = cnt; 177 offset = cnt;
112 environ[cnt + 1] = NULL; 178 environ[cnt + 1] = NULL;
113 } 179 }
114 for (C = (char *)name; *C && *C != '='; ++C)
115 ; /* no `=' in name */
116 if (!(environ[offset] = /* name + `=' + value */ 180 if (!(environ[offset] = /* name + `=' + value */
117 malloc((size_t)((int)(C - name) + l_value + 2)))) 181 malloc((size_t)((int)(np - name) + l_value + 2))))
118 return (-1); 182 return (-1);
119 for (C = environ[offset]; (*C = *name++) && *C != '='; ++C) 183 for (C = environ[offset]; (*C = *name++) && *C != '='; ++C)
120 ; 184 ;
@@ -122,6 +186,7 @@ setenv(const char *name, const char *value, int rewrite)
122 ; 186 ;
123 return (0); 187 return (0);
124} 188}
189
125#endif /* HAVE_SETENV */ 190#endif /* HAVE_SETENV */
126 191
127#ifndef HAVE_UNSETENV 192#ifndef HAVE_UNSETENV
@@ -129,17 +194,33 @@ setenv(const char *name, const char *value, int rewrite)
129 * unsetenv(name) -- 194 * unsetenv(name) --
130 * Delete environmental variable "name". 195 * Delete environmental variable "name".
131 */ 196 */
132void 197int
133unsetenv(const char *name) 198unsetenv(const char *name)
134{ 199{
135 char **P; 200 char **P;
136 size_t offset; 201 const char *np;
202 int offset = 0;
137 203
138 while (__findenv(name, &offset)) /* if set multiple times */ 204 if (!name || !*name) {
205 errno = EINVAL;
206 return (-1);
207 }
208 for (np = name; *np && *np != '='; ++np)
209 ;
210 if (*np) {
211 errno = EINVAL;
212 return (-1); /* has `=' in name */
213 }
214
215 /* could be set multiple times */
216 while (__findenv(name, (int)(np - name), &offset)) {
139 for (P = &environ[offset];; ++P) 217 for (P = &environ[offset];; ++P)
140 if (!(*P = *(P + 1))) 218 if (!(*P = *(P + 1)))
141 break; 219 break;
220 }
221 return (0);
142} 222}
143#endif /* HAVE_UNSETENV */ 223#endif /* HAVE_UNSETENV */
144 224
145#endif /* !defined(HAVE_SETENV) || !defined(HAVE_UNSETENV) */ 225#endif /* !defined(HAVE_SETENV) || !defined(HAVE_UNSETENV) */
226