#include #include #include #include #include #include #include "option-parser.h" #include "readmsg-common.h" /* write content to the given filename */ static int etpan_write_data(char * filename, char * data, size_t len) { size_t write_len; FILE * f; int res; mode_t old_umask; old_umask = umask(0077); f = fopen(filename, "wb"); umask(old_umask); if (f == NULL) { res = ERROR_FILE; goto err; } write_len = fwrite(data, 1, len, f); if (write_len < len) { res = ERROR_FILE; goto close; } fclose(f); return NO_ERROR; close: fclose(f); err: return res; } /* save attachment */ 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; } /* fetch attachments */ 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; } int main(int argc, char ** argv) { int r; int driver; char * server; int port; int connection_type; char * user; char * password; int auth_type; bool xoauth2; char * path; char * cache_directory; char * flags_directory; struct mailstorage * storage; struct mailfolder * folder; /* get options */ r = parse_options(argc, argv, &driver, &server, &port, &connection_type, &user, &password, &auth_type, &xoauth2, &path, &cache_directory, &flags_directory); /* build the storage structure */ storage = mailstorage_new(NULL); if (storage == NULL) { printf("error initializing storage\n"); goto free_opt; } r = init_storage(storage, driver, server, port, connection_type, user, password, auth_type, xoauth2, path, cache_directory, flags_directory); if (r != MAIL_NO_ERROR) { printf("error initializing storage\n"); goto free_opt; } /* get the folder structure */ folder = mailfolder_new(storage, path, NULL); if (folder == NULL) { printf("error initializing folder\n"); goto free_storage; } r = mailfolder_connect(folder); if (r != MAIL_NO_ERROR) { printf("error initializing folder\n"); goto free_folder; } while (optind < argc) { mailmessage * msg; uint32_t msg_num; struct mailmime * mime; msg_num = strtoul(argv[optind], NULL, 10); r = mailsession_get_message(folder->fld_session, msg_num, &msg); if (r != MAIL_NO_ERROR) { printf("** message %i not found ** - %s\n", msg_num, maildriver_strerror(r)); optind ++; continue; } r = mailmessage_get_bodystructure(msg, &mime); if (r != MAIL_NO_ERROR) { printf("** message %i not found - %s **\n", msg_num, maildriver_strerror(r)); mailmessage_free(msg); optind ++; continue; } r = etpan_fetch_mime(stdout, msg, mime); mailmessage_free(msg); optind ++; } mailfolder_free(folder); mailstorage_free(storage); if (server != NULL) free(server); if (user != NULL) free(user); if (password != NULL) free(password); if (path != NULL) free(path); if (cache_directory != NULL) free(cache_directory); if (flags_directory != NULL) free(flags_directory); return 0; free_folder: mailfolder_free(folder); free_storage: mailstorage_free(storage); free_opt: if (server != NULL) free(server); if (user != NULL) free(user); if (password != NULL) free(password); if (path != NULL) free(path); if (cache_directory != NULL) free(cache_directory); if (flags_directory != NULL) free(flags_directory); return -1; }