summaryrefslogtreecommitdiffabout
path: root/libetpan/src/low-level/imf/mailimf_types_helper.c
Unidiff
Diffstat (limited to 'libetpan/src/low-level/imf/mailimf_types_helper.c') (more/less context) (ignore whitespace changes)
-rw-r--r--libetpan/src/low-level/imf/mailimf_types_helper.c1636
1 files changed, 1636 insertions, 0 deletions
diff --git a/libetpan/src/low-level/imf/mailimf_types_helper.c b/libetpan/src/low-level/imf/mailimf_types_helper.c
new file mode 100644
index 0000000..a4f669c
--- a/dev/null
+++ b/libetpan/src/low-level/imf/mailimf_types_helper.c
@@ -0,0 +1,1636 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2005 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32#include "mailimf_types_helper.h"
33
34#include <stdlib.h>
35#include <string.h>
36#include <time.h>
37#include <unistd.h>
38
39#include "mailimf.h"
40
41struct mailimf_mailbox_list *
42mailimf_mailbox_list_new_empty()
43{
44 clist * list;
45 struct mailimf_mailbox_list * mb_list;
46
47 list = clist_new();
48 if (list == NULL)
49 return NULL;
50
51 mb_list = mailimf_mailbox_list_new(list);
52 if (mb_list == NULL)
53 return NULL;
54
55 return mb_list;
56}
57
58int mailimf_mailbox_list_add(struct mailimf_mailbox_list * mailbox_list,
59 struct mailimf_mailbox * mb)
60{
61 int r;
62
63 r = clist_append(mailbox_list->mb_list, mb);
64 if (r < 0)
65 return MAILIMF_ERROR_MEMORY;
66
67 return MAILIMF_NO_ERROR;
68}
69
70int mailimf_mailbox_list_add_parse(struct mailimf_mailbox_list * mailbox_list,
71 char * mb_str)
72{
73 int r;
74 size_t cur_token;
75 struct mailimf_mailbox * mb;
76 int res;
77
78 cur_token = 0;
79 r = mailimf_mailbox_parse(mb_str, strlen(mb_str), &cur_token, &mb);
80 if (r != MAILIMF_NO_ERROR) {
81 res = r;
82 goto err;
83 }
84
85 r = mailimf_mailbox_list_add(mailbox_list, mb);
86 if (r != MAILIMF_NO_ERROR) {
87 res = r;
88 goto free;
89 }
90
91 return MAILIMF_NO_ERROR;
92
93 free:
94 mailimf_mailbox_free(mb);
95 err:
96 return res;
97}
98
99int mailimf_mailbox_list_add_mb(struct mailimf_mailbox_list * mailbox_list,
100 char * display_name, char * address)
101{
102 int r;
103 struct mailimf_mailbox * mb;
104 int res;
105
106 mb = mailimf_mailbox_new(display_name, address);
107 if (mb == NULL) {
108 res = MAILIMF_ERROR_MEMORY;
109 goto err;
110 }
111
112 r = mailimf_mailbox_list_add(mailbox_list, mb);
113 if (r != MAILIMF_NO_ERROR) {
114 res = r;
115 goto free;
116 }
117
118 return MAILIMF_NO_ERROR;
119
120 free:
121 mailimf_mailbox_free(mb);
122 err:
123 return res;
124}
125
126
127
128struct mailimf_address_list *
129mailimf_address_list_new_empty()
130{
131 clist * list;
132 struct mailimf_address_list * addr_list;
133
134 list = clist_new();
135 if (list == NULL)
136 return NULL;
137
138 addr_list = mailimf_address_list_new(list);
139 if (addr_list == NULL)
140 return NULL;
141
142 return addr_list;
143}
144
145int mailimf_address_list_add(struct mailimf_address_list * address_list,
146 struct mailimf_address * addr)
147{
148 int r;
149
150 r = clist_append(address_list->ad_list, addr);
151 if (r < 0)
152 return MAILIMF_ERROR_MEMORY;
153
154 return MAILIMF_NO_ERROR;
155}
156
157int mailimf_address_list_add_parse(struct mailimf_address_list * address_list,
158 char * addr_str)
159{
160 int r;
161 size_t cur_token;
162 struct mailimf_address * addr;
163 int res;
164
165 cur_token = 0;
166 r = mailimf_address_parse(addr_str, strlen(addr_str), &cur_token, &addr);
167 if (r != MAILIMF_NO_ERROR) {
168 res = r;
169 goto err;
170 }
171
172 r = mailimf_address_list_add(address_list, addr);
173 if (r != MAILIMF_NO_ERROR) {
174 res = r;
175 goto free;
176 }
177
178 return MAILIMF_NO_ERROR;
179
180 free:
181 mailimf_address_free(addr);
182 err:
183 return res;
184}
185
186int mailimf_address_list_add_mb(struct mailimf_address_list * address_list,
187 char * display_name, char * address)
188{
189 int r;
190 struct mailimf_mailbox * mb;
191 struct mailimf_address * addr;
192 int res;
193
194 mb = mailimf_mailbox_new(display_name, address);
195 if (mb == NULL) {
196 res = MAILIMF_ERROR_MEMORY;
197 goto err;
198 }
199
200 addr = mailimf_address_new(MAILIMF_ADDRESS_MAILBOX, mb, NULL);
201 if (addr == NULL) {
202 res = MAILIMF_ERROR_MEMORY;
203 goto free_mb;
204 }
205
206 r = mailimf_address_list_add(address_list, addr);
207 if (r != MAILIMF_NO_ERROR) {
208 res = r;
209 goto free_addr;
210 }
211
212 return MAILIMF_NO_ERROR;
213
214 free_addr:
215 mailimf_address_free(addr);
216 free_mb:
217 mailimf_mailbox_free(mb);
218 err:
219 return res;
220}
221
222
223#if 0
224struct mailimf_resent_fields_list *
225mailimf_resent_fields_list_new_empty()
226{
227 clist * list;
228 struct mailimf_resent_fields_list * rf_list;
229
230 list = clist_new();
231 if (list == NULL)
232 return NULL;
233
234 rf_list = mailimf_resent_fields_list_new(list);
235 if (rf_list == NULL)
236 return NULL;
237
238 return rf_list;
239}
240
241int mailimf_resent_fields_add(struct mailimf_resent_fields_list * fields,
242 struct mailimf_resent_field * field)
243{
244 int r;
245
246 r = clist_append(fields->list, field);
247 if (r < 0)
248 return MAILIMF_ERROR_MEMORY;
249
250 return MAILIMF_NO_ERROR;
251}
252#endif
253
254
255static void detach_free_common_fields(struct mailimf_orig_date * imf_date,
256 struct mailimf_from * imf_from,
257 struct mailimf_sender * imf_sender,
258 struct mailimf_to * imf_to,
259 struct mailimf_cc * imf_cc,
260 struct mailimf_bcc * imf_bcc,
261 struct mailimf_message_id * imf_msg_id)
262{
263 if (imf_date != NULL) {
264 imf_date->dt_date_time = NULL;
265 mailimf_orig_date_free(imf_date);
266 }
267 if (imf_from != NULL) {
268 imf_from->frm_mb_list = NULL;
269 mailimf_from_free(imf_from);
270 }
271 if (imf_sender != NULL) {
272 imf_sender->snd_mb = NULL;
273 mailimf_sender_free(imf_sender);
274 }
275 if (imf_to != NULL) {
276 imf_to->to_addr_list = NULL;
277 mailimf_to_free(imf_to);
278 }
279 if (imf_cc != NULL) {
280 imf_cc->cc_addr_list = NULL;
281 mailimf_to_free(imf_to);
282 }
283 if (imf_bcc != NULL) {
284 imf_bcc->bcc_addr_list = NULL;
285 mailimf_bcc_free(imf_bcc);
286 }
287 if (imf_msg_id != NULL) {
288 imf_msg_id->mid_value = NULL;
289 mailimf_message_id_free(imf_msg_id);
290 }
291}
292
293static void detach_resent_field(struct mailimf_field * field)
294{
295 field->fld_type = MAILIMF_FIELD_NONE;
296 mailimf_field_free(field);
297}
298
299int
300mailimf_resent_fields_add_data(struct mailimf_fields * fields,
301 struct mailimf_date_time * resent_date,
302 struct mailimf_mailbox_list * resent_from,
303 struct mailimf_mailbox * resent_sender,
304 struct mailimf_address_list * resent_to,
305 struct mailimf_address_list * resent_cc,
306 struct mailimf_address_list * resent_bcc,
307 char * resent_msg_id)
308{
309 struct mailimf_orig_date * imf_resent_date;
310 struct mailimf_from * imf_resent_from;
311 struct mailimf_sender * imf_resent_sender;
312 struct mailimf_to * imf_resent_to;
313 struct mailimf_cc * imf_resent_cc;
314 struct mailimf_bcc * imf_resent_bcc;
315 struct mailimf_message_id * imf_resent_msg_id;
316 struct mailimf_field * field;
317 int r;
318
319 imf_resent_date = NULL;
320 imf_resent_from = NULL;
321 imf_resent_sender = NULL;
322 imf_resent_to = NULL;
323 imf_resent_cc = NULL;
324 imf_resent_bcc = NULL;
325 imf_resent_msg_id = NULL;
326 field = NULL;
327
328 if (resent_date != NULL) {
329 imf_resent_date = mailimf_orig_date_new(resent_date);
330 if (imf_resent_date == NULL)
331 goto free;
332 field = mailimf_field_new(MAILIMF_FIELD_RESENT_DATE,
333 NULL /* return-path */,
334 imf_resent_date /* resent date */,
335 NULL /* resent from */,
336 NULL /* resent sender */,
337 NULL /* resent to */,
338 NULL /* resent cc */,
339 NULL /* resent bcc */,
340 NULL /* resent msg id */,
341 NULL /* date */,
342 NULL /* from */,
343 NULL /* sender */,
344 NULL /* reply-to */,
345 NULL /* to */,
346 NULL /* cc */,
347 NULL /* bcc */,
348 NULL /* message id */,
349 NULL /* in reply to */,
350 NULL /* references */,
351 NULL /* subject */,
352 NULL /* comments */,
353 NULL /* keywords */,
354 NULL /* optional field */);
355 if (field == NULL)
356 goto free;
357 r = mailimf_fields_add(fields, field);
358 if (r != MAILIMF_NO_ERROR)
359 goto free_field;
360 }
361
362 if (resent_from != NULL) {
363 imf_resent_from = mailimf_from_new(resent_from);
364 if (imf_resent_from == NULL)
365 goto free_field;
366 field = mailimf_field_new(MAILIMF_FIELD_RESENT_FROM,
367 NULL /* return-path */,
368 NULL /* resent date */,
369 imf_resent_from /* resent from */,
370 NULL /* resent sender */,
371 NULL /* resent to */,
372 NULL /* resent cc */,
373 NULL /* resent bcc */,
374 NULL /* resent msg id */,
375 NULL /* date */,
376 NULL /* from */,
377 NULL /* sender */,
378 NULL /* reply-to */,
379 NULL /* to */,
380 NULL /* cc */,
381 NULL /* bcc */,
382 NULL /* message id */,
383 NULL /* in reply to */,
384 NULL /* references */,
385 NULL /* subject */,
386 NULL /* comments */,
387 NULL /* keywords */,
388 NULL /* optional field */);
389 if (field == NULL)
390 goto free;
391 r = mailimf_fields_add(fields, field);
392 if (r != MAILIMF_NO_ERROR)
393 goto free_field;
394 }
395
396 if (resent_sender != NULL) {
397 imf_resent_sender = mailimf_sender_new(resent_sender);
398 if (imf_resent_sender == NULL)
399 goto free;
400 field = mailimf_field_new(MAILIMF_FIELD_RESENT_SENDER,
401 NULL /* return-path */,
402 NULL /* resent date */,
403 NULL /* resent from */,
404 imf_resent_sender /* resent sender */,
405 NULL /* resent to */,
406 NULL /* resent cc */,
407 NULL /* resent bcc */,
408 NULL /* resent msg id */,
409 NULL /* date */,
410 NULL /* from */,
411 NULL /* sender */,
412 NULL /* reply-to */,
413 NULL /* to */,
414 NULL /* cc */,
415 NULL /* bcc */,
416 NULL /* message id */,
417 NULL /* in reply to */,
418 NULL /* references */,
419 NULL /* subject */,
420 NULL /* comments */,
421 NULL /* keywords */,
422 NULL /* optional field */);
423 if (field == NULL)
424 goto free;
425 r = mailimf_fields_add(fields, field);
426 if (r != MAILIMF_NO_ERROR)
427 goto free_field;
428 }
429
430 if (resent_to != NULL) {
431 imf_resent_to = mailimf_to_new(resent_to);
432 if (imf_resent_to == NULL)
433 goto free;
434 field = mailimf_field_new(MAILIMF_FIELD_RESENT_TO,
435 NULL /* return-path */,
436 NULL /* resent date */,
437 NULL /* resent from */,
438 NULL /* resent sender */,
439 imf_resent_to /* resent to */,
440 NULL /* resent cc */,
441 NULL /* resent bcc */,
442 NULL /* resent msg id */,
443 NULL /* date */,
444 NULL /* from */,
445 NULL /* sender */,
446 NULL /* reply-to */,
447 NULL /* to */,
448 NULL /* cc */,
449 NULL /* bcc */,
450 NULL /* message id */,
451 NULL /* in reply to */,
452 NULL /* references */,
453 NULL /* subject */,
454 NULL /* comments */,
455 NULL /* keywords */,
456 NULL /* optional field */);
457 if (field == NULL)
458 goto free;
459 r = mailimf_fields_add(fields, field);
460 if (r != MAILIMF_NO_ERROR)
461 goto free_field;
462 }
463
464 if (resent_cc != NULL) {
465 imf_resent_cc = mailimf_cc_new(resent_cc);
466 if (imf_resent_cc == NULL)
467 goto free;
468 field = mailimf_field_new(MAILIMF_FIELD_RESENT_CC,
469 NULL /* return-path */,
470 NULL /* resent date */,
471 NULL /* resent from */,
472 NULL /* resent sender */,
473 NULL /* resent to */,
474 imf_resent_cc /* resent cc */,
475 NULL /* resent bcc */,
476 NULL /* resent msg id */,
477 NULL /* date */,
478 NULL /* from */,
479 NULL /* sender */,
480 NULL /* reply-to */,
481 NULL /* to */,
482 NULL /* cc */,
483 NULL /* bcc */,
484 NULL /* message id */,
485 NULL /* in reply to */,
486 NULL /* references */,
487 NULL /* subject */,
488 NULL /* comments */,
489 NULL /* keywords */,
490 NULL /* optional field */);
491 if (field == NULL)
492 goto free;
493 r = mailimf_fields_add(fields, field);
494 if (r != MAILIMF_NO_ERROR)
495 goto free_field;
496 }
497
498 if (resent_bcc != NULL) {
499 imf_resent_bcc = mailimf_bcc_new(resent_bcc);
500 if (imf_resent_bcc == NULL)
501 goto free;
502 field = mailimf_field_new(MAILIMF_FIELD_RESENT_BCC,
503 NULL /* return-path */,
504 NULL /* resent date */,
505 NULL /* resent from */,
506 NULL /* resent sender */,
507 NULL /* resent to */,
508 NULL /* resent cc */,
509 imf_resent_bcc /* resent bcc */,
510 NULL /* resent msg id */,
511 NULL /* date */,
512 NULL /* from */,
513 NULL /* sender */,
514 NULL /* reply-to */,
515 NULL /* to */,
516 NULL /* cc */,
517 NULL /* bcc */,
518 NULL /* message id */,
519 NULL /* in reply to */,
520 NULL /* references */,
521 NULL /* subject */,
522 NULL /* comments */,
523 NULL /* keywords */,
524 NULL /* optional field */);
525 if (field == NULL)
526 goto free;
527 r = mailimf_fields_add(fields, field);
528 if (r != MAILIMF_NO_ERROR)
529 goto free_field;
530 }
531
532 if (resent_msg_id != NULL) {
533 imf_resent_msg_id = mailimf_message_id_new(resent_msg_id);
534 if (imf_resent_msg_id == NULL)
535 goto free;
536 field = mailimf_field_new(MAILIMF_FIELD_RESENT_MSG_ID,
537 NULL /* return-path */,
538 NULL /* resent date */,
539 NULL /* resent from */,
540 NULL /* resent sender */,
541 NULL /* resent to */,
542 NULL /* resent cc */,
543 NULL /* resent bcc */,
544 imf_resent_msg_id /* resent msg id */,
545 NULL /* date */,
546 NULL /* from */,
547 NULL /* sender */,
548 NULL /* reply-to */,
549 NULL /* to */,
550 NULL /* cc */,
551 NULL /* bcc */,
552 NULL /* message id */,
553 NULL /* in reply to */,
554 NULL /* references */,
555 NULL /* subject */,
556 NULL /* comments */,
557 NULL /* keywords */,
558 NULL /* optional field */);
559 if (field == NULL)
560 goto free;
561 r = mailimf_fields_add(fields, field);
562 if (r != MAILIMF_NO_ERROR)
563 goto free_field;
564 }
565
566 return MAILIMF_NO_ERROR;
567
568 free_field:
569 if (field != NULL) {
570 detach_resent_field(field);
571 mailimf_field_free(field);
572 }
573 free:
574 detach_free_common_fields(imf_resent_date,
575 imf_resent_from,
576 imf_resent_sender,
577 imf_resent_to,
578 imf_resent_cc,
579 imf_resent_bcc,
580 imf_resent_msg_id);
581 return MAILIMF_ERROR_MEMORY;
582}
583
584struct mailimf_fields *
585mailimf_resent_fields_new_with_data_all(struct mailimf_date_time *
586 resent_date,
587 struct mailimf_mailbox_list *
588 resent_from,
589 struct mailimf_mailbox *
590 resent_sender,
591 struct mailimf_address_list *
592 resent_to,
593 struct mailimf_address_list *
594 resent_cc,
595 struct mailimf_address_list *
596 resent_bcc,
597 char * resent_msg_id)
598{
599 struct mailimf_fields * resent_fields;
600 int r;
601
602 resent_fields = mailimf_fields_new_empty();
603 if (resent_fields == NULL)
604 goto err;
605
606 r = mailimf_resent_fields_add_data(resent_fields,
607 resent_date, resent_from,
608 resent_sender, resent_to,
609 resent_cc, resent_bcc,
610 resent_msg_id);
611 if (r != MAILIMF_NO_ERROR)
612 goto free;
613
614 return resent_fields;
615
616 free:
617 mailimf_fields_free(resent_fields);
618 err:
619 return NULL;
620}
621
622
623struct mailimf_fields *
624mailimf_resent_fields_new_with_data(struct mailimf_mailbox_list * from,
625 struct mailimf_mailbox * sender,
626 struct mailimf_address_list * to,
627 struct mailimf_address_list * cc,
628 struct mailimf_address_list * bcc)
629{
630 struct mailimf_date_time * date;
631 char * msg_id;
632 struct mailimf_fields * fields;
633
634 date = mailimf_get_current_date();
635 if (date == NULL)
636 goto err;
637
638 msg_id = mailimf_get_message_id();
639 if (msg_id == NULL)
640 goto free_date;
641
642 fields = mailimf_resent_fields_new_with_data_all(date,
643 from, sender, to, cc, bcc, msg_id);
644 if (fields == NULL)
645 goto free_msg_id;
646
647 return fields;
648
649 free_msg_id:
650 free(msg_id);
651 free_date:
652 mailimf_date_time_free(date);
653 err:
654 return NULL;
655}
656
657
658struct mailimf_fields *
659mailimf_fields_new_empty(void)
660{
661 clist * list;
662 struct mailimf_fields * fields_list;
663
664 list = clist_new();
665 if (list == NULL)
666 return NULL;
667
668 fields_list = mailimf_fields_new(list);
669 if (fields_list == NULL)
670 return NULL;
671
672 return fields_list;
673}
674
675int mailimf_fields_add(struct mailimf_fields * fields,
676 struct mailimf_field * field)
677{
678 int r;
679
680 r = clist_append(fields->fld_list, field);
681 if (r < 0)
682 return MAILIMF_ERROR_MEMORY;
683
684 return MAILIMF_NO_ERROR;
685}
686
687static void detach_free_fields(struct mailimf_orig_date * date,
688 struct mailimf_from * from,
689 struct mailimf_sender * sender,
690 struct mailimf_reply_to * reply_to,
691 struct mailimf_to * to,
692 struct mailimf_cc * cc,
693 struct mailimf_bcc * bcc,
694 struct mailimf_message_id * msg_id,
695 struct mailimf_in_reply_to * in_reply_to,
696 struct mailimf_references * references,
697 struct mailimf_subject * subject)
698{
699 detach_free_common_fields(date,
700 from,
701 sender,
702 to,
703 cc,
704 bcc,
705 msg_id);
706
707 if (reply_to != NULL) {
708 reply_to->rt_addr_list = NULL;
709 mailimf_reply_to_free(reply_to);
710 }
711
712 if (in_reply_to != NULL) {
713 in_reply_to->mid_list = NULL;
714 mailimf_in_reply_to_free(in_reply_to);
715 }
716
717 if (references != NULL) {
718 references->mid_list = NULL;
719 mailimf_references_free(references);
720 }
721
722 if (subject != NULL) {
723 subject->sbj_value = NULL;
724 mailimf_subject_free(subject);
725 }
726}
727
728
729static void detach_field(struct mailimf_field * field)
730{
731 field->fld_type = MAILIMF_FIELD_NONE;
732 mailimf_field_free(field);
733}
734
735int mailimf_fields_add_data(struct mailimf_fields * fields,
736 struct mailimf_date_time * date,
737 struct mailimf_mailbox_list * from,
738 struct mailimf_mailbox * sender,
739 struct mailimf_address_list * reply_to,
740 struct mailimf_address_list * to,
741 struct mailimf_address_list * cc,
742 struct mailimf_address_list * bcc,
743 char * msg_id,
744 clist * in_reply_to,
745 clist * references,
746 char * subject)
747{
748 struct mailimf_orig_date * imf_date;
749 struct mailimf_from * imf_from;
750 struct mailimf_sender * imf_sender;
751 struct mailimf_reply_to * imf_reply_to;
752 struct mailimf_to * imf_to;
753 struct mailimf_cc * imf_cc;
754 struct mailimf_bcc * imf_bcc;
755 struct mailimf_message_id * imf_msg_id;
756 struct mailimf_references * imf_references;
757 struct mailimf_in_reply_to * imf_in_reply_to;
758 struct mailimf_subject * imf_subject;
759 struct mailimf_field * field;
760 int r;
761
762 imf_date = NULL;
763 imf_from = NULL;
764 imf_sender = NULL;
765 imf_reply_to = NULL;
766 imf_to = NULL;
767 imf_cc = NULL;
768 imf_bcc = NULL;
769 imf_msg_id = NULL;
770 imf_references = NULL;
771 imf_in_reply_to = NULL;
772 imf_subject =NULL;
773 field = NULL;
774
775 if (date != NULL) {
776 imf_date = mailimf_orig_date_new(date);
777 if (imf_date == NULL)
778 goto free;
779 field = mailimf_field_new(MAILIMF_FIELD_ORIG_DATE,
780 NULL /* return-path */,
781 NULL /* resent date */,
782 NULL /* resent from */,
783 NULL /* resent sender */,
784 NULL /* resent to */,
785 NULL /* resent cc */,
786 NULL /* resent bcc */,
787 NULL /* resent msg id */,
788 imf_date /* date */,
789 NULL /* from */,
790 NULL /* sender */,
791 NULL /* reply-to */,
792 NULL /* to */,
793 NULL /* cc */,
794 NULL /* bcc */,
795 NULL /* message id */,
796 NULL /* in reply to */,
797 NULL /* references */,
798 NULL /* subject */,
799 NULL /* comments */,
800 NULL /* keywords */,
801 NULL /* optional field */);
802 if (field == NULL)
803 goto free;
804 r = mailimf_fields_add(fields, field);
805 if (r != MAILIMF_NO_ERROR)
806 goto free_field;
807 }
808
809 if (from != NULL) {
810 imf_from = mailimf_from_new(from);
811 if (imf_from == NULL)
812 goto free_field;
813 field = mailimf_field_new(MAILIMF_FIELD_FROM,
814 NULL /* return-path */,
815 NULL /* resent date */,
816 NULL /* resent from */,
817 NULL /* resent sender */,
818 NULL /* resent to */,
819 NULL /* resent cc */,
820 NULL /* resent bcc */,
821 NULL /* resent msg id */,
822 NULL /* date */,
823 imf_from /* from */,
824 NULL /* sender */,
825 NULL /* reply-to */,
826 NULL /* to */,
827 NULL /* cc */,
828 NULL /* bcc */,
829 NULL /* message id */,
830 NULL /* in reply to */,
831 NULL /* references */,
832 NULL /* subject */,
833 NULL /* comments */,
834 NULL /* keywords */,
835 NULL /* optional field */);
836 if (field == NULL)
837 goto free;
838 r = mailimf_fields_add(fields, field);
839 if (r != MAILIMF_NO_ERROR)
840 goto free_field;
841 }
842
843 if (sender != NULL) {
844 imf_sender = mailimf_sender_new(sender);
845 if (imf_sender == NULL)
846 goto free;
847 field = mailimf_field_new(MAILIMF_FIELD_SENDER,
848 NULL /* return-path */,
849 NULL /* resent date */,
850 NULL /* resent from */,
851 NULL /* resent sender */,
852 NULL /* resent to */,
853 NULL /* resent cc */,
854 NULL /* resent bcc */,
855 NULL /* resent msg id */,
856 NULL /* date */,
857 NULL /* from */,
858 imf_sender /* sender */,
859 NULL /* reply-to */,
860 NULL /* to */,
861 NULL /* cc */,
862 NULL /* bcc */,
863 NULL /* message id */,
864 NULL /* in reply to */,
865 NULL /* references */,
866 NULL /* subject */,
867 NULL /* comments */,
868 NULL /* keywords */,
869 NULL /* optional field */);
870 if (field == NULL)
871 goto free;
872 r = mailimf_fields_add(fields, field);
873 if (r != MAILIMF_NO_ERROR)
874 goto free_field;
875 }
876
877 if (reply_to != NULL) {
878 imf_reply_to = mailimf_reply_to_new(reply_to);
879 if (imf_reply_to == NULL)
880 goto free;
881 field = mailimf_field_new(MAILIMF_FIELD_REPLY_TO,
882 NULL /* return-path */,
883 NULL /* resent date */,
884 NULL /* resent from */,
885 NULL /* resent sender */,
886 NULL /* resent to */,
887 NULL /* resent cc */,
888 NULL /* resent bcc */,
889 NULL /* resent msg id */,
890 NULL /* date */,
891 NULL /* from */,
892 NULL /* sender */,
893 imf_reply_to /* reply-to */,
894 NULL /* to */,
895 NULL /* cc */,
896 NULL /* bcc */,
897 NULL /* message id */,
898 NULL /* in reply to */,
899 NULL /* references */,
900 NULL /* subject */,
901 NULL /* comments */,
902 NULL /* keywords */,
903 NULL /* optional field */);
904 if (field == NULL)
905 goto free;
906 r = mailimf_fields_add(fields, field);
907 if (r != MAILIMF_NO_ERROR)
908 goto free_field;
909 }
910
911 if (to != NULL) {
912 imf_to = mailimf_to_new(to);
913 if (imf_to == NULL)
914 goto free;
915 field = mailimf_field_new(MAILIMF_FIELD_TO,
916 NULL /* return-path */,
917 NULL /* resent date */,
918 NULL /* resent from */,
919 NULL /* resent sender */,
920 NULL /* resent to */,
921 NULL /* resent cc */,
922 NULL /* resent bcc */,
923 NULL /* resent msg id */,
924 NULL /* date */,
925 NULL /* from */,
926 NULL /* sender */,
927 NULL /* reply-to */,
928 imf_to /* to */,
929 NULL /* cc */,
930 NULL /* bcc */,
931 NULL /* message id */,
932 NULL /* in reply to */,
933 NULL /* references */,
934 NULL /* subject */,
935 NULL /* comments */,
936 NULL /* keywords */,
937 NULL /* optional field */);
938 if (field == NULL)
939 goto free;
940 r = mailimf_fields_add(fields, field);
941 if (r != MAILIMF_NO_ERROR)
942 goto free_field;
943 }
944
945 if (cc != NULL) {
946 imf_cc = mailimf_cc_new(cc);
947 if (imf_cc == NULL)
948 goto free;
949 field = mailimf_field_new(MAILIMF_FIELD_CC,
950 NULL /* return-path */,
951 NULL /* resent date */,
952 NULL /* resent from */,
953 NULL /* resent sender */,
954 NULL /* resent to */,
955 NULL /* resent cc */,
956 NULL /* resent bcc */,
957 NULL /* resent msg id */,
958 NULL /* date */,
959 NULL /* from */,
960 NULL /* sender */,
961 NULL /* reply-to */,
962 NULL /* to */,
963 imf_cc /* cc */,
964 NULL /* bcc */,
965 NULL /* message id */,
966 NULL /* in reply to */,
967 NULL /* references */,
968 NULL /* subject */,
969 NULL /* comments */,
970 NULL /* keywords */,
971 NULL /* optional field */);
972 if (field == NULL)
973 goto free;
974 r = mailimf_fields_add(fields, field);
975 if (r != MAILIMF_NO_ERROR)
976 goto free_field;
977 }
978
979 if (bcc != NULL) {
980 imf_bcc = mailimf_bcc_new(bcc);
981 if (imf_bcc == NULL)
982 goto free;
983 field = mailimf_field_new(MAILIMF_FIELD_BCC,
984 NULL /* return-path */,
985 NULL /* resent date */,
986 NULL /* resent from */,
987 NULL /* resent sender */,
988 NULL /* resent to */,
989 NULL /* resent cc */,
990 NULL /* resent bcc */,
991 NULL /* resent msg id */,
992 NULL /* date */,
993 NULL /* from */,
994 NULL /* sender */,
995 NULL /* reply-to */,
996 NULL /* to */,
997 NULL /* cc */,
998 imf_bcc /* bcc */,
999 NULL /* message id */,
1000 NULL /* in reply to */,
1001 NULL /* references */,
1002 NULL /* subject */,
1003 NULL /* comments */,
1004 NULL /* keywords */,
1005 NULL /* optional field */);
1006 if (field == NULL)
1007 goto free;
1008 r = mailimf_fields_add(fields, field);
1009 if (r != MAILIMF_NO_ERROR)
1010 goto free_field;
1011 }
1012
1013 if (msg_id != NULL) {
1014 imf_msg_id = mailimf_message_id_new(msg_id);
1015 if (imf_msg_id == NULL)
1016 goto free;
1017 field = mailimf_field_new(MAILIMF_FIELD_MESSAGE_ID,
1018 NULL /* return-path */,
1019 NULL /* resent date */,
1020 NULL /* resent from */,
1021 NULL /* resent sender */,
1022 NULL /* resent to */,
1023 NULL /* resent cc */,
1024 NULL /* resent bcc */,
1025 NULL /* resent msg id */,
1026 NULL /* date */,
1027 NULL /* from */,
1028 NULL /* sender */,
1029 NULL /* reply-to */,
1030 NULL /* to */,
1031 NULL /* cc */,
1032 NULL /* bcc */,
1033 imf_msg_id /* message id */,
1034 NULL /* in reply to */,
1035 NULL /* references */,
1036 NULL /* subject */,
1037 NULL /* comments */,
1038 NULL /* keywords */,
1039 NULL /* optional field */);
1040 if (field == NULL)
1041 goto free;
1042 r = mailimf_fields_add(fields, field);
1043 if (r != MAILIMF_NO_ERROR)
1044 goto free_field;
1045 }
1046
1047 if (in_reply_to != NULL) {
1048 imf_in_reply_to = mailimf_in_reply_to_new(in_reply_to);
1049 if (imf_in_reply_to == NULL)
1050 goto free;
1051 field = mailimf_field_new(MAILIMF_FIELD_IN_REPLY_TO,
1052 NULL /* return-path */,
1053 NULL /* resent date */,
1054 NULL /* resent from */,
1055 NULL /* resent sender */,
1056 NULL /* resent to */,
1057 NULL /* resent cc */,
1058 NULL /* resent bcc */,
1059 NULL /* resent msg id */,
1060 NULL /* date */,
1061 NULL /* from */,
1062 NULL /* sender */,
1063 NULL /* reply-to */,
1064 NULL /* to */,
1065 NULL /* cc */,
1066 NULL /* bcc */,
1067 NULL /* message id */,
1068 imf_in_reply_to /* in reply to */,
1069 NULL /* references */,
1070 NULL /* subject */,
1071 NULL /* comments */,
1072 NULL /* keywords */,
1073 NULL /* optional field */);
1074 if (field == NULL)
1075 goto free;
1076 r = mailimf_fields_add(fields, field);
1077 if (r != MAILIMF_NO_ERROR)
1078 goto free_field;
1079 }
1080
1081 if (references != NULL) {
1082 imf_references = mailimf_references_new(references);
1083 if (imf_references == NULL)
1084 goto free;
1085 field = mailimf_field_new(MAILIMF_FIELD_REFERENCES,
1086 NULL /* return-path */,
1087 NULL /* resent date */,
1088 NULL /* resent from */,
1089 NULL /* resent sender */,
1090 NULL /* resent to */,
1091 NULL /* resent cc */,
1092 NULL /* resent bcc */,
1093 NULL /* resent msg id */,
1094 NULL /* date */,
1095 NULL /* from */,
1096 NULL /* sender */,
1097 NULL /* reply-to */,
1098 NULL /* to */,
1099 NULL /* cc */,
1100 NULL /* bcc */,
1101 NULL /* message id */,
1102 NULL /* in reply to */,
1103 imf_references /* references */,
1104 NULL /* subject */,
1105 NULL /* comments */,
1106 NULL /* keywords */,
1107 NULL /* optional field */);
1108 if (field == NULL)
1109 goto free;
1110 r = mailimf_fields_add(fields, field);
1111 if (r != MAILIMF_NO_ERROR)
1112 goto free_field;
1113 }
1114
1115 if (subject != NULL) {
1116 imf_subject = mailimf_subject_new(subject);
1117 if (imf_subject == NULL)
1118 goto free;
1119 field = mailimf_field_new(MAILIMF_FIELD_SUBJECT,
1120 NULL /* return-path */,
1121 NULL /* resent date */,
1122 NULL /* resent from */,
1123 NULL /* resent sender */,
1124 NULL /* resent to */,
1125 NULL /* resent cc */,
1126 NULL /* resent bcc */,
1127 NULL /* resent msg id */,
1128 NULL /* date */,
1129 NULL /* from */,
1130 NULL /* sender */,
1131 NULL /* reply-to */,
1132 NULL /* to */,
1133 NULL /* cc */,
1134 NULL /* bcc */,
1135 NULL /* message id */,
1136 NULL /* in reply to */,
1137 NULL /* references */,
1138 imf_subject /* subject */,
1139 NULL /* comments */,
1140 NULL /* keywords */,
1141 NULL /* optional field */);
1142 if (field == NULL)
1143 goto free;
1144 r = mailimf_fields_add(fields, field);
1145 if (r != MAILIMF_NO_ERROR)
1146 goto free_field;
1147 }
1148
1149 return MAILIMF_NO_ERROR;
1150
1151 free_field:
1152 if (field != NULL) {
1153 detach_field(field);
1154 mailimf_field_free(field);
1155 }
1156 free:
1157 detach_free_fields(imf_date,
1158 imf_from,
1159 imf_sender,
1160 imf_reply_to,
1161 imf_to,
1162 imf_cc,
1163 imf_bcc,
1164 imf_msg_id,
1165 imf_in_reply_to,
1166 imf_references,
1167 imf_subject);
1168
1169 return MAILIMF_ERROR_MEMORY;
1170}
1171
1172struct mailimf_fields *
1173mailimf_fields_new_with_data_all(struct mailimf_date_time * date,
1174 struct mailimf_mailbox_list * from,
1175 struct mailimf_mailbox * sender,
1176 struct mailimf_address_list * reply_to,
1177 struct mailimf_address_list * to,
1178 struct mailimf_address_list * cc,
1179 struct mailimf_address_list * bcc,
1180 char * message_id,
1181 clist * in_reply_to,
1182 clist * references,
1183 char * subject)
1184{
1185 struct mailimf_fields * fields;
1186 int r;
1187
1188 fields = mailimf_fields_new_empty();
1189 if (fields == NULL)
1190 goto err;
1191
1192 r = mailimf_fields_add_data(fields,
1193 date,
1194 from,
1195 sender,
1196 reply_to,
1197 to,
1198 cc,
1199 bcc,
1200 message_id,
1201 in_reply_to,
1202 references,
1203 subject);
1204 if (r != MAILIMF_NO_ERROR)
1205 goto free;
1206
1207 return fields;
1208
1209 free:
1210 mailimf_fields_free(fields);
1211 err:
1212 return NULL;
1213}
1214
1215struct mailimf_fields *
1216mailimf_fields_new_with_data(struct mailimf_mailbox_list * from,
1217 struct mailimf_mailbox * sender,
1218 struct mailimf_address_list * reply_to,
1219 struct mailimf_address_list * to,
1220 struct mailimf_address_list * cc,
1221 struct mailimf_address_list * bcc,
1222 clist * in_reply_to,
1223 clist * references,
1224 char * subject)
1225{
1226 struct mailimf_date_time * date;
1227 char * msg_id;
1228 struct mailimf_fields * fields;
1229
1230 date = mailimf_get_current_date();
1231 if (date == NULL)
1232 goto err;
1233
1234 msg_id = mailimf_get_message_id();
1235 if (msg_id == NULL)
1236 goto free_date;
1237
1238 fields = mailimf_fields_new_with_data_all(date,
1239 from, sender, reply_to,
1240 to, cc, bcc,
1241 msg_id,
1242 in_reply_to, references,
1243 subject);
1244 if (fields == NULL)
1245 goto free_msg_id;
1246
1247 return fields;
1248
1249 free_msg_id:
1250 free(msg_id);
1251 free_date:
1252 mailimf_date_time_free(date);
1253 err:
1254 return NULL;
1255}
1256
1257
1258
1259#define MAX_MESSAGE_ID 512
1260
1261char * mailimf_get_message_id(void)
1262{
1263 char id[MAX_MESSAGE_ID];
1264 time_t now;
1265 char name[MAX_MESSAGE_ID];
1266 long value;
1267
1268 now = time(NULL);
1269 value = random();
1270
1271 gethostname(name, MAX_MESSAGE_ID);
1272 snprintf(id, MAX_MESSAGE_ID, "etPan.%lx.%lx.%x@%s",
1273 now, value, getpid(), name);
1274
1275 return strdup(id);
1276}
1277
1278
1279
1280static time_t mkgmtime(struct tm * tmp);
1281
1282
1283struct mailimf_date_time * mailimf_get_current_date(void)
1284{
1285 struct tm gmt;
1286 struct tm lt;
1287 int off;
1288 time_t now;
1289 struct mailimf_date_time * date_time;
1290
1291 now = time(NULL);
1292
1293 if (gmtime_r(&now, &gmt) == NULL)
1294 return NULL;
1295
1296 if (localtime_r(&now, &lt) == NULL)
1297 return NULL;
1298
1299 off = (mkgmtime(&lt) - mkgmtime(&gmt)) / (60 * 60) * 100;
1300
1301 date_time = mailimf_date_time_new(lt.tm_mday, lt.tm_mon + 1, lt.tm_year + 1900,
1302 lt.tm_hour, lt.tm_min, lt.tm_sec,
1303 off);
1304
1305 return date_time;
1306}
1307
1308
1309
1310/* mkgmtime.c - make time corresponding to a GMT timeval struct
1311 $Id$
1312
1313 * Copyright (c) 1998-2000 Carnegie Mellon University. All rights reserved.
1314 *
1315 * Redistribution and use in source and binary forms, with or without
1316 * modification, are permitted provided that the following conditions
1317 * are met:
1318 *
1319 * 1. Redistributions of source code must retain the above copyright
1320 * notice, this list of conditions and the following disclaimer.
1321 *
1322 * 2. Redistributions in binary form must reproduce the above copyright
1323 * notice, this list of conditions and the following disclaimer in
1324 * the documentation and/or other materials provided with the
1325 * distribution.
1326 *
1327 * 3. The name "Carnegie Mellon University" must not be used to
1328 * endorse or promote products derived from this software without
1329 * prior written permission. For permission or any other legal
1330 * details, please contact
1331 * Office of Technology Transfer
1332 * Carnegie Mellon University
1333 * 5000 Forbes Avenue
1334 * Pittsburgh, PA 15213-3890
1335 * (412) 268-4387, fax: (412) 268-7395
1336 * tech-transfer@andrew.cmu.edu
1337 *
1338 * 4. Redistributions of any form whatsoever must retain the following
1339 * acknowledgment:
1340 * "This product includes software developed by Computing Services
1341 * at Carnegie Mellon University (http://www.cmu.edu/computing/)."
1342 *
1343 * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
1344 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
1345 * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
1346 * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1347 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
1348 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
1349 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1350 *
1351 *
1352 */
1353/*
1354 * Copyright (c) 1987, 1989, 1993
1355 *The Regents of the University of California. All rights reserved.
1356 *
1357 * This code is derived from software contributed to Berkeley by
1358 * Arthur David Olson of the National Cancer Institute.
1359 *
1360 * Redistribution and use in source and binary forms, with or without
1361 * modification, are permitted provided that the following conditions
1362 * are met:
1363 * 1. Redistributions of source code must retain the above copyright
1364 * notice, this list of conditions and the following disclaimer.
1365 * 2. Redistributions in binary form must reproduce the above copyright
1366 * notice, this list of conditions and the following disclaimer in the
1367 * documentation and/or other materials provided with the distribution.
1368 * 3. All advertising materials mentioning features or use of this software
1369 * must display the following acknowledgement:
1370 *This product includes software developed by the University of
1371 *California, Berkeley and its contributors.
1372 * 4. Neither the name of the University nor the names of its contributors
1373 * may be used to endorse or promote products derived from this software
1374 * without specific prior written permission.
1375 *
1376 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
1377 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1378 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1379 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
1380 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1381 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1382 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1383 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1384 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1385 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1386 * SUCH DAMAGE.
1387 */
1388
1389/*
1390** Adapted from code provided by Robert Elz, who writes:
1391 **The "best" way to do mktime I think is based on an idea of Bob
1392 **Kridle's (so its said...) from a long time ago. (mtxinu!kridle now).
1393 **It does a binary search of the time_t space. Since time_t's are
1394 **just 32 bits, its a max of 32 iterations (even at 64 bits it
1395 **would still be very reasonable).
1396*/
1397
1398/*
1399 adapted for libEtPan! by DINH V. Hoa
1400*/
1401
1402#ifndef WRONG
1403 #define WRONG(-1)
1404#endif /* !defined WRONG */
1405
1406static int tmcomp(struct tm * atmp, struct tm * btmp)
1407{
1408 register intresult;
1409
1410 if ((result = (atmp->tm_year - btmp->tm_year)) == 0 &&
1411 (result = (atmp->tm_mon - btmp->tm_mon)) == 0 &&
1412 (result = (atmp->tm_mday - btmp->tm_mday)) == 0 &&
1413 (result = (atmp->tm_hour - btmp->tm_hour)) == 0 &&
1414 (result = (atmp->tm_min - btmp->tm_min)) == 0)
1415 result = atmp->tm_sec - btmp->tm_sec;
1416 return result;
1417}
1418
1419static time_t mkgmtime(struct tm * tmp)
1420{
1421 register int dir;
1422 register int bits;
1423 register int saved_seconds;
1424 time_t t;
1425 struct tm yourtm, *mytm;
1426
1427 yourtm = *tmp;
1428 saved_seconds = yourtm.tm_sec;
1429 yourtm.tm_sec = 0;
1430 /*
1431 ** Calculate the number of magnitude bits in a time_t
1432 ** (this works regardless of whether time_t is
1433 ** signed or unsigned, though lint complains if unsigned).
1434 */
1435 for (bits = 0, t = 1; t > 0; ++bits, t <<= 1)
1436 ;
1437 /*
1438 ** If time_t is signed, then 0 is the median value,
1439 ** if time_t is unsigned, then 1 << bits is median.
1440 */
1441 t = (t < 0) ? 0 : ((time_t) 1 << bits);
1442 for ( ; ; ) {
1443 mytm = gmtime(&t);
1444 dir = tmcomp(mytm, &yourtm);
1445 if (dir != 0) {
1446 if (bits-- < 0)
1447 return WRONG;
1448 if (bits < 0)
1449 --t;
1450 else if (dir > 0)
1451 t -= (time_t) 1 << bits;
1452 elset += (time_t) 1 << bits;
1453 continue;
1454 }
1455 break;
1456 }
1457 t += saved_seconds;
1458 return t;
1459}
1460
1461
1462
1463
1464
1465
1466
1467void mailimf_single_fields_init(struct mailimf_single_fields * single_fields,
1468 struct mailimf_fields * fields)
1469{
1470 clistiter * cur;
1471
1472 memset(single_fields, 0, sizeof(struct mailimf_single_fields));
1473
1474 cur = clist_begin(fields->fld_list);
1475 while (cur != NULL) {
1476 struct mailimf_field * field;
1477
1478 field = clist_content(cur);
1479
1480 switch (field->fld_type) {
1481 case MAILIMF_FIELD_ORIG_DATE:
1482 if (single_fields->fld_orig_date == NULL)
1483 single_fields->fld_orig_date = field->fld_data.fld_orig_date;
1484 cur = clist_next(cur);
1485 break;
1486 case MAILIMF_FIELD_FROM:
1487 if (single_fields->fld_from == NULL) {
1488 single_fields->fld_from = field->fld_data.fld_from;
1489 cur = clist_next(cur);
1490 }
1491 else {
1492 clist_concat(single_fields->fld_from->frm_mb_list->mb_list,
1493 field->fld_data.fld_from->frm_mb_list->mb_list);
1494 mailimf_field_free(field);
1495 cur = clist_delete(fields->fld_list, cur);
1496 }
1497 break;
1498 case MAILIMF_FIELD_SENDER:
1499 if (single_fields->fld_sender == NULL)
1500 single_fields->fld_sender = field->fld_data.fld_sender;
1501 cur = clist_next(cur);
1502 break;
1503 case MAILIMF_FIELD_REPLY_TO:
1504 if (single_fields->fld_reply_to == NULL) {
1505 single_fields->fld_reply_to = field->fld_data.fld_reply_to;
1506 cur = clist_next(cur);
1507 }
1508 else {
1509 clist_concat(single_fields->fld_reply_to->rt_addr_list->ad_list,
1510 field->fld_data.fld_reply_to->rt_addr_list->ad_list);
1511 mailimf_field_free(field);
1512 cur = clist_delete(fields->fld_list, cur);
1513 }
1514 break;
1515 case MAILIMF_FIELD_TO:
1516 if (single_fields->fld_to == NULL) {
1517 single_fields->fld_to = field->fld_data.fld_to;
1518 cur = clist_next(cur);
1519 }
1520 else {
1521 clist_concat(single_fields->fld_to->to_addr_list->ad_list,
1522 field->fld_data.fld_to->to_addr_list->ad_list);
1523 mailimf_field_free(field);
1524 cur = clist_delete(fields->fld_list, cur);
1525 }
1526 break;
1527 case MAILIMF_FIELD_CC:
1528 if (single_fields->fld_cc == NULL) {
1529 single_fields->fld_cc = field->fld_data.fld_cc;
1530 cur = clist_next(cur);
1531 }
1532 else {
1533 clist_concat(single_fields->fld_cc->cc_addr_list->ad_list,
1534 field->fld_data.fld_cc->cc_addr_list->ad_list);
1535 mailimf_field_free(field);
1536 cur = clist_delete(fields->fld_list, cur);
1537 }
1538 break;
1539 case MAILIMF_FIELD_BCC:
1540 if (single_fields->fld_bcc == NULL) {
1541 single_fields->fld_bcc = field->fld_data.fld_bcc;
1542 cur = clist_next(cur);
1543 }
1544 else {
1545 clist_concat(single_fields->fld_bcc->bcc_addr_list->ad_list,
1546 field->fld_data.fld_bcc->bcc_addr_list->ad_list);
1547 mailimf_field_free(field);
1548 cur = clist_delete(fields->fld_list, cur);
1549 }
1550 break;
1551 case MAILIMF_FIELD_MESSAGE_ID:
1552 if (single_fields->fld_message_id == NULL)
1553 single_fields->fld_message_id = field->fld_data.fld_message_id;
1554 cur = clist_next(cur);
1555 break;
1556 case MAILIMF_FIELD_IN_REPLY_TO:
1557 if (single_fields->fld_in_reply_to == NULL)
1558 single_fields->fld_in_reply_to = field->fld_data.fld_in_reply_to;
1559 cur = clist_next(cur);
1560 break;
1561 case MAILIMF_FIELD_REFERENCES:
1562 if (single_fields->fld_references == NULL)
1563 single_fields->fld_references = field->fld_data.fld_references;
1564 cur = clist_next(cur);
1565 break;
1566 case MAILIMF_FIELD_SUBJECT:
1567 if (single_fields->fld_subject == NULL)
1568 single_fields->fld_subject = field->fld_data.fld_subject;
1569 cur = clist_next(cur);
1570 break;
1571 case MAILIMF_FIELD_COMMENTS:
1572 if (single_fields->fld_comments == NULL)
1573 single_fields->fld_comments = field->fld_data.fld_comments;
1574 cur = clist_next(cur);
1575 break;
1576 case MAILIMF_FIELD_KEYWORDS:
1577 if (single_fields->fld_keywords == NULL)
1578 single_fields->fld_keywords = field->fld_data.fld_keywords;
1579 cur = clist_next(cur);
1580 break;
1581 default:
1582 cur = clist_next(cur);
1583 break;
1584 }
1585 }
1586}
1587
1588
1589struct mailimf_single_fields *
1590mailimf_single_fields_new(struct mailimf_fields * fields)
1591{
1592 struct mailimf_single_fields * single_fields;
1593
1594 single_fields = malloc(sizeof(struct mailimf_single_fields));
1595 if (single_fields == NULL)
1596 goto err;
1597
1598 mailimf_single_fields_init(single_fields, fields);
1599
1600 return single_fields;
1601
1602 err:
1603 return NULL;
1604}
1605
1606void mailimf_single_fields_free(struct mailimf_single_fields *
1607 single_fields)
1608{
1609 free(single_fields);
1610}
1611
1612struct mailimf_field * mailimf_field_new_custom(char * name, char * value)
1613{
1614 struct mailimf_optional_field * opt_field;
1615 struct mailimf_field * field;
1616
1617 opt_field = mailimf_optional_field_new(name, value);
1618 if (opt_field == NULL)
1619 goto err;
1620
1621 field = mailimf_field_new(MAILIMF_FIELD_OPTIONAL_FIELD,
1622 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
1623 NULL, NULL, NULL, NULL,
1624 NULL, NULL, NULL, NULL,
1625 NULL, NULL, NULL, NULL,
1626 NULL, NULL, opt_field);
1627 if (field == NULL)
1628 goto free_opt_field;
1629
1630 return field;
1631
1632 free_opt_field:
1633 mailimf_optional_field_free(opt_field);
1634 err:
1635 return NULL;
1636}