Commit | Line | Data |
---|---|---|
2117e02e MW |
1 | /* env.c, envread.c, env.h: environ library |
2 | Daniel J. Bernstein, djb@silverton.berkeley.edu. | |
3 | Depends on str.h, alloc.h. | |
4 | Requires environ. | |
5 | 19960113: rewrite. warning: interface is different. | |
6 | No known patent problems. | |
7 | */ | |
8 | ||
9 | #include "str.h" | |
10 | #include "alloc.h" | |
11 | #include "env.h" | |
12 | ||
13 | int env_isinit = 0; /* if env_isinit: */ | |
14 | static int ea; /* environ is a pointer to ea+1 char*'s. */ | |
15 | static int en; /* the first en of those are ALLOCATED. environ[en] is 0. */ | |
16 | ||
17 | static void env_goodbye(i) int i; | |
18 | { | |
19 | alloc_free(environ[i]); | |
20 | environ[i] = environ[--en]; | |
21 | environ[en] = 0; | |
22 | } | |
23 | ||
24 | static char *null = 0; | |
25 | ||
26 | void env_clear() | |
27 | { | |
28 | if (env_isinit) while (en) env_goodbye(0); | |
29 | else environ = &null; | |
30 | } | |
31 | ||
32 | static void env_unsetlen(s,len) char *s; int len; | |
33 | { | |
34 | int i; | |
35 | for (i = en - 1;i >= 0;--i) | |
36 | if (!str_diffn(s,environ[i],len)) | |
37 | if (environ[i][len] == '=') | |
38 | env_goodbye(i); | |
39 | } | |
40 | ||
41 | int env_unset(s) char *s; | |
42 | { | |
43 | if (!env_isinit) if (!env_init()) return 0; | |
44 | env_unsetlen(s,str_len(s)); | |
45 | return 1; | |
46 | } | |
47 | ||
48 | static int env_add(s) char *s; | |
49 | { | |
50 | char *t; | |
51 | t = env_findeq(s); | |
52 | if (t) env_unsetlen(s,t - s); | |
53 | if (en == ea) | |
54 | { | |
55 | ea += 30; | |
56 | if (!alloc_re(&environ,(en + 1) * sizeof(char *),(ea + 1) * sizeof(char *))) | |
57 | { ea = en; return 0; } | |
58 | } | |
59 | environ[en++] = s; | |
60 | environ[en] = 0; | |
61 | return 1; | |
62 | } | |
63 | ||
64 | int env_put(s) char *s; | |
65 | { | |
66 | char *u; | |
67 | if (!env_isinit) if (!env_init()) return 0; | |
68 | u = alloc(str_len(s) + 1); | |
69 | if (!u) return 0; | |
70 | str_copy(u,s); | |
71 | if (!env_add(u)) { alloc_free(u); return 0; } | |
72 | return 1; | |
73 | } | |
74 | ||
75 | int env_put2(s,t) char *s; char *t; | |
76 | { | |
77 | char *u; | |
78 | int slen; | |
79 | if (!env_isinit) if (!env_init()) return 0; | |
80 | slen = str_len(s); | |
81 | u = alloc(slen + str_len(t) + 2); | |
82 | if (!u) return 0; | |
83 | str_copy(u,s); | |
84 | u[slen] = '='; | |
85 | str_copy(u + slen + 1,t); | |
86 | if (!env_add(u)) { alloc_free(u); return 0; } | |
87 | return 1; | |
88 | } | |
89 | ||
90 | int env_init() | |
91 | { | |
92 | char **newenviron; | |
93 | int i; | |
94 | for (en = 0;environ[en];++en) ; | |
95 | ea = en + 10; | |
96 | newenviron = (char **) alloc((ea + 1) * sizeof(char *)); | |
97 | if (!newenviron) return 0; | |
98 | for (en = 0;environ[en];++en) | |
99 | { | |
100 | newenviron[en] = alloc(str_len(environ[en]) + 1); | |
101 | if (!newenviron[en]) | |
102 | { | |
103 | for (i = 0;i < en;++i) alloc_free(newenviron[i]); | |
104 | alloc_free(newenviron); | |
105 | return 0; | |
106 | } | |
107 | str_copy(newenviron[en],environ[en]); | |
108 | } | |
109 | newenviron[en] = 0; | |
110 | environ = newenviron; | |
111 | env_isinit = 1; | |
112 | return 1; | |
113 | } |