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