int mailmime_smart_remove_part(struct mailmime * mime) { struct mailmime * parent; int res; parent = mime->mm_parent; if (parent == NULL) { res = MAILIMF_ERROR_INVAL; goto err; } switch (mime->mm_type) { case MAILMIME_MESSAGE: if (mime->mm_data.mm_message.mm_msg_mime != NULL) { res = MAILIMF_ERROR_INVAL; goto err; } mailmime_remove_part(mime); mailmime_free(mime); return MAILIMF_NO_ERROR; case MAILMIME_MULTIPLE: if (!clist_isempty(mime->mm_data.mm_multipart.mm_mp_list)) { res = MAILIMF_ERROR_INVAL; goto err; } mailmime_remove_part(mime); mailmime_free(mime); return MAILIMF_NO_ERROR; case MAILMIME_SINGLE: mailmime_remove_part(mime); mailmime_free(mime); return MAILIMF_NO_ERROR; default: return MAILIMF_ERROR_INVAL; } err: return res; }
mailmessage * mime_message_init(struct mailmime * mime) { mailmessage * msg; int r; msg = mailmessage_new(); if (msg == NULL) goto err; r = mailmessage_init(msg, NULL, mime_message_driver, 0, 0); if (r != MAIL_NO_ERROR) goto free; if (mime != NULL) { mailmime_free(msg->msg_mime); msg->msg_mime = mime; } return msg; free: mailmessage_free(msg); err: return NULL; }
int mailmessage_encrypt(struct mailprivacy * privacy, struct mailmessage * msg, char * protocol, char * encryption_method) { int r; int res; struct mailmime * mime; struct mailmime * encrypted_mime; struct mailmime * part_to_encrypt; r = mailprivacy_msg_get_bodystructure(privacy, msg, &mime); if (r != MAIL_NO_ERROR) { res = r; goto err; } part_to_encrypt = mime->mm_data.mm_message.mm_msg_mime; r = mailprivacy_encrypt_msg(privacy, protocol, encryption_method, msg, part_to_encrypt, &encrypted_mime); if (r != MAIL_NO_ERROR) { res = r; goto err; } mime->mm_data.mm_message.mm_msg_mime = encrypted_mime; encrypted_mime->mm_parent = mime; part_to_encrypt->mm_parent = NULL; mailmime_free(part_to_encrypt); return MAIL_NO_ERROR; err: return res; }
static int smime_sign_encrypt(struct mailprivacy * privacy, mailmessage * msg, struct mailmime * mime, struct mailmime ** result) { struct mailmime * signed_part; struct mailmime * encrypted; int r; int res; r = smime_sign(privacy, msg, mime, &signed_part); if (r != MAIL_NO_ERROR) { res = r; goto err; } r = smime_encrypt(privacy, msg, signed_part, &encrypted); if (r != MAIL_NO_ERROR) { res = r; goto free_signed; } * result = encrypted; return MAIL_NO_ERROR; free_signed: mailprivacy_mime_clear(signed_part); mailmime_free(signed_part); err: return res; }
static void imap_flush(mailmessage * msg_info) { if (msg_info->msg_mime != NULL) { mailmime_free(msg_info->msg_mime); msg_info->msg_mime = NULL; } }
int main(int argc, char ** argv) { struct mailmime * msg_mime; struct mailmime * mime; struct mailmime * submime; struct mailimf_fields * fields; int col; msg_mime = mailmime_new_message_data(NULL); fields = build_fields(); mailmime_set_imf_fields(msg_mime, fields); mime = get_multipart_mixed(NULL); submime = get_plain_text_part(); mailmime_smart_add_part(mime, submime); submime = get_sample_file_part(); mailmime_smart_add_part(mime, submime); mailmime_add_part(msg_mime, mime); col = 0; mailmime_write_file(stdout, &col, mime); mailmime_free(msg_mime); exit(0); }
static void uninitialize(mailmessage * msg) { /* tmp dir name */ if (msg->msg_data != NULL) free(msg->msg_data); if (msg->msg_mime != NULL) mailmime_free(msg->msg_mime); msg->msg_mime = NULL; }
static struct mailmime * build_body_text(char * text) { struct mailmime_fields * mime_fields; struct mailmime * mime_sub; struct mailmime_content * content; struct mailmime_parameter * param; int r; /* text/plain part */ mime_fields = mailmime_fields_new_encoding(MAILMIME_MECHANISM_8BIT); if (mime_fields == NULL) { goto err; } content = mailmime_content_new_with_str("text/plain"); if (content == NULL) { goto free_fields; } param = mailmime_param_new_with_data("charset", DEST_CHARSET); if (param == NULL) { goto free_content; } r = clist_append(content->ct_parameters, param); if (r < 0) { mailmime_parameter_free(param); goto free_content; } mime_sub = mailmime_new_empty(content, mime_fields); if (mime_sub == NULL) { goto free_content; } r = mailmime_set_body_text(mime_sub, text, strlen(text)); if (r != MAILIMF_NO_ERROR) { goto free_mime; } return mime_sub; free_mime: mailmime_free(mime_sub); goto err; free_content: mailmime_content_free(content); free_fields: mailmime_fields_free(mime_fields); err: return NULL; }
void mailmessage_generic_flush(mailmessage * msg_info) { struct generic_message_t * msg; if (msg_info->msg_mime != NULL) { mailmime_free(msg_info->msg_mime); msg_info->msg_mime = NULL; } msg = msg_info->msg_data; if (msg != NULL) { if (msg->msg_prefetch_free != NULL) msg->msg_prefetch_free(msg); msg->msg_fetched = 0; } }
int mailprivacy_get_part_from_file(struct mailprivacy * privacy, int check_security, int reencode, char * filename, struct mailmime ** result_mime) { int fd; struct mailmime * mime; int r; struct stat stat_info; int res; char * mapping; fd = open(filename, O_RDONLY); if (fd < 0) { res = MAIL_ERROR_FILE; goto err; } r = fstat(fd, &stat_info); if (r < 0) { res = MAIL_ERROR_FILE; goto close; } mapping = mmap(NULL, stat_info.st_size, PROT_READ, MAP_PRIVATE, fd, 0); if (mapping == (char *)MAP_FAILED) { res = MAIL_ERROR_FILE; goto close; } mime = NULL; /* check recursive parts if privacy is set */ r = mailprivacy_get_mime(privacy, check_security, reencode, mapping, stat_info.st_size, &mime); if (r != MAIL_NO_ERROR) { res = r; goto unmap; } if (mime->mm_type == MAILMIME_MESSAGE) { struct mailmime * submime; submime = mime->mm_data.mm_message.mm_msg_mime; if (mime->mm_data.mm_message.mm_msg_mime != NULL) { mailmime_remove_part(submime); mailmime_free(mime); mime = submime; } } munmap(mapping, stat_info.st_size); close(fd); * result_mime = mime; return MAIL_NO_ERROR; unmap: munmap(mapping, stat_info.st_size); close: close(fd); err: return res; }
struct mailmime * mailprivacy_new_file_part(struct mailprivacy * privacy, char * filename, char * default_content_type, int default_encoding) { char basename_buf[PATH_MAX]; char * name; struct mailmime_mechanism * encoding; struct mailmime_content * content; struct mailmime * mime; int r; char * dup_filename; struct mailmime_fields * mime_fields; int encoding_type; char * content_type_str; int do_encoding; if (filename != NULL) { strncpy(basename_buf, filename, PATH_MAX); name = libetpan_basename(basename_buf); } else { name = NULL; } encoding = NULL; /* default content-type */ if (default_content_type == NULL) content_type_str = "application/octet-stream"; else content_type_str = default_content_type; content = mailmime_content_new_with_str(content_type_str); if (content == NULL) { goto free_content; } do_encoding = 1; if (content->ct_type->tp_type == MAILMIME_TYPE_COMPOSITE_TYPE) { struct mailmime_composite_type * composite; composite = content->ct_type->tp_data.tp_composite_type; switch (composite->ct_type) { case MAILMIME_COMPOSITE_TYPE_MESSAGE: if (strcasecmp(content->ct_subtype, "rfc822") == 0) do_encoding = 0; break; case MAILMIME_COMPOSITE_TYPE_MULTIPART: do_encoding = 0; break; } } if (do_encoding) { if (default_encoding == -1) encoding_type = MAILMIME_MECHANISM_BASE64; else encoding_type = default_encoding; /* default Content-Transfer-Encoding */ encoding = mailmime_mechanism_new(encoding_type, NULL); if (encoding == NULL) { goto free_content; } } mime_fields = mailmime_fields_new_with_data(encoding, NULL, NULL, NULL, NULL); if (mime_fields == NULL) { goto free_content; } mime = mailmime_new_empty(content, mime_fields); if (mime == NULL) { goto free_mime_fields; } if ((filename != NULL) && (mime->mm_type == MAILMIME_SINGLE)) { /* duplicates the file so that the file can be deleted when the MIME part is done */ dup_filename = dup_file(privacy, filename); if (dup_filename == NULL) { goto free_mime; } r = mailmime_set_body_file(mime, dup_filename); if (r != MAILIMF_NO_ERROR) { free(dup_filename); goto free_mime; } } return mime; free_mime: mailmime_free(mime); goto err; free_mime_fields: mailmime_fields_free(mime_fields); mailmime_content_free(content); goto err; free_content: if (encoding != NULL) mailmime_mechanism_free(encoding); if (content != NULL) mailmime_content_free(content); err: return NULL; }
static int smime_verify(struct mailprivacy * privacy, mailmessage * msg, struct mailmime * mime, struct mailmime ** result) { char smime_filename[PATH_MAX]; char quoted_smime_filename[PATH_MAX]; int res; int r; char command[PATH_MAX]; int sign_ok; struct mailmime * description_mime; char description_filename[PATH_MAX]; struct mailmime * multipart; char stripped_filename[PATH_MAX]; struct mailmime * stripped_mime; char check_CA[PATH_MAX]; char quoted_CAfile[PATH_MAX]; char noverify[PATH_MAX]; if (store_cert) get_cert_from_sig(privacy, msg, mime); * check_CA = '\0'; if (CAfile != NULL) { r = mail_quote_filename(quoted_CAfile, sizeof(quoted_CAfile), CAfile); if (r < 0) { res = MAIL_ERROR_MEMORY; goto err; } snprintf(check_CA, sizeof(check_CA), "-CAfile '%s'", quoted_CAfile); } * noverify = '\0'; if (!CA_check) { snprintf(noverify, sizeof(noverify), "-noverify"); } /* fetch the whole multipart and write it to a file */ r = mailprivacy_fetch_mime_body_to_file(privacy, smime_filename, sizeof(smime_filename), msg, mime); if (r != MAIL_NO_ERROR) { res = r; goto err; } r = mailprivacy_get_tmp_filename(privacy,stripped_filename, sizeof(stripped_filename)); if (r != MAIL_NO_ERROR) { res = r; goto unlink_smime; } /* description */ r = mailprivacy_get_tmp_filename(privacy, description_filename, sizeof(description_filename)); if (r != MAIL_NO_ERROR) { res = r; goto unlink_stripped; } /* run the command */ r = mail_quote_filename(quoted_smime_filename, sizeof(quoted_smime_filename), smime_filename); if (r < 0) { res = MAIL_ERROR_MEMORY; goto unlink_description; } sign_ok = 0; snprintf(command, sizeof(command), "openssl smime -verify -in '%s' %s %s", quoted_smime_filename, check_CA, noverify); r = smime_command_passphrase(privacy, msg, command, NULL, stripped_filename, description_filename); switch (r) { case NO_ERROR_SMIME: sign_ok = 1; break; case ERROR_SMIME_NOPASSPHRASE: case ERROR_SMIME_CHECK: sign_ok = 0; break; case ERROR_SMIME_COMMAND: res = MAIL_ERROR_COMMAND; goto unlink_description; case ERROR_SMIME_FILE: res = MAIL_ERROR_FILE; goto unlink_description; } /* building multipart */ r = mailmime_new_with_content("multipart/x-verified", NULL, &multipart); if (r != MAILIMF_NO_ERROR) { res = MAIL_ERROR_MEMORY; goto unlink_description; } /* building the description part */ description_mime = mailprivacy_new_file_part(privacy, description_filename, "text/plain", MAILMIME_MECHANISM_8BIT); if (description_mime == NULL) { mailprivacy_mime_clear(multipart); mailmime_free(multipart); res = MAIL_ERROR_MEMORY; goto unlink_description; } /* adds the description part */ r = mailmime_smart_add_part(multipart, description_mime); if (r != MAIL_NO_ERROR) { mailprivacy_mime_clear(description_mime); mailmime_free(description_mime); mailprivacy_mime_clear(multipart); mailmime_free(multipart); res = MAIL_ERROR_MEMORY; goto unlink_description; } /* insert the signed part */ if (!sign_ok) { if (mime->mm_type == MAILMIME_MULTIPLE) { clistiter * child_iter; struct mailmime * child; child_iter = clist_begin(mime->mm_data.mm_multipart.mm_mp_list); child = clist_content(child_iter); r = mailprivacy_fetch_mime_body_to_file(privacy, stripped_filename, sizeof(stripped_filename), msg, child); } } r = mailprivacy_get_part_from_file(privacy, 1, 0, stripped_filename, &stripped_mime); if (r != MAIL_NO_ERROR) { mailprivacy_mime_clear(multipart); mailmime_free(multipart); res = r; goto unlink_description; } r = mailmime_smart_add_part(multipart, stripped_mime); if (r != MAIL_NO_ERROR) { mailprivacy_mime_clear(stripped_mime); mailmime_free(stripped_mime); mailprivacy_mime_clear(multipart); mailmime_free(multipart); res = MAIL_ERROR_MEMORY; goto unlink_description; } unlink(description_filename); unlink(stripped_filename); /* unlink(smime_filename); */ * result = multipart; return MAIL_NO_ERROR; unlink_description: unlink(description_filename); unlink_stripped: unlink(stripped_filename); unlink_smime: unlink(smime_filename); err: return res; }
static int smime_decrypt(struct mailprivacy * privacy, mailmessage * msg, struct mailmime * mime, struct mailmime ** result) { char smime_filename[PATH_MAX]; char quoted_smime_filename[PATH_MAX]; char description_filename[PATH_MAX]; char decrypted_filename[PATH_MAX]; char command[PATH_MAX]; struct mailmime * description_mime; struct mailmime * decrypted_mime; int r; int res; int sign_ok; struct mailmime * multipart; char * smime_cert; char * smime_key; char quoted_smime_cert[PATH_MAX]; char quoted_smime_key[PATH_MAX]; char * email; chashiter * iter; /* fetch the whole multipart and write it to a file */ r = mailprivacy_fetch_mime_body_to_file(privacy, smime_filename, sizeof(smime_filename), msg, mime); if (r != MAIL_NO_ERROR) { res = r; goto err; } /* we are in a safe directory */ r = mailprivacy_get_tmp_filename(privacy, decrypted_filename, sizeof(decrypted_filename)); if (r != MAIL_NO_ERROR) { res = MAIL_ERROR_FILE; goto unlink_smime; } /* description */ r = mailprivacy_get_tmp_filename(privacy, description_filename, sizeof(description_filename)); if (r != MAIL_NO_ERROR) { res = MAIL_ERROR_FILE; goto unlink_decrypted; } sign_ok = 0; for(iter = chash_begin(private_keys) ; iter != NULL ; iter = chash_next(private_keys, iter)) { chashdatum key; char email_buf[BUF_SIZE]; chash_key(iter, &key); if (key.len >= sizeof(email_buf)) continue; strncpy(email_buf, key.data, key.len); email_buf[key.len] = '\0'; email = email_buf; /* get encryption key */ smime_key = get_private_key_file(email); smime_cert = get_cert_file(email); if ((smime_cert == NULL) || (smime_key == NULL)) { res = MAIL_ERROR_INVAL; goto unlink_description; } r = mail_quote_filename(quoted_smime_cert, sizeof(quoted_smime_cert), smime_cert); if (r < 0) { res = MAIL_ERROR_MEMORY; goto unlink_description; } r = mail_quote_filename(quoted_smime_key, sizeof(quoted_smime_key), smime_key); if (r < 0) { res = MAIL_ERROR_MEMORY; goto unlink_description; } /* run the command */ r = mail_quote_filename(quoted_smime_filename, sizeof(quoted_smime_filename), smime_filename); if (r < 0) { res = MAIL_ERROR_MEMORY; goto unlink_description; } sign_ok = 0; snprintf(command, sizeof(command), "openssl smime -decrypt -passin fd:0 -in '%s' -inkey '%s' -recip '%s'", quoted_smime_filename, quoted_smime_key, quoted_smime_cert); unlink(description_filename); r = smime_command_passphrase(privacy, msg, command, email, decrypted_filename, description_filename); switch (r) { case NO_ERROR_SMIME: sign_ok = 1; break; case ERROR_SMIME_CHECK: case ERROR_SMIME_NOPASSPHRASE: sign_ok = 0; break; case ERROR_SMIME_COMMAND: res = MAIL_ERROR_COMMAND; goto unlink_description; case ERROR_SMIME_FILE: res = MAIL_ERROR_FILE; goto unlink_description; } if (sign_ok) { break; } } if (!sign_ok) { if (chash_count(private_keys) == 0) { FILE * description_f; description_f = mailprivacy_get_tmp_file(privacy, description_filename, sizeof(description_filename)); if (description_f == NULL) { res = MAIL_ERROR_FILE; goto unlink_decrypted; } fprintf(description_f, SMIME_DECRYPT_FAILED); fclose(description_f); } } else { mailprivacy_smime_encryption_id_list_clear(privacy, msg); } /* building multipart */ r = mailmime_new_with_content("multipart/x-decrypted", NULL, &multipart); if (r != MAILIMF_NO_ERROR) { res = MAIL_ERROR_MEMORY; goto unlink_description; } /* building the description part */ description_mime = mailprivacy_new_file_part(privacy, description_filename, "text/plain", MAILMIME_MECHANISM_8BIT); if (description_mime == NULL) { mailprivacy_mime_clear(multipart); mailmime_free(multipart); res = MAIL_ERROR_MEMORY; goto unlink_description; } /* adds the description part */ r = mailmime_smart_add_part(multipart, description_mime); if (r != MAIL_NO_ERROR) { mailprivacy_mime_clear(description_mime); mailmime_free(description_mime); mailprivacy_mime_clear(multipart); mailmime_free(multipart); res = MAIL_ERROR_MEMORY; goto unlink_description; } /* building the decrypted part */ r = mailprivacy_get_part_from_file(privacy, 1, 0, decrypted_filename, &decrypted_mime); if (r == MAIL_NO_ERROR) { /* adds the decrypted part */ r = mailmime_smart_add_part(multipart, decrypted_mime); if (r != MAIL_NO_ERROR) { mailprivacy_mime_clear(decrypted_mime); mailmime_free(decrypted_mime); mailprivacy_mime_clear(multipart); mailmime_free(multipart); res = MAIL_ERROR_MEMORY; goto unlink_description; } } unlink(description_filename); unlink(decrypted_filename); unlink(smime_filename); * result = multipart; return MAIL_NO_ERROR; unlink_description: unlink(description_filename); unlink_decrypted: unlink(decrypted_filename); unlink_smime: unlink(smime_filename); err: return res; }
static int recursive_check_privacy(struct mailprivacy * privacy, mailmessage * msg, struct mailmime * mime) { int r; clistiter * cur; struct mailmime * alternative; int res; struct mailmime * multipart; if (privacy == NULL) return MAIL_NO_ERROR; if (mime_is_registered(privacy, mime)) return MAIL_ERROR_INVAL; r = privacy_handler(privacy, msg, mime, &alternative); if (r == MAIL_NO_ERROR) { if (privacy->make_alternative) { multipart = mime_add_alternative(privacy, msg, mime, alternative); if (multipart == NULL) { mailprivacy_mime_clear(alternative); mailmime_free(alternative); return MAIL_ERROR_MEMORY; } } else { mailmime_substitute(mime, alternative); mailmime_free(mime); mime = NULL; } return MAIL_NO_ERROR; } else { switch (mime->mm_type) { case MAILMIME_SINGLE: return MAIL_ERROR_INVAL; case MAILMIME_MULTIPLE: res = MAIL_ERROR_INVAL; 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_check_privacy(privacy, msg, child); if (r == MAIL_NO_ERROR) res = MAIL_NO_ERROR; } return res; case MAILMIME_MESSAGE: if (mime->mm_data.mm_message.mm_msg_mime != NULL) return recursive_check_privacy(privacy, msg, mime->mm_data.mm_message.mm_msg_mime); return MAIL_ERROR_INVAL; default: return MAIL_ERROR_INVAL; } } }
static struct mailmime * mime_add_alternative(struct mailprivacy * privacy, mailmessage * msg, struct mailmime * mime, struct mailmime * alternative) { struct mailmime * multipart; int r; struct mailmime * mime_copy; char original_filename[PATH_MAX]; if (mime->mm_parent == NULL) goto err; r = mailmime_new_with_content("multipart/alternative", NULL, &multipart); if (r != MAILIMF_NO_ERROR) goto err; r = mailmime_smart_add_part(multipart, alternative); if (r != MAILIMF_NO_ERROR) { goto free_multipart; } /* get copy of mime part "mime" and set parts */ r = mailprivacy_fetch_mime_body_to_file(privacy, original_filename, sizeof(original_filename), msg, mime); if (r != MAIL_NO_ERROR) goto detach_alternative; r = mailprivacy_get_part_from_file(privacy, 0, 0, original_filename, &mime_copy); unlink(original_filename); if (r != MAIL_NO_ERROR) { goto detach_alternative; } r = mailmime_smart_add_part(multipart, mime_copy); if (r != MAILIMF_NO_ERROR) { goto free_mime_copy; } r = recursive_register_mime(privacy, multipart); if (r != MAIL_NO_ERROR) goto detach_mime_copy; mailmime_substitute(mime, multipart); mailmime_free(mime); return multipart; detach_mime_copy: mailprivacy_recursive_unregister_mime(privacy, multipart); mailmime_remove_part(alternative); free_mime_copy: mailprivacy_mime_clear(mime_copy); mailmime_free(mime_copy); detach_alternative: mailmime_remove_part(alternative); free_multipart: mailmime_free(multipart); err: return NULL; }
int main(int argc, char ** argv) { struct mailimf_fields * fields; char * text; char * filename; struct mailmime * message; struct mailmime * text_part; struct mailmime * file_part; int r; int col; if (argc < 3) { printf("syntax: compose-msg \"text\" filename\n"); return 1; } fields = build_fields(); if (fields == NULL) goto err; message = build_message(fields); if (message == NULL) goto free_fields; text = argv[1]; text_part = build_body_text(text); if (text_part == NULL) goto free_message; filename = argv[2]; file_part = build_body_file(filename); if (file_part == NULL) goto free_text; r = mailmime_smart_add_part(message, text_part); if (r != MAILIMF_NO_ERROR) goto free_file; r = mailmime_smart_add_part(message, file_part); if (r != MAILIMF_NO_ERROR) goto free_file_alone; col = 0; mailmime_write(stdout, &col, message); mailmime_free(message); return 0; free_file_alone: mailmime_free(file_part); goto free_text; free_file: mailmime_free(file_part); free_text: mailmime_free(text_part); free_message: mailmime_free(message); goto err; free_fields: mailimf_fields_free(fields); err: printf("error memory\n"); return 1; }
static struct mailmime * build_body_file(char * filename) { struct mailmime_fields * mime_fields; struct mailmime * mime_sub; struct mailmime_content * content; struct mailmime_parameter * param; char * dup_filename; int r; /* text/plain part */ dup_filename = strdup(filename); if (dup_filename == NULL) goto err; mime_fields = mailmime_fields_new_filename(MAILMIME_DISPOSITION_TYPE_ATTACHMENT, dup_filename, MAILMIME_MECHANISM_BASE64); if (mime_fields == NULL) goto free_dup_filename; content = mailmime_content_new_with_str("text/plain"); if (content == NULL) { goto free_fields; } param = mailmime_param_new_with_data("charset", DEST_CHARSET); if (param == NULL) { goto free_content; } r = clist_append(content->ct_parameters, param); if (r < 0) { mailmime_parameter_free(param); goto free_content; } mime_sub = mailmime_new_empty(content, mime_fields); if (mime_sub == NULL) { goto free_content; } dup_filename = strdup(filename); if (dup_filename == NULL) goto free_mime; r = mailmime_set_body_file(mime_sub, dup_filename); if (r != MAILIMF_NO_ERROR) { goto free_mime; } return mime_sub; free_mime: mailmime_free(mime_sub); goto err; free_content: mailmime_content_free(content); free_fields: mailmime_fields_free(mime_fields); goto err; free_dup_filename: free(dup_filename); err: return NULL; }
static int imap_get_bodystructure(mailmessage * msg_info, struct mailmime ** result) { int r; struct mailimap_set * set; struct mailimap_fetch_att * fetch_att; struct mailimap_fetch_type * fetch_type; clist * fetch_result; struct mailimap_msg_att * msg_att; struct mailimap_body * imap_body; struct mailmime * body; int res; struct mailimf_fields * fields; struct mailmime * new_body; struct mailmime_content * content_message; struct mailimap_envelope * envelope; uint32_t uid; char * references; size_t ref_size; clistiter * cur; if (msg_info->msg_mime != NULL) { * result = msg_info->msg_mime; return MAIL_NO_ERROR; } set = mailimap_set_new_single(msg_info->msg_index); if (set == NULL) { res = MAIL_ERROR_MEMORY; goto err; } fetch_type = mailimap_fetch_type_new_fetch_att_list_empty(); if (fetch_type == NULL) { res = MAIL_ERROR_MEMORY; goto free_set; } fetch_att = mailimap_fetch_att_new_uid(); if (fetch_att == NULL) { res = MAIL_ERROR_MEMORY; goto free_fetch_type; } r = mailimap_fetch_type_new_fetch_att_list_add(fetch_type, fetch_att); if (r != MAILIMAP_NO_ERROR) { mailimap_fetch_att_free(fetch_att); res = MAIL_ERROR_MEMORY; goto free_fetch_type; } fetch_att = mailimap_fetch_att_new_bodystructure(); if (fetch_att == NULL) { res = MAIL_ERROR_MEMORY; goto free_fetch_type; } r = mailimap_fetch_type_new_fetch_att_list_add(fetch_type, fetch_att); if (r != MAILIMAP_NO_ERROR) { mailimap_fetch_att_free(fetch_att); res = MAIL_ERROR_MEMORY; goto free_fetch_type; } r = imap_add_envelope_fetch_att(fetch_type); if (r != MAIL_NO_ERROR) { res = r; goto free_fetch_type; } r = mailimap_uid_fetch(get_imap_session(msg_info), set, fetch_type, &fetch_result); mailimap_fetch_type_free(fetch_type); mailimap_set_free(set); switch (r) { case MAILIMAP_NO_ERROR: break; default: return imap_error_to_mail_error(r); } cur = clist_begin(fetch_result); if (cur == NULL) { mailimap_fetch_list_free(fetch_result); return MAIL_ERROR_FETCH; } msg_att = clist_content(cur); uid = 0; references = NULL; ref_size = 0; imap_body = NULL; envelope = NULL; r = imap_get_msg_att_info(msg_att, &uid, &envelope, &references, &ref_size, NULL, &imap_body); if (r != MAIL_NO_ERROR) { mailimap_fetch_list_free(fetch_result); res = r; goto err; } if (uid != msg_info->msg_index) { mailimap_fetch_list_free(fetch_result); res = MAIL_ERROR_MSG_NOT_FOUND; goto err; } if (imap_body == NULL) { mailimap_fetch_list_free(fetch_result); res = MAIL_ERROR_FETCH; goto err; } r = imap_body_to_body(imap_body, &body); if (r != MAIL_NO_ERROR) { mailimap_fetch_list_free(fetch_result); res = r; goto err; } fields = NULL; if (envelope != NULL) { r = imap_env_to_fields(envelope, references, ref_size, &fields); if (r != MAIL_NO_ERROR) { mailmime_free(body); mailimap_fetch_list_free(fetch_result); res = r; goto err; } } content_message = mailmime_get_content_message(); if (content_message == NULL) { if (fields != NULL) mailimf_fields_free(fields); mailmime_free(body); mailimap_fetch_list_free(fetch_result); res = MAIL_ERROR_MEMORY; goto err; } new_body = mailmime_new(MAILMIME_MESSAGE, NULL, 0, NULL, content_message, NULL, NULL, NULL, NULL, fields, body); if (new_body == NULL) { mailmime_content_free(content_message); if (fields != NULL) mailimf_fields_free(fields); mailmime_free(body); mailimap_fetch_list_free(fetch_result); res = MAIL_ERROR_MEMORY; goto err; } msg_info->msg_mime = new_body; mailimap_fetch_list_free(fetch_result); * result = new_body; return MAIL_NO_ERROR; free_fetch_type: mailimap_fetch_type_free(fetch_type); free_set: mailimap_set_free(set); err: return res; }
int mailmime_smart_add_part(struct mailmime * mime, struct mailmime * mime_sub) { struct mailmime * saved_sub; struct mailmime * mp; int res; int r; switch (mime->mm_type) { case MAILMIME_SINGLE: res = MAILIMF_ERROR_INVAL; goto err; case MAILMIME_MULTIPLE: r = mailmime_add_part(mime, mime_sub); if (r != MAILIMF_NO_ERROR) { res = MAILIMF_ERROR_MEMORY; goto err; } return MAILIMF_NO_ERROR; } /* MAILMIME_MESSAGE */ if (mime->mm_data.mm_message.mm_msg_mime == NULL) { /* there is no subpart, we can simply attach it */ r = mailmime_add_part(mime, mime_sub); if (r != MAILIMF_NO_ERROR) { res = MAILIMF_ERROR_MEMORY; goto err; } return MAILIMF_NO_ERROR; } if (mime->mm_data.mm_message.mm_msg_mime->mm_type == MAILMIME_MULTIPLE) { /* in case the subpart is multipart, simply attach it to the subpart */ return mailmime_add_part(mime->mm_data.mm_message.mm_msg_mime, mime_sub); } /* we save the current subpart, ... */ saved_sub = mime->mm_data.mm_message.mm_msg_mime; /* create a multipart */ mp = mailmime_multiple_new("multipart/mixed"); if (mp == NULL) { res = MAILIMF_ERROR_MEMORY; goto err; } /* detach the saved subpart from the parent */ mailmime_remove_part(saved_sub); /* the created multipart is the new child of the parent */ r = mailmime_add_part(mime, mp); if (r != MAILIMF_NO_ERROR) { res = MAILIMF_ERROR_MEMORY; goto free_mp; } /* then, attach the saved subpart and ... */ r = mailmime_add_part(mp, saved_sub); if (r != MAILIMF_NO_ERROR) { res = MAILIMF_ERROR_MEMORY; goto free_saved_sub; } /* the given part to the parent */ r = mailmime_add_part(mp, mime_sub); if (r != MAILIMF_NO_ERROR) { res = MAILIMF_ERROR_MEMORY; goto free_saved_sub; } return MAILIMF_NO_ERROR; free_mp: mailmime_free(mp); free_saved_sub: mailmime_free(saved_sub); err: return res; }