static void prepare_mime_single(struct mailmime * mime) { struct mailmime_single_fields single_fields; int encoding; int r; if (mime->mm_mime_fields != NULL) { mailmime_single_fields_init(&single_fields, mime->mm_mime_fields, mime->mm_content_type); if (single_fields.fld_encoding != NULL) { encoding = single_fields.fld_encoding->enc_type; switch (encoding) { case MAILMIME_MECHANISM_8BIT: case MAILMIME_MECHANISM_7BIT: case MAILMIME_MECHANISM_BINARY: single_fields.fld_encoding->enc_type = MAILMIME_MECHANISM_QUOTED_PRINTABLE; break; } } else { struct mailmime_mechanism * mechanism; struct mailmime_field * field; mechanism = mailmime_mechanism_new(MAILMIME_MECHANISM_QUOTED_PRINTABLE, NULL); if (mechanism == NULL) return; field = mailmime_field_new(MAILMIME_FIELD_TRANSFER_ENCODING, NULL, mechanism, NULL, NULL, 0, NULL, NULL, NULL); if (field == NULL) { mailmime_mechanism_free(mechanism); return; } r = clist_append(mime->mm_mime_fields->fld_list, field); if (r < 0) { mailmime_field_free(field); return; } } } if (mime->mm_type == MAILMIME_SINGLE) { switch (mime->mm_data.mm_single->dt_encoding) { case MAILMIME_MECHANISM_8BIT: case MAILMIME_MECHANISM_7BIT: case MAILMIME_MECHANISM_BINARY: mime->mm_data.mm_single->dt_encoding = MAILMIME_MECHANISM_QUOTED_PRINTABLE; mime->mm_data.mm_single->dt_encoded = 0; break; } } }
static int etpan_fetch_mime(FILE * f, mailmessage * msg_info, struct mailmime * mime) { int r; clistiter * cur; struct mailmime_single_fields fields; int res; memset(&fields, 0, sizeof(struct mailmime_single_fields)); if (mime->mm_mime_fields != NULL) mailmime_single_fields_init(&fields, mime->mm_mime_fields, mime->mm_content_type); switch(mime->mm_type) { case MAILMIME_SINGLE: save_mime_content(msg_info, mime); break; case MAILMIME_MULTIPLE: for(cur = clist_begin(mime->mm_data.mm_multipart.mm_mp_list) ; cur != NULL ; cur = clist_next(cur)) { r = etpan_fetch_mime(f, msg_info, clist_content(cur)); if (r != NO_ERROR) { res = r; goto err; } } break; case MAILMIME_MESSAGE: if (mime->mm_data.mm_message.mm_msg_mime != NULL) { r = etpan_fetch_mime(f, msg_info, mime->mm_data.mm_message.mm_msg_mime); if (r != NO_ERROR) { res = r; goto err; } } break; } return NO_ERROR; err: return res; }
static int save_mime_content(mailmessage * msg_info, struct mailmime * mime_part) { char * body; size_t body_len; int r; char * filename; struct mailmime_single_fields fields; int res; memset(&fields, 0, sizeof(struct mailmime_single_fields)); if (mime_part->mm_mime_fields != NULL) mailmime_single_fields_init(&fields, mime_part->mm_mime_fields, mime_part->mm_content_type); filename = fields.fld_disposition_filename; if (filename == NULL) filename = fields.fld_content_name; if (filename == NULL) return ERROR_INVAL; r = etpan_fetch_message(msg_info, mime_part, &fields, &body, &body_len); if (r != NO_ERROR) { res = r; goto err; } printf("writing %s, %lu bytes\n", filename, (unsigned long) body_len); r = etpan_write_data(filename, body, body_len); if (r != NO_ERROR) { res = r; goto free; } mailmime_decoded_part_free(body); return NO_ERROR; free: mailmime_decoded_part_free(body); err: return res; }
struct mailmime_single_fields * mailmime_single_fields_new(struct mailmime_fields * fld_fields, struct mailmime_content * fld_content) { struct mailmime_single_fields * single_fields; single_fields = malloc(sizeof(struct mailmime_single_fields)); if (single_fields == NULL) goto err; mailmime_single_fields_init(single_fields, fld_fields, fld_content); return single_fields; err: return NULL; }
static int recursive_replace_single_parts(struct mailprivacy * privacy, struct mailmime * mime, int reencode) { int r; int res; clistiter * cur; mime->mm_mime_start = NULL; switch(mime->mm_type) { case MAILMIME_SINGLE: if (mime->mm_data.mm_single != NULL) { int encoding_type; struct mailmime_single_fields single_fields; mailmime_single_fields_init(&single_fields, mime->mm_mime_fields, mime->mm_content_type); if (single_fields.fld_encoding != NULL) encoding_type = single_fields.fld_encoding->enc_type; else encoding_type = -1; r = mime_data_replace(privacy, encoding_type, mime->mm_data.mm_single, reencode); if (r != MAIL_NO_ERROR) { res = r; goto err; } } break; case MAILMIME_MULTIPLE: if (mime->mm_data.mm_multipart.mm_preamble != NULL) { r = mime_data_replace(privacy, -1, mime->mm_data.mm_multipart.mm_preamble, reencode); if (r != MAIL_NO_ERROR) { res = r; goto err; } } if (mime->mm_data.mm_multipart.mm_epilogue != NULL) { r = mime_data_replace(privacy, -1, mime->mm_data.mm_multipart.mm_epilogue, reencode); if (r != MAIL_NO_ERROR) { res = r; goto err; } } for(cur = clist_begin(mime->mm_data.mm_multipart.mm_mp_list) ; cur != NULL ; cur = clist_next(cur)) { struct mailmime * child; child = clist_content(cur); r = recursive_replace_single_parts(privacy, child, reencode); if (r != MAIL_NO_ERROR) { res = r; goto err; } } break; case MAILMIME_MESSAGE: if (mime->mm_data.mm_message.mm_msg_mime != NULL) { r = recursive_replace_single_parts(privacy, mime->mm_data.mm_message.mm_msg_mime, reencode); if (r != MAIL_NO_ERROR) { res = r; goto err; } } break; } return MAIL_NO_ERROR; err: return res; }
int mailprivacy_fetch_decoded_to_file(struct mailprivacy * privacy, char * filename, size_t size, mailmessage * msg, struct mailmime * mime) { int r; int res; FILE * f; char * content; size_t content_len; size_t written; struct mailmime_single_fields single_fields; int encoding; size_t cur_token; char * parsed_content; size_t parsed_content_len; mailmime_single_fields_init(&single_fields, mime->mm_mime_fields, mime->mm_content_type); if (single_fields.fld_encoding != NULL) encoding = single_fields.fld_encoding->enc_type; else encoding = MAILMIME_MECHANISM_8BIT; r = mailprivacy_msg_fetch_section(privacy, msg, mime, &content, &content_len); if (r != MAIL_NO_ERROR) { res = MAIL_ERROR_FETCH; goto err; } cur_token = 0; r = mailmime_part_parse(content, content_len, &cur_token, encoding, &parsed_content, &parsed_content_len); mailprivacy_msg_fetch_result_free(privacy, msg, content); if (r != MAILIMF_NO_ERROR) { res = MAIL_ERROR_PARSE; goto err; } f = mailprivacy_get_tmp_file(privacy, filename, size); if (f == NULL) { res = MAIL_ERROR_FETCH; goto free_fetch; } written = fwrite(parsed_content, 1, parsed_content_len, f); if (written != parsed_content_len) { res = MAIL_ERROR_FILE; goto close; } fclose(f); mmap_string_unref(parsed_content); return MAIL_NO_ERROR; close: fclose(f); unlink(filename); free_fetch: mmap_string_unref(parsed_content); err: return res; }