1 #include <string.h>
2 #include <stdlib.h>
3 #include <bglibs/msg.h>
4 #include <bglibs/envstr.h>
5 #include "mailfront-internal.h"
6
7 struct session session = {
8 .protocol = 0,
9 };
10
session_protocol(void)11 const char* session_protocol(void)
12 {
13 return session.protocol->name;
14 }
15
session_getenv(const char * name)16 const char* session_getenv(const char* name)
17 {
18 const char* s;
19 if ((s = envstr_get(&session.env, name)) == 0)
20 s = getenv(name);
21 return s;
22 }
23
24 /* Returns the first unsigned integer value set */
session_getenvu_dflt(const char * name,unsigned long dflt)25 unsigned long session_getenvu_dflt(const char* name, unsigned long dflt)
26 {
27 const char* s;
28 unsigned long val;
29
30 #define IFGET(FN) if ((s = FN) != NULL && *s != 0) { \
31 val = strtoul(s, (char**)&s, 10); \
32 if (*s == 0) \
33 return val; \
34 }
35
36 IFGET(envstr_get(&session.env, name));
37 IFGET(getenv(name));
38 return dflt;
39 }
40
min_u_s(unsigned long u,const char * s)41 static unsigned long min_u_s(unsigned long u, const char* s)
42 {
43 unsigned long newu;
44 if (s != 0) {
45 if ((newu = strtoul(s, (char**)&s, 10)) != 0 &&
46 *s == 0 &&
47 (u == 0 || newu < u))
48 u = newu;
49 }
50 return u;
51 }
52
53 /* Returns the smallest non-zero value set */
session_getenvu(const char * name)54 unsigned long session_getenvu(const char* name)
55 {
56 unsigned i;
57 const unsigned namelen = strlen(name);
58 unsigned long val;
59 val = min_u_s(0, getenv(name));
60 for (i = 0; i < session.env.len; i += strlen(session.env.s + i) + 1) {
61 if (memcmp(session.env.s + i, name, namelen) == 0 &&
62 session.env.s[i + namelen] == '=')
63 val = min_u_s(val, session.env.s + i + namelen + 1);
64 }
65 return val;
66 }
67
session_exportenv(void)68 int session_exportenv(void)
69 {
70 unsigned i;
71 for (i = 0; i < session.env.len; i += strlen(session.env.s + i) + 1)
72 if (putenv(session.env.s + i) != 0) return 0;
73 return 1;
74 }
75
session_putenv(const char * s)76 int session_putenv(const char* s)
77 {
78 if (session.env.len > 0)
79 if (!str_catc(&session.env, 0))
80 return 0;
81 return str_catb(&session.env, s, strlen(s) + 1);
82 }
83
session_setenv(const char * name,const char * value,int overwrite)84 int session_setenv(const char* name, const char* value, int overwrite)
85 {
86 return envstr_set(&session.env, name, value, overwrite);
87 }
88
session_resetenv(void)89 void session_resetenv(void)
90 {
91 session.env.len = 0;
92 }
93
94
95 GHASH_DEFN(session_strs,const char*,const char*,
96 adt_hashsp,adt_cmpsp,0,adt_copysp,0,adt_freesp);
97 GHASH_DEFN(session_nums,const char*,unsigned long,
98 adt_hashsp,adt_cmpsp,0,0,0,0);
99
session_delnum(const char * name)100 void session_delnum(const char* name)
101 {
102 session_nums_remove(&session.nums, &name);
103 }
104
session_delstr(const char * name)105 void session_delstr(const char* name)
106 {
107 session_strs_remove(&session.strs, &name);
108 }
109
session_getstr(const char * name)110 const char* session_getstr(const char* name)
111 {
112 struct session_strs_entry* p;
113 if ((p = session_strs_get(&session.strs, &name)) == 0)
114 return 0;
115 return p->data;
116 }
117
session_setstr(const char * name,const char * value)118 void session_setstr(const char* name, const char* value)
119 {
120 /* FIXME: use _set when bglibs 1.103 is released */
121 session_strs_remove(&session.nums, &name);
122 if (session_strs_add(&session.strs, &name, &value) == 0)
123 die_oom(111);
124 }
125
session_hasnum(const char * name,unsigned long * num)126 int session_hasnum(const char* name, unsigned long* num)
127 {
128 struct session_nums_entry* p;
129 if ((p = session_nums_get(&session.nums, &name)) == 0)
130 return 0;
131 if (num != 0)
132 *num = p->data;
133 return 1;
134 }
135
session_getnum(const char * name,unsigned long dflt)136 unsigned long session_getnum(const char* name, unsigned long dflt)
137 {
138 struct session_nums_entry* p;
139 if ((p = session_nums_get(&session.nums, &name)) == 0)
140 return dflt;
141 return p->data;
142 }
143
session_setnum(const char * name,unsigned long value)144 void session_setnum(const char* name, unsigned long value)
145 {
146 /* FIXME: use _set when bglibs 1.103 is released */
147 session_nums_remove(&session.nums, &name);
148 if (session_nums_add(&session.nums, &name, &value) == 0)
149 die_oom(111);
150 }
151
152
session_init(void)153 void session_init(void)
154 {
155 memset(&session, 0, sizeof session);
156 session.fd = -1;
157 session_strs_init(&session.strs);
158 session_nums_init(&session.nums);
159 }
160