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 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 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 * 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 * 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