summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog2
-rw-r--r--openbsd-compat/setenv.c123
2 files changed, 104 insertions, 21 deletions
diff --git a/ChangeLog b/ChangeLog
index 5c9d719ba..13f736397 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -9,6 +9,8 @@
9 - (djm) [openbsd-compat/sha2.c openbsd-compat/sha2.h] Remove OpenBSD rcsid 9 - (djm) [openbsd-compat/sha2.c openbsd-compat/sha2.h] Remove OpenBSD rcsid
10 marker. The upstream API has changed (function and structure names) 10 marker. The upstream API has changed (function and structure names)
11 enough to put it out of sync with other providers of this interface. 11 enough to put it out of sync with other providers of this interface.
12 - (djm) [openbsd-compat/setenv.c] Forklift upgrade, including inclusion
13 of static __findenv() function from upstream setenv.c
12 - OpenBSD CVS Sync 14 - OpenBSD CVS Sync
13 - millert@cvs.openbsd.org 2006/05/05 15:27:38 15 - millert@cvs.openbsd.org 2006/05/05 15:27:38
14 [openbsd-compat/strlcpy.c] 16 [openbsd-compat/strlcpy.c]
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