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