| 1 | /* |
| 2 | * Copyright (c) 1987 Regents of the University of California. |
| 3 | * All rights reserved. |
| 4 | * |
| 5 | * %sccs.include.redist.c% |
| 6 | */ |
| 7 | |
| 8 | #if defined(LIBC_SCCS) && !defined(lint) |
| 9 | static char sccsid[] = "@(#)setenv.c 5.4 (Berkeley) %G%"; |
| 10 | #endif /* LIBC_SCCS and not lint */ |
| 11 | |
| 12 | #include <stddef.h> |
| 13 | #include <stdlib.h> |
| 14 | |
| 15 | /* |
| 16 | * setenv -- |
| 17 | * Set the value of the environmental variable "name" to be |
| 18 | * "value". If rewrite is set, replace any current value. |
| 19 | */ |
| 20 | setenv(name, value, rewrite) |
| 21 | register char *name, *value; |
| 22 | int rewrite; |
| 23 | { |
| 24 | extern char **environ; |
| 25 | static int alloced; /* if allocated space before */ |
| 26 | register char *C; |
| 27 | int l_value, offset; |
| 28 | char *_findenv(); |
| 29 | |
| 30 | if (*value == '=') /* no `=' in value */ |
| 31 | ++value; |
| 32 | l_value = strlen(value); |
| 33 | if ((C = _findenv(name, &offset))) { /* find if already exists */ |
| 34 | if (!rewrite) |
| 35 | return(0); |
| 36 | if (strlen(C) >= l_value) { /* old larger; copy over */ |
| 37 | while (*C++ = *value++); |
| 38 | return(0); |
| 39 | } |
| 40 | } |
| 41 | else { /* create new slot */ |
| 42 | register int cnt; |
| 43 | register char **P; |
| 44 | |
| 45 | for (P = environ, cnt = 0; *P; ++P, ++cnt); |
| 46 | if (alloced) { /* just increase size */ |
| 47 | environ = (char **)realloc((char *)environ, |
| 48 | (size_t)(sizeof(char *) * (cnt + 2))); |
| 49 | if (!environ) |
| 50 | return(-1); |
| 51 | } |
| 52 | else { /* get new space */ |
| 53 | alloced = 1; /* copy old entries into it */ |
| 54 | P = (char **)malloc((size_t)(sizeof(char *) * |
| 55 | (cnt + 2))); |
| 56 | if (!P) |
| 57 | return(-1); |
| 58 | bcopy(environ, P, cnt * sizeof(char *)); |
| 59 | environ = P; |
| 60 | } |
| 61 | environ[cnt + 1] = NULL; |
| 62 | offset = cnt; |
| 63 | } |
| 64 | for (C = name; *C && *C != '='; ++C); /* no `=' in name */ |
| 65 | if (!(environ[offset] = /* name + `=' + value */ |
| 66 | malloc((size_t)((int)(C - name) + l_value + 2)))) |
| 67 | return(-1); |
| 68 | for (C = environ[offset]; (*C = *name++) && *C != '='; ++C); |
| 69 | for (*C++ = '='; *C++ = *value++;); |
| 70 | return(0); |
| 71 | } |
| 72 | |
| 73 | /* |
| 74 | * unsetenv(name) -- |
| 75 | * Delete environmental variable "name". |
| 76 | */ |
| 77 | void |
| 78 | unsetenv(name) |
| 79 | char *name; |
| 80 | { |
| 81 | extern char **environ; |
| 82 | register char **P; |
| 83 | int offset; |
| 84 | |
| 85 | while (_findenv(name, &offset)) /* if set multiple times */ |
| 86 | for (P = &environ[offset];; ++P) |
| 87 | if (!(*P = *(P + 1))) |
| 88 | break; |
| 89 | } |