1 /* $OpenBSD: environ.c,v 1.3 2009/08/09 15:17:50 nicm Exp $ */ 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 int 33 environ_cmp(struct environ_entry *envent1, struct environ_entry *envent2) 34 { 35 return (strcmp(envent1->name, envent2->name)); 36 } 37 38 void 39 environ_init(struct environ *env) 40 { 41 RB_INIT(env); 42 } 43 44 void 45 environ_free(struct environ *env) 46 { 47 struct environ_entry *envent; 48 49 while (!RB_EMPTY(env)) { 50 envent = RB_ROOT(env); 51 RB_REMOVE(environ, env, envent); 52 xfree(envent->name); 53 if (envent->value != NULL) 54 xfree(envent->value); 55 xfree(envent); 56 } 57 } 58 59 void 60 environ_copy(struct environ *srcenv, struct environ *dstenv) 61 { 62 struct environ_entry *envent; 63 64 RB_FOREACH(envent, environ, srcenv) 65 environ_set(dstenv, envent->name, envent->value); 66 } 67 68 struct environ_entry * 69 environ_find(struct environ *env, const char *name) 70 { 71 struct environ_entry envent; 72 73 envent.name = (char *) name; 74 return (RB_FIND(environ, env, &envent)); 75 } 76 77 void 78 environ_set(struct environ *env, const char *name, const char *value) 79 { 80 struct environ_entry *envent; 81 82 if ((envent = environ_find(env, name)) != NULL) { 83 if (envent->value != NULL) 84 xfree(envent->value); 85 if (value != NULL) 86 envent->value = xstrdup(value); 87 else 88 envent->value = NULL; 89 } else { 90 envent = xmalloc(sizeof *envent); 91 envent->name = xstrdup(name); 92 if (value != NULL) 93 envent->value = xstrdup(value); 94 else 95 envent->value = NULL; 96 RB_INSERT(environ, env, envent); 97 } 98 } 99 100 void 101 environ_put(struct environ *env, const char *var) 102 { 103 char *name, *value; 104 105 value = strchr(var, '='); 106 if (value == NULL) 107 return; 108 value++; 109 110 name = xstrdup(var); 111 name[strcspn(name, "=")] = '\0'; 112 113 environ_set(env, name, value); 114 xfree(name); 115 } 116 117 void 118 environ_unset(struct environ *env, const char *name) 119 { 120 struct environ_entry *envent; 121 122 if ((envent = environ_find(env, name)) == NULL) 123 return; 124 RB_REMOVE(environ, env, envent); 125 xfree(envent->name); 126 if (envent->value != NULL) 127 xfree(envent->value); 128 xfree(envent); 129 } 130 131 void 132 environ_update(const char *vars, struct environ *srcenv, struct environ *dstenv) 133 { 134 struct environ_entry *envent; 135 char *copyvars, *var, *next; 136 137 copyvars = next = xstrdup(vars); 138 while ((var = strsep(&next, " ")) != NULL) { 139 if ((envent = environ_find(srcenv, var)) == NULL) 140 environ_set(dstenv, var, NULL); 141 else 142 environ_set(dstenv, envent->name, envent->value); 143 } 144 xfree(copyvars); 145 } 146