1 #include <stdio.h>
2 #include <string.h>
3 #include <stdlib.h>
4 #include "eps.h"
5
6 static void address_fixup(address_t *);
7
address_evaluate(const char * data)8 group_t *address_evaluate(const char *data)
9 {
10 group_t *g = NULL;
11 char *d = NULL, *h = NULL, *t = NULL;
12 address_t *alist = NULL, *a = NULL, *a_tail = NULL;
13
14 g = (group_t *)malloc(sizeof(group_t));
15 if (g == NULL)
16 return NULL;
17
18 alist = (address_t *)malloc(sizeof(address_t));
19 if (alist == NULL) {
20 free(g);
21 return NULL;
22 }
23
24 a_tail = alist;
25 alist->next = NULL;
26 g->group = NULL;
27 g->members = a_tail;
28 g->nmembers = 0;
29
30 /*
31 address_evaluate_one mangles data
32 */
33 d = mstrdup((char *)data);
34 if (d == NULL) {
35 free(g);
36 free(alist);
37 return NULL;
38 }
39
40 t = d;
41 h = rfc2822_next_token(d, ':', "<>;");
42 if (*h == ':') {
43 *h++ = '\0';
44
45 g->group = mstrdup(t);
46
47 while((*h == ' ') || (*h == '\t'))
48 h++;
49
50 t = h;
51 }
52
53 else
54 h = t = d;
55
56 while(1) {
57 h = rfc2822_next_token(t, ',', NULL);
58 if (!(*h))
59 break;
60
61 *h = '\0';
62
63 a = address_evaluate_one(t);
64 if (!a)
65 break;
66
67 a_tail->next = a;
68 a->next = NULL;
69 a_tail = a;
70 g->nmembers++;
71
72 t = (h + 1);
73 }
74
75 if (*t) {
76 a = address_evaluate_one(t);
77 if (a) {
78 a_tail->next = a;
79 a->next = NULL;
80 a_tail = a;
81 g->nmembers++;
82 }
83 }
84
85 if (g->group) {
86 h = rfc2822_convert_literals(g->group);
87 free(g->group);
88 g->group = h;
89 }
90
91 free(d);
92 return g;
93 }
94
address_evaluate_one(char * data)95 address_t *address_evaluate_one(char *data)
96 {
97 address_t *a = NULL;
98 char *p = NULL, *n = NULL, *u = NULL, *h = NULL, *d = NULL;
99
100 n = u = d = NULL;
101
102 a = (address_t *)malloc(sizeof(address_t));
103 if (a == NULL)
104 return NULL;
105
106 memset((address_t *)a, 0, sizeof(address_t));
107
108 p = data;
109
110 /*
111 Name/User
112 */
113 h = rfc2822_next_token(data, '<', NULL);
114 if (*h == '<') {
115 *h++ = '\0';
116
117 if (*p)
118 n = data;
119
120 if (*h)
121 u = h;
122 else
123 return a;
124
125 for (p = (h - 2); ((p > data) && ((*p == ' ') || (*p == '\t'))); p--);
126 *(++p) = '\0';
127 p = h;
128
129 if ((n) && (*n))
130 a->name = mstrdup(n);
131 }
132
133 /*
134 User/Domain
135 */
136 h = rfc2822_next_token(p, '@', ">");
137 if (*h == '@') {
138 *h++ = '\0';
139 if (!(*h))
140 return a;
141
142 if (!u) {
143 while((*p == ' ') || (*p == '\t'))
144 p++;
145
146 u = p;
147 }
148
149 d = p = h;
150 }
151
152 else
153 return a;
154
155 a->user = mstrdup(u);
156
157 /*
158 End
159 */
160 h = rfc2822_next_token(p, '>', " ");
161 if (*h == '>')
162 *h = '\0';
163
164 a->domain = mstrdup(d);
165
166 address_fixup(a);
167
168 return a;
169 }
170
address_kill(group_t * g)171 void address_kill(group_t *g)
172 {
173 address_t *a = NULL, *ao = NULL;
174
175 if (g->members) {
176 a = g->members;
177 while(a->next) {
178 ao = a->next;
179 a->next = a->next->next;
180
181 address_kill_one(ao);
182 }
183
184 free(g->members);
185 }
186
187 free(g);
188 }
189
address_kill_one(address_t * a)190 void address_kill_one(address_t *a)
191 {
192 if (!a)
193 return;
194
195 if (a->name)
196 free(a->name);
197
198 if (a->user)
199 free(a->user);
200
201 if (a->domain)
202 free(a->domain);
203
204 free(a);
205 }
206
address_fixup(address_t * a)207 void address_fixup(address_t *a)
208 {
209 char *p = NULL;
210
211 if (!a)
212 return;
213
214 if (a->name) {
215 p = rfc2822_convert_literals(a->name);
216 free(a->name);
217 a->name = p;
218 }
219 }
220
221