summaryrefslogtreecommitdiff
path: root/env.c
diff options
context:
space:
mode:
Diffstat (limited to 'env.c')
-rw-r--r--env.c136
1 files changed, 136 insertions, 0 deletions
diff --git a/env.c b/env.c
new file mode 100644
index 0000000..2ecaa83
--- /dev/null
+++ b/env.c
@@ -0,0 +1,136 @@
+#include "str.h"
+#include "alloc.h"
+#include "env.h"
+
+/**
+ @file env.c
+ @author djb
+ @source ucspi-tcp
+ @brief setting up environment after fork
+*/
+
+extern /*@null@*/char *env_get(char *s)
+{
+ int i;
+ unsigned int len;
+
+ if (!s) return 0;
+ len = str_len(s);
+ for (i = 0; environ[i]; ++i)
+ if (str_start(environ[i],s) && (environ[i][len] == '='))
+ return environ[i] + len + 1;
+ return 0;
+}
+
+extern char *env_findeq(char *s)
+{
+ for (; *s; ++s)
+ if (*s == '=') return s;
+ return 0;
+}
+
+int env_isinit = 0; /* if env_isinit: */
+static int ea; /* environ is a pointer to ea+1 char*'s. */
+static int en; /* the first en of those are ALLOCATED. environ[en] is 0. */
+
+static void env_del(int i) {
+ alloc_free(environ[i]);
+ environ[i] = environ[--en];
+ environ[en] = 0;
+}
+
+static void env_unsetlen(char *s,int len)
+{
+ int i;
+
+ for (i = en - 1; i >= 0; --i)
+ if (!str_diffn(s,environ[i],len))
+ if (environ[i][len] == '=')
+ env_del(i);
+}
+
+int env_unset(char *s)
+{
+ if (!env_isinit)
+ if (!env_init()) return 0;
+ env_unsetlen(s,str_len(s));
+ return 1;
+}
+
+int env_set(char *s) {
+ char *t;
+
+ t = env_findeq(s);
+ if (t) env_unsetlen(s,t - s);
+ if (en == ea) {
+ ea += 30;
+ if (!alloc_re(&environ,(en + 1) * sizeof(char *),(ea + 1) * sizeof(char *)))
+ { ea = en; return 0; }
+ }
+ environ[en++] = s;
+ environ[en] = 0;
+ return 1;
+}
+
+int env_puts(char *s) {
+ char *u;
+
+ if (!env_isinit)
+ if (!env_init()) return 0;
+ u = alloc(str_len(s) + 1);
+ if (!u) return 0;
+ str_copy(u,s);
+ if (!env_set(u)) { alloc_free(u); return 0; }
+ return 1;
+}
+
+int env_put(char *name,char *value) {
+ char *ln;
+ int len;
+
+ if (!env_isinit)
+ if (!env_init()) return 0;
+ len = str_len(name);
+ ln = alloc(len + str_len(value) + 2);
+ if (!ln) return 0;
+ str_copy(ln,name);
+ ln[len] = '=';
+ str_copy(ln + len + 1,value);
+ if (!env_set(ln)) { alloc_free(ln); return 0; }
+ return 1;
+}
+
+int env_init() {
+ char **newenviron;
+ int i;
+
+ for (en = 0; environ[en]; ++en)
+ ;
+ ea = en + 10;
+ newenviron = (char **) alloc((ea + 1) * sizeof(char *));
+ if (!newenviron) return 0;
+
+ for (en = 0; environ[en]; ++en) {
+ newenviron[en] = alloc(str_len(environ[en]) + 1);
+ if (!newenviron[en]) {
+ for (i = 0; i < en; ++i) alloc_free(newenviron[i]);
+ alloc_free(newenviron);
+ return 0;
+ }
+ str_copy(newenviron[en],environ[en]);
+ }
+
+ newenviron[en] = 0;
+ environ = newenviron;
+ env_isinit = 1;
+ return 1;
+}
+
+static char *null = 0;
+
+void env_clear() {
+ if (env_isinit)
+ while (en) env_del(0);
+ else environ = &null;
+}
+extern char *env_pick() { return environ[0]; }