source: trunk/third/tcp_wrappers/environ.c @ 11717

Revision 11717, 4.8 KB checked in by danw, 26 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r11716, which included commits to RCS files with non-trunk default branches.
Line 
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
10static char sccsid[] = "@(#) environ.c 1.2 94/03/23 16:09:46";
11#endif
12
13/* System libraries. */
14
15extern char **environ;
16extern char *strchr();
17extern char *strcpy();
18extern char *strncpy();
19extern char *malloc();
20extern char *realloc();
21extern int strncmp();
22extern void free();
23
24#ifdef no_memcpy
25#define memcpy(d,s,l) bcopy(s,d,l)
26#else
27extern char *memcpy();
28#endif
29
30/* Local stuff. */
31
32static int addenv();                    /* append entry to environment */
33
34static 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
40static int namelength(name)
41char   *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
51static char **findenv(name, len)
52char   *name;
53int     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
65char   *getenv(name)
66char   *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
76int     putenv(nameval)
77char   *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
87void    unsetenv(name)
88char   *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
99int     setenv(name, value, clobber)
100char   *name;
101char   *value;
102int     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
136static char *cmalloc(new_len, old, old_len)
137char   *old;
138int     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
149static int addenv(nameval)
150char   *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
185static void printenv()
186{
187    char  **envp;
188
189    for (envp = environ; envp && *envp; envp++)
190        printf("%s\n", *envp);
191}
192
193int     main(argc, argv)
194int     argc;
195char  **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 */
Note: See TracBrowser for help on using the repository browser.