1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /*
3 * Copyright (c) 1987 Regents of the University of California.
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms are permitted
7 * provided that the above copyright notice and this paragraph are
8 * duplicated in all such forms and that any documentation,
9 * advertising materials, and other materials related to such
10 * distribution and use acknowledge that the software was developed
11 * by the University of California, Berkeley. The name of the
12 * University may not be used to endorse or promote products derived
13 * from this software without specific prior written permission.
14 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
16 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
17 */
18 /*
19 * Copyright (c) 1987 Regents of the University of California.
20 * All rights reserved.
21 *
22 * Redistribution and use in source and binary forms are permitted
23 * provided that the above copyright notice and this paragraph are
24 * duplicated in all such forms and that any documentation,
25 * advertising materials, and other materials related to such
26 * distribution and use acknowledge that the software was developed
27 * by the University of California, Berkeley. The name of the
28 * University may not be used to endorse or promote products derived
29 * from this software without specific prior written permission.
30 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
31 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
32 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
33 */
34
35 /* based on @(#)setenv.c 5.2 (Berkeley) 6/27/88 */
36
37 #include "autoconf.h"
38 #include <sys/types.h>
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include <string.h>
42
43 static char *_findenv(char *, int *);
44
45 #ifndef HAVE_SETENV
46 extern int setenv(char *, char *, int);
47 #endif
48 #ifndef HAVE_UNSETENV
49 extern void unsetenv(char *);
50 #endif
51
52 /*
53 * setenv --
54 * Set the value of the environmental variable "name" to be
55 * "value". If rewrite is set, replace any current value.
56 */
57 #ifndef HAVE_SETENV
58 int
setenv(name,value,rewrite)59 setenv(name, value, rewrite)
60 char *name, *value;
61 int rewrite;
62 {
63 extern char **environ;
64 static int alloced; /* if allocated space before */
65 char *C;
66 int l_value, offset;
67
68 if (*value == '=') /* no `=' in value */
69 ++value;
70 l_value = strlen(value);
71 if ((C = _findenv(name, &offset))) { /* find if already exists */
72 if (!rewrite)
73 return(0);
74 if (strlen(C) >= l_value) { /* old larger; copy over */
75 while ((*C++ = *value++));
76 return(0);
77 }
78 }
79 else { /* create new slot */
80 int cnt;
81 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 (u_int)(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((u_int)(sizeof(char *) *
93 (cnt + 2)));
94 if (!P)
95 return(-1);
96 memcpy(P, environ, cnt * sizeof(char *));
97 environ = P;
98 }
99 environ[cnt + 1] = NULL;
100 offset = cnt;
101 }
102 for (C = name; *C && *C != '='; ++C); /* no `=' in name */
103 if (!(environ[offset] = /* name + `=' + value */
104 malloc((u_int)((int)(C - name) + l_value + 2))))
105 return(-1);
106 for (C = environ[offset]; (*C = *name++) &&( *C != '='); ++C);
107 for (*C++ = '='; (*C++ = *value++) != NULL;);
108 return(0);
109 }
110 #endif
111
112 /*
113 * unsetenv(name) --
114 * Delete environmental variable "name".
115 */
116 #ifndef HAVE_UNSETENV
117 void
unsetenv(name)118 unsetenv(name)
119 char *name;
120 {
121 extern char **environ;
122 char **P;
123 int offset;
124
125 while (_findenv(name, &offset)) /* if set multiple times */
126 for (P = &environ[offset];; ++P)
127 if (!(*P = *(P + 1)))
128 break;
129 }
130 #endif
131
132 /* based on @(#)getenv.c 5.5 (Berkeley) 6/27/88 */
133
134 /*
135 * getenv --
136 * Returns ptr to value associated with name, if any, else NULL.
137 */
138 #ifndef HAVE_GETENV
139 char *
getenv(name)140 getenv(name)
141 char *name;
142 {
143 int offset;
144
145 return(_findenv(name, &offset));
146 }
147 #endif
148
149 /*
150 * _findenv --
151 * Returns pointer to value associated with name, if any, else NULL.
152 * Sets offset to be the offset of the name/value combination in the
153 * environmental array, for use by setenv(3) and unsetenv(3).
154 * Explicitly removes '=' in argument name.
155 *
156 */
157 static char *
_findenv(name,offset)158 _findenv(name, offset)
159 char *name;
160 int *offset;
161 {
162 extern char **environ;
163 int len;
164 char **P, *C;
165
166 for (C = name, len = 0; *C && *C != '='; ++C, ++len);
167 for (P = environ; *P; ++P)
168 if (!strncmp(*P, name, len))
169 if (*(C = *P + len) == '=') {
170 *offset = P - environ;
171 return(++C);
172 }
173 return(NULL);
174 }
175