(_address_get_nth): Get nth sub-address from an address.
(most of the functions): Rewritten using _address_get_nth (address_aget_personal, address_aget_comments): new functions. (address_dup): New function. Create a copy of a (single) address. (address_contains_email): New function. Check if the given email is contained in the address. (address_union): New function. Create a union of two addresses.
Showing
1 changed file
with
352 additions
and
156 deletions
... | @@ -37,7 +37,7 @@ | ... | @@ -37,7 +37,7 @@ |
37 | 37 | ||
38 | /* Get email addresses from rfc822 address. */ | 38 | /* Get email addresses from rfc822 address. */ |
39 | int | 39 | int |
40 | address_create (address_t *a, const char *s) | 40 | address_create (address_t * a, const char *s) |
41 | { | 41 | { |
42 | /* 'a' must exist, and can't already have been initialized | 42 | /* 'a' must exist, and can't already have been initialized |
43 | */ | 43 | */ |
... | @@ -46,7 +46,7 @@ address_create (address_t *a, const char *s) | ... | @@ -46,7 +46,7 @@ address_create (address_t *a, const char *s) |
46 | if (!a) | 46 | if (!a) |
47 | return MU_ERR_OUT_PTR_NULL; | 47 | return MU_ERR_OUT_PTR_NULL; |
48 | 48 | ||
49 | if(!s) | 49 | if (!s) |
50 | return EINVAL; | 50 | return EINVAL; |
51 | 51 | ||
52 | *a = NULL; | 52 | *a = NULL; |
... | @@ -63,29 +63,29 @@ address_create (address_t *a, const char *s) | ... | @@ -63,29 +63,29 @@ address_create (address_t *a, const char *s) |
63 | { | 63 | { |
64 | address_destroy (a); | 64 | address_destroy (a); |
65 | return ENOMEM; | 65 | return ENOMEM; |
66 | } | 66 | } |
67 | } | 67 | } |
68 | return status; | 68 | return status; |
69 | } | 69 | } |
70 | 70 | ||
71 | /* Get email addresses from array of rfc822 addresses. */ | 71 | /* Get email addresses from array of rfc822 addresses. */ |
72 | int | 72 | int |
73 | address_createv (address_t *a, const char *sv[], size_t len) | 73 | address_createv (address_t * a, const char *sv[], size_t len) |
74 | { | 74 | { |
75 | int status = 0; | 75 | int status = 0; |
76 | size_t buflen = 0; | 76 | size_t buflen = 0; |
77 | char* buf = 0; | 77 | char *buf = 0; |
78 | size_t i; | 78 | size_t i; |
79 | 79 | ||
80 | if(!a) | 80 | if (!a) |
81 | return MU_ERR_OUT_PTR_NULL; | 81 | return MU_ERR_OUT_PTR_NULL; |
82 | 82 | ||
83 | if (!sv) | 83 | if (!sv) |
84 | return EINVAL; | 84 | return EINVAL; |
85 | 85 | ||
86 | if (len == (size_t)-1) | 86 | if (len == (size_t) - 1) |
87 | { | 87 | { |
88 | const char** vp = sv; | 88 | const char **vp = sv; |
89 | 89 | ||
90 | len = 0; | 90 | len = 0; |
91 | 91 | ||
... | @@ -97,14 +97,14 @@ address_createv (address_t *a, const char *sv[], size_t len) | ... | @@ -97,14 +97,14 @@ address_createv (address_t *a, const char *sv[], size_t len) |
97 | return EINVAL; | 97 | return EINVAL; |
98 | 98 | ||
99 | for (i = 0; i < len; i++) | 99 | for (i = 0; i < len; i++) |
100 | { | 100 | { |
101 | /* NULL strings are allowed */ | 101 | /* NULL strings are allowed */ |
102 | if(sv[i]) | 102 | if (sv[i]) |
103 | buflen += strlen(sv[i]); | 103 | buflen += strlen (sv[i]); |
104 | } | 104 | } |
105 | 105 | ||
106 | buflen += (len - 1) * strlen (", "); | 106 | buflen += (len - 1) * strlen (", "); |
107 | buflen += 1; /* Termination null. */ | 107 | buflen += 1; /* Termination null. */ |
108 | 108 | ||
109 | buf = malloc (buflen); | 109 | buf = malloc (buflen); |
110 | 110 | ||
... | @@ -113,11 +113,11 @@ address_createv (address_t *a, const char *sv[], size_t len) | ... | @@ -113,11 +113,11 @@ address_createv (address_t *a, const char *sv[], size_t len) |
113 | 113 | ||
114 | for (i = 0, buf[0] = '\0'; i < len; i++) | 114 | for (i = 0, buf[0] = '\0'; i < len; i++) |
115 | { | 115 | { |
116 | if(i != 0) | 116 | if (i != 0) |
117 | strcat (buf, ", "); | 117 | strcat (buf, ", "); |
118 | 118 | ||
119 | if(sv[i]) | 119 | if (sv[i]) |
120 | strcat (buf, sv[i]); | 120 | strcat (buf, sv[i]); |
121 | } | 121 | } |
122 | 122 | ||
123 | status = address_create (a, buf); | 123 | status = address_create (a, buf); |
... | @@ -128,7 +128,7 @@ address_createv (address_t *a, const char *sv[], size_t len) | ... | @@ -128,7 +128,7 @@ address_createv (address_t *a, const char *sv[], size_t len) |
128 | } | 128 | } |
129 | 129 | ||
130 | void | 130 | void |
131 | address_destroy (address_t *paddress) | 131 | address_destroy (address_t * paddress) |
132 | { | 132 | { |
133 | if (paddress && *paddress) | 133 | if (paddress && *paddress) |
134 | { | 134 | { |
... | @@ -157,181 +157,299 @@ address_destroy (address_t *paddress) | ... | @@ -157,181 +157,299 @@ address_destroy (address_t *paddress) |
157 | } | 157 | } |
158 | } | 158 | } |
159 | 159 | ||
160 | int address_concatenate (address_t to, address_t* from) | 160 | int |
161 | address_concatenate (address_t to, address_t * from) | ||
161 | { | 162 | { |
162 | if(!to || !from || !*from) | 163 | if (!to || !from || !*from) |
163 | return EINVAL; | 164 | return EINVAL; |
164 | 165 | ||
165 | while(to->next) | 166 | while (to->next) |
166 | to = to->next; | 167 | to = to->next; |
167 | 168 | ||
168 | assert(to && !to->next); | 169 | assert (to && !to->next); |
169 | 170 | ||
170 | to->next = *from; | 171 | to->next = *from; |
171 | *from = NULL; | 172 | *from = NULL; |
172 | 173 | ||
173 | to = to->next; | 174 | to = to->next; |
174 | 175 | ||
175 | if(to->addr) | 176 | if (to->addr) |
176 | { | 177 | { |
177 | free(to->addr); | 178 | free (to->addr); |
178 | to->addr = NULL; | 179 | to->addr = NULL; |
179 | } | 180 | } |
180 | 181 | ||
181 | return 0; | 182 | return 0; |
182 | } | 183 | } |
183 | 184 | ||
185 | address_t | ||
186 | _address_get_nth (address_t addr, size_t no) | ||
187 | { | ||
188 | int i; | ||
189 | |||
190 | for (i = 1; addr; addr = addr->next, i++) | ||
191 | if (i == no) | ||
192 | break; | ||
193 | return addr; | ||
194 | } | ||
195 | |||
184 | int | 196 | int |
185 | address_get_personal (address_t addr, size_t no, char *buf, size_t len, | 197 | address_get_personal (address_t addr, size_t no, char *buf, size_t len, |
186 | size_t *n) | 198 | size_t * n) |
187 | { | 199 | { |
188 | size_t i, j; | 200 | size_t i; |
189 | int status = ENOENT; | 201 | address_t subaddr; |
202 | |||
190 | if (addr == NULL) | 203 | if (addr == NULL) |
191 | return EINVAL; | 204 | return EINVAL; |
192 | for (i = 0, j = 1; addr; addr = addr->next, j++) | 205 | |
193 | { | 206 | subaddr = _address_get_nth (addr, no); |
194 | if (j == no) | 207 | if (!subaddr) |
195 | { | 208 | return ENOENT; |
196 | i = mu_cpystr (buf, addr->personal, len); | 209 | |
197 | status = 0; | 210 | i = mu_cpystr (buf, subaddr->personal, len); |
198 | break; | ||
199 | } | ||
200 | } | ||
201 | if (n) | 211 | if (n) |
202 | *n = i; | 212 | *n = i; |
203 | return status; | 213 | return 0; |
204 | } | 214 | } |
205 | 215 | ||
206 | int | 216 | int |
207 | address_get_comments (address_t addr, size_t no, char *buf, size_t len, | 217 | address_get_comments (address_t addr, size_t no, char *buf, size_t len, |
208 | size_t *n) | 218 | size_t * n) |
209 | { | 219 | { |
210 | size_t i, j; | 220 | size_t i; |
211 | int status = ENOENT; | 221 | address_t subaddr; |
222 | |||
223 | if (addr == NULL) | ||
224 | return EINVAL; | ||
225 | |||
226 | subaddr = _address_get_nth (addr, no); | ||
227 | if (!subaddr) | ||
228 | return ENOENT; | ||
229 | |||
230 | i = mu_cpystr (buf, subaddr->comments, len); | ||
231 | if (n) | ||
232 | *n = i; | ||
233 | return 0; | ||
234 | } | ||
235 | |||
236 | int | ||
237 | address_get_email (address_t addr, size_t no, char *buf, size_t len, | ||
238 | size_t * n) | ||
239 | { | ||
240 | size_t i; | ||
241 | address_t subaddr; | ||
242 | |||
212 | if (addr == NULL) | 243 | if (addr == NULL) |
213 | return EINVAL; | 244 | return EINVAL; |
214 | for (j = 1; addr; addr = addr->next, j++) | 245 | |
246 | subaddr = _address_get_nth (addr, no); | ||
247 | if (!subaddr) | ||
248 | return ENOENT; | ||
249 | |||
250 | i = mu_cpystr (buf, subaddr->email, len); | ||
251 | if (n) | ||
252 | *n = i; | ||
253 | return 0; | ||
254 | } | ||
255 | |||
256 | #define format_char(c) do {\ | ||
257 | if (buflen) \ | ||
258 | {\ | ||
259 | *buf++ = c;\ | ||
260 | buflen--;\ | ||
261 | }\ | ||
262 | else\ | ||
263 | rc++;\ | ||
264 | } while(0) | ||
265 | |||
266 | #define format_string(str) do {\ | ||
267 | if (buflen) \ | ||
268 | {\ | ||
269 | int n = snprintf (buf, buflen, "%s", str);\ | ||
270 | buf += n;\ | ||
271 | buflen -= n;\ | ||
272 | }\ | ||
273 | else\ | ||
274 | rc += strlen (str);\ | ||
275 | } while (0) | ||
276 | |||
277 | size_t | ||
278 | address_format_string (address_t addr, char *buf, size_t buflen) | ||
279 | { | ||
280 | int rc = 0; | ||
281 | int comma = 0; | ||
282 | |||
283 | for (;addr; addr = addr->next) | ||
215 | { | 284 | { |
216 | if (j == no) | 285 | if (addr->email) |
217 | { | 286 | { |
218 | i = mu_cpystr (buf, addr->comments, len); | 287 | int space = 0; |
219 | if (n) | 288 | |
220 | *n = i; | 289 | if (comma) |
221 | status = 0; | 290 | format_char (','); |
222 | break; | 291 | |
292 | if (addr->personal) | ||
293 | { | ||
294 | format_char ('"'); | ||
295 | format_string (addr->personal); | ||
296 | format_char ('"'); | ||
297 | space++; | ||
298 | } | ||
299 | |||
300 | if (addr->comments) | ||
301 | { | ||
302 | if (space) | ||
303 | format_char (' '); | ||
304 | format_char ('('); | ||
305 | format_string (addr->comments); | ||
306 | format_char (')'); | ||
307 | space++; | ||
308 | } | ||
309 | |||
310 | if (space) | ||
311 | format_char (' '); | ||
312 | format_char ('<'); | ||
313 | format_string (addr->email); | ||
314 | format_char ('>'); | ||
315 | comma++; | ||
223 | } | 316 | } |
224 | } | 317 | } |
318 | format_char (0); | ||
319 | return rc; | ||
320 | } | ||
321 | |||
322 | int | ||
323 | address_aget_personal (address_t addr, size_t no, char **buf) | ||
324 | { | ||
325 | int status; | ||
326 | address_t subaddr; | ||
327 | |||
328 | if (addr == NULL) | ||
329 | return EINVAL; | ||
330 | |||
331 | subaddr = _address_get_nth (addr, no); | ||
332 | if (!subaddr) | ||
333 | return ENOENT; | ||
334 | |||
335 | if (subaddr->personal) | ||
336 | { | ||
337 | *buf = strdup (subaddr->personal); | ||
338 | if (!*buf) | ||
339 | status = ENOMEM; | ||
340 | } | ||
341 | else | ||
342 | buf = NULL; | ||
225 | return status; | 343 | return status; |
226 | } | 344 | } |
227 | 345 | ||
228 | int | 346 | int |
229 | address_get_email (address_t addr, size_t no, char *buf, size_t len, size_t *n) | 347 | address_aget_comments (address_t addr, size_t no, char **buf) |
230 | { | 348 | { |
231 | size_t i, j; | 349 | int status; |
232 | int status = ENOENT; | 350 | address_t subaddr; |
351 | |||
233 | if (addr == NULL) | 352 | if (addr == NULL) |
234 | return EINVAL; | 353 | return EINVAL; |
235 | for (j = 1; addr; addr = addr->next, j++) | 354 | |
355 | subaddr = _address_get_nth (addr, no); | ||
356 | if (!subaddr) | ||
357 | return ENOENT; | ||
358 | |||
359 | if (subaddr->comments) | ||
236 | { | 360 | { |
237 | if (j == no) | 361 | *buf = strdup (subaddr->comments); |
238 | { | 362 | if (!*buf) |
239 | i = mu_cpystr (buf, addr->email, len); | 363 | status = ENOMEM; |
240 | if (n) | ||
241 | *n = i; | ||
242 | status = 0; | ||
243 | break; | ||
244 | } | ||
245 | } | 364 | } |
365 | else | ||
366 | buf = NULL; | ||
246 | return status; | 367 | return status; |
247 | } | 368 | } |
248 | 369 | ||
249 | int | 370 | int |
250 | address_aget_email (address_t addr, size_t no, char **buf) | 371 | address_aget_email (address_t addr, size_t no, char **buf) |
251 | { | 372 | { |
252 | size_t j; | 373 | int status = 0; |
253 | int status = ENOENT; | 374 | address_t subaddr; |
375 | |||
254 | if (addr == NULL || buf == NULL) | 376 | if (addr == NULL || buf == NULL) |
255 | return EINVAL; | 377 | return EINVAL; |
256 | for (j = 1; addr; addr = addr->next, j++) | 378 | |
379 | subaddr = _address_get_nth (addr, no); | ||
380 | if (!subaddr) | ||
381 | return ENOENT; | ||
382 | |||
383 | if (subaddr->email) | ||
257 | { | 384 | { |
258 | if (j == no) | 385 | *buf = strdup (subaddr->email); |
259 | { | 386 | if (!*buf) |
260 | status = 0; | 387 | status = ENOMEM; |
261 | *buf = NULL; | ||
262 | if (addr->email) | ||
263 | { | ||
264 | *buf = strdup (addr->email); | ||
265 | if (!*buf) | ||
266 | status = ENOMEM; | ||
267 | } | ||
268 | break; | ||
269 | } | ||
270 | } | 388 | } |
389 | else | ||
390 | *buf = NULL; | ||
391 | |||
271 | return status; | 392 | return status; |
272 | } | 393 | } |
273 | 394 | ||
274 | int | 395 | int |
275 | address_get_local_part (address_t addr, size_t no, char *buf, size_t len, size_t *n) | 396 | address_get_local_part (address_t addr, size_t no, char *buf, size_t len, |
397 | size_t * n) | ||
276 | { | 398 | { |
277 | size_t i, j; | 399 | size_t i; |
278 | int status = ENOENT; | 400 | address_t subaddr; |
401 | |||
279 | if (addr == NULL) | 402 | if (addr == NULL) |
280 | return EINVAL; | 403 | return EINVAL; |
281 | for (j = 1; addr; addr = addr->next, j++) | 404 | |
282 | { | 405 | subaddr = _address_get_nth (addr, no); |
283 | if (j == no) | 406 | if (!subaddr) |
284 | { | 407 | return ENOENT; |
285 | i = mu_cpystr (buf, addr->local_part, len); | 408 | |
286 | if (n) | 409 | i = mu_cpystr (buf, subaddr->local_part, len); |
287 | *n = i; | 410 | if (n) |
288 | status = 0; | 411 | *n = i; |
289 | break; | 412 | return 0; |
290 | } | ||
291 | } | ||
292 | return status; | ||
293 | } | 413 | } |
294 | 414 | ||
295 | int | 415 | int |
296 | address_get_domain (address_t addr, size_t no, char *buf, size_t len, size_t *n) | 416 | address_get_domain (address_t addr, size_t no, char *buf, size_t len, |
417 | size_t * n) | ||
297 | { | 418 | { |
298 | size_t i, j; | 419 | size_t i; |
299 | int status = ENOENT; | 420 | address_t subaddr; |
421 | |||
300 | if (addr == NULL) | 422 | if (addr == NULL) |
301 | return EINVAL; | 423 | return EINVAL; |
302 | for (j = 1; addr; addr = addr->next, j++) | 424 | |
303 | { | 425 | subaddr = _address_get_nth (addr, no); |
304 | if (j == no) | 426 | if (!subaddr) |
305 | { | 427 | return ENOENT; |
306 | i = mu_cpystr (buf, addr->domain, len); | 428 | |
307 | if (n) | 429 | i = mu_cpystr (buf, subaddr->domain, len); |
308 | *n = i; | 430 | if (n) |
309 | status = 0; | 431 | *n = i; |
310 | break; | 432 | return 0; |
311 | } | ||
312 | } | ||
313 | return status; | ||
314 | } | 433 | } |
315 | 434 | ||
316 | int | 435 | int |
317 | address_get_route (address_t addr, size_t no, char *buf, size_t len, size_t *n) | 436 | address_get_route (address_t addr, size_t no, char *buf, size_t len, |
437 | size_t * n) | ||
318 | { | 438 | { |
319 | size_t i, j; | 439 | size_t i; |
320 | int status = ENOENT; | 440 | address_t subaddr; |
441 | |||
321 | if (addr == NULL) | 442 | if (addr == NULL) |
322 | return EINVAL; | 443 | return EINVAL; |
323 | for (j = 1; addr; addr = addr->next, j++) | 444 | |
324 | { | 445 | subaddr = _address_get_nth (addr, no); |
325 | if (j == no) | 446 | if (!subaddr) |
326 | { | 447 | return ENOENT; |
327 | i = mu_cpystr (buf, addr->route, len); | 448 | |
328 | if (n) | 449 | i = mu_cpystr (buf, subaddr->route, len); |
329 | *n = i; | 450 | if (n) |
330 | status = 0; | 451 | *n = i; |
331 | break; | 452 | return 0; |
332 | } | ||
333 | } | ||
334 | return status; | ||
335 | } | 453 | } |
336 | 454 | ||
337 | static int | 455 | static int |
... | @@ -359,35 +477,40 @@ _address_is_unix_mailbox (address_t addr) | ... | @@ -359,35 +477,40 @@ _address_is_unix_mailbox (address_t addr) |
359 | } | 477 | } |
360 | 478 | ||
361 | int | 479 | int |
362 | address_is_group (address_t addr, size_t no, int* yes) | 480 | address_is_group (address_t addr, size_t no, int *yes) |
363 | { | 481 | { |
364 | size_t j; | 482 | address_t subaddr; |
365 | int status = ENOENT; | 483 | |
366 | if(addr == NULL) | 484 | if (addr == NULL) |
367 | return EINVAL; | 485 | return EINVAL; |
368 | for (j = 1; addr; addr = addr->next, j++) | 486 | |
369 | { | 487 | subaddr = _address_get_nth (addr, no); |
370 | if (j == no) | 488 | if (!subaddr) |
371 | { | 489 | return ENOENT; |
372 | status = 0; | 490 | |
373 | if(yes) | 491 | if (yes) |
374 | { | 492 | *yes = _address_is_group (subaddr); |
375 | *yes = _address_is_group(addr); | 493 | return 0; |
376 | } | ||
377 | break; | ||
378 | } | ||
379 | } | ||
380 | return status; | ||
381 | } | 494 | } |
382 | 495 | ||
383 | int | 496 | int |
384 | address_to_string (address_t addr, char *buf, size_t len, size_t *n) | 497 | address_to_string (address_t addr, char *buf, size_t len, size_t * n) |
385 | { | 498 | { |
386 | size_t i; | 499 | size_t i; |
387 | if (addr == NULL) | 500 | if (addr == NULL) |
388 | return EINVAL; | 501 | return EINVAL; |
389 | if (buf) | 502 | if (buf) |
390 | *buf = '\0'; | 503 | *buf = '\0'; |
504 | |||
505 | if (!addr->addr) | ||
506 | { | ||
507 | i = address_format_string (addr, NULL, 0); | ||
508 | addr->addr = malloc (i + 1); | ||
509 | if (!addr->addr) | ||
510 | return ENOMEM; | ||
511 | address_format_string (addr, addr->addr, i+1); | ||
512 | } | ||
513 | |||
391 | i = mu_cpystr (buf, addr->addr, len); | 514 | i = mu_cpystr (buf, addr->addr, len); |
392 | if (n) | 515 | if (n) |
393 | *n = i; | 516 | *n = i; |
... | @@ -395,7 +518,7 @@ address_to_string (address_t addr, char *buf, size_t len, size_t *n) | ... | @@ -395,7 +518,7 @@ address_to_string (address_t addr, char *buf, size_t len, size_t *n) |
395 | } | 518 | } |
396 | 519 | ||
397 | int | 520 | int |
398 | address_get_count (address_t addr, size_t *pcount) | 521 | address_get_count (address_t addr, size_t * pcount) |
399 | { | 522 | { |
400 | size_t j; | 523 | size_t j; |
401 | for (j = 0; addr; addr = addr->next, j++) | 524 | for (j = 0; addr; addr = addr->next, j++) |
... | @@ -404,45 +527,118 @@ address_get_count (address_t addr, size_t *pcount) | ... | @@ -404,45 +527,118 @@ address_get_count (address_t addr, size_t *pcount) |
404 | *pcount = j; | 527 | *pcount = j; |
405 | return 0; | 528 | return 0; |
406 | } | 529 | } |
530 | |||
407 | int | 531 | int |
408 | address_get_group_count (address_t addr, size_t *pcount) | 532 | address_get_group_count (address_t addr, size_t * pcount) |
409 | { | 533 | { |
410 | size_t j; | 534 | size_t j; |
411 | for (j = 0; addr; addr = addr->next) | 535 | for (j = 0; addr; addr = addr->next) |
412 | { | 536 | { |
413 | if(_address_is_group(addr)) | 537 | if (_address_is_group (addr)) |
414 | j++; | 538 | j++; |
415 | } | 539 | } |
416 | if (pcount) | 540 | if (pcount) |
417 | *pcount = j; | 541 | *pcount = j; |
418 | return 0; | 542 | return 0; |
419 | } | 543 | } |
420 | 544 | ||
421 | int | 545 | int |
422 | address_get_email_count (address_t addr, size_t *pcount) | 546 | address_get_email_count (address_t addr, size_t * pcount) |
423 | { | 547 | { |
424 | size_t j; | 548 | size_t j; |
425 | for (j = 0; addr; addr = addr->next) | 549 | for (j = 0; addr; addr = addr->next) |
426 | { | 550 | { |
427 | if(_address_is_email(addr)) | 551 | if (_address_is_email (addr)) |
428 | j++; | 552 | j++; |
429 | } | 553 | } |
430 | if (pcount) | 554 | if (pcount) |
431 | *pcount = j; | 555 | *pcount = j; |
432 | return 0; | 556 | return 0; |
433 | } | 557 | } |
434 | 558 | ||
435 | int | 559 | int |
436 | address_get_unix_mailbox_count (address_t addr, size_t *pcount) | 560 | address_get_unix_mailbox_count (address_t addr, size_t * pcount) |
437 | { | 561 | { |
438 | size_t j; | 562 | size_t j; |
439 | for (j = 0; addr; addr = addr->next) | 563 | for (j = 0; addr; addr = addr->next) |
440 | { | 564 | { |
441 | if(_address_is_unix_mailbox(addr)) | 565 | if (_address_is_unix_mailbox (addr)) |
442 | j++; | 566 | j++; |
443 | } | 567 | } |
444 | if (pcount) | 568 | if (pcount) |
445 | *pcount = j; | 569 | *pcount = j; |
446 | return 0; | 570 | return 0; |
447 | } | 571 | } |
448 | 572 | ||
573 | int | ||
574 | address_contains_email (address_t addr, const char *email) | ||
575 | { | ||
576 | for (; addr; addr = addr->next) | ||
577 | if (strcasecmp (addr->email, email) == 0) | ||
578 | return 1; | ||
579 | return 0; | ||
580 | } | ||
581 | |||
582 | address_t | ||
583 | address_dup (address_t src) | ||
584 | { | ||
585 | address_t dst = calloc (1, sizeof (*dst)); | ||
586 | |||
587 | if (!dst) | ||
588 | return NULL; | ||
589 | |||
590 | if (src->comments) | ||
591 | dst->comments = strdup (src->comments); | ||
592 | if (src->personal) | ||
593 | dst->personal = strdup (src->personal); | ||
594 | if (src->email) | ||
595 | dst->email = strdup (src->email); | ||
596 | if (src->local_part) | ||
597 | dst->local_part = strdup (src->local_part); | ||
598 | if (src->domain) | ||
599 | dst->domain = strdup (src->domain); | ||
600 | if (src->route) | ||
601 | dst->route = strdup (src->route); | ||
602 | |||
603 | return dst; | ||
604 | } | ||
605 | |||
606 | int | ||
607 | address_union (address_t *a, address_t b) | ||
608 | { | ||
609 | address_t last = NULL; | ||
610 | |||
611 | if (!a || !b) | ||
612 | return EINVAL; | ||
613 | |||
614 | if (!*a) | ||
615 | { | ||
616 | *a = address_dup (b); | ||
617 | if (!*a) | ||
618 | return ENOMEM; | ||
619 | last = *a; | ||
620 | b = b->next; | ||
621 | } | ||
622 | else | ||
623 | { | ||
624 | if ((*a)->addr) | ||
625 | { | ||
626 | free ((*a)->addr); | ||
627 | (*a)->addr = NULL; | ||
628 | } | ||
629 | for (last = *a; last->next; last = last->next) | ||
630 | ; | ||
631 | } | ||
632 | |||
633 | for (; b; b = b->next) | ||
634 | if (!address_contains_email (*a, b->email)) | ||
635 | { | ||
636 | address_t next = address_dup (b); | ||
637 | if (!next) | ||
638 | return ENOMEM; | ||
639 | last->next = next; | ||
640 | last = next; | ||
641 | } | ||
642 | return 0; | ||
643 | } | ||
644 | ... | ... |
-
Please register or sign in to post a comment