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
38 #include "claws-features.h"
42 #include "file-utils.h"
48 A message-originating SMTP system SHOULD NOT send a message that
49 already contains a Return-path header. SMTP servers performing a
50 relay function MUST NOT inspect the message data, and especially not
51 to the extent needed to determine if Return-path headers are present.
52 SMTP servers making final delivery MAY remove Return-path headers
53 before adding their own.
57 #include <mmapstring.h>
75 static inline int is_dtext(char ch
);
78 static int mailimf_quoted_pair_parse(const char * message
, size_t length
,
79 size_t * index
, char * result
);
81 static int mailimf_ccontent_parse(const char * message
, size_t length
,
85 mailimf_comment_fws_ccontent_parse(const char * message
, size_t length
,
88 static inline int mailimf_comment_parse(const char * message
, size_t length
,
91 static int mailimf_qcontent_parse(const char * message
, size_t length
,
92 size_t * index
, char * ch
);
94 static int mailimf_phrase_parse(const char * message
, size_t length
,
95 size_t * index
, char ** result
);
97 static int mailimf_unstructured_parse(const char * message
, size_t length
,
98 size_t * index
, char ** result
);
100 static int mailimf_ignore_unstructured_parse(const char * message
, size_t length
,
103 static int mailimf_day_of_week_parse(const char * message
, size_t length
,
104 size_t * index
, int * result
);
106 static int mailimf_day_name_parse(const char * message
, size_t length
,
107 size_t * index
, int * result
);
109 static int mailimf_date_parse(const char * message
, size_t length
,
111 int * pday
, int * pmonth
, int * pyear
);
113 static int mailimf_year_parse(const char * message
, size_t length
,
114 size_t * index
, int * result
);
116 static int mailimf_month_parse(const char * message
, size_t length
,
117 size_t * index
, int * result
);
119 static int mailimf_month_name_parse(const char * message
, size_t length
,
120 size_t * index
, int * result
);
122 static int mailimf_day_parse(const char * message
, size_t length
,
123 size_t * index
, int * result
);
125 static int mailimf_time_parse(const char * message
, size_t length
,
127 int * phour
, int * pmin
,
130 static int mailimf_time_of_day_parse(const char * message
, size_t length
,
132 int * phour
, int * pmin
,
135 static int mailimf_hour_parse(const char * message
, size_t length
,
136 size_t * index
, int * result
);
138 static int mailimf_minute_parse(const char * message
, size_t length
,
139 size_t * index
, int * result
);
141 static int mailimf_second_parse(const char * message
, size_t length
,
142 size_t * index
, int * result
);
144 static int mailimf_zone_parse(const char * message
, size_t length
,
145 size_t * index
, int * result
);
147 static int mailimf_name_addr_parse(const char * message
, size_t length
,
149 char ** pdisplay_name
,
150 char ** pangle_addr
);
152 static int mailimf_angle_addr_parse(const char * message
, size_t length
,
153 size_t * index
, char ** result
);
155 static int mailimf_group_parse(const char * message
, size_t length
,
157 struct mailimf_group
** result
);
159 static int mailimf_display_name_parse(const char * message
, size_t length
,
160 size_t * index
, char ** result
);
162 static int mailimf_addr_spec_parse(const char * message
, size_t length
,
167 static int mailimf_local_part_parse(const char * message
, size_t length
,
171 static int mailimf_domain_parse(const char * message
, size_t length
,
177 static int mailimf_domain_literal_parse(const char * message
, size_t length
,
178 size_t * index
, char ** result
);
182 static int mailimf_dcontent_parse(const char * message
, size_t length
,
183 size_t * index
, char * result
);
187 mailimf_orig_date_parse(const char * message
, size_t length
,
188 size_t * index
, struct mailimf_orig_date
** result
);
191 mailimf_from_parse(const char * message
, size_t length
,
192 size_t * index
, struct mailimf_from
** result
);
195 mailimf_sender_parse(const char * message
, size_t length
,
196 size_t * index
, struct mailimf_sender
** result
);
199 mailimf_reply_to_parse(const char * message
, size_t length
,
200 size_t * index
, struct mailimf_reply_to
** result
);
203 mailimf_to_parse(const char * message
, size_t length
,
204 size_t * index
, struct mailimf_to
** result
);
207 mailimf_cc_parse(const char * message
, size_t length
,
208 size_t * index
, struct mailimf_cc
** result
);
211 mailimf_bcc_parse(const char * message
, size_t length
,
212 size_t * index
, struct mailimf_bcc
** result
);
214 static int mailimf_message_id_parse(const char * message
, size_t length
,
216 struct mailimf_message_id
** result
);
219 mailimf_in_reply_to_parse(const char * message
, size_t length
,
221 struct mailimf_in_reply_to
** result
);
224 static int mailimf_references_parse(const char * message
, size_t length
,
226 struct mailimf_references
**
230 static int mailimf_unstrict_msg_id_parse(const char * message
, size_t length
,
235 static int mailimf_id_left_parse(const char * message
, size_t length
,
236 size_t * index
, char ** result
);
238 static int mailimf_id_right_parse(const char * message
, size_t length
,
239 size_t * index
, char ** result
);
243 static int mailimf_no_fold_quote_parse(const char * message
, size_t length
,
244 size_t * index
, char ** result
);
246 static int mailimf_no_fold_literal_parse(const char * message
, size_t length
,
247 size_t * index
, char ** result
);
250 static int mailimf_subject_parse(const char * message
, size_t length
,
252 struct mailimf_subject
** result
);
254 static int mailimf_comments_parse(const char * message
, size_t length
,
256 struct mailimf_comments
** result
);
258 static int mailimf_keywords_parse(const char * message
, size_t length
,
260 struct mailimf_keywords
** result
);
263 mailimf_resent_date_parse(const char * message
, size_t length
,
264 size_t * index
, struct mailimf_orig_date
** result
);
267 mailimf_resent_from_parse(const char * message
, size_t length
,
268 size_t * index
, struct mailimf_from
** result
);
271 mailimf_resent_sender_parse(const char * message
, size_t length
,
272 size_t * index
, struct mailimf_sender
** result
);
275 mailimf_resent_to_parse(const char * message
, size_t length
,
276 size_t * index
, struct mailimf_to
** result
);
279 mailimf_resent_cc_parse(const char * message
, size_t length
,
280 size_t * index
, struct mailimf_cc
** result
);
283 mailimf_resent_bcc_parse(const char * message
, size_t length
,
284 size_t * index
, struct mailimf_bcc
** result
);
287 mailimf_resent_msg_id_parse(const char * message
, size_t length
,
289 struct mailimf_message_id
** result
);
291 static int mailimf_return_parse(const char * message
, size_t length
,
293 struct mailimf_return
** result
);
296 mailimf_path_parse(const char * message
, size_t length
,
297 size_t * index
, struct mailimf_path
** result
);
300 mailimf_optional_field_parse(const char * message
, size_t length
,
302 struct mailimf_optional_field
** result
);
304 static int mailimf_field_name_parse(const char * message
, size_t length
,
305 size_t * index
, char ** result
);
331 /* *************************************************************** */
333 static inline int is_digit(char ch
)
335 return (ch
>= '0') && (ch
<= '9');
338 static int mailimf_digit_parse(const char * message
, size_t length
,
339 size_t * index
, int * result
)
345 if (cur_token
>= length
)
346 return MAILIMF_ERROR_PARSE
;
348 if (is_digit(message
[cur_token
])) {
349 * result
= message
[cur_token
] - '0';
352 return MAILIMF_NO_ERROR
;
355 return MAILIMF_ERROR_PARSE
;
359 mailimf_number_parse(const char * message
, size_t length
,
360 size_t * index
, uint32_t * result
)
373 r
= mailimf_digit_parse(message
, length
, &cur_token
, &digit
);
374 if (r
!= MAILIMF_NO_ERROR
) {
375 if (r
== MAILIMF_ERROR_PARSE
)
386 return MAILIMF_ERROR_PARSE
;
391 return MAILIMF_NO_ERROR
;
394 int mailimf_char_parse(const char * message
, size_t length
,
395 size_t * index
, char token
)
401 if (cur_token
>= length
)
402 return MAILIMF_ERROR_PARSE
;
404 if (message
[cur_token
] == token
) {
407 return MAILIMF_NO_ERROR
;
410 return MAILIMF_ERROR_PARSE
;
413 int mailimf_unstrict_char_parse(const char * message
, size_t length
,
414 size_t * index
, char token
)
421 r
= mailimf_cfws_parse(message
, length
, &cur_token
);
422 if ((r
!= MAILIMF_NO_ERROR
) && (r
!= MAILIMF_ERROR_PARSE
))
425 r
= mailimf_char_parse(message
, length
, &cur_token
, token
);
426 if (r
!= MAILIMF_NO_ERROR
)
431 return MAILIMF_NO_ERROR
;
435 mailimf_token_case_insensitive_len_parse(const char * message
, size_t length
,
436 size_t * index
, char * token
,
443 if (cur_token
+ token_length
- 1 >= length
)
444 return MAILIMF_ERROR_PARSE
;
446 if (strncasecmp(message
+ cur_token
, token
, token_length
) == 0) {
447 cur_token
+= token_length
;
449 return MAILIMF_NO_ERROR
;
452 return MAILIMF_ERROR_PARSE
;
455 static int mailimf_oparenth_parse(const char * message
, size_t length
,
458 return mailimf_char_parse(message
, length
, index
, '(');
461 static int mailimf_cparenth_parse(const char * message
, size_t length
,
464 return mailimf_char_parse(message
, length
, index
, ')');
467 static int mailimf_comma_parse(const char * message
, size_t length
,
470 return mailimf_unstrict_char_parse(message
, length
, index
, ',');
473 static int mailimf_dquote_parse(const char * message
, size_t length
,
476 return mailimf_char_parse(message
, length
, index
, '\"');
479 static int mailimf_colon_parse(const char * message
, size_t length
,
482 return mailimf_unstrict_char_parse(message
, length
, index
, ':');
485 static int mailimf_semi_colon_parse(const char * message
, size_t length
,
488 return mailimf_unstrict_char_parse(message
, length
, index
, ';');
491 static int mailimf_plus_parse(const char * message
, size_t length
,
494 return mailimf_unstrict_char_parse(message
, length
, index
, '+');
497 static int mailimf_minus_parse(const char * message
, size_t length
,
500 return mailimf_unstrict_char_parse(message
, length
, index
, '-');
503 static int mailimf_lower_parse(const char * message
, size_t length
,
506 return mailimf_unstrict_char_parse(message
, length
, index
, '<');
509 static int mailimf_greater_parse(const char * message
, size_t length
,
512 return mailimf_unstrict_char_parse(message
, length
, index
, '>');
516 static int mailimf_obracket_parse(const char * message
, size_t length
,
519 return mailimf_unstrict_char_parse(message
, length
, index
, '[');
522 static int mailimf_cbracket_parse(const char * message
, size_t length
,
525 return mailimf_unstrict_char_parse(message
, length
, index
, ']');
529 static int mailimf_at_sign_parse(const char * message
, size_t length
,
532 return mailimf_unstrict_char_parse(message
, length
, index
, '@');
535 static int mailimf_point_parse(const char * message
, size_t length
,
538 return mailimf_unstrict_char_parse(message
, length
, index
, '.');
542 mailimf_custom_string_parse(const char * message
, size_t length
,
543 size_t * index
, char ** result
,
544 int (* is_custom_char
)(char))
555 return MAILIMF_ERROR_PARSE
;
557 while (is_custom_char(message
[end
])) {
565 gstr = strndup(message + begin, end - begin);
567 gstr
= malloc(end
- begin
+ 1);
569 return MAILIMF_ERROR_MEMORY
;
570 strncpy(gstr
, message
+ begin
, end
- begin
);
571 gstr
[end
- begin
] = '\0';
575 return MAILIMF_NO_ERROR
;
578 return MAILIMF_ERROR_PARSE
;
587 typedef int mailimf_struct_parser(const char * message
, size_t length
,
588 size_t * index
, void * result
);
590 typedef int mailimf_struct_destructor(void * result
);
594 mailimf_struct_multiple_parse(const char * message
, size_t length
,
595 size_t * index
, clist
** result
,
596 mailimf_struct_parser
* parser
,
597 mailimf_struct_destructor
* destructor
)
607 r
= parser(message
, length
, &cur_token
, &value
);
608 if (r
!= MAILIMF_NO_ERROR
) {
613 struct_list
= clist_new();
614 if (struct_list
== NULL
) {
616 res
= MAILIMF_ERROR_MEMORY
;
620 r
= clist_append(struct_list
, value
);
623 res
= MAILIMF_ERROR_MEMORY
;
628 r
= parser(message
, length
, &cur_token
, &value
);
629 if (r
!= MAILIMF_NO_ERROR
) {
630 if (r
== MAILIMF_ERROR_PARSE
)
637 r
= clist_append(struct_list
, value
);
639 (* destructor
)(value
);
640 res
= MAILIMF_ERROR_MEMORY
;
645 * result
= struct_list
;
648 return MAILIMF_NO_ERROR
;
651 clist_foreach(struct_list
, (clist_func
) destructor
, NULL
);
652 clist_free(struct_list
);
660 mailimf_struct_list_parse(const char * message
, size_t length
,
661 size_t * index
, clist
** result
,
663 mailimf_struct_parser
* parser
,
664 mailimf_struct_destructor
* destructor
)
675 r
= parser(message
, length
, &cur_token
, &value
);
676 if (r
!= MAILIMF_NO_ERROR
) {
681 struct_list
= clist_new();
682 if (struct_list
== NULL
) {
684 res
= MAILIMF_ERROR_MEMORY
;
688 r
= clist_append(struct_list
, value
);
691 res
= MAILIMF_ERROR_MEMORY
;
695 final_token
= cur_token
;
698 r
= mailimf_unstrict_char_parse(message
, length
, &cur_token
, symbol
);
699 if (r
!= MAILIMF_NO_ERROR
) {
700 if (r
== MAILIMF_ERROR_PARSE
)
708 r
= parser(message
, length
, &cur_token
, &value
);
709 if (r
!= MAILIMF_NO_ERROR
) {
710 if (r
== MAILIMF_ERROR_PARSE
)
718 r
= clist_append(struct_list
, value
);
721 res
= MAILIMF_ERROR_MEMORY
;
725 final_token
= cur_token
;
728 * result
= struct_list
;
729 * index
= final_token
;
731 return MAILIMF_NO_ERROR
;
734 clist_foreach(struct_list
, (clist_func
) destructor
, NULL
);
735 clist_free(struct_list
);
740 static inline int mailimf_wsp_parse(const char * message
, size_t length
,
747 if (cur_token
>= length
)
748 return MAILIMF_ERROR_PARSE
;
750 if ((message
[cur_token
] != ' ') && (message
[cur_token
] != '\t'))
751 return MAILIMF_ERROR_PARSE
;
756 return MAILIMF_NO_ERROR
;
760 int mailimf_crlf_parse(const char * message
, size_t length
, size_t * index
)
767 r
= mailimf_char_parse(message
, length
, &cur_token
, '\r');
768 if ((r
!= MAILIMF_NO_ERROR
) && (r
!= MAILIMF_ERROR_PARSE
))
771 r
= mailimf_char_parse(message
, length
, &cur_token
, '\n');
772 if (r
!= MAILIMF_NO_ERROR
)
776 return MAILIMF_NO_ERROR
;
779 static int mailimf_unstrict_crlf_parse(const char * message
,
780 size_t length
, size_t * index
)
787 mailimf_cfws_parse(message
, length
, &cur_token
);
789 r
= mailimf_char_parse(message
, length
, &cur_token
, '\r');
790 if ((r
!= MAILIMF_NO_ERROR
) && (r
!= MAILIMF_ERROR_PARSE
))
793 r
= mailimf_char_parse(message
, length
, &cur_token
, '\n');
794 if (r
!= MAILIMF_NO_ERROR
)
798 return MAILIMF_NO_ERROR
;
801 /* ************************************************************************ */
805 /* RFC 2822 grammar */
808 NO-WS-CTL = %d1-8 / ; US-ASCII control characters
809 %d11 / ; that do not include the
810 %d12 / ; carriage return, line feed,
811 %d14-31 / ; and white space characters
815 static inline int is_no_ws_ctl(char ch
)
817 if ((ch
== 9) || (ch
== 10) || (ch
== 13))
823 return (ch
>= 1) && (ch
<= 31);
827 text = %d1-9 / ; Characters excluding CR and LF
835 specials = "(" / ")" / ; Special characters used in
836 "<" / ">" / ; other parts of the syntax
845 quoted-pair = ("\" text) / obs-qp
848 static inline int mailimf_quoted_pair_parse(const char * message
, size_t length
,
849 size_t * index
, char * result
)
855 if (cur_token
+ 1 >= length
)
856 return MAILIMF_ERROR_PARSE
;
858 if (message
[cur_token
] != '\\')
859 return MAILIMF_ERROR_PARSE
;
862 * result
= message
[cur_token
];
866 return MAILIMF_NO_ERROR
;
870 FWS = ([*WSP CRLF] 1*WSP) / ; Folding white space
874 int mailimf_fws_parse(const char * message
, size_t length
, size_t * index
)
887 r
= mailimf_wsp_parse(message
, length
, &cur_token
);
888 if (r
!= MAILIMF_NO_ERROR
) {
889 if (r
== MAILIMF_ERROR_PARSE
)
896 final_token
= cur_token
;
898 r
= mailimf_crlf_parse(message
, length
, &cur_token
);
900 case MAILIMF_NO_ERROR
:
903 case MAILIMF_ERROR_PARSE
:
913 r
= mailimf_wsp_parse(message
, length
, &cur_token
);
914 if (r
!= MAILIMF_NO_ERROR
) {
915 if (r
== MAILIMF_ERROR_PARSE
)
924 if ((!fws_1
) && (!fws_3
))
925 return MAILIMF_ERROR_PARSE
;
928 cur_token
= final_token
;
932 return MAILIMF_NO_ERROR
;
937 ctext = NO-WS-CTL / ; Non white space controls
939 %d33-39 / ; The rest of the US-ASCII
940 %d42-91 / ; characters not including "(",
941 %d93-126 ; ")", or "\"
944 static inline int is_ctext(char ch
)
946 unsigned char uch
= (unsigned char) ch
;
948 if (is_no_ws_ctl(ch
))
954 if ((uch
== 40) || (uch
== 41))
967 ccontent = ctext / quoted-pair / comment
970 static inline int mailimf_ccontent_parse(const char * message
, size_t length
,
979 if (cur_token
>= length
)
980 return MAILIMF_ERROR_PARSE
;
982 if (is_ctext(message
[cur_token
])) {
986 r
= mailimf_quoted_pair_parse(message
, length
, &cur_token
, &ch
);
988 if (r
== MAILIMF_ERROR_PARSE
)
989 r
= mailimf_comment_parse(message
, length
, &cur_token
);
991 if (r
== MAILIMF_ERROR_PARSE
)
997 return MAILIMF_NO_ERROR
;
1005 mailimf_comment_fws_ccontent_parse(const char * message
, size_t length
,
1011 cur_token
= * index
;
1013 r
= mailimf_fws_parse(message
, length
, &cur_token
);
1014 if ((r
!= MAILIMF_NO_ERROR
) && (r
!= MAILIMF_ERROR_PARSE
))
1017 r
= mailimf_ccontent_parse(message
, length
, &cur_token
);
1018 if (r
!= MAILIMF_NO_ERROR
)
1021 * index
= cur_token
;
1023 return MAILIMF_NO_ERROR
;
1027 comment = "(" *([FWS] ccontent) [FWS] ")"
1030 static inline int mailimf_comment_parse(const char * message
, size_t length
,
1036 cur_token
= * index
;
1038 r
= mailimf_oparenth_parse(message
, length
, &cur_token
);
1039 if (r
!= MAILIMF_NO_ERROR
)
1043 r
= mailimf_comment_fws_ccontent_parse(message
, length
, &cur_token
);
1044 if (r
!= MAILIMF_NO_ERROR
) {
1045 if (r
== MAILIMF_ERROR_PARSE
)
1052 r
= mailimf_fws_parse(message
, length
, &cur_token
);
1053 if ((r
!= MAILIMF_NO_ERROR
) && (r
!= MAILIMF_ERROR_PARSE
))
1056 r
= mailimf_cparenth_parse(message
, length
, &cur_token
);
1057 if (r
!= MAILIMF_NO_ERROR
)
1060 * index
= cur_token
;
1062 return MAILIMF_NO_ERROR
;
1069 static inline int mailimf_cfws_fws_comment_parse(const char * message
, size_t length
,
1075 cur_token
= * index
;
1077 r
= mailimf_fws_parse(message
, length
, &cur_token
);
1078 if ((r
!= MAILIMF_NO_ERROR
) && (r
!= MAILIMF_ERROR_PARSE
))
1081 r
= mailimf_comment_parse(message
, length
, &cur_token
);
1082 if (r
!= MAILIMF_NO_ERROR
)
1085 * index
= cur_token
;
1087 return MAILIMF_NO_ERROR
;
1091 CFWS = *([FWS] comment) (([FWS] comment) / FWS)
1094 int mailimf_cfws_parse(const char * message
, size_t length
,
1101 cur_token
= * index
;
1103 has_comment
= FALSE
;
1105 r
= mailimf_cfws_fws_comment_parse(message
, length
, &cur_token
);
1106 if (r
!= MAILIMF_NO_ERROR
) {
1107 if (r
== MAILIMF_ERROR_PARSE
)
1116 r
= mailimf_fws_parse(message
, length
, &cur_token
);
1117 if (r
!= MAILIMF_NO_ERROR
)
1121 * index
= cur_token
;
1123 return MAILIMF_NO_ERROR
;
1127 atext = ALPHA / DIGIT / ; Any character except controls,
1128 "!" / "#" / ; SP, and specials.
1129 "$" / "%" / ; Used for atoms
1140 static inline int is_atext(char ch
)
1167 atom = [CFWS] 1*atext [CFWS]
1170 int mailimf_atom_parse(const char * message
, size_t length
,
1171 size_t * index
, char ** result
)
1179 cur_token
= * index
;
1181 r
= mailimf_cfws_parse(message
, length
, &cur_token
);
1182 if ((r
!= MAILIMF_NO_ERROR
) && (r
!= MAILIMF_ERROR_PARSE
)) {
1188 if (end
>= length
) {
1189 res
= MAILIMF_ERROR_PARSE
;
1193 while (is_atext(message
[end
])) {
1198 if (end
== cur_token
) {
1199 res
= MAILIMF_ERROR_PARSE
;
1203 atom
= malloc(end
- cur_token
+ 1);
1205 res
= MAILIMF_ERROR_MEMORY
;
1208 strncpy(atom
, message
+ cur_token
, end
- cur_token
);
1209 atom
[end
- cur_token
] = '\0';
1213 * index
= cur_token
;
1216 return MAILIMF_NO_ERROR
;
1222 int mailimf_fws_atom_parse(const char * message
, size_t length
,
1223 size_t * index
, char ** result
)
1231 cur_token
= * index
;
1233 r
= mailimf_fws_parse(message
, length
, &cur_token
);
1234 if ((r
!= MAILIMF_NO_ERROR
) && (r
!= MAILIMF_ERROR_PARSE
)) {
1240 if (end
>= length
) {
1241 res
= MAILIMF_ERROR_PARSE
;
1245 while (is_atext(message
[end
])) {
1250 if (end
== cur_token
) {
1251 res
= MAILIMF_ERROR_PARSE
;
1255 atom
= malloc(end
- cur_token
+ 1);
1257 res
= MAILIMF_ERROR_MEMORY
;
1260 strncpy(atom
, message
+ cur_token
, end
- cur_token
);
1261 atom
[end
- cur_token
] = '\0';
1265 * index
= cur_token
;
1268 return MAILIMF_NO_ERROR
;
1275 dot-atom = [CFWS] dot-atom-text [CFWS]
1279 static int mailimf_dot_atom_parse(const char * message
, size_t length
,
1280 size_t * index
, char ** result
)
1282 return mailimf_atom_parse(message
, length
, index
, result
);
1287 dot-atom-text = 1*atext *("." 1*atext)
1292 mailimf_dot_atom_text_parse(const char * message
, size_t length
,
1293 size_t * index
, char ** result
)
1295 return mailimf_atom_parse(message
, length
, index
, result
);
1300 qtext = NO-WS-CTL / ; Non white space controls
1302 %d33 / ; The rest of the US-ASCII
1303 %d35-91 / ; characters not including "\"
1304 %d93-126 ; or the quote character
1307 static inline int is_qtext(char ch
)
1309 unsigned char uch
= (unsigned char) ch
;
1311 if (is_no_ws_ctl(ch
))
1330 qcontent = qtext / quoted-pair
1333 static int mailimf_qcontent_parse(const char * message
, size_t length
,
1334 size_t * index
, char * result
)
1340 cur_token
= * index
;
1342 if (cur_token
>= length
)
1343 return MAILIMF_ERROR_PARSE
;
1345 if (is_qtext(message
[cur_token
])) {
1346 ch
= message
[cur_token
];
1350 r
= mailimf_quoted_pair_parse(message
, length
, &cur_token
, &ch
);
1352 if (r
!= MAILIMF_NO_ERROR
)
1357 * index
= cur_token
;
1359 return MAILIMF_NO_ERROR
;
1363 quoted-string = [CFWS]
1364 DQUOTE *([FWS] qcontent) [FWS] DQUOTE
1368 int mailimf_quoted_string_parse(const char * message
, size_t length
,
1369 size_t * index
, char ** result
)
1378 cur_token
= * index
;
1380 r
= mailimf_cfws_parse(message
, length
, &cur_token
);
1381 if ((r
!= MAILIMF_NO_ERROR
) && (r
!= MAILIMF_ERROR_PARSE
)) {
1386 r
= mailimf_dquote_parse(message
, length
, &cur_token
);
1387 if (r
!= MAILIMF_NO_ERROR
) {
1392 gstr
= mmap_string_new("");
1394 res
= MAILIMF_ERROR_MEMORY
;
1399 if (mmap_string_append_c(gstr
, '\"') == NULL
) {
1400 res
= MAILIMF_ERROR_MEMORY
;
1406 r
= mailimf_fws_parse(message
, length
, &cur_token
);
1407 if (r
== MAILIMF_NO_ERROR
) {
1408 if (mmap_string_append_c(gstr
, ' ') == NULL
) {
1409 res
= MAILIMF_ERROR_MEMORY
;
1413 else if (r
!= MAILIMF_ERROR_PARSE
) {
1418 r
= mailimf_qcontent_parse(message
, length
, &cur_token
, &ch
);
1419 if (r
== MAILIMF_NO_ERROR
) {
1420 if (mmap_string_append_c(gstr
, ch
) == NULL
) {
1421 res
= MAILIMF_ERROR_MEMORY
;
1425 else if (r
== MAILIMF_ERROR_PARSE
)
1433 r
= mailimf_dquote_parse(message
, length
, &cur_token
);
1434 if (r
!= MAILIMF_NO_ERROR
) {
1440 if (mmap_string_append_c(gstr
, '\"') == NULL
) {
1441 res
= MAILIMF_ERROR_MEMORY
;
1446 str
= strdup(gstr
->str
);
1448 res
= MAILIMF_ERROR_MEMORY
;
1451 mmap_string_free(gstr
);
1453 * index
= cur_token
;
1456 return MAILIMF_NO_ERROR
;
1459 mmap_string_free(gstr
);
1464 int mailimf_fws_quoted_string_parse(const char * message
, size_t length
,
1465 size_t * index
, char ** result
)
1474 cur_token
= * index
;
1476 r
= mailimf_fws_parse(message
, length
, &cur_token
);
1477 if ((r
!= MAILIMF_NO_ERROR
) && (r
!= MAILIMF_ERROR_PARSE
)) {
1482 r
= mailimf_dquote_parse(message
, length
, &cur_token
);
1483 if (r
!= MAILIMF_NO_ERROR
) {
1488 gstr
= mmap_string_new("");
1490 res
= MAILIMF_ERROR_MEMORY
;
1495 if (mmap_string_append_c(gstr
, '\"') == NULL
) {
1496 res
= MAILIMF_ERROR_MEMORY
;
1502 r
= mailimf_fws_parse(message
, length
, &cur_token
);
1503 if (r
== MAILIMF_NO_ERROR
) {
1504 if (mmap_string_append_c(gstr
, ' ') == NULL
) {
1505 res
= MAILIMF_ERROR_MEMORY
;
1509 else if (r
!= MAILIMF_ERROR_PARSE
) {
1514 r
= mailimf_qcontent_parse(message
, length
, &cur_token
, &ch
);
1515 if (r
== MAILIMF_NO_ERROR
) {
1516 if (mmap_string_append_c(gstr
, ch
) == NULL
) {
1517 res
= MAILIMF_ERROR_MEMORY
;
1521 else if (r
== MAILIMF_ERROR_PARSE
)
1529 r
= mailimf_dquote_parse(message
, length
, &cur_token
);
1530 if (r
!= MAILIMF_NO_ERROR
) {
1536 if (mmap_string_append_c(gstr
, '\"') == NULL
) {
1537 res
= MAILIMF_ERROR_MEMORY
;
1542 str
= strdup(gstr
->str
);
1544 res
= MAILIMF_ERROR_MEMORY
;
1547 mmap_string_free(gstr
);
1549 * index
= cur_token
;
1552 return MAILIMF_NO_ERROR
;
1555 mmap_string_free(gstr
);
1561 word = atom / quoted-string
1564 int mailimf_word_parse(const char * message
, size_t length
,
1565 size_t * index
, char ** result
)
1571 cur_token
= * index
;
1573 r
= mailimf_atom_parse(message
, length
, &cur_token
, &word
);
1575 if (r
== MAILIMF_ERROR_PARSE
)
1576 r
= mailimf_quoted_string_parse(message
, length
, &cur_token
, &word
);
1578 if (r
!= MAILIMF_NO_ERROR
)
1582 * index
= cur_token
;
1584 return MAILIMF_NO_ERROR
;
1587 int mailimf_fws_word_parse(const char * message
, size_t length
,
1588 size_t * index
, char ** result
)
1594 cur_token
= * index
;
1596 r
= mailimf_fws_atom_parse(message
, length
, &cur_token
, &word
);
1598 if (r
== MAILIMF_ERROR_PARSE
)
1599 r
= mailimf_fws_quoted_string_parse(message
, length
, &cur_token
, &word
);
1601 if (r
!= MAILIMF_NO_ERROR
)
1605 * index
= cur_token
;
1607 return MAILIMF_NO_ERROR
;
1611 phrase = 1*word / obs-phrase
1614 static int mailimf_phrase_parse(const char * message
, size_t length
,
1615 size_t * index
, char ** result
)
1617 MMAPString
* gphrase
;
1625 cur_token
= * index
;
1627 gphrase
= mmap_string_new("");
1628 if (gphrase
== NULL
) {
1629 res
= MAILIMF_ERROR_MEMORY
;
1636 r
= mailimf_fws_word_parse(message
, length
, &cur_token
, &word
);
1637 if (r
== MAILIMF_NO_ERROR
) {
1639 if (mmap_string_append_c(gphrase
, ' ') == NULL
) {
1640 mailimf_word_free(word
);
1641 res
= MAILIMF_ERROR_MEMORY
;
1645 if (mmap_string_append(gphrase
, word
) == NULL
) {
1646 mailimf_word_free(word
);
1647 res
= MAILIMF_ERROR_MEMORY
;
1650 mailimf_word_free(word
);
1653 else if (r
== MAILIMF_ERROR_PARSE
)
1662 res
= MAILIMF_ERROR_PARSE
;
1666 str
= strdup(gphrase
->str
);
1668 res
= MAILIMF_ERROR_MEMORY
;
1671 mmap_string_free(gphrase
);
1674 * index
= cur_token
;
1676 return MAILIMF_NO_ERROR
;
1679 mmap_string_free(gphrase
);
1685 utext = NO-WS-CTL / ; Non white space controls
1686 %d33-126 / ; The rest of US-ASCII
1700 static int mailimf_unstructured_parse(const char * message
, size_t length
,
1701 size_t * index
, char ** result
)
1709 cur_token
= * index
;
1715 r
= mailimf_wsp_parse(message
, length
, &cur_token
);
1716 if (r
== MAILIMF_NO_ERROR
) {
1719 else if (r
== MAILIMF_ERROR_PARSE
)
1726 state
= UNSTRUCTURED_START
;
1728 terminal
= cur_token
;
1730 while (state
!= UNSTRUCTURED_OUT
) {
1733 case UNSTRUCTURED_START
:
1734 if (cur_token
>= length
)
1735 return MAILIMF_ERROR_PARSE
;
1737 terminal
= cur_token
;
1738 switch(message
[cur_token
]) {
1740 state
= UNSTRUCTURED_CR
;
1743 state
= UNSTRUCTURED_LF
;
1746 state
= UNSTRUCTURED_START
;
1750 case UNSTRUCTURED_CR
:
1751 if (cur_token
>= length
)
1752 return MAILIMF_ERROR_PARSE
;
1754 switch(message
[cur_token
]) {
1756 state
= UNSTRUCTURED_LF
;
1759 state
= UNSTRUCTURED_START
;
1764 case UNSTRUCTURED_LF
:
1765 if (cur_token
>= length
) {
1766 state
= UNSTRUCTURED_OUT
;
1770 switch(message
[cur_token
]) {
1773 state
= UNSTRUCTURED_WSP
;
1776 state
= UNSTRUCTURED_OUT
;
1780 case UNSTRUCTURED_WSP
:
1781 if (cur_token
>= length
)
1782 return MAILIMF_ERROR_PARSE
;
1784 switch(message
[cur_token
]) {
1786 state
= UNSTRUCTURED_CR
;
1789 state
= UNSTRUCTURED_LF
;
1792 state
= UNSTRUCTURED_START
;
1801 str
= malloc(terminal
- begin
+ 1);
1803 return MAILIMF_ERROR_MEMORY
;
1804 strncpy(str
, message
+ begin
, terminal
- begin
);
1805 str
[terminal
- begin
] = '\0';
1810 return MAILIMF_NO_ERROR
;
1814 static int mailimf_ignore_unstructured_parse(const char * message
, size_t length
,
1821 cur_token
= * index
;
1823 state
= UNSTRUCTURED_START
;
1824 terminal
= cur_token
;
1826 while (state
!= UNSTRUCTURED_OUT
) {
1829 case UNSTRUCTURED_START
:
1830 if (cur_token
>= length
)
1831 return MAILIMF_ERROR_PARSE
;
1832 terminal
= cur_token
;
1833 switch(message
[cur_token
]) {
1835 state
= UNSTRUCTURED_CR
;
1838 state
= UNSTRUCTURED_LF
;
1841 state
= UNSTRUCTURED_START
;
1845 case UNSTRUCTURED_CR
:
1846 if (cur_token
>= length
)
1847 return MAILIMF_ERROR_PARSE
;
1848 switch(message
[cur_token
]) {
1850 state
= UNSTRUCTURED_LF
;
1853 state
= UNSTRUCTURED_START
;
1857 case UNSTRUCTURED_LF
:
1858 if (cur_token
>= length
) {
1859 state
= UNSTRUCTURED_OUT
;
1862 switch(message
[cur_token
]) {
1865 state
= UNSTRUCTURED_WSP
;
1868 state
= UNSTRUCTURED_OUT
;
1872 case UNSTRUCTURED_WSP
:
1873 if (cur_token
>= length
)
1874 return MAILIMF_ERROR_PARSE
;
1875 switch(message
[cur_token
]) {
1877 state
= UNSTRUCTURED_CR
;
1880 state
= UNSTRUCTURED_LF
;
1883 state
= UNSTRUCTURED_START
;
1894 return MAILIMF_NO_ERROR
;
1898 int mailimf_ignore_field_parse(const char * message
, size_t length
,
1907 cur_token
= * index
;
1909 terminal
= cur_token
;
1910 state
= UNSTRUCTURED_START
;
1912 /* check if this is not a beginning CRLF */
1914 if (cur_token
>= length
)
1915 return MAILIMF_ERROR_PARSE
;
1917 switch (message
[cur_token
]) {
1919 return MAILIMF_ERROR_PARSE
;
1921 return MAILIMF_ERROR_PARSE
;
1924 while (state
!= UNSTRUCTURED_OUT
) {
1927 case UNSTRUCTURED_START
:
1928 if (cur_token
>= length
)
1929 return MAILIMF_ERROR_PARSE
;
1931 switch(message
[cur_token
]) {
1933 state
= UNSTRUCTURED_CR
;
1936 state
= UNSTRUCTURED_LF
;
1940 state
= UNSTRUCTURED_START
;
1943 state
= UNSTRUCTURED_START
;
1947 case UNSTRUCTURED_CR
:
1948 if (cur_token
>= length
)
1949 return MAILIMF_ERROR_PARSE
;
1951 switch(message
[cur_token
]) {
1953 state
= UNSTRUCTURED_LF
;
1957 state
= UNSTRUCTURED_START
;
1960 state
= UNSTRUCTURED_START
;
1964 case UNSTRUCTURED_LF
:
1965 if (cur_token
>= length
) {
1966 terminal
= cur_token
;
1967 state
= UNSTRUCTURED_OUT
;
1971 switch(message
[cur_token
]) {
1974 state
= UNSTRUCTURED_WSP
;
1977 terminal
= cur_token
;
1978 state
= UNSTRUCTURED_OUT
;
1982 case UNSTRUCTURED_WSP
:
1983 if (cur_token
>= length
)
1984 return MAILIMF_ERROR_PARSE
;
1986 switch(message
[cur_token
]) {
1988 state
= UNSTRUCTURED_CR
;
1991 state
= UNSTRUCTURED_LF
;
1995 state
= UNSTRUCTURED_START
;
1998 state
= UNSTRUCTURED_START
;
2008 return MAILIMF_ERROR_PARSE
;
2012 return MAILIMF_NO_ERROR
;
2017 date-time = [ day-of-week "," ] date FWS time [CFWS]
2020 int mailimf_date_time_parse(const char * message
, size_t length
,
2022 struct mailimf_date_time
** result
)
2026 struct mailimf_date_time
* date_time
;
2036 cur_token
= * index
;
2039 r
= mailimf_day_of_week_parse(message
, length
, &cur_token
, &day_of_week
);
2040 if (r
== MAILIMF_NO_ERROR
) {
2041 r
= mailimf_comma_parse(message
, length
, &cur_token
);
2042 if (r
!= MAILIMF_NO_ERROR
)
2045 else if (r
!= MAILIMF_ERROR_PARSE
)
2048 r
= mailimf_date_parse(message
, length
, &cur_token
, &day
, &month
, &year
);
2049 if (r
!= MAILIMF_NO_ERROR
)
2052 r
= mailimf_fws_parse(message
, length
, &cur_token
);
2053 if (r
!= MAILIMF_NO_ERROR
)
2056 r
= mailimf_time_parse(message
, length
, &cur_token
,
2057 &hour
, &min
, &sec
, &zone
);
2058 if (r
!= MAILIMF_NO_ERROR
)
2061 date_time
= mailimf_date_time_new(day
, month
, year
, hour
, min
, sec
, zone
);
2062 if (date_time
== NULL
)
2063 return MAILIMF_ERROR_MEMORY
;
2065 * index
= cur_token
;
2066 * result
= date_time
;
2068 return MAILIMF_NO_ERROR
;
2072 day-of-week = ([FWS] day-name) / obs-day-of-week
2075 static int mailimf_day_of_week_parse(const char * message
, size_t length
,
2076 size_t * index
, int * result
)
2082 cur_token
= * index
;
2084 r
= mailimf_cfws_parse(message
, length
, &cur_token
);
2085 if ((r
!= MAILIMF_NO_ERROR
) && (r
!= MAILIMF_ERROR_PARSE
))
2088 r
= mailimf_day_name_parse(message
, length
, &cur_token
, &day_of_week
);
2089 if (r
!= MAILIMF_NO_ERROR
)
2092 * index
= cur_token
;
2093 * result
= day_of_week
;
2095 return MAILIMF_NO_ERROR
;
2099 day-name = "Mon" / "Tue" / "Wed" / "Thu" /
2100 "Fri" / "Sat" / "Sun"
2103 struct mailimf_token_value
{
2108 static struct mailimf_token_value day_names
[] = {
2124 static int guess_day_name(const char * message
, size_t length
, size_t index
)
2128 state
= DAY_NAME_START
;
2132 if (index
>= length
)
2136 case DAY_NAME_START
:
2137 switch((char) toupper((unsigned char) message
[index
])) {
2141 case 'T': /* Tue Thu */
2148 case 'S': /* Sat Sun */
2156 switch((char) toupper((unsigned char) message
[index
])) {
2166 switch((char) toupper((unsigned char) message
[index
])) {
2181 static int mailimf_day_name_parse(const char * message
, size_t length
,
2182 size_t * index
, int * result
)
2189 cur_token
= * index
;
2191 guessed_day
= guess_day_name(message
, length
, cur_token
);
2192 if (guessed_day
== -1)
2193 return MAILIMF_ERROR_PARSE
;
2195 r
= mailimf_token_case_insensitive_parse(message
, length
,
2197 day_names
[guessed_day
- 1].str
);
2198 if (r
!= MAILIMF_NO_ERROR
)
2201 day_of_week
= guessed_day
;
2203 * result
= day_of_week
;
2204 * index
= cur_token
;
2206 return MAILIMF_NO_ERROR
;
2210 date = day month year
2213 static int mailimf_date_parse(const char * message
, size_t length
,
2215 int * pday
, int * pmonth
, int * pyear
)
2223 cur_token
= * index
;
2225 r
= mailimf_day_parse(message
, length
, &cur_token
, &day
);
2226 if (r
!= MAILIMF_NO_ERROR
)
2229 r
= mailimf_month_parse(message
, length
, &cur_token
, &month
);
2230 if (r
!= MAILIMF_NO_ERROR
)
2233 r
= mailimf_year_parse(message
, length
, &cur_token
, &year
);
2234 if (r
!= MAILIMF_NO_ERROR
)
2241 * index
= cur_token
;
2243 return MAILIMF_NO_ERROR
;
2247 year = 4*DIGIT / obs-year
2250 static int mailimf_year_parse(const char * message
, size_t length
,
2251 size_t * index
, int * result
)
2257 cur_token
= * index
;
2259 r
= mailimf_cfws_parse(message
, length
, &cur_token
);
2260 if ((r
!= MAILIMF_NO_ERROR
) && (r
!= MAILIMF_ERROR_PARSE
))
2263 r
= mailimf_number_parse(message
, length
, &cur_token
, &number
);
2264 if (r
!= MAILIMF_NO_ERROR
)
2267 * index
= cur_token
;
2270 return MAILIMF_NO_ERROR
;
2274 month = (FWS month-name FWS) / obs-month
2277 static int mailimf_month_parse(const char * message
, size_t length
,
2278 size_t * index
, int * result
)
2284 cur_token
= * index
;
2286 r
= mailimf_cfws_parse(message
, length
, &cur_token
);
2287 if ((r
!= MAILIMF_NO_ERROR
) && (r
!= MAILIMF_ERROR_PARSE
))
2290 r
= mailimf_month_name_parse(message
, length
, &cur_token
, &month
);
2291 if (r
!= MAILIMF_NO_ERROR
)
2295 * index
= cur_token
;
2297 return MAILIMF_NO_ERROR
;
2301 month-name = "Jan" / "Feb" / "Mar" / "Apr" /
2302 "May" / "Jun" / "Jul" / "Aug" /
2303 "Sep" / "Oct" / "Nov" / "Dec"
2306 static struct mailimf_token_value month_names
[] = {
2330 static int guess_month(const char * message
, size_t length
, size_t index
)
2334 state
= MONTH_START
;
2338 if (index
>= length
)
2343 switch((char) toupper((unsigned char) message
[index
])) {
2344 case 'J': /* Jan Jun Jul */
2349 case 'M': /* Mar May */
2352 case 'A': /* Apr Aug */
2368 switch((char) toupper((unsigned char) message
[index
])) {
2379 switch((char) toupper((unsigned char) message
[index
])) {
2389 switch((char) toupper((unsigned char) message
[index
])) {
2398 switch((char) toupper((unsigned char) message
[index
])) {
2408 switch((char) toupper((unsigned char) message
[index
])) {
2423 static int mailimf_month_name_parse(const char * message
, size_t length
,
2424 size_t * index
, int * result
)
2431 cur_token
= * index
;
2433 guessed_month
= guess_month(message
, length
, cur_token
);
2434 if (guessed_month
== -1)
2435 return MAILIMF_ERROR_PARSE
;
2437 r
= mailimf_token_case_insensitive_parse(message
, length
,
2439 month_names
[guessed_month
- 1].str
);
2440 if (r
!= MAILIMF_NO_ERROR
)
2443 month
= guessed_month
;
2446 * index
= cur_token
;
2448 return MAILIMF_NO_ERROR
;
2452 day = ([FWS] 1*2DIGIT) / obs-day
2455 static int mailimf_day_parse(const char * message
, size_t length
,
2456 size_t * index
, int * result
)
2462 cur_token
= * index
;
2464 r
= mailimf_cfws_parse(message
, length
, &cur_token
);
2465 if ((r
!= MAILIMF_NO_ERROR
) && (r
!= MAILIMF_ERROR_PARSE
))
2468 r
= mailimf_number_parse(message
, length
, &cur_token
, &day
);
2469 if (r
!= MAILIMF_NO_ERROR
)
2473 * index
= cur_token
;
2475 return MAILIMF_NO_ERROR
;
2479 time = time-of-day FWS zone
2482 static int mailimf_time_parse(const char * message
, size_t length
,
2484 int * phour
, int * pmin
,
2495 cur_token
= * index
;
2497 r
= mailimf_cfws_parse(message
, length
, &cur_token
);
2498 if ((r
!= MAILIMF_NO_ERROR
) && (r
!= MAILIMF_ERROR_PARSE
))
2501 r
= mailimf_time_of_day_parse(message
, length
, &cur_token
,
2503 if (r
!= MAILIMF_NO_ERROR
)
2506 r
= mailimf_fws_parse(message
, length
, &cur_token
);
2507 if ((r
!= MAILIMF_NO_ERROR
) && (r
!= MAILIMF_ERROR_PARSE
))
2510 r
= mailimf_zone_parse(message
, length
, &cur_token
, &zone
);
2511 if (r
== MAILIMF_NO_ERROR
) {
2514 else if (r
== MAILIMF_ERROR_PARSE
) {
2526 * index
= cur_token
;
2528 return MAILIMF_NO_ERROR
;
2532 time-of-day = hour ":" minute [ ":" second ]
2535 static int mailimf_time_of_day_parse(const char * message
, size_t length
,
2537 int * phour
, int * pmin
,
2546 cur_token
= * index
;
2548 r
= mailimf_hour_parse(message
, length
, &cur_token
, &hour
);
2549 if (r
!= MAILIMF_NO_ERROR
)
2552 r
= mailimf_colon_parse(message
, length
, &cur_token
);
2553 if (r
!= MAILIMF_NO_ERROR
)
2556 r
= mailimf_minute_parse(message
, length
, &cur_token
, &min
);
2557 if (r
!= MAILIMF_NO_ERROR
)
2560 r
= mailimf_colon_parse(message
, length
, &cur_token
);
2561 if (r
== MAILIMF_NO_ERROR
) {
2562 r
= mailimf_second_parse(message
, length
, &cur_token
, &sec
);
2563 if (r
!= MAILIMF_NO_ERROR
)
2566 else if (r
== MAILIMF_ERROR_PARSE
)
2574 * index
= cur_token
;
2576 return MAILIMF_NO_ERROR
;
2580 hour = 2DIGIT / obs-hour
2583 static int mailimf_hour_parse(const char * message
, size_t length
,
2584 size_t * index
, int * result
)
2589 r
= mailimf_number_parse(message
, length
, index
, &hour
);
2590 if (r
!= MAILIMF_NO_ERROR
)
2595 return MAILIMF_NO_ERROR
;
2599 minute = 2DIGIT / obs-minute
2602 static int mailimf_minute_parse(const char * message
, size_t length
,
2603 size_t * index
, int * result
)
2608 r
= mailimf_number_parse(message
, length
, index
, &minute
);
2609 if (r
!= MAILIMF_NO_ERROR
)
2614 return MAILIMF_NO_ERROR
;
2618 second = 2DIGIT / obs-second
2621 static int mailimf_second_parse(const char * message
, size_t length
,
2622 size_t * index
, int * result
)
2627 r
= mailimf_number_parse(message
, length
, index
, &second
);
2628 if (r
!= MAILIMF_NO_ERROR
)
2633 return MAILIMF_NO_ERROR
;
2637 zone = (( "+" / "-" ) 4DIGIT) / obs-zone
2641 obs-zone = "UT" / "GMT" / ; Universal Time
2644 "EST" / "EDT" / ; Eastern: - 5/ - 4
2645 "CST" / "CDT" / ; Central: - 6/ - 5
2646 "MST" / "MDT" / ; Mountain: - 7/ - 6
2647 "PST" / "PDT" / ; Pacific: - 8/ - 7
2649 %d65-73 / ; Military zones - "A"
2650 %d75-90 / ; through "I" and "K"
2651 %d97-105 / ; through "Z", both
2652 %d107-122 ; upper and lower case
2661 STATE_ZONE_CONT
= 5,
2664 static int mailimf_zone_parse(const char * message
, size_t length
,
2665 size_t * index
, int * result
)
2672 cur_token
= * index
;
2674 if (cur_token
+ 1 < length
) {
2675 if ((message
[cur_token
] == 'U') && (message
[cur_token
+ 1] == 'T')) {
2677 * index
= cur_token
+ 2;
2679 return MAILIMF_NO_ERROR
;
2683 if (cur_token
+ 2 < length
) {
2686 state
= STATE_ZONE_1
;
2688 while (state
<= 2) {
2691 switch (message
[cur_token
]) {
2693 if (message
[cur_token
+ 1] == 'M' && message
[cur_token
+ 2] == 'T') {
2695 state
= STATE_ZONE_OK
;
2698 state
= STATE_ZONE_ERR
;
2703 state
= STATE_ZONE_2
;
2707 state
= STATE_ZONE_2
;
2711 state
= STATE_ZONE_2
;
2715 state
= STATE_ZONE_2
;
2718 state
= STATE_ZONE_CONT
;
2723 switch (message
[cur_token
+ 1]) {
2725 state
= STATE_ZONE_3
;
2729 state
= STATE_ZONE_3
;
2732 state
= STATE_ZONE_ERR
;
2737 if (message
[cur_token
+ 2] == 'T') {
2739 state
= STATE_ZONE_OK
;
2742 state
= STATE_ZONE_ERR
;
2750 * index
= cur_token
+ 3;
2751 return MAILIMF_NO_ERROR
;
2753 case STATE_ZONE_ERR
:
2754 return MAILIMF_ERROR_PARSE
;
2759 r
= mailimf_plus_parse(message
, length
, &cur_token
);
2760 if (r
== MAILIMF_NO_ERROR
)
2763 if (r
== MAILIMF_ERROR_PARSE
) {
2764 r
= mailimf_minus_parse(message
, length
, &cur_token
);
2765 if (r
== MAILIMF_NO_ERROR
)
2769 if (r
== MAILIMF_NO_ERROR
) {
2772 else if (r
== MAILIMF_ERROR_PARSE
)
2777 r
= mailimf_number_parse(message
, length
, &cur_token
, &zone
);
2778 if (r
!= MAILIMF_NO_ERROR
)
2783 * index
= cur_token
;
2786 return MAILIMF_NO_ERROR
;
2790 address = mailbox / group
2793 int mailimf_address_parse(const char * message
, size_t length
,
2795 struct mailimf_address
** result
)
2799 struct mailimf_mailbox
* mailbox
;
2800 struct mailimf_group
* group
;
2801 struct mailimf_address
* address
;
2805 cur_token
= * index
;
2810 type
= MAILIMF_ADDRESS_ERROR
; /* XXX - removes a gcc warning */
2811 r
= mailimf_group_parse(message
, length
, &cur_token
, &group
);
2812 if (r
== MAILIMF_NO_ERROR
)
2813 type
= MAILIMF_ADDRESS_GROUP
;
2815 if (r
== MAILIMF_ERROR_PARSE
) {
2816 r
= mailimf_mailbox_parse(message
, length
, &cur_token
, &mailbox
);
2817 if (r
== MAILIMF_NO_ERROR
)
2818 type
= MAILIMF_ADDRESS_MAILBOX
;
2821 if (r
!= MAILIMF_NO_ERROR
) {
2826 address
= mailimf_address_new(type
, mailbox
, group
);
2827 if (address
== NULL
) {
2828 res
= MAILIMF_ERROR_MEMORY
;
2833 * index
= cur_token
;
2835 return MAILIMF_NO_ERROR
;
2838 if (mailbox
!= NULL
)
2839 mailimf_mailbox_free(mailbox
);
2841 mailimf_group_free(group
);
2848 mailbox = name-addr / addr-spec
2852 int mailimf_mailbox_parse(const char * message
, size_t length
,
2854 struct mailimf_mailbox
** result
)
2857 char * display_name
;
2858 struct mailimf_mailbox
* mailbox
;
2863 cur_token
= * index
;
2864 display_name
= NULL
;
2867 r
= mailimf_name_addr_parse(message
, length
, &cur_token
,
2868 &display_name
, &addr_spec
);
2869 if (r
== MAILIMF_ERROR_PARSE
)
2870 r
= mailimf_addr_spec_parse(message
, length
, &cur_token
, &addr_spec
);
2872 if (r
!= MAILIMF_NO_ERROR
) {
2877 mailbox
= mailimf_mailbox_new(display_name
, addr_spec
);
2878 if (mailbox
== NULL
) {
2879 res
= MAILIMF_ERROR_MEMORY
;
2884 * index
= cur_token
;
2886 return MAILIMF_NO_ERROR
;
2889 if (display_name
!= NULL
)
2890 mailimf_display_name_free(display_name
);
2891 if (addr_spec
!= NULL
)
2892 mailimf_addr_spec_free(addr_spec
);
2898 name-addr = [display-name] angle-addr
2901 static int mailimf_name_addr_parse(const char * message
, size_t length
,
2903 char ** pdisplay_name
,
2904 char ** pangle_addr
)
2906 char * display_name
;
2912 cur_token
= * index
;
2914 display_name
= NULL
;
2917 r
= mailimf_display_name_parse(message
, length
, &cur_token
, &display_name
);
2918 if ((r
!= MAILIMF_NO_ERROR
) && (r
!= MAILIMF_ERROR_PARSE
)) {
2923 r
= mailimf_angle_addr_parse(message
, length
, &cur_token
, &angle_addr
);
2924 if (r
!= MAILIMF_NO_ERROR
) {
2926 goto free_display_name
;
2929 * pdisplay_name
= display_name
;
2930 * pangle_addr
= angle_addr
;
2931 * index
= cur_token
;
2933 return MAILIMF_NO_ERROR
;
2936 if (display_name
!= NULL
)
2937 mailimf_display_name_free(display_name
);
2943 angle-addr = [CFWS] "<" addr-spec ">" [CFWS] / obs-angle-addr
2946 static int mailimf_angle_addr_parse(const char * message
, size_t length
,
2947 size_t * index
, char ** result
)
2953 cur_token
= * index
;
2955 r
= mailimf_cfws_parse(message
, length
, &cur_token
);
2956 if ((r
!= MAILIMF_NO_ERROR
) && (r
!= MAILIMF_ERROR_PARSE
))
2959 r
= mailimf_lower_parse(message
, length
, &cur_token
);
2960 if (r
!= MAILIMF_NO_ERROR
)
2963 r
= mailimf_addr_spec_parse(message
, length
, &cur_token
, &addr_spec
);
2964 if (r
!= MAILIMF_NO_ERROR
)
2967 r
= mailimf_greater_parse(message
, length
, &cur_token
);
2968 if (r
!= MAILIMF_NO_ERROR
) {
2973 * result
= addr_spec
;
2974 * index
= cur_token
;
2976 return MAILIMF_NO_ERROR
;
2980 group = display-name ":" [mailbox-list / CFWS] ";"
2984 static int mailimf_group_parse(const char * message
, size_t length
,
2986 struct mailimf_group
** result
)
2989 char * display_name
;
2990 struct mailimf_mailbox_list
* mailbox_list
;
2991 struct mailimf_group
* group
;
2996 cur_token
= * index
;
2998 mailbox_list
= NULL
;
3000 r
= mailimf_display_name_parse(message
, length
, &cur_token
, &display_name
);
3001 if (r
!= MAILIMF_NO_ERROR
) {
3006 r
= mailimf_colon_parse(message
, length
, &cur_token
);
3007 if (r
!= MAILIMF_NO_ERROR
) {
3009 goto free_display_name
;
3012 r
= mailimf_mailbox_list_parse(message
, length
, &cur_token
, &mailbox_list
);
3014 case MAILIMF_NO_ERROR
:
3016 case MAILIMF_ERROR_PARSE
:
3017 r
= mailimf_cfws_parse(message
, length
, &cur_token
);
3018 if ((r
!= MAILIMF_NO_ERROR
) && (r
!= MAILIMF_ERROR_PARSE
)) {
3020 goto free_display_name
;
3024 res
= MAILIMF_ERROR_MEMORY
;
3025 goto free_display_name
;
3027 mailbox_list
= mailimf_mailbox_list_new(list
);
3028 if (mailbox_list
== NULL
) {
3029 res
= MAILIMF_ERROR_MEMORY
;
3031 goto free_display_name
;
3036 goto free_display_name
;
3039 r
= mailimf_semi_colon_parse(message
, length
, &cur_token
);
3040 if (r
!= MAILIMF_NO_ERROR
) {
3042 goto free_mailbox_list
;
3045 group
= mailimf_group_new(display_name
, mailbox_list
);
3046 if (group
== NULL
) {
3047 res
= MAILIMF_ERROR_MEMORY
;
3048 goto free_mailbox_list
;
3051 * index
= cur_token
;
3054 return MAILIMF_NO_ERROR
;
3057 mailimf_mailbox_list_free(mailbox_list
);
3059 mailimf_display_name_free(display_name
);
3065 display-name = phrase
3068 static int mailimf_display_name_parse(const char * message
, size_t length
,
3069 size_t * index
, char ** result
)
3071 return mailimf_phrase_parse(message
, length
, index
, result
);
3075 mailbox-list = (mailbox *("," mailbox)) / obs-mbox-list
3079 mailimf_mailbox_list_parse(const char * message
, size_t length
,
3081 struct mailimf_mailbox_list
** result
)
3085 struct mailimf_mailbox_list
* mailbox_list
;
3089 cur_token
= * index
;
3091 r
= mailimf_struct_list_parse(message
, length
,
3092 &cur_token
, &list
, ',',
3093 (mailimf_struct_parser
*)
3094 mailimf_mailbox_parse
,
3095 (mailimf_struct_destructor
*)
3096 mailimf_mailbox_free
);
3097 if (r
!= MAILIMF_NO_ERROR
) {
3102 mailbox_list
= mailimf_mailbox_list_new(list
);
3103 if (mailbox_list
== NULL
) {
3104 res
= MAILIMF_ERROR_MEMORY
;
3108 * result
= mailbox_list
;
3109 * index
= cur_token
;
3111 return MAILIMF_NO_ERROR
;
3114 clist_foreach(list
, (clist_func
) mailimf_mailbox_free
, NULL
);
3121 address-list = (address *("," address)) / obs-addr-list
3126 mailimf_address_list_parse(const char * message
, size_t length
,
3128 struct mailimf_address_list
** result
)
3132 struct mailimf_address_list
* address_list
;
3136 cur_token
= * index
;
3138 r
= mailimf_struct_list_parse(message
, length
,
3139 &cur_token
, &list
, ',',
3140 (mailimf_struct_parser
*)
3141 mailimf_address_parse
,
3142 (mailimf_struct_destructor
*)
3143 mailimf_address_free
);
3144 if (r
!= MAILIMF_NO_ERROR
) {
3149 address_list
= mailimf_address_list_new(list
);
3150 if (address_list
== NULL
) {
3151 res
= MAILIMF_ERROR_MEMORY
;
3155 * result
= address_list
;
3156 * index
= cur_token
;
3158 return MAILIMF_NO_ERROR
;
3161 clist_foreach(list
, (clist_func
) mailimf_address_free
, NULL
);
3168 addr-spec = local-part "@" domain
3172 static int mailimf_addr_spec_parse(const char * message
, size_t length
,
3192 cur_token
= * index
;
3194 r
= mailimf_cfws_parse(message
, length
, &cur_token
);
3195 if ((r
!= MAILIMF_NO_ERROR
) && (r
!= MAILIMF_ERROR_PARSE
)) {
3201 if (end
>= length
) {
3202 res
= MAILIMF_ERROR_PARSE
;
3210 switch (message
[end
]) {
3232 res
= MAILIMF_ERROR_PARSE
;
3236 addr_spec
= malloc(end
- cur_token
+ 1);
3237 if (addr_spec
== NULL
) {
3238 res
= MAILIMF_ERROR_MEMORY
;
3242 count
= end
- cur_token
;
3243 src
= message
+ cur_token
;
3245 for(i
= 0 ; i
< count
; i
++) {
3246 if ((* src
!= ' ') && (* src
!= '\t')) {
3255 strncpy(addr_spec
, message
+ cur_token
, end
- cur_token
);
3256 addr_spec
[end
- cur_token
] = '\0';
3262 r
= mailimf_local_part_parse(message
, length
, &cur_token
, &local_part
);
3263 if (r
!= MAILIMF_NO_ERROR
) {
3268 r
= mailimf_at_sign_parse(message
, length
, &cur_token
);
3270 case MAILIMF_NO_ERROR
:
3271 r
= mailimf_domain_parse(message
, length
, &cur_token
, &domain
);
3272 if (r
!= MAILIMF_NO_ERROR
) {
3274 goto free_local_part
;
3278 case MAILIMF_ERROR_PARSE
:
3284 goto free_local_part
;
3288 addr_spec
= malloc(strlen(local_part
) + strlen(domain
) + 2);
3289 if (addr_spec
== NULL
) {
3290 res
= MAILIMF_ERROR_MEMORY
;
3294 strcpy(addr_spec
, local_part
);
3295 strcat(addr_spec
, "@");
3296 strcat(addr_spec
, domain
);
3298 mailimf_domain_free(domain
);
3299 mailimf_local_part_free(local_part
);
3302 addr_spec
= local_part
;
3306 * result
= addr_spec
;
3307 * index
= cur_token
;
3309 return MAILIMF_NO_ERROR
;
3313 mailimf_domain_free(domain
);
3315 mailimf_local_part_free(local_part
);
3322 local-part = dot-atom / quoted-string / obs-local-part
3326 static int mailimf_local_part_parse(const char * message
, size_t length
,
3332 r
= mailimf_dot_atom_parse(message
, length
, index
, result
);
3334 case MAILIMF_NO_ERROR
:
3336 case MAILIMF_ERROR_PARSE
:
3342 r
= mailimf_quoted_string_parse(message
, length
, index
, result
);
3343 if (r
!= MAILIMF_NO_ERROR
)
3346 return MAILIMF_NO_ERROR
;
3351 domain = dot-atom / domain-literal / obs-domain
3355 static int mailimf_domain_parse(const char * message
, size_t length
,
3361 r
= mailimf_dot_atom_parse(message
, length
, index
, result
);
3363 case MAILIMF_NO_ERROR
:
3365 case MAILIMF_ERROR_PARSE
:
3371 r
= mailimf_domain_literal_parse(message
, length
, index
, result
);
3372 if (r
!= MAILIMF_NO_ERROR
)
3375 return MAILIMF_NO_ERROR
;
3385 mailimf_domain_literal_fws_dcontent_parse(const char * message
, size_t length
,
3392 cur_token
= * index
;
3394 r
= mailimf_cfws_parse(message
, length
, &cur_token
);
3395 if ((r
!= MAILIMF_NO_ERROR
) && (r
!= MAILIMF_ERROR_PARSE
))
3398 r
= mailimf_dcontent_parse(message
, length
, &cur_token
, &ch
);
3399 if (r
!= MAILIMF_NO_ERROR
)
3402 * index
= cur_token
;
3404 return MAILIMF_NO_ERROR
;
3409 domain-literal = [CFWS] "[" *([FWS] dcontent) [FWS] "]" [CFWS]
3413 static int mailimf_domain_literal_parse(const char * message
, size_t length
,
3414 size_t * index
, char ** result
)
3419 char * domain_literal
;
3422 cur_token
= * index
;
3424 r
= mailimf_cfws_parse(message
, length
, &cur_token
);
3425 if ((r
!= MAILIMF_NO_ERROR
) && (r
!= MAILIMF_ERROR_PARSE
))
3429 r
= mailimf_obracket_parse(message
, length
, &cur_token
);
3430 if (r
!= MAILIMF_NO_ERROR
)
3434 r
= mailimf_domain_literal_fws_dcontent_parse(message
, length
,
3436 if (r
== MAILIMF_NO_ERROR
) {
3439 else if (r
== MAILIMF_ERROR_PARSE
)
3445 r
= mailimf_fws_parse(message
, length
, &cur_token
);
3446 if ((r
!= MAILIMF_NO_ERROR
) && (r
!= MAILIMF_ERROR_PARSE
))
3449 r
= mailimf_cbracket_parse(message
, length
, &cur_token
);
3450 if (r
!= MAILIMF_NO_ERROR
)
3453 len
= cur_token
- begin
;
3455 domain_literal
= malloc(len
+ 1);
3456 if (domain_literal
== NULL
)
3457 return MAILIMF_ERROR_MEMORY
;
3458 strncpy(domain_literal
, message
+ begin
, len
);
3459 domain_literal
[len
] = '\0';
3461 * result
= domain_literal
;
3462 * index
= cur_token
;
3464 return MAILIMF_NO_ERROR
;
3469 dcontent = dtext / quoted-pair
3473 static int mailimf_dcontent_parse(const char * message
, size_t length
,
3474 size_t * index
, char * result
)
3480 cur_token
= * index
;
3482 if (cur_token
>= length
)
3483 return MAILIMF_ERROR_PARSE
;
3485 if (is_dtext(message
[cur_token
])) {
3486 ch
= message
[cur_token
];
3490 r
= mailimf_quoted_pair_parse(message
, length
, &cur_token
, &ch
);
3492 if (r
!= MAILIMF_NO_ERROR
)
3496 * index
= cur_token
;
3499 return MAILIMF_NO_ERROR
;
3505 dtext = NO-WS-CTL / ; Non white space controls
3507 %d33-90 / ; The rest of the US-ASCII
3508 %d94-126 ; characters not including "[",
3513 static inline int is_dtext(char ch
)
3515 unsigned char uch
= (unsigned char) ch
;
3517 if (is_no_ws_ctl(ch
))
3523 if ((uch
>= 91) && (uch
<= 93))
3534 message = (fields / obs-fields)
3538 int mailimf_message_parse(const char * message
, size_t length
,
3540 struct mailimf_message
** result
)
3542 struct mailimf_fields
* fields
;
3543 struct mailimf_body
* body
;
3544 struct mailimf_message
* msg
;
3549 cur_token
= * index
;
3551 r
= mailimf_fields_parse(message
, length
, &cur_token
, &fields
);
3552 if (r
!= MAILIMF_NO_ERROR
) {
3557 r
= mailimf_crlf_parse(message
, length
, &cur_token
);
3558 if ((r
!= MAILIMF_NO_ERROR
) && (r
!= MAILIMF_ERROR_PARSE
)) {
3563 r
= mailimf_body_parse(message
, length
, &cur_token
, &body
);
3564 if (r
!= MAILIMF_NO_ERROR
) {
3569 msg
= mailimf_message_new(fields
, body
);
3571 res
= MAILIMF_ERROR_MEMORY
;
3575 * index
= cur_token
;
3578 return MAILIMF_NO_ERROR
;
3581 mailimf_body_free(body
);
3583 mailimf_fields_free(fields
);
3589 body = *(*998text CRLF) *998text
3592 int mailimf_body_parse(const char * message
, size_t length
,
3594 struct mailimf_body
** result
)
3597 struct mailimf_body
* body
;
3599 cur_token
= * index
;
3601 body
= mailimf_body_new(message
+ cur_token
, length
- cur_token
);
3603 return MAILIMF_ERROR_MEMORY
;
3608 * index
= cur_token
;
3610 return MAILIMF_NO_ERROR
;
3614 CHANGE TO THE RFC 2822
3641 INTO THE FOLLOWING :
3645 resent-fields-list = *(resent-date /
3656 RESENT_HEADER_START
,
3659 static int guess_resent_header_type(char * message
,
3660 size_t length
, size_t index
)
3664 r
= mailimf_token_case_insensitive_parse(message
,
3665 length
, &index
, "Resent-");
3666 if (r
!= MAILIMF_NO_ERROR
)
3667 return MAILIMF_RESENT_FIELD_NONE
;
3669 if (index
>= length
)
3670 return MAILIMF_RESENT_FIELD_NONE
;
3672 switch(toupper(message
[index
])) {
3674 return MAILIMF_RESENT_FIELD_DATE
;
3676 return MAILIMF_RESENT_FIELD_FROM
;
3678 return MAILIMF_RESENT_FIELD_SENDER
;
3680 return MAILIMF_RESENT_FIELD_TO
;
3682 return MAILIMF_RESENT_FIELD_CC
;
3684 return MAILIMF_RESENT_FIELD_BCC
;
3686 return MAILIMF_RESENT_FIELD_MSG_ID
;
3688 return MAILIMF_RESENT_FIELD_NONE
;
3695 mailimf_resent_field_parse(const char * message
, size_t length
,
3697 struct mailimf_resent_field
** result
)
3699 struct mailimf_orig_date
* resent_date
;
3700 struct mailimf_from
* resent_from
;
3701 struct mailimf_sender
* resent_sender
;
3702 struct mailimf_to
* resent_to
;
3703 struct mailimf_cc
* resent_cc
;
3704 struct mailimf_bcc
* resent_bcc
;
3705 struct mailimf_message_id
* resent_msg_id
;
3708 struct mailimf_resent_field
* resent_field
;
3712 cur_token
= * index
;
3716 resent_sender
= NULL
;
3720 resent_msg_id
= NULL
;
3722 type
= guess_resent_header_type(message
, length
, cur_token
);
3725 case MAILIMF_RESENT_FIELD_DATE
:
3726 r
= mailimf_resent_date_parse(message
, length
, &cur_token
,
3728 if (r
!= MAILIMF_NO_ERROR
) {
3733 case MAILIMF_RESENT_FIELD_FROM
:
3734 r
= mailimf_resent_from_parse(message
, length
, &cur_token
,
3736 if (r
!= MAILIMF_NO_ERROR
) {
3741 case MAILIMF_RESENT_FIELD_SENDER
:
3742 r
= mailimf_resent_sender_parse(message
, length
, &cur_token
,
3744 if (r
!= MAILIMF_NO_ERROR
) {
3749 case MAILIMF_RESENT_FIELD_TO
:
3750 r
= mailimf_resent_to_parse(message
, length
, &cur_token
,
3752 if (r
!= MAILIMF_NO_ERROR
) {
3757 case MAILIMF_RESENT_FIELD_CC
:
3758 r
= mailimf_resent_cc_parse(message
, length
, &cur_token
,
3760 if (r
!= MAILIMF_NO_ERROR
) {
3765 case MAILIMF_RESENT_FIELD_BCC
:
3766 r
= mailimf_resent_bcc_parse(message
, length
, &cur_token
,
3768 if (r
!= MAILIMF_NO_ERROR
) {
3773 case MAILIMF_RESENT_FIELD_MSG_ID
:
3774 r
= mailimf_resent_msg_id_parse(message
, length
, &cur_token
,
3776 if (r
!= MAILIMF_NO_ERROR
) {
3782 res
= MAILIMF_ERROR_PARSE
;
3786 resent_field
= mailimf_resent_field_new(type
, resent_date
,
3787 resent_from
, resent_sender
,
3788 resent_to
, resent_cc
,
3789 resent_bcc
, resent_msg_id
);
3790 if (resent_field
== NULL
) {
3791 res
= MAILIMF_ERROR_MEMORY
;
3795 * result
= resent_field
;
3796 * index
= cur_token
;
3798 return MAILIMF_NO_ERROR
;
3801 if (resent_msg_id
!= NULL
)
3802 mailimf_message_id_free(resent_msg_id
);
3803 if (resent_bcc
!= NULL
)
3804 mailimf_bcc_free(resent_bcc
);
3805 if (resent_cc
!= NULL
)
3806 mailimf_cc_free(resent_cc
);
3807 if (resent_to
!= NULL
)
3808 mailimf_to_free(resent_to
);
3809 if (resent_sender
!= NULL
)
3810 mailimf_sender_free(resent_sender
);
3811 if (resent_from
!= NULL
)
3812 mailimf_from_free(resent_from
);
3813 if (resent_date
!= NULL
)
3814 mailimf_orig_date_free(resent_date
);
3822 mailimf_resent_fields_list_parse(const char * message
, size_t length
,
3824 struct mailimf_resent_fields_list
** result
)
3828 struct mailimf_resent_fields_list
* resent_fields_list
;
3832 cur_token
= * index
;
3835 r
= mailimf_struct_multiple_parse(message
, length
, &cur_token
, &list
,
3836 (mailimf_struct_parser
*)
3837 mailimf_resent_field_parse
,
3838 (mailimf_struct_destructor
*)
3839 mailimf_resent_field_free
);
3840 if (r
!= MAILIMF_NO_ERROR
) {
3845 resent_fields_list
= mailimf_resent_fields_list_new(list
);
3846 if (resent_fields_list
== NULL
) {
3847 res
= MAILIMF_ERROR_MEMORY
;
3851 * result
= resent_fields_list
;
3852 * index
= cur_token
;
3854 return MAILIMF_NO_ERROR
;
3857 clist_foreach(list
, (clist_func
) mailimf_resent_field_free
, NULL
);
3866 [resent-fields-list])
3871 mailimf_trace_resent_fields_parse(const char * message
, size_t length
,
3873 struct mailimf_trace_resent_fields
** result
)
3876 struct mailimf_return
* return_path
;
3877 struct mailimf_resent_fields_list
* resent_fields
;
3878 struct mailimf_trace_resent_fields
* trace_resent_fields
;
3882 cur_token
= * index
;
3885 resent_fields
= NULL
;
3887 r
= mailimf_return_parse(message
, length
, &cur_token
,
3889 if ((r
!= MAILIMF_NO_ERROR
) && (r
!= MAILIMF_ERROR_PARSE
)) {
3894 r
= mailimf_resent_fields_list_parse(message
, length
, &cur_token
,
3896 if ((r
!= MAILIMF_NO_ERROR
) && (r
!= MAILIMF_ERROR_PARSE
)) {
3901 if ((return_path
== NULL
) && (resent_fields
== NULL
)) {
3902 res
= MAILIMF_ERROR_PARSE
;
3906 trace_resent_fields
= mailimf_trace_resent_fields_new(return_path
,
3908 if (trace_resent_fields
== NULL
) {
3909 res
= MAILIMF_ERROR_MEMORY
;
3910 goto free_resent_fields
;
3913 * result
= trace_resent_fields
;
3914 * index
= cur_token
;
3916 return MAILIMF_NO_ERROR
;
3919 if (resent_fields
!= NULL
)
3920 mailimf_resent_fields_list_free(resent_fields
);
3921 if (return_path
!= NULL
)
3922 mailimf_return_free(return_path
);
3929 delivering-info = *([trace]
3930 [resent-fields-list])
3935 mailimf_delivering_info_parse(const char * message
, size_t length
,
3937 struct mailimf_delivering_info
** result
)
3941 struct mailimf_delivering_info
* delivering_info
;
3945 cur_token
= * index
;
3947 r
= mailimf_struct_multiple_parse(message
, length
, &cur_token
,
3949 (mailimf_struct_parser
*)
3950 mailimf_trace_resent_fields_parse
,
3951 (mailimf_struct_destructor
*)
3952 mailimf_trace_resent_fields_free
);
3953 if (r
!= MAILIMF_NO_ERROR
) {
3958 delivering_info
= mailimf_delivering_info_new(list
);
3959 if (delivering_info
== NULL
) {
3960 res
= MAILIMF_ERROR_MEMORY
;
3964 * result
= delivering_info
;
3965 * index
= cur_token
;
3967 return MAILIMF_NO_ERROR
;
3970 clist_foreach(list
, (clist_func
) mailimf_trace_resent_fields_free
, NULL
);
3978 field = delivering-info /
4004 static int guess_header_type(const char * message
, size_t length
, size_t index
)
4009 state
= HEADER_START
;
4013 if (index
>= length
)
4014 return MAILIMF_FIELD_NONE
;
4018 switch((char) toupper((unsigned char) message
[index
])) {
4020 return MAILIMF_FIELD_BCC
;
4025 return MAILIMF_FIELD_ORIG_DATE
;
4027 return MAILIMF_FIELD_FROM
;
4029 return MAILIMF_FIELD_IN_REPLY_TO
;
4031 return MAILIMF_FIELD_KEYWORDS
;
4033 return MAILIMF_FIELD_MESSAGE_ID
;
4038 return MAILIMF_FIELD_TO
;
4044 return MAILIMF_FIELD_NONE
;
4048 switch((char) toupper((unsigned char) message
[index
])) {
4050 return MAILIMF_FIELD_COMMENTS
;
4052 return MAILIMF_FIELD_CC
;
4054 return MAILIMF_FIELD_NONE
;
4058 switch((char) toupper((unsigned char) message
[index
])) {
4063 return MAILIMF_FIELD_NONE
;
4067 switch((char) toupper((unsigned char) message
[index
])) {
4069 return MAILIMF_FIELD_REFERENCES
;
4071 return MAILIMF_FIELD_REPLY_TO
;
4076 return MAILIMF_FIELD_RETURN_PATH
;
4078 return MAILIMF_FIELD_NONE
;
4082 switch((char) toupper((unsigned char) message
[index
])) {
4084 return MAILIMF_FIELD_SENDER
;
4086 return MAILIMF_FIELD_SUBJECT
;
4088 return MAILIMF_FIELD_NONE
;
4093 r
= mailimf_token_case_insensitive_parse(message
,
4094 length
, &index
, "ent-");
4095 if (r
!= MAILIMF_NO_ERROR
)
4096 return MAILIMF_FIELD_NONE
;
4098 if (index
>= length
)
4099 return MAILIMF_FIELD_NONE
;
4101 switch((char) toupper((unsigned char) message
[index
])) {
4103 return MAILIMF_FIELD_RESENT_DATE
;
4105 return MAILIMF_FIELD_RESENT_FROM
;
4107 return MAILIMF_FIELD_RESENT_SENDER
;
4109 return MAILIMF_FIELD_RESENT_TO
;
4111 return MAILIMF_FIELD_RESENT_CC
;
4113 return MAILIMF_FIELD_RESENT_BCC
;
4115 return MAILIMF_FIELD_RESENT_MSG_ID
;
4117 return MAILIMF_FIELD_NONE
;
4125 static int mailimf_field_parse(const char * message
, size_t length
,
4127 struct mailimf_field
** result
)
4131 struct mailimf_return
* return_path
;
4132 struct mailimf_orig_date
* resent_date
;
4133 struct mailimf_from
* resent_from
;
4134 struct mailimf_sender
* resent_sender
;
4135 struct mailimf_to
* resent_to
;
4136 struct mailimf_cc
* resent_cc
;
4137 struct mailimf_bcc
* resent_bcc
;
4138 struct mailimf_message_id
* resent_msg_id
;
4139 struct mailimf_orig_date
* orig_date
;
4140 struct mailimf_from
* from
;
4141 struct mailimf_sender
* sender
;
4142 struct mailimf_reply_to
* reply_to
;
4143 struct mailimf_to
* to
;
4144 struct mailimf_cc
* cc
;
4145 struct mailimf_bcc
* bcc
;
4146 struct mailimf_message_id
* message_id
;
4147 struct mailimf_in_reply_to
* in_reply_to
;
4148 struct mailimf_references
* references
;
4149 struct mailimf_subject
* subject
;
4150 struct mailimf_comments
* comments
;
4151 struct mailimf_keywords
* keywords
;
4152 struct mailimf_optional_field
* optional_field
;
4153 struct mailimf_field
* field
;
4158 cur_token
= * index
;
4163 resent_sender
= NULL
;
4167 resent_msg_id
= NULL
;
4181 optional_field
= NULL
;
4183 guessed_type
= guess_header_type(message
, length
, cur_token
);
4184 type
= MAILIMF_FIELD_NONE
;
4186 switch (guessed_type
) {
4187 case MAILIMF_FIELD_ORIG_DATE
:
4188 r
= mailimf_orig_date_parse(message
, length
, &cur_token
,
4190 if (r
== MAILIMF_NO_ERROR
)
4191 type
= MAILIMF_FIELD_ORIG_DATE
;
4192 else if (r
== MAILIMF_ERROR_PARSE
) {
4200 case MAILIMF_FIELD_FROM
:
4201 r
= mailimf_from_parse(message
, length
, &cur_token
,
4203 if (r
== MAILIMF_NO_ERROR
)
4204 type
= guessed_type
;
4205 else if (r
== MAILIMF_ERROR_PARSE
) {
4213 case MAILIMF_FIELD_SENDER
:
4214 r
= mailimf_sender_parse(message
, length
, &cur_token
,
4216 if (r
== MAILIMF_NO_ERROR
)
4217 type
= guessed_type
;
4218 else if (r
== MAILIMF_ERROR_PARSE
) {
4226 case MAILIMF_FIELD_REPLY_TO
:
4227 r
= mailimf_reply_to_parse(message
, length
, &cur_token
,
4229 if (r
== MAILIMF_NO_ERROR
)
4230 type
= guessed_type
;
4231 else if (r
== MAILIMF_ERROR_PARSE
) {
4239 case MAILIMF_FIELD_TO
:
4240 r
= mailimf_to_parse(message
, length
, &cur_token
,
4242 if (r
== MAILIMF_NO_ERROR
)
4243 type
= guessed_type
;
4244 else if (r
== MAILIMF_ERROR_PARSE
) {
4252 case MAILIMF_FIELD_CC
:
4253 r
= mailimf_cc_parse(message
, length
, &cur_token
,
4255 if (r
== MAILIMF_NO_ERROR
)
4256 type
= guessed_type
;
4257 else if (r
== MAILIMF_ERROR_PARSE
) {
4265 case MAILIMF_FIELD_BCC
:
4266 r
= mailimf_bcc_parse(message
, length
, &cur_token
,
4268 if (r
== MAILIMF_NO_ERROR
)
4269 type
= guessed_type
;
4270 else if (r
== MAILIMF_ERROR_PARSE
) {
4278 case MAILIMF_FIELD_MESSAGE_ID
:
4279 r
= mailimf_message_id_parse(message
, length
, &cur_token
,
4281 if (r
== MAILIMF_NO_ERROR
)
4282 type
= guessed_type
;
4283 else if (r
== MAILIMF_ERROR_PARSE
) {
4291 case MAILIMF_FIELD_IN_REPLY_TO
:
4292 r
= mailimf_in_reply_to_parse(message
, length
, &cur_token
,
4294 if (r
== MAILIMF_NO_ERROR
)
4295 type
= guessed_type
;
4296 else if (r
== MAILIMF_ERROR_PARSE
) {
4304 case MAILIMF_FIELD_REFERENCES
:
4305 r
= mailimf_references_parse(message
, length
, &cur_token
,
4307 if (r
== MAILIMF_NO_ERROR
)
4308 type
= guessed_type
;
4309 else if (r
== MAILIMF_ERROR_PARSE
) {
4317 case MAILIMF_FIELD_SUBJECT
:
4318 r
= mailimf_subject_parse(message
, length
, &cur_token
,
4320 if (r
== MAILIMF_NO_ERROR
)
4321 type
= guessed_type
;
4322 else if (r
== MAILIMF_ERROR_PARSE
) {
4330 case MAILIMF_FIELD_COMMENTS
:
4331 r
= mailimf_comments_parse(message
, length
, &cur_token
,
4333 if (r
== MAILIMF_NO_ERROR
)
4334 type
= guessed_type
;
4335 else if (r
== MAILIMF_ERROR_PARSE
) {
4343 case MAILIMF_FIELD_KEYWORDS
:
4344 r
= mailimf_keywords_parse(message
, length
, &cur_token
,
4346 if (r
== MAILIMF_NO_ERROR
)
4347 type
= guessed_type
;
4348 else if (r
== MAILIMF_ERROR_PARSE
) {
4356 case MAILIMF_FIELD_RETURN_PATH
:
4357 r
= mailimf_return_parse(message
, length
, &cur_token
,
4359 if (r
== MAILIMF_NO_ERROR
)
4360 type
= guessed_type
;
4361 else if (r
== MAILIMF_ERROR_PARSE
) {
4369 case MAILIMF_FIELD_RESENT_DATE
:
4370 r
= mailimf_resent_date_parse(message
, length
, &cur_token
,
4372 if (r
== MAILIMF_NO_ERROR
)
4373 type
= guessed_type
;
4374 else if (r
== MAILIMF_ERROR_PARSE
) {
4382 case MAILIMF_FIELD_RESENT_FROM
:
4383 r
= mailimf_resent_from_parse(message
, length
, &cur_token
,
4385 if (r
== MAILIMF_NO_ERROR
)
4386 type
= guessed_type
;
4387 else if (r
== MAILIMF_ERROR_PARSE
) {
4395 case MAILIMF_FIELD_RESENT_SENDER
:
4396 r
= mailimf_resent_sender_parse(message
, length
, &cur_token
,
4398 if (r
== MAILIMF_NO_ERROR
)
4399 type
= guessed_type
;
4400 else if (r
== MAILIMF_ERROR_PARSE
) {
4408 case MAILIMF_FIELD_RESENT_TO
:
4409 r
= mailimf_resent_to_parse(message
, length
, &cur_token
,
4411 if (r
== MAILIMF_NO_ERROR
)
4412 type
= guessed_type
;
4413 else if (r
== MAILIMF_ERROR_PARSE
) {
4421 case MAILIMF_FIELD_RESENT_CC
:
4422 r
= mailimf_resent_cc_parse(message
, length
, &cur_token
,
4424 if (r
== MAILIMF_NO_ERROR
)
4425 type
= guessed_type
;
4426 else if (r
== MAILIMF_ERROR_PARSE
) {
4434 case MAILIMF_FIELD_RESENT_BCC
:
4435 r
= mailimf_resent_bcc_parse(message
, length
, &cur_token
,
4437 if (r
== MAILIMF_NO_ERROR
)
4438 type
= guessed_type
;
4439 else if (r
== MAILIMF_ERROR_PARSE
) {
4447 case MAILIMF_FIELD_RESENT_MSG_ID
:
4448 r
= mailimf_resent_msg_id_parse(message
, length
, &cur_token
,
4450 if (r
== MAILIMF_NO_ERROR
)
4451 type
= guessed_type
;
4452 else if (r
== MAILIMF_ERROR_PARSE
) {
4462 if (type
== MAILIMF_FIELD_NONE
) {
4463 r
= mailimf_optional_field_parse(message
, length
, &cur_token
,
4465 if (r
!= MAILIMF_NO_ERROR
) {
4470 type
= MAILIMF_FIELD_OPTIONAL_FIELD
;
4473 field
= mailimf_field_new(type
, return_path
, resent_date
,
4474 resent_from
, resent_sender
, resent_to
, resent_cc
, resent_bcc
,
4475 resent_msg_id
, orig_date
, from
, sender
, reply_to
, to
,
4476 cc
, bcc
, message_id
, in_reply_to
, references
,
4477 subject
, comments
, keywords
, optional_field
);
4478 if (field
== NULL
) {
4479 res
= MAILIMF_ERROR_MEMORY
;
4484 * index
= cur_token
;
4486 return MAILIMF_NO_ERROR
;
4489 if (return_path
!= NULL
)
4490 mailimf_return_free(return_path
);
4491 if (resent_date
!= NULL
)
4492 mailimf_orig_date_free(resent_date
);
4493 if (resent_from
!= NULL
)
4494 mailimf_from_free(resent_from
);
4495 if (resent_sender
!= NULL
)
4496 mailimf_sender_free(resent_sender
);
4497 if (resent_to
!= NULL
)
4498 mailimf_to_free(resent_to
);
4499 if (resent_cc
!= NULL
)
4500 mailimf_cc_free(resent_cc
);
4501 if (resent_bcc
!= NULL
)
4502 mailimf_bcc_free(resent_bcc
);
4503 if (resent_msg_id
!= NULL
)
4504 mailimf_message_id_free(resent_msg_id
);
4505 if (orig_date
!= NULL
)
4506 mailimf_orig_date_free(orig_date
);
4508 mailimf_from_free(from
);
4510 mailimf_sender_free(sender
);
4511 if (reply_to
!= NULL
)
4512 mailimf_reply_to_free(reply_to
);
4514 mailimf_to_free(to
);
4516 mailimf_cc_free(cc
);
4518 mailimf_bcc_free(bcc
);
4519 if (message_id
!= NULL
)
4520 mailimf_message_id_free(message_id
);
4521 if (in_reply_to
!= NULL
)
4522 mailimf_in_reply_to_free(in_reply_to
);
4523 if (references
!= NULL
)
4524 mailimf_references_free(references
);
4525 if (subject
!= NULL
)
4526 mailimf_subject_free(subject
);
4527 if (comments
!= NULL
)
4528 mailimf_comments_free(comments
);
4529 if (keywords
!= NULL
)
4530 mailimf_keywords_free(keywords
);
4531 if (optional_field
!= NULL
)
4532 mailimf_optional_field_free(optional_field
);
4538 fields = *(delivering-info /
4557 mailimf_unparsed_fields_parse(const char * message
, size_t length
,
4559 struct mailimf_unparsed_fields
** result
)
4563 struct mailimf_unparsed_fields
* fields
;
4567 cur_token
= * index
;
4571 r
= mailimf_struct_multiple_parse(message
, length
, &cur_token
,
4573 (mailimf_struct_parser
*)
4574 mailimf_optional_field_parse
,
4575 (mailimf_struct_destructor
*)
4576 mailimf_optional_field_free
);
4578 if ((r = MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
4585 case MAILIMF_NO_ERROR
:
4589 case MAILIMF_ERROR_PARSE
:
4592 res
= MAILIMF_ERROR_MEMORY
;
4602 fields
= mailimf_unparsed_fields_new(list
);
4603 if (fields
== NULL
) {
4604 res
= MAILIMF_ERROR_MEMORY
;
4609 * index
= cur_token
;
4611 return MAILIMF_NO_ERROR
;
4615 clist_foreach(list
, (clist_func
) mailimf_optional_field_free
, NULL
);
4623 int mailimf_fields_parse(const char * message
, size_t length
,
4625 struct mailimf_fields
** result
)
4629 struct mailimf_fields
* fields
;
4633 cur_token
= * index
;
4637 r
= mailimf_struct_multiple_parse(message
, length
, &cur_token
,
4639 (mailimf_struct_parser
*)
4640 mailimf_field_parse
,
4641 (mailimf_struct_destructor
*)
4642 mailimf_field_free
);
4644 if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
4651 case MAILIMF_NO_ERROR
:
4655 case MAILIMF_ERROR_PARSE
:
4658 res
= MAILIMF_ERROR_MEMORY
;
4668 fields
= mailimf_fields_new(list
);
4669 if (fields
== NULL
) {
4670 res
= MAILIMF_ERROR_MEMORY
;
4675 * index
= cur_token
;
4677 return MAILIMF_NO_ERROR
;
4681 clist_foreach(list
, (clist_func
) mailimf_field_free
, NULL
);
4689 orig-date = "Date:" date-time CRLF
4694 mailimf_orig_date_parse(const char * message
, size_t length
,
4695 size_t * index
, struct mailimf_orig_date
** result
)
4697 struct mailimf_date_time
* date_time
;
4698 struct mailimf_orig_date
* orig_date
;
4703 cur_token
= * index
;
4705 r
= mailimf_token_case_insensitive_parse(message
, length
,
4706 &cur_token
, "Date:");
4707 if (r
!= MAILIMF_NO_ERROR
) {
4712 r
= mailimf_date_time_parse(message
, length
, &cur_token
, &date_time
);
4713 if (r
!= MAILIMF_NO_ERROR
) {
4718 r
= mailimf_ignore_unstructured_parse(message
, length
, &cur_token
);
4719 if (r
!= MAILIMF_NO_ERROR
) {
4721 goto free_date_time
;
4724 r
= mailimf_unstrict_crlf_parse(message
, length
, &cur_token
);
4725 if (r
!= MAILIMF_NO_ERROR
) {
4727 goto free_date_time
;
4730 orig_date
= mailimf_orig_date_new(date_time
);
4731 if (orig_date
== NULL
) {
4732 res
= MAILIMF_ERROR_MEMORY
;
4733 goto free_date_time
;
4736 * result
= orig_date
;
4737 * index
= cur_token
;
4739 return MAILIMF_NO_ERROR
;
4742 mailimf_date_time_free(date_time
);
4748 from = "From:" mailbox-list CRLF
4752 mailimf_from_parse(const char * message
, size_t length
,
4753 size_t * index
, struct mailimf_from
** result
)
4755 struct mailimf_mailbox_list
* mb_list
;
4756 struct mailimf_from
* from
;
4761 cur_token
= * index
;
4763 r
= mailimf_token_case_insensitive_parse(message
, length
,
4764 &cur_token
, "From");
4765 if (r
!= MAILIMF_NO_ERROR
) {
4770 r
= mailimf_colon_parse(message
, length
, &cur_token
);
4771 if (r
!= MAILIMF_NO_ERROR
) {
4776 r
= mailimf_mailbox_list_parse(message
, length
, &cur_token
, &mb_list
);
4778 if (r
!= MAILIMF_NO_ERROR
) {
4783 r
= mailimf_unstrict_crlf_parse(message
, length
, &cur_token
);
4784 if (r
!= MAILIMF_NO_ERROR
) {
4789 from
= mailimf_from_new(mb_list
);
4791 res
= MAILIMF_ERROR_MEMORY
;
4796 * index
= cur_token
;
4798 return MAILIMF_NO_ERROR
;
4801 mailimf_mailbox_list_free(mb_list
);
4807 sender = "Sender:" mailbox CRLF
4811 mailimf_sender_parse(const char * message
, size_t length
,
4812 size_t * index
, struct mailimf_sender
** result
)
4814 struct mailimf_mailbox
* mb
;
4815 struct mailimf_sender
* sender
;
4820 cur_token
= * index
;
4822 r
= mailimf_token_case_insensitive_parse(message
, length
,
4823 &cur_token
, "Sender");
4824 if (r
!= MAILIMF_NO_ERROR
) {
4829 r
= mailimf_colon_parse(message
, length
, &cur_token
);
4830 if (r
!= MAILIMF_NO_ERROR
) {
4835 r
= mailimf_mailbox_parse(message
, length
, &cur_token
, &mb
);
4836 if (r
!= MAILIMF_NO_ERROR
) {
4841 r
= mailimf_unstrict_crlf_parse(message
, length
, &cur_token
);
4842 if (r
!= MAILIMF_NO_ERROR
) {
4847 sender
= mailimf_sender_new(mb
);
4848 if (sender
== NULL
) {
4849 res
= MAILIMF_ERROR_MEMORY
;
4854 * index
= cur_token
;
4856 return MAILIMF_NO_ERROR
;
4859 mailimf_mailbox_free(mb
);
4865 reply-to = "Reply-To:" address-list CRLF
4870 mailimf_reply_to_parse(const char * message
, size_t length
,
4871 size_t * index
, struct mailimf_reply_to
** result
)
4873 struct mailimf_address_list
* addr_list
;
4874 struct mailimf_reply_to
* reply_to
;
4879 cur_token
= * index
;
4881 r
= mailimf_token_case_insensitive_parse(message
, length
,
4882 &cur_token
, "Reply-To");
4883 if (r
!= MAILIMF_NO_ERROR
) {
4888 r
= mailimf_colon_parse(message
, length
, &cur_token
);
4889 if (r
!= MAILIMF_NO_ERROR
) {
4894 r
= mailimf_address_list_parse(message
, length
, &cur_token
, &addr_list
);
4895 if (r
!= MAILIMF_NO_ERROR
) {
4900 r
= mailimf_unstrict_crlf_parse(message
, length
, &cur_token
);
4901 if (r
!= MAILIMF_NO_ERROR
) {
4903 goto free_addr_list
;
4906 reply_to
= mailimf_reply_to_new(addr_list
);
4907 if (reply_to
== NULL
) {
4908 res
= MAILIMF_ERROR_MEMORY
;
4909 goto free_addr_list
;
4912 * result
= reply_to
;
4913 * index
= cur_token
;
4915 return MAILIMF_NO_ERROR
;
4918 mailimf_address_list_free(addr_list
);
4924 to = "To:" address-list CRLF
4928 mailimf_to_parse(const char * message
, size_t length
,
4929 size_t * index
, struct mailimf_to
** result
)
4931 struct mailimf_address_list
* addr_list
;
4932 struct mailimf_to
* to
;
4937 cur_token
= * index
;
4939 r
= mailimf_token_case_insensitive_parse(message
, length
,
4941 if (r
!= MAILIMF_NO_ERROR
) {
4946 r
= mailimf_colon_parse(message
, length
, &cur_token
);
4947 if (r
!= MAILIMF_NO_ERROR
) {
4952 r
= mailimf_address_list_parse(message
, length
, &cur_token
, &addr_list
);
4953 if (r
!= MAILIMF_NO_ERROR
) {
4958 r
= mailimf_unstrict_crlf_parse(message
, length
, &cur_token
);
4959 if (r
!= MAILIMF_NO_ERROR
) {
4961 goto free_addr_list
;
4964 to
= mailimf_to_new(addr_list
);
4966 res
= MAILIMF_ERROR_MEMORY
;
4967 goto free_addr_list
;
4971 * index
= cur_token
;
4973 return MAILIMF_NO_ERROR
;
4976 mailimf_address_list_free(addr_list
);
4982 cc = "Cc:" address-list CRLF
4987 mailimf_cc_parse(const char * message
, size_t length
,
4988 size_t * index
, struct mailimf_cc
** result
)
4990 struct mailimf_address_list
* addr_list
;
4991 struct mailimf_cc
* cc
;
4996 cur_token
= * index
;
4998 r
= mailimf_token_case_insensitive_parse(message
, length
,
5000 if (r
!= MAILIMF_NO_ERROR
) {
5005 r
= mailimf_colon_parse(message
, length
, &cur_token
);
5006 if (r
!= MAILIMF_NO_ERROR
) {
5011 r
= mailimf_address_list_parse(message
, length
, &cur_token
, &addr_list
);
5012 if (r
!= MAILIMF_NO_ERROR
) {
5017 r
= mailimf_unstrict_crlf_parse(message
, length
, &cur_token
);
5018 if (r
!= MAILIMF_NO_ERROR
) {
5020 goto free_addr_list
;
5023 cc
= mailimf_cc_new(addr_list
);
5025 res
= MAILIMF_ERROR_MEMORY
;
5026 goto free_addr_list
;
5030 * index
= cur_token
;
5032 return MAILIMF_NO_ERROR
;
5035 mailimf_address_list_free(addr_list
);
5041 bcc = "Bcc:" (address-list / [CFWS]) CRLF
5046 mailimf_bcc_parse(const char * message
, size_t length
,
5047 size_t * index
, struct mailimf_bcc
** result
)
5049 struct mailimf_address_list
* addr_list
;
5050 struct mailimf_bcc
* bcc
;
5055 cur_token
= * index
;
5058 r
= mailimf_token_case_insensitive_parse(message
, length
,
5060 if (r
!= MAILIMF_NO_ERROR
) {
5065 r
= mailimf_colon_parse(message
, length
, &cur_token
);
5066 if (r
!= MAILIMF_NO_ERROR
) {
5071 r
= mailimf_address_list_parse(message
, length
, &cur_token
, &addr_list
);
5073 case MAILIMF_NO_ERROR
:
5076 case MAILIMF_ERROR_PARSE
:
5077 r
= mailimf_cfws_parse(message
, length
, &cur_token
);
5078 if ((r
!= MAILIMF_NO_ERROR
) && (r
!= MAILIMF_ERROR_PARSE
)) {
5088 r
= mailimf_unstrict_crlf_parse(message
, length
, &cur_token
);
5089 if (r
!= MAILIMF_NO_ERROR
) {
5091 goto free_addr_list
;
5094 bcc
= mailimf_bcc_new(addr_list
);
5096 res
= MAILIMF_ERROR_MEMORY
;
5097 goto free_addr_list
;
5101 * index
= cur_token
;
5103 return MAILIMF_NO_ERROR
;
5106 mailimf_address_list_free(addr_list
);
5112 message-id = "Message-ID:" msg-id CRLF
5115 static int mailimf_message_id_parse(const char * message
, size_t length
,
5117 struct mailimf_message_id
** result
)
5121 struct mailimf_message_id
* message_id
;
5125 cur_token
= * index
;
5127 r
= mailimf_token_case_insensitive_parse(message
, length
,
5128 &cur_token
, "Message-ID");
5129 if (r
!= MAILIMF_NO_ERROR
) {
5134 r
= mailimf_colon_parse(message
, length
, &cur_token
);
5135 if (r
!= MAILIMF_NO_ERROR
) {
5140 r
= mailimf_msg_id_parse(message
, length
, &cur_token
, &value
);
5141 if (r
!= MAILIMF_NO_ERROR
) {
5146 r
= mailimf_unstrict_crlf_parse(message
, length
, &cur_token
);
5147 if (r
!= MAILIMF_NO_ERROR
) {
5152 message_id
= mailimf_message_id_new(value
);
5153 if (message_id
== NULL
) {
5154 res
= MAILIMF_ERROR_MEMORY
;
5158 * result
= message_id
;
5159 * index
= cur_token
;
5161 return MAILIMF_NO_ERROR
;
5164 mailimf_msg_id_free(value
);
5170 in-reply-to = "In-Reply-To:" 1*msg-id CRLF
5173 int mailimf_msg_id_list_parse(const char * message
, size_t length
,
5174 size_t * index
, clist
** result
)
5176 return mailimf_struct_multiple_parse(message
, length
, index
,
5178 (mailimf_struct_parser
*)
5179 mailimf_unstrict_msg_id_parse
,
5180 (mailimf_struct_destructor
*)
5181 mailimf_msg_id_free
);
5184 static int mailimf_in_reply_to_parse(const char * message
, size_t length
,
5186 struct mailimf_in_reply_to
** result
)
5188 struct mailimf_in_reply_to
* in_reply_to
;
5190 clist
* msg_id_list
;
5194 cur_token
= * index
;
5196 r
= mailimf_token_case_insensitive_parse(message
, length
,
5197 &cur_token
, "In-Reply-To");
5198 if (r
!= MAILIMF_NO_ERROR
) {
5203 r
= mailimf_colon_parse(message
, length
, &cur_token
);
5204 if (r
!= MAILIMF_NO_ERROR
) {
5209 r
= mailimf_msg_id_list_parse(message
, length
, &cur_token
, &msg_id_list
);
5210 if (r
!= MAILIMF_NO_ERROR
) {
5215 r
= mailimf_unstrict_crlf_parse(message
, length
, &cur_token
);
5216 if (r
!= MAILIMF_NO_ERROR
) {
5221 in_reply_to
= mailimf_in_reply_to_new(msg_id_list
);
5222 if (in_reply_to
== NULL
) {
5223 res
= MAILIMF_ERROR_MEMORY
;
5227 * result
= in_reply_to
;
5228 * index
= cur_token
;
5230 return MAILIMF_NO_ERROR
;
5233 clist_foreach(msg_id_list
, (clist_func
) mailimf_msg_id_free
, NULL
);
5234 clist_free(msg_id_list
);
5240 references = "References:" 1*msg-id CRLF
5243 int mailimf_references_parse(const char * message
, size_t length
,
5245 struct mailimf_references
** result
)
5247 struct mailimf_references
* references
;
5249 clist
* msg_id_list
;
5253 cur_token
= * index
;
5255 r
= mailimf_token_case_insensitive_parse(message
, length
,
5256 &cur_token
, "References");
5257 if (r
!= MAILIMF_NO_ERROR
) {
5262 r
= mailimf_colon_parse(message
, length
, &cur_token
);
5263 if (r
!= MAILIMF_NO_ERROR
) {
5268 r
= mailimf_msg_id_list_parse(message
, length
, &cur_token
, &msg_id_list
);
5269 if (r
!= MAILIMF_NO_ERROR
) {
5274 r
= mailimf_unstrict_crlf_parse(message
, length
, &cur_token
);
5275 if (r
!= MAILIMF_NO_ERROR
) {
5280 references
= mailimf_references_new(msg_id_list
);
5281 if (references
== NULL
) {
5282 res
= MAILIMF_ERROR_MEMORY
;
5286 * result
= references
;
5287 * index
= cur_token
;
5289 return MAILIMF_NO_ERROR
;
5292 clist_foreach(msg_id_list
, (clist_func
) mailimf_msg_id_free
, NULL
);
5293 clist_free(msg_id_list
);
5299 msg-id = [CFWS] "<" id-left "@" id-right ">" [CFWS]
5302 int mailimf_msg_id_parse(const char * message
, size_t length
,
5315 cur_token
= * index
;
5317 r
= mailimf_cfws_parse(message
, length
, &cur_token
);
5318 if ((r
!= MAILIMF_NO_ERROR
) && (r
!= MAILIMF_ERROR_PARSE
))
5321 r
= mailimf_lower_parse(message
, length
, &cur_token
);
5322 if (r
!= MAILIMF_NO_ERROR
) {
5327 r
= mailimf_addr_spec_parse(message
, length
, &cur_token
, &msg_id
);
5328 if (r
!= MAILIMF_NO_ERROR
) {
5333 r
= mailimf_greater_parse(message
, length
, &cur_token
);
5334 if (r
!= MAILIMF_NO_ERROR
) {
5341 r
= mailimf_id_left_parse(message
, length
, &cur_token
, &id_left
);
5342 if (r
!= MAILIMF_NO_ERROR
) {
5347 r
= mailimf_at_sign_parse(message
, length
, &cur_token
);
5348 if (r
!= MAILIMF_NO_ERROR
) {
5353 r
= mailimf_id_right_parse(message
, length
, &cur_token
, &id_right
);
5354 if (r
!= MAILIMF_NO_ERROR
) {
5359 r
= mailimf_greater_parse(message
, length
, &cur_token
);
5360 if (r
!= MAILIMF_NO_ERROR
) {
5365 msg_id
= malloc(strlen(id_left
) + strlen(id_right
) + 2);
5366 if (msg_id
== NULL
) {
5367 res
= MAILIMF_ERROR_MEMORY
;
5370 strcpy(msg_id
, id_left
);
5371 strcat(msg_id
, "@");
5372 strcat(msg_id
, id_right
);
5374 mailimf_id_left_free(id_left
);
5375 mailimf_id_right_free(id_right
);
5379 * index
= cur_token
;
5381 return MAILIMF_NO_ERROR
;
5385 mailimf_id_right_free(id_right
);
5387 mailimf_id_left_free(id_left
);
5391 mailimf_atom_free(msg_id);
5397 static int mailimf_parse_unwanted_msg_id(const char * message
, size_t length
,
5405 cur_token
= * index
;
5407 token_parsed
= TRUE
;
5408 while (token_parsed
) {
5409 token_parsed
= FALSE
;
5410 r
= mailimf_word_parse(message
, length
, &cur_token
, &word
);
5411 if (r
== MAILIMF_NO_ERROR
) {
5412 mailimf_word_free(word
);
5413 token_parsed
= TRUE
;
5415 else if (r
== MAILIMF_ERROR_PARSE
) {
5420 r
= mailimf_semi_colon_parse(message
, length
, &cur_token
);
5421 if (r
== MAILIMF_NO_ERROR
)
5422 token_parsed
= TRUE
;
5423 else if (r
== MAILIMF_ERROR_PARSE
) {
5428 r
= mailimf_comma_parse(message
, length
, &cur_token
);
5429 if (r
== MAILIMF_NO_ERROR
)
5430 token_parsed
= TRUE
;
5431 else if (r
== MAILIMF_ERROR_PARSE
) {
5436 r
= mailimf_plus_parse(message
, length
, &cur_token
);
5437 if (r
== MAILIMF_NO_ERROR
)
5438 token_parsed
= TRUE
;
5439 else if (r
== MAILIMF_ERROR_PARSE
) {
5444 r
= mailimf_colon_parse(message
, length
, &cur_token
);
5445 if (r
== MAILIMF_NO_ERROR
)
5446 token_parsed
= TRUE
;
5447 else if (r
== MAILIMF_ERROR_PARSE
) {
5452 r
= mailimf_point_parse(message
, length
, &cur_token
);
5453 if (r
== MAILIMF_NO_ERROR
)
5454 token_parsed
= TRUE
;
5455 else if (r
== MAILIMF_ERROR_PARSE
) {
5460 r
= mailimf_at_sign_parse(message
, length
, &cur_token
);
5461 if (r
== MAILIMF_NO_ERROR
)
5462 token_parsed
= TRUE
;
5463 else if (r
== MAILIMF_ERROR_PARSE
) {
5470 return MAILIMF_NO_ERROR
;
5473 static int mailimf_unstrict_msg_id_parse(const char * message
, size_t length
,
5477 char * msgid
= NULL
;
5481 cur_token
= * index
;
5483 r
= mailimf_cfws_parse(message
, length
, &cur_token
);
5484 if ((r
!= MAILIMF_NO_ERROR
) && (r
!= MAILIMF_ERROR_PARSE
))
5487 r
= mailimf_parse_unwanted_msg_id(message
, length
, &cur_token
);
5488 if (r
!= MAILIMF_NO_ERROR
)
5491 r
= mailimf_msg_id_parse(message
, length
, &cur_token
, &msgid
);
5492 if (r
!= MAILIMF_NO_ERROR
)
5495 r
= mailimf_parse_unwanted_msg_id(message
, length
, &cur_token
);
5496 if (r
!= MAILIMF_NO_ERROR
) {
5502 * index
= cur_token
;
5504 return MAILIMF_NO_ERROR
;
5508 id-left = dot-atom-text / no-fold-quote / obs-id-left
5512 static int mailimf_id_left_parse(const char * message
, size_t length
,
5513 size_t * index
, char ** result
)
5517 r
= mailimf_dot_atom_text_parse(message
, length
, index
, result
);
5519 case MAILIMF_NO_ERROR
:
5520 return MAILIMF_NO_ERROR
;
5521 case MAILIMF_ERROR_PARSE
:
5527 r
= mailimf_no_fold_quote_parse(message
, length
, index
, result
);
5528 if (r
!= MAILIMF_NO_ERROR
)
5531 return MAILIMF_NO_ERROR
;
5536 id-right = dot-atom-text / no-fold-literal / obs-id-right
5540 static int mailimf_id_right_parse(const char * message
, size_t length
,
5541 size_t * index
, char ** result
)
5545 r
= mailimf_dot_atom_text_parse(message
, length
, index
, result
);
5547 case MAILIMF_NO_ERROR
:
5548 return MAILIMF_NO_ERROR
;
5549 case MAILIMF_ERROR_PARSE
:
5555 r
= mailimf_no_fold_literal_parse(message
, length
, index
, result
);
5556 if (r
!= MAILIMF_NO_ERROR
)
5559 return MAILIMF_NO_ERROR
;
5564 no-fold-quote = DQUOTE *(qtext / quoted-pair) DQUOTE
5568 static int mailimf_no_fold_quote_char_parse(const char * message
, size_t length
,
5569 size_t * index
, char * result
)
5575 cur_token
= * index
;
5578 r
= mailimf_qtext_parse(message
, length
, &cur_token
, &ch
);
5581 if (cur_token
>= length
)
5582 return MAILIMF_ERROR_PARSE
;
5584 if (is_qtext(message
[cur_token
])) {
5585 ch
= message
[cur_token
];
5589 r
= mailimf_quoted_pair_parse(message
, length
, &cur_token
, &ch
);
5591 if (r
!= MAILIMF_NO_ERROR
)
5595 * index
= cur_token
;
5598 return MAILIMF_NO_ERROR
;
5603 static int mailimf_no_fold_quote_parse(const char * message
, size_t length
,
5604 size_t * index
, char ** result
)
5609 char * no_fold_quote
;
5614 r
= mailimf_dquote_parse(message
, length
, &cur_token
);
5615 if (r
!= MAILIMF_NO_ERROR
) {
5621 r
= mailimf_no_fold_quote_char_parse(message
, length
, &cur_token
, &ch
);
5622 if (r
== MAILIMF_NO_ERROR
) {
5625 else if (r
== MAILIMF_ERROR_PARSE
)
5633 r
= mailimf_dquote_parse(message
, length
, &cur_token
);
5634 if (r
!= MAILIMF_NO_ERROR
) {
5639 /* no_fold_quote = strndup(message + begin, cur_token - begin); */
5640 no_fold_quote
= malloc(cur_token
- begin
+ 1);
5641 if (no_fold_quote
== NULL
) {
5642 res
= MAILIMF_ERROR_MEMORY
;
5645 strncpy(no_fold_quote
, message
+ begin
, cur_token
- begin
);
5646 no_fold_quote
[cur_token
- begin
] = '\0';
5648 * result
= no_fold_quote
;
5649 * index
= cur_token
;
5651 return MAILIMF_NO_ERROR
;
5659 no-fold-literal = "[" *(dtext / quoted-pair) "]"
5664 mailimf_no_fold_literal_char_parse(const char * message
, size_t length
,
5665 size_t * index
, char * result
)
5671 cur_token
= * index
;
5674 r
= mailimf_dtext_parse(message
, length
, &cur_token
, &ch
);
5676 if (cur_token
>= length
)
5677 return MAILIMF_ERROR_PARSE
;
5679 if (is_dtext(message
[cur_token
])) {
5680 ch
= message
[cur_token
];
5684 r
= mailimf_quoted_pair_parse(message
, length
, &cur_token
, &ch
);
5686 if (r
!= MAILIMF_NO_ERROR
)
5690 * index
= cur_token
;
5693 return MAILIMF_NO_ERROR
;
5698 static int mailimf_no_fold_literal_parse(const char * message
, size_t length
,
5699 size_t * index
, char ** result
)
5704 char * no_fold_literal
;
5709 r
= mailimf_obracket_parse(message
, length
, &cur_token
);
5710 if (r
!= MAILIMF_NO_ERROR
) {
5716 r
= mailimf_no_fold_literal_char_parse(message
, length
,
5718 if (r
== MAILIMF_NO_ERROR
) {
5721 else if (r
== MAILIMF_ERROR_PARSE
)
5729 r
= mailimf_cbracket_parse(message
, length
, &cur_token
);
5730 if (r
!= MAILIMF_NO_ERROR
) {
5736 no_fold_literal = strndup(message + begin, cur_token - begin);
5738 no_fold_literal
= malloc(cur_token
- begin
+ 1);
5739 if (no_fold_literal
== NULL
) {
5740 res
= MAILIMF_NO_ERROR
;
5743 strncpy(no_fold_literal
, message
+ begin
, cur_token
- begin
);
5744 no_fold_literal
[cur_token
- begin
] = '\0';
5746 * result
= no_fold_literal
;
5747 * index
= cur_token
;
5749 return MAILIMF_NO_ERROR
;
5757 subject = "Subject:" unstructured CRLF
5760 static int mailimf_subject_parse(const char * message
, size_t length
,
5762 struct mailimf_subject
** result
)
5764 struct mailimf_subject
* subject
;
5770 cur_token
= * index
;
5772 r
= mailimf_token_case_insensitive_parse(message
, length
,
5773 &cur_token
, "Subject");
5774 if (r
!= MAILIMF_NO_ERROR
) {
5779 r
= mailimf_colon_parse(message
, length
, &cur_token
);
5780 if (r
!= MAILIMF_NO_ERROR
) {
5785 r
= mailimf_unstructured_parse(message
, length
, &cur_token
, &value
);
5786 if (r
!= MAILIMF_NO_ERROR
) {
5791 r
= mailimf_unstrict_crlf_parse(message
, length
, &cur_token
);
5792 if (r
!= MAILIMF_NO_ERROR
) {
5797 subject
= mailimf_subject_new(value
);
5798 if (subject
== NULL
) {
5799 res
= MAILIMF_ERROR_MEMORY
;
5804 * index
= cur_token
;
5806 return MAILIMF_NO_ERROR
;
5809 mailimf_unstructured_free(value
);
5815 comments = "Comments:" unstructured CRLF
5818 static int mailimf_comments_parse(const char * message
, size_t length
,
5820 struct mailimf_comments
** result
)
5822 struct mailimf_comments
* comments
;
5828 cur_token
= * index
;
5830 r
= mailimf_token_case_insensitive_parse(message
, length
,
5831 &cur_token
, "Comments");
5832 if (r
!= MAILIMF_NO_ERROR
) {
5837 r
= mailimf_colon_parse(message
, length
, &cur_token
);
5838 if (r
!= MAILIMF_NO_ERROR
) {
5843 r
= mailimf_unstructured_parse(message
, length
, &cur_token
, &value
);
5844 if (r
!= MAILIMF_NO_ERROR
) {
5849 r
= mailimf_unstrict_crlf_parse(message
, length
, &cur_token
);
5850 if (r
!= MAILIMF_NO_ERROR
) {
5855 comments
= mailimf_comments_new(value
);
5856 if (comments
== NULL
) {
5857 res
= MAILIMF_ERROR_MEMORY
;
5861 * result
= comments
;
5862 * index
= cur_token
;
5864 return MAILIMF_NO_ERROR
;
5867 mailimf_unstructured_free(value
);
5873 keywords = "Keywords:" phrase *("," phrase) CRLF
5876 static int mailimf_keywords_parse(const char * message
, size_t length
,
5878 struct mailimf_keywords
** result
)
5880 struct mailimf_keywords
* keywords
;
5886 cur_token
= * index
;
5888 r
= mailimf_token_case_insensitive_parse(message
, length
,
5889 &cur_token
, "Keywords");
5890 if (r
!= MAILIMF_NO_ERROR
) {
5895 r
= mailimf_colon_parse(message
, length
, &cur_token
);
5896 if (r
!= MAILIMF_NO_ERROR
) {
5901 r
= mailimf_struct_list_parse(message
, length
, &cur_token
,
5903 (mailimf_struct_parser
*)
5904 mailimf_phrase_parse
,
5905 (mailimf_struct_destructor
*)
5906 mailimf_phrase_free
);
5907 if (r
!= MAILIMF_NO_ERROR
) {
5912 r
= mailimf_unstrict_crlf_parse(message
, length
, &cur_token
);
5913 if (r
!= MAILIMF_NO_ERROR
) {
5918 keywords
= mailimf_keywords_new(list
);
5919 if (keywords
== NULL
) {
5920 res
= MAILIMF_ERROR_MEMORY
;
5924 * result
= keywords
;
5925 * index
= cur_token
;
5927 return MAILIMF_NO_ERROR
;
5930 clist_foreach(list
, (clist_func
) mailimf_phrase_free
, NULL
);
5937 resent-date = "Resent-Date:" date-time CRLF
5941 mailimf_resent_date_parse(const char * message
, size_t length
,
5942 size_t * index
, struct mailimf_orig_date
** result
)
5944 struct mailimf_orig_date
* orig_date
;
5945 struct mailimf_date_time
* date_time
;
5950 cur_token
= * index
;
5952 r
= mailimf_token_case_insensitive_parse(message
, length
,
5953 &cur_token
, "Resent-Date");
5954 if (r
!= MAILIMF_NO_ERROR
) {
5959 r
= mailimf_colon_parse(message
, length
, &cur_token
);
5960 if (r
!= MAILIMF_NO_ERROR
) {
5965 r
= mailimf_date_time_parse(message
, length
, &cur_token
, &date_time
);
5966 if (r
!= MAILIMF_NO_ERROR
) {
5971 r
= mailimf_unstrict_crlf_parse(message
, length
, &cur_token
);
5972 if (r
!= MAILIMF_NO_ERROR
) {
5974 goto free_date_time
;
5977 orig_date
= mailimf_orig_date_new(date_time
);
5978 if (orig_date
== NULL
) {
5979 res
= MAILIMF_ERROR_MEMORY
;
5980 goto free_date_time
;
5983 * result
= orig_date
;
5984 * index
= cur_token
;
5986 return MAILIMF_NO_ERROR
;
5989 mailimf_date_time_free(date_time
);
5995 resent-from = "Resent-From:" mailbox-list CRLF
5999 mailimf_resent_from_parse(const char * message
, size_t length
,
6000 size_t * index
, struct mailimf_from
** result
)
6002 struct mailimf_mailbox_list
* mb_list
;
6003 struct mailimf_from
* from
;
6008 cur_token
= * index
;
6010 r
= mailimf_token_case_insensitive_parse(message
, length
,
6011 &cur_token
, "Resent-From");
6012 if (r
!= MAILIMF_NO_ERROR
) {
6017 r
= mailimf_colon_parse(message
, length
, &cur_token
);
6018 if (r
!= MAILIMF_NO_ERROR
) {
6023 r
= mailimf_mailbox_list_parse(message
, length
, &cur_token
, &mb_list
);
6024 if (r
!= MAILIMF_NO_ERROR
) {
6029 r
= mailimf_unstrict_crlf_parse(message
, length
, &cur_token
);
6030 if (r
!= MAILIMF_NO_ERROR
) {
6035 from
= mailimf_from_new(mb_list
);
6037 res
= MAILIMF_ERROR_MEMORY
;
6042 * index
= cur_token
;
6044 return MAILIMF_NO_ERROR
;
6047 mailimf_mailbox_list_free(mb_list
);
6053 resent-sender = "Resent-Sender:" mailbox CRLF
6057 mailimf_resent_sender_parse(const char * message
, size_t length
,
6058 size_t * index
, struct mailimf_sender
** result
)
6060 struct mailimf_mailbox
* mb
;
6061 struct mailimf_sender
* sender
;
6068 r
= mailimf_token_case_insensitive_parse(message
, length
,
6069 &cur_token
, "Resent-Sender");
6070 if (r
!= MAILIMF_NO_ERROR
) {
6075 r
= mailimf_colon_parse(message
, length
, &cur_token
);
6076 if (r
!= MAILIMF_NO_ERROR
) {
6081 r
= mailimf_mailbox_parse(message
, length
, &cur_token
, &mb
);
6082 if (r
!= MAILIMF_NO_ERROR
) {
6087 r
= mailimf_unstrict_crlf_parse(message
, length
, &cur_token
);
6088 if (r
!= MAILIMF_NO_ERROR
) {
6093 sender
= mailimf_sender_new(mb
);
6094 if (sender
== NULL
) {
6095 res
= MAILIMF_ERROR_MEMORY
;
6100 * index
= cur_token
;
6102 return MAILIMF_NO_ERROR
;
6105 mailimf_mailbox_free(mb
);
6111 resent-to = "Resent-To:" address-list CRLF
6115 mailimf_resent_to_parse(const char * message
, size_t length
,
6116 size_t * index
, struct mailimf_to
** result
)
6118 struct mailimf_address_list
* addr_list
;
6119 struct mailimf_to
* to
;
6124 cur_token
= * index
;
6126 r
= mailimf_token_case_insensitive_parse(message
, length
,
6127 &cur_token
, "Resent-To");
6128 if (r
!= MAILIMF_NO_ERROR
) {
6133 r
= mailimf_colon_parse(message
, length
, &cur_token
);
6134 if (r
!= MAILIMF_NO_ERROR
) {
6139 r
= mailimf_address_list_parse(message
, length
, &cur_token
, &addr_list
);
6140 if (r
!= MAILIMF_NO_ERROR
) {
6145 r
= mailimf_unstrict_crlf_parse(message
, length
, &cur_token
);
6146 if (r
!= MAILIMF_NO_ERROR
) {
6148 goto free_addr_list
;
6151 to
= mailimf_to_new(addr_list
);
6153 res
= MAILIMF_ERROR_MEMORY
;
6154 goto free_addr_list
;
6158 * index
= cur_token
;
6160 return MAILIMF_NO_ERROR
;
6163 mailimf_address_list_free(addr_list
);
6169 resent-cc = "Resent-Cc:" address-list CRLF
6173 mailimf_resent_cc_parse(const char * message
, size_t length
,
6174 size_t * index
, struct mailimf_cc
** result
)
6176 struct mailimf_address_list
* addr_list
;
6177 struct mailimf_cc
* cc
;
6182 cur_token
= * index
;
6184 r
= mailimf_token_case_insensitive_parse(message
, length
,
6185 &cur_token
, "Resent-Cc");
6186 if (r
!= MAILIMF_NO_ERROR
) {
6191 r
= mailimf_colon_parse(message
, length
, &cur_token
);
6192 if (r
!= MAILIMF_NO_ERROR
) {
6197 r
= mailimf_address_list_parse(message
, length
, &cur_token
, &addr_list
);
6198 if (r
!= MAILIMF_NO_ERROR
) {
6203 r
= mailimf_unstrict_crlf_parse(message
, length
, &cur_token
);
6204 if (r
!= MAILIMF_NO_ERROR
) {
6206 goto free_addr_list
;
6209 cc
= mailimf_cc_new(addr_list
);
6211 res
= MAILIMF_ERROR_MEMORY
;
6212 goto free_addr_list
;
6216 * index
= cur_token
;
6218 return MAILIMF_NO_ERROR
;
6221 mailimf_address_list_free(addr_list
);
6227 resent-bcc = "Resent-Bcc:" (address-list / [CFWS]) CRLF
6231 mailimf_resent_bcc_parse(const char * message
, size_t length
,
6232 size_t * index
, struct mailimf_bcc
** result
)
6234 struct mailimf_address_list
* addr_list
;
6235 struct mailimf_bcc
* bcc
;
6240 cur_token
= * index
;
6243 r
= mailimf_token_case_insensitive_parse(message
, length
,
6244 &cur_token
, "Resent-Bcc");
6245 if (r
!= MAILIMF_NO_ERROR
) {
6250 r
= mailimf_colon_parse(message
, length
, &cur_token
);
6251 if (r
!= MAILIMF_NO_ERROR
) {
6256 r
= mailimf_address_list_parse(message
, length
, &cur_token
, &addr_list
);
6257 if ((r
!= MAILIMF_NO_ERROR
) && (r
!= MAILIMF_ERROR_PARSE
)) {
6262 r
= mailimf_unstrict_crlf_parse(message
, length
, &cur_token
);
6263 if (r
!= MAILIMF_NO_ERROR
) {
6265 goto free_addr_list
;
6268 bcc
= mailimf_bcc_new(addr_list
);
6270 res
= MAILIMF_ERROR_MEMORY
;
6271 goto free_addr_list
;
6275 * index
= cur_token
;
6280 mailimf_address_list_free(addr_list
);
6286 resent-msg-id = "Resent-Message-ID:" msg-id CRLF
6290 mailimf_resent_msg_id_parse(const char * message
, size_t length
,
6292 struct mailimf_message_id
** result
)
6296 struct mailimf_message_id
* message_id
;
6300 cur_token
= * index
;
6302 r
= mailimf_token_case_insensitive_parse(message
, length
,
6303 &cur_token
, "Resent-Message-ID");
6304 if (r
!= MAILIMF_NO_ERROR
) {
6309 r
= mailimf_colon_parse(message
, length
, &cur_token
);
6310 if (r
!= MAILIMF_NO_ERROR
) {
6315 r
= mailimf_msg_id_parse(message
, length
, &cur_token
, &value
);
6316 if (r
!= MAILIMF_NO_ERROR
) {
6321 r
= mailimf_unstrict_crlf_parse(message
, length
, &cur_token
);
6322 if (r
!= MAILIMF_NO_ERROR
) {
6327 message_id
= mailimf_message_id_new(value
);
6328 if (message_id
== NULL
) {
6329 res
= MAILIMF_ERROR_MEMORY
;
6333 * result
= message_id
;
6334 * index
= cur_token
;
6336 return MAILIMF_NO_ERROR
;
6339 mailimf_msg_id_free(value
);
6350 static int mailimf_trace_parse(const char * message
, size_t length
,
6352 struct mailimf_trace
** result
)
6355 struct mailimf_return
* return_path
;
6356 clist
* received_list
;
6357 struct mailimf_trace
* trace
;
6361 cur_token
= * index
;
6363 received_list
= NULL
;
6365 r
= mailimf_return_parse(message
, length
, &cur_token
, &return_path
);
6366 if ((r
!= MAILIMF_NO_ERROR
) && (r
!= MAILIMF_ERROR_PARSE
)) {
6371 r
= mailimf_struct_multiple_parse(message
, length
, &cur_token
,
6373 (mailimf_struct_parser
*)
6374 mailimf_received_parse
,
6375 (mailimf_struct_destructor
*)
6376 mailimf_received_free
);
6377 if ((r
!= MAILIMF_NO_ERROR
) && (r
!= MAILIMF_ERROR_PARSE
)) {
6382 if ((received_list
== NULL
) && (return_path
== NULL
)) {
6383 res
= MAILIMF_ERROR_PARSE
;
6387 trace
= mailimf_trace_new(return_path
, received_list
);
6388 if (trace
== NULL
) {
6389 res
= MAILIMF_ERROR_MEMORY
;
6394 * index
= cur_token
;
6396 return MAILIMF_NO_ERROR
;
6399 clist_foreach(received_list
, (clist_func
) mailimf_received_free
, NULL
);
6400 clist_free(received_list
);
6402 if (return_path
!= NULL
)
6403 mailimf_return_free(return_path
);
6410 return = "Return-Path:" path CRLF
6413 static int mailimf_return_parse(const char * message
, size_t length
,
6415 struct mailimf_return
** result
)
6417 struct mailimf_path
* path
= NULL
;
6418 struct mailimf_return
* return_path
;
6423 cur_token
= * index
;
6425 r
= mailimf_token_case_insensitive_parse(message
, length
,
6426 &cur_token
, "Return-Path");
6427 if (r
!= MAILIMF_NO_ERROR
) {
6432 r
= mailimf_colon_parse(message
, length
, &cur_token
);
6433 if (r
!= MAILIMF_NO_ERROR
) {
6438 r
= mailimf_path_parse(message
, length
, &cur_token
, &path
);
6439 if ( r
!= MAILIMF_NO_ERROR
) {
6444 r
= mailimf_unstrict_crlf_parse(message
, length
, &cur_token
);
6445 if (r
!= MAILIMF_NO_ERROR
) {
6450 return_path
= mailimf_return_new(path
);
6451 if (return_path
== NULL
) {
6452 res
= MAILIMF_ERROR_MEMORY
;
6456 * result
= return_path
;
6457 * index
= cur_token
;
6459 return MAILIMF_NO_ERROR
;
6462 mailimf_path_free(path
);
6468 path = ([CFWS] "<" ([CFWS] / addr-spec) ">" [CFWS]) /
6472 static int mailimf_path_parse(const char * message
, size_t length
,
6473 size_t * index
, struct mailimf_path
** result
)
6477 struct mailimf_path
* path
;
6481 cur_token
= * index
;
6484 r
= mailimf_cfws_parse(message
, length
, &cur_token
);
6485 if ((r
!= MAILIMF_NO_ERROR
) && (r
!= MAILIMF_ERROR_PARSE
)) {
6490 r
= mailimf_lower_parse(message
, length
, &cur_token
);
6491 if (r
!= MAILIMF_NO_ERROR
) {
6496 r
= mailimf_addr_spec_parse(message
, length
, &cur_token
, &addr_spec
);
6498 case MAILIMF_NO_ERROR
:
6500 case MAILIMF_ERROR_PARSE
:
6501 r
= mailimf_cfws_parse(message
, length
, &cur_token
);
6502 if ((r
!= MAILIMF_NO_ERROR
) && (r
!= MAILIMF_ERROR_PARSE
)) {
6511 r
= mailimf_greater_parse(message
, length
, &cur_token
);
6512 if (r
!= MAILIMF_NO_ERROR
) {
6514 goto free_addr_spec
;
6517 path
= mailimf_path_new(addr_spec
);
6519 res
= MAILIMF_ERROR_MEMORY
;
6520 goto free_addr_spec
;
6523 * index
= cur_token
;
6526 return MAILIMF_NO_ERROR
;
6529 if (addr_spec
!= NULL
)
6530 mailimf_addr_spec_free(addr_spec
);
6536 received = "Received:" name-val-list ";" date-time CRLF
6540 static int mailimf_received_parse(const char * message
, size_t length
,
6542 struct mailimf_received
** result
)
6545 struct mailimf_received
* received
;
6546 struct mailimf_name_val_list
* name_val_list
;
6547 struct mailimf_date_time
* date_time
;
6551 cur_token
= * index
;
6553 r
= mailimf_token_case_insensitive_parse(message
, length
,
6554 &cur_token
, "Received");
6555 if (r
!= MAILIMF_NO_ERROR
) {
6560 r
= mailimf_colon_parse(message
, length
, &cur_token
);
6561 if (r
!= MAILIMF_NO_ERROR
) {
6566 r
= mailimf_name_val_list_parse(message
, length
,
6567 &cur_token
, &name_val_list
);
6568 if (r
!= MAILIMF_NO_ERROR
) {
6573 r
= mailimf_semi_colon_parse(message
, length
, &cur_token
);
6574 if (r
!= MAILIMF_NO_ERROR
) {
6576 goto free_name_val_list
;
6579 r
= mailimf_date_time_parse(message
, length
, &cur_token
, &date_time
);
6580 if (r
!= MAILIMF_NO_ERROR
) {
6582 goto free_name_val_list
;
6585 r
= mailimf_unstrict_crlf_parse(message
, length
, &cur_token
);
6586 if (r
!= MAILIMF_NO_ERROR
) {
6588 goto free_date_time
;
6591 received
= mailimf_received_new(name_val_list
, date_time
);
6592 if (received
== NULL
) {
6593 res
= MAILIMF_ERROR_MEMORY
;
6594 goto free_date_time
;
6597 * index
= cur_token
;
6598 * result
= received
;
6600 return MAILIMF_NO_ERROR
;
6603 mailimf_date_time_free(date_time
);
6605 mailimf_name_val_list_free(name_val_list
);
6612 name-val-list = [CFWS] [name-val-pair *(CFWS name-val-pair)]
6617 mailimf_name_val_list_parse(const char * message
, size_t length
,
6619 struct mailimf_name_val_list
** result
)
6622 struct mailimf_name_val_pair
* pair
;
6623 struct mailimf_name_val_list
* name_val_list
;
6628 cur_token
= * index
;
6631 r
= mailimf_name_val_pair_parse(message
, length
, &cur_token
, &pair
);
6633 if (r
== MAILIMF_NO_ERROR
){
6638 mailimf_name_val_pair_free(pair
);
6639 res
= MAILIMF_ERROR_MEMORY
;
6643 r
= clist_append(list
, pair
);
6645 mailimf_name_val_pair_free(pair
);
6646 res
= MAILIMF_ERROR_MEMORY
;
6650 final_token
= cur_token
;
6653 r
= mailimf_cfws_parse(message
, length
, &cur_token
);
6654 if ((r
!= MAILIMF_NO_ERROR
) && (r
!= MAILIMF_ERROR_PARSE
)) {
6659 r
= mailimf_name_val_pair_parse(message
, length
, &cur_token
, &pair
);
6660 if (r
== MAILIMF_NO_ERROR
) {
6663 else if (r
== MAILIMF_ERROR_PARSE
)
6670 r
= clist_append(list
, pair
);
6672 mailimf_name_val_pair_free(pair
);
6673 res
= MAILIMF_ERROR_MEMORY
;
6677 final_token
= cur_token
;
6679 cur_token
= final_token
;
6682 name_val_list
= mailimf_name_val_list_new(list
);
6683 if (name_val_list
== NULL
) {
6684 res
= MAILIMF_ERROR_MEMORY
;
6688 * index
= cur_token
;
6689 * result
= name_val_list
;
6691 return MAILIMF_NO_ERROR
;
6695 clist_foreach(list
, (clist_func
) mailimf_name_val_pair_free
, NULL
);
6704 name-val-pair = item-name CFWS item-value
6709 mailimf_name_val_pair_parse(const char * message
, size_t length
,
6711 struct mailimf_name_val_pair
** result
)
6715 struct mailimf_item_value
* item_value
;
6716 struct mailimf_name_val_pair
* name_val_pair
;
6720 cur_token
= * index
;
6722 r
= mailimf_cfws_parse(message
, length
, &cur_token
);
6723 if ((r
!= MAILIMF_NO_ERROR
) && (r
!= MAILIMF_ERROR_PARSE
)) {
6728 r
= mailimf_item_name_parse(message
, length
, &cur_token
, &item_name
);
6729 if (r
!= MAILIMF_NO_ERROR
) {
6734 r
= mailimf_cfws_parse(message
, length
, &cur_token
);
6735 if (r
!= MAILIMF_NO_ERROR
) {
6737 goto free_item_name
;
6740 r
= mailimf_item_value_parse(message
, length
, &cur_token
, &item_value
);
6741 if (r
!= MAILIMF_NO_ERROR
) {
6743 goto free_item_name
;
6746 name_val_pair
= mailimf_name_val_pair_new(item_name
, item_value
);
6747 if (name_val_pair
== NULL
) {
6748 res
= MAILIMF_ERROR_MEMORY
;
6749 goto free_item_value
;
6752 * result
= name_val_pair
;
6753 * index
= cur_token
;
6755 return MAILIMF_NO_ERROR
;
6758 mailimf_item_value_free(item_value
);
6760 mailimf_item_name_free(item_name
);
6767 item-name = ALPHA *(["-"] (ALPHA / DIGIT))
6771 static int mailimf_item_name_parse(const char * message
, size_t length
,
6772 size_t * index
, char ** result
)
6782 cur_token
= * index
;
6786 r
= mailimf_alpha_parse(message
, length
, &cur_token
, &ch
);
6787 if (r
!= MAILIMF_NO_ERROR
) {
6795 minus_sign
= mailimf_minus_parse(message
, length
, &cur_token
);
6797 r
= mailimf_alpha_parse(message
, length
, &cur_token
, &ch
);
6798 if (r
== MAILIMF_ERROR_PARSE
)
6799 r
= mailimf_digit_parse(message
, length
, &cur_token
, &digit
);
6801 if (r
== MAILIMF_NO_ERROR
) {
6804 if (r
== MAILIMF_ERROR_PARSE
)
6806 else if (r
!= MAILIMF_NO_ERROR
) {
6812 item_name
= strndup(message
+ begin
, cur_token
- begin
);
6813 if (item_name
== NULL
) {
6814 res
= MAILIMF_ERROR_MEMORY
;
6818 * index
= cur_token
;
6819 * result
= item_name
;
6821 return MAILIMF_NO_ERROR
;
6829 item-value = 1*angle-addr / addr-spec /
6830 atom / domain / msg-id
6834 static int is_item_value_atext(char ch
)
6848 static int mailimf_item_value_atom_parse(const char * message
, size_t length
,
6849 size_t * index
, char ** result
)
6855 cur_token
= * index
;
6857 r
= mailimf_cfws_parse(message
, length
, &cur_token
);
6858 if ((r
!= MAILIMF_NO_ERROR
) && (r
!= MAILIMF_ERROR_PARSE
))
6861 r
= mailimf_custom_string_parse(message
, length
, &cur_token
,
6862 &atom
, is_item_value_atext
);
6863 if (r
!= MAILIMF_NO_ERROR
)
6866 r
= mailimf_cfws_parse(message
, length
, &cur_token
);
6867 if ((r
!= MAILIMF_NO_ERROR
) && (r
!= MAILIMF_ERROR_PARSE
))
6870 * index
= cur_token
;
6873 return MAILIMF_NO_ERROR
;
6876 static int mailimf_item_value_parse(const char * message
, size_t length
,
6878 struct mailimf_item_value
** result
)
6881 clist
* angle_addr_list
;
6887 struct mailimf_item_value
* item_value
;
6891 cur_token
= * index
;
6893 angle_addr_list
= NULL
;
6899 r
= mailimf_struct_multiple_parse(message
, length
, &cur_token
,
6901 (mailimf_struct_parser
*)
6902 mailimf_angle_addr_parse
,
6903 (mailimf_struct_destructor
*)
6904 mailimf_angle_addr_free
);
6905 if (r
== MAILIMF_NO_ERROR
)
6906 type
= MAILIMF_ITEM_VALUE_ANGLE_ADDR_LIST
;
6908 if (r
== MAILIMF_ERROR_PARSE
) {
6909 r
= mailimf_addr_spec_parse(message
, length
, &cur_token
,
6911 if (r
== MAILIMF_NO_ERROR
)
6912 type
= MAILIMF_ITEM_VALUE_ADDR_SPEC
;
6915 if (r
== MAILIMF_ERROR_PARSE
) {
6916 r
= mailimf_msg_id_parse(message
, length
, &cur_token
,
6918 if (r
== MAILIMF_NO_ERROR
)
6919 type
= MAILIMF_ITEM_VALUE_MSG_ID
;
6923 else if (mailimf_domain_parse(message, length, &cur_token,
6925 type = MAILIMF_ITEM_VALUE_DOMAIN;
6928 else if (mailimf_atom_parse(message, length, &cur_token,
6930 type = MAILIMF_ITEM_VALUE_ATOM;
6933 if (r
== MAILIMF_ERROR_PARSE
) {
6934 r
= mailimf_item_value_atom_parse(message
, length
, &cur_token
,
6936 if (r
== MAILIMF_NO_ERROR
)
6937 type
= MAILIMF_ITEM_VALUE_ATOM
;
6940 if (r
!= MAILIMF_NO_ERROR
) {
6945 item_value
= mailimf_item_value_new(type
, angle_addr_list
, addr_spec
,
6946 atom
, domain
, msg_id
);
6947 if (item_value
== NULL
) {
6948 res
= MAILIMF_ERROR_MEMORY
;
6952 * result
= item_value
;
6953 * index
= cur_token
;
6955 return MAILIMF_NO_ERROR
;
6958 if (angle_addr_list
!= NULL
) {
6959 clist_foreach(angle_addr_list
, (clist_func
) mailimf_angle_addr_free
, NULL
);
6960 clist_free(angle_addr_list
);
6962 if (addr_spec
!= NULL
)
6963 mailimf_addr_spec_free(addr_spec
);
6965 mailimf_atom_free(atom
);
6967 mailimf_domain_free(domain
);
6969 mailimf_msg_id_free(msg_id
);
6976 optional-field = field-name ":" unstructured CRLF
6980 mailimf_optional_field_parse(const char * message
, size_t length
,
6982 struct mailimf_optional_field
** result
)
6986 struct mailimf_optional_field
* optional_field
;
6993 optional_field
= NULL
;
6995 cur_token
= * index
;
6997 r
= mailimf_field_name_parse(message
, length
, &cur_token
, &name
);
6998 if (r
!= MAILIMF_NO_ERROR
) {
7003 r
= mailimf_colon_parse(message
, length
, &cur_token
);
7004 if (r
!= MAILIMF_NO_ERROR
) {
7009 r
= mailimf_unstructured_parse(message
, length
, &cur_token
, &value
);
7010 if (r
!= MAILIMF_NO_ERROR
) {
7015 r
= mailimf_unstrict_crlf_parse(message
, length
, &cur_token
);
7016 if (r
!= MAILIMF_NO_ERROR
) {
7021 optional_field
= mailimf_optional_field_new(name
, value
);
7022 if (optional_field
== NULL
) {
7023 res
= MAILIMF_ERROR_MEMORY
;
7027 * result
= optional_field
;
7028 * index
= cur_token
;
7030 return MAILIMF_NO_ERROR
;
7034 mailimf_unstructured_free(value
);
7036 mailimf_field_name_free(name
);
7043 field-name = 1*ftext
7046 static inline int is_ftext(char ch
);
7048 static int mailimf_field_name_parse(const char * message
, size_t length
,
7049 size_t * index
, char ** result
)
7055 cur_token
= * index
;
7058 if (end
>= length
) {
7059 return MAILIMF_ERROR_PARSE
;
7062 while (is_ftext(message
[end
])) {
7067 if (end
== cur_token
) {
7068 return MAILIMF_ERROR_PARSE
;
7071 /* field_name = strndup(message + cur_token, end - cur_token); */
7072 field_name
= malloc(end
- cur_token
+ 1);
7073 if (field_name
== NULL
) {
7074 return MAILIMF_ERROR_MEMORY
;
7076 strncpy(field_name
, message
+ cur_token
, end
- cur_token
);
7077 field_name
[end
- cur_token
] = '\0';
7081 * index
= cur_token
;
7082 * result
= field_name
;
7084 return MAILIMF_NO_ERROR
;
7088 ftext = %d33-57 / ; Any character except
7089 %d59-126 ; controls, SP, and
7093 static inline int is_ftext(char ch
)
7095 unsigned char uch
= (unsigned char) ch
;
7107 static int mailimf_ftext_parse(const char * message, size_t length,
7108 size_t * index, gchar * result)
7110 return mailimf_typed_text_parse(message, length, index, result, is_ftext);
7117 static int mailimf_envelope_field_parse(const char * message
, size_t length
,
7119 struct mailimf_field
** result
)
7123 struct mailimf_orig_date
* orig_date
;
7124 struct mailimf_from
* from
;
7125 struct mailimf_sender
* sender
;
7126 struct mailimf_reply_to
* reply_to
;
7127 struct mailimf_to
* to
;
7128 struct mailimf_cc
* cc
;
7129 struct mailimf_bcc
* bcc
;
7130 struct mailimf_message_id
* message_id
;
7131 struct mailimf_in_reply_to
* in_reply_to
;
7132 struct mailimf_references
* references
;
7133 struct mailimf_subject
* subject
;
7134 struct mailimf_field
* field
;
7139 cur_token
= * index
;
7153 guessed_type
= guess_header_type(message
, length
, cur_token
);
7154 type
= MAILIMF_FIELD_NONE
;
7156 switch (guessed_type
) {
7157 case MAILIMF_FIELD_ORIG_DATE
:
7158 r
= mailimf_orig_date_parse(message
, length
, &cur_token
,
7160 if (r
== MAILIMF_NO_ERROR
)
7161 type
= guessed_type
;
7162 else if (r
== MAILIMF_ERROR_PARSE
) {
7170 case MAILIMF_FIELD_FROM
:
7171 r
= mailimf_from_parse(message
, length
, &cur_token
,
7173 if (r
== MAILIMF_NO_ERROR
)
7174 type
= guessed_type
;
7175 else if (r
== MAILIMF_ERROR_PARSE
) {
7183 case MAILIMF_FIELD_SENDER
:
7184 r
= mailimf_sender_parse(message
, length
, &cur_token
,
7186 if (r
== MAILIMF_NO_ERROR
)
7187 type
= guessed_type
;
7188 else if (r
== MAILIMF_ERROR_PARSE
) {
7196 case MAILIMF_FIELD_REPLY_TO
:
7197 r
= mailimf_reply_to_parse(message
, length
, &cur_token
,
7199 if (r
== MAILIMF_NO_ERROR
)
7200 type
= guessed_type
;
7201 else if (r
== MAILIMF_ERROR_PARSE
) {
7209 case MAILIMF_FIELD_TO
:
7210 r
= mailimf_to_parse(message
, length
, &cur_token
,
7212 if (r
== MAILIMF_NO_ERROR
)
7213 type
= guessed_type
;
7214 else if (r
== MAILIMF_ERROR_PARSE
) {
7222 case MAILIMF_FIELD_CC
:
7223 r
= mailimf_cc_parse(message
, length
, &cur_token
,
7225 if (r
== MAILIMF_NO_ERROR
)
7226 type
= guessed_type
;
7227 else if (r
== MAILIMF_ERROR_PARSE
) {
7235 case MAILIMF_FIELD_BCC
:
7236 r
= mailimf_bcc_parse(message
, length
, &cur_token
,
7238 if (r
== MAILIMF_NO_ERROR
)
7239 type
= guessed_type
;
7240 else if (r
== MAILIMF_ERROR_PARSE
) {
7248 case MAILIMF_FIELD_MESSAGE_ID
:
7249 r
= mailimf_message_id_parse(message
, length
, &cur_token
,
7251 if (r
== MAILIMF_NO_ERROR
)
7252 type
= guessed_type
;
7253 else if (r
== MAILIMF_ERROR_PARSE
) {
7261 case MAILIMF_FIELD_IN_REPLY_TO
:
7262 r
= mailimf_in_reply_to_parse(message
, length
, &cur_token
,
7264 if (r
== MAILIMF_NO_ERROR
)
7265 type
= guessed_type
;
7266 else if (r
== MAILIMF_ERROR_PARSE
) {
7274 case MAILIMF_FIELD_REFERENCES
:
7275 r
= mailimf_references_parse(message
, length
, &cur_token
,
7277 if (r
== MAILIMF_NO_ERROR
)
7278 type
= guessed_type
;
7279 else if (r
== MAILIMF_ERROR_PARSE
) {
7287 case MAILIMF_FIELD_SUBJECT
:
7288 r
= mailimf_subject_parse(message
, length
, &cur_token
,
7290 if (r
== MAILIMF_NO_ERROR
)
7291 type
= guessed_type
;
7292 else if (r
== MAILIMF_ERROR_PARSE
) {
7302 if (type
== MAILIMF_FIELD_NONE
) {
7303 res
= MAILIMF_ERROR_PARSE
;
7307 field
= mailimf_field_new(type
, NULL
, NULL
, NULL
, NULL
, NULL
,
7309 orig_date
, from
, sender
, reply_to
, to
,
7310 cc
, bcc
, message_id
, in_reply_to
, references
,
7311 subject
, NULL
, NULL
, NULL
);
7312 if (field
== NULL
) {
7313 res
= MAILIMF_ERROR_MEMORY
;
7318 * index
= cur_token
;
7320 return MAILIMF_NO_ERROR
;
7323 if (orig_date
!= NULL
)
7324 mailimf_orig_date_free(orig_date
);
7326 mailimf_from_free(from
);
7328 mailimf_sender_free(sender
);
7329 if (reply_to
!= NULL
)
7330 mailimf_reply_to_free(reply_to
);
7332 mailimf_to_free(to
);
7334 mailimf_cc_free(cc
);
7336 mailimf_bcc_free(bcc
);
7337 if (message_id
!= NULL
)
7338 mailimf_message_id_free(message_id
);
7339 if (in_reply_to
!= NULL
)
7340 mailimf_in_reply_to_free(in_reply_to
);
7341 if (references
!= NULL
)
7342 mailimf_references_free(references
);
7343 if (subject
!= NULL
)
7344 mailimf_subject_free(subject
);
7349 int mailimf_envelope_fields_parse(const char * message
, size_t length
,
7351 struct mailimf_fields
** result
)
7355 struct mailimf_fields
* fields
;
7359 cur_token
= * index
;
7363 res
= MAILIMF_ERROR_MEMORY
;
7368 struct mailimf_field
* elt
;
7370 r
= mailimf_envelope_field_parse(message
, length
, &cur_token
, &elt
);
7371 if (r
== MAILIMF_NO_ERROR
) {
7372 r
= clist_append(list
, elt
);
7374 res
= MAILIMF_ERROR_MEMORY
;
7378 else if (r
== MAILIMF_ERROR_PARSE
) {
7379 r
= mailimf_ignore_field_parse(message
, length
, &cur_token
);
7380 if (r
== MAILIMF_NO_ERROR
) {
7383 else if (r
== MAILIMF_ERROR_PARSE
) {
7397 fields
= mailimf_fields_new(list
);
7398 if (fields
== NULL
) {
7399 res
= MAILIMF_ERROR_MEMORY
;
7404 * index
= cur_token
;
7406 return MAILIMF_NO_ERROR
;
7410 clist_foreach(list
, (clist_func
) mailimf_field_free
, NULL
);
7419 mailimf_envelope_or_optional_field_parse(const char * message
,
7422 struct mailimf_field
** result
)
7426 struct mailimf_optional_field
* optional_field
;
7427 struct mailimf_field
* field
;
7429 r
= mailimf_envelope_field_parse(message
, length
, index
, result
);
7430 if (r
== MAILIMF_NO_ERROR
)
7431 return MAILIMF_NO_ERROR
;
7433 cur_token
= * index
;
7435 r
= mailimf_optional_field_parse(message
, length
, &cur_token
,
7437 if (r
!= MAILIMF_NO_ERROR
)
7440 field
= mailimf_field_new(MAILIMF_FIELD_OPTIONAL_FIELD
, NULL
,
7445 NULL
, NULL
, NULL
, NULL
, NULL
,
7446 NULL
, NULL
, NULL
, optional_field
);
7447 if (field
== NULL
) {
7448 mailimf_optional_field_free(optional_field
);
7449 return MAILIMF_ERROR_MEMORY
;
7453 * index
= cur_token
;
7455 return MAILIMF_NO_ERROR
;
7460 mailimf_envelope_and_optional_fields_parse(const char * message
, size_t length
,
7462 struct mailimf_fields
** result
)
7466 struct mailimf_fields
* fields
;
7470 cur_token
= * index
;
7474 r
= mailimf_struct_multiple_parse(message
, length
, &cur_token
,
7476 (mailimf_struct_parser
*)
7477 mailimf_envelope_or_optional_field_parse
,
7478 (mailimf_struct_destructor
*)
7479 mailimf_field_free
);
7481 case MAILIMF_NO_ERROR
:
7485 case MAILIMF_ERROR_PARSE
:
7488 res
= MAILIMF_ERROR_MEMORY
;
7498 fields
= mailimf_fields_new(list
);
7499 if (fields
== NULL
) {
7500 res
= MAILIMF_ERROR_MEMORY
;
7505 * index
= cur_token
;
7507 return MAILIMF_NO_ERROR
;
7511 clist_foreach(list
, (clist_func
) mailimf_field_free
, NULL
);
7521 mailimf_only_optional_field_parse(const char * message
,
7524 struct mailimf_field
** result
)
7528 struct mailimf_optional_field
* optional_field
;
7529 struct mailimf_field
* field
;
7531 cur_token
= * index
;
7533 r
= mailimf_optional_field_parse(message
, length
, &cur_token
,
7535 if (r
!= MAILIMF_NO_ERROR
)
7538 field
= mailimf_field_new(MAILIMF_FIELD_OPTIONAL_FIELD
, NULL
, NULL
, NULL
,
7539 NULL
, NULL
, NULL
, NULL
, NULL
,
7540 NULL
, NULL
, NULL
, NULL
, NULL
,
7541 NULL
, NULL
, NULL
, NULL
, NULL
,
7542 NULL
, NULL
, NULL
, optional_field
);
7543 if (field
== NULL
) {
7544 mailimf_optional_field_free(optional_field
);
7545 return MAILIMF_ERROR_MEMORY
;
7549 * index
= cur_token
;
7551 return MAILIMF_NO_ERROR
;
7556 mailimf_optional_fields_parse(const char * message
, size_t length
,
7558 struct mailimf_fields
** result
)
7562 struct mailimf_fields
* fields
;
7566 cur_token
= * index
;
7570 r
= mailimf_struct_multiple_parse(message
, length
, &cur_token
,
7572 (mailimf_struct_parser
*)
7573 mailimf_only_optional_field_parse
,
7574 (mailimf_struct_destructor
*)
7575 mailimf_field_free
);
7577 case MAILIMF_NO_ERROR
:
7581 case MAILIMF_ERROR_PARSE
:
7584 res
= MAILIMF_ERROR_MEMORY
;
7594 fields
= mailimf_fields_new(list
);
7595 if (fields
== NULL
) {
7596 res
= MAILIMF_ERROR_MEMORY
;
7601 * index
= cur_token
;
7603 return MAILIMF_NO_ERROR
;
7607 clist_foreach(list
, (clist_func
) mailimf_field_free
, NULL
);