216 lines
5.7 KiB
C
216 lines
5.7 KiB
C
/* Copyright (c) 2008, 2009
|
|
* Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
|
|
* Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de)
|
|
* Micah Cowan (micah@cowan.name)
|
|
* Sadrul Habib Chowdhury (sadrul@users.sourceforge.net)
|
|
* Copyright (c) 1993-2002, 2003, 2005, 2006, 2007
|
|
* Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
|
|
* Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de)
|
|
* Copyright (c) 1987 Oliver Laumann
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 3, or (at your option)
|
|
* any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program (see the file COPYING); if not, see
|
|
* https://www.gnu.org/licenses/, or contact Free Software Foundation, Inc.,
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
|
|
*
|
|
****************************************************************
|
|
*/
|
|
|
|
/*
|
|
* putenv -- put value into environment
|
|
*
|
|
* Usage: i = putenv (string)
|
|
* int i;
|
|
* char *string;
|
|
*
|
|
* where string is of the form <name>=<value>.
|
|
* If "value" is 0, then "name" will be deleted from the environment.
|
|
* Putenv returns 0 normally, -1 on error (not enough core for malloc).
|
|
*
|
|
* Putenv may need to add a new name into the environment, or to
|
|
* associate a value longer than the current value with a particular
|
|
* name. So, to make life simpler, putenv() copies your entire
|
|
* environment into the heap (i.e. malloc()) from the stack
|
|
* (i.e. where it resides when your process is initiated) the first
|
|
* time you call it.
|
|
*
|
|
* HISTORY
|
|
* 3-Sep-91 Michael Schroeder (mlschroe). Modified to behave as
|
|
* as putenv.
|
|
* 16-Aug-91 Tim MacKenzie (tym) at Monash University. Modified for
|
|
* use in screen (iScreen) (ignores final int parameter)
|
|
* 14-Oct-85 Michael Mauldin (mlm) at Carnegie-Mellon University
|
|
* Ripped out of CMU lib for Rob-O-Matic portability
|
|
* 20-Nov-79 Steven Shafer (sas) at Carnegie-Mellon University
|
|
* Created for VAX. Too bad Bell Labs didn't provide this. It's
|
|
* unfortunate that you have to copy the whole environment onto the
|
|
* heap, but the bookkeeping-and-not-so-much-copying approach turns
|
|
* out to be much hairier. So, I decided to do the simple thing,
|
|
* copying the entire environment onto the heap the first time you
|
|
* call putenv(), then doing realloc() uniformly later on.
|
|
*/
|
|
|
|
#include "config.h"
|
|
|
|
#ifdef NEEDPUTENV
|
|
|
|
#if defined(__STDC__)
|
|
# define __P(a) a
|
|
#else
|
|
# define __P(a) ()
|
|
#endif
|
|
|
|
char *malloc __P((int));
|
|
char *realloc __P((char *, int));
|
|
void free __P((char *));
|
|
int sprintf __P((char *, char *, ...));
|
|
|
|
#define EXTRASIZE 5 /* increment to add to env. size */
|
|
|
|
static int envsize = -1; /* current size of environment */
|
|
extern char **environ; /* the global which is your env. */
|
|
|
|
static int findenv __P((char *)); /* look for a name in the env. */
|
|
static int newenv __P((void)); /* copy env. from stack to heap */
|
|
static int moreenv __P((void)); /* incr. size of env. */
|
|
|
|
int
|
|
unsetenv(name)
|
|
char *name;
|
|
{
|
|
register int i;
|
|
|
|
if (envsize < 0)
|
|
{ /* first time putenv called */
|
|
if (newenv() < 0) /* copy env. to heap */
|
|
return -1;
|
|
}
|
|
i = findenv(name);
|
|
if (i < 0)
|
|
return 0; /* Already here */
|
|
|
|
free(environ[i]);
|
|
if (envsize > 0)
|
|
envsize--;
|
|
for (; environ[i]; i++)
|
|
environ[i] = environ[i+1];
|
|
return 0; /* Already here */
|
|
}
|
|
|
|
int
|
|
putenv(string)
|
|
char *string;
|
|
{
|
|
register int i;
|
|
register char *p;
|
|
|
|
if (envsize < 0)
|
|
{ /* first time putenv called */
|
|
if (newenv() < 0) /* copy env. to heap */
|
|
return -1;
|
|
}
|
|
|
|
i = findenv(string); /* look for name in environment */
|
|
|
|
if (i < 0)
|
|
{ /* name must be added */
|
|
for (i = 0; environ[i]; i++);
|
|
if (i >= (envsize - 1))
|
|
{ /* need new slot */
|
|
if (moreenv() < 0)
|
|
return -1;
|
|
}
|
|
p = malloc(strlen(string) + 1);
|
|
if (p == 0) /* not enough core */
|
|
return -1;
|
|
environ[i + 1] = 0; /* new end of env. */
|
|
}
|
|
else
|
|
{ /* name already in env. */
|
|
p = realloc(environ[i], strlen(string) + 1);
|
|
if (p == 0)
|
|
return -1;
|
|
}
|
|
sprintf(p, "%s", string); /* copy into env. */
|
|
environ[i] = p;
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int
|
|
findenv(name)
|
|
char *name;
|
|
{
|
|
register char *namechar, *envchar;
|
|
register int i, found;
|
|
|
|
found = 0;
|
|
for (i = 0; environ[i] && !found; i++)
|
|
{
|
|
envchar = environ[i];
|
|
namechar = name;
|
|
while (*namechar && *namechar != '=' && (*namechar == *envchar))
|
|
{
|
|
namechar++;
|
|
envchar++;
|
|
}
|
|
found = ((*namechar == '\0' || *namechar == '=') && *envchar == '=');
|
|
}
|
|
return found ? i - 1 : -1;
|
|
}
|
|
|
|
static int
|
|
newenv()
|
|
{
|
|
register char **env, *elem;
|
|
register int i, esize;
|
|
|
|
for (i = 0; environ[i]; i++)
|
|
;
|
|
esize = i + EXTRASIZE + 1;
|
|
env = (char **)malloc(esize * sizeof (elem));
|
|
if (env == 0)
|
|
return -1;
|
|
|
|
for (i = 0; environ[i]; i++)
|
|
{
|
|
elem = malloc(strlen(environ[i]) + 1);
|
|
if (elem == 0)
|
|
return -1;
|
|
env[i] = elem;
|
|
strcpy(elem, environ[i]);
|
|
}
|
|
|
|
env[i] = 0;
|
|
environ = env;
|
|
envsize = esize;
|
|
return 0;
|
|
}
|
|
|
|
static int
|
|
moreenv()
|
|
{
|
|
register int esize;
|
|
register char **env;
|
|
|
|
esize = envsize + EXTRASIZE;
|
|
env = (char **)realloc((char *)environ, esize * sizeof (*env));
|
|
if (env == 0)
|
|
return -1;
|
|
environ = env;
|
|
envsize = esize;
|
|
return 0;
|
|
}
|
|
|
|
#endif /* NEEDPUTENV */
|
|
|