1/* Copyright (c) 1993-2002 2 * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) 3 * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) 4 * Copyright (c) 1987 Oliver Laumann 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2, or (at your option) 9 * any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program (see the file COPYING); if not, write to the 18 * Free Software Foundation, Inc., 19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA 20 * 21 **************************************************************** 22 */ 23 24/* 25 * putenv -- put value into environment 26 * 27 * Usage: i = putenv (string) 28 * int i; 29 * char *string; 30 * 31 * where string is of the form <name>=<value>. 32 * If "value" is 0, then "name" will be deleted from the environment. 33 * Putenv returns 0 normally, -1 on error (not enough core for malloc). 34 * 35 * Putenv may need to add a new name into the environment, or to 36 * associate a value longer than the current value with a particular 37 * name. So, to make life simpler, putenv() copies your entire 38 * environment into the heap (i.e. malloc()) from the stack 39 * (i.e. where it resides when your process is initiated) the first 40 * time you call it. 41 * 42 * HISTORY 43 * 3-Sep-91 Michael Schroeder (mlschroe). Modified to behave as 44 * as putenv. 45 * 16-Aug-91 Tim MacKenzie (tym) at Monash University. Modified for 46 * use in screen (iScreen) (ignores final int parameter) 47 * 14-Oct-85 Michael Mauldin (mlm) at Carnegie-Mellon University 48 * Ripped out of CMU lib for Rob-O-Matic portability 49 * 20-Nov-79 Steven Shafer (sas) at Carnegie-Mellon University 50 * Created for VAX. Too bad Bell Labs didn't provide this. It's 51 * unfortunate that you have to copy the whole environment onto the 52 * heap, but the bookkeeping-and-not-so-much-copying approach turns 53 * out to be much hairier. So, I decided to do the simple thing, 54 * copying the entire environment onto the heap the first time you 55 * call putenv(), then doing realloc() uniformly later on. 56 */ 57 58#include "config.h" 59 60#ifdef NEEDPUTENV 61 62#if defined(__STDC__) 63# define __P(a) a 64#else 65# define __P(a) () 66#endif 67 68char *malloc __P((int)); 69char *realloc __P((char *, int)); 70void free __P((char *)); 71int sprintf __P((char *, char *, ...)); 72 73#define EXTRASIZE 5 /* increment to add to env. size */ 74 75static int envsize = -1; /* current size of environment */ 76extern char **environ; /* the global which is your env. */ 77 78static int findenv __P((char *)); /* look for a name in the env. */ 79static int newenv __P((void)); /* copy env. from stack to heap */ 80static int moreenv __P((void)); /* incr. size of env. */ 81 82int 83unsetenv(name) 84char *name; 85{ 86 register int i; 87 88 if (envsize < 0) 89 { /* first time putenv called */ 90 if (newenv() < 0) /* copy env. to heap */ 91 return -1; 92 } 93 i = findenv(name); 94 if (i < 0) 95 return 0; /* Already here */ 96 97 free(environ[i]); 98 if (envsize > 0) 99 envsize--; 100 for (; environ[i]; i++) 101 environ[i] = environ[i+1]; 102 return 0; /* Already here */ 103} 104 105int 106putenv(string) 107char *string; 108{ 109 register int i; 110 register char *p; 111 112 if (envsize < 0) 113 { /* first time putenv called */ 114 if (newenv() < 0) /* copy env. to heap */ 115 return -1; 116 } 117 118 i = findenv(string); /* look for name in environment */ 119 120 if (i < 0) 121 { /* name must be added */ 122 for (i = 0; environ[i]; i++); 123 if (i >= (envsize - 1)) 124 { /* need new slot */ 125 if (moreenv() < 0) 126 return -1; 127 } 128 p = malloc(strlen(string) + 1); 129 if (p == 0) /* not enough core */ 130 return -1; 131 environ[i + 1] = 0; /* new end of env. */ 132 } 133 else 134 { /* name already in env. */ 135 p = realloc(environ[i], strlen(string) + 1); 136 if (p == 0) 137 return -1; 138 } 139 sprintf(p, "%s", string); /* copy into env. */ 140 environ[i] = p; 141 142 return 0; 143} 144 145static int 146findenv(name) 147char *name; 148{ 149 register char *namechar, *envchar; 150 register int i, found; 151 152 found = 0; 153 for (i = 0; environ[i] && !found; i++) 154 { 155 envchar = environ[i]; 156 namechar = name; 157 while (*namechar && *namechar != '=' && (*namechar == *envchar)) 158 { 159 namechar++; 160 envchar++; 161 } 162 found = ((*namechar == '\0' || *namechar == '=') && *envchar == '='); 163 } 164 return found ? i - 1 : -1; 165} 166 167static int 168newenv() 169{ 170 register char **env, *elem; 171 register int i, esize; 172 173 for (i = 0; environ[i]; i++) 174 ; 175 esize = i + EXTRASIZE + 1; 176 env = (char **)malloc(esize * sizeof (elem)); 177 if (env == 0) 178 return -1; 179 180 for (i = 0; environ[i]; i++) 181 { 182 elem = malloc(strlen(environ[i]) + 1); 183 if (elem == 0) 184 return -1; 185 env[i] = elem; 186 strcpy(elem, environ[i]); 187 } 188 189 env[i] = 0; 190 environ = env; 191 envsize = esize; 192 return 0; 193} 194 195static int 196moreenv() 197{ 198 register int esize; 199 register char **env; 200 201 esize = envsize + EXTRASIZE; 202 env = (char **)realloc((char *)environ, esize * sizeof (*env)); 203 if (env == 0) 204 return -1; 205 environ = env; 206 envsize = esize; 207 return 0; 208} 209 210#endif /* NEEDPUTENV */ 211 212