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; }
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; }
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; }
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; }