Annotation of src/usr.bin/tmux/environ.c, Revision 1.2
1.2 ! nicm 1: /* $OpenBSD: environ.c,v 1.1 2009/08/08 21:52:43 nicm Exp $ */
1.1 nicm 2:
3: /*
4: * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
5: *
6: * Permission to use, copy, modify, and distribute this software for any
7: * purpose with or without fee is hereby granted, provided that the above
8: * copyright notice and this permission notice appear in all copies.
9: *
10: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14: * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
15: * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
16: * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17: */
18:
19: #include <sys/types.h>
20:
21: #include <stdlib.h>
22: #include <string.h>
23:
24: #include "tmux.h"
25:
26: /*
27: * Environment - manipulate a set of environment variables.
28: */
29:
30: RB_GENERATE(environ, environ_entry, entry, environ_cmp);
31:
32: void environ_set1(struct environ *, char *, char *);
33:
34: int
35: environ_cmp(struct environ_entry *envent1, struct environ_entry *envent2)
36: {
37: return (strcmp(envent1->name, envent2->name));
38: }
39:
40: void
41: environ_init(struct environ *env)
42: {
43: RB_INIT(env);
44: }
45:
46: void
47: environ_free(struct environ *env)
48: {
49: struct environ_entry *envent;
50:
51: while (!RB_EMPTY(env)) {
52: envent = RB_ROOT(env);
53: RB_REMOVE(environ, env, envent);
54: xfree(envent->name);
55: if (envent->value != NULL)
56: xfree(envent->value);
57: xfree(envent);
58: }
59: }
60:
61: void
62: environ_copy(struct environ *srcenv, struct environ *dstenv)
63: {
64: struct environ_entry *envent;
65:
66: RB_FOREACH(envent, environ, srcenv)
67: environ_set(dstenv, envent->name, envent->value);
68: }
69:
70: struct environ_entry *
71: environ_find(struct environ *env, const char *name)
72: {
73: struct environ_entry envent;
74:
75: envent.name = (char *) name;
76: return (RB_FIND(environ, env, &envent));
77: }
78:
79: void
80: environ_set(struct environ *env, const char *name, const char *value)
81: {
82: struct environ_entry *envent;
83:
84: if ((envent = environ_find(env, name)) != NULL) {
85: if (envent->value != NULL)
86: xfree(envent->value);
87: if (value != NULL)
88: envent->value = xstrdup(value);
89: else
90: envent->value = NULL;
91: } else {
92: envent = xmalloc(sizeof *envent);
93: envent->name = xstrdup(name);
94: if (value != NULL)
95: envent->value = xstrdup(value);
96: else
97: envent->value = NULL;
98: RB_INSERT(environ, env, envent);
99: }
100: }
101:
102: void
103: environ_put(struct environ *env, const char *var)
104: {
105: char *name, *value;
106:
107: value = strchr(var, '=');
108: if (value == NULL)
109: return;
110: value++;
111:
112: name = xstrdup(var);
113: name[strcspn(name, "=")] = '\0';
114:
115: environ_set(env, name, value);
116: xfree(name);
117: }
118:
119: void
120: environ_unset(struct environ *env, const char *name)
121: {
122: struct environ_entry *envent;
123:
124: if ((envent = environ_find(env, name)) == NULL)
125: return;
126: RB_REMOVE(environ, env, envent);
127: xfree(envent->name);
128: if (envent->value != NULL)
129: xfree(envent->value);
130: xfree(envent);
131: }
132:
133: void
134: environ_update(const char *vars, struct environ *srcenv, struct environ *dstenv)
135: {
136: struct environ_entry *envent;
1.2 ! nicm 137: char *copyvars, *var, *next;
1.1 nicm 138:
1.2 ! nicm 139: copyvars = next = xstrdup(vars);
1.1 nicm 140: while ((var = strsep(&next, " ")) != NULL) {
141: if ((envent = environ_find(srcenv, var)) == NULL)
142: environ_set(dstenv, var, NULL);
143: else
144: environ_set(dstenv, envent->name, envent->value);
145: }
1.2 ! nicm 146: xfree(copyvars);
1.1 nicm 147: }