1*0a6a1f1dSLionel Sambuc /* Id */
2eda6f593SDavid van Moolenbroek
3eda6f593SDavid van Moolenbroek /*
4eda6f593SDavid van Moolenbroek * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
5eda6f593SDavid van Moolenbroek *
6eda6f593SDavid van Moolenbroek * Permission to use, copy, modify, and distribute this software for any
7eda6f593SDavid van Moolenbroek * purpose with or without fee is hereby granted, provided that the above
8eda6f593SDavid van Moolenbroek * copyright notice and this permission notice appear in all copies.
9eda6f593SDavid van Moolenbroek *
10eda6f593SDavid van Moolenbroek * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11eda6f593SDavid van Moolenbroek * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12eda6f593SDavid van Moolenbroek * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13eda6f593SDavid van Moolenbroek * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14eda6f593SDavid van Moolenbroek * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
15eda6f593SDavid van Moolenbroek * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
16eda6f593SDavid van Moolenbroek * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17eda6f593SDavid van Moolenbroek */
18eda6f593SDavid van Moolenbroek
19eda6f593SDavid van Moolenbroek #include <sys/types.h>
20eda6f593SDavid van Moolenbroek
21eda6f593SDavid van Moolenbroek #include <stdlib.h>
22eda6f593SDavid van Moolenbroek #include <string.h>
23eda6f593SDavid van Moolenbroek
24eda6f593SDavid van Moolenbroek #include "tmux.h"
25eda6f593SDavid van Moolenbroek
26eda6f593SDavid van Moolenbroek /*
27eda6f593SDavid van Moolenbroek * Environment - manipulate a set of environment variables.
28eda6f593SDavid van Moolenbroek */
29eda6f593SDavid van Moolenbroek
30eda6f593SDavid van Moolenbroek RB_GENERATE(environ, environ_entry, entry, environ_cmp);
31eda6f593SDavid van Moolenbroek
32eda6f593SDavid van Moolenbroek int
environ_cmp(struct environ_entry * envent1,struct environ_entry * envent2)33eda6f593SDavid van Moolenbroek environ_cmp(struct environ_entry *envent1, struct environ_entry *envent2)
34eda6f593SDavid van Moolenbroek {
35eda6f593SDavid van Moolenbroek return (strcmp(envent1->name, envent2->name));
36eda6f593SDavid van Moolenbroek }
37eda6f593SDavid van Moolenbroek
38eda6f593SDavid van Moolenbroek /* Initialise the environment. */
39eda6f593SDavid van Moolenbroek void
environ_init(struct environ * env)40eda6f593SDavid van Moolenbroek environ_init(struct environ *env)
41eda6f593SDavid van Moolenbroek {
42eda6f593SDavid van Moolenbroek RB_INIT(env);
43eda6f593SDavid van Moolenbroek }
44eda6f593SDavid van Moolenbroek
45eda6f593SDavid van Moolenbroek /* Free an environment. */
46eda6f593SDavid van Moolenbroek void
environ_free(struct environ * env)47eda6f593SDavid van Moolenbroek environ_free(struct environ *env)
48eda6f593SDavid van Moolenbroek {
49eda6f593SDavid van Moolenbroek struct environ_entry *envent;
50eda6f593SDavid van Moolenbroek
51eda6f593SDavid van Moolenbroek while (!RB_EMPTY(env)) {
52eda6f593SDavid van Moolenbroek envent = RB_ROOT(env);
53eda6f593SDavid van Moolenbroek RB_REMOVE(environ, env, envent);
54*0a6a1f1dSLionel Sambuc free(envent->name);
55*0a6a1f1dSLionel Sambuc free(envent->value);
56*0a6a1f1dSLionel Sambuc free(envent);
57eda6f593SDavid van Moolenbroek }
58eda6f593SDavid van Moolenbroek }
59eda6f593SDavid van Moolenbroek
60eda6f593SDavid van Moolenbroek /* Copy one environment into another. */
61eda6f593SDavid van Moolenbroek void
environ_copy(struct environ * srcenv,struct environ * dstenv)62eda6f593SDavid van Moolenbroek environ_copy(struct environ *srcenv, struct environ *dstenv)
63eda6f593SDavid van Moolenbroek {
64eda6f593SDavid van Moolenbroek struct environ_entry *envent;
65eda6f593SDavid van Moolenbroek
66eda6f593SDavid van Moolenbroek RB_FOREACH(envent, environ, srcenv)
67eda6f593SDavid van Moolenbroek environ_set(dstenv, envent->name, envent->value);
68eda6f593SDavid van Moolenbroek }
69eda6f593SDavid van Moolenbroek
70eda6f593SDavid van Moolenbroek /* Find an environment variable. */
71eda6f593SDavid van Moolenbroek struct environ_entry *
environ_find(struct environ * env,const char * name)72eda6f593SDavid van Moolenbroek environ_find(struct environ *env, const char *name)
73eda6f593SDavid van Moolenbroek {
74eda6f593SDavid van Moolenbroek struct environ_entry envent;
75eda6f593SDavid van Moolenbroek
76eda6f593SDavid van Moolenbroek envent.name = __UNCONST(name);
77eda6f593SDavid van Moolenbroek return (RB_FIND(environ, env, &envent));
78eda6f593SDavid van Moolenbroek }
79eda6f593SDavid van Moolenbroek
80eda6f593SDavid van Moolenbroek /* Set an environment variable. */
81eda6f593SDavid van Moolenbroek void
environ_set(struct environ * env,const char * name,const char * value)82eda6f593SDavid van Moolenbroek environ_set(struct environ *env, const char *name, const char *value)
83eda6f593SDavid van Moolenbroek {
84eda6f593SDavid van Moolenbroek struct environ_entry *envent;
85eda6f593SDavid van Moolenbroek
86eda6f593SDavid van Moolenbroek if ((envent = environ_find(env, name)) != NULL) {
87*0a6a1f1dSLionel Sambuc free(envent->value);
88eda6f593SDavid van Moolenbroek if (value != NULL)
89eda6f593SDavid van Moolenbroek envent->value = xstrdup(value);
90eda6f593SDavid van Moolenbroek else
91eda6f593SDavid van Moolenbroek envent->value = NULL;
92eda6f593SDavid van Moolenbroek } else {
93eda6f593SDavid van Moolenbroek envent = xmalloc(sizeof *envent);
94eda6f593SDavid van Moolenbroek envent->name = xstrdup(name);
95eda6f593SDavid van Moolenbroek if (value != NULL)
96eda6f593SDavid van Moolenbroek envent->value = xstrdup(value);
97eda6f593SDavid van Moolenbroek else
98eda6f593SDavid van Moolenbroek envent->value = NULL;
99eda6f593SDavid van Moolenbroek RB_INSERT(environ, env, envent);
100eda6f593SDavid van Moolenbroek }
101eda6f593SDavid van Moolenbroek }
102eda6f593SDavid van Moolenbroek
103eda6f593SDavid van Moolenbroek /* Set an environment variable from a NAME=VALUE string. */
104eda6f593SDavid van Moolenbroek void
environ_put(struct environ * env,const char * var)105eda6f593SDavid van Moolenbroek environ_put(struct environ *env, const char *var)
106eda6f593SDavid van Moolenbroek {
107eda6f593SDavid van Moolenbroek char *name, *value;
108eda6f593SDavid van Moolenbroek
109eda6f593SDavid van Moolenbroek value = strchr(var, '=');
110eda6f593SDavid van Moolenbroek if (value == NULL)
111eda6f593SDavid van Moolenbroek return;
112eda6f593SDavid van Moolenbroek value++;
113eda6f593SDavid van Moolenbroek
114eda6f593SDavid van Moolenbroek name = xstrdup(var);
115eda6f593SDavid van Moolenbroek name[strcspn(name, "=")] = '\0';
116eda6f593SDavid van Moolenbroek
117eda6f593SDavid van Moolenbroek environ_set(env, name, value);
118*0a6a1f1dSLionel Sambuc free(name);
119eda6f593SDavid van Moolenbroek }
120eda6f593SDavid van Moolenbroek
121eda6f593SDavid van Moolenbroek /* Unset an environment variable. */
122eda6f593SDavid van Moolenbroek void
environ_unset(struct environ * env,const char * name)123eda6f593SDavid van Moolenbroek environ_unset(struct environ *env, const char *name)
124eda6f593SDavid van Moolenbroek {
125eda6f593SDavid van Moolenbroek struct environ_entry *envent;
126eda6f593SDavid van Moolenbroek
127eda6f593SDavid van Moolenbroek if ((envent = environ_find(env, name)) == NULL)
128eda6f593SDavid van Moolenbroek return;
129eda6f593SDavid van Moolenbroek RB_REMOVE(environ, env, envent);
130*0a6a1f1dSLionel Sambuc free(envent->name);
131*0a6a1f1dSLionel Sambuc free(envent->value);
132*0a6a1f1dSLionel Sambuc free(envent);
133eda6f593SDavid van Moolenbroek }
134eda6f593SDavid van Moolenbroek
135eda6f593SDavid van Moolenbroek /*
136eda6f593SDavid van Moolenbroek * Copy a space-separated list of variables from a destination into a source
137eda6f593SDavid van Moolenbroek * environment.
138eda6f593SDavid van Moolenbroek */
139eda6f593SDavid van Moolenbroek void
environ_update(const char * vars,struct environ * srcenv,struct environ * dstenv)140eda6f593SDavid van Moolenbroek environ_update(const char *vars, struct environ *srcenv, struct environ *dstenv)
141eda6f593SDavid van Moolenbroek {
142eda6f593SDavid van Moolenbroek struct environ_entry *envent;
143eda6f593SDavid van Moolenbroek char *copyvars, *var, *next;
144eda6f593SDavid van Moolenbroek
145eda6f593SDavid van Moolenbroek copyvars = next = xstrdup(vars);
146eda6f593SDavid van Moolenbroek while ((var = strsep(&next, " ")) != NULL) {
147eda6f593SDavid van Moolenbroek if ((envent = environ_find(srcenv, var)) == NULL)
148eda6f593SDavid van Moolenbroek environ_set(dstenv, var, NULL);
149eda6f593SDavid van Moolenbroek else
150eda6f593SDavid van Moolenbroek environ_set(dstenv, envent->name, envent->value);
151eda6f593SDavid van Moolenbroek }
152*0a6a1f1dSLionel Sambuc free(copyvars);
153eda6f593SDavid van Moolenbroek }
154eda6f593SDavid van Moolenbroek
155eda6f593SDavid van Moolenbroek /* Push environment into the real environment - use after fork(). */
156eda6f593SDavid van Moolenbroek void
environ_push(struct environ * env)157eda6f593SDavid van Moolenbroek environ_push(struct environ *env)
158eda6f593SDavid van Moolenbroek {
159eda6f593SDavid van Moolenbroek ARRAY_DECL(, char *) varlist;
160eda6f593SDavid van Moolenbroek struct environ_entry *envent;
161eda6f593SDavid van Moolenbroek char **varp, *var;
162eda6f593SDavid van Moolenbroek u_int i;
163eda6f593SDavid van Moolenbroek
164eda6f593SDavid van Moolenbroek ARRAY_INIT(&varlist);
165eda6f593SDavid van Moolenbroek for (varp = environ; *varp != NULL; varp++) {
166eda6f593SDavid van Moolenbroek var = xstrdup(*varp);
167eda6f593SDavid van Moolenbroek var[strcspn(var, "=")] = '\0';
168eda6f593SDavid van Moolenbroek ARRAY_ADD(&varlist, var);
169eda6f593SDavid van Moolenbroek }
170eda6f593SDavid van Moolenbroek for (i = 0; i < ARRAY_LENGTH(&varlist); i++)
171eda6f593SDavid van Moolenbroek unsetenv(ARRAY_ITEM(&varlist, i));
172eda6f593SDavid van Moolenbroek ARRAY_FREE(&varlist);
173eda6f593SDavid van Moolenbroek
174eda6f593SDavid van Moolenbroek RB_FOREACH(envent, environ, env) {
175eda6f593SDavid van Moolenbroek if (envent->value != NULL)
176eda6f593SDavid van Moolenbroek setenv(envent->name, envent->value, 1);
177eda6f593SDavid van Moolenbroek }
178eda6f593SDavid van Moolenbroek }
179