2 * libEtPan! -- a mail stuff library
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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.
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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
34 #include "mailimf_types_helper.h"
45 struct mailimf_mailbox_list *
46 mailimf_mailbox_list_new_empty()
49 struct mailimf_mailbox_list * mb_list;
55 mb_list = mailimf_mailbox_list_new(list);
62 int mailimf_mailbox_list_add(struct mailimf_mailbox_list * mailbox_list,
63 struct mailimf_mailbox * mb)
67 r = clist_append(mailbox_list->mb_list, mb);
69 return MAILIMF_ERROR_MEMORY;
71 return MAILIMF_NO_ERROR;
74 int mailimf_mailbox_list_add_parse(struct mailimf_mailbox_list * mailbox_list,
79 struct mailimf_mailbox * mb;
83 r = mailimf_mailbox_parse(mb_str, strlen(mb_str), &cur_token, &mb);
84 if (r != MAILIMF_NO_ERROR) {
89 r = mailimf_mailbox_list_add(mailbox_list, mb);
90 if (r != MAILIMF_NO_ERROR) {
95 return MAILIMF_NO_ERROR;
98 mailimf_mailbox_free(mb);
103 int mailimf_mailbox_list_add_mb(struct mailimf_mailbox_list * mailbox_list,
104 char * display_name, char * address)
107 struct mailimf_mailbox * mb;
110 mb = mailimf_mailbox_new(display_name, address);
112 res = MAILIMF_ERROR_MEMORY;
116 r = mailimf_mailbox_list_add(mailbox_list, mb);
117 if (r != MAILIMF_NO_ERROR) {
122 return MAILIMF_NO_ERROR;
125 mailimf_mailbox_free(mb);
132 struct mailimf_address_list *
133 mailimf_address_list_new_empty()
136 struct mailimf_address_list * addr_list;
142 addr_list = mailimf_address_list_new(list);
143 if (addr_list == NULL)
149 int mailimf_address_list_add(struct mailimf_address_list * address_list,
150 struct mailimf_address * addr)
154 r = clist_append(address_list->ad_list, addr);
156 return MAILIMF_ERROR_MEMORY;
158 return MAILIMF_NO_ERROR;
161 int mailimf_address_list_add_parse(struct mailimf_address_list * address_list,
166 struct mailimf_address * addr;
170 r = mailimf_address_parse(addr_str, strlen(addr_str), &cur_token, &addr);
171 if (r != MAILIMF_NO_ERROR) {
176 r = mailimf_address_list_add(address_list, addr);
177 if (r != MAILIMF_NO_ERROR) {
182 return MAILIMF_NO_ERROR;
185 mailimf_address_free(addr);
190 int mailimf_address_list_add_mb(struct mailimf_address_list * address_list,
191 char * display_name, char * address)
194 struct mailimf_mailbox * mb;
195 struct mailimf_address * addr;
198 mb = mailimf_mailbox_new(display_name, address);
200 res = MAILIMF_ERROR_MEMORY;
204 addr = mailimf_address_new(MAILIMF_ADDRESS_MAILBOX, mb, NULL);
206 res = MAILIMF_ERROR_MEMORY;
210 r = mailimf_address_list_add(address_list, addr);
211 if (r != MAILIMF_NO_ERROR) {
216 return MAILIMF_NO_ERROR;
219 mailimf_address_free(addr);
221 mailimf_mailbox_free(mb);
228 struct mailimf_resent_fields_list *
229 mailimf_resent_fields_list_new_empty()
232 struct mailimf_resent_fields_list * rf_list;
238 rf_list = mailimf_resent_fields_list_new(list);
245 int mailimf_resent_fields_add(struct mailimf_resent_fields_list * fields,
246 struct mailimf_resent_field * field)
250 r = clist_append(fields->list, field);
252 return MAILIMF_ERROR_MEMORY;
254 return MAILIMF_NO_ERROR;
259 static void detach_free_common_fields(struct mailimf_orig_date * imf_date,
260 struct mailimf_from * imf_from,
261 struct mailimf_sender * imf_sender,
262 struct mailimf_to * imf_to,
263 struct mailimf_cc * imf_cc,
264 struct mailimf_bcc * imf_bcc,
265 struct mailimf_message_id * imf_msg_id)
267 if (imf_date != NULL) {
268 imf_date->dt_date_time = NULL;
269 mailimf_orig_date_free(imf_date);
271 if (imf_from != NULL) {
272 imf_from->frm_mb_list = NULL;
273 mailimf_from_free(imf_from);
275 if (imf_sender != NULL) {
276 imf_sender->snd_mb = NULL;
277 mailimf_sender_free(imf_sender);
279 if (imf_to != NULL) {
280 imf_to->to_addr_list = NULL;
281 mailimf_to_free(imf_to);
283 if (imf_cc != NULL) {
284 imf_cc->cc_addr_list = NULL;
285 mailimf_cc_free(imf_cc);
287 if (imf_bcc != NULL) {
288 imf_bcc->bcc_addr_list = NULL;
289 mailimf_bcc_free(imf_bcc);
291 if (imf_msg_id != NULL) {
292 imf_msg_id->mid_value = NULL;
293 mailimf_message_id_free(imf_msg_id);
297 static void detach_resent_field(struct mailimf_field * field)
299 field->fld_type = MAILIMF_FIELD_NONE;
300 mailimf_field_free(field);
304 mailimf_resent_fields_add_data(struct mailimf_fields * fields,
305 struct mailimf_date_time * resent_date,
306 struct mailimf_mailbox_list * resent_from,
307 struct mailimf_mailbox * resent_sender,
308 struct mailimf_address_list * resent_to,
309 struct mailimf_address_list * resent_cc,
310 struct mailimf_address_list * resent_bcc,
311 char * resent_msg_id)
313 struct mailimf_orig_date * imf_resent_date;
314 struct mailimf_from * imf_resent_from;
315 struct mailimf_sender * imf_resent_sender;
316 struct mailimf_to * imf_resent_to;
317 struct mailimf_cc * imf_resent_cc;
318 struct mailimf_bcc * imf_resent_bcc;
319 struct mailimf_message_id * imf_resent_msg_id;
320 struct mailimf_field * field;
323 imf_resent_date = NULL;
324 imf_resent_from = NULL;
325 imf_resent_sender = NULL;
326 imf_resent_to = NULL;
327 imf_resent_cc = NULL;
328 imf_resent_bcc = NULL;
329 imf_resent_msg_id = NULL;
332 if (resent_date != NULL) {
333 imf_resent_date = mailimf_orig_date_new(resent_date);
334 if (imf_resent_date == NULL)
336 field = mailimf_field_new(MAILIMF_FIELD_RESENT_DATE,
337 NULL /* return-path */,
338 imf_resent_date /* resent date */,
339 NULL /* resent from */,
340 NULL /* resent sender */,
341 NULL /* resent to */,
342 NULL /* resent cc */,
343 NULL /* resent bcc */,
344 NULL /* resent msg id */,
352 NULL /* message id */,
353 NULL /* in reply to */,
354 NULL /* references */,
358 NULL /* optional field */);
361 r = mailimf_fields_add(fields, field);
362 if (r != MAILIMF_NO_ERROR)
366 if (resent_from != NULL) {
367 imf_resent_from = mailimf_from_new(resent_from);
368 if (imf_resent_from == NULL)
370 field = mailimf_field_new(MAILIMF_FIELD_RESENT_FROM,
371 NULL /* return-path */,
372 NULL /* resent date */,
373 imf_resent_from /* resent from */,
374 NULL /* resent sender */,
375 NULL /* resent to */,
376 NULL /* resent cc */,
377 NULL /* resent bcc */,
378 NULL /* resent msg id */,
386 NULL /* message id */,
387 NULL /* in reply to */,
388 NULL /* references */,
392 NULL /* optional field */);
395 r = mailimf_fields_add(fields, field);
396 if (r != MAILIMF_NO_ERROR)
400 if (resent_sender != NULL) {
401 imf_resent_sender = mailimf_sender_new(resent_sender);
402 if (imf_resent_sender == NULL)
404 field = mailimf_field_new(MAILIMF_FIELD_RESENT_SENDER,
405 NULL /* return-path */,
406 NULL /* resent date */,
407 NULL /* resent from */,
408 imf_resent_sender /* resent sender */,
409 NULL /* resent to */,
410 NULL /* resent cc */,
411 NULL /* resent bcc */,
412 NULL /* resent msg id */,
420 NULL /* message id */,
421 NULL /* in reply to */,
422 NULL /* references */,
426 NULL /* optional field */);
429 r = mailimf_fields_add(fields, field);
430 if (r != MAILIMF_NO_ERROR)
434 if (resent_to != NULL) {
435 imf_resent_to = mailimf_to_new(resent_to);
436 if (imf_resent_to == NULL)
438 field = mailimf_field_new(MAILIMF_FIELD_RESENT_TO,
439 NULL /* return-path */,
440 NULL /* resent date */,
441 NULL /* resent from */,
442 NULL /* resent sender */,
443 imf_resent_to /* resent to */,
444 NULL /* resent cc */,
445 NULL /* resent bcc */,
446 NULL /* resent msg id */,
454 NULL /* message id */,
455 NULL /* in reply to */,
456 NULL /* references */,
460 NULL /* optional field */);
463 r = mailimf_fields_add(fields, field);
464 if (r != MAILIMF_NO_ERROR)
468 if (resent_cc != NULL) {
469 imf_resent_cc = mailimf_cc_new(resent_cc);
470 if (imf_resent_cc == NULL)
472 field = mailimf_field_new(MAILIMF_FIELD_RESENT_CC,
473 NULL /* return-path */,
474 NULL /* resent date */,
475 NULL /* resent from */,
476 NULL /* resent sender */,
477 NULL /* resent to */,
478 imf_resent_cc /* resent cc */,
479 NULL /* resent bcc */,
480 NULL /* resent msg id */,
488 NULL /* message id */,
489 NULL /* in reply to */,
490 NULL /* references */,
494 NULL /* optional field */);
497 r = mailimf_fields_add(fields, field);
498 if (r != MAILIMF_NO_ERROR)
502 if (resent_bcc != NULL) {
503 imf_resent_bcc = mailimf_bcc_new(resent_bcc);
504 if (imf_resent_bcc == NULL)
506 field = mailimf_field_new(MAILIMF_FIELD_RESENT_BCC,
507 NULL /* return-path */,
508 NULL /* resent date */,
509 NULL /* resent from */,
510 NULL /* resent sender */,
511 NULL /* resent to */,
512 NULL /* resent cc */,
513 imf_resent_bcc /* resent bcc */,
514 NULL /* resent msg id */,
522 NULL /* message id */,
523 NULL /* in reply to */,
524 NULL /* references */,
528 NULL /* optional field */);
531 r = mailimf_fields_add(fields, field);
532 if (r != MAILIMF_NO_ERROR)
536 if (resent_msg_id != NULL) {
537 imf_resent_msg_id = mailimf_message_id_new(resent_msg_id);
538 if (imf_resent_msg_id == NULL)
540 field = mailimf_field_new(MAILIMF_FIELD_RESENT_MSG_ID,
541 NULL /* return-path */,
542 NULL /* resent date */,
543 NULL /* resent from */,
544 NULL /* resent sender */,
545 NULL /* resent to */,
546 NULL /* resent cc */,
547 NULL /* resent bcc */,
548 imf_resent_msg_id /* resent msg id */,
556 NULL /* message id */,
557 NULL /* in reply to */,
558 NULL /* references */,
562 NULL /* optional field */);
565 r = mailimf_fields_add(fields, field);
566 if (r != MAILIMF_NO_ERROR)
570 return MAILIMF_NO_ERROR;
574 detach_resent_field(field);
577 detach_free_common_fields(imf_resent_date,
584 return MAILIMF_ERROR_MEMORY;
587 struct mailimf_fields *
588 mailimf_resent_fields_new_with_data_all(struct mailimf_date_time *
590 struct mailimf_mailbox_list *
592 struct mailimf_mailbox *
594 struct mailimf_address_list *
596 struct mailimf_address_list *
598 struct mailimf_address_list *
600 char * resent_msg_id)
602 struct mailimf_fields * resent_fields;
605 resent_fields = mailimf_fields_new_empty();
606 if (resent_fields == NULL)
609 r = mailimf_resent_fields_add_data(resent_fields,
610 resent_date, resent_from,
611 resent_sender, resent_to,
612 resent_cc, resent_bcc,
614 if (r != MAILIMF_NO_ERROR)
617 return resent_fields;
620 mailimf_fields_free(resent_fields);
626 struct mailimf_fields *
627 mailimf_resent_fields_new_with_data(struct mailimf_mailbox_list * from,
628 struct mailimf_mailbox * sender,
629 struct mailimf_address_list * to,
630 struct mailimf_address_list * cc,
631 struct mailimf_address_list * bcc)
633 struct mailimf_date_time * date;
635 struct mailimf_fields * fields;
637 date = mailimf_get_current_date();
641 msg_id = mailimf_get_message_id();
645 fields = mailimf_resent_fields_new_with_data_all(date,
646 from, sender, to, cc, bcc, msg_id);
655 mailimf_date_time_free(date);
661 struct mailimf_fields *
662 mailimf_fields_new_empty(void)
665 struct mailimf_fields * fields_list;
671 fields_list = mailimf_fields_new(list);
672 if (fields_list == NULL)
678 int mailimf_fields_add(struct mailimf_fields * fields,
679 struct mailimf_field * field)
683 r = clist_append(fields->fld_list, field);
685 return MAILIMF_ERROR_MEMORY;
687 return MAILIMF_NO_ERROR;
690 static void detach_free_fields(struct mailimf_orig_date * date,
691 struct mailimf_from * from,
692 struct mailimf_sender * sender,
693 struct mailimf_reply_to * reply_to,
694 struct mailimf_to * to,
695 struct mailimf_cc * cc,
696 struct mailimf_bcc * bcc,
697 struct mailimf_message_id * msg_id,
698 struct mailimf_in_reply_to * in_reply_to,
699 struct mailimf_references * references,
700 struct mailimf_subject * subject)
702 detach_free_common_fields(date,
710 if (reply_to != NULL) {
711 reply_to->rt_addr_list = NULL;
712 mailimf_reply_to_free(reply_to);
715 if (in_reply_to != NULL) {
716 in_reply_to->mid_list = NULL;
717 mailimf_in_reply_to_free(in_reply_to);
720 if (references != NULL) {
721 references->mid_list = NULL;
722 mailimf_references_free(references);
725 if (subject != NULL) {
726 subject->sbj_value = NULL;
727 mailimf_subject_free(subject);
732 static void detach_field(struct mailimf_field * field)
734 field->fld_type = MAILIMF_FIELD_NONE;
735 mailimf_field_free(field);
738 int mailimf_fields_add_data(struct mailimf_fields * fields,
739 struct mailimf_date_time * date,
740 struct mailimf_mailbox_list * from,
741 struct mailimf_mailbox * sender,
742 struct mailimf_address_list * reply_to,
743 struct mailimf_address_list * to,
744 struct mailimf_address_list * cc,
745 struct mailimf_address_list * bcc,
751 struct mailimf_orig_date * imf_date;
752 struct mailimf_from * imf_from;
753 struct mailimf_sender * imf_sender;
754 struct mailimf_reply_to * imf_reply_to;
755 struct mailimf_to * imf_to;
756 struct mailimf_cc * imf_cc;
757 struct mailimf_bcc * imf_bcc;
758 struct mailimf_message_id * imf_msg_id;
759 struct mailimf_references * imf_references;
760 struct mailimf_in_reply_to * imf_in_reply_to;
761 struct mailimf_subject * imf_subject;
762 struct mailimf_field * field;
773 imf_references = NULL;
774 imf_in_reply_to = NULL;
779 imf_date = mailimf_orig_date_new(date);
780 if (imf_date == NULL)
782 field = mailimf_field_new(MAILIMF_FIELD_ORIG_DATE,
783 NULL /* return-path */,
784 NULL /* resent date */,
785 NULL /* resent from */,
786 NULL /* resent sender */,
787 NULL /* resent to */,
788 NULL /* resent cc */,
789 NULL /* resent bcc */,
790 NULL /* resent msg id */,
798 NULL /* message id */,
799 NULL /* in reply to */,
800 NULL /* references */,
804 NULL /* optional field */);
807 r = mailimf_fields_add(fields, field);
808 if (r != MAILIMF_NO_ERROR)
813 imf_from = mailimf_from_new(from);
814 if (imf_from == NULL)
816 field = mailimf_field_new(MAILIMF_FIELD_FROM,
817 NULL /* return-path */,
818 NULL /* resent date */,
819 NULL /* resent from */,
820 NULL /* resent sender */,
821 NULL /* resent to */,
822 NULL /* resent cc */,
823 NULL /* resent bcc */,
824 NULL /* resent msg id */,
832 NULL /* message id */,
833 NULL /* in reply to */,
834 NULL /* references */,
838 NULL /* optional field */);
841 r = mailimf_fields_add(fields, field);
842 if (r != MAILIMF_NO_ERROR)
846 if (sender != NULL) {
847 imf_sender = mailimf_sender_new(sender);
848 if (imf_sender == NULL)
850 field = mailimf_field_new(MAILIMF_FIELD_SENDER,
851 NULL /* return-path */,
852 NULL /* resent date */,
853 NULL /* resent from */,
854 NULL /* resent sender */,
855 NULL /* resent to */,
856 NULL /* resent cc */,
857 NULL /* resent bcc */,
858 NULL /* resent msg id */,
861 imf_sender /* sender */,
866 NULL /* message id */,
867 NULL /* in reply to */,
868 NULL /* references */,
872 NULL /* optional field */);
875 r = mailimf_fields_add(fields, field);
876 if (r != MAILIMF_NO_ERROR)
880 if (reply_to != NULL) {
881 imf_reply_to = mailimf_reply_to_new(reply_to);
882 if (imf_reply_to == NULL)
884 field = mailimf_field_new(MAILIMF_FIELD_REPLY_TO,
885 NULL /* return-path */,
886 NULL /* resent date */,
887 NULL /* resent from */,
888 NULL /* resent sender */,
889 NULL /* resent to */,
890 NULL /* resent cc */,
891 NULL /* resent bcc */,
892 NULL /* resent msg id */,
896 imf_reply_to /* reply-to */,
900 NULL /* message id */,
901 NULL /* in reply to */,
902 NULL /* references */,
906 NULL /* optional field */);
909 r = mailimf_fields_add(fields, field);
910 if (r != MAILIMF_NO_ERROR)
915 imf_to = mailimf_to_new(to);
918 field = mailimf_field_new(MAILIMF_FIELD_TO,
919 NULL /* return-path */,
920 NULL /* resent date */,
921 NULL /* resent from */,
922 NULL /* resent sender */,
923 NULL /* resent to */,
924 NULL /* resent cc */,
925 NULL /* resent bcc */,
926 NULL /* resent msg id */,
934 NULL /* message id */,
935 NULL /* in reply to */,
936 NULL /* references */,
940 NULL /* optional field */);
943 r = mailimf_fields_add(fields, field);
944 if (r != MAILIMF_NO_ERROR)
949 imf_cc = mailimf_cc_new(cc);
952 field = mailimf_field_new(MAILIMF_FIELD_CC,
953 NULL /* return-path */,
954 NULL /* resent date */,
955 NULL /* resent from */,
956 NULL /* resent sender */,
957 NULL /* resent to */,
958 NULL /* resent cc */,
959 NULL /* resent bcc */,
960 NULL /* resent msg id */,
968 NULL /* message id */,
969 NULL /* in reply to */,
970 NULL /* references */,
974 NULL /* optional field */);
977 r = mailimf_fields_add(fields, field);
978 if (r != MAILIMF_NO_ERROR)
983 imf_bcc = mailimf_bcc_new(bcc);
986 field = mailimf_field_new(MAILIMF_FIELD_BCC,
987 NULL /* return-path */,
988 NULL /* resent date */,
989 NULL /* resent from */,
990 NULL /* resent sender */,
991 NULL /* resent to */,
992 NULL /* resent cc */,
993 NULL /* resent bcc */,
994 NULL /* resent msg id */,
1002 NULL /* message id */,
1003 NULL /* in reply to */,
1004 NULL /* references */,
1006 NULL /* comments */,
1007 NULL /* keywords */,
1008 NULL /* optional field */);
1011 r = mailimf_fields_add(fields, field);
1012 if (r != MAILIMF_NO_ERROR)
1016 if (msg_id != NULL) {
1017 imf_msg_id = mailimf_message_id_new(msg_id);
1018 if (imf_msg_id == NULL)
1020 field = mailimf_field_new(MAILIMF_FIELD_MESSAGE_ID,
1021 NULL /* return-path */,
1022 NULL /* resent date */,
1023 NULL /* resent from */,
1024 NULL /* resent sender */,
1025 NULL /* resent to */,
1026 NULL /* resent cc */,
1027 NULL /* resent bcc */,
1028 NULL /* resent msg id */,
1032 NULL /* reply-to */,
1036 imf_msg_id /* message id */,
1037 NULL /* in reply to */,
1038 NULL /* references */,
1040 NULL /* comments */,
1041 NULL /* keywords */,
1042 NULL /* optional field */);
1045 r = mailimf_fields_add(fields, field);
1046 if (r != MAILIMF_NO_ERROR)
1050 if (in_reply_to != NULL) {
1051 imf_in_reply_to = mailimf_in_reply_to_new(in_reply_to);
1052 if (imf_in_reply_to == NULL)
1054 field = mailimf_field_new(MAILIMF_FIELD_IN_REPLY_TO,
1055 NULL /* return-path */,
1056 NULL /* resent date */,
1057 NULL /* resent from */,
1058 NULL /* resent sender */,
1059 NULL /* resent to */,
1060 NULL /* resent cc */,
1061 NULL /* resent bcc */,
1062 NULL /* resent msg id */,
1066 NULL /* reply-to */,
1070 NULL /* message id */,
1071 imf_in_reply_to /* in reply to */,
1072 NULL /* references */,
1074 NULL /* comments */,
1075 NULL /* keywords */,
1076 NULL /* optional field */);
1079 r = mailimf_fields_add(fields, field);
1080 if (r != MAILIMF_NO_ERROR)
1084 if (references != NULL) {
1085 imf_references = mailimf_references_new(references);
1086 if (imf_references == NULL)
1088 field = mailimf_field_new(MAILIMF_FIELD_REFERENCES,
1089 NULL /* return-path */,
1090 NULL /* resent date */,
1091 NULL /* resent from */,
1092 NULL /* resent sender */,
1093 NULL /* resent to */,
1094 NULL /* resent cc */,
1095 NULL /* resent bcc */,
1096 NULL /* resent msg id */,
1100 NULL /* reply-to */,
1104 NULL /* message id */,
1105 NULL /* in reply to */,
1106 imf_references /* references */,
1108 NULL /* comments */,
1109 NULL /* keywords */,
1110 NULL /* optional field */);
1113 r = mailimf_fields_add(fields, field);
1114 if (r != MAILIMF_NO_ERROR)
1118 if (subject != NULL) {
1119 imf_subject = mailimf_subject_new(subject);
1120 if (imf_subject == NULL)
1122 field = mailimf_field_new(MAILIMF_FIELD_SUBJECT,
1123 NULL /* return-path */,
1124 NULL /* resent date */,
1125 NULL /* resent from */,
1126 NULL /* resent sender */,
1127 NULL /* resent to */,
1128 NULL /* resent cc */,
1129 NULL /* resent bcc */,
1130 NULL /* resent msg id */,
1134 NULL /* reply-to */,
1138 NULL /* message id */,
1139 NULL /* in reply to */,
1140 NULL /* references */,
1141 imf_subject /* subject */,
1142 NULL /* comments */,
1143 NULL /* keywords */,
1144 NULL /* optional field */);
1147 r = mailimf_fields_add(fields, field);
1148 if (r != MAILIMF_NO_ERROR)
1152 return MAILIMF_NO_ERROR;
1155 if (field != NULL) {
1156 detach_field(field);
1159 detach_free_fields(imf_date,
1171 return MAILIMF_ERROR_MEMORY;
1174 struct mailimf_fields *
1175 mailimf_fields_new_with_data_all(struct mailimf_date_time * date,
1176 struct mailimf_mailbox_list * from,
1177 struct mailimf_mailbox * sender,
1178 struct mailimf_address_list * reply_to,
1179 struct mailimf_address_list * to,
1180 struct mailimf_address_list * cc,
1181 struct mailimf_address_list * bcc,
1183 clist * in_reply_to,
1187 struct mailimf_fields * fields;
1190 fields = mailimf_fields_new_empty();
1194 r = mailimf_fields_add_data(fields,
1206 if (r != MAILIMF_NO_ERROR)
1212 mailimf_fields_free(fields);
1217 struct mailimf_fields *
1218 mailimf_fields_new_with_data(struct mailimf_mailbox_list * from,
1219 struct mailimf_mailbox * sender,
1220 struct mailimf_address_list * reply_to,
1221 struct mailimf_address_list * to,
1222 struct mailimf_address_list * cc,
1223 struct mailimf_address_list * bcc,
1224 clist * in_reply_to,
1228 struct mailimf_date_time * date;
1230 struct mailimf_fields * fields;
1232 date = mailimf_get_current_date();
1236 msg_id = mailimf_get_message_id();
1240 fields = mailimf_fields_new_with_data_all(date,
1241 from, sender, reply_to,
1244 in_reply_to, references,
1254 mailimf_date_time_free(date);
1261 #define MAX_MESSAGE_ID 512
1263 char * mailimf_get_message_id(void)
1265 char id[MAX_MESSAGE_ID];
1267 char name[HOST_NAME_MAX];
1274 /* It's unlikely that HOST_NAME_MAX goes above 64, but let's
1275 * leave a generous reserve for the hostname in the message
1277 if (HOST_NAME_MAX > MAX_MESSAGE_ID - 64 ||
1278 (ret = gethostname(name, HOST_NAME_MAX)) != 0) {
1280 perror("gethostname");
1281 strncpy(name, "unknown", HOST_NAME_MAX);
1284 snprintf(id, MAX_MESSAGE_ID, "etPan.%llx.%lx.%x@%s",
1285 (long long)now, value, getpid(), name);
1292 static time_t mkgmtime(struct tm * tmp);
1295 struct mailimf_date_time * mailimf_get_current_date(void)
1301 struct mailimf_date_time * date_time;
1305 if (gmtime_r(&now, &gmt) == NULL)
1308 if (localtime_r(&now, <) == NULL)
1311 off = (mkgmtime(<) - mkgmtime(&gmt)) / (60 * 60) * 100;
1313 date_time = mailimf_date_time_new(lt.tm_mday, lt.tm_mon + 1, lt.tm_year + 1900,
1314 lt.tm_hour, lt.tm_min, lt.tm_sec,
1322 /* mkgmtime.c - make time corresponding to a GMT timeval struct
1325 * Copyright (c) 1998-2000 Carnegie Mellon University. All rights reserved.
1327 * Redistribution and use in source and binary forms, with or without
1328 * modification, are permitted provided that the following conditions
1331 * 1. Redistributions of source code must retain the above copyright
1332 * notice, this list of conditions and the following disclaimer.
1334 * 2. Redistributions in binary form must reproduce the above copyright
1335 * notice, this list of conditions and the following disclaimer in
1336 * the documentation and/or other materials provided with the
1339 * 3. The name "Carnegie Mellon University" must not be used to
1340 * endorse or promote products derived from this software without
1341 * prior written permission. For permission or any other legal
1342 * details, please contact
1343 * Office of Technology Transfer
1344 * Carnegie Mellon University
1345 * 5000 Forbes Avenue
1346 * Pittsburgh, PA 15213-3890
1347 * (412) 268-4387, fax: (412) 268-7395
1348 * tech-transfer@andrew.cmu.edu
1350 * 4. Redistributions of any form whatsoever must retain the following
1352 * "This product includes software developed by Computing Services
1353 * at Carnegie Mellon University (http://www.cmu.edu/computing/)."
1355 * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
1356 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
1357 * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
1358 * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1359 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
1360 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
1361 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1366 * Copyright (c) 1987, 1989, 1993
1367 * The Regents of the University of California. All rights reserved.
1369 * This code is derived from software contributed to Berkeley by
1370 * Arthur David Olson of the National Cancer Institute.
1372 * Redistribution and use in source and binary forms, with or without
1373 * modification, are permitted provided that the following conditions
1375 * 1. Redistributions of source code must retain the above copyright
1376 * notice, this list of conditions and the following disclaimer.
1377 * 2. Redistributions in binary form must reproduce the above copyright
1378 * notice, this list of conditions and the following disclaimer in the
1379 * documentation and/or other materials provided with the distribution.
1380 * 3. All advertising materials mentioning features or use of this software
1381 * must display the following acknowledgement:
1382 * This product includes software developed by the University of
1383 * California, Berkeley and its contributors.
1384 * 4. Neither the name of the University nor the names of its contributors
1385 * may be used to endorse or promote products derived from this software
1386 * without specific prior written permission.
1388 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
1389 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1390 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1391 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
1392 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1393 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1394 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1395 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1396 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1397 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1402 ** Adapted from code provided by Robert Elz, who writes:
1403 ** The "best" way to do mktime I think is based on an idea of Bob
1404 ** Kridle's (so its said...) from a long time ago. (mtxinu!kridle now).
1405 ** It does a binary search of the time_t space. Since time_t's are
1406 ** just 32 bits, its a max of 32 iterations (even at 64 bits it
1407 ** would still be very reasonable).
1411 adapted for libEtPan! by DINH V. Hoa
1416 #endif /* !defined WRONG */
1418 static int tmcomp(struct tm * atmp, struct tm * btmp)
1420 register int result;
1422 if ((result = (atmp->tm_year - btmp->tm_year)) == 0 &&
1423 (result = (atmp->tm_mon - btmp->tm_mon)) == 0 &&
1424 (result = (atmp->tm_mday - btmp->tm_mday)) == 0 &&
1425 (result = (atmp->tm_hour - btmp->tm_hour)) == 0 &&
1426 (result = (atmp->tm_min - btmp->tm_min)) == 0)
1427 result = atmp->tm_sec - btmp->tm_sec;
1431 static time_t mkgmtime(struct tm * tmp)
1435 register int saved_seconds;
1437 struct tm yourtm, *mytm, buft;
1440 saved_seconds = yourtm.tm_sec;
1443 ** Calculate the number of magnitude bits in a time_t
1444 ** (this works regardless of whether time_t is
1445 ** signed or unsigned, though lint complains if unsigned).
1447 for (bits = 0, t = 1; t > 0; ++bits, t <<= 1)
1450 ** If time_t is signed, then 0 is the median value,
1451 ** if time_t is unsigned, then 1 << bits is median.
1453 t = (t < 0) ? 0 : ((time_t) 1 << bits);
1455 mytm = gmtime_r(&t, &buft);
1456 dir = tmcomp(mytm, &yourtm);
1463 t -= (time_t) 1 << bits;
1464 else t += (time_t) 1 << bits;
1479 void mailimf_single_fields_init(struct mailimf_single_fields * single_fields,
1480 struct mailimf_fields * fields)
1484 memset(single_fields, 0, sizeof(struct mailimf_single_fields));
1486 cur = clist_begin(fields->fld_list);
1487 while (cur != NULL) {
1488 struct mailimf_field * field;
1490 field = clist_content(cur);
1492 switch (field->fld_type) {
1493 case MAILIMF_FIELD_ORIG_DATE:
1494 if (single_fields->fld_orig_date == NULL)
1495 single_fields->fld_orig_date = field->fld_data.fld_orig_date;
1496 cur = clist_next(cur);
1498 case MAILIMF_FIELD_FROM:
1499 if (single_fields->fld_from == NULL) {
1500 single_fields->fld_from = field->fld_data.fld_from;
1501 cur = clist_next(cur);
1504 clist_concat(single_fields->fld_from->frm_mb_list->mb_list,
1505 field->fld_data.fld_from->frm_mb_list->mb_list);
1506 mailimf_field_free(field);
1507 cur = clist_delete(fields->fld_list, cur);
1510 case MAILIMF_FIELD_SENDER:
1511 if (single_fields->fld_sender == NULL)
1512 single_fields->fld_sender = field->fld_data.fld_sender;
1513 cur = clist_next(cur);
1515 case MAILIMF_FIELD_REPLY_TO:
1516 if (single_fields->fld_reply_to == NULL) {
1517 single_fields->fld_reply_to = field->fld_data.fld_reply_to;
1518 cur = clist_next(cur);
1521 clist_concat(single_fields->fld_reply_to->rt_addr_list->ad_list,
1522 field->fld_data.fld_reply_to->rt_addr_list->ad_list);
1523 mailimf_field_free(field);
1524 cur = clist_delete(fields->fld_list, cur);
1527 case MAILIMF_FIELD_TO:
1528 if (single_fields->fld_to == NULL) {
1529 single_fields->fld_to = field->fld_data.fld_to;
1530 cur = clist_next(cur);
1533 clist_concat(single_fields->fld_to->to_addr_list->ad_list,
1534 field->fld_data.fld_to->to_addr_list->ad_list);
1535 mailimf_field_free(field);
1536 cur = clist_delete(fields->fld_list, cur);
1539 case MAILIMF_FIELD_CC:
1540 if (single_fields->fld_cc == NULL) {
1541 single_fields->fld_cc = field->fld_data.fld_cc;
1542 cur = clist_next(cur);
1545 clist_concat(single_fields->fld_cc->cc_addr_list->ad_list,
1546 field->fld_data.fld_cc->cc_addr_list->ad_list);
1547 mailimf_field_free(field);
1548 cur = clist_delete(fields->fld_list, cur);
1551 case MAILIMF_FIELD_BCC:
1552 if (single_fields->fld_bcc == NULL) {
1553 single_fields->fld_bcc = field->fld_data.fld_bcc;
1554 cur = clist_next(cur);
1557 clist_concat(single_fields->fld_bcc->bcc_addr_list->ad_list,
1558 field->fld_data.fld_bcc->bcc_addr_list->ad_list);
1559 mailimf_field_free(field);
1560 cur = clist_delete(fields->fld_list, cur);
1563 case MAILIMF_FIELD_MESSAGE_ID:
1564 if (single_fields->fld_message_id == NULL)
1565 single_fields->fld_message_id = field->fld_data.fld_message_id;
1566 cur = clist_next(cur);
1568 case MAILIMF_FIELD_IN_REPLY_TO:
1569 if (single_fields->fld_in_reply_to == NULL)
1570 single_fields->fld_in_reply_to = field->fld_data.fld_in_reply_to;
1571 cur = clist_next(cur);
1573 case MAILIMF_FIELD_REFERENCES:
1574 if (single_fields->fld_references == NULL)
1575 single_fields->fld_references = field->fld_data.fld_references;
1576 cur = clist_next(cur);
1578 case MAILIMF_FIELD_SUBJECT:
1579 if (single_fields->fld_subject == NULL)
1580 single_fields->fld_subject = field->fld_data.fld_subject;
1581 cur = clist_next(cur);
1583 case MAILIMF_FIELD_COMMENTS:
1584 if (single_fields->fld_comments == NULL)
1585 single_fields->fld_comments = field->fld_data.fld_comments;
1586 cur = clist_next(cur);
1588 case MAILIMF_FIELD_KEYWORDS:
1589 if (single_fields->fld_keywords == NULL)
1590 single_fields->fld_keywords = field->fld_data.fld_keywords;
1591 cur = clist_next(cur);
1594 cur = clist_next(cur);
1601 struct mailimf_single_fields *
1602 mailimf_single_fields_new(struct mailimf_fields * fields)
1604 struct mailimf_single_fields * single_fields;
1606 single_fields = malloc(sizeof(struct mailimf_single_fields));
1607 if (single_fields == NULL)
1610 mailimf_single_fields_init(single_fields, fields);
1612 return single_fields;
1618 void mailimf_single_fields_free(struct mailimf_single_fields *
1621 free(single_fields);
1624 struct mailimf_field * mailimf_field_new_custom(char * name, char * value)
1626 struct mailimf_optional_field * opt_field;
1627 struct mailimf_field * field;
1629 opt_field = mailimf_optional_field_new(name, value);
1630 if (opt_field == NULL)
1633 field = mailimf_field_new(MAILIMF_FIELD_OPTIONAL_FIELD,
1634 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
1635 NULL, NULL, NULL, NULL,
1636 NULL, NULL, NULL, NULL,
1637 NULL, NULL, NULL, NULL,
1638 NULL, NULL, opt_field);
1640 goto free_opt_field;
1645 mailimf_optional_field_free(opt_field);