summaryrefslogtreecommitdiffabout
path: root/kmicromail/libetpan/tests/readmsg-common.c
Side-by-side diff
Diffstat (limited to 'kmicromail/libetpan/tests/readmsg-common.c') (more/less context) (ignore whitespace changes)
-rw-r--r--kmicromail/libetpan/tests/readmsg-common.c720
1 files changed, 720 insertions, 0 deletions
diff --git a/kmicromail/libetpan/tests/readmsg-common.c b/kmicromail/libetpan/tests/readmsg-common.c
new file mode 100644
index 0000000..060497d
--- a/dev/null
+++ b/kmicromail/libetpan/tests/readmsg-common.c
@@ -0,0 +1,720 @@
+#include "readmsg-common.h"
+
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+
+/* returns TRUE is given MIME part is a text part */
+
+int etpan_mime_is_text(struct mailmime * build_info)
+{
+ if (build_info->mm_type == MAILMIME_SINGLE) {
+ if (build_info->mm_content_type != NULL) {
+ if (build_info->mm_content_type->ct_type->tp_type ==
+ MAILMIME_TYPE_DISCRETE_TYPE) {
+ if (build_info->mm_content_type->ct_type->tp_data.tp_discrete_type->dt_type ==
+ MAILMIME_DISCRETE_TYPE_TEXT)
+ return 1;
+ }
+ }
+ else
+ return 1;
+ }
+
+ return 0;
+}
+
+
+/* display content type */
+
+int show_part_info(FILE * f,
+ struct mailmime_single_fields * mime_fields,
+ struct mailmime_content * content)
+{
+ char * description;
+ char * filename;
+ int col;
+ int r;
+
+ description = mime_fields->fld_description;
+ filename = mime_fields->fld_disposition_filename;
+
+ col = 0;
+
+ r = fprintf(f, " [ Part ");
+ if (r < 0)
+ goto err;
+
+ if (content != NULL) {
+ r = mailmime_content_type_write(f, &col, content);
+ if (r != MAILIMF_NO_ERROR)
+ goto err;
+ }
+
+ if (filename != NULL) {
+ r = fprintf(f, " (%s)", filename);
+ if (r < 0)
+ goto err;
+ }
+
+ if (description != NULL) {
+ r = fprintf(f, " : %s", description);
+ if (r < 0)
+ goto err;
+ }
+
+ r = fprintf(f, " ]\n\n");
+ if (r < 0)
+ goto err;
+
+ return NO_ERROR;
+
+ err:
+ return ERROR_FILE;
+}
+
+/*
+ fetch the data of the mailmime_data structure whether it is a file
+ or a string.
+
+ data must be freed with mmap_string_unref()
+*/
+
+#if 0
+static int fetch_data(struct mailmime_data * data,
+ char ** result, size_t * result_len)
+{
+ int fd;
+ int r;
+ char * text;
+ struct stat buf;
+ int res;
+ MMAPString * mmapstr;
+
+ switch (data->dt_type) {
+ case MAILMIME_DATA_TEXT:
+ mmapstr = mmap_string_new_len(data->dt_data.dt_text.dt_data,
+ data->dt_data.dt_text.dt_length);
+ if (mmapstr == NULL) {
+ res = ERROR_MEMORY;
+ goto err;
+ }
+
+ * result = mmapstr->str;
+ * result_len = mmapstr->len;
+
+ return NO_ERROR;
+
+ case MAILMIME_DATA_FILE:
+ fd = open(data->dt_data.dt_filename, O_RDONLY);
+ if (fd < 0) {
+ res = ERROR_FILE;
+ goto err;
+ }
+
+ r = fstat(fd, &buf);
+ if (r < 0) {
+ res = ERROR_FILE;
+ goto close;
+ }
+
+ if (buf.st_size != 0) {
+ text = mmap(NULL, buf.st_size, PROT_READ, MAP_SHARED, fd, 0);
+ if (text == MAP_FAILED) {
+ res = ERROR_FILE;
+ goto close;
+ }
+
+ mmapstr = mmap_string_new_len(text, buf.st_size);
+ if (mmapstr == NULL) {
+ res = r;
+ goto unmap;
+ }
+
+ munmap(text, buf.st_size);
+ }
+ else {
+ mmapstr = mmap_string_new("");
+ if (mmapstr == NULL) {
+ res = r;
+ goto close;
+ }
+ }
+
+ close(fd);
+
+ * result = mmapstr->str;
+ * result_len = mmapstr->len;
+
+ return NO_ERROR;
+
+ default:
+ return ERROR_INVAL;
+ }
+
+ unmap:
+ munmap(text, buf.st_size);
+ close:
+ close(fd);
+ err:
+ return res;
+}
+#endif
+
+/* fetch message and decode if it is base64 or quoted-printable */
+
+int etpan_fetch_message(mailmessage * msg_info,
+ struct mailmime * mime_part,
+ struct mailmime_single_fields * fields,
+ char ** result, size_t * result_len)
+{
+ char * data;
+ size_t len;
+ int r;
+ int encoding;
+ char * decoded;
+ size_t decoded_len;
+ size_t cur_token;
+ int res;
+ int encoded;
+
+ encoded = 0;
+
+ r = mailmessage_fetch_section(msg_info,
+ mime_part, &data, &len);
+ if (r != MAIL_NO_ERROR) {
+ res = ERROR_FETCH;
+ goto err;
+ }
+
+ encoded = 1;
+
+ /* decode message */
+
+ if (encoded) {
+ if (fields->fld_encoding != NULL)
+ encoding = fields->fld_encoding->enc_type;
+ else
+ encoding = MAILMIME_MECHANISM_8BIT;
+ }
+ else {
+ encoding = MAILMIME_MECHANISM_8BIT;
+ }
+
+ cur_token = 0;
+ r = mailmime_part_parse(data, len, &cur_token,
+ encoding, &decoded, &decoded_len);
+ if (r != MAILIMF_NO_ERROR) {
+ res = ERROR_FETCH;
+ goto free;
+ }
+
+ mailmessage_fetch_result_free(msg_info, data);
+
+ * result = decoded;
+ * result_len = decoded_len;
+
+ return NO_ERROR;
+
+ free:
+ mailmessage_fetch_result_free(msg_info, data);
+ err:
+ return res;
+}
+
+
+/* fetch fields */
+
+struct mailimf_fields * fetch_fields(mailmessage * msg_info,
+ struct mailmime * mime)
+{
+ char * data;
+ size_t len;
+ int r;
+ size_t cur_token;
+ struct mailimf_fields * fields;
+
+ r = mailmessage_fetch_section_header(msg_info, mime, &data, &len);
+ if (r != MAIL_NO_ERROR)
+ return NULL;
+
+ cur_token = 0;
+ r = mailimf_fields_parse(data, len, &cur_token, &fields);
+ if (r != MAILIMF_NO_ERROR) {
+ mailmessage_fetch_result_free(msg_info, data);
+ return NULL;
+ }
+
+ mailmessage_fetch_result_free(msg_info, data);
+
+ return fields;
+}
+
+
+
+#define MAX_MAIL_COL 72
+
+/* write decoded mailbox */
+
+static int
+etpan_mailbox_write(FILE * f, int * col,
+ struct mailimf_mailbox * mb)
+{
+ int r;
+
+ if (* col > 1) {
+
+ if (* col + strlen(mb->mb_addr_spec) >= MAX_MAIL_COL) {
+ r = mailimf_string_write(f, col, "\r\n ", 3);
+ if (r != MAILIMF_NO_ERROR)
+ return ERROR_FILE;
+ * col = 1;
+ }
+ }
+
+ if (mb->mb_display_name) {
+ char * decoded_from;
+ size_t cur_token;
+
+ cur_token = 0;
+ r = mailmime_encoded_phrase_parse(DEST_CHARSET,
+ mb->mb_display_name, strlen(mb->mb_display_name),
+ &cur_token, DEST_CHARSET,
+ &decoded_from);
+ if (r != MAILIMF_NO_ERROR) {
+ decoded_from = strdup(mb->mb_display_name);
+ if (decoded_from == NULL)
+ return ERROR_MEMORY;
+ }
+
+ r = mailimf_quoted_string_write(f, col, decoded_from,
+ strlen(decoded_from));
+ if (r != MAILIMF_NO_ERROR) {
+ free(decoded_from);
+ return ERROR_FILE;
+ }
+
+ if (* col > 1) {
+
+ if (* col + strlen(decoded_from) + 3 >= MAX_MAIL_COL) {
+ r = mailimf_string_write(f, col, "\r\n ", 3);
+ if (r != MAILIMF_NO_ERROR) {
+ free(decoded_from);
+ return r;
+ }
+ * col = 1;
+ }
+ }
+
+ free(decoded_from);
+
+ r = mailimf_string_write(f, col, " <", 2);
+ if (r != MAILIMF_NO_ERROR)
+ return ERROR_FILE;
+
+ r = mailimf_string_write(f, col,
+ mb->mb_addr_spec, strlen(mb->mb_addr_spec));
+ if (r != MAILIMF_NO_ERROR)
+ return ERROR_FILE;
+
+ r = mailimf_string_write(f, col, ">", 1);
+ if (r != MAILIMF_NO_ERROR)
+ return ERROR_FILE;
+ }
+ else {
+ r = mailimf_string_write(f, col,
+ mb->mb_addr_spec, strlen(mb->mb_addr_spec));
+ if (r != MAILIMF_NO_ERROR)
+ return ERROR_FILE;
+ }
+
+
+ return NO_ERROR;
+
+}
+
+/* write decoded mailbox list */
+
+int
+etpan_mailbox_list_write(FILE * f, int * col,
+ struct mailimf_mailbox_list * mb_list)
+{
+ clistiter * cur;
+ int r;
+ int first;
+
+ first = 1;
+
+ for(cur = clist_begin(mb_list->mb_list) ; cur != NULL ;
+ cur = clist_next(cur)) {
+ struct mailimf_mailbox * mb;
+
+ mb = cur->data;
+
+ if (!first) {
+ r = mailimf_string_write(f, col, ", ", 2);
+ if (r != MAILIMF_NO_ERROR)
+ return ERROR_FILE;
+ }
+ else {
+ first = 0;
+ }
+
+ r = etpan_mailbox_write(f, col, mb);
+ if (r != NO_ERROR)
+ return r;
+ }
+
+ return NO_ERROR;
+}
+
+/* write decoded group */
+
+static int
+etpan_group_write(FILE * f, int * col,
+ struct mailimf_group * group)
+{
+ int r;
+
+ r = mailimf_string_write(f, col, group->grp_display_name,
+ strlen(group->grp_display_name));
+ if (r != MAILIMF_NO_ERROR)
+ return ERROR_FILE;
+
+ r = mailimf_string_write(f, col, ": ", 2);
+ if (r != MAILIMF_NO_ERROR)
+ return ERROR_FILE;
+
+ if (group->grp_mb_list != NULL) {
+ r = etpan_mailbox_list_write(f, col, group->grp_mb_list);
+ if (r != NO_ERROR)
+ return r;
+ }
+
+ r = mailimf_string_write(f, col, ";", 1);
+ if (r != MAILIMF_NO_ERROR)
+ return ERROR_FILE;
+
+ return NO_ERROR;
+}
+
+/* write decoded address */
+
+int
+etpan_address_write(FILE * f, int * col,
+ struct mailimf_address * addr)
+{
+ int r;
+
+ switch(addr->ad_type) {
+ case MAILIMF_ADDRESS_MAILBOX:
+ r = etpan_mailbox_write(f, col, addr->ad_data.ad_mailbox);
+ if (r != NO_ERROR)
+ return r;
+
+ break;
+
+ case MAILIMF_ADDRESS_GROUP:
+ r = etpan_group_write(f, col, addr->ad_data.ad_group);
+ if (r != NO_ERROR)
+ return r;
+
+ break;
+ }
+
+ return MAILIMF_NO_ERROR;
+}
+
+/* write decoded address list */
+
+int
+etpan_address_list_write(FILE * f, int * col,
+ struct mailimf_address_list * addr_list)
+{
+ clistiter * cur;
+ int r;
+ int first;
+
+ first = 1;
+
+ for(cur = clist_begin(addr_list->ad_list) ; cur != NULL ;
+ cur = clist_next(cur)) {
+ struct mailimf_address * addr;
+
+ addr = clist_content(cur);
+
+ if (!first) {
+ r = mailimf_string_write(f, col, ", ", 2);
+ if (r != MAILIMF_NO_ERROR)
+ return ERROR_FILE;
+ }
+ else {
+ first = 0;
+ }
+
+ r = etpan_address_write(f, col, addr);
+ if (r != NO_ERROR)
+ return r;
+ }
+
+ return NO_ERROR;
+}
+
+/* write decoded subject */
+
+static int etpan_subject_write(FILE * f, int * col,
+ char * subject)
+{
+ int r;
+ char * decoded_subject;
+ size_t cur_token;
+
+ r = mailimf_string_write(f, col, "Subject: ", 9);
+ if (r != MAILIMF_NO_ERROR) {
+ return ERROR_FILE;
+ }
+
+ cur_token = 0;
+ r = mailmime_encoded_phrase_parse(DEST_CHARSET,
+ subject, strlen(subject),
+ &cur_token, DEST_CHARSET,
+ &decoded_subject);
+ if (r != MAILIMF_NO_ERROR) {
+ decoded_subject = strdup(subject);
+ if (decoded_subject == NULL)
+ return ERROR_MEMORY;
+ }
+
+ r = mailimf_string_write(f, col, decoded_subject, strlen(decoded_subject));
+ if (r != MAILIMF_NO_ERROR) {
+ free(decoded_subject);
+ return ERROR_FILE;
+ }
+
+ free(decoded_subject);
+
+ r = mailimf_string_write(f, col, "\r\n", 2);
+ if (r != MAILIMF_NO_ERROR) {
+ return ERROR_FILE;
+ }
+ * col = 0;
+
+ return NO_ERROR;
+}
+
+/* write decoded fields */
+
+int fields_write(FILE * f, int * col,
+ struct mailimf_fields * fields)
+{
+ clistiter * cur;
+ int r;
+
+ for(cur = clist_begin(fields->fld_list) ; cur != NULL ;
+ cur = clist_next(cur)) {
+ struct mailimf_field * field;
+
+ field = clist_content(cur);
+
+ switch (field->fld_type) {
+ case MAILIMF_FIELD_FROM:
+ r = mailimf_string_write(f, col, "From: ", 6);
+ if (r != MAILIMF_NO_ERROR)
+ goto err;
+
+ r = etpan_mailbox_list_write(f, col,
+ field->fld_data.fld_from->frm_mb_list);
+ if (r != NO_ERROR)
+ goto err;
+
+ r = mailimf_string_write(f, col, "\r\n", 2);
+ if (r != MAILIMF_NO_ERROR)
+ goto err;
+ * col = 0;
+
+ break;
+
+ case MAILIMF_FIELD_REPLY_TO:
+ r = mailimf_string_write(f, col, "Reply-To: ", 10);
+ if (r != MAILIMF_NO_ERROR)
+ goto err;
+
+ r = etpan_address_list_write(f, col,
+ field->fld_data.fld_reply_to->rt_addr_list);
+ if (r != NO_ERROR)
+ goto err;
+
+ r = mailimf_string_write(f, col, "\r\n", 2);
+ if (r != MAILIMF_NO_ERROR)
+ goto err;
+ * col = 0;
+
+ break;
+
+ case MAILIMF_FIELD_TO:
+ r = mailimf_string_write(f, col, "To: ", 4);
+ if (r != MAILIMF_NO_ERROR)
+ goto err;
+
+ r = etpan_address_list_write(f, col,
+ field->fld_data.fld_to->to_addr_list);
+ if (r != NO_ERROR)
+ goto err;
+
+ r = mailimf_string_write(f, col, "\r\n", 2);
+ if (r != MAILIMF_NO_ERROR)
+ goto err;
+ * col = 0;
+
+ break;
+
+ case MAILIMF_FIELD_CC:
+ r = mailimf_string_write(f, col, "Cc: ", 4);
+ if (r != MAILIMF_NO_ERROR)
+ goto err;
+
+ r = etpan_address_list_write(f, col,
+ field->fld_data.fld_cc->cc_addr_list);
+ if (r != NO_ERROR)
+ goto err;
+
+ r = mailimf_string_write(f, col, "\r\n", 2);
+ if (r != MAILIMF_NO_ERROR)
+ goto err;
+ * col = 0;
+
+ break;
+
+ case MAILIMF_FIELD_BCC:
+ r = mailimf_string_write(f, col, "Bcc: ", 10);
+ if (r != MAILIMF_NO_ERROR)
+ goto err;
+
+ if (field->fld_data.fld_bcc->bcc_addr_list != NULL) {
+ r = etpan_address_list_write(f, col,
+ field->fld_data.fld_bcc->bcc_addr_list);
+ if (r != NO_ERROR)
+ goto err;
+ }
+
+ r = mailimf_string_write(f, col, "\r\n", 2);
+ if (r != MAILIMF_NO_ERROR)
+ goto err;
+ * col = 0;
+
+ break;
+
+ case MAILIMF_FIELD_SUBJECT:
+ r = etpan_subject_write(f, col, field->fld_data.fld_subject->sbj_value);
+ if (r != MAILIMF_NO_ERROR)
+ goto err;
+ break;
+
+ case MAILIMF_FIELD_RESENT_FROM:
+ r = mailimf_string_write(f, col, "Resent-From: ", 13);
+ if (r != MAILIMF_NO_ERROR)
+ goto err;
+
+ r = etpan_mailbox_list_write(f, col,
+ field->fld_data.fld_resent_from->frm_mb_list);
+ if (r != NO_ERROR)
+ goto err;
+
+ r = mailimf_string_write(f, col, "\r\n", 2);
+ if (r != MAILIMF_NO_ERROR)
+ goto err;
+ * col = 0;
+ break;
+
+ case MAILIMF_FIELD_RESENT_TO:
+ r = mailimf_string_write(f, col, "Resent-To: ", 11);
+ if (r != MAILIMF_NO_ERROR)
+ goto err;
+
+ r = etpan_address_list_write(f, col,
+ field->fld_data.fld_resent_to->to_addr_list);
+ if (r != NO_ERROR)
+ goto err;
+
+ r = mailimf_string_write(f, col, "\r\n", 2);
+ if (r != MAILIMF_NO_ERROR)
+ goto err;
+ * col = 0;
+
+ break;
+ case MAILIMF_FIELD_RESENT_CC:
+ r = mailimf_string_write(f, col, "Resent-Cc: ", 11);
+ if (r != MAILIMF_NO_ERROR)
+ goto err;
+
+ r = etpan_address_list_write(f, col,
+ field->fld_data.fld_resent_cc->cc_addr_list);
+ if (r != NO_ERROR)
+ goto err;
+
+ r = mailimf_string_write(f, col, "\r\n", 2);
+ if (r != MAILIMF_NO_ERROR)
+ goto err;
+ * col = 0;
+
+ break;
+ case MAILIMF_FIELD_RESENT_BCC:
+ r = mailimf_string_write(f, col, "Resent-Bcc: ", 12);
+ if (r != MAILIMF_NO_ERROR)
+ goto err;
+
+ if (field->fld_data.fld_resent_bcc->bcc_addr_list != NULL) {
+ r = etpan_address_list_write(f, col,
+ field->fld_data.fld_resent_bcc->bcc_addr_list);
+ if (r != NO_ERROR)
+ goto err;
+ }
+
+ r = mailimf_string_write(f, col, "\r\n", 2);
+ if (r != MAILIMF_NO_ERROR)
+ goto err;
+ * col = 0;
+
+ break;
+
+ case MAILIMF_FIELD_ORIG_DATE:
+ case MAILIMF_FIELD_RESENT_DATE:
+ r = mailimf_field_write(f, col, field);
+ if (r != MAILIMF_NO_ERROR)
+ goto err;
+ break;
+
+ case MAILIMF_FIELD_OPTIONAL_FIELD:
+ if ((strcasecmp(field->fld_data.fld_optional_field->fld_name,
+ "X-Mailer") == 0)
+ || (strncasecmp(field->fld_data.fld_optional_field->fld_name,
+ "Resent-", 7) == 0)
+ || (strcasecmp(field->fld_data.fld_optional_field->fld_name,
+ "Newsgroups") == 0)
+ || (strcasecmp(field->fld_data.fld_optional_field->fld_name,
+ "Followup-To") == 0)
+ || (strcasecmp(field->fld_data.fld_optional_field->fld_name,
+ "User-Agent") == 0)) {
+ r = mailimf_field_write(f, col, field);
+ if (r != MAILIMF_NO_ERROR)
+ goto err;
+ }
+ break;
+
+ case MAILIMF_FIELD_MESSAGE_ID:
+ case MAILIMF_FIELD_SENDER:
+ case MAILIMF_FIELD_IN_REPLY_TO:
+ case MAILIMF_FIELD_REFERENCES:
+ default:
+ break;
+ }
+ }
+
+ return NO_ERROR;
+
+ err:
+ return ERROR_FILE;
+}