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