1: /*
   2:  * Many systems have putenv() but no setenv(). Other systems have setenv()
   3:  * but no putenv() (MIPS). Still other systems have neither (NeXT). This is a
   4:  * re-implementation that hopefully ends all problems.
   5:  *
   6:  * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
   7:  */
   8: 
   9: #ifndef lint
  10: static char sccsid[] = "@(#) environ.c 1.2 94/03/23 16:09:46";
  11: #endif
  12: 
  13: /* System libraries. */
  14: 
  15: extern char **environ;
  16: extern char *strchr();
  17: extern char *strcpy();
  18: extern char *strncpy();
  19: extern char *malloc();
  20: extern char *realloc();
  21: extern int strncmp();
  22: extern void free();
  23: 
  24: #ifdef no_memcpy
  25: #define memcpy(d,s,l) bcopy(s,d,l)
  26: #else
  27: extern char *memcpy();
  28: #endif
  29: 
  30: /* Local stuff. */
  31: 
  32: static int addenv();            /* append entry to environment */
  33: 
  34: static int allocated = 0;       /* environ is, or is not, allocated */
  35: 
  36: #define DO_CLOBBER  1
  37: 
  38: /* namelength - determine length of name in "name=whatever" */
  39: 
  40: static int namelength(name)
  41: char   *name;
  42: {
  43:     char   *equal;
  44: 
  45:     equal = strchr(name, '=');
  46:     return ((equal == 0) ? strlen(name) : (equal - name));
  47: }
  48: 
  49: /* findenv - given name, locate name=value */
  50: 
  51: static char **findenv(name, len)
  52: char   *name;
  53: int     len;
  54: {
  55:     char  **envp;
  56: 
  57:     for (envp = environ; envp && *envp; envp++)
  58:     if (strncmp(name, *envp, len) == 0 && (*envp)[len] == '=')
  59:         return (envp);
  60:     return (0);
  61: }
  62: 
  63: /* getenv - given name, locate value */
  64: 
  65: char   *getenv(name)
  66: char   *name;
  67: {
  68:     int     len = namelength(name);
  69:     char  **envp = findenv(name, len);
  70: 
  71:     return (envp ? *envp + len + 1 : 0);
  72: }
  73: 
  74: /* putenv - update or append environment (name,value) pair */
  75: 
  76: int     putenv(nameval)
  77: char   *nameval;
  78: {
  79:     char   *equal = strchr(nameval, '=');
  80:     char   *value = (equal ? equal : "");
  81: 
  82:     return (setenv(nameval, value, DO_CLOBBER));
  83: }
  84: 
  85: /* unsetenv - remove variable from environment */
  86: 
  87: void    unsetenv(name)
  88: char   *name;
  89: {
  90:     char  **envp;
  91: 
  92:     if ((envp = findenv(name, namelength(name))) != 0)
  93:     while (envp[0] = envp[1])
  94:         envp++;
  95: }
  96: 
  97: /* setenv - update or append environment (name,value) pair */
  98: 
  99: int     setenv(name, value, clobber)
 100: char   *name;
 101: char   *value;
 102: int     clobber;
 103: {
 104:     char   *destination;
 105:     char  **envp;
 106:     int     l_name;         /* length of name part */
 107:     int     l_nameval;          /* length of name=value */
 108: 
 109:     /* Permit name= and =value. */
 110: 
 111:     l_name = namelength(name);
 112:     envp = findenv(name, l_name);
 113:     if (envp != 0 && clobber == 0)
 114:     return (0);
 115:     if (*value == '=')
 116:     value++;
 117:     l_nameval = l_name + strlen(value) + 1;
 118: 
 119:     /*
 120:      * Use available memory if the old value is long enough. Never free an
 121:      * old name=value entry because it may not be allocated.
 122:      */
 123: 
 124:     destination = (envp != 0 && strlen(*envp) >= l_nameval) ?
 125:     *envp : malloc(l_nameval + 1);
 126:     if (destination == 0)
 127:     return (-1);
 128:     strncpy(destination, name, l_name);
 129:     destination[l_name] = '=';
 130:     strcpy(destination + l_name + 1, value);
 131:     return ((envp == 0) ? addenv(destination) : (*envp = destination, 0));
 132: }
 133: 
 134: /* cmalloc - malloc and copy block of memory */
 135: 
 136: static char *cmalloc(new_len, old, old_len)
 137: char   *old;
 138: int     old_len;
 139: {
 140:     char   *new = malloc(new_len);
 141: 
 142:     if (new != 0)
 143:     memcpy(new, old, old_len);
 144:     return (new);
 145: }
 146: 
 147: /* addenv - append environment entry */
 148: 
 149: static int addenv(nameval)
 150: char   *nameval;
 151: {
 152:     char  **envp;
 153:     int     n_used;         /* number of environment entries */
 154:     int     l_used;         /* bytes used excl. terminator */
 155:     int     l_need;         /* bytes needed incl. terminator */
 156: 
 157:     for (envp = environ; envp && *envp; envp++)
 158:      /* void */ ;
 159:     n_used = envp - environ;
 160:     l_used = n_used * sizeof(*envp);
 161:     l_need = l_used + 2 * sizeof(*envp);
 162: 
 163:     envp = allocated ?
 164:     (char **) realloc((char *) environ, l_need) :
 165:     (char **) cmalloc(l_need, (char *) environ, l_used);
 166:     if (envp == 0) {
 167:     return (-1);
 168:     } else {
 169:     allocated = 1;
 170:     environ = envp;
 171:     environ[n_used++] = nameval;        /* add new entry */
 172:     environ[n_used] = 0;            /* terminate list */
 173:     return (0);
 174:     }
 175: }
 176: 
 177: #ifdef TEST
 178: 
 179:  /*
 180:   * Stand-alone program for test purposes.
 181:   */
 182: 
 183: /* printenv - display environment */
 184: 
 185: static void printenv()
 186: {
 187:     char  **envp;
 188: 
 189:     for (envp = environ; envp && *envp; envp++)
 190:     printf("%s\n", *envp);
 191: }
 192: 
 193: int     main(argc, argv)
 194: int     argc;
 195: char  **argv;
 196: {
 197:     char   *cp;
 198:     int     changed = 0;
 199: 
 200:     if (argc < 2) {
 201:     printf("usage: %s name[=value]...\n", argv[0]);
 202:     return (1);
 203:     }
 204:     while (--argc && *++argv) {
 205:     if (argv[0][0] == '-') {        /* unsetenv() test */
 206:         unsetenv(argv[0] + 1);
 207:         changed = 1;
 208:     } else if (strchr(argv[0], '=') == 0) { /* getenv() test */
 209:         cp = getenv(argv[0]);
 210:         printf("%s: %s\n", argv[0], cp ? cp : "not found");
 211:     } else {                /* putenv() test */
 212:         if (putenv(argv[0])) {
 213:         perror("putenv");
 214:         return (1);
 215:         }
 216:         changed = 1;
 217:     }
 218:     }
 219:     if (changed)
 220:     printenv();
 221:     return (0);
 222: }
 223: 
 224: #endif /* TEST */

Defined functions

addenv defined in line 149; used 2 times
cmalloc defined in line 136; used 1 times
findenv defined in line 51; used 3 times
getenv defined in line 65; used 3 times
main defined in line 193; never used
namelength defined in line 40; used 3 times
printenv defined in line 185; used 1 times
putenv defined in line 76; used 3 times
setenv defined in line 99; used 2 times
unsetenv defined in line 87; used 1 times

Defined variables

allocated defined in line 34; used 2 times
sccsid defined in line 10; never used

Defined macros

DO_CLOBBER defined in line 36; used 1 times
  • in line 82
memcpy defined in line 25; used 2 times
Last modified: 1994-03-23
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 538
Valid CSS Valid XHTML 1.0 Strict