From 658ec82f9930f51d35496d0972ddc702ebfb5cc9 Mon Sep 17 00:00:00 2001 From: rbbrnc Date: Mon, 11 Apr 2011 14:40:21 +0200 Subject: [PATCH] Move common functions to mail.c --- src/utils/mail.c | 117 +++++++++++++++++++++++++++++++++++++++++++++ src/utils/mail.h | 22 ++++++--- src/utils/test_view_mail.c | 94 ++---------------------------------- 3 files changed, 138 insertions(+), 95 deletions(-) create mode 100644 src/utils/mail.c diff --git a/src/utils/mail.c b/src/utils/mail.c new file mode 100644 index 0000000..ee41339 --- /dev/null +++ b/src/utils/mail.c @@ -0,0 +1,117 @@ +#include +#include + +#include "rfc822.h" +#include "rfc5322.h" + +#include "md5_utils.h" + +#include "mime.h" + +#include "mail.h" + +void init_mail_header(struct mail_header *hdr) +{ + memset(hdr->from, 0, sizeof(hdr->from)); + memset(hdr->subject, 0, sizeof(hdr->subject)); + + hdr->body_offset = 0L; + + /* MIME */ + /* [RFC2045] + * If no Content-Type header field is specified, default to: + * Content-type: text/plain; charset=us-ascii + */ + hdr->mime.type = MIME_TYPE_TEXT; + hdr->mime.type_charset = MIME_TYPE_CHARSET_US_ASCII; + hdr->mime.subtype = MIME_SUBTYPE_PLAIN; + hdr->mime.disposition = MIME_DISPOSITION_UNKNOWN; + + /* [RFC2045] "Content-Transfer-Encoding: 7BIT" is assumed if the + * Content-Transfer-Encoding header field is not present. + * ... If a Content-Transfer-Encoding header field appears as part + * of a message header, it applies to the entire body of that message. + * If a Content-Transfer-Encoding header field appears as part of an + * entity's headers, it applies only to the body of that entity. + * If an entity is of type "multipart" the Content-Transfer-Encoding + * is not permitted to have any value other than "7bit", "8bit" or + * "binary". + */ + hdr->mime.transfer_encoding = MIME_ENCODING_7BIT; +} + +void parse_mail_header(FILE *fh, struct mail_header *hdr) +{ + char buf[1024]; + char *crlf; + unsigned int fld_cont; /* RFC822 Header field folding flag */ + unsigned int fa_valid; /* Valid From Address flag */ + + crlf = NULL; + fld_cont = 0; + fa_valid = 0; + + /* Scan all lines */ + do { + /* + * Don't get a new line if we are coming from a folding + * field + */ + if (!fld_cont) { + if (fgets(buf, sizeof(buf), fh) == NULL) { + break; + } + } + + fld_cont = 0; + + if (!strncasecmp(buf, "From:", 5)) { + rfc5322_extract_address(hdr->from, buf, sizeof(hdr->from)); + fa_valid = 1; + } else if (!strncasecmp(buf, "Reply-to:", 9)) { + if (fa_valid) + continue; + + if (!rfc5322_extract_address(hdr->from, buf, sizeof(hdr->from))) { + fa_valid = 1; + } + + } else if (!strncasecmp(buf, "Subject:", 8)) { + rfc5322_extract_subject(hdr->subject, buf, sizeof(hdr->subject)); + } else if (!strncasecmp(buf, "Date:", 5)) { + hdr->date = rfc822_parsedt(buf); + } else if (!strncasecmp(buf, "Content-Type:", 13)) { + mime_content_type(buf + 14, &hdr->mime); + + while (fgets(buf, sizeof(buf), fh)) { + if (rfc822_check_field_folding(buf)) { + /* Decode folded line */ + mime_content_type_parameter(buf, &hdr->mime); + } else { + fld_cont = 1; + break; + } + } + } else if (!strncasecmp(buf, "Content-Disposition:", 20)) { + mime_content_disposition(buf + 21, &hdr->mime); + } else if (!strncasecmp(buf, "Content-Transfer-Encoding:", 26)) { + mime_content_transfer_encoding(buf + 27, &hdr->mime); + } else { + /*printf("[SKIP] ------- %s", buf);*/ + } + } while (!rfc822_check_header_end(buf)); + + /* If a valid 'from' address was found calc the MD5 of this address */ + if (fa_valid) { + crlf = strrchr(hdr->from, '\n'); + if (crlf) + *crlf = '\0'; + + md5_calc_sum(hdr->from, hdr->addr_md5); + } + + /* Get file offset of the message body */ + hdr->body_offset = ftell(fh); +} + + diff --git a/src/utils/mail.h b/src/utils/mail.h index 6110276..011d1ba 100644 --- a/src/utils/mail.h +++ b/src/utils/mail.h @@ -1,18 +1,28 @@ #ifndef MAIL_H #define MAIL_H +#include +#include + #include "mime.h" +#define LINE_LENGTH 1024 + struct mail_header { - char from[1024]; - char subject[1024]; - unsigned char addr_md5[16]; + char filename[1024]; /* Filename */ + char from[LINE_LENGTH]; /* From or Reply-To address */ + char subject[LINE_LENGTH]; /* Subject */ + unsigned char addr_md5[16]; /* MD5 sum of 'from' field */ - time_t date; + time_t date; /* Mail date time */ - long body_offset; + long body_offset; /* File offset of start of msg body */ - struct mime_header mime; + struct mime_header mime; /* MIME informations */ }; + +void init_mail_header(struct mail_header *hdr); +void parse_mail_header(FILE *fh, struct mail_header *hdr); + #endif /* MAIL_H */ diff --git a/src/utils/test_view_mail.c b/src/utils/test_view_mail.c index dcd0f4c..644b231 100644 --- a/src/utils/test_view_mail.c +++ b/src/utils/test_view_mail.c @@ -18,6 +18,7 @@ #include "rfc2047.h" #include "rfc822.h" #include "mime.h" +#include "md5_utils.h" #include "mail.h" static int hdr_only = 0; @@ -58,99 +59,12 @@ static void parse_mail_body(FILE *fh, struct mail_header *hdr) } } -static void parse_mail_header(FILE *fh, struct mail_header *hdr) -{ - char buf[1024]; - char *crlf; - unsigned int fld_cont; /* RFC822 Header field folding flag */ - - crlf = NULL; - fld_cont = 0; - - /* Scan all lines */ - do { - /* - * Don't get a new line if we are coming from a folding - * field - */ - if (!fld_cont) { - if (fgets(buf, sizeof(buf), fh) == NULL) { - break; - } - } - - fld_cont = 0; - - if (!strncasecmp(buf, "From:", 5)) { - rfc5322_extract_address(hdr->from, buf, sizeof(hdr->from)); - crlf = strrchr(buf, '\n'); - if (crlf) - *crlf = '\0'; - } else if (!strncasecmp(buf, "Subject:", 8)) { - rfc5322_extract_subject(hdr->subject, buf, sizeof(hdr->subject)); - } else if (!strncasecmp(buf, "Date:", 5)) { - hdr->date = rfc822_parsedt(buf); - } else if (!strncasecmp(buf, "Content-Type:", 13)) { - mime_content_type(buf + 14, &hdr->mime); - - while (fgets(buf, sizeof(buf), fh)) { - if (rfc822_check_field_folding(buf)) { - /* Decode folded line */ - mime_content_type_parameter(buf, &hdr->mime); - } else { - fld_cont = 1; - break; - } - } - } else if (!strncasecmp(buf, "Content-Disposition:", 20)) { - mime_content_disposition(buf + 21, &hdr->mime); - } else if (!strncasecmp(buf, "Content-Transfer-Encoding:", 26)) { - mime_content_transfer_encoding(buf + 27, &hdr->mime); - } else { - /*printf("[SKIP] ------- %s", buf);*/ - } - } while (!rfc822_check_header_end(buf)); - - /* Get file offset of the message body */ - hdr->body_offset = ftell(fh); -} - -static void init_mail_header(struct mail_header *hdr) -{ - memset(hdr->from, 0, sizeof(hdr->from)); - memset(hdr->subject, 0, sizeof(hdr->subject)); - - hdr->body_offset = 0L; - - /* MIME */ - /* [RFC2045] - * If no Content-Type header field is specified, default to: - * Content-type: text/plain; charset=us-ascii - */ - hdr->mime.type = MIME_TYPE_TEXT; - hdr->mime.type_charset = MIME_TYPE_CHARSET_US_ASCII; - hdr->mime.subtype = MIME_SUBTYPE_PLAIN; - hdr->mime.disposition = MIME_DISPOSITION_UNKNOWN; - - /* [RFC2045] "Content-Transfer-Encoding: 7BIT" is assumed if the - * Content-Transfer-Encoding header field is not present. - * ... If a Content-Transfer-Encoding header field appears as part - * of a message header, it applies to the entire body of that message. - * If a Content-Transfer-Encoding header field appears as part of an - * entity's headers, it applies only to the body of that entity. - * If an entity is of type "multipart" the Content-Transfer-Encoding - * is not permitted to have any value other than "7bit", "8bit" or - * "binary". - */ - hdr->mime.transfer_encoding = MIME_ENCODING_7BIT; -} - void usage(const char *appname) { fprintf(stderr, "Usage:\n%s options\n", appname); fprintf(stderr, "Options:\n"); fprintf(stderr, " -h Parse header only\n" - " -m Parse MIMI only\n" + " -m Parse MIME only\n" " -f Parse file\n" " -d Parse maildir\n"); } @@ -170,10 +84,12 @@ static void parse_file(const char *file) init_mail_header(&mail_hdr); + strncpy(mail_hdr.filename, file, 1024); + parse_mail_header(fh, &mail_hdr); fprintf(stderr, "-------------------------------------------\n"); - fprintf(stderr, "Test file: %s\n", file); + fprintf(stderr, "Test file: %s\n", mail_hdr.filename); fprintf(stderr, "-------------------------------------------\n"); if (!mime_only) { fprintf(stderr, "Date : %s\n", rfc822_mkdt(mail_hdr.date)); -- 2.11.4.GIT