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