xref: /freebsd/crypto/krb5/src/clients/ksu/setenv.c (revision 7f2fe78b9dd5f51c821d771b63d2e096f6fd49e9)
1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /*
3  * Copyright (c) 1987 Regents of the University of California.
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms are permitted
7  * provided that the above copyright notice and this paragraph are
8  * duplicated in all such forms and that any documentation,
9  * advertising materials, and other materials related to such
10  * distribution and use acknowledge that the software was developed
11  * by the University of California, Berkeley.  The name of the
12  * University may not be used to endorse or promote products derived
13  * from this software without specific prior written permission.
14  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
15  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
16  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
17  */
18 /*
19  * Copyright (c) 1987 Regents of the University of California.
20  * All rights reserved.
21  *
22  * Redistribution and use in source and binary forms are permitted
23  * provided that the above copyright notice and this paragraph are
24  * duplicated in all such forms and that any documentation,
25  * advertising materials, and other materials related to such
26  * distribution and use acknowledge that the software was developed
27  * by the University of California, Berkeley.  The name of the
28  * University may not be used to endorse or promote products derived
29  * from this software without specific prior written permission.
30  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
31  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
32  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
33  */
34 
35 /* based on @(#)setenv.c        5.2 (Berkeley) 6/27/88 */
36 
37 #include "autoconf.h"
38 #include <sys/types.h>
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include <string.h>
42 
43 static char *_findenv(char *, int *);
44 
45 #ifndef HAVE_SETENV
46 extern int setenv(char *, char *, int);
47 #endif
48 #ifndef HAVE_UNSETENV
49 extern void unsetenv(char *);
50 #endif
51 
52 /*
53  * setenv --
54  *      Set the value of the environmental variable "name" to be
55  *      "value".  If rewrite is set, replace any current value.
56  */
57 #ifndef HAVE_SETENV
58 int
setenv(name,value,rewrite)59 setenv(name, value, rewrite)
60     char *name, *value;
61     int rewrite;
62 {
63     extern char **environ;
64     static int alloced;                     /* if allocated space before */
65     char *C;
66     int l_value, offset;
67 
68     if (*value == '=')                      /* no `=' in value */
69         ++value;
70     l_value = strlen(value);
71     if ((C = _findenv(name, &offset))) {    /* find if already exists */
72         if (!rewrite)
73             return(0);
74         if (strlen(C) >= l_value) {     /* old larger; copy over */
75             while ((*C++ = *value++));
76             return(0);
77         }
78     }
79     else {                                  /* create new slot */
80         int    cnt;
81         char   **P;
82 
83         for (P = environ, cnt = 0; *P; ++P, ++cnt);
84         if (alloced) {                  /* just increase size */
85             environ = (char **)realloc((char *)environ,
86                                        (u_int)(sizeof(char *) * (cnt + 2)));
87             if (!environ)
88                 return(-1);
89         }
90         else {                          /* get new space */
91             alloced = 1;            /* copy old entries into it */
92             P = (char **)malloc((u_int)(sizeof(char *) *
93                                         (cnt + 2)));
94             if (!P)
95                 return(-1);
96             memcpy(P, environ, cnt * sizeof(char *));
97             environ = P;
98         }
99         environ[cnt + 1] = NULL;
100         offset = cnt;
101     }
102     for (C = name; *C && *C != '='; ++C);   /* no `=' in name */
103     if (!(environ[offset] =                 /* name + `=' + value */
104           malloc((u_int)((int)(C - name) + l_value + 2))))
105         return(-1);
106     for (C = environ[offset]; (*C = *name++) &&( *C != '='); ++C);
107     for (*C++ = '='; (*C++ = *value++) != NULL;);
108     return(0);
109 }
110 #endif
111 
112 /*
113  * unsetenv(name) --
114  *      Delete environmental variable "name".
115  */
116 #ifndef HAVE_UNSETENV
117 void
unsetenv(name)118 unsetenv(name)
119     char    *name;
120 {
121     extern  char    **environ;
122     char   **P;
123     int     offset;
124 
125     while (_findenv(name, &offset))         /* if set multiple times */
126         for (P = &environ[offset];; ++P)
127             if (!(*P = *(P + 1)))
128                 break;
129 }
130 #endif
131 
132 /* based on @(#)getenv.c        5.5 (Berkeley) 6/27/88 */
133 
134 /*
135  * getenv --
136  *      Returns ptr to value associated with name, if any, else NULL.
137  */
138 #ifndef HAVE_GETENV
139 char *
getenv(name)140 getenv(name)
141     char *name;
142 {
143     int offset;
144 
145     return(_findenv(name, &offset));
146 }
147 #endif
148 
149 /*
150  * _findenv --
151  *      Returns pointer to value associated with name, if any, else NULL.
152  *      Sets offset to be the offset of the name/value combination in the
153  *      environmental array, for use by setenv(3) and unsetenv(3).
154  *      Explicitly removes '=' in argument name.
155  *
156  */
157 static char *
_findenv(name,offset)158 _findenv(name, offset)
159     char *name;
160     int *offset;
161 {
162     extern char **environ;
163     int len;
164     char **P, *C;
165 
166     for (C = name, len = 0; *C && *C != '='; ++C, ++len);
167     for (P = environ; *P; ++P)
168         if (!strncmp(*P, name, len))
169             if (*(C = *P + len) == '=') {
170                 *offset = P - environ;
171                 return(++C);
172             }
173     return(NULL);
174 }
175