diff --git a/src/mrimfparser.cpp b/src/mrimfparser.cpp index 9d5febf1..5edb9341 100644 --- a/src/mrimfparser.cpp +++ b/src/mrimfparser.cpp @@ -363,7 +363,7 @@ int32_t MrImfParser::Imf2Msg(const char* imf_raw, size_t imf_len) // fine, so far. now, split the message into simple parts usable as "short messages" // and add them to the database (mails send by other LibreChat clients should result // into only one message; mails send by other clients may result in several messages (eg. one per attachment)) - mime_parser.Parse(NULL, imf->msg_body->bd_text); + mime_parser.Parse(NULL, imf_raw); part_cnt = carray_count(mime_parser.m_parts); // should be at least one - maybe empty - part for( part_i = 0; part_i < part_cnt; part_i++ ) { diff --git a/src/mrmimeparser.cpp b/src/mrmimeparser.cpp index affa19c2..6c92389e 100644 --- a/src/mrmimeparser.cpp +++ b/src/mrmimeparser.cpp @@ -33,6 +33,343 @@ #include "mrtools.h" +/******************************************************************************* + * debug output + ******************************************************************************/ + + +#define DEBUG_MIME_OUTPUT 1 + + +#if DEBUG_MIME_OUTPUT + + +static void display_mime_content(struct mailmime_content * content_type); + +static void display_mime_data(struct mailmime_data * data) +{ + switch (data->dt_type) { + case MAILMIME_DATA_TEXT: + printf("data : %u bytes\n", (unsigned int) data->dt_data.dt_text.dt_length); + break; + case MAILMIME_DATA_FILE: + printf("data (file) : %s\n", data->dt_data.dt_filename); + break; + } +} + +static void display_mime_dsp_parm(struct mailmime_disposition_parm * param) +{ + switch (param->pa_type) { + case MAILMIME_DISPOSITION_PARM_FILENAME: + printf("filename: %s\n", param->pa_data.pa_filename); + break; + } +} + +static void display_mime_disposition(struct mailmime_disposition * disposition) +{ + clistiter * cur; + + for(cur = clist_begin(disposition->dsp_parms) ; + cur != NULL ; cur = clist_next(cur)) { + struct mailmime_disposition_parm * param; + + param = (mailmime_disposition_parm*)clist_content(cur); + display_mime_dsp_parm(param); + } +} + +static void display_mime_field(struct mailmime_field * field) +{ + switch (field->fld_type) { + case MAILMIME_FIELD_TYPE: + printf("content-type: "); + display_mime_content(field->fld_data.fld_content); + printf("\n"); + break; + case MAILMIME_FIELD_DISPOSITION: + display_mime_disposition(field->fld_data.fld_disposition); + break; + } +} + +static void display_mime_fields(struct mailmime_fields * fields) +{ + clistiter * cur; + + for(cur = clist_begin(fields->fld_list) ; cur != NULL ; cur = clist_next(cur)) { + struct mailmime_field * field; + + field = (mailmime_field*)clist_content(cur); + display_mime_field(field); + } +} + +static void display_date_time(struct mailimf_date_time * d) +{ + printf("%02i/%02i/%i %02i:%02i:%02i %+04i", + d->dt_day, d->dt_month, d->dt_year, + d->dt_hour, d->dt_min, d->dt_sec, d->dt_zone); +} + +static void display_orig_date(struct mailimf_orig_date * orig_date) +{ + display_date_time(orig_date->dt_date_time); +} + +static void display_mailbox(struct mailimf_mailbox * mb) +{ + if (mb->mb_display_name != NULL) + printf("%s ", mb->mb_display_name); + printf("<%s>", mb->mb_addr_spec); +} + +static void display_mailbox_list(struct mailimf_mailbox_list * mb_list) +{ + clistiter * cur; + + for(cur = clist_begin(mb_list->mb_list) ; cur != NULL ; + cur = clist_next(cur)) { + struct mailimf_mailbox * mb; + + mb = (mailimf_mailbox*)clist_content(cur); + + display_mailbox(mb); + if (clist_next(cur) != NULL) { + printf(", "); + } + } +} + +static void display_group(struct mailimf_group * group) +{ + clistiter * cur; + + printf("%s: ", group->grp_display_name); + for(cur = clist_begin(group->grp_mb_list->mb_list) ; cur != NULL ; cur = clist_next(cur)) { + struct mailimf_mailbox * mb; + + mb = (mailimf_mailbox*)clist_content(cur); + display_mailbox(mb); + } + printf("; "); +} + +static void display_address(struct mailimf_address * a) +{ + switch (a->ad_type) { + case MAILIMF_ADDRESS_GROUP: + display_group(a->ad_data.ad_group); + break; + + case MAILIMF_ADDRESS_MAILBOX: + display_mailbox(a->ad_data.ad_mailbox); + break; + } +} + +static void display_address_list(struct mailimf_address_list * addr_list) +{ + clistiter * cur; + + for(cur = clist_begin(addr_list->ad_list) ; cur != NULL ; + cur = clist_next(cur)) { + struct mailimf_address * addr; + + addr = (mailimf_address*)clist_content(cur); + + display_address(addr); + + if (clist_next(cur) != NULL) { + printf(", "); + } + } +} + +static void display_from(struct mailimf_from * from) +{ + display_mailbox_list(from->frm_mb_list); +} + +static void display_to(struct mailimf_to * to) +{ + display_address_list(to->to_addr_list); +} + +static void display_cc(struct mailimf_cc * cc) +{ + display_address_list(cc->cc_addr_list); +} + +static void display_subject(struct mailimf_subject * subject) +{ + printf("%s", subject->sbj_value); +} + +static void display_field(struct mailimf_field * field) +{ + switch (field->fld_type) { + case MAILIMF_FIELD_ORIG_DATE: + printf("Date: "); + display_orig_date(field->fld_data.fld_orig_date); + printf("\n"); + break; + case MAILIMF_FIELD_FROM: + printf("From: "); + display_from(field->fld_data.fld_from); + printf("\n"); + break; + case MAILIMF_FIELD_TO: + printf("To: "); + display_to(field->fld_data.fld_to); + printf("\n"); + break; + case MAILIMF_FIELD_CC: + printf("Cc: "); + display_cc(field->fld_data.fld_cc); + printf("\n"); + break; + case MAILIMF_FIELD_SUBJECT: + printf("Subject: "); + display_subject(field->fld_data.fld_subject); + printf("\n"); + break; + case MAILIMF_FIELD_MESSAGE_ID: + printf("Message-ID: %s\n", field->fld_data.fld_message_id->mid_value); + break; + } +} + +static void display_fields(struct mailimf_fields * fields) +{ + clistiter * cur; + + for(cur = clist_begin(fields->fld_list) ; cur != NULL ; + cur = clist_next(cur)) { + struct mailimf_field * f; + + f = (mailimf_field*)clist_content(cur); + + display_field(f); + } +} + +static void display_mime_discrete_type(struct mailmime_discrete_type * discrete_type) +{ + switch (discrete_type->dt_type) { + case MAILMIME_DISCRETE_TYPE_TEXT: + printf("text"); + break; + case MAILMIME_DISCRETE_TYPE_IMAGE: + printf("image"); + break; + case MAILMIME_DISCRETE_TYPE_AUDIO: + printf("audio"); + break; + case MAILMIME_DISCRETE_TYPE_VIDEO: + printf("video"); + break; + case MAILMIME_DISCRETE_TYPE_APPLICATION: + printf("application"); + break; + case MAILMIME_DISCRETE_TYPE_EXTENSION: + printf("%s", discrete_type->dt_extension); + break; + } +} + +static void display_mime_composite_type(struct mailmime_composite_type * ct) +{ + switch (ct->ct_type) { + case MAILMIME_COMPOSITE_TYPE_MESSAGE: + printf("message"); + break; + case MAILMIME_COMPOSITE_TYPE_MULTIPART: + printf("multipart"); + break; + case MAILMIME_COMPOSITE_TYPE_EXTENSION: + printf("%s", ct->ct_token); + break; + } +} + +static void display_mime_type(struct mailmime_type * type) +{ + switch (type->tp_type) { + case MAILMIME_TYPE_DISCRETE_TYPE: + display_mime_discrete_type(type->tp_data.tp_discrete_type); + break; + case MAILMIME_TYPE_COMPOSITE_TYPE: + display_mime_composite_type(type->tp_data.tp_composite_type); + break; + } +} + +static void display_mime_content(struct mailmime_content * content_type) +{ + printf("type: "); + display_mime_type(content_type->ct_type); + printf("/%s\n", content_type->ct_subtype); +} + +static void display_mime(struct mailmime * mime) +{ + clistiter * cur; + + switch (mime->mm_type) { + case MAILMIME_SINGLE: + printf("single part\n"); + break; + case MAILMIME_MULTIPLE: + printf("multipart\n"); + break; + case MAILMIME_MESSAGE: + printf("message\n"); + break; + } + + if (mime->mm_mime_fields != NULL) { + if (clist_begin(mime->mm_mime_fields->fld_list) != NULL) { + printf("MIME headers begin\n"); + display_mime_fields(mime->mm_mime_fields); + printf("MIME headers end\n"); + } + } + + display_mime_content(mime->mm_content_type); + + switch (mime->mm_type) { + case MAILMIME_SINGLE: + display_mime_data(mime->mm_data.mm_single); + break; + + case MAILMIME_MULTIPLE: + for(cur = clist_begin(mime->mm_data.mm_multipart.mm_mp_list) ; cur != NULL ; cur = clist_next(cur)) { + display_mime((mailmime*)clist_content(cur)); + } + break; + + case MAILMIME_MESSAGE: + if (mime->mm_data.mm_message.mm_fields) { + if (clist_begin(mime->mm_data.mm_message.mm_fields->fld_list) != NULL) { + printf("headers begin\n"); + display_fields(mime->mm_data.mm_message.mm_fields); + printf("headers end\n"); + } + + if (mime->mm_data.mm_message.mm_msg_mime != NULL) { + display_mime(mime->mm_data.mm_message.mm_msg_mime); + } + break; + } + } +} + +#endif // DEBUG_MIME_OUTPUT + + + /******************************************************************************* * a MIME part ******************************************************************************/ @@ -103,6 +440,12 @@ carray* MrMimeParser::Parse(const char* subject, const char* body) goto Parse_Cleanup; } + #if DEBUG_MIME_OUTPUT + printf("-----------------------------------------------------------------------\n"); + display_mime(mime); + printf("-----------------------------------------------------------------------\n"); + #endif + // check parsing result if( (part=new MrMimePart())==NULL ) { goto Parse_Cleanup; @@ -111,7 +454,7 @@ carray* MrMimeParser::Parse(const char* subject, const char* body) part->m_txt = save_strdup((char*)body); carray_add(m_parts, (void*)part, NULL); - // Cleanup + // Cleanup - and try to create at least an empty part if there are no parts yet Parse_Cleanup: if( carray_count(m_parts)==0 ) { if( (part=new MrMimePart())!=NULL ) {