Diffstat (limited to 'kmicromail/libetpan/imf/mailimf.c') (more/less context) (ignore whitespace changes)
-rw-r--r-- | kmicromail/libetpan/imf/mailimf.c | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/kmicromail/libetpan/imf/mailimf.c b/kmicromail/libetpan/imf/mailimf.c index 84d81a1..e0164b8 100644 --- a/kmicromail/libetpan/imf/mailimf.c +++ b/kmicromail/libetpan/imf/mailimf.c @@ -1,1075 +1,1075 @@ /* * libEtPan! -- a mail stuff library * * Copyright (C) 2001, 2002 - DINH Viet Hoa * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the libEtPan! project nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * $Id$ */ #include "mailimf.h" /* RFC 2822 RFC 2821 ... A message-originating SMTP system SHOULD NOT send a message that already contains a Return-path header. SMTP servers performing a relay function MUST NOT inspect the message data, and especially not to the extent needed to determine if Return-path headers are present. SMTP servers making final delivery MAY remove Return-path headers before adding their own. */ #include <ctype.h> -#include <mmapstring.h> +#include "mmapstring.h" #include <stdlib.h> #include <string.h> #ifndef TRUE #define TRUE 1 #endif #ifndef FALSE #define FALSE 0 #endif static inline int is_dtext(char ch); static int mailimf_quoted_pair_parse(const char * message, size_t length, size_t * index, char * result); static int mailimf_ccontent_parse(const char * message, size_t length, size_t * index); static int mailimf_comment_fws_ccontent_parse(const char * message, size_t length, size_t * index); static inline int mailimf_comment_parse(const char * message, size_t length, size_t * index); static int mailimf_qcontent_parse(const char * message, size_t length, size_t * index, char * ch); static int mailimf_phrase_parse(const char * message, size_t length, size_t * index, char ** result); static int mailimf_unstructured_parse(const char * message, size_t length, size_t * index, char ** result); static int mailimf_ignore_unstructured_parse(const char * message, size_t length, size_t * index); static int mailimf_day_of_week_parse(const char * message, size_t length, size_t * index, int * result); static int mailimf_day_name_parse(const char * message, size_t length, size_t * index, int * result); static int mailimf_date_parse(const char * message, size_t length, size_t * index, int * pday, int * pmonth, int * pyear); static int mailimf_year_parse(const char * message, size_t length, size_t * index, int * result); static int mailimf_month_parse(const char * message, size_t length, size_t * index, int * result); static int mailimf_month_name_parse(const char * message, size_t length, size_t * index, int * result); static int mailimf_day_parse(const char * message, size_t length, size_t * index, int * result); static int mailimf_time_parse(const char * message, size_t length, size_t * index, int * phour, int * pmin, int * psec, int * zone); static int mailimf_time_of_day_parse(const char * message, size_t length, size_t * index, int * phour, int * pmin, int * psec); static int mailimf_hour_parse(const char * message, size_t length, size_t * index, int * result); static int mailimf_minute_parse(const char * message, size_t length, size_t * index, int * result); static int mailimf_second_parse(const char * message, size_t length, size_t * index, int * result); static int mailimf_zone_parse(const char * message, size_t length, size_t * index, int * result); static int mailimf_name_addr_parse(const char * message, size_t length, size_t * index, char ** pdisplay_name, char ** pangle_addr); static int mailimf_angle_addr_parse(const char * message, size_t length, size_t * index, char ** result); static int mailimf_group_parse(const char * message, size_t length, size_t * index, struct mailimf_group ** result); static int mailimf_display_name_parse(const char * message, size_t length, size_t * index, char ** result); static int mailimf_addr_spec_parse(const char * message, size_t length, size_t * index, char ** address); #if 0 static int mailimf_local_part_parse(const char * message, size_t length, size_t * index, char ** result); static int mailimf_domain_parse(const char * message, size_t length, size_t * index, char ** result); #endif #if 0 static int mailimf_domain_literal_parse(const char * message, size_t length, size_t * index, char ** result); #endif #if 0 static int mailimf_dcontent_parse(const char * message, size_t length, size_t * index, char * result); #endif static int mailimf_orig_date_parse(const char * message, size_t length, size_t * index, struct mailimf_orig_date ** result); static int mailimf_from_parse(const char * message, size_t length, size_t * index, struct mailimf_from ** result); static int mailimf_sender_parse(const char * message, size_t length, size_t * index, struct mailimf_sender ** result); static int mailimf_reply_to_parse(const char * message, size_t length, size_t * index, struct mailimf_reply_to ** result); static int mailimf_to_parse(const char * message, size_t length, size_t * index, struct mailimf_to ** result); static int mailimf_cc_parse(const char * message, size_t length, size_t * index, struct mailimf_cc ** result); static int mailimf_bcc_parse(const char * message, size_t length, size_t * index, struct mailimf_bcc ** result); static int mailimf_message_id_parse(const char * message, size_t length, size_t * index, struct mailimf_message_id ** result); static int mailimf_in_reply_to_parse(const char * message, size_t length, size_t * index, struct mailimf_in_reply_to ** result); #if 0 static int mailimf_references_parse(const char * message, size_t length, size_t * index, struct mailimf_references ** result); #endif static int mailimf_unstrict_msg_id_parse(const char * message, size_t length, size_t * index, char ** result); #if 0 static int mailimf_id_left_parse(const char * message, size_t length, size_t * index, char ** result); static int mailimf_id_right_parse(const char * message, size_t length, size_t * index, char ** result); #endif #if 0 static int mailimf_no_fold_quote_parse(const char * message, size_t length, size_t * index, char ** result); static int mailimf_no_fold_literal_parse(const char * message, size_t length, size_t * index, char ** result); #endif static int mailimf_subject_parse(const char * message, size_t length, size_t * index, struct mailimf_subject ** result); static int mailimf_comments_parse(const char * message, size_t length, size_t * index, struct mailimf_comments ** result); static int mailimf_keywords_parse(const char * message, size_t length, size_t * index, struct mailimf_keywords ** result); static int mailimf_resent_date_parse(const char * message, size_t length, size_t * index, struct mailimf_orig_date ** result); static int mailimf_resent_from_parse(const char * message, size_t length, size_t * index, struct mailimf_from ** result); static int mailimf_resent_sender_parse(const char * message, size_t length, size_t * index, struct mailimf_sender ** result); static int mailimf_resent_to_parse(const char * message, size_t length, size_t * index, struct mailimf_to ** result); static int mailimf_resent_cc_parse(const char * message, size_t length, size_t * index, struct mailimf_cc ** result); static int mailimf_resent_bcc_parse(const char * message, size_t length, size_t * index, struct mailimf_bcc ** result); static int mailimf_resent_msg_id_parse(const char * message, size_t length, size_t * index, struct mailimf_message_id ** result); static int mailimf_return_parse(const char * message, size_t length, size_t * index, struct mailimf_return ** result); static int mailimf_path_parse(const char * message, size_t length, size_t * index, struct mailimf_path ** result); static int mailimf_optional_field_parse(const char * message, size_t length, size_t * index, struct mailimf_optional_field ** result); static int mailimf_field_name_parse(const char * message, size_t length, size_t * index, char ** result); /* *************************************************************** */ static inline int is_digit(char ch) { return (ch >= '0') && (ch <= '9'); } static int mailimf_digit_parse(const char * message, size_t length, size_t * index, int * result) { size_t cur_token; cur_token = * index; if (cur_token >= length) return MAILIMF_ERROR_PARSE; if (is_digit(message[cur_token])) { * result = message[cur_token] - '0'; cur_token ++; * index = cur_token; return MAILIMF_NO_ERROR; } else return MAILIMF_ERROR_PARSE; } int mailimf_number_parse(const char * message, size_t length, size_t * index, uint32_t * result) { size_t cur_token; int digit; uint32_t number; int parsed; int r; cur_token = * index; parsed = FALSE; number = 0; while (1) { r = mailimf_digit_parse(message, length, &cur_token, &digit); if (r != MAILIMF_NO_ERROR) { if (r == MAILIMF_ERROR_PARSE) break; else return r; } number *= 10; number += digit; parsed = TRUE; } if (!parsed) return MAILIMF_ERROR_PARSE; * result = number; * index = cur_token; return MAILIMF_NO_ERROR; } int mailimf_char_parse(const char * message, size_t length, size_t * index, char token) { size_t cur_token; cur_token = * index; if (cur_token >= length) return MAILIMF_ERROR_PARSE; if (message[cur_token] == token) { cur_token ++; * index = cur_token; return MAILIMF_NO_ERROR; } else return MAILIMF_ERROR_PARSE; } int mailimf_unstrict_char_parse(const char * message, size_t length, size_t * index, char token) { size_t cur_token; int r; cur_token = * index; r = mailimf_cfws_parse(message, length, &cur_token); if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) return r; r = mailimf_char_parse(message, length, &cur_token, token); if (r != MAILIMF_NO_ERROR) return r; * index = cur_token; return MAILIMF_NO_ERROR; } int mailimf_token_case_insensitive_len_parse(const char * message, size_t length, size_t * index, char * token, size_t token_length) { size_t cur_token; cur_token = * index; if (cur_token + token_length - 1 >= length) return MAILIMF_ERROR_PARSE; if (strncasecmp(message + cur_token, token, token_length) == 0) { cur_token += token_length; * index = cur_token; return MAILIMF_NO_ERROR; } else return MAILIMF_ERROR_PARSE; } static int mailimf_oparenth_parse(const char * message, size_t length, size_t * index) { return mailimf_char_parse(message, length, index, '('); } static int mailimf_cparenth_parse(const char * message, size_t length, size_t * index) { return mailimf_char_parse(message, length, index, ')'); } static int mailimf_comma_parse(const char * message, size_t length, size_t * index) { return mailimf_unstrict_char_parse(message, length, index, ','); } static int mailimf_dquote_parse(const char * message, size_t length, size_t * index) { return mailimf_char_parse(message, length, index, '\"'); } static int mailimf_colon_parse(const char * message, size_t length, size_t * index) { return mailimf_unstrict_char_parse(message, length, index, ':'); } static int mailimf_semi_colon_parse(const char * message, size_t length, size_t * index) { return mailimf_unstrict_char_parse(message, length, index, ';'); } static int mailimf_plus_parse(const char * message, size_t length, size_t * index) { return mailimf_unstrict_char_parse(message, length, index, '+'); } static int mailimf_minus_parse(const char * message, size_t length, size_t * index) { return mailimf_unstrict_char_parse(message, length, index, '-'); } static int mailimf_lower_parse(const char * message, size_t length, size_t * index) { return mailimf_unstrict_char_parse(message, length, index, '<'); } static int mailimf_greater_parse(const char * message, size_t length, size_t * index) { return mailimf_unstrict_char_parse(message, length, index, '>'); } #if 0 static int mailimf_obracket_parse(const char * message, size_t length, size_t * index) { return mailimf_unstrict_char_parse(message, length, index, '['); } static int mailimf_cbracket_parse(const char * message, size_t length, size_t * index) { return mailimf_unstrict_char_parse(message, length, index, ']'); } #endif static int mailimf_at_sign_parse(const char * message, size_t length, size_t * index) { return mailimf_unstrict_char_parse(message, length, index, '@'); } static int mailimf_point_parse(const char * message, size_t length, size_t * index) { return mailimf_unstrict_char_parse(message, length, index, '.'); } int mailimf_custom_string_parse(const char * message, size_t length, size_t * index, char ** result, int (* is_custom_char)(char)) { size_t begin; size_t end; char * gstr; begin = * index; end = begin; if (end >= length) return MAILIMF_ERROR_PARSE; while (is_custom_char(message[end])) { end ++; if (end >= length) break; } if (end != begin) { /* gstr = strndup(message + begin, end - begin); */ gstr = malloc(end - begin + 1); if (gstr == NULL) return MAILIMF_ERROR_MEMORY; strncpy(gstr, message + begin, end - begin); gstr[end - begin] = '\0'; * index = end; * result = gstr; return MAILIMF_NO_ERROR; } else return MAILIMF_ERROR_PARSE; } typedef int mailimf_struct_parser(const char * message, size_t length, size_t * index, void * result); typedef int mailimf_struct_destructor(void * result); static int mailimf_struct_multiple_parse(const char * message, size_t length, size_t * index, clist ** result, mailimf_struct_parser * parser, mailimf_struct_destructor * destructor) { clist * struct_list; size_t cur_token; void * value; int r; int res; cur_token = * index; r = parser(message, length, &cur_token, &value); if (r != MAILIMF_NO_ERROR) { res = r; goto err; } struct_list = clist_new(); if (struct_list == NULL) { destructor(value); res = MAILIMF_ERROR_MEMORY; goto err; } r = clist_append(struct_list, value); if (r < 0) { destructor(value); res = MAILIMF_ERROR_MEMORY; goto free; } while (1) { r = parser(message, length, &cur_token, &value); if (r != MAILIMF_NO_ERROR) { if (r == MAILIMF_ERROR_PARSE) break; else { res = r; goto free; } } r = clist_append(struct_list, value); if (r < 0) { (* destructor)(value); res = MAILIMF_ERROR_MEMORY; goto free; } } * result = struct_list; * index = cur_token; return MAILIMF_NO_ERROR; free: clist_foreach(struct_list, (clist_func) destructor, NULL); clist_free(struct_list); err: return res; } static int mailimf_struct_list_parse(const char * message, size_t length, size_t * index, clist ** result, char symbol, mailimf_struct_parser * parser, mailimf_struct_destructor * destructor) { clist * struct_list; size_t cur_token; void * value; size_t final_token; int r; int res; cur_token = * index; r = parser(message, length, &cur_token, &value); if (r != MAILIMF_NO_ERROR) { res = r; goto err; } struct_list = clist_new(); if (struct_list == NULL) { destructor(value); res = MAILIMF_ERROR_MEMORY; goto err; } r = clist_append(struct_list, value); if (r < 0) { destructor(value); res = MAILIMF_ERROR_MEMORY; goto free; } final_token = cur_token; while (1) { r = mailimf_unstrict_char_parse(message, length, &cur_token, symbol); if (r != MAILIMF_NO_ERROR) { if (r == MAILIMF_ERROR_PARSE) break; else { res = r; goto free; } } r = parser(message, length, &cur_token, &value); if (r != MAILIMF_NO_ERROR) { if (r == MAILIMF_ERROR_PARSE) break; else { res = r; goto free; } } r = clist_append(struct_list, value); if (r < 0) { destructor(value); res = MAILIMF_ERROR_MEMORY; goto free; } final_token = cur_token; } * result = struct_list; * index = final_token; return MAILIMF_NO_ERROR; free: clist_foreach(struct_list, (clist_func) destructor, NULL); clist_free(struct_list); err: return res; } static inline int mailimf_wsp_parse(const char * message, size_t length, size_t * index) { size_t cur_token; cur_token = * index; if (cur_token >= length) return MAILIMF_ERROR_PARSE; if ((message[cur_token] != ' ') && (message[cur_token] != '\t')) return MAILIMF_ERROR_PARSE; cur_token ++; * index = cur_token; return MAILIMF_NO_ERROR; } int mailimf_crlf_parse(const char * message, size_t length, size_t * index) { size_t cur_token; int r; cur_token = * index; r = mailimf_char_parse(message, length, &cur_token, '\r'); if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) return r; r = mailimf_char_parse(message, length, &cur_token, '\n'); if (r != MAILIMF_NO_ERROR) return r; * index = cur_token; return MAILIMF_NO_ERROR; } static int mailimf_unstrict_crlf_parse(const char * message, size_t length, size_t * index) { size_t cur_token; int r; cur_token = * index; mailimf_cfws_parse(message, length, &cur_token); r = mailimf_char_parse(message, length, &cur_token, '\r'); if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) return r; r = mailimf_char_parse(message, length, &cur_token, '\n'); if (r != MAILIMF_NO_ERROR) return r; * index = cur_token; return MAILIMF_NO_ERROR; } /* ************************************************************************ */ /* RFC 2822 grammar */ /* NO-WS-CTL = %d1-8 / ; US-ASCII control characters %d11 / ; that do not include the %d12 / ; carriage return, line feed, %d14-31 / ; and white space characters %d127 */ static inline int is_no_ws_ctl(char ch) { if ((ch == 9) || (ch == 10) || (ch == 13)) return FALSE; if (ch == 127) return TRUE; return (ch >= 1) && (ch <= 31); } /* text = %d1-9 / ; Characters excluding CR and LF %d11 / %d12 / %d14-127 / obs-text */ /* specials = "(" / ")" / ; Special characters used in "<" / ">" / ; other parts of the syntax "[" / "]" / ":" / ";" / "@" / "\" / "," / "." / DQUOTE */ /* quoted-pair = ("\" text) / obs-qp */ static inline int mailimf_quoted_pair_parse(const char * message, size_t length, size_t * index, char * result) { size_t cur_token; cur_token = * index; if (cur_token + 1 >= length) return MAILIMF_ERROR_PARSE; if (message[cur_token] != '\\') return MAILIMF_ERROR_PARSE; cur_token ++; * result = message[cur_token]; cur_token ++; * index = cur_token; return MAILIMF_NO_ERROR; } /* FWS = ([*WSP CRLF] 1*WSP) / ; Folding white space obs-FWS */ int mailimf_fws_parse(const char * message, size_t length, size_t * index) { size_t cur_token; size_t final_token; int fws_1; int fws_2; int fws_3; int r; cur_token = * index; fws_1 = FALSE; while (1) { r = mailimf_wsp_parse(message, length, &cur_token); if (r != MAILIMF_NO_ERROR) { if (r == MAILIMF_ERROR_PARSE) break; else return r; } fws_1 = TRUE; } final_token = cur_token; r = mailimf_crlf_parse(message, length, &cur_token); switch (r) { case MAILIMF_NO_ERROR: fws_2 = TRUE; break; case MAILIMF_ERROR_PARSE: fws_2 = FALSE; break; default: return r; } fws_3 = FALSE; if (fws_2) { while (1) { r = mailimf_wsp_parse(message, length, &cur_token); if (r != MAILIMF_NO_ERROR) { if (r == MAILIMF_ERROR_PARSE) break; else return r; } fws_3 = TRUE; } } if ((!fws_1) && (!fws_3)) return MAILIMF_ERROR_PARSE; if (!fws_3) cur_token = final_token; * index = cur_token; return MAILIMF_NO_ERROR; } /* ctext = NO-WS-CTL / ; Non white space controls %d33-39 / ; The rest of the US-ASCII %d42-91 / ; characters not including "(", %d93-126 ; ")", or "\" */ static inline int is_ctext(char ch) { unsigned char uch = (unsigned char) ch; if (is_no_ws_ctl(ch)) return TRUE; if (uch < 33) return FALSE; if ((uch == 40) || (uch == 41)) return FALSE; if (uch == 92) return FALSE; if (uch == 127) return FALSE; return TRUE; } /* ccontent = ctext / quoted-pair / comment */ static inline int mailimf_ccontent_parse(const char * message, size_t length, size_t * index) { size_t cur_token; char ch; int r; cur_token = * index; if (cur_token >= length) return MAILIMF_ERROR_PARSE; if (is_ctext(message[cur_token])) { cur_token ++; } else { r = mailimf_quoted_pair_parse(message, length, &cur_token, &ch); if (r == MAILIMF_ERROR_PARSE) r = mailimf_comment_parse(message, length, &cur_token); if (r == MAILIMF_ERROR_PARSE) return r; } * index = cur_token; return MAILIMF_NO_ERROR; } /* [FWS] ccontent */ static inline int mailimf_comment_fws_ccontent_parse(const char * message, size_t length, size_t * index) { size_t cur_token; int r; cur_token = * index; r = mailimf_fws_parse(message, length, &cur_token); if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) return r; r = mailimf_ccontent_parse(message, length, &cur_token); if (r != MAILIMF_NO_ERROR) return r; * index = cur_token; return MAILIMF_NO_ERROR; } /* comment = "(" *([FWS] ccontent) [FWS] ")" */ static inline int mailimf_comment_parse(const char * message, size_t length, size_t * index) { size_t cur_token; int r; cur_token = * index; r = mailimf_oparenth_parse(message, length, &cur_token); if (r != MAILIMF_NO_ERROR) return r; while (1) { r = mailimf_comment_fws_ccontent_parse(message, length, &cur_token); if (r != MAILIMF_NO_ERROR) { if (r == MAILIMF_ERROR_PARSE) break; else return r; } } r = mailimf_fws_parse(message, length, &cur_token); if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) return r; r = mailimf_cparenth_parse(message, length, &cur_token); if (r != MAILIMF_NO_ERROR) return r; * index = cur_token; return MAILIMF_NO_ERROR; } /* [FWS] comment */ static inline int mailimf_cfws_fws_comment_parse(const char * message, size_t length, size_t * index) { size_t cur_token; int r; cur_token = * index; r = mailimf_fws_parse(message, length, &cur_token); if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) return r; r = mailimf_comment_parse(message, length, &cur_token); if (r != MAILIMF_NO_ERROR) |