author | zautrix <zautrix> | 2004-09-01 10:23:29 (UTC) |
---|---|---|
committer | zautrix <zautrix> | 2004-09-01 10:23:29 (UTC) |
commit | 6cefbdc9c8f3f3001373f10715361e2740c45395 (patch) (side-by-side diff) | |
tree | cb2c36f57620e698913c27ca4ebe59e4a7c9d46e /kmicromail | |
parent | b9257cb225cd29bab5d96fcdaf557926603ee587 (diff) | |
download | kdepimpi-6cefbdc9c8f3f3001373f10715361e2740c45395.zip kdepimpi-6cefbdc9c8f3f3001373f10715361e2740c45395.tar.gz kdepimpi-6cefbdc9c8f3f3001373f10715361e2740c45395.tar.bz2 |
Mail fixes and libetpan updated
68 files changed, 1002 insertions, 89 deletions
diff --git a/kmicromail/libetpan/generic/imapdriver.c b/kmicromail/libetpan/generic/imapdriver.c index 0d63319..b3e5982 100644 --- a/kmicromail/libetpan/generic/imapdriver.c +++ b/kmicromail/libetpan/generic/imapdriver.c @@ -7,249 +7,252 @@ * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the libEtPan! project nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * $Id$ */ #include "imapdriver.h" #include "mail.h" #include "imapdriver_tools.h" #include "mailmessage.h" #include "imapdriver_message.h" #include "imapdriver_types.h" #include "maildriver.h" #include "maildriver_tools.h" #include "generic_cache.h" #include <stdlib.h> #include <string.h> static int imapdriver_initialize(mailsession * session); static void imapdriver_uninitialize(mailsession * session); static int imapdriver_connect_stream(mailsession * session, mailstream * s); static int imapdriver_starttls(mailsession * session); static int imapdriver_login(mailsession * session, char * userid, char * password); static int imapdriver_logout(mailsession * session); static int imapdriver_noop(mailsession * session); static int imapdriver_build_folder_name(mailsession * session, char * mb, char * name, char ** result); static int imapdriver_create_folder(mailsession * session, char * mb); static int imapdriver_delete_folder(mailsession * session, char * mb); static int imapdriver_rename_folder(mailsession * session, char * mb, char * new_name); static int imapdriver_check_folder(mailsession * session); static int imapdriver_examine_folder(mailsession * session, char * mb); static int imapdriver_select_folder(mailsession * session, char * mb); static int imapdriver_expunge_folder(mailsession * session); static int imapdriver_status_folder(mailsession * session, char * mb, uint32_t * result_messages, uint32_t * result_recent, uint32_t * result_unseen); static int imapdriver_messages_number(mailsession * session, char * mb, uint32_t * result); static int imapdriver_recent_number(mailsession * session, char * mb, uint32_t * result); static int imapdriver_unseen_number(mailsession * session, char * mb, uint32_t * result); static int imapdriver_list_folders(mailsession * session, char * mb, struct mail_list ** result); static int imapdriver_lsub_folders(mailsession * session, char * mb, struct mail_list ** result); static int imapdriver_subscribe_folder(mailsession * session, char * mb); static int imapdriver_unsubscribe_folder(mailsession * session, char * mb); static int imapdriver_append_message(mailsession * session, char * message, size_t size); +static int imapdriver_append_message_flags(mailsession * session, + char * message, size_t size, struct mail_flags * flags); static int imapdriver_copy_message(mailsession * session, uint32_t num, char * mb); static int imapdriver_get_messages_list(mailsession * session, struct mailmessage_list ** result); static int imapdriver_get_envelopes_list(mailsession * session, struct mailmessage_list * env_list); #if 0 static int imapdriver_search_messages(mailsession * session, char * charset, struct mail_search_key * key, struct mail_search_result ** result); #endif static int imapdriver_get_message(mailsession * session, uint32_t num, mailmessage ** result); static int imapdriver_get_message_by_uid(mailsession * session, const char * uid, mailmessage ** result); static mailsession_driver local_imap_session_driver = { .sess_name = "imap", .sess_initialize = imapdriver_initialize, .sess_uninitialize = imapdriver_uninitialize, .sess_parameters = NULL, .sess_connect_stream = imapdriver_connect_stream, .sess_connect_path = NULL, .sess_starttls = imapdriver_starttls, .sess_login = imapdriver_login, .sess_logout = imapdriver_logout, .sess_noop = imapdriver_noop, .sess_build_folder_name = imapdriver_build_folder_name, .sess_create_folder = imapdriver_create_folder, .sess_delete_folder = imapdriver_delete_folder, .sess_rename_folder = imapdriver_rename_folder, .sess_check_folder = imapdriver_check_folder, .sess_examine_folder = imapdriver_examine_folder, .sess_select_folder = imapdriver_select_folder, .sess_expunge_folder = imapdriver_expunge_folder, .sess_status_folder = imapdriver_status_folder, .sess_messages_number = imapdriver_messages_number, .sess_recent_number = imapdriver_recent_number, .sess_unseen_number = imapdriver_unseen_number, .sess_list_folders = imapdriver_list_folders, .sess_lsub_folders = imapdriver_lsub_folders, .sess_subscribe_folder = imapdriver_subscribe_folder, .sess_unsubscribe_folder = imapdriver_unsubscribe_folder, .sess_append_message = imapdriver_append_message, + .sess_append_message_flags = imapdriver_append_message_flags, .sess_copy_message = imapdriver_copy_message, .sess_move_message = NULL, .sess_get_messages_list = imapdriver_get_messages_list, .sess_get_envelopes_list = imapdriver_get_envelopes_list, .sess_remove_message = NULL, #if 0 .sess_search_messages = imapdriver_search_messages, #endif .sess_get_message = imapdriver_get_message, .sess_get_message_by_uid = imapdriver_get_message_by_uid, }; mailsession_driver * imap_session_driver = &local_imap_session_driver; static inline struct imap_session_state_data * get_data(mailsession * session) { return session->sess_data; } static mailimap * get_imap_session(mailsession * session) { return get_data(session)->imap_session; } static int imapdriver_initialize(mailsession * session) { struct imap_session_state_data * data; mailimap * imap; struct mail_flags_store * flags_store; imap = mailimap_new(0, NULL); if (imap == NULL) goto err; flags_store = mail_flags_store_new(); if (flags_store == NULL) goto free_session; data = malloc(sizeof(* data)); if (data == NULL) goto free_flags_store; data->imap_mailbox = NULL; data->imap_session = imap; data->imap_flags_store = flags_store; session->sess_data = data; return MAIL_NO_ERROR; free_flags_store: mail_flags_store_free(flags_store); free_session: mailimap_free(imap); err: return MAIL_ERROR_MEMORY; } static void imap_flags_store_process(mailimap * imap, struct mail_flags_store * flags_store) { unsigned int i; int r; mailmessage * first; mailmessage * last; mail_flags_store_sort(flags_store); if (carray_count(flags_store->fls_tab) == 0) return; first = carray_get(flags_store->fls_tab, 0); last = first; for(i = 1 ; i < carray_count(flags_store->fls_tab) ; i ++) { mailmessage * msg; msg = carray_get(flags_store->fls_tab, i); if (last->msg_index + 1 == msg->msg_index) { r = mail_flags_compare(first->msg_flags, msg->msg_flags); if (r == 0) { last = msg; continue; } } r = imap_store_flags(imap, first->msg_index, last->msg_index, first->msg_flags); first = msg; last = msg; } @@ -678,192 +681,217 @@ enum { }; static int imapdriver_list_lsub_folders(mailsession * session, int type, char * mb, struct mail_list ** result) { clist * imap_list; struct mail_list * resp; int r; int res; switch (type) { case IMAP_LIST: r = mailimap_list(get_imap_session(session), mb, "*", &imap_list); break; case IMAP_LSUB: r = mailimap_lsub(get_imap_session(session), mb, "*", &imap_list); break; default: res = MAIL_ERROR_LIST; goto err; } switch (r) { case MAILIMAP_NO_ERROR: break; default: res = imap_error_to_mail_error(r); goto err; } r = imap_list_to_list(imap_list, &resp); if (r != MAIL_NO_ERROR) { mailimap_list_result_free(imap_list); res = r; goto err; } mailimap_list_result_free(imap_list); * result = resp; return MAIL_NO_ERROR; err: return res; } static int imapdriver_list_folders(mailsession * session, char * mb, struct mail_list ** result) { return imapdriver_list_lsub_folders(session, IMAP_LIST, mb, result); } static int imapdriver_lsub_folders(mailsession * session, char * mb, struct mail_list ** result) { return imapdriver_list_lsub_folders(session, IMAP_LSUB, mb, result); } static int imapdriver_subscribe_folder(mailsession * session, char * mb) { int r; r = mailimap_subscribe(get_imap_session(session), mb); return imap_error_to_mail_error(r); } static int imapdriver_unsubscribe_folder(mailsession * session, char * mb) { int r; r = mailimap_unsubscribe(get_imap_session(session), mb); return imap_error_to_mail_error(r); } /* messages operations */ static int imapdriver_append_message(mailsession * session, char * message, size_t size) { int r; r = mailimap_append_simple(get_imap_session(session), get_data(session)->imap_mailbox, message, size); return imap_error_to_mail_error(r); } +static int imapdriver_append_message_flags(mailsession * session, + char * message, size_t size, struct mail_flags * flags) +{ + struct mailimap_flag_list * flag_list; + int r; + + if (flags != NULL) { + r = imap_flags_to_imap_flags(flags, &flag_list); + if (r != MAIL_NO_ERROR) + return r; + } + else { + flag_list = NULL; + } + + r = mailimap_append(get_imap_session(session), + get_data(session)->imap_mailbox, + flag_list, NULL, message, size); + + if (flag_list != NULL) + mailimap_flag_list_free(flag_list); + + return imap_error_to_mail_error(r); +} + static int imapdriver_copy_message(mailsession * session, uint32_t num, char * mb) { int r; struct mailimap_set * set; int res; set = mailimap_set_new_single(num); if (set == NULL) { res = MAIL_ERROR_MEMORY; goto err; } r = mailimap_uid_copy(get_imap_session(session), set, mb); mailimap_set_free(set); return imap_error_to_mail_error(r); err: return res; } static int imapdriver_get_messages_list(mailsession * session, struct mailmessage_list ** result) { return imap_get_messages_list(get_imap_session(session), session, imap_message_driver, 1, result); } static int imapdriver_get_envelopes_list(mailsession * session, struct mailmessage_list * env_list) { struct mailimap_set * set; struct mailimap_fetch_att * fetch_att; struct mailimap_fetch_type * fetch_type; int res; clist * fetch_result; int r; uint32_t exists; clist * msg_list; if (get_imap_session(session)->imap_selection_info == NULL) { res = MAIL_ERROR_BAD_STATE; goto err; } imap_flags_store_process(get_imap_session(session), get_data(session)->imap_flags_store); exists = get_imap_session(session)->imap_selection_info->sel_exists; if (exists == 0) return MAIL_NO_ERROR; fetch_type = mailimap_fetch_type_new_fetch_att_list_empty(); if (fetch_type == NULL) { res = MAIL_ERROR_MEMORY; goto err; } 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_flags(); 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; } diff --git a/kmicromail/libetpan/generic/imapdriver_cached.c b/kmicromail/libetpan/generic/imapdriver_cached.c index e6af8e8..04044ae 100644 --- a/kmicromail/libetpan/generic/imapdriver_cached.c +++ b/kmicromail/libetpan/generic/imapdriver_cached.c @@ -12,252 +12,255 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the libEtPan! project nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * $Id$ */ #include "imapdriver_cached.h" #include "libetpan-config.h" #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <string.h> #include <unistd.h> #include <stdlib.h> #include "mail.h" #include "imapdriver_tools.h" #include "mail_cache_db.h" #include "mailmessage.h" #include "imapdriver_cached_message.h" #include "maildriver.h" #include "imapdriver_types.h" #include "generic_cache.h" #include "imfcache.h" #include "maildriver_tools.h" #include "imapdriver.h" static int imapdriver_cached_initialize(mailsession * session); static void imapdriver_cached_uninitialize(mailsession * session); static int imapdriver_cached_parameters(mailsession * session, int id, void * value); static int imapdriver_cached_connect_stream(mailsession * session, mailstream * s); static int imapdriver_cached_starttls(mailsession * session); static int imapdriver_cached_login(mailsession * session, char * userid, char * password); static int imapdriver_cached_logout(mailsession * session); static int imapdriver_cached_noop(mailsession * session); static int imapdriver_cached_build_folder_name(mailsession * session, char * mb, char * name, char ** result); static int imapdriver_cached_create_folder(mailsession * session, char * mb); static int imapdriver_cached_delete_folder(mailsession * session, char * mb); static int imapdriver_cached_rename_folder(mailsession * session, char * mb, char * new_name); static int imapdriver_cached_check_folder(mailsession * session); static int imapdriver_cached_examine_folder(mailsession * session, char * mb); static int imapdriver_cached_select_folder(mailsession * session, char * mb); static int imapdriver_cached_expunge_folder(mailsession * session); static int imapdriver_cached_status_folder(mailsession * session, char * mb, uint32_t * result_messages, uint32_t * result_recent, uint32_t * result_unseen); static int imapdriver_cached_messages_number(mailsession * session, char * mb, uint32_t * result); static int imapdriver_cached_recent_number(mailsession * session, char * mb, uint32_t * result); static int imapdriver_cached_unseen_number(mailsession * session, char * mb, uint32_t * result); static int imapdriver_cached_list_folders(mailsession * session, char * mb, struct mail_list ** result); static int imapdriver_cached_lsub_folders(mailsession * session, char * mb, struct mail_list ** result); static int imapdriver_cached_subscribe_folder(mailsession * session, char * mb); static int imapdriver_cached_unsubscribe_folder(mailsession * session, char * mb); static int imapdriver_cached_append_message(mailsession * session, char * message, size_t size); +static int imapdriver_cached_append_message_flags(mailsession * session, + char * message, size_t size, struct mail_flags * flags); static int imapdriver_cached_copy_message(mailsession * session, uint32_t num, char * mb); static int imapdriver_cached_get_messages_list(mailsession * session, struct mailmessage_list ** result); static int imapdriver_cached_get_envelopes_list(mailsession * session, struct mailmessage_list * env_list); static int imapdriver_cached_remove_message(mailsession * session, uint32_t num); #if 0 static int imapdriver_cached_search_messages(mailsession * session, char * charset, struct mail_search_key * key, struct mail_search_result ** result); #endif static int imapdriver_cached_get_message(mailsession * session, uint32_t num, mailmessage ** result); static int imapdriver_cached_get_message_by_uid(mailsession * session, const char * uid, mailmessage ** result); static mailsession_driver local_imap_cached_session_driver = { .sess_name = "imap-cached", .sess_initialize = imapdriver_cached_initialize, .sess_uninitialize = imapdriver_cached_uninitialize, .sess_parameters = imapdriver_cached_parameters, .sess_connect_stream = imapdriver_cached_connect_stream, .sess_connect_path = NULL, .sess_starttls = imapdriver_cached_starttls, .sess_login = imapdriver_cached_login, .sess_logout = imapdriver_cached_logout, .sess_noop = imapdriver_cached_noop, .sess_build_folder_name = imapdriver_cached_build_folder_name, .sess_create_folder = imapdriver_cached_create_folder, .sess_delete_folder = imapdriver_cached_delete_folder, .sess_rename_folder = imapdriver_cached_rename_folder, .sess_check_folder = imapdriver_cached_check_folder, .sess_examine_folder = imapdriver_cached_examine_folder, .sess_select_folder = imapdriver_cached_select_folder, .sess_expunge_folder = imapdriver_cached_expunge_folder, .sess_status_folder = imapdriver_cached_status_folder, .sess_messages_number = imapdriver_cached_messages_number, .sess_recent_number = imapdriver_cached_recent_number, .sess_unseen_number = imapdriver_cached_unseen_number, .sess_list_folders = imapdriver_cached_list_folders, .sess_lsub_folders = imapdriver_cached_lsub_folders, .sess_subscribe_folder = imapdriver_cached_subscribe_folder, .sess_unsubscribe_folder = imapdriver_cached_unsubscribe_folder, .sess_append_message = imapdriver_cached_append_message, + .sess_append_message_flags = imapdriver_cached_append_message_flags, .sess_copy_message = imapdriver_cached_copy_message, .sess_move_message = NULL, .sess_get_messages_list = imapdriver_cached_get_messages_list, .sess_get_envelopes_list = imapdriver_cached_get_envelopes_list, .sess_remove_message = imapdriver_cached_remove_message, #if 0 .sess_search_messages = imapdriver_cached_search_messages, #endif .sess_get_message = imapdriver_cached_get_message, .sess_get_message_by_uid = imapdriver_cached_get_message_by_uid, }; mailsession_driver * imap_cached_session_driver = &local_imap_cached_session_driver; #define CACHE_MESSAGE_LIST static inline struct imap_cached_session_state_data * get_cached_data(mailsession * session) { return session->sess_data; } static inline mailsession * get_ancestor(mailsession * s) { return get_cached_data(s)->imap_ancestor; } static inline struct imap_session_state_data * get_ancestor_data(mailsession * s) { return get_ancestor(s)->sess_data; } static inline mailimap * get_imap_session(mailsession * session) { return get_ancestor_data(session)->imap_session; } static int imapdriver_cached_initialize(mailsession * session) { struct imap_cached_session_state_data * data; data = malloc(sizeof(* data)); if (data == NULL) goto err; data->imap_ancestor = mailsession_new(imap_session_driver); if (data->imap_ancestor == NULL) goto free_data; data->imap_quoted_mb = NULL; data->imap_cache_directory[0] = '\0'; data->imap_uid_list = carray_new(128); if (data->imap_uid_list == NULL) goto free_session; session->sess_data = data; return MAIL_NO_ERROR; free_session: mailsession_free(data->imap_ancestor); free_data: free(data); err: return MAIL_ERROR_MEMORY; } static void free_quoted_mb(struct imap_cached_session_state_data * imap_cached_data) { if (imap_cached_data->imap_quoted_mb != NULL) { free(imap_cached_data->imap_quoted_mb); imap_cached_data->imap_quoted_mb = NULL; } } struct uid_cache_item { uint32_t uid; uint32_t size; }; static int update_uid_cache(mailsession * session, struct mailmessage_list * env_list) { unsigned int i; int r; struct imap_cached_session_state_data * data; int res; data = get_cached_data(session); /* free all UID cache */ for(i = 0 ; i < carray_count(data->imap_uid_list) ; i ++) { @@ -683,192 +686,205 @@ static int imapdriver_cached_messages_number(mailsession * session, char * mb, uint32_t * result) { int r; r = mailsession_messages_number(get_ancestor(session), mb, result); check_for_uid_cache(session); return r; } static int imapdriver_cached_recent_number(mailsession * session, char * mb, uint32_t * result) { int r; r = mailsession_recent_number(get_ancestor(session), mb, result); check_for_uid_cache(session); return r; } static int imapdriver_cached_unseen_number(mailsession * session, char * mb, uint32_t * result) { int r; r = mailsession_unseen_number(get_ancestor(session), mb, result); check_for_uid_cache(session); return r; } static int imapdriver_cached_list_folders(mailsession * session, char * mb, struct mail_list ** result) { int r; r = mailsession_list_folders(get_ancestor(session), mb, result); check_for_uid_cache(session); return r; } static int imapdriver_cached_lsub_folders(mailsession * session, char * mb, struct mail_list ** result) { int r; r = mailsession_lsub_folders(get_ancestor(session), mb, result); check_for_uid_cache(session); return r; } static int imapdriver_cached_subscribe_folder(mailsession * session, char * mb) { int r; r = mailsession_subscribe_folder(get_ancestor(session), mb); check_for_uid_cache(session); return r; } static int imapdriver_cached_unsubscribe_folder(mailsession * session, char * mb) { int r; r = mailsession_unsubscribe_folder(get_ancestor(session), mb); check_for_uid_cache(session); return r; } static int imapdriver_cached_append_message(mailsession * session, char * message, size_t size) { int r; r = mailsession_append_message(get_ancestor(session), message, size); check_for_uid_cache(session); return r; } +static int imapdriver_cached_append_message_flags(mailsession * session, + char * message, size_t size, struct mail_flags * flags) +{ + int r; + + r = mailsession_append_message_flags(get_ancestor(session), + message, size, flags); + + check_for_uid_cache(session); + + return r; +} + static int imapdriver_cached_copy_message(mailsession * session, uint32_t num, char * mb) { int r; r = mailsession_copy_message(get_ancestor(session), num, mb); check_for_uid_cache(session); return r; } static int cmp_uid(uint32_t ** pa, uint32_t ** pb) { uint32_t * a; uint32_t * b; a = * pa; b = * pb; return * a - * b; } static int imapdriver_cached_get_messages_list(mailsession * session, struct mailmessage_list ** result) { #if 0 mailsession * imap_session; #endif mailimap * imap; uint32_t uid_max; struct imap_cached_session_state_data * data; struct mailmessage_list * env_list; unsigned i; int r; int res; carray * tab; #if 0 data = session->data; imap_session = get_ancestor(session); imap = ((struct imap_session_state_data *) (imap_session->data))->session; #endif data = get_cached_data(session); imap = get_imap_session(session); uid_max = 0; #ifdef CACHE_MESSAGE_LIST /* get UID max */ uid_max = 0; for(i = 0 ; i < carray_count(data->imap_uid_list) ; i ++) { struct uid_cache_item * cache_item; cache_item = carray_get(data->imap_uid_list, i); if (cache_item->uid > uid_max) uid_max = cache_item->uid; } #endif r = imap_get_messages_list(imap, session, imap_cached_message_driver, uid_max + 1, &env_list); check_for_uid_cache(session); if (r != MAIL_NO_ERROR) { res = r; goto err; } #ifdef CACHE_MESSAGE_LIST /* remove unsollicited message */ i = 0; while (i < carray_count(env_list->msg_tab)) { mailmessage * msg; msg = carray_get(env_list->msg_tab, i); if (msg->msg_index < uid_max + 1) carray_delete(env_list->msg_tab, i); else i ++; } tab = carray_new(carray_count(env_list->msg_tab) + carray_count(data->imap_uid_list)); if (tab == NULL) { res = MAIL_ERROR_MEMORY; goto free; } carray_set_size(tab, carray_count(env_list->msg_tab) + carray_count(data->imap_uid_list)); /* sort cached data before adding them to the list */ qsort(carray_data(data->imap_uid_list), carray_count(data->imap_uid_list), diff --git a/kmicromail/libetpan/generic/imapdriver_cached_message.c b/kmicromail/libetpan/generic/imapdriver_cached_message.c index c0542a3..c4357a3 100644 --- a/kmicromail/libetpan/generic/imapdriver_cached_message.c +++ b/kmicromail/libetpan/generic/imapdriver_cached_message.c @@ -119,193 +119,193 @@ static mailmessage_driver local_imap_cached_message_driver = { .msg_get_bodystructure = imap_get_bodystructure, .msg_fetch_section = imap_fetch_section, .msg_fetch_section_header = imap_fetch_section_header, .msg_fetch_section_mime = imap_fetch_section_mime, .msg_fetch_section_body = imap_fetch_section_body, .msg_fetch_envelope = imap_fetch_envelope, .msg_get_flags = imap_get_flags, }; mailmessage_driver * imap_cached_message_driver = &local_imap_cached_message_driver; static inline struct imap_cached_session_state_data * get_cached_session_data(mailmessage * msg) { return msg->msg_session->sess_data; } static inline mailmessage * get_ancestor(mailmessage * msg_info) { return msg_info->msg_data; } static inline struct imap_cached_session_state_data * cached_session_get_data(mailsession * s) { return s->sess_data; } static inline mailsession * cached_session_get_ancestor(mailsession * s) { return cached_session_get_data(s)->imap_ancestor; } static inline struct imap_session_state_data * cached_session_get_ancestor_data(mailsession * s) { return cached_session_get_ancestor(s)->sess_data; } static inline mailimap * cached_session_get_imap_session(mailsession * session) { return cached_session_get_ancestor_data(session)->imap_session; } static inline mailimap * get_imap_session(mailmessage * msg) { return cached_session_get_imap_session(msg->msg_session); } static inline mailsession * get_ancestor_session(mailmessage * msg_info) { return cached_session_get_ancestor(msg_info->msg_session); } static void generate_key_from_mime_section(char * key, size_t size, struct mailmime * mime) { clistiter * cur; MMAPString * gstr; struct mailmime_section * part; int r; snprintf(key, size, "unvalid"); r = mailmime_get_section_id(mime, &part); if (r != MAILIMF_NO_ERROR) goto err; gstr = mmap_string_new("part"); if (gstr == NULL) goto free_section; for(cur = clist_begin(part->sec_list) ; cur != NULL ; cur = clist_next(cur)) { char s[20]; snprintf(s, 20, ".%u", * (uint32_t *) clist_content(cur)); if (mmap_string_append(gstr, s) == NULL) goto free_str; } snprintf(key, size, "%s", gstr->str); mmap_string_free(gstr); mailmime_section_free(part); return; free_str: mmap_string_free(gstr); free_section: mailmime_section_free(part); - err: + err:; } static void generate_key_from_section(char * key, size_t size, mailmessage * msg_info, struct mailmime * mime, int type) { char section_str[PATH_MAX]; generate_key_from_mime_section(section_str, PATH_MAX, mime); switch (type) { case IMAP_SECTION_MESSAGE: snprintf(key, size, "%s-%s", msg_info->msg_uid, section_str); break; case IMAP_SECTION_HEADER: snprintf(key, size, "%s-%s-header", msg_info->msg_uid, section_str); break; case IMAP_SECTION_MIME: snprintf(key, size, "%s-%s-mime", msg_info->msg_uid, section_str); break; case IMAP_SECTION_BODY: snprintf(key, size, "%s-%s-text", msg_info->msg_uid, section_str); break; } } static void generate_key_from_message(char * key, size_t size, mailmessage * msg_info, int type) { switch (type) { case MAILIMAP_MSG_ATT_RFC822: snprintf(key, size, "%s-rfc822", msg_info->msg_uid); break; case MAILIMAP_MSG_ATT_RFC822_HEADER: snprintf(key, size, "%s-rfc822-header", msg_info->msg_uid); break; case MAILIMAP_MSG_ATT_RFC822_TEXT: snprintf(key, size, "%s-rfc822-text", msg_info->msg_uid); break; case MAILIMAP_MSG_ATT_ENVELOPE: snprintf(key, size, "%s-envelope", msg_info->msg_uid); break; } } static void build_cache_name(char * filename, size_t size, mailmessage * msg, char * key) { char * quoted_mb; quoted_mb = get_cached_session_data(msg)->imap_quoted_mb; snprintf(filename, size, "%s/%s", quoted_mb, key); } static int imap_initialize(mailmessage * msg_info) { mailmessage * ancestor; int r; char key[PATH_MAX]; char * uid; mailimap * imap; ancestor = mailmessage_new(); if (ancestor == NULL) return MAIL_ERROR_MEMORY; r = mailmessage_init(ancestor, get_ancestor_session(msg_info), imap_message_driver, msg_info->msg_index, 0); if (r != MAIL_NO_ERROR) { mailmessage_free(ancestor); return r; } imap = get_imap_session(msg_info); snprintf(key, PATH_MAX, "%u-%u", imap->imap_selection_info->sel_uidvalidity, msg_info->msg_index); uid = strdup(key); if (uid == NULL) { mailmessage_free(ancestor); return MAIL_ERROR_MEMORY; } msg_info->msg_data = ancestor; msg_info->msg_uid = uid; return MAIL_NO_ERROR; } static void imap_uninitialize(mailmessage * msg_info) { mailmessage_free(get_ancestor(msg_info)); msg_info->msg_data = NULL; diff --git a/kmicromail/libetpan/generic/imapdriver_tools.c b/kmicromail/libetpan/generic/imapdriver_tools.c index 3d737f3..de4008f 100644 --- a/kmicromail/libetpan/generic/imapdriver_tools.c +++ b/kmicromail/libetpan/generic/imapdriver_tools.c @@ -3014,325 +3014,349 @@ uid_list_to_env_list(clist * fetch_result, MAILIMAP_FLAG_DELETED, MAILIMAP_FLAG_SEEN, MAILIMAP_FLAG_DRAFT, MAILIMAP_FLAG_KEYWORD, MAILIMAP_FLAG_EXTENSION */ static int imap_flags_to_flags(struct mailimap_msg_att_dynamic * att_dyn, struct mail_flags ** result) { struct mail_flags * flags; clist * flag_list; clistiter * cur; flags = mail_flags_new_empty(); if (flags == NULL) goto err; flags->fl_flags = 0; flag_list = att_dyn->att_list; if (flag_list != NULL) { for(cur = clist_begin(flag_list) ; cur != NULL ; cur = clist_next(cur)) { struct mailimap_flag_fetch * flag_fetch; flag_fetch = clist_content(cur); if (flag_fetch->fl_type == MAILIMAP_FLAG_FETCH_RECENT) flags->fl_flags |= MAIL_FLAG_NEW; else { char * keyword; int r; switch (flag_fetch->fl_flag->fl_type) { case MAILIMAP_FLAG_ANSWERED: flags->fl_flags |= MAIL_FLAG_ANSWERED; break; case MAILIMAP_FLAG_FLAGGED: flags->fl_flags |= MAIL_FLAG_FLAGGED; break; case MAILIMAP_FLAG_DELETED: flags->fl_flags |= MAIL_FLAG_DELETED; break; case MAILIMAP_FLAG_SEEN: flags->fl_flags |= MAIL_FLAG_SEEN; break; case MAILIMAP_FLAG_DRAFT: keyword = strdup("Draft"); if (keyword == NULL) goto free; r = clist_append(flags->fl_extension, keyword); if (r < 0) { free(keyword); goto free; } break; case MAILIMAP_FLAG_KEYWORD: if (strcasecmp(flag_fetch->fl_flag->fl_data.fl_keyword, "$Forwarded") == 0) { flags->fl_flags |= MAIL_FLAG_FORWARDED; } else { keyword = strdup(flag_fetch->fl_flag->fl_data.fl_keyword); if (keyword == NULL) goto free; r = clist_append(flags->fl_extension, keyword); if (r < 0) { free(keyword); goto free; } } break; case MAILIMAP_FLAG_EXTENSION: /* do nothing */ break; } } } /* MAIL_FLAG_NEW was set for \Recent messages. Correct this flag for \Seen messages by unsetting it. */ if ((flags->fl_flags & MAIL_FLAG_SEEN) && (flags->fl_flags & MAIL_FLAG_NEW)) { flags->fl_flags &= ~MAIL_FLAG_NEW; } } * result = flags; return MAIL_NO_ERROR; free: mail_flags_free(flags); err: return MAIL_ERROR_MEMORY; } -static int flags_to_imap_flags(struct mail_flags * flags, - struct mailimap_store_att_flags ** result) +int imap_flags_to_imap_flags(struct mail_flags * flags, + struct mailimap_flag_list ** result) { struct mailimap_flag * flag; struct mailimap_flag_list * flag_list; - struct mailimap_store_att_flags * att_flags; int res; clistiter * cur; int r; flag_list = mailimap_flag_list_new_empty(); if (flag_list == NULL) { res = MAIL_ERROR_MEMORY; goto err; } if ((flags->fl_flags & MAIL_FLAG_DELETED) != 0) { flag = mailimap_flag_new_deleted(); if (flag == NULL) { res = MAIL_ERROR_MEMORY; goto free_flag_list; } r = mailimap_flag_list_add(flag_list, flag); if (r != MAILIMAP_NO_ERROR) { mailimap_flag_free(flag); res = MAIL_ERROR_MEMORY; goto free_flag_list; } } if ((flags->fl_flags & MAIL_FLAG_FLAGGED) != 0) { flag = mailimap_flag_new_flagged(); if (flag == NULL) { res = MAIL_ERROR_MEMORY; goto free_flag_list; } r = mailimap_flag_list_add(flag_list, flag); if (r != MAILIMAP_NO_ERROR) { mailimap_flag_free(flag); res = MAIL_ERROR_MEMORY; goto free_flag_list; } } if ((flags->fl_flags & MAIL_FLAG_SEEN) != 0) { flag = mailimap_flag_new_seen(); if (flag == NULL) { res = MAIL_ERROR_MEMORY; goto free_flag_list; } r = mailimap_flag_list_add(flag_list, flag); if (r != MAILIMAP_NO_ERROR) { res = MAIL_ERROR_MEMORY; goto free_flag_list; } } if ((flags->fl_flags & MAIL_FLAG_ANSWERED) != 0) { flag = mailimap_flag_new_answered(); if (flag == NULL) { res = MAIL_ERROR_MEMORY; goto free_flag_list; } r = mailimap_flag_list_add(flag_list, flag); if (r != MAILIMAP_NO_ERROR) { mailimap_flag_free(flag); res = MAIL_ERROR_MEMORY; goto free_flag_list; } } if ((flags->fl_flags & MAIL_FLAG_FORWARDED) != 0) { char * flag_str; flag_str = strdup("$Forwarded"); if (flag_str == NULL) { res = MAIL_ERROR_MEMORY; goto free_flag_list; } flag = mailimap_flag_new_flag_keyword(flag_str); if (flag == NULL) { free(flag_str); res = MAIL_ERROR_MEMORY; goto free_flag_list; } r = mailimap_flag_list_add(flag_list, flag); if (r != MAILIMAP_NO_ERROR) { mailimap_flag_free(flag); res = MAIL_ERROR_MEMORY; goto free_flag_list; } } for(cur = clist_begin(flags->fl_extension) ; cur != NULL ; cur = clist_next(cur)) { char * flag_str; flag_str = clist_content(cur); if (strcasecmp(flag_str, "Draft") == 0) { flag = mailimap_flag_new_draft(); if (flag == NULL) { res = MAIL_ERROR_MEMORY; goto free_flag_list; } r = mailimap_flag_list_add(flag_list, flag); if (r != MAILIMAP_NO_ERROR) { mailimap_flag_free(flag); res = MAIL_ERROR_MEMORY; goto free_flag_list; } } else { flag_str = strdup(flag_str); if (flag_str == NULL) { res = MAIL_ERROR_MEMORY; goto free_flag_list; } flag = mailimap_flag_new_flag_keyword(flag_str); if (flag == NULL) { free(flag_str); res = MAIL_ERROR_MEMORY; goto free_flag_list; } r = mailimap_flag_list_add(flag_list, flag); if (r != MAILIMAP_NO_ERROR) { mailimap_flag_free(flag); res = MAIL_ERROR_MEMORY; goto free_flag_list; } } } + * result = flag_list; + + return MAIL_NO_ERROR; + + free_flag_list: + mailimap_flag_list_free(flag_list); + err: + return res; +} + +static int flags_to_imap_flags(struct mail_flags * flags, + struct mailimap_store_att_flags ** result) +{ + struct mailimap_flag_list * flag_list; + struct mailimap_store_att_flags * att_flags; + int res; + int r; + + r = imap_flags_to_imap_flags(flags, + &flag_list); + if (r != MAIL_NO_ERROR) { + res = r; + goto err; + } + att_flags = mailimap_store_att_flags_new_set_flags_silent(flag_list); if (att_flags == NULL) { res = MAIL_ERROR_MEMORY; goto free_flag_list; } * result = att_flags; return MAIL_NO_ERROR; free_flag_list: mailimap_flag_list_free(flag_list); err: return res; } static int imap_fetch_result_to_flags(clist * fetch_result, uint32_t index, struct mail_flags ** result) { clistiter * cur; int r; for(cur = clist_begin(fetch_result) ; cur != NULL ; cur = clist_next(cur)) { struct mailimap_msg_att * msg_att; clistiter * item_cur; uint32_t uid; struct mailimap_msg_att_dynamic * att_dyn; msg_att = clist_content(cur); uid = 0; att_dyn = NULL; for(item_cur = clist_begin(msg_att->att_list) ; item_cur != NULL ; item_cur = clist_next(item_cur)) { struct mailimap_msg_att_item * item; item = clist_content(item_cur); if (item->att_type == MAILIMAP_MSG_ATT_ITEM_STATIC) { switch (item->att_data.att_static->att_type) { case MAILIMAP_MSG_ATT_UID: uid = item->att_data.att_static->att_data.att_uid; break; } } else if (item->att_type == MAILIMAP_MSG_ATT_ITEM_DYNAMIC) { if (att_dyn == NULL) { att_dyn = item->att_data.att_dyn; } } } if (uid != 0) { if (uid == index) { struct mail_flags * flags; if (att_dyn != NULL) { r = imap_flags_to_flags(att_dyn, &flags); if (r == MAIL_NO_ERROR) { * result = flags; return MAIL_NO_ERROR; } } } } } return MAIL_ERROR_MSG_NOT_FOUND; } int imap_fetch_flags(mailimap * imap, uint32_t index, struct mail_flags ** result) { struct mailimap_fetch_att * fetch_att; struct mailimap_fetch_type * fetch_type; struct mailimap_set * set; int r; int res; clist * fetch_result; struct mail_flags * flags; fetch_type = mailimap_fetch_type_new_fetch_att_list_empty(); if (fetch_type == NULL) { res = MAIL_ERROR_MEMORY; goto err; } fetch_att = mailimap_fetch_att_new_uid(); if (fetch_att == NULL) { res = MAIL_ERROR_MEMORY; diff --git a/kmicromail/libetpan/generic/imapdriver_tools.h b/kmicromail/libetpan/generic/imapdriver_tools.h index 6582a31..59c993e 100644 --- a/kmicromail/libetpan/generic/imapdriver_tools.h +++ b/kmicromail/libetpan/generic/imapdriver_tools.h @@ -13,101 +13,104 @@ * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the libEtPan! project nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * $Id$ */ #ifndef IMAPDRIVER_TOOLS_H #define IMAPDRIVER_TOOLS_H #include "mailimap.h" #include "mailmime.h" #include "imapdriver_types.h" #include "mail_cache_db.h" #ifdef __cplusplus extern "C" { #endif int imap_list_to_list(clist * imap_list, struct mail_list ** result); int section_to_imap_section(struct mailmime_section * section, int type, struct mailimap_section ** result); int imap_get_msg_att_info(struct mailimap_msg_att * msg_att, uint32_t * puid, struct mailimap_envelope ** pimap_envelope, char ** preferences, size_t * pref_size, struct mailimap_msg_att_dynamic ** patt_dyn, struct mailimap_body ** pimap_body); int imap_add_envelope_fetch_att(struct mailimap_fetch_type * fetch_type); int imap_env_to_fields(struct mailimap_envelope * env, char * ref_str, size_t ref_size, struct mailimf_fields ** result); int imap_fetch_result_to_envelop_list(clist * fetch_result, struct mailmessage_list * env_list); int imap_body_to_body(struct mailimap_body * imap_body, struct mailmime ** result); #if 0 int mail_search_to_imap_search(struct mail_search_key * key, struct mailimap_search_key ** result); #endif int msg_list_to_imap_set(clist * msg_list, struct mailimap_set ** result); int imap_error_to_mail_error(int error); int imap_store_flags(mailimap * imap, uint32_t first, uint32_t last, struct mail_flags * flags); int imap_fetch_flags(mailimap * imap, uint32_t index, struct mail_flags ** result); int imap_get_messages_list(mailimap * imap, mailsession * session, mailmessage_driver * driver, uint32_t first_index, struct mailmessage_list ** result); int imapdriver_get_cached_envelope(struct mail_cache_db * cache_db, MMAPString * mmapstr, mailsession * session, mailmessage * msg, struct mailimf_fields ** result); int imapdriver_write_cached_envelope(struct mail_cache_db * cache_db, MMAPString * mmapstr, mailsession * session, mailmessage * msg, struct mailimf_fields * fields); +int imap_flags_to_imap_flags(struct mail_flags * flags, + struct mailimap_flag_list ** result); + #ifdef __cplusplus } #endif #endif diff --git a/kmicromail/libetpan/generic/imapstorage.c b/kmicromail/libetpan/generic/imapstorage.c index e8683d8..972b6dd 100644 --- a/kmicromail/libetpan/generic/imapstorage.c +++ b/kmicromail/libetpan/generic/imapstorage.c @@ -1,170 +1,170 @@ /* * libEtPan! -- a mail stuff library * * Copyright (C) 2001, 2002 - DINH Viet Hoa * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the libEtPan! project nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * $Id$ */ #include "imapstorage.h" #include <stdlib.h> #include <string.h> #include "mail.h" #include "imapdriver.h" #include "imapdriver_cached.h" #include "mailstorage_tools.h" #include "maildriver.h" /* imap storage */ #define IMAP_DEFAULT_PORT 143 #define IMAPS_DEFAULT_PORT 993 static int imap_mailstorage_connect(struct mailstorage * storage); static int imap_mailstorage_get_folder_session(struct mailstorage * storage, char * pathname, mailsession ** result); static void imap_mailstorage_uninitialize(struct mailstorage * storage); static mailstorage_driver imap_mailstorage_driver = { .sto_name = "imap", .sto_connect = imap_mailstorage_connect, .sto_get_folder_session = imap_mailstorage_get_folder_session, .sto_uninitialize = imap_mailstorage_uninitialize, }; int imap_mailstorage_init(struct mailstorage * storage, char * imap_servername, uint16_t imap_port, char * imap_command, int imap_connection_type, int imap_auth_type, char * imap_login, char * imap_password, int imap_cached, char * imap_cache_directory) { struct imap_mailstorage * imap_storage; - imap_storage = malloc(sizeof(struct imap_mailstorage)); + imap_storage = malloc(sizeof(* imap_storage)); if (imap_storage == NULL) goto err; imap_storage->imap_servername = strdup(imap_servername); if (imap_storage->imap_servername == NULL) goto free; imap_storage->imap_connection_type = imap_connection_type; if (imap_port == 0) { switch (imap_connection_type) { case CONNECTION_TYPE_PLAIN: case CONNECTION_TYPE_TRY_STARTTLS: case CONNECTION_TYPE_STARTTLS: case CONNECTION_TYPE_COMMAND: case CONNECTION_TYPE_COMMAND_TRY_STARTTLS: case CONNECTION_TYPE_COMMAND_STARTTLS: imap_port = IMAP_DEFAULT_PORT; break; case CONNECTION_TYPE_TLS: case CONNECTION_TYPE_COMMAND_TLS: imap_port = IMAPS_DEFAULT_PORT; break; } } imap_storage->imap_port = imap_port; if (imap_command != NULL) { imap_storage->imap_command = strdup(imap_command); if (imap_storage->imap_command == NULL) goto free_servername; } else imap_storage->imap_command = NULL; imap_storage->imap_auth_type = imap_auth_type; if (imap_login != NULL) { imap_storage->imap_login = strdup(imap_login); if (imap_storage->imap_login == NULL) goto free_command; } else imap_storage->imap_login = NULL; if (imap_password != NULL) { imap_storage->imap_password = strdup(imap_password); if (imap_storage->imap_password == NULL) goto free_login; } else imap_storage->imap_password = NULL; imap_storage->imap_cached = imap_cached; if (imap_cached && (imap_cache_directory != NULL)) { imap_storage->imap_cache_directory = strdup(imap_cache_directory); if (imap_storage->imap_cache_directory == NULL) goto free_password; } else { imap_storage->imap_cached = FALSE; imap_storage->imap_cache_directory = NULL; } storage->sto_data = imap_storage; storage->sto_driver = &imap_mailstorage_driver; return MAIL_NO_ERROR; free_password: free(imap_storage->imap_password); free_login: free(imap_storage->imap_login); free_command: free(imap_storage->imap_command); free_servername: free(imap_storage->imap_servername); free: free(imap_storage); err: return MAIL_ERROR_MEMORY; } static void imap_mailstorage_uninitialize(struct mailstorage * storage) { struct imap_mailstorage * imap_storage; imap_storage = storage->sto_data; if (imap_storage->imap_cache_directory != NULL) free(imap_storage->imap_cache_directory); if (imap_storage->imap_password != NULL) free(imap_storage->imap_password); diff --git a/kmicromail/libetpan/generic/maildirdriver.c b/kmicromail/libetpan/generic/maildirdriver.c index 7830ceb..5f21422 100644 --- a/kmicromail/libetpan/generic/maildirdriver.c +++ b/kmicromail/libetpan/generic/maildirdriver.c @@ -1,227 +1,231 @@ /* * libEtPan! -- a mail stuff library * * Copyright (C) 2001, 2002 - DINH Viet Hoa * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the libEtPan! project nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * $Id$ */ /* flags directory MUST be kept so that we can have other flags than standards */ #include "maildirdriver.h" #include <stdio.h> #include <sys/types.h> #include <dirent.h> #include <unistd.h> #include <sys/stat.h> #include <ctype.h> #include <fcntl.h> #include <sys/mman.h> #include <stdlib.h> #include <string.h> #include "maildir.h" #include "maildriver_tools.h" #include "maildirdriver_message.h" #include "maildirdriver_tools.h" #include "mailmessage.h" #include "generic_cache.h" static int initialize(mailsession * session); static void uninitialize(mailsession * session); static int connect_path(mailsession * session, char * path); static int logout(mailsession * session); static int expunge_folder(mailsession * session); static int status_folder(mailsession * session, char * mb, uint32_t * result_messages, uint32_t * result_recent, uint32_t * result_unseen); static int recent_number(mailsession * session, char * mb, uint32_t * result); static int unseen_number(mailsession * session, char * mb, uint32_t * result); static int messages_number(mailsession * session, char * mb, uint32_t * result); static int append_message(mailsession * session, char * message, size_t size); +static int append_message_flags(mailsession * session, + char * message, size_t size, struct mail_flags * flags); + static int get_messages_list(mailsession * session, struct mailmessage_list ** result); static int get_envelopes_list(mailsession * session, struct mailmessage_list * env_list); static int check_folder(mailsession * session); static int get_message_by_uid(mailsession * session, const char * uid, mailmessage ** result); static mailsession_driver local_maildir_session_driver = { .sess_name = "maildir", .sess_initialize = initialize, .sess_uninitialize = uninitialize, .sess_parameters = NULL, .sess_connect_stream = NULL, .sess_connect_path = connect_path, .sess_starttls = NULL, .sess_login = NULL, .sess_logout = logout, .sess_noop = NULL, .sess_build_folder_name = NULL, .sess_create_folder = NULL, .sess_delete_folder = NULL, .sess_rename_folder = NULL, .sess_check_folder = check_folder, .sess_examine_folder = NULL, .sess_select_folder = NULL, .sess_expunge_folder = expunge_folder, .sess_status_folder = status_folder, .sess_messages_number = messages_number, .sess_recent_number = recent_number, .sess_unseen_number = unseen_number, .sess_list_folders = NULL, .sess_lsub_folders = NULL, .sess_subscribe_folder = NULL, .sess_unsubscribe_folder = NULL, .sess_append_message = append_message, + .sess_append_message_flags = append_message_flags, .sess_copy_message = NULL, .sess_move_message = NULL, .sess_get_messages_list = get_messages_list, .sess_get_envelopes_list = get_envelopes_list, .sess_remove_message = NULL, #if 0 .sess_search_messages = maildriver_generic_search_messages, #endif .sess_get_message = NULL, .sess_get_message_by_uid = get_message_by_uid, }; mailsession_driver * maildir_session_driver = &local_maildir_session_driver; static int flags_store_process(struct maildir * md, struct mail_flags_store * flags_store); static inline struct maildir_session_state_data * get_data(mailsession * session) { return session->sess_data; } static struct maildir * get_maildir_session(mailsession * session) { return get_data(session)->md_session; } static int initialize(mailsession * session) { struct maildir_session_state_data * data; data = malloc(sizeof(* data)); if (data == NULL) goto err; data->md_session = NULL; data->md_flags_store = mail_flags_store_new(); if (data->md_flags_store == NULL) goto free; session->sess_data = data; return MAIL_NO_ERROR; free: free(data); err: return MAIL_ERROR_MEMORY; } static void uninitialize(mailsession * session) { struct maildir_session_state_data * data; data = get_data(session); if (data->md_session != NULL) flags_store_process(data->md_session, data->md_flags_store); mail_flags_store_free(data->md_flags_store); if (data->md_session != NULL) maildir_free(data->md_session); free(data); session->sess_data = NULL; } static int connect_path(mailsession * session, char * path) { struct maildir * md; int res; int r; if (get_maildir_session(session) != NULL) { res = MAIL_ERROR_BAD_STATE; goto err; } md = maildir_new(path); if (md == NULL) { res = MAIL_ERROR_MEMORY; goto err; } r = maildir_update(md); if (r != MAILDIR_NO_ERROR) { res = maildirdriver_maildir_error_to_mail_error(r); goto free; } @@ -262,204 +266,251 @@ static int status_folder(mailsession * session, char * mb, struct maildir * md; unsigned int i; uint32_t messages; uint32_t recent; uint32_t unseen; check_folder(session); md = get_maildir_session(session); if (md == NULL) return MAIL_ERROR_BAD_STATE; r = maildir_update(md); if (r != MAILDIR_NO_ERROR) return maildirdriver_maildir_error_to_mail_error(r); messages = 0; recent = 0; unseen = 0; for(i = 0 ; i < carray_count(md->mdir_msg_list) ; i ++) { struct maildir_msg * msg; msg = carray_get(md->mdir_msg_list, i); if ((msg->msg_flags & MAILDIR_FLAG_NEW) != 0) recent ++; if ((msg->msg_flags & MAILDIR_FLAG_SEEN) == 0) unseen ++; messages ++; } * result_messages = messages; * result_recent = recent; * result_unseen = unseen; return MAIL_NO_ERROR; } static int messages_number(mailsession * session, char * mb, uint32_t * result) { struct maildir * md; int r; md = get_maildir_session(session); if (md == NULL) return MAIL_ERROR_BAD_STATE; r = maildir_update(md); if (r != MAILDIR_NO_ERROR) return maildirdriver_maildir_error_to_mail_error(r); * result = carray_count(md->mdir_msg_list); return MAIL_NO_ERROR; } static int unseen_number(mailsession * session, char * mb, uint32_t * result) { uint32_t messages; uint32_t recent; uint32_t unseen; int r; r = status_folder(session, mb, &messages, &recent, &unseen); if (r != MAIL_NO_ERROR) return r; * result = unseen; return MAIL_NO_ERROR; } static int recent_number(mailsession * session, char * mb, uint32_t * result) { uint32_t messages; uint32_t recent; uint32_t unseen; int r; r = status_folder(session, mb, &messages, &recent, &unseen); if (r != MAIL_NO_ERROR) return r; * result = recent; return MAIL_NO_ERROR; } /* messages operations */ static int append_message(mailsession * session, char * message, size_t size) { +#if 0 struct maildir * md; int r; md = get_maildir_session(session); if (md == NULL) return MAIL_ERROR_BAD_STATE; r = maildir_message_add(md, message, size); if (r != MAILDIR_NO_ERROR) return maildirdriver_maildir_error_to_mail_error(r); return MAIL_NO_ERROR; +#endif + + return append_message_flags(session, message, size, NULL); +} + +static int append_message_flags(mailsession * session, + char * message, size_t size, struct mail_flags * flags) +{ + struct maildir * md; + int r; + char uid[PATH_MAX]; + struct maildir_msg * md_msg; + chashdatum key; + chashdatum value; + uint32_t md_flags; + + md = get_maildir_session(session); + if (md == NULL) + return MAIL_ERROR_BAD_STATE; + + r = maildir_message_add_uid(md, message, size, + uid, sizeof(uid)); + if (r != MAILDIR_NO_ERROR) + return maildirdriver_maildir_error_to_mail_error(r); + + if (flags == NULL) + goto exit; + + key.data = uid; + key.len = strlen(uid); + r = chash_get(md->mdir_msg_hash, &key, &value); + if (r < 0) + goto exit; + + md_msg = value.data; + + md_flags = maildirdriver_flags_to_maildir_flags(flags->fl_flags); + + r = maildir_message_change_flags(md, uid, md_flags); + if (r != MAILDIR_NO_ERROR) + goto exit; + + return MAIL_NO_ERROR; + + exit: + return MAIL_NO_ERROR; } static int get_messages_list(mailsession * session, struct mailmessage_list ** result) { struct maildir * md; int r; struct mailmessage_list * env_list; int res; md = get_maildir_session(session); if (md == NULL) return MAIL_ERROR_BAD_STATE; r = maildir_update(md); if (r != MAILDIR_NO_ERROR) { res = maildirdriver_maildir_error_to_mail_error(r); goto err; } r = maildir_get_messages_list(session, md, maildir_message_driver, &env_list); if (r != MAILDIR_NO_ERROR) { res = r; goto free_list; } * result = env_list; return MAIL_NO_ERROR; free_list: mailmessage_list_free(env_list); err: return res; } static int get_envelopes_list(mailsession * session, struct mailmessage_list * env_list) { int r; struct maildir * md; unsigned int i; int res; check_folder(session); md = get_maildir_session(session); if (md == NULL) { res = MAIL_ERROR_BAD_STATE; goto err; } r = maildir_update(md); if (r != MAILDIR_NO_ERROR) { res = maildirdriver_maildir_error_to_mail_error(r); goto err; } r = maildriver_generic_get_envelopes_list(session, env_list); if (r != MAIL_NO_ERROR) { res = r; goto err; } for(i = 0 ; i < carray_count(env_list->msg_tab) ; i++) { struct maildir_msg * md_msg; mailmessage * msg; uint32_t driver_flags; clist * ext; chashdatum key; chashdatum value; msg = carray_get(env_list->msg_tab, i); key.data = msg->msg_uid; key.len = strlen(msg->msg_uid); r = chash_get(md->mdir_msg_hash, &key, &value); if (r < 0) continue; md_msg = value.data; driver_flags = maildirdriver_maildir_flags_to_flags(md_msg->msg_flags); if (msg->msg_flags == NULL) { ext = clist_new(); if (ext == NULL) { res = MAIL_ERROR_MEMORY; continue; } msg->msg_flags = mail_flags_new(driver_flags, ext); if (msg->msg_flags == NULL) { clist_free(ext); res = MAIL_ERROR_MEMORY; diff --git a/kmicromail/libetpan/generic/maildirdriver_cached.c b/kmicromail/libetpan/generic/maildirdriver_cached.c index 503d1c9..8a5e206 100644 --- a/kmicromail/libetpan/generic/maildirdriver_cached.c +++ b/kmicromail/libetpan/generic/maildirdriver_cached.c @@ -1,231 +1,235 @@ /* * libEtPan! -- a mail stuff library * * Copyright (C) 2001, 2002 - DINH Viet Hoa * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the libEtPan! project nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * $Id$ */ #include "maildirdriver.h" #include <stdio.h> #include <sys/types.h> #include <dirent.h> #include <unistd.h> #include <sys/stat.h> #include <ctype.h> #include <fcntl.h> #include <sys/mman.h> #include <stdlib.h> #include <string.h> #include "mail.h" #include "maildir.h" #include "maildriver_tools.h" #include "maildirdriver_tools.h" #include "maildirdriver_cached_message.h" #include "mailmessage.h" #include "generic_cache.h" #include "imfcache.h" #include "mail_cache_db.h" #include "libetpan-config.h" static int initialize(mailsession * session); static void uninitialize(mailsession * session); static int parameters(mailsession * session, int id, void * value); static int connect_path(mailsession * session, char * path); static int logout(mailsession * session); static int expunge_folder(mailsession * session); static int status_folder(mailsession * session, char * mb, uint32_t * result_messages, uint32_t * result_recent, uint32_t * result_unseen); static int recent_number(mailsession * session, char * mb, uint32_t * result); static int unseen_number(mailsession * session, char * mb, uint32_t * result); static int messages_number(mailsession * session, char * mb, uint32_t * result); static int append_message(mailsession * session, char * message, size_t size); +static int append_message_flags(mailsession * session, + char * message, size_t size, struct mail_flags * flags); + static int get_messages_list(mailsession * session, struct mailmessage_list ** result); static int get_envelopes_list(mailsession * session, struct mailmessage_list * env_list); static int check_folder(mailsession * session); static int get_message(mailsession * session, uint32_t num, mailmessage ** result); static int get_message_by_uid(mailsession * session, const char * uid, mailmessage ** result); static mailsession_driver local_maildir_cached_session_driver = { .sess_name = "maildir-cached", .sess_initialize = initialize, .sess_uninitialize = uninitialize, .sess_parameters = parameters, .sess_connect_stream = NULL, .sess_connect_path = connect_path, .sess_starttls = NULL, .sess_login = NULL, .sess_logout = logout, .sess_noop = NULL, .sess_build_folder_name = NULL, .sess_create_folder = NULL, .sess_delete_folder = NULL, .sess_rename_folder = NULL, .sess_check_folder = check_folder, .sess_examine_folder = NULL, .sess_select_folder = NULL, .sess_expunge_folder = expunge_folder, .sess_status_folder = status_folder, .sess_messages_number = messages_number, .sess_recent_number = recent_number, .sess_unseen_number = unseen_number, .sess_list_folders = NULL, .sess_lsub_folders = NULL, .sess_subscribe_folder = NULL, .sess_unsubscribe_folder = NULL, .sess_append_message = append_message, + .sess_append_message_flags = append_message_flags, .sess_copy_message = NULL, .sess_move_message = NULL, .sess_get_messages_list = get_messages_list, .sess_get_envelopes_list = get_envelopes_list, .sess_remove_message = NULL, #if 0 .sess_search_messages = maildriver_generic_search_messages, #endif .sess_get_message = get_message, .sess_get_message_by_uid = get_message_by_uid, }; mailsession_driver * maildir_cached_session_driver = &local_maildir_cached_session_driver; static inline struct maildir_cached_session_state_data * get_cached_data(mailsession * session) { return session->sess_data; } static inline mailsession * get_ancestor(mailsession * session) { return get_cached_data(session)->md_ancestor; } static inline struct maildir_session_state_data * get_ancestor_data(mailsession * session) { return get_ancestor(session)->sess_data; } static struct maildir * get_maildir_session(mailsession * session) { return get_ancestor_data(session)->md_session; } static int initialize(mailsession * session) { struct maildir_cached_session_state_data * data; data = malloc(sizeof(* data)); if (data == NULL) goto err; data->md_ancestor = mailsession_new(maildir_session_driver); if (data->md_ancestor == NULL) goto free; data->md_flags_store = mail_flags_store_new(); if (data->md_flags_store == NULL) goto free_session; data->md_quoted_mb = NULL; data->md_cache_directory[0] = '\0'; data->md_flags_directory[0] = '\0'; session->sess_data = data; return MAIL_NO_ERROR; free_session: mailsession_free(data->md_ancestor); free: free(data); err: return MAIL_ERROR_MEMORY; } static void free_quoted_mb(struct maildir_cached_session_state_data * maildir_cached_data) { if (maildir_cached_data->md_quoted_mb != NULL) { free(maildir_cached_data->md_quoted_mb); maildir_cached_data->md_quoted_mb = NULL; } } static int write_cached_flags(struct mail_cache_db * cache_db, MMAPString * mmapstr, char * uid, struct mail_flags * flags); #define ENV_NAME "env.db" #define FLAGS_NAME "flags.db" static int flags_store_process(char * flags_directory, char * quoted_mb, struct mail_flags_store * flags_store) { char filename_flags[PATH_MAX]; struct mail_cache_db * cache_db_flags; MMAPString * mmapstr; @@ -361,195 +365,269 @@ static int get_cache_folder(mailsession * session, char ** result) snprintf(key, PATH_MAX, "%s/%s", data->md_flags_directory, quoted_mb); r = generic_cache_create_dir(key); if (r != MAIL_NO_ERROR) { res = r; goto free_quoted_mb; } * result = quoted_mb; return MAIL_NO_ERROR; free_quoted_mb: free(quoted_mb); err: return res; } static int connect_path(mailsession * session, char * path) { int r; int res; char * quoted_mb; r = mailsession_connect_path(get_ancestor(session), path); if (r != MAIL_NO_ERROR) { res = r; goto err; } r = get_cache_folder(session, "ed_mb); if (r != MAIL_NO_ERROR) { res = r; goto logout; } get_cached_data(session)->md_quoted_mb = quoted_mb; return MAILDIR_NO_ERROR; logout: mailsession_logout(get_ancestor(session)); err: return res; } static int logout(mailsession * session) { struct maildir_cached_session_state_data * data; int r; data = get_cached_data(session); flags_store_process(data->md_flags_directory, data->md_quoted_mb, data->md_flags_store); r = mailsession_logout(get_ancestor(session)); if (r != MAIL_NO_ERROR) return r; free_quoted_mb(get_cached_data(session)); return MAIL_NO_ERROR; } static int status_folder(mailsession * session, char * mb, uint32_t * result_messages, uint32_t * result_recent, uint32_t * result_unseen) { return mailsession_status_folder(get_ancestor(session), mb, result_messages, result_recent, result_unseen); } static int messages_number(mailsession * session, char * mb, uint32_t * result) { return mailsession_messages_number(get_ancestor(session), mb, result); } static int unseen_number(mailsession * session, char * mb, uint32_t * result) { return mailsession_unseen_number(get_ancestor(session), mb, result); } static int recent_number(mailsession * session, char * mb, uint32_t * result) { return mailsession_recent_number(get_ancestor(session), mb, result); } static int append_message(mailsession * session, char * message, size_t size) { +#if 0 return mailsession_append_message(get_ancestor(session), message, size); +#endif + return append_message_flags(session, message, size, NULL); } +static int append_message_flags(mailsession * session, + char * message, size_t size, struct mail_flags * flags) +{ + struct maildir * md; + int r; + char uid[PATH_MAX]; + struct maildir_msg * md_msg; + chashdatum key; + chashdatum value; + uint32_t md_flags; + struct mail_cache_db * cache_db_flags; + char filename_flags[PATH_MAX]; + MMAPString * mmapstr; + struct maildir_cached_session_state_data * data; + + md = get_maildir_session(session); + if (md == NULL) + return MAIL_ERROR_BAD_STATE; + + r = maildir_message_add_uid(md, message, size, + uid, sizeof(uid)); + if (r != MAILDIR_NO_ERROR) + return maildirdriver_maildir_error_to_mail_error(r); + + if (flags == NULL) + goto exit; + + data = get_cached_data(session); + + snprintf(filename_flags, PATH_MAX, "%s%c%s%c%s", + data->md_flags_directory, MAIL_DIR_SEPARATOR, data->md_quoted_mb, + MAIL_DIR_SEPARATOR, FLAGS_NAME); + + r = mail_cache_db_open_lock(filename_flags, &cache_db_flags); + if (r < 0) + goto exit; + + mmapstr = mmap_string_new(""); + if (mmapstr == NULL) + goto close_db_flags; + + r = write_cached_flags(cache_db_flags, mmapstr, + uid, flags); + + mmap_string_free(mmapstr); + mail_cache_db_close_unlock(filename_flags, cache_db_flags); + + if (r != MAIL_NO_ERROR) + goto exit; + + key.data = uid; + key.len = strlen(uid); + r = chash_get(md->mdir_msg_hash, &key, &value); + if (r < 0) + goto exit; + + md_msg = value.data; + + md_flags = maildirdriver_flags_to_maildir_flags(flags->fl_flags); + + r = maildir_message_change_flags(md, uid, md_flags); + if (r != MAILDIR_NO_ERROR) + goto exit; + + return MAIL_NO_ERROR; + + close_db_flags: + mail_cache_db_close_unlock(filename_flags, cache_db_flags); + exit: + return MAIL_NO_ERROR; +} #define UID_NAME "uid.db" static int uid_clean_up(struct mail_cache_db * uid_db, struct mailmessage_list * env_list) { chash * hash_exist; int res; int r; unsigned int i; chashdatum key; chashdatum value; char key_str[PATH_MAX]; /* flush cache */ hash_exist = chash_new(CHASH_DEFAULTSIZE, CHASH_COPYALL); if (hash_exist == NULL) { res = MAIL_ERROR_MEMORY; goto err; } value.data = NULL; value.len = 0; key.data = "max-uid"; key.len = strlen("max-uid"); r = chash_set(hash_exist, &key, &value, NULL); for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) { mailmessage * msg; msg = carray_get(env_list->msg_tab, i); value.data = NULL; value.len = 0; key.data = msg->msg_uid; key.len = strlen(msg->msg_uid); r = chash_set(hash_exist, &key, &value, NULL); if (r < 0) { res = MAIL_ERROR_MEMORY; goto free; } snprintf(key_str, sizeof(key_str), "uid-%lu", (unsigned long) msg->msg_index); key.data = key_str; key.len = strlen(key_str); r = chash_set(hash_exist, &key, &value, NULL); if (r < 0) { res = MAIL_ERROR_MEMORY; goto free; } } mail_cache_db_clean_up(uid_db, hash_exist); chash_free(hash_exist); return MAIL_NO_ERROR; free: chash_free(hash_exist); err: return res; } static int get_messages_list(mailsession * session, struct mailmessage_list ** result) { struct maildir * md; int r; struct mailmessage_list * env_list; int res; uint32_t max_uid; char filename[PATH_MAX]; struct mail_cache_db * uid_db; void * value; size_t value_len; unsigned long i; struct maildir_cached_session_state_data * data; char key[PATH_MAX]; data = get_cached_data(session); md = get_maildir_session(session); if (md == NULL) { res = MAIL_ERROR_BAD_STATE; goto err; } check_folder(session); r = maildir_update(md); if (r != MAILDIR_NO_ERROR) { diff --git a/kmicromail/libetpan/generic/maildirdriver_cached_message.c b/kmicromail/libetpan/generic/maildirdriver_cached_message.c index 51866aa..34de351 100644 --- a/kmicromail/libetpan/generic/maildirdriver_cached_message.c +++ b/kmicromail/libetpan/generic/maildirdriver_cached_message.c @@ -1,248 +1,334 @@ /* * libEtPan! -- a mail stuff library * * Copyright (C) 2001, 2002 - DINH Viet Hoa * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the libEtPan! project nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * $Id$ */ #include "maildirdriver_message.h" #include "mailmessage_tools.h" #include "maildirdriver.h" #include "maildir.h" #include "generic_cache.h" +#include "mail_cache_db.h" +#include "maildirdriver_tools.h" #include <unistd.h> #include <sys/mman.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <string.h> #include <stdlib.h> +static int get_flags(mailmessage * msg_info, + struct mail_flags ** result); + static int prefetch(mailmessage * msg_info); static void prefetch_free(struct generic_message_t * msg); static int initialize(mailmessage * msg_info); static void check(mailmessage * msg_info); static mailmessage_driver local_maildir_cached_message_driver = { .msg_name = "maildir-cached", .msg_initialize = initialize, .msg_uninitialize = mailmessage_generic_uninitialize, .msg_flush = mailmessage_generic_flush, .msg_check = check, .msg_fetch_result_free = mailmessage_generic_fetch_result_free, .msg_fetch = mailmessage_generic_fetch, .msg_fetch_header = mailmessage_generic_fetch_header, .msg_fetch_body = mailmessage_generic_fetch_header, .msg_fetch_size = NULL, .msg_get_bodystructure = mailmessage_generic_get_bodystructure, .msg_fetch_section = mailmessage_generic_fetch_section, .msg_fetch_section_header = mailmessage_generic_fetch_section_header, .msg_fetch_section_mime = mailmessage_generic_fetch_section_mime, .msg_fetch_section_body = mailmessage_generic_fetch_section_body, .msg_fetch_envelope = mailmessage_generic_fetch_envelope, - .msg_get_flags = NULL, + .msg_get_flags = get_flags, }; mailmessage_driver * maildir_cached_message_driver = &local_maildir_cached_message_driver; struct maildir_msg_data { int fd; }; #if 0 static inline struct maildir_cached_session_state_data * get_cached_session_data(mailmessage * msg) { return msg->session->data; } static inline mailsession * cached_session_get_ancestor(mailsession * session) { return get_data(session)->session; } static inline struct maildir_session_state_data * cached_session_get_ancestor_data(mailsession * session) { return get_ancestor(session)->data; } static struct maildir * get_maildir_session(mailmessage * msg) { return cached_session_get_ancestor_data(msg->session)->session; } #endif static inline struct maildir_cached_session_state_data * get_cached_session_data(mailmessage * msg) { return msg->msg_session->sess_data; } static inline struct maildir_cached_session_state_data * cached_session_get_data(mailsession * s) { return s->sess_data; } static inline mailsession * cached_session_get_ancestor(mailsession * s) { return cached_session_get_data(s)->md_ancestor; } static inline struct maildir_session_state_data * cached_session_get_ancestor_data(mailsession * s) { return cached_session_get_ancestor(s)->sess_data; } static inline struct maildir_session_state_data * get_session_ancestor_data(mailmessage * msg) { return cached_session_get_ancestor_data(msg->msg_session); } static inline struct maildir * cached_session_get_maildir_session(mailsession * session) { return cached_session_get_ancestor_data(session)->md_session; } static inline struct maildir * get_maildir_session(mailmessage * msg) { return cached_session_get_maildir_session(msg->msg_session); } static int prefetch(mailmessage * msg_info) { struct generic_message_t * msg; int res; struct maildir_msg_data * data; char * filename; int fd; char * mapping; struct maildir * md; md = get_maildir_session(msg_info); filename = maildir_message_get(md, msg_info->msg_uid); if (filename == NULL) { res = MAIL_ERROR_MEMORY; goto err; } fd = open(filename, O_RDONLY); free(filename); if (fd == -1) { res = MAIL_ERROR_FILE; goto err; } mapping = mmap(NULL, msg_info->msg_size, PROT_READ, MAP_PRIVATE, fd, 0); if (mapping == MAP_FAILED) { res = MAIL_ERROR_FILE; goto close; } data = malloc(sizeof(* data)); if (data == NULL) { res = MAIL_ERROR_MEMORY; goto unmap; } data->fd = fd; msg = msg_info->msg_data; msg->msg_data = data; msg->msg_message = mapping; msg->msg_length = msg_info->msg_size; return MAIL_NO_ERROR; unmap: munmap(mapping, msg_info->msg_size); close: close(fd); err: return res; } static void prefetch_free(struct generic_message_t * msg) { if (msg->msg_message != NULL) { struct maildir_msg_data * data; munmap(msg->msg_message, msg->msg_length); msg->msg_message = NULL; data = msg->msg_data; close(data->fd); free(data); } } static int initialize(mailmessage * msg_info) { struct generic_message_t * msg; int r; r = mailmessage_generic_initialize(msg_info); if (r != MAIL_NO_ERROR) return r; msg = msg_info->msg_data; msg->msg_prefetch = prefetch; msg->msg_prefetch_free = prefetch_free; return MAIL_NO_ERROR; } static void check(mailmessage * msg_info) { int r; if (msg_info->msg_flags != NULL) { r = mail_flags_store_set(get_session_ancestor_data(msg_info)->md_flags_store, msg_info); r = mail_flags_store_set(get_cached_session_data(msg_info)->md_flags_store, msg_info); /* ignore errors */ } } + +#define FLAGS_NAME "flags.db" + +static int get_flags(mailmessage * msg_info, + struct mail_flags ** result) +{ + struct mail_cache_db * cache_db_flags; + chashdatum key; + chashdatum value; + struct maildir * md; + struct mail_flags * flags; + struct maildir_cached_session_state_data * data; + struct maildir_msg * md_msg; + int r; + uint32_t driver_flags; + char filename_flags[PATH_MAX]; + char keyname[PATH_MAX]; + MMAPString * mmapstr; + + if (msg_info->msg_flags != NULL) { + * result = msg_info->msg_flags; + return MAIL_NO_ERROR; + } + + data = get_cached_session_data(msg_info); + flags = mail_flags_store_get(data->md_flags_store, + msg_info->msg_index); + if (flags != NULL) { + msg_info->msg_flags = flags; + * result = msg_info->msg_flags; + return MAIL_NO_ERROR; + } + + snprintf(filename_flags, PATH_MAX, "%s%c%s%c%s", + data->md_flags_directory, MAIL_DIR_SEPARATOR, data->md_quoted_mb, + MAIL_DIR_SEPARATOR, FLAGS_NAME); + + r = mail_cache_db_open_lock(filename_flags, &cache_db_flags); + if (r < 0) + return MAIL_ERROR_FILE; + + snprintf(keyname, PATH_MAX, "%s-flags", msg_info->msg_uid); + + mmapstr = mmap_string_new(""); + if (mmapstr == NULL) { + mail_cache_db_close_unlock(filename_flags, cache_db_flags); + return MAIL_ERROR_MEMORY; + } + + r = generic_cache_flags_read(cache_db_flags, mmapstr, keyname, &flags); + mmap_string_free(mmapstr); + + mail_cache_db_close_unlock(filename_flags, cache_db_flags); + + if (r != MAIL_NO_ERROR) { + flags = mail_flags_new_empty(); + if (flags == NULL) + return MAIL_ERROR_MEMORY; + } + + md = get_maildir_session(msg_info); + if (md == NULL) + return MAIL_ERROR_BAD_STATE; + + key.data = msg_info->msg_uid; + key.len = strlen(msg_info->msg_uid); + r = chash_get(md->mdir_msg_hash, &key, &value); + if (r < 0) + return MAIL_ERROR_MSG_NOT_FOUND; + + md_msg = value.data; + + driver_flags = maildirdriver_maildir_flags_to_flags(md_msg->msg_flags); + + flags->fl_flags = driver_flags; + msg_info->msg_flags = flags; + + * result = msg_info->msg_flags; + + return MAIL_NO_ERROR; +} diff --git a/kmicromail/libetpan/generic/maildirdriver_message.c b/kmicromail/libetpan/generic/maildirdriver_message.c index 7cf9dd1..613fc39 100644 --- a/kmicromail/libetpan/generic/maildirdriver_message.c +++ b/kmicromail/libetpan/generic/maildirdriver_message.c @@ -1,199 +1,255 @@ /* * libEtPan! -- a mail stuff library * * Copyright (C) 2001, 2002 - DINH Viet Hoa * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the libEtPan! project nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * $Id$ */ #include "maildirdriver_message.h" +#include "maildirdriver_tools.h" #include "mailmessage_tools.h" #include "maildirdriver.h" #include "maildir.h" #include "generic_cache.h" #include <unistd.h> #include <sys/mman.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <string.h> #include <stdlib.h> +static int get_flags(mailmessage * msg_info, + struct mail_flags ** result); + static int prefetch(mailmessage * msg_info); static void prefetch_free(struct generic_message_t * msg); static int initialize(mailmessage * msg_info); static void check(mailmessage * msg_info); static mailmessage_driver local_maildir_message_driver = { .msg_name = "maildir", .msg_initialize = initialize, .msg_uninitialize = mailmessage_generic_uninitialize, .msg_flush = mailmessage_generic_flush, .msg_check = check, .msg_fetch_result_free = mailmessage_generic_fetch_result_free, .msg_fetch = mailmessage_generic_fetch, .msg_fetch_header = mailmessage_generic_fetch_header, .msg_fetch_body = mailmessage_generic_fetch_header, .msg_fetch_size = NULL, .msg_get_bodystructure = mailmessage_generic_get_bodystructure, .msg_fetch_section = mailmessage_generic_fetch_section, .msg_fetch_section_header = mailmessage_generic_fetch_section_header, .msg_fetch_section_mime = mailmessage_generic_fetch_section_mime, .msg_fetch_section_body = mailmessage_generic_fetch_section_body, .msg_fetch_envelope = mailmessage_generic_fetch_envelope, - .msg_get_flags = NULL, + .msg_get_flags = get_flags, }; mailmessage_driver * maildir_message_driver = &local_maildir_message_driver; struct maildir_msg_data { int fd; }; static inline struct maildir_session_state_data * get_session_data(mailmessage * msg) { return msg->msg_session->sess_data; } static struct maildir * get_maildir_session(mailmessage * msg) { return get_session_data(msg)->md_session; } static int prefetch(mailmessage * msg_info) { struct generic_message_t * msg; int res; struct maildir_msg_data * data; char * filename; int fd; char * mapping; struct maildir * md; md = get_maildir_session(msg_info); if (msg_info->msg_uid == NULL) { res = MAIL_ERROR_INVAL; goto err; } filename = maildir_message_get(md, msg_info->msg_uid); if (filename == NULL) { res = MAIL_ERROR_MEMORY; goto err; } fd = open(filename, O_RDONLY); free(filename); if (fd == -1) { res = MAIL_ERROR_FILE; goto err; } mapping = mmap(NULL, msg_info->msg_size, PROT_READ, MAP_PRIVATE, fd, 0); if (mapping == MAP_FAILED) { res = MAIL_ERROR_FILE; goto close; } data = malloc(sizeof(* data)); if (data == NULL) { res = MAIL_ERROR_MEMORY; goto unmap; } data->fd = fd; msg = msg_info->msg_data; msg->msg_data = data; msg->msg_message = mapping; msg->msg_length = msg_info->msg_size; return MAIL_NO_ERROR; unmap: munmap(mapping, msg_info->msg_size); close: close(fd); err: return res; } static void prefetch_free(struct generic_message_t * msg) { if (msg->msg_message != NULL) { struct maildir_msg_data * data; munmap(msg->msg_message, msg->msg_length); msg->msg_message = NULL; data = msg->msg_data; close(data->fd); free(data); } } static int initialize(mailmessage * msg_info) { struct generic_message_t * msg; int r; r = mailmessage_generic_initialize(msg_info); if (r != MAIL_NO_ERROR) return r; msg = msg_info->msg_data; msg->msg_prefetch = prefetch; msg->msg_prefetch_free = prefetch_free; return MAIL_NO_ERROR; } static void check(mailmessage * msg_info) { int r; if (msg_info->msg_flags != NULL) { r = mail_flags_store_set(get_session_data(msg_info)->md_flags_store, msg_info); /* ignore errors */ } } + +static int get_flags(mailmessage * msg_info, + struct mail_flags ** result) +{ + chashdatum key; + chashdatum value; + struct maildir * md; + struct mail_flags * flags; + struct maildir_session_state_data * data; + struct maildir_msg * md_msg; + int r; + uint32_t driver_flags; + clist * ext; + + if (msg_info->msg_flags != NULL) { + * result = msg_info->msg_flags; + return MAIL_NO_ERROR; + } + + data = get_session_data(msg_info); + flags = mail_flags_store_get(data->md_flags_store, + msg_info->msg_index); + if (flags != NULL) { + msg_info->msg_flags = flags; + * result = msg_info->msg_flags; + return MAIL_NO_ERROR; + } + + md = get_maildir_session(msg_info); + if (md == NULL) + return MAIL_ERROR_BAD_STATE; + + key.data = msg_info->msg_uid; + key.len = strlen(msg_info->msg_uid); + r = chash_get(md->mdir_msg_hash, &key, &value); + if (r < 0) + return MAIL_ERROR_MSG_NOT_FOUND; + + md_msg = value.data; + + driver_flags = maildirdriver_maildir_flags_to_flags(md_msg->msg_flags); + + ext = clist_new(); + if (ext == NULL) + return MAIL_ERROR_MEMORY; + + msg_info->msg_flags = mail_flags_new(driver_flags, ext); + + * result = msg_info->msg_flags; + + return MAIL_NO_ERROR; +} diff --git a/kmicromail/libetpan/generic/maildirstorage.c b/kmicromail/libetpan/generic/maildirstorage.c index 7e6b461..e37f591 100644 --- a/kmicromail/libetpan/generic/maildirstorage.c +++ b/kmicromail/libetpan/generic/maildirstorage.c @@ -1,164 +1,165 @@ /* * libEtPan! -- a mail stuff library * * Copyright (C) 2001, 2002 - DINH Viet Hoa * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the libEtPan! project nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * $Id$ */ +#include "maildirstorage.h" #include "mailstorage.h" #include "mail.h" #include "mailmessage.h" #include "maildirdriver.h" #include "maildirdriver_cached.h" #include "maildriver.h" #include <stdlib.h> #include <string.h> /* maildir storage */ static int maildir_mailstorage_connect(struct mailstorage * storage); static int maildir_mailstorage_get_folder_session(struct mailstorage * storage, char * pathname, mailsession ** result); static void maildir_mailstorage_uninitialize(struct mailstorage * storage); static mailstorage_driver maildir_mailstorage_driver = { .sto_name = "maildir", .sto_connect = maildir_mailstorage_connect, .sto_get_folder_session = maildir_mailstorage_get_folder_session, .sto_uninitialize = maildir_mailstorage_uninitialize, }; int maildir_mailstorage_init(struct mailstorage * storage, char * md_pathname, int md_cached, char * md_cache_directory, char * md_flags_directory) { struct maildir_mailstorage * maildir_storage; - maildir_storage = malloc(sizeof(struct maildir_mailstorage)); + maildir_storage = malloc(sizeof(* maildir_storage)); if (maildir_storage == NULL) goto err; maildir_storage->md_pathname = strdup(md_pathname); if (maildir_storage->md_pathname == NULL) goto free; maildir_storage->md_cached = md_cached; if (md_cached && (md_cache_directory != NULL) && (md_flags_directory != NULL)) { maildir_storage->md_cache_directory = strdup(md_cache_directory); if (maildir_storage->md_cache_directory == NULL) goto free_pathname; maildir_storage->md_flags_directory = strdup(md_flags_directory); if (maildir_storage->md_flags_directory == NULL) goto free_cache_directory; } else { maildir_storage->md_cached = FALSE; maildir_storage->md_cache_directory = NULL; maildir_storage->md_flags_directory = NULL; } storage->sto_data = maildir_storage; storage->sto_driver = &maildir_mailstorage_driver; return MAIL_NO_ERROR; free_cache_directory: free(maildir_storage->md_cache_directory); free_pathname: free(maildir_storage->md_pathname); free: free(maildir_storage); err: return MAIL_ERROR_MEMORY; } static void maildir_mailstorage_uninitialize(struct mailstorage * storage) { struct maildir_mailstorage * maildir_storage; maildir_storage = storage->sto_data; if (maildir_storage->md_flags_directory != NULL) free(maildir_storage->md_flags_directory); if (maildir_storage->md_cache_directory != NULL) free(maildir_storage->md_cache_directory); free(maildir_storage->md_pathname); free(maildir_storage); storage->sto_data = NULL; } static int maildir_mailstorage_connect(struct mailstorage * storage) { struct maildir_mailstorage * maildir_storage; mailsession_driver * driver; int r; int res; mailsession * session; maildir_storage = storage->sto_data; if (maildir_storage->md_cached) driver = maildir_cached_session_driver; else driver = maildir_session_driver; session = mailsession_new(driver); if (session == NULL) { res = MAIL_ERROR_MEMORY; goto err; } if (maildir_storage->md_cached) { r = mailsession_parameters(session, MAILDIRDRIVER_CACHED_SET_CACHE_DIRECTORY, maildir_storage->md_cache_directory); if (r != MAIL_NO_ERROR) { res = r; goto free; } r = mailsession_parameters(session, MAILDIRDRIVER_CACHED_SET_FLAGS_DIRECTORY, maildir_storage->md_flags_directory); if (r != MAIL_NO_ERROR) { res = r; goto free; } } r = mailsession_connect_path(session, maildir_storage->md_pathname); switch (r) { diff --git a/kmicromail/libetpan/generic/maildirstorage.h b/kmicromail/libetpan/generic/maildirstorage.h index d17ea2c..73d7b20 100644 --- a/kmicromail/libetpan/generic/maildirstorage.h +++ b/kmicromail/libetpan/generic/maildirstorage.h @@ -1,69 +1,69 @@ /* * libEtPan! -- a mail stuff library * * Copyright (C) 2001, 2002 - DINH Viet Hoa * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the libEtPan! project nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * $Id$ */ #ifndef MAILDIRSTORAGE_H #define MAILDIRSTORAGE_H #include <libetpan/maildirdriver_types.h> #ifdef __cplusplus extern "C" { #endif /* - maildir_mailstorage_init is the constructor for a mbox storage. + maildir_mailstorage_init is the constructor for a maildir storage. @param storage this is the storage to initialize. @param pathname is the directory that contains the mailbox. @param cached if this value is != 0, a persistant cache will be stored on local system. @param cache_directory is the location of the cache @param flags_directory is the location of the flags */ int maildir_mailstorage_init(struct mailstorage * storage, char * md_pathname, int md_cached, char * md_cache_directory, char * md_flags_directory); #ifdef __cplusplus } #endif #endif diff --git a/kmicromail/libetpan/generic/maildriver.c b/kmicromail/libetpan/generic/maildriver.c index 01e3e34..1fc478a 100644 --- a/kmicromail/libetpan/generic/maildriver.c +++ b/kmicromail/libetpan/generic/maildriver.c @@ -189,185 +189,195 @@ int mailsession_select_folder(mailsession * session, char * mb) return MAIL_ERROR_NOT_IMPLEMENTED; return session->sess_driver->sess_select_folder(session, mb); } int mailsession_expunge_folder(mailsession * session) { if (session->sess_driver->sess_expunge_folder == NULL) return MAIL_ERROR_NOT_IMPLEMENTED; return session->sess_driver->sess_expunge_folder(session); } int mailsession_status_folder(mailsession * session, char * mb, uint32_t * result_messages, uint32_t * result_recent, uint32_t * result_unseen) { if (session->sess_driver->sess_status_folder == NULL) return MAIL_ERROR_NOT_IMPLEMENTED; return session->sess_driver->sess_status_folder(session, mb, result_messages, result_recent, result_unseen); } int mailsession_messages_number(mailsession * session, char * mb, uint32_t * result) { if (session->sess_driver->sess_messages_number == NULL) return MAIL_ERROR_NOT_IMPLEMENTED; return session->sess_driver->sess_messages_number(session, mb, result); } int mailsession_recent_number(mailsession * session, char * mb, uint32_t * result) { if (session->sess_driver->sess_recent_number == NULL) return MAIL_ERROR_NOT_IMPLEMENTED; return session->sess_driver->sess_recent_number(session, mb, result); } int mailsession_unseen_number(mailsession * session, char * mb, uint32_t * result) { if (session->sess_driver->sess_unseen_number == NULL) return MAIL_ERROR_NOT_IMPLEMENTED; return session->sess_driver->sess_recent_number(session, mb, result); } int mailsession_list_folders(mailsession * session, char * mb, struct mail_list ** result) { if (session->sess_driver->sess_list_folders == NULL) return MAIL_ERROR_NOT_IMPLEMENTED; return session->sess_driver->sess_list_folders(session, mb, result); } int mailsession_lsub_folders(mailsession * session, char * mb, struct mail_list ** result) { if (session->sess_driver->sess_lsub_folders == NULL) return MAIL_ERROR_NOT_IMPLEMENTED; return session->sess_driver->sess_lsub_folders(session, mb, result); } int mailsession_subscribe_folder(mailsession * session, char * mb) { if (session->sess_driver->sess_subscribe_folder == NULL) return MAIL_ERROR_NOT_IMPLEMENTED; return session->sess_driver->sess_subscribe_folder(session, mb); } int mailsession_unsubscribe_folder(mailsession * session, char * mb) { if (session->sess_driver->sess_unsubscribe_folder == NULL) return MAIL_ERROR_NOT_IMPLEMENTED; return session->sess_driver->sess_unsubscribe_folder(session, mb); } /* message */ int mailsession_append_message(mailsession * session, char * message, size_t size) { if (session->sess_driver->sess_append_message == NULL) return MAIL_ERROR_NOT_IMPLEMENTED; return session->sess_driver->sess_append_message(session, message, size); } +int mailsession_append_message_flags(mailsession * session, + char * message, size_t size, struct mail_flags * flags) +{ + if (session->sess_driver->sess_append_message_flags == NULL) + return MAIL_ERROR_NOT_IMPLEMENTED; + + return session->sess_driver->sess_append_message_flags(session, + message, size, flags); +} + int mailsession_copy_message(mailsession * session, uint32_t num, char * mb) { if (session->sess_driver->sess_copy_message == NULL) return MAIL_ERROR_NOT_IMPLEMENTED; return session->sess_driver->sess_copy_message(session, num, mb); } int mailsession_move_message(mailsession * session, uint32_t num, char * mb) { if (session->sess_driver->sess_move_message == NULL) { int r; if ((session->sess_driver->sess_copy_message == NULL) && (session->sess_driver->sess_remove_message == NULL)) return MAIL_ERROR_NOT_IMPLEMENTED; r = mailsession_copy_message(session, num, mb); if (r != MAIL_NO_ERROR) return r; r = mailsession_remove_message(session, num); if (r != MAIL_NO_ERROR) return r; return MAIL_NO_ERROR; } return session->sess_driver->sess_move_message(session, num, mb); } int mailsession_get_envelopes_list(mailsession * session, struct mailmessage_list * env_list) { if (session->sess_driver->sess_get_envelopes_list == NULL) return MAIL_ERROR_NOT_IMPLEMENTED; return session->sess_driver->sess_get_envelopes_list(session, env_list); } int mailsession_get_messages_list(mailsession * session, struct mailmessage_list ** result) { if (session->sess_driver->sess_get_messages_list == NULL) return MAIL_ERROR_NOT_IMPLEMENTED; return session->sess_driver->sess_get_messages_list(session, result); } int mailsession_remove_message(mailsession * session, uint32_t num) { if (session->sess_driver->sess_remove_message == NULL) return MAIL_ERROR_NOT_IMPLEMENTED; return session->sess_driver->sess_remove_message(session, num); } #if 0 int mailsession_search_messages(mailsession * session, char * charset, struct mail_search_key * key, struct mail_search_result ** result) { if (session->sess_driver->sess_search_messages == NULL) return MAIL_ERROR_NOT_IMPLEMENTED; return session->sess_driver->sess_search_messages(session, charset, key, result); } #endif int mailsession_get_message(mailsession * session, uint32_t num, mailmessage ** result) { if (session->sess_driver->sess_get_message == NULL) return MAIL_ERROR_NOT_IMPLEMENTED; return session->sess_driver->sess_get_message(session, num, result); } int mailsession_get_message_by_uid(mailsession * session, const char * uid, mailmessage ** result) { if (session->sess_driver->sess_get_message_by_uid == NULL) return MAIL_ERROR_NOT_IMPLEMENTED; return session->sess_driver->sess_get_message_by_uid(session, uid, result); } diff --git a/kmicromail/libetpan/generic/maildriver.h b/kmicromail/libetpan/generic/maildriver.h index 7da9aea..c773190 100644 --- a/kmicromail/libetpan/generic/maildriver.h +++ b/kmicromail/libetpan/generic/maildriver.h @@ -307,192 +307,195 @@ int mailsession_messages_number(mailsession * session, char * mb, int mailsession_recent_number(mailsession * session, char * mb, uint32_t * result); /* mailsession_unseen_number queries the number of unseen messages in the folder @param session the session @param mb mailbox to query @param result the number of unseen messages is stored in (* result) @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned on error */ int mailsession_unseen_number(mailsession * session, char * mb, uint32_t * result); /* NOTE: driver's specific should be used mailsession_list_folders returns the list of all sub-mailboxes of the given mailbox @param session the session @param mb the mailbox @param result list of mailboxes if stored in (* result), this structure have to be freed with mail_list_free() @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned on error */ int mailsession_list_folders(mailsession * session, char * mb, struct mail_list ** result); /* NOTE: driver's specific should be used mailsession_lsub_folders returns the list of subscribed sub-mailboxes of the given mailbox @param session the session @param mb the mailbox @param result list of mailboxes if stored in (* result), this structure have to be freed with mail_list_free() @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned on error */ int mailsession_lsub_folders(mailsession * session, char * mb, struct mail_list ** result); /* NOTE: driver's specific should be used mailsession_subscribe_folder subscribes to the given mailbox @param session the session @param mb the mailbox @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned on error */ int mailsession_subscribe_folder(mailsession * session, char * mb); /* NOTE: driver's specific should be used mailsession_unsubscribe_folder unsubscribes to the given mailbox @param session the session @param mb the mailbox @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned on error */ int mailsession_unsubscribe_folder(mailsession * session, char * mb); /* mailsession_append_message adds a RFC 2822 message to the current given mailbox @param session the session @param message is a string that contains the RFC 2822 message @param size this is the size of the message @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned on error */ int mailsession_append_message(mailsession * session, char * message, size_t size); +int mailsession_append_message_flags(mailsession * session, + char * message, size_t size, struct mail_flags * flags); + /* NOTE: some drivers does not implement this mailsession_copy_message copies a message whose number is given to a given mailbox. The mailbox must be accessible from the same session. @param session the session @param num the message number @param mb the destination mailbox @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned on error */ int mailsession_copy_message(mailsession * session, uint32_t num, char * mb); /* NOTE: some drivers does not implement this mailsession_move_message copies a message whose number is given to a given mailbox. The mailbox must be accessible from the same session. @param session the session @param num the message number @param mb the destination mailbox @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned on error */ int mailsession_move_message(mailsession * session, uint32_t num, char * mb); /* mailsession_get_messages_list returns the list of message numbers of the current mailbox. @param session the session @param result the list of message numbers will be stored in (* result), this structure have to be freed with mailmessage_list_free() @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned on error */ int mailsession_get_messages_list(mailsession * session, struct mailmessage_list ** result); /* mailsession_get_envelopes_list fills the parsed fields in the mailmessage structures of the mailmessage_list. @param session the session @param result this is the list of mailmessage structures @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned on error */ int mailsession_get_envelopes_list(mailsession * session, struct mailmessage_list * result); /* NOTE: some drivers does not implement this mailsession_remove_message removes the given message from the mailbox. The message is permanently deleted. @param session the session @param num is the message number @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned on error */ int mailsession_remove_message(mailsession * session, uint32_t num); /* NOTE: this function is not implemented in most drivers mailsession_search_message returns a list of message numbers that corresponds to the given criteria. @param session the session @param charset is the charset to use (it can be NULL) @param key is the list of criteria @param result the search result is stored in (* result), this structure have to be freed with mail_search_result_free() @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned on error */ #if 0 diff --git a/kmicromail/libetpan/generic/maildriver_types.h b/kmicromail/libetpan/generic/maildriver_types.h index 3ff9440..9eab4d6 100644 --- a/kmicromail/libetpan/generic/maildriver_types.h +++ b/kmicromail/libetpan/generic/maildriver_types.h @@ -414,192 +414,194 @@ void mail_search_result_free(struct mail_search_result * search_result); mailmessage structures of the mailmessage_list. - remove_message() removes the given message from the mailbox. The message is permanently deleted. - search_message() returns a list of message numbers that corresponds to the given criteria. - get_message returns a mailmessage structure that corresponds to the given message number. - get_message_by_uid returns a mailmessage structure that corresponds to the given message unique identifier. * mandatory functions are the following : - connect_stream() of connect_path() - logout() - get_messages_list() - get_envelopes_list() * we advise you to implement these functions : - select_folder() (in case a session can access several folders) - noop() (to check if the server is responding) - check_folder() (to make a checkpoint of the session) - status_folder(), messages_number(), recent_number(), unseen_number() (to get stat of the folder) - append_message() (but can't be done in the case of POP3 at least) - login() in a case of an authenticated driver. - starttls() in a case of a stream driver, if the procotol supports STARTTLS. - get_message_by_uid() so that the application can remember the message by UID and build its own list of messages. * drivers' specific : Everything that is specific to the driver will be implemented in this function : - parameters() */ struct mailsession_driver { char * sess_name; int (* sess_initialize)(mailsession * session); void (* sess_uninitialize)(mailsession * session); int (* sess_parameters)(mailsession * session, int id, void * value); int (* sess_connect_stream)(mailsession * session, mailstream * s); int (* sess_connect_path)(mailsession * session, char * path); int (* sess_starttls)(mailsession * session); int (* sess_login)(mailsession * session, char * userid, char * password); int (* sess_logout)(mailsession * session); int (* sess_noop)(mailsession * session); /* folders operations */ int (* sess_build_folder_name)(mailsession * session, char * mb, char * name, char ** result); int (* sess_create_folder)(mailsession * session, char * mb); int (* sess_delete_folder)(mailsession * session, char * mb); int (* sess_rename_folder)(mailsession * session, char * mb, char * new_name); int (* sess_check_folder)(mailsession * session); int (* sess_examine_folder)(mailsession * session, char * mb); int (* sess_select_folder)(mailsession * session, char * mb); int (* sess_expunge_folder)(mailsession * session); int (* sess_status_folder)(mailsession * session, char * mb, uint32_t * result_num, uint32_t * result_recent, uint32_t * result_unseen); int (* sess_messages_number)(mailsession * session, char * mb, uint32_t * result); int (* sess_recent_number)(mailsession * session, char * mb, uint32_t * result); int (* sess_unseen_number)(mailsession * session, char * mb, uint32_t * result); int (* sess_list_folders)(mailsession * session, char * mb, struct mail_list ** result); int (* sess_lsub_folders)(mailsession * session, char * mb, struct mail_list ** result); int (* sess_subscribe_folder)(mailsession * session, char * mb); int (* sess_unsubscribe_folder)(mailsession * session, char * mb); /* messages operations */ int (* sess_append_message)(mailsession * session, char * message, size_t size); + int (* sess_append_message_flags)(mailsession * session, + char * message, size_t size, struct mail_flags * flags); int (* sess_copy_message)(mailsession * session, uint32_t num, char * mb); int (* sess_move_message)(mailsession * session, uint32_t num, char * mb); int (* sess_get_message)(mailsession * session, uint32_t num, mailmessage ** result); int (* sess_get_message_by_uid)(mailsession * session, const char * uid, mailmessage ** result); int (* sess_get_messages_list)(mailsession * session, struct mailmessage_list ** result); int (* sess_get_envelopes_list)(mailsession * session, struct mailmessage_list * env_list); int (* sess_remove_message)(mailsession * session, uint32_t num); #if 0 int (* sess_search_messages)(mailsession * session, char * charset, struct mail_search_key * key, struct mail_search_result ** result); #endif }; /* session is the data structure for a mail session. - data is the internal data structure used by the driver It is called when initializing the mailsession structure. - driver is the driver used for the session */ struct mailsession { void * sess_data; mailsession_driver * sess_driver; }; /* mailmessage_driver is the driver structure to get information from messages. - name is the name of the driver - initialize() is the function that will initializes a data structure specific to the driver, it returns a value that will be stored in the field data of the mailsession. The field data of the session is the state of the session, the internal data structure used by the driver. It is called when initializing the mailmessage structure with mailmessage_init(). - uninitialize() frees the structure created with initialize(). It will be called by mailmessage_free(). - flush() will free from memory all temporary structures of the message (for example, the MIME structure of the message). - fetch_result_free() will free all strings resulted by fetch() or any fetch_xxx() functions that returns a string. - fetch() returns the content of the message (headers and text). - fetch_header() returns the content of the headers. - fetch_body() returns the message text (message content without headers) - fetch_size() returns the size of the message content. - get_bodystructure() returns the MIME structure of the message. - fetch_section() returns the content of a given MIME part - fetch_section_header() returns the header of the message contained by the given MIME part. - fetch_section_mime() returns the MIME headers of the given MIME part. - fetch_section_body() returns the text (if this is a message, this is the message content without headers) of the given MIME part. - fetch_envelope() returns a mailimf_fields structure, with a list of fields chosen by the driver. - get_flags() returns a the flags related to the message. When you want to get flags of a message, you have to make sure to call get_flags() at least once before using directly message->flags. */ #define LIBETPAN_MAIL_MESSAGE_CHECK struct mailmessage_driver { char * msg_name; diff --git a/kmicromail/libetpan/generic/mailfolder.c b/kmicromail/libetpan/generic/mailfolder.c index 2ddc37d..89ba891 100644 --- a/kmicromail/libetpan/generic/mailfolder.c +++ b/kmicromail/libetpan/generic/mailfolder.c @@ -1,96 +1,103 @@ #include "mailfolder.h" #include "maildriver.h" int mailfolder_noop(struct mailfolder * folder) { return mailsession_noop(folder->fld_session); } int mailfolder_check(struct mailfolder * folder) { return mailsession_check_folder(folder->fld_session); } int mailfolder_expunge(struct mailfolder * folder) { return mailsession_expunge_folder(folder->fld_session); } int mailfolder_status(struct mailfolder * folder, uint32_t * result_messages, uint32_t * result_recent, uint32_t * result_unseen) { return mailsession_status_folder(folder->fld_session, folder->fld_pathname, result_messages, result_recent, result_unseen); } int mailfolder_append_message(struct mailfolder * folder, char * message, size_t size) { return mailsession_append_message(folder->fld_session, message, size); } +int mailfolder_append_message_flags(struct mailfolder * folder, + char * message, size_t size, struct mail_flags * flags) +{ + return mailsession_append_message_flags(folder->fld_session, message, + size, flags); +} + int mailfolder_get_messages_list(struct mailfolder * folder, struct mailmessage_list ** result) { int r; struct mailmessage_list * msg_list; unsigned int i; r = mailsession_get_messages_list(folder->fld_session, &msg_list); if (r != MAIL_NO_ERROR) return r; for(i = 0 ; i < carray_count(msg_list->msg_tab) ; i ++) { mailmessage * msg; msg = carray_get(msg_list->msg_tab, i); msg->msg_folder = folder; } * result = msg_list; return MAIL_NO_ERROR; } int mailfolder_get_envelopes_list(struct mailfolder * folder, struct mailmessage_list * result) { return mailsession_get_envelopes_list(folder->fld_session, result); } int mailfolder_get_message(struct mailfolder * folder, uint32_t num, mailmessage ** result) { mailmessage * msg; int r; r = mailsession_get_message(folder->fld_session, num, &msg); if (r != MAIL_NO_ERROR) return r; msg->msg_folder = folder; * result = msg; return MAIL_NO_ERROR; } int mailfolder_get_message_by_uid(struct mailfolder * folder, const char * uid, mailmessage ** result) { mailmessage * msg; int r; r = mailsession_get_message_by_uid(folder->fld_session, uid, &msg); if (r != MAIL_NO_ERROR) return r; msg->msg_folder = folder; * result = msg; return MAIL_NO_ERROR; } diff --git a/kmicromail/libetpan/generic/mailfolder.h b/kmicromail/libetpan/generic/mailfolder.h index 3ecad23..ff53470 100644 --- a/kmicromail/libetpan/generic/mailfolder.h +++ b/kmicromail/libetpan/generic/mailfolder.h @@ -1,32 +1,35 @@ #ifndef MAILFOLDER_H #define MAILFOLDER_H #include "mailstorage_types.h" int mailfolder_noop(struct mailfolder * folder); int mailfolder_check(struct mailfolder * folder); int mailfolder_expunge(struct mailfolder * folder); int mailfolder_status(struct mailfolder * folder, uint32_t * result_messages, uint32_t * result_recent, uint32_t * result_unseen); int mailfolder_append_message(struct mailfolder * folder, char * message, size_t size); +int mailfolder_append_message_flags(struct mailfolder * folder, + char * message, size_t size, struct mail_flags * flags); + int mailfolder_get_messages_list(struct mailfolder * folder, struct mailmessage_list ** result); int mailfolder_get_envelopes_list(struct mailfolder * folder, struct mailmessage_list * result); int mailfolder_get_message(struct mailfolder * folder, uint32_t num, mailmessage ** result); int mailfolder_get_message_by_uid(struct mailfolder * folder, const char * uid, mailmessage ** result); #endif diff --git a/kmicromail/libetpan/generic/mailstorage.c b/kmicromail/libetpan/generic/mailstorage.c index 25e561e..dc91744 100644 --- a/kmicromail/libetpan/generic/mailstorage.c +++ b/kmicromail/libetpan/generic/mailstorage.c @@ -230,105 +230,112 @@ int mailfolder_detach_parent(struct mailfolder * folder) } folder->fld_parent = NULL; folder->fld_sibling_index = 0; return MAIL_NO_ERROR; } struct mailstorage * mailstorage_new(char * sto_id) { struct mailstorage * storage; storage = malloc(sizeof(struct mailstorage)); if (storage == NULL) goto err; if (sto_id != NULL) { storage->sto_id = strdup(sto_id); if (storage->sto_id == NULL) goto free; } else storage->sto_id = NULL; storage->sto_data = NULL; storage->sto_session = NULL; storage->sto_driver = NULL; storage->sto_shared_folders = clist_new(); if (storage->sto_shared_folders == NULL) goto free_id; return storage; free_id: if (storage->sto_id != NULL) free(storage->sto_id); free: free(storage); err: return NULL; } void mailstorage_free(struct mailstorage * storage) { if (storage->sto_session != NULL) mailstorage_disconnect(storage); if (storage->sto_driver != NULL) { if (storage->sto_driver->sto_uninitialize != NULL) storage->sto_driver->sto_uninitialize(storage); } clist_free(storage->sto_shared_folders); if (storage->sto_id != NULL) free(storage->sto_id); free(storage); } int mailstorage_connect(struct mailstorage * storage) { if (storage->sto_session != NULL) return MAIL_NO_ERROR; if (!clist_isempty(storage->sto_shared_folders)) return MAIL_ERROR_BAD_STATE; if (storage->sto_driver->sto_connect == NULL) return MAIL_ERROR_NOT_IMPLEMENTED; return storage->sto_driver->sto_connect(storage); } void mailstorage_disconnect(struct mailstorage * storage) { int r; clistiter * cur; while ((cur = clist_begin(storage->sto_shared_folders)) != NULL) { struct mailfolder * folder; folder = cur->data; mailfolder_disconnect(folder); } if (storage->sto_session == NULL) return; r = mailsession_logout(storage->sto_session); mailsession_free(storage->sto_session); storage->sto_session = NULL; } + +int mailstorage_noop(struct mailstorage * storage) +{ + return mailsession_noop(storage->sto_session); +} + + static int mailstorage_get_folder(struct mailstorage * storage, char * pathname, mailsession ** result) { if (storage->sto_driver->sto_get_folder_session == NULL) return MAIL_ERROR_NOT_IMPLEMENTED; return storage->sto_driver->sto_get_folder_session(storage, pathname, result); } diff --git a/kmicromail/libetpan/generic/mailstorage.h b/kmicromail/libetpan/generic/mailstorage.h index d56aef1..4c57883 100644 --- a/kmicromail/libetpan/generic/mailstorage.h +++ b/kmicromail/libetpan/generic/mailstorage.h @@ -1,98 +1,99 @@ /* * libEtPan! -- a mail stuff library * * Copyright (C) 2001, 2002 - DINH Viet Hoa * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the libEtPan! project nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * $Id$ */ #ifndef MAIL_STORAGE_H #define MAIL_STORAGE_H #include <libetpan/maildriver_types.h> #include <libetpan/mailstorage_types.h> #ifdef __cplusplus extern "C" { #endif /* storage */ /* mailstorage_new This function creates an empty storage. This storage have to be initialized. The "driver" and "data" fields should be initialized. @param id is the name of the storage. It can be NULL. The given parameter is no more needed when the creation is finished. The given string is duplicated. @return The mail storage is returned. */ struct mailstorage * mailstorage_new(char * sto_id); void mailstorage_free(struct mailstorage * storage); /* session will be initialized on success. */ int mailstorage_connect(struct mailstorage * storage); void mailstorage_disconnect(struct mailstorage * storage); +int mailstorage_noop(struct mailstorage * storage); + /* folder */ struct mailfolder * mailfolder_new(struct mailstorage * fld_storage, char * fld_pathname, char * fld_virtual_name); void mailfolder_free(struct mailfolder * folder); int mailfolder_add_child(struct mailfolder * parent, struct mailfolder * child); int mailfolder_detach_parent(struct mailfolder * folder); int mailfolder_connect(struct mailfolder * folder); void mailfolder_disconnect(struct mailfolder * folder); - #ifdef __cplusplus } #endif #endif diff --git a/kmicromail/libetpan/generic/mboxdriver.c b/kmicromail/libetpan/generic/mboxdriver.c index fa3e2ea..c19a668 100644 --- a/kmicromail/libetpan/generic/mboxdriver.c +++ b/kmicromail/libetpan/generic/mboxdriver.c @@ -1,224 +1,228 @@ /* * libEtPan! -- a mail stuff library * * Copyright (C) 2001, 2002 - DINH Viet Hoa * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the libEtPan! project nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * $Id$ */ #include "mboxdriver.h" #include <stdio.h> #include <string.h> #include <sys/types.h> #include <dirent.h> #include <unistd.h> #include <sys/stat.h> #include <ctype.h> #include <stdlib.h> #include <sys/times.h> #include "mail.h" #include "maildriver_tools.h" #include "mailmbox.h" #include "mboxdriver_tools.h" #include "maildriver.h" #include "carray.h" #include "mboxdriver_message.h" #include "mailmessage.h" static int mboxdriver_initialize(mailsession * session); static void mboxdriver_uninitialize(mailsession * session); static int mboxdriver_parameters(mailsession * session, int id, void * value); static int mboxdriver_connect_path(mailsession * session, char * path); static int mboxdriver_logout(mailsession * session); static int mboxdriver_expunge_folder(mailsession * session); static int mboxdriver_status_folder(mailsession * session, char * mb, uint32_t * result_messages, uint32_t * result_recent, uint32_t * result_unseen); static int mboxdriver_messages_number(mailsession * session, char * mb, uint32_t * result); static int mboxdriver_append_message(mailsession * session, char * message, size_t size); +static int mboxdriver_append_message_flags(mailsession * session, + char * message, size_t size, struct mail_flags * flags); + static int mboxdriver_get_messages_list(mailsession * session, struct mailmessage_list ** result); static int mboxdriver_get_envelopes_list(mailsession * session, struct mailmessage_list * env_list); static int mboxdriver_remove_message(mailsession * session, uint32_t num); static int mboxdriver_get_message(mailsession * session, uint32_t num, mailmessage ** result); static int mboxdriver_get_message_by_uid(mailsession * session, const char * uid, mailmessage ** result); static mailsession_driver local_mbox_session_driver = { .sess_name = "mbox", .sess_initialize = mboxdriver_initialize, .sess_uninitialize = mboxdriver_uninitialize, .sess_parameters = mboxdriver_parameters, .sess_connect_path = mboxdriver_connect_path, .sess_connect_stream = NULL, .sess_starttls = NULL, .sess_login = NULL, .sess_logout = mboxdriver_logout, .sess_noop = NULL, .sess_build_folder_name = NULL, .sess_create_folder = NULL, .sess_delete_folder = NULL, .sess_rename_folder = NULL, .sess_check_folder = NULL, .sess_examine_folder = NULL, .sess_select_folder = NULL, .sess_expunge_folder = mboxdriver_expunge_folder, .sess_status_folder = mboxdriver_status_folder, .sess_messages_number = mboxdriver_messages_number, .sess_recent_number = mboxdriver_messages_number, .sess_unseen_number = mboxdriver_messages_number, .sess_list_folders = NULL, .sess_lsub_folders = NULL, .sess_subscribe_folder = NULL, .sess_unsubscribe_folder = NULL, .sess_append_message = mboxdriver_append_message, + .sess_append_message_flags = mboxdriver_append_message_flags, .sess_copy_message = NULL, .sess_move_message = NULL, .sess_get_messages_list = mboxdriver_get_messages_list, .sess_get_envelopes_list = mboxdriver_get_envelopes_list, .sess_remove_message = mboxdriver_remove_message, #if 0 .sess_search_messages = maildriver_generic_search_messages, #endif .sess_get_message = mboxdriver_get_message, .sess_get_message_by_uid = mboxdriver_get_message_by_uid, }; mailsession_driver * mbox_session_driver = &local_mbox_session_driver; static inline struct mbox_session_state_data * get_data(mailsession * session) { return session->sess_data; } static inline struct mailmbox_folder * get_mbox_session(mailsession * session) { return get_data(session)->mbox_folder; } static int mboxdriver_initialize(mailsession * session) { struct mbox_session_state_data * data; data = malloc(sizeof(* data)); if (data == NULL) goto err; data->mbox_folder = NULL; data->mbox_force_read_only = FALSE; data->mbox_force_no_uid = TRUE; session->sess_data = data; return MAIL_NO_ERROR; err: return MAIL_ERROR_MEMORY; } static void free_state(struct mbox_session_state_data * mbox_data) { if (mbox_data->mbox_folder != NULL) { mailmbox_done(mbox_data->mbox_folder); mbox_data->mbox_folder = NULL; } } static void mboxdriver_uninitialize(mailsession * session) { struct mbox_session_state_data * data; data = get_data(session); free_state(data); free(data); } static int mboxdriver_parameters(mailsession * session, int id, void * value) { struct mbox_session_state_data * data; data = get_data(session); switch (id) { case MBOXDRIVER_SET_READ_ONLY: { int * param; param = value; data->mbox_force_read_only = * param; return MAIL_NO_ERROR; } case MBOXDRIVER_SET_NO_UID: { int * param; param = value; data->mbox_force_no_uid = * param; return MAIL_NO_ERROR; } } return MAIL_ERROR_INVAL; @@ -251,192 +255,198 @@ static int mboxdriver_connect_path(mailsession * session, char * path) } static int mboxdriver_logout(mailsession * session) { struct mbox_session_state_data * mbox_data; mbox_data = get_data(session); if (mbox_data->mbox_folder == NULL) return MAIL_ERROR_BAD_STATE; free_state(mbox_data); mbox_data->mbox_folder = NULL; return MAIL_NO_ERROR; } static int mboxdriver_expunge_folder(mailsession * session) { int r; struct mbox_session_state_data * mbox_data; mbox_data = get_data(session); if (mbox_data->mbox_folder == NULL) return MAIL_ERROR_BAD_STATE; r = mailmbox_expunge(mbox_data->mbox_folder); if (r != MAILMBOX_NO_ERROR) return mboxdriver_mbox_error_to_mail_error(r); return MAIL_NO_ERROR; } static int mboxdriver_status_folder(mailsession * session, char * mb, uint32_t * result_messages, uint32_t * result_recent, uint32_t * result_unseen) { uint32_t count; int r; r = mboxdriver_messages_number(session, mb, &count); if (r != MAIL_NO_ERROR) return r; * result_messages = count; * result_recent = count; * result_unseen = count; return MAIL_NO_ERROR; } static int mboxdriver_messages_number(mailsession * session, char * mb, uint32_t * result) { struct mailmbox_folder * folder; int r; folder = get_mbox_session(session); if (folder == NULL) return MAIL_ERROR_STATUS; r = mailmbox_validate_read_lock(folder); if (r != MAIL_NO_ERROR) return r; mailmbox_read_unlock(folder); * result = carray_count(folder->mb_tab) - folder->mb_deleted_count; return MAILMBOX_NO_ERROR; } /* messages operations */ static int mboxdriver_append_message(mailsession * session, char * message, size_t size) { int r; struct mailmbox_folder * folder; folder = get_mbox_session(session); if (folder == NULL) return MAIL_ERROR_APPEND; r = mailmbox_append_message(folder, message, size); switch (r) { case MAILMBOX_ERROR_FILE: return MAIL_ERROR_DISKSPACE; default: return mboxdriver_mbox_error_to_mail_error(r); } } +static int mboxdriver_append_message_flags(mailsession * session, + char * message, size_t size, struct mail_flags * flags) +{ + return mboxdriver_append_message(session, message, size); +} + static int mboxdriver_get_messages_list(mailsession * session, struct mailmessage_list ** result) { struct mailmbox_folder * folder; int res; folder = get_mbox_session(session); if (folder == NULL) { res = MAIL_ERROR_BAD_STATE; goto err; } return mbox_get_messages_list(folder, session, mbox_message_driver, result); err: return res; } static int mboxdriver_get_envelopes_list(mailsession * session, struct mailmessage_list * env_list) { struct mailmbox_folder * folder; unsigned int i; int r; int res; folder = get_mbox_session(session); if (folder == NULL) { res = MAIL_ERROR_BAD_STATE; goto err; } r = mailmbox_validate_read_lock(folder); if (r != MAILMBOX_NO_ERROR) { res = mboxdriver_mbox_error_to_mail_error(r); goto err; } for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) { mailmessage * msg; struct mailimf_fields * fields; char * headers; size_t headers_len; size_t cur_token; msg = carray_get(env_list->msg_tab, i); if (msg == NULL) continue; if (msg->msg_fields != NULL) continue; r = mailmbox_fetch_msg_headers_no_lock(folder, msg->msg_index, &headers, &headers_len); if (r != MAILMBOX_NO_ERROR) { res = mboxdriver_mbox_error_to_mail_error(r); goto unlock; } cur_token = 0; r = mailimf_envelope_fields_parse(headers, headers_len, &cur_token, &fields); if (r != MAILIMF_NO_ERROR) continue; msg->msg_fields = fields; } mailmbox_read_unlock(folder); return MAIL_NO_ERROR; unlock: mailmbox_read_unlock(folder); err: return res; } static int mboxdriver_remove_message(mailsession * session, uint32_t num) { int r; struct mailmbox_folder * folder; folder = get_mbox_session(session); if (folder == NULL) return MAIL_ERROR_DELETE; r = mailmbox_delete_msg(folder, num); return mboxdriver_mbox_error_to_mail_error(r); } static int mboxdriver_get_message(mailsession * session, diff --git a/kmicromail/libetpan/generic/mboxdriver_cached.c b/kmicromail/libetpan/generic/mboxdriver_cached.c index 07871fa..3af7fb9 100644 --- a/kmicromail/libetpan/generic/mboxdriver_cached.c +++ b/kmicromail/libetpan/generic/mboxdriver_cached.c @@ -1,235 +1,240 @@ /* * libEtPan! -- a mail stuff library * * Copyright (C) 2001, 2002 - DINH Viet Hoa * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the libEtPan! project nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * $Id$ */ #include "mboxdriver_cached.h" #include <stdio.h> #include <string.h> #include <dirent.h> #include <unistd.h> #include <ctype.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <stdlib.h> #include "mail.h" #include "mail_cache_db.h" #include "mboxdriver.h" #include "mboxdriver_tools.h" #include "maildriver_tools.h" #include "mailmbox.h" #include "maildriver.h" #include "carray.h" #include "generic_cache.h" #include "imfcache.h" #include "mboxdriver_cached_message.h" #include "libetpan-config.h" static int mboxdriver_cached_initialize(mailsession * session); static void mboxdriver_cached_uninitialize(mailsession * session); static int mboxdriver_cached_parameters(mailsession * session, int id, void * value); static int mboxdriver_cached_connect_path(mailsession * session, char * path); static int mboxdriver_cached_logout(mailsession * session); static int mboxdriver_cached_check_folder(mailsession * session); static int mboxdriver_cached_expunge_folder(mailsession * session); static int mboxdriver_cached_status_folder(mailsession * session, char * mb, uint32_t * result_messages, uint32_t * result_recent, uint32_t * result_unseen); static int mboxdriver_cached_messages_number(mailsession * session, char * mb, uint32_t * result); static int mboxdriver_cached_recent_number(mailsession * session, char * mb, uint32_t * result); static int mboxdriver_cached_unseen_number(mailsession * session, char * mb, uint32_t * result); static int mboxdriver_cached_append_message(mailsession * session, char * message, size_t size); +static int mboxdriver_cached_append_message_flags(mailsession * session, + char * message, size_t size, struct mail_flags * flags); + static int mboxdriver_cached_get_messages_list(mailsession * session, struct mailmessage_list ** result); static int mboxdriver_cached_get_envelopes_list(mailsession * session, struct mailmessage_list * env_list); static int mboxdriver_cached_remove_message(mailsession * session, uint32_t num); static int mboxdriver_cached_get_message(mailsession * session, uint32_t num, mailmessage ** result); static int mboxdriver_cached_get_message_by_uid(mailsession * session, const char * uid, mailmessage ** result); static mailsession_driver local_mbox_cached_session_driver = { .sess_name = "mbox-cached", .sess_initialize = mboxdriver_cached_initialize, .sess_uninitialize = mboxdriver_cached_uninitialize, .sess_parameters = mboxdriver_cached_parameters, .sess_connect_path = mboxdriver_cached_connect_path, .sess_connect_stream = NULL, .sess_starttls = NULL, .sess_login = NULL, .sess_logout = mboxdriver_cached_logout, .sess_noop = NULL, .sess_build_folder_name = NULL, .sess_create_folder = NULL, .sess_delete_folder = NULL, .sess_rename_folder = NULL, .sess_check_folder = mboxdriver_cached_check_folder, .sess_examine_folder = NULL, .sess_select_folder = NULL, .sess_expunge_folder = mboxdriver_cached_expunge_folder, .sess_status_folder = mboxdriver_cached_status_folder, .sess_messages_number = mboxdriver_cached_messages_number, .sess_recent_number = mboxdriver_cached_recent_number, .sess_unseen_number = mboxdriver_cached_unseen_number, .sess_list_folders = NULL, .sess_lsub_folders = NULL, .sess_subscribe_folder = NULL, .sess_unsubscribe_folder = NULL, .sess_append_message = mboxdriver_cached_append_message, + .sess_append_message_flags = mboxdriver_cached_append_message_flags, + .sess_copy_message = NULL, .sess_move_message = NULL, .sess_get_messages_list = mboxdriver_cached_get_messages_list, .sess_get_envelopes_list = mboxdriver_cached_get_envelopes_list, .sess_remove_message = mboxdriver_cached_remove_message, #if 0 .sess_search_messages = maildriver_generic_search_messages, #endif .sess_get_message = mboxdriver_cached_get_message, .sess_get_message_by_uid = mboxdriver_cached_get_message_by_uid, }; mailsession_driver * mbox_cached_session_driver = &local_mbox_cached_session_driver; #define ENV_NAME "env.db" #define FLAGS_NAME "flags.db" static int mbox_error_to_mail_error(int error) { switch (error) { case MAILMBOX_NO_ERROR: return MAIL_NO_ERROR; case MAILMBOX_ERROR_PARSE: return MAIL_ERROR_PARSE; case MAILMBOX_ERROR_INVAL: return MAIL_ERROR_INVAL; case MAILMBOX_ERROR_FILE_NOT_FOUND: return MAIL_ERROR_PARSE; case MAILMBOX_ERROR_MEMORY: return MAIL_ERROR_MEMORY; case MAILMBOX_ERROR_TEMPORARY_FILE: return MAIL_ERROR_PARSE; case MAILMBOX_ERROR_FILE: return MAIL_ERROR_FILE; case MAILMBOX_ERROR_MSG_NOT_FOUND: return MAIL_ERROR_MSG_NOT_FOUND; case MAILMBOX_ERROR_READONLY: return MAIL_ERROR_READONLY; default: return MAIL_ERROR_INVAL; } } static inline struct mbox_cached_session_state_data * get_cached_data(mailsession * session) { return session->sess_data; } static inline mailsession * get_ancestor(mailsession * session) { return get_cached_data(session)->mbox_ancestor; } static inline struct mbox_session_state_data * get_ancestor_data(mailsession * session) { return get_ancestor(session)->sess_data; } static inline struct mailmbox_folder * get_mbox_session(mailsession * session) { return get_ancestor_data(session)->mbox_folder; } static int mboxdriver_cached_initialize(mailsession * session) { struct mbox_cached_session_state_data * cached_data; struct mbox_session_state_data * mbox_data; cached_data = malloc(sizeof(* cached_data)); if (cached_data == NULL) goto err; cached_data->mbox_flags_store = mail_flags_store_new(); if (cached_data->mbox_flags_store == NULL) goto free; @@ -813,293 +818,372 @@ static int mboxdriver_cached_status_folder(mailsession * session, char * mb, } for(i = 0 ; i < carray_count(folder->mb_tab) ; i ++) { struct mailmbox_msg_info * msg_info; struct mail_flags * flags; msg_info = carray_get(folder->mb_tab, i); if (msg_info == NULL) continue; if (msg_info->msg_deleted) continue; r = mboxdriver_get_cached_flags(cache_db_flags, mmapstr, session, msg_info->msg_uid, &flags); if (r != MAIL_NO_ERROR) { recent ++; unseen ++; num ++; continue; } if ((flags->fl_flags & MAIL_FLAG_NEW) != 0) { recent ++; } if ((flags->fl_flags & MAIL_FLAG_SEEN) == 0) { unseen ++; } num ++; mail_flags_free(flags); } mmap_string_free(mmapstr); mail_cache_db_close_unlock(filename_flags, cache_db_flags); * result_messages = num; * result_recent = recent; * result_unseen = unseen; return MAIL_NO_ERROR; close_db_flags: mail_cache_db_close_unlock(filename_flags, cache_db_flags); err: return res; } static int mboxdriver_cached_messages_number(mailsession * session, char * mb, uint32_t * result) { return mailsession_messages_number(get_ancestor(session), mb, result); } static int mboxdriver_cached_recent_number(mailsession * session, char * mb, uint32_t * result) { uint32_t messages; uint32_t recent; uint32_t unseen; int r; r = mboxdriver_cached_status_folder(session, mb, &messages, &recent, &unseen); if (r != MAIL_NO_ERROR) return r; * result = recent; return MAIL_NO_ERROR; } static int mboxdriver_cached_unseen_number(mailsession * session, char * mb, uint32_t * result) { uint32_t messages; uint32_t recent; uint32_t unseen; int r; r = mboxdriver_cached_status_folder(session, mb, &messages, &recent, &unseen); if (r != MAIL_NO_ERROR) return r; * result = unseen; return MAIL_NO_ERROR; } /* messages operations */ static int mboxdriver_cached_append_message(mailsession * session, char * message, size_t size) { - return mailsession_append_message(get_ancestor(session), message, size); + return mboxdriver_cached_append_message_flags(session, + message, size, NULL); +} + +static int mboxdriver_cached_append_message_flags(mailsession * session, + char * message, size_t size, struct mail_flags * flags) +{ + int r; + struct mailmbox_folder * folder; + struct mbox_cached_session_state_data * data; + unsigned int uid; + struct mailmbox_msg_info * msg_info; + chashdatum key; + chashdatum value; + struct mail_cache_db * cache_db_flags; + char filename_flags[PATH_MAX]; + MMAPString * mmapstr; + char keyname[PATH_MAX]; + + folder = get_mbox_session(session); + if (folder == NULL) + return MAIL_ERROR_APPEND; + + r = mailmbox_append_message_uid(folder, message, size, &uid); + + switch (r) { + case MAILMBOX_ERROR_FILE: + return MAIL_ERROR_DISKSPACE; + case MAILMBOX_NO_ERROR: + break; + default: + return mboxdriver_mbox_error_to_mail_error(r); + } + + /* could store in flags store instead */ + + if (flags == NULL) + goto exit; + + key.data = &uid; + key.len = sizeof(uid); + r = chash_get(folder->mb_hash, &key, &value); + if (r < 0) + goto exit; + + msg_info = value.data; + + data = get_cached_data(session); + + snprintf(filename_flags, PATH_MAX, "%s%c%s%c%s", + data->mbox_flags_directory, MAIL_DIR_SEPARATOR, data->mbox_quoted_mb, + MAIL_DIR_SEPARATOR, FLAGS_NAME); + + r = mail_cache_db_open_lock(filename_flags, &cache_db_flags); + if (r < 0) + goto exit; + + mmapstr = mmap_string_new(""); + if (mmapstr == NULL) + goto close_db_flags; + + snprintf(keyname, PATH_MAX, "%u-%lu", uid, + (unsigned long) msg_info->msg_body_len); + + r = mboxdriver_write_cached_flags(cache_db_flags, mmapstr, keyname, flags); + + mmap_string_free(mmapstr); + mail_cache_db_close_unlock(filename_flags, cache_db_flags); + + if (r != MAIL_NO_ERROR) + goto exit; + + return MAIL_NO_ERROR; + + close_db_flags: + mail_cache_db_close_unlock(filename_flags, cache_db_flags); + exit: + return MAIL_NO_ERROR; } static int mboxdriver_cached_get_messages_list(mailsession * session, struct mailmessage_list ** result) { struct mailmbox_folder * folder; int res; folder = get_mbox_session(session); if (folder == NULL) { res = MAIL_ERROR_BAD_STATE; goto err; } return mbox_get_uid_messages_list(folder, session, mbox_cached_message_driver, result); err: return res; } static int get_cached_envelope(struct mail_cache_db * cache_db, MMAPString * mmapstr, mailsession * session, uint32_t num, struct mailimf_fields ** result) { int r; char keyname[PATH_MAX]; struct mailimf_fields * fields; int res; struct mailmbox_msg_info * info; struct mailmbox_folder * folder; chashdatum key; chashdatum data; folder = get_mbox_session(session); if (folder == NULL) { res = MAIL_ERROR_BAD_STATE; goto err; } key.data = # key.len = sizeof(num); r = chash_get(folder->mb_hash, &key, &data); if (r < 0) { res = MAIL_ERROR_MSG_NOT_FOUND; goto err; } info = data.data; - snprintf(keyname, PATH_MAX, "%u-%u-envelope", num, info->msg_body_len); + snprintf(keyname, PATH_MAX, "%u-%lu-envelope", num, + (unsigned long) info->msg_body_len); r = generic_cache_fields_read(cache_db, mmapstr, keyname, &fields); if (r != MAIL_NO_ERROR) { res = r; goto err; } * result = fields; return MAIL_NO_ERROR; err: return res; } static int write_cached_envelope(struct mail_cache_db * cache_db, MMAPString * mmapstr, mailsession * session, uint32_t num, struct mailimf_fields * fields) { int r; char keyname[PATH_MAX]; int res; struct mailmbox_msg_info * info; struct mailmbox_folder * folder; chashdatum key; chashdatum data; folder = get_mbox_session(session); if (folder == NULL) { res = MAIL_ERROR_BAD_STATE; goto err; } key.data = # key.len = sizeof(num); r = chash_get(folder->mb_hash, &key, &data); if (r < 0) { res = MAIL_ERROR_MSG_NOT_FOUND; goto err; } info = data.data; - snprintf(keyname, PATH_MAX, "%u-%u-envelope", num, info->msg_body_len); + snprintf(keyname, PATH_MAX, "%u-%lu-envelope", num, + (unsigned long) info->msg_body_len); r = generic_cache_fields_write(cache_db, mmapstr, keyname, fields); if (r != MAIL_NO_ERROR) { res = r; goto err; } return MAIL_NO_ERROR; err: return res; } static int mboxdriver_cached_get_envelopes_list(mailsession * session, struct mailmessage_list * env_list) { int r; unsigned int i; struct mbox_cached_session_state_data * cached_data; char filename_env[PATH_MAX]; char filename_flags[PATH_MAX]; struct mail_cache_db * cache_db_env; struct mail_cache_db * cache_db_flags; MMAPString * mmapstr; int res; struct mailmbox_folder * folder; folder = get_mbox_session(session); if (folder == NULL) { res = MAIL_ERROR_BAD_STATE; goto err; } cached_data = get_cached_data(session); if (cached_data->mbox_quoted_mb == NULL) { res = MAIL_ERROR_BAD_STATE; goto err; } mbox_flags_store_process(cached_data->mbox_flags_directory, cached_data->mbox_quoted_mb, cached_data->mbox_flags_store); mmapstr = mmap_string_new(""); if (mmapstr == NULL) { res = MAIL_ERROR_MEMORY; goto err; } snprintf(filename_env, PATH_MAX, "%s%c%s%c%s", cached_data->mbox_cache_directory, MAIL_DIR_SEPARATOR, cached_data->mbox_quoted_mb, MAIL_DIR_SEPARATOR, ENV_NAME); r = mail_cache_db_open_lock(filename_env, &cache_db_env); if (r < 0) { res = MAIL_ERROR_MEMORY; goto free_mmapstr; } snprintf(filename_flags, PATH_MAX, "%s%c%s%c%s", cached_data->mbox_flags_directory, MAIL_DIR_SEPARATOR, cached_data->mbox_quoted_mb, MAIL_DIR_SEPARATOR, FLAGS_NAME); r = mail_cache_db_open_lock(filename_flags, &cache_db_flags); if (r < 0) { res = MAIL_ERROR_FILE; goto close_db_env; } /* fill with cached */ for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) { mailmessage * msg; struct mailimf_fields * fields; struct mail_flags * flags; msg = carray_get(env_list->msg_tab, i); if (msg->msg_fields == NULL) { r = get_cached_envelope(cache_db_env, mmapstr, session, msg->msg_index, &fields); if (r == MAIL_NO_ERROR) { msg->msg_cached = TRUE; msg->msg_fields = fields; } } if (msg->msg_flags == NULL) { r = mboxdriver_get_cached_flags(cache_db_flags, mmapstr, session, msg->msg_index, &flags); if (r == MAIL_NO_ERROR) { msg->msg_flags = flags; diff --git a/kmicromail/libetpan/generic/mboxdriver_cached_message.c b/kmicromail/libetpan/generic/mboxdriver_cached_message.c index 6d92b22..828396b 100644 --- a/kmicromail/libetpan/generic/mboxdriver_cached_message.c +++ b/kmicromail/libetpan/generic/mboxdriver_cached_message.c @@ -89,193 +89,194 @@ static mailmessage_driver local_mbox_cached_message_driver = { .msg_fetch_body = mailmessage_generic_fetch_body, .msg_fetch_size = mbox_fetch_size, .msg_get_bodystructure = mailmessage_generic_get_bodystructure, .msg_fetch_section = mailmessage_generic_fetch_section, .msg_fetch_section_header = mailmessage_generic_fetch_section_header, .msg_fetch_section_mime = mailmessage_generic_fetch_section_mime, .msg_fetch_section_body = mailmessage_generic_fetch_section_body, .msg_fetch_envelope = mailmessage_generic_fetch_envelope, .msg_get_flags = mbox_get_flags, }; mailmessage_driver * mbox_cached_message_driver = &local_mbox_cached_message_driver; static inline struct mbox_cached_session_state_data * get_cached_session_data(mailmessage * msg) { return msg->msg_session->sess_data; } static inline mailsession * get_ancestor_session(mailmessage * msg) { return get_cached_session_data(msg)->mbox_ancestor; } static inline struct mbox_session_state_data * get_ancestor_session_data(mailmessage * msg) { return get_ancestor_session(msg)->sess_data; } static inline struct mailmbox_folder * get_mbox_session(mailmessage * msg) { return get_ancestor_session_data(msg)->mbox_folder; } static int mbox_prefetch(mailmessage * msg_info) { struct generic_message_t * msg; int r; char * msg_content; size_t msg_length; r = mboxdriver_fetch_msg(get_ancestor_session(msg_info), msg_info->msg_index, &msg_content, &msg_length); if (r != MAIL_NO_ERROR) return r; msg = msg_info->msg_data; msg->msg_message = msg_content; msg->msg_length = msg_length; return MAIL_NO_ERROR; } static void mbox_prefetch_free(struct generic_message_t * msg) { if (msg->msg_message != NULL) { mmap_string_unref(msg->msg_message); msg->msg_message = NULL; } } static int mbox_initialize(mailmessage * msg_info) { struct generic_message_t * msg; int r; char * uid; char static_uid[PATH_MAX]; struct mailmbox_msg_info * info; struct mailmbox_folder * folder; int res; chashdatum key; chashdatum data; folder = get_mbox_session(msg_info); if (folder == NULL) { res = MAIL_ERROR_BAD_STATE; goto err; } key.data = (char *) &msg_info->msg_index; key.len = sizeof(msg_info->msg_index); r = chash_get(folder->mb_hash, &key, &data); if (r < 0) { res = MAIL_ERROR_MSG_NOT_FOUND; goto err; } info = (struct mailmbox_msg_info *) data.data; - snprintf(static_uid, PATH_MAX, "%u-%u", msg_info->msg_index, info->msg_body_len); + snprintf(static_uid, PATH_MAX, "%u-%lu", + msg_info->msg_index, (unsigned long) info->msg_body_len); uid = strdup(static_uid); if (uid == NULL) { res = MAIL_ERROR_MEMORY; goto err; } r = mailmessage_generic_initialize(msg_info); if (r != MAIL_NO_ERROR) { free(uid); res = r; goto err; } msg = msg_info->msg_data; msg->msg_prefetch = mbox_prefetch; msg->msg_prefetch_free = mbox_prefetch_free; msg_info->msg_uid = uid; return MAIL_NO_ERROR; err: return res; } static void mbox_uninitialize(mailmessage * msg_info) { mailmessage_generic_uninitialize(msg_info); } #define FLAGS_NAME "flags.db" static void mbox_flush(mailmessage * msg_info) { mailmessage_generic_flush(msg_info); } static void mbox_check(mailmessage * msg_info) { int r; if (msg_info->msg_flags != NULL) { r = mail_flags_store_set(get_cached_session_data(msg_info)->mbox_flags_store, msg_info); /* ignore errors */ } } static int mbox_fetch_size(mailmessage * msg_info, size_t * result) { int r; size_t size; r = mboxdriver_fetch_size(get_ancestor_session(msg_info), msg_info->msg_index, &size); if (r != MAIL_NO_ERROR) return r; * result = size; return MAIL_NO_ERROR; } static int mbox_get_flags(mailmessage * msg_info, struct mail_flags ** result) { int r; struct mail_flags * flags; struct mail_cache_db * cache_db_flags; char filename_flags[PATH_MAX]; int res; struct mbox_cached_session_state_data * cached_data; MMAPString * mmapstr; struct mailmbox_folder * folder; if (msg_info->msg_flags != NULL) { * result = msg_info->msg_flags; return MAIL_NO_ERROR; } flags = mail_flags_store_get(get_cached_session_data(msg_info)->mbox_flags_store, msg_info->msg_index); if (flags == NULL) { folder = get_mbox_session(msg_info); if (folder == NULL) { res = MAIL_ERROR_BAD_STATE; goto err; } cached_data = get_cached_session_data(msg_info); if (cached_data->mbox_quoted_mb == NULL) { res = MAIL_ERROR_BAD_STATE; diff --git a/kmicromail/libetpan/generic/mboxdriver_message.c b/kmicromail/libetpan/generic/mboxdriver_message.c index da9a65d..6922625 100644 --- a/kmicromail/libetpan/generic/mboxdriver_message.c +++ b/kmicromail/libetpan/generic/mboxdriver_message.c @@ -1,225 +1,225 @@ /* * libEtPan! -- a mail stuff library * * Copyright (C) 2001, 2002 - DINH Viet Hoa * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the libEtPan! project nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * $Id$ */ -#include "mhdriver_message.h" +#include "mboxdriver_message.h" #include "mailmessage_tools.h" #include "mboxdriver_tools.h" #include "mboxdriver.h" #include "mailmbox.h" #include <unistd.h> #include <sys/mman.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <string.h> #include <stdlib.h> static int mbox_prefetch(mailmessage * msg_info); static void mbox_prefetch_free(struct generic_message_t * msg); static int mbox_initialize(mailmessage * msg_info); static int mbox_fetch_size(mailmessage * msg_info, size_t * result); static int mbox_fetch_header(mailmessage * msg_info, char ** result, size_t * result_len); static mailmessage_driver local_mbox_message_driver = { .msg_name = "mbox", .msg_initialize = mbox_initialize, .msg_uninitialize = mailmessage_generic_uninitialize, .msg_flush = mailmessage_generic_flush, .msg_check = NULL, .msg_fetch_result_free = mailmessage_generic_fetch_result_free, .msg_fetch = mailmessage_generic_fetch, .msg_fetch_header = mbox_fetch_header, .msg_fetch_body = mailmessage_generic_fetch_body, .msg_fetch_size = mbox_fetch_size, .msg_get_bodystructure = mailmessage_generic_get_bodystructure, .msg_fetch_section = mailmessage_generic_fetch_section, .msg_fetch_section_header = mailmessage_generic_fetch_section_header, .msg_fetch_section_mime = mailmessage_generic_fetch_section_mime, .msg_fetch_section_body = mailmessage_generic_fetch_section_body, .msg_fetch_envelope = mailmessage_generic_fetch_envelope, .msg_get_flags = NULL, }; mailmessage_driver * mbox_message_driver = &local_mbox_message_driver; static inline struct mbox_session_state_data * get_data(mailmessage * msg) { return msg->msg_session->sess_data; } static inline struct mailmbox_folder * get_mbox_session(mailmessage * msg) { return get_data(msg)->mbox_folder; } static int mbox_prefetch(mailmessage * msg_info) { struct generic_message_t * msg; int r; char * msg_content; size_t msg_length; r = mboxdriver_fetch_msg(msg_info->msg_session, msg_info->msg_index, &msg_content, &msg_length); if (r != MAIL_NO_ERROR) return r; msg = msg_info->msg_data; msg->msg_message = msg_content; msg->msg_length = msg_length; return MAIL_NO_ERROR; } static void mbox_prefetch_free(struct generic_message_t * msg) { if (msg->msg_message != NULL) { mmap_string_unref(msg->msg_message); msg->msg_message = NULL; } } static int mbox_initialize(mailmessage * msg_info) { struct generic_message_t * msg; int r; char * uid; char static_uid[PATH_MAX]; struct mailmbox_msg_info * info; struct mailmbox_folder * folder; int res; chashdatum key; chashdatum data; folder = get_mbox_session(msg_info); if (folder == NULL) { res = MAIL_ERROR_BAD_STATE; goto err; } key.data = &msg_info->msg_index; key.len = sizeof(msg_info->msg_index); r = chash_get(folder->mb_hash, &key, &data); if (r < 0) { res = MAIL_ERROR_MSG_NOT_FOUND; goto err; } info = data.data; - snprintf(static_uid, PATH_MAX, "%u-%u", - msg_info->msg_index, info->msg_body_len); + snprintf(static_uid, PATH_MAX, "%u-%lu", + msg_info->msg_index, (unsigned long) info->msg_body_len); uid = strdup(static_uid); if (uid == NULL) { res = MAIL_ERROR_MEMORY; goto err; } r = mailmessage_generic_initialize(msg_info); if (r != MAIL_NO_ERROR) { free(uid); res = r; goto err; } msg = msg_info->msg_data; msg->msg_prefetch = mbox_prefetch; msg->msg_prefetch_free = mbox_prefetch_free; msg_info->msg_uid = uid; return MAIL_NO_ERROR; err: return res; } static int mbox_fetch_size(mailmessage * msg_info, size_t * result) { int r; size_t size; r = mboxdriver_fetch_size(msg_info->msg_session, msg_info->msg_index, &size); if (r != MAIL_NO_ERROR) return r; * result = size; return MAIL_NO_ERROR; } static int mbox_fetch_header(mailmessage * msg_info, char ** result, size_t * result_len) { struct generic_message_t * msg; int r; char * msg_content; size_t msg_length; msg = msg_info->msg_data; if (msg->msg_message != NULL) { return mailmessage_generic_fetch_header(msg_info, result, result_len); } else { r = mboxdriver_fetch_header(msg_info->msg_session, msg_info->msg_index, &msg_content, &msg_length); if (r != MAIL_NO_ERROR) return r; * result = msg_content; * result_len = msg_length; return MAIL_NO_ERROR; } } diff --git a/kmicromail/libetpan/generic/mboxdriver_tools.c b/kmicromail/libetpan/generic/mboxdriver_tools.c index 1e27798..252a20b 100644 --- a/kmicromail/libetpan/generic/mboxdriver_tools.c +++ b/kmicromail/libetpan/generic/mboxdriver_tools.c @@ -124,193 +124,194 @@ int mboxdriver_mbox_error_to_mail_error(int error) int mboxdriver_fetch_msg(mailsession * session, uint32_t index, char ** result, size_t * result_len) { int r; char * msg_content; size_t msg_length; struct mailmbox_folder * folder; folder = session_get_mbox_session(session); if (folder == NULL) return MAIL_ERROR_BAD_STATE; r = mailmbox_fetch_msg(folder, index, &msg_content, &msg_length); if (r != MAILMBOX_NO_ERROR) return mboxdriver_mbox_error_to_mail_error(r); * result = msg_content; * result_len = msg_length; return MAIL_NO_ERROR; } int mboxdriver_fetch_size(mailsession * session, uint32_t index, size_t * result) { struct mailmbox_folder * folder; int r; char * data; size_t len; int res; folder = session_get_mbox_session(session); if (folder == NULL) { res = MAIL_ERROR_FETCH; goto err; } r = mailmbox_validate_read_lock(folder); if (r != MAILMBOX_NO_ERROR) { res = mboxdriver_mbox_error_to_mail_error(r); goto err; } r = mailmbox_fetch_msg_no_lock(folder, index, &data, &len); if (r != MAILMBOX_NO_ERROR) { res = mboxdriver_mbox_error_to_mail_error(r); goto unlock; } mailmbox_read_unlock(folder); * result = len; return MAIL_NO_ERROR; unlock: mailmbox_read_unlock(folder); err: return res; } int mboxdriver_get_cached_flags(struct mail_cache_db * cache_db, MMAPString * mmapstr, mailsession * session, uint32_t num, struct mail_flags ** result) { int r; char keyname[PATH_MAX]; struct mail_flags * flags; int res; struct mailmbox_msg_info * info; struct mailmbox_folder * folder; chashdatum key; chashdatum data; folder = cached_session_get_mbox_session(session); if (folder == NULL) { res = MAIL_ERROR_BAD_STATE; goto err; } key.data = # key.len = sizeof(num); r = chash_get(folder->mb_hash, &key, &data); if (r < 0) { res = MAIL_ERROR_MSG_NOT_FOUND; goto err; } info = data.data; - snprintf(keyname, PATH_MAX, "%u-%u-flags", num, info->msg_body_len); + snprintf(keyname, PATH_MAX, "%u-%lu-flags", num, + (unsigned long) info->msg_body_len); r = generic_cache_flags_read(cache_db, mmapstr, keyname, &flags); if (r != MAIL_NO_ERROR) { res = r; goto err; } * result = flags; return MAIL_NO_ERROR; err: return res; } int mboxdriver_write_cached_flags(struct mail_cache_db * cache_db, MMAPString * mmapstr, char * uid, struct mail_flags * flags) { int r; char keyname[PATH_MAX]; int res; snprintf(keyname, PATH_MAX, "%s-flags", uid); r = generic_cache_flags_write(cache_db, mmapstr, keyname, flags); if (r != MAIL_NO_ERROR) { res = r; goto err; } return MAIL_NO_ERROR; err: return res; } int mboxdriver_fetch_header(mailsession * session, uint32_t index, char ** result, size_t * result_len) { int r; char * msg_content; size_t msg_length; struct mailmbox_folder * folder; folder = session_get_mbox_session(session); if (folder == NULL) return MAIL_ERROR_BAD_STATE; r = mailmbox_fetch_msg_headers(folder, index, &msg_content, &msg_length); if (r != MAILMBOX_NO_ERROR) return mboxdriver_mbox_error_to_mail_error(r); * result = msg_content; * result_len = msg_length; return MAIL_NO_ERROR; } int mbox_get_locked_messages_list(struct mailmbox_folder * folder, mailsession * session, mailmessage_driver * driver, int (* lock)(struct mailmbox_folder *), int (* unlock)(struct mailmbox_folder *), struct mailmessage_list ** result) { struct mailmessage_list * env_list; unsigned int i; int r; int res; carray * tab; tab = carray_new(128); if (tab == NULL) { res = MAIL_ERROR_MEMORY; goto err; } r = lock(folder); if (r != MAIL_NO_ERROR) { res = r; goto free; } for(i = 0 ; i < carray_count(folder->mb_tab) ; i ++) { struct mailmbox_msg_info * msg_info; mailmessage * msg; msg_info = carray_get(folder->mb_tab, i); if (msg_info == NULL) continue; if (msg_info->msg_deleted) diff --git a/kmicromail/libetpan/generic/mboxstorage.c b/kmicromail/libetpan/generic/mboxstorage.c index 0a7dc93..4b55b2b 100644 --- a/kmicromail/libetpan/generic/mboxstorage.c +++ b/kmicromail/libetpan/generic/mboxstorage.c @@ -1,164 +1,164 @@ /* * libEtPan! -- a mail stuff library * * Copyright (C) 2001, 2002 - DINH Viet Hoa * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the libEtPan! project nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * $Id$ */ #include "mboxstorage.h" #include "mail.h" #include "mailmessage.h" #include "mboxdriver.h" #include "mboxdriver_cached.h" #include "maildriver.h" #include <stdlib.h> #include <string.h> /* mbox storage */ static int mbox_mailstorage_connect(struct mailstorage * storage); static int mbox_mailstorage_get_folder_session(struct mailstorage * storage, char * pathname, mailsession ** result); static void mbox_mailstorage_uninitialize(struct mailstorage * storage); static mailstorage_driver mbox_mailstorage_driver = { .sto_name = "mbox", .sto_connect = mbox_mailstorage_connect, .sto_get_folder_session = mbox_mailstorage_get_folder_session, .sto_uninitialize = mbox_mailstorage_uninitialize, }; int mbox_mailstorage_init(struct mailstorage * storage, char * mbox_pathname, int mbox_cached, char * mbox_cache_directory, char * mbox_flags_directory) { struct mbox_mailstorage * mbox_storage; - mbox_storage = malloc(sizeof(struct mbox_mailstorage)); + mbox_storage = malloc(sizeof(* mbox_storage)); if (mbox_storage == NULL) goto err; mbox_storage->mbox_pathname = strdup(mbox_pathname); if (mbox_storage->mbox_pathname == NULL) goto free; mbox_storage->mbox_cached = mbox_cached; if (mbox_cached && (mbox_cache_directory != NULL) && (mbox_flags_directory != NULL)) { mbox_storage->mbox_cache_directory = strdup(mbox_cache_directory); if (mbox_storage->mbox_cache_directory == NULL) goto free_pathname; mbox_storage->mbox_flags_directory = strdup(mbox_flags_directory); if (mbox_storage->mbox_flags_directory == NULL) goto free_cache_directory; } else { mbox_storage->mbox_cached = FALSE; mbox_storage->mbox_cache_directory = NULL; mbox_storage->mbox_flags_directory = NULL; } storage->sto_data = mbox_storage; storage->sto_driver = &mbox_mailstorage_driver; return MAIL_NO_ERROR; free_cache_directory: free(mbox_storage->mbox_cache_directory); free_pathname: free(mbox_storage->mbox_pathname); free: free(mbox_storage); err: return MAIL_ERROR_MEMORY; } static void mbox_mailstorage_uninitialize(struct mailstorage * storage) { struct mbox_mailstorage * mbox_storage; mbox_storage = storage->sto_data; if (mbox_storage->mbox_flags_directory != NULL) free(mbox_storage->mbox_flags_directory); if (mbox_storage->mbox_cache_directory != NULL) free(mbox_storage->mbox_cache_directory); free(mbox_storage->mbox_pathname); free(mbox_storage); storage->sto_data = NULL; } static int mbox_mailstorage_connect(struct mailstorage * storage) { struct mbox_mailstorage * mbox_storage; mailsession_driver * driver; int r; int res; mailsession * session; mbox_storage = storage->sto_data; if (mbox_storage->mbox_cached) driver = mbox_cached_session_driver; else driver = mbox_session_driver; session = mailsession_new(driver); if (session == NULL) { res = MAIL_ERROR_MEMORY; goto err; } if (mbox_storage->mbox_cached) { r = mailsession_parameters(session, MBOXDRIVER_CACHED_SET_CACHE_DIRECTORY, mbox_storage->mbox_cache_directory); if (r != MAIL_NO_ERROR) { res = r; goto free; } r = mailsession_parameters(session, MBOXDRIVER_CACHED_SET_FLAGS_DIRECTORY, mbox_storage->mbox_flags_directory); if (r != MAIL_NO_ERROR) { res = r; goto free; } } r = mailsession_connect_path(session, mbox_storage->mbox_pathname); switch (r) { diff --git a/kmicromail/libetpan/generic/mhdriver.c b/kmicromail/libetpan/generic/mhdriver.c index af38d27..05a6a4f 100644 --- a/kmicromail/libetpan/generic/mhdriver.c +++ b/kmicromail/libetpan/generic/mhdriver.c @@ -1,238 +1,241 @@ /* * libEtPan! -- a mail stuff library * * Copyright (C) 2001, 2002 - DINH Viet Hoa * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the libEtPan! project nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * $Id$ */ #include "mhdriver.h" #include <stdio.h> #include <sys/types.h> #include <dirent.h> #include <unistd.h> #include <sys/stat.h> #include <ctype.h> #include <fcntl.h> #include <sys/mman.h> #include <stdlib.h> #include <string.h> #include "mailmh.h" #include "maildriver_tools.h" #include "mhdriver_tools.h" #include "mhdriver_message.h" #include "mailmessage.h" static int mhdriver_initialize(mailsession * session); static void mhdriver_uninitialize(mailsession * session); static int mhdriver_connect_path(mailsession * session, char * path); static int mhdriver_logout(mailsession * session); static int mhdriver_build_folder_name(mailsession * session, char * mb, char * name, char ** result); static int mhdriver_create_folder(mailsession * session, char * mb); static int mhdriver_delete_folder(mailsession * session, char * mb); static int mhdriver_rename_folder(mailsession * session, char * mb, char * new_name); static int mhdriver_select_folder(mailsession * session, char * mb); static int mhdriver_status_folder(mailsession * session, char * mb, uint32_t * result_messages, uint32_t * result_recent, uint32_t * result_unseen); static int mhdriver_messages_number(mailsession * session, char * mb, uint32_t * result); static int mhdriver_list_folders(mailsession * session, char * mb, struct mail_list ** result); static int mhdriver_lsub_folders(mailsession * session, char * mb, struct mail_list ** result); static int mhdriver_subscribe_folder(mailsession * session, char * mb); static int mhdriver_unsubscribe_folder(mailsession * session, char * mb); static int mhdriver_append_message(mailsession * session, char * message, size_t size); +static int mhdriver_append_message_flags(mailsession * session, + char * message, size_t size, struct mail_flags * flags); static int mhdriver_copy_message(mailsession * session, uint32_t num, char * mb); static int mhdriver_remove_message(mailsession * session, uint32_t num); static int mhdriver_move_message(mailsession * session, uint32_t num, char * mb); static int mhdriver_get_messages_list(mailsession * session, struct mailmessage_list ** result); static int mhdriver_get_message(mailsession * session, uint32_t num, mailmessage ** result); static int mhdriver_get_message_by_uid(mailsession * session, const char * uid, mailmessage ** result); static mailsession_driver local_mh_session_driver = { .sess_name = "mh", .sess_initialize = mhdriver_initialize, .sess_uninitialize = mhdriver_uninitialize, .sess_parameters = NULL, .sess_connect_stream = NULL, .sess_connect_path = mhdriver_connect_path, .sess_starttls = NULL, .sess_login = NULL, .sess_logout = mhdriver_logout, .sess_noop = NULL, .sess_build_folder_name = mhdriver_build_folder_name, .sess_create_folder = mhdriver_create_folder, .sess_delete_folder = mhdriver_delete_folder, .sess_rename_folder = mhdriver_rename_folder, .sess_check_folder = NULL, .sess_examine_folder = NULL, .sess_select_folder = mhdriver_select_folder, .sess_expunge_folder = NULL, .sess_status_folder = mhdriver_status_folder, .sess_messages_number = mhdriver_messages_number, .sess_recent_number = mhdriver_messages_number, .sess_unseen_number = mhdriver_messages_number, .sess_list_folders = mhdriver_list_folders, .sess_lsub_folders = mhdriver_lsub_folders, .sess_subscribe_folder = mhdriver_subscribe_folder, .sess_unsubscribe_folder = mhdriver_unsubscribe_folder, .sess_append_message = mhdriver_append_message, + .sess_append_message_flags = mhdriver_append_message_flags, .sess_copy_message = mhdriver_copy_message, .sess_move_message = mhdriver_move_message, .sess_get_messages_list = mhdriver_get_messages_list, .sess_get_envelopes_list = maildriver_generic_get_envelopes_list, .sess_remove_message = mhdriver_remove_message, #if 0 .sess_search_messages = maildriver_generic_search_messages, #endif .sess_get_message = mhdriver_get_message, .sess_get_message_by_uid = mhdriver_get_message_by_uid, }; mailsession_driver * mh_session_driver = &local_mh_session_driver; static inline struct mh_session_state_data * get_data(mailsession * session) { return session->sess_data; } static inline struct mailmh * get_mh_session(mailsession * session) { return get_data(session)->mh_session; } static inline struct mailmh_folder * get_mh_cur_folder(mailsession * session) { return get_data(session)->mh_cur_folder; } static int add_to_list(mailsession * session, char * mb) { char * new_mb; struct mh_session_state_data * data; int r; data = get_data(session); new_mb = strdup(mb); if (new_mb == NULL) return -1; r = clist_append(data->mh_subscribed_list, new_mb); if (r < 0) { free(mb); return -1; } return 0; } static int remove_from_list(mailsession * session, char * mb) { clistiter * cur; struct mh_session_state_data * data; data = get_data(session); for(cur = clist_begin(data->mh_subscribed_list) ; cur != NULL ; cur = clist_next(cur)) { char * cur_name; cur_name = clist_content(cur); if (strcmp(cur_name, mb) == 0) { clist_delete(data->mh_subscribed_list, cur); free(cur_name); return 0; } } return -1; } static int mhdriver_initialize(mailsession * session) { struct mh_session_state_data * data; data = malloc(sizeof(* data)); if (data == NULL) goto err; data->mh_session = NULL; data->mh_cur_folder = NULL; data->mh_subscribed_list = clist_new(); if (data->mh_subscribed_list == NULL) goto free; session->sess_data = data; return MAIL_NO_ERROR; free: free(data); err: @@ -591,192 +594,198 @@ static int mhdriver_lsub_folders(mailsession * session, char * mb, struct mail_list ** result) { clist * subscribed; clist * lsub_result; clistiter * cur; struct mail_list * lsub; size_t length; int r; length = strlen(mb); subscribed = get_data(session)->mh_subscribed_list; lsub_result = clist_new(); if (lsub_result == NULL) return MAIL_ERROR_MEMORY; for(cur = clist_begin(subscribed) ; cur != NULL ; cur = clist_next(cur)) { char * cur_mb; char * new_mb; cur_mb = clist_content(cur); if (strncmp(mb, cur_mb, length) == 0) { new_mb = strdup(cur_mb); if (new_mb == NULL) goto free_list; r = clist_append(lsub_result, new_mb); if (r < 0) { free(new_mb); goto free_list; } } } lsub = mail_list_new(lsub_result); if (lsub == NULL) goto free_list; * result = lsub; return MAIL_NO_ERROR; free_list: clist_foreach(lsub_result, (clist_func) free, NULL); clist_free(lsub_result); return MAIL_ERROR_MEMORY; } static int mhdriver_subscribe_folder(mailsession * session, char * mb) { int r; r = add_to_list(session, mb); if (r < 0) return MAIL_ERROR_SUBSCRIBE; return MAIL_NO_ERROR; } static int mhdriver_unsubscribe_folder(mailsession * session, char * mb) { int r; r = remove_from_list(session, mb); if (r < 0) return MAIL_ERROR_UNSUBSCRIBE; return MAIL_NO_ERROR; } /* messages operations */ static int mhdriver_append_message(mailsession * session, char * message, size_t size) { int r; struct mailmh_folder * folder; folder = get_mh_cur_folder(session); if (folder == NULL) return MAIL_ERROR_BAD_STATE; r = mailmh_folder_add_message(folder, message, size); switch (r) { case MAILMH_ERROR_FILE: return MAIL_ERROR_DISKSPACE; default: return mhdriver_mh_error_to_mail_error(r); } } +static int mhdriver_append_message_flags(mailsession * session, + char * message, size_t size, struct mail_flags * flags) +{ + return mhdriver_append_message(session, message, size); +} + static int mhdriver_copy_message(mailsession * session, uint32_t num, char * mb) { int fd; int r; struct mailmh_folder * folder; struct mailmh * mh; int res; mh = get_mh_session(session); if (mh == NULL) { res = MAIL_ERROR_BAD_STATE; goto err; } folder = get_mh_cur_folder(session); if (folder == NULL) { res = MAIL_ERROR_BAD_STATE; goto err; } r = mailmh_folder_get_message_fd(folder, num, O_RDONLY, &fd); if (r != MAIL_NO_ERROR) { res = r; goto err; } folder = mailmh_folder_find(mh->mh_main, mb); if (folder == NULL) { res = MAIL_ERROR_FOLDER_NOT_FOUND; goto close; } r = mailmh_folder_add_message_file(folder, fd); if (r != MAIL_NO_ERROR) { res = MAIL_ERROR_COPY; goto close; } close(fd); return MAIL_NO_ERROR; close: close(fd); err: return res; } static int mhdriver_remove_message(mailsession * session, uint32_t num) { int r; struct mailmh_folder * folder; folder = get_mh_cur_folder(session); if (folder == NULL) return MAIL_ERROR_DELETE; r = mailmh_folder_remove_message(folder, num); return mhdriver_mh_error_to_mail_error(r); } static int mhdriver_move_message(mailsession * session, uint32_t num, char * mb) { int r; struct mailmh_folder * src_folder; struct mailmh_folder * dest_folder; struct mailmh * mh; mh = get_mh_session(session); if (mh == NULL) return MAIL_ERROR_BAD_STATE; src_folder = get_mh_cur_folder(session); if (src_folder == NULL) return MAIL_ERROR_BAD_STATE; dest_folder = mailmh_folder_find(mh->mh_main, mb); if (dest_folder == NULL) return MAIL_ERROR_FOLDER_NOT_FOUND; r = mailmh_folder_move_message(dest_folder, src_folder, num); return mhdriver_mh_error_to_mail_error(r); } static int mhdriver_get_messages_list(mailsession * session, struct mailmessage_list ** result) { struct mailmh_folder * folder; int res; folder = get_mh_cur_folder(session); diff --git a/kmicromail/libetpan/generic/mhdriver_cached.c b/kmicromail/libetpan/generic/mhdriver_cached.c index 5c35089..04aa523 100644 --- a/kmicromail/libetpan/generic/mhdriver_cached.c +++ b/kmicromail/libetpan/generic/mhdriver_cached.c @@ -15,249 +15,252 @@ * 3. Neither the name of the libEtPan! project nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * $Id$ */ #include "mhdriver_cached.h" #include <stdio.h> #include <sys/types.h> #include <dirent.h> #include <unistd.h> #include <sys/stat.h> #include <ctype.h> #include <fcntl.h> #include <sys/mman.h> #include <stdlib.h> #include <string.h> #include "mail.h" #include "mail_cache_db.h" #include "generic_cache.h" #include "imfcache.h" #include "mhdriver.h" #include "mhdriver_cached_message.h" #include "mailmh.h" #include "maildriver_tools.h" #include "mhdriver_tools.h" #include "mailmessage.h" static int mhdriver_cached_initialize(mailsession * session); static void mhdriver_cached_uninitialize(mailsession * session); static int mhdriver_cached_parameters(mailsession * session, int id, void * value); static int mhdriver_cached_connect_path(mailsession * session, char * path); static int mhdriver_cached_logout(mailsession * session); static int mhdriver_cached_build_folder_name(mailsession * session, char * mb, char * name, char ** result); static int mhdriver_cached_create_folder(mailsession * session, char * mb); static int mhdriver_cached_delete_folder(mailsession * session, char * mb); static int mhdriver_cached_rename_folder(mailsession * session, char * mb, char * new_name); static int mhdriver_cached_check_folder(mailsession * session); static int mhdriver_cached_select_folder(mailsession * session, char * mb); static int mhdriver_cached_expunge_folder(mailsession * session); static int mhdriver_cached_status_folder(mailsession * session, char * mb, uint32_t * result_messages, uint32_t * result_recent, uint32_t * result_unseen); static int mhdriver_cached_messages_number(mailsession * session, char * mb, uint32_t * result); static int mhdriver_cached_recent_number(mailsession * session, char * mb, uint32_t * result); static int mhdriver_cached_unseen_number(mailsession * session, char * mb, uint32_t * result); static int mhdriver_cached_list_folders(mailsession * session, char * mb, struct mail_list ** result); static int mhdriver_cached_lsub_folders(mailsession * session, char * mb, struct mail_list ** result); static int mhdriver_cached_subscribe_folder(mailsession * session, char * mb); static int mhdriver_cached_unsubscribe_folder(mailsession * session, char * mb); static int mhdriver_cached_append_message(mailsession * session, char * message, size_t size); +static int mhdriver_cached_append_message_flags(mailsession * session, + char * message, size_t size, struct mail_flags * flags); static int mhdriver_cached_copy_message(mailsession * session, uint32_t num, char * mb); static int mhdriver_cached_remove_message(mailsession * session, uint32_t num); static int mhdriver_cached_move_message(mailsession * session, uint32_t num, char * mb); static int mhdriver_cached_get_messages_list(mailsession * session, struct mailmessage_list ** result); static int mhdriver_cached_get_envelopes_list(mailsession * session, struct mailmessage_list * env_list); static int mhdriver_cached_get_message(mailsession * session, uint32_t num, mailmessage ** result); static int mhdriver_cached_get_message_by_uid(mailsession * session, const char * uid, mailmessage ** result); static mailsession_driver local_mh_cached_session_driver = { .sess_name = "mh-cached", .sess_initialize = mhdriver_cached_initialize, .sess_uninitialize = mhdriver_cached_uninitialize, .sess_parameters = mhdriver_cached_parameters, .sess_connect_stream = NULL, .sess_connect_path = mhdriver_cached_connect_path, .sess_starttls = NULL, .sess_login = NULL, .sess_logout = mhdriver_cached_logout, .sess_noop = NULL, .sess_build_folder_name = mhdriver_cached_build_folder_name, .sess_create_folder = mhdriver_cached_create_folder, .sess_delete_folder = mhdriver_cached_delete_folder, .sess_rename_folder = mhdriver_cached_rename_folder, .sess_check_folder = mhdriver_cached_check_folder, .sess_examine_folder = NULL, .sess_select_folder = mhdriver_cached_select_folder, .sess_expunge_folder = mhdriver_cached_expunge_folder, .sess_status_folder = mhdriver_cached_status_folder, .sess_messages_number = mhdriver_cached_messages_number, .sess_recent_number = mhdriver_cached_recent_number, .sess_unseen_number = mhdriver_cached_unseen_number, .sess_list_folders = mhdriver_cached_list_folders, .sess_lsub_folders = mhdriver_cached_lsub_folders, .sess_subscribe_folder = mhdriver_cached_subscribe_folder, .sess_unsubscribe_folder = mhdriver_cached_unsubscribe_folder, .sess_append_message = mhdriver_cached_append_message, + .sess_append_message_flags = mhdriver_cached_append_message_flags, .sess_copy_message = mhdriver_cached_copy_message, .sess_move_message = mhdriver_cached_move_message, .sess_get_messages_list = mhdriver_cached_get_messages_list, .sess_get_envelopes_list = mhdriver_cached_get_envelopes_list, .sess_remove_message = mhdriver_cached_remove_message, #if 0 .sess_search_messages = maildriver_generic_search_messages, #endif .sess_get_message = mhdriver_cached_get_message, .sess_get_message_by_uid = mhdriver_cached_get_message_by_uid, }; mailsession_driver * mh_cached_session_driver = &local_mh_cached_session_driver; #define ENV_NAME "env.db" #define FLAGS_NAME "flags.db" static inline struct mh_cached_session_state_data * get_cached_data(mailsession * session) { return session->sess_data; } static inline mailsession * get_ancestor(mailsession * session) { return get_cached_data(session)->mh_ancestor; } static inline struct mh_session_state_data * get_ancestor_data(mailsession * session) { return get_ancestor(session)->sess_data; } static inline struct mailmh * get_mh_session(mailsession * session) { return get_ancestor_data(session)->mh_session; } static inline struct mailmh_folder * get_mh_cur_folder(mailsession * session) { return get_ancestor_data(session)->mh_cur_folder; } #define FILENAME_MAX_UID "max-uid" /* write max uid current value */ static int write_max_uid_value(mailsession * session) { int r; char filename[PATH_MAX]; FILE * f; int res; struct mh_cached_session_state_data * cached_data; struct mh_session_state_data * ancestor_data; int fd; MMAPString * mmapstr; size_t cur_token; cached_data = get_cached_data(session); ancestor_data = get_ancestor_data(session); if (cached_data->mh_quoted_mb == NULL) return MAIL_ERROR_BAD_STATE; snprintf(filename, PATH_MAX, "%s/%s/%s", cached_data->mh_cache_directory, cached_data->mh_quoted_mb, FILENAME_MAX_UID); fd = creat(filename, S_IRUSR | S_IWUSR); if (fd < 0) { res = MAIL_ERROR_FILE; goto err; } f = fdopen(fd, "w"); if (f == NULL) { close(fd); res = MAIL_ERROR_FILE; goto err; } mmapstr = mmap_string_new(""); if (mmapstr == NULL) { res = MAIL_ERROR_MEMORY; goto close; } @@ -790,309 +793,389 @@ static int mhdriver_cached_status_folder(mailsession * session, char * mb, } if ((flags->fl_flags & MAIL_FLAG_NEW) != 0) { recent ++; } if ((flags->fl_flags & MAIL_FLAG_SEEN) == 0) { unseen ++; } mail_flags_free(flags); } mmap_string_free(mmapstr); mail_cache_db_close_unlock(filename_flags, cache_db_flags); * result_messages = count; * result_recent = recent; * result_unseen = unseen; return MAIL_NO_ERROR; close_db_flags: mail_cache_db_close_unlock(filename_flags, cache_db_flags); err: return res; } static int mhdriver_cached_messages_number(mailsession * session, char * mb, uint32_t * result) { return mailsession_messages_number(get_ancestor(session), mb, result); } static int mhdriver_cached_recent_number(mailsession * session, char * mb, uint32_t * result) { uint32_t messages; uint32_t recent; uint32_t unseen; int r; r = mhdriver_cached_status_folder(session, mb, &messages, &recent, &unseen); if (r != MAIL_NO_ERROR) return r; * result = recent; return MAIL_NO_ERROR; } static int mhdriver_cached_unseen_number(mailsession * session, char * mb, uint32_t * result) { uint32_t messages; uint32_t recent; uint32_t unseen; int r; r = mhdriver_cached_status_folder(session, mb, &messages, &recent, &unseen); if (r != MAIL_NO_ERROR) return r; * result = recent; return MAIL_NO_ERROR; } static int mhdriver_cached_list_folders(mailsession * session, char * mb, struct mail_list ** result) { return mailsession_list_folders(get_ancestor(session), mb, result); } static int mhdriver_cached_lsub_folders(mailsession * session, char * mb, struct mail_list ** result) { return mailsession_lsub_folders(get_ancestor(session), mb, result); } static int mhdriver_cached_subscribe_folder(mailsession * session, char * mb) { return mailsession_subscribe_folder(get_ancestor(session), mb); } static int mhdriver_cached_unsubscribe_folder(mailsession * session, char * mb) { return mailsession_unsubscribe_folder(get_ancestor(session), mb); } /* messages operations */ static int mhdriver_cached_append_message(mailsession * session, char * message, size_t size) { - return mailsession_append_message(get_ancestor(session), message, size); + return mhdriver_cached_append_message_flags(session, + message, size, NULL); +} + +static int mhdriver_cached_append_message_flags(mailsession * session, + char * message, size_t size, struct mail_flags * flags) +{ + int r; + struct mailmh_folder * folder; + struct mailmh_msg_info * msg_info; + chashdatum key; + chashdatum value; + uint32_t uid; + struct mh_cached_session_state_data * data; + char filename_flags[PATH_MAX]; + struct mail_cache_db * cache_db_flags; + MMAPString * mmapstr; + char keyname[PATH_MAX]; + + folder = get_mh_cur_folder(session); + if (folder == NULL) + return MAIL_ERROR_BAD_STATE; + + r = mailmh_folder_add_message_uid(folder, + message, size, &uid); + + switch (r) { + case MAILMH_ERROR_FILE: + return MAIL_ERROR_DISKSPACE; + + case MAILMH_NO_ERROR: + break; + + default: + return mhdriver_mh_error_to_mail_error(r); + } + + if (flags == NULL) + goto exit; + + key.data = &uid; + key.len = sizeof(uid); + r = chash_get(folder->fl_msgs_hash, &key, &value); + if (r < 0) + return MAIL_ERROR_CACHE_MISS; + + msg_info = value.data; + + data = get_cached_data(session); + + snprintf(filename_flags, PATH_MAX, "%s/%s/%s", + data->mh_flags_directory, data->mh_quoted_mb, FLAGS_NAME); + + r = mail_cache_db_open_lock(filename_flags, &cache_db_flags); + if (r < 0) + goto exit; + + mmapstr = mmap_string_new(""); + if (mmapstr == NULL) + goto close_db_flags; + + snprintf(keyname, PATH_MAX, "%u-%lu-%lu-flags", + uid, (unsigned long) msg_info->msg_mtime, + (unsigned long) msg_info->msg_size); + + r = mhdriver_write_cached_flags(cache_db_flags, mmapstr, keyname, flags); + + mmap_string_free(mmapstr); + mail_cache_db_close_unlock(filename_flags, cache_db_flags); + + if (r != MAIL_NO_ERROR) + goto exit; + + return MAIL_NO_ERROR; + + close_db_flags: + mail_cache_db_close_unlock(filename_flags, cache_db_flags); + exit: + return MAIL_NO_ERROR; } static int mhdriver_cached_copy_message(mailsession * session, uint32_t num, char * mb) { return mailsession_copy_message(get_ancestor(session), num, mb); } static int mhdriver_cached_remove_message(mailsession * session, uint32_t num) { return mailsession_remove_message(get_ancestor(session), num); } static int mhdriver_cached_move_message(mailsession * session, uint32_t num, char * mb) { return mailsession_move_message(get_ancestor(session), num, mb); } static int mhdriver_cached_get_messages_list(mailsession * session, struct mailmessage_list ** result) { struct mailmh_folder * folder; int res; folder = get_mh_cur_folder(session); if (folder == NULL) { res = MAIL_ERROR_BAD_STATE; goto err; } return mh_get_messages_list(folder, session, mh_cached_message_driver, result); err: return res; } static int get_cached_envelope(struct mail_cache_db * cache_db, MMAPString * mmapstr, mailsession * session, uint32_t num, struct mailimf_fields ** result) { int r; char keyname[PATH_MAX]; struct mailimf_fields * fields; int res; struct mailmh_folder * folder; struct mailmh_msg_info * msg_info; chashdatum key; chashdatum data; folder = get_mh_cur_folder(session); #if 0 msg_info = cinthash_find(mh_data->mh_cur_folder->fl_msgs_hash, num); if (msg_info == NULL) return MAIL_ERROR_CACHE_MISS; #endif key.data = # key.len = sizeof(num); r = chash_get(folder->fl_msgs_hash, &key, &data); if (r < 0) return MAIL_ERROR_CACHE_MISS; msg_info = data.data; - snprintf(keyname, PATH_MAX, "%u-%u-%u-envelope", - num, (uint32_t) msg_info->msg_mtime, msg_info->msg_size); + snprintf(keyname, PATH_MAX, "%u-%lu-%lu-envelope", + num, (unsigned long) msg_info->msg_mtime, + (unsigned long) msg_info->msg_size); r = generic_cache_fields_read(cache_db, mmapstr, keyname, &fields); if (r != MAIL_NO_ERROR) { res = r; goto err; } * result = fields; return MAIL_NO_ERROR; err: return res; } static int write_cached_envelope(struct mail_cache_db * cache_db, MMAPString * mmapstr, mailsession * session, uint32_t num, struct mailimf_fields * fields) { int r; char keyname[PATH_MAX]; int res; struct mailmh_folder * folder; chashdatum key; chashdatum data; struct mailmh_msg_info * msg_info; folder = get_mh_cur_folder(session); #if 0 msg_info = cinthash_find(mh_data->mh_cur_folder->fl_msgs_hash, num); if (msg_info == NULL) { res = MAIL_ERROR_CACHE_MISS; goto err; } #endif key.data = # key.len = sizeof(num); r = chash_get(folder->fl_msgs_hash, &key, &data); if (r < 0) return MAIL_ERROR_CACHE_MISS; msg_info = data.data; - snprintf(keyname, PATH_MAX, "%u-%u-%u-envelope", - num, (uint32_t) msg_info->msg_mtime, msg_info->msg_size); + snprintf(keyname, PATH_MAX, "%u-%lu-%lu-envelope", + num, (unsigned long) msg_info->msg_mtime, + (unsigned long) msg_info->msg_size); r = generic_cache_fields_write(cache_db, mmapstr, keyname, fields); if (r != MAIL_NO_ERROR) { res = r; goto err; } return MAIL_NO_ERROR; err: return res; } static int mhdriver_cached_get_envelopes_list(mailsession * session, struct mailmessage_list * env_list) { int r; unsigned int i; char filename_env[PATH_MAX]; char filename_flags[PATH_MAX]; struct mail_cache_db * cache_db_env; struct mail_cache_db * cache_db_flags; MMAPString * mmapstr; int res; struct mh_cached_session_state_data * cached_data; cached_data = get_cached_data(session); if (cached_data->mh_quoted_mb == NULL) { res = MAIL_ERROR_BAD_STATE; goto err; } mh_flags_store_process(cached_data->mh_flags_directory, cached_data->mh_quoted_mb, cached_data->mh_flags_store); mmapstr = mmap_string_new(""); if (mmapstr == NULL) { res = MAIL_ERROR_MEMORY; goto err; } snprintf(filename_env, PATH_MAX, "%s/%s/%s", cached_data->mh_cache_directory, cached_data->mh_quoted_mb, ENV_NAME); r = mail_cache_db_open_lock(filename_env, &cache_db_env); if (r < 0) { res = MAIL_ERROR_MEMORY; goto free_mmapstr; } snprintf(filename_flags, PATH_MAX, "%s/%s/%s", cached_data->mh_flags_directory, cached_data->mh_quoted_mb, FLAGS_NAME); r = mail_cache_db_open_lock(filename_flags, &cache_db_flags); if (r < 0) { res = MAIL_ERROR_MEMORY; goto close_db_env; } /* fill with cached */ for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) { mailmessage * msg; struct mailimf_fields * fields; struct mail_flags * flags; msg = carray_get(env_list->msg_tab, i); if (msg->msg_fields == NULL) { r = get_cached_envelope(cache_db_env, mmapstr, msg->msg_session, msg->msg_index, &fields); if (r == MAIL_NO_ERROR) { msg->msg_cached = TRUE; msg->msg_fields = fields; } } if (msg->msg_flags == NULL) { r = mhdriver_get_cached_flags(cache_db_flags, mmapstr, session, msg->msg_index, &flags); if (r == MAIL_NO_ERROR) { msg->msg_flags = flags; } } } mail_cache_db_close_unlock(filename_flags, cache_db_flags); mail_cache_db_close_unlock(filename_env, cache_db_env); r = mailsession_get_envelopes_list(get_ancestor(session), env_list); if (r != MAIL_NO_ERROR) { res = r; diff --git a/kmicromail/libetpan/generic/mhdriver_cached_message.c b/kmicromail/libetpan/generic/mhdriver_cached_message.c index f716fb9..f69868d 100644 --- a/kmicromail/libetpan/generic/mhdriver_cached_message.c +++ b/kmicromail/libetpan/generic/mhdriver_cached_message.c @@ -86,194 +86,194 @@ static mailmessage_driver local_mh_cached_message_driver = { .msg_fetch = mailmessage_generic_fetch, .msg_fetch_header = mh_fetch_header, .msg_fetch_body = mailmessage_generic_fetch_body, .msg_fetch_size = mh_fetch_size, .msg_get_bodystructure = mailmessage_generic_get_bodystructure, .msg_fetch_section = mailmessage_generic_fetch_section, .msg_fetch_section_header = mailmessage_generic_fetch_section_header, .msg_fetch_section_mime = mailmessage_generic_fetch_section_mime, .msg_fetch_section_body = mailmessage_generic_fetch_section_body, .msg_fetch_envelope = mailmessage_generic_fetch_envelope, .msg_get_flags = mh_get_flags, }; mailmessage_driver * mh_cached_message_driver = &local_mh_cached_message_driver; static inline struct mh_cached_session_state_data * get_cached_session_data(mailmessage * msg) { return msg->msg_session->sess_data; } static inline mailsession * get_ancestor_session(mailmessage * msg) { return get_cached_session_data(msg)->mh_ancestor; } static inline struct mh_session_state_data * get_ancestor_session_data(mailmessage * msg) { return get_ancestor_session(msg)->sess_data; } static inline struct mailmh * get_mh_session(mailmessage * msg) { return get_ancestor_session_data(msg)->mh_session; } static inline struct mailmh_folder * get_mh_cur_folder(mailmessage * msg) { return get_ancestor_session_data(msg)->mh_cur_folder; } static int mh_prefetch(mailmessage * msg_info) { struct generic_message_t * msg; int r; char * msg_content; size_t msg_length; r = mhdriver_fetch_message(get_ancestor_session(msg_info), msg_info->msg_index, &msg_content, &msg_length); if (r != MAIL_NO_ERROR) return r; msg = msg_info->msg_data; msg->msg_message = msg_content; msg->msg_length = msg_length; return MAIL_NO_ERROR; } static void mh_prefetch_free(struct generic_message_t * msg) { if (msg->msg_message != NULL) { mmap_string_unref(msg->msg_message); msg->msg_message = NULL; } } static int mh_initialize(mailmessage * msg_info) { struct generic_message_t * msg; int r; char * uid; char static_uid[PATH_MAX]; struct mailmh_msg_info * mh_msg_info; chashdatum key; chashdatum data; struct mailmh_folder * folder; folder = get_mh_cur_folder(msg_info); key.data = &msg_info->msg_index; key.len = sizeof(msg_info->msg_index); r = chash_get(folder->fl_msgs_hash, &key, &data); if (r < 0) return MAIL_ERROR_INVAL; mh_msg_info = data.data; - snprintf(static_uid, PATH_MAX, "%u-%lu-%u", msg_info->msg_index, - mh_msg_info->msg_mtime, mh_msg_info->msg_size); + snprintf(static_uid, PATH_MAX, "%u-%lu-%lu", msg_info->msg_index, + mh_msg_info->msg_mtime, (unsigned long) mh_msg_info->msg_size); uid = strdup(static_uid); if (uid == NULL) return MAIL_ERROR_MEMORY; r = mailmessage_generic_initialize(msg_info); if (r != MAIL_NO_ERROR) { free(uid); return r; } msg = msg_info->msg_data; msg->msg_prefetch = mh_prefetch; msg->msg_prefetch_free = mh_prefetch_free; msg_info->msg_uid = uid; return MAIL_NO_ERROR; } static void mh_uninitialize(mailmessage * msg_info) { mailmessage_generic_uninitialize(msg_info); } #define FLAGS_NAME "flags.db" static void mh_flush(mailmessage * msg_info) { mailmessage_generic_flush(msg_info); } static void mh_check(mailmessage * msg_info) { int r; if (msg_info->msg_flags != NULL) { r = mail_flags_store_set(get_cached_session_data(msg_info)->mh_flags_store, msg_info); /* ignore errors */ } } static int mh_fetch_size(mailmessage * msg_info, size_t * result) { int r; size_t size; r = mhdriver_fetch_size(get_ancestor_session(msg_info), msg_info->msg_index, &size); if (r != MAIL_NO_ERROR) return r; * result = size; return MAIL_NO_ERROR; } static int mh_get_flags(mailmessage * msg_info, struct mail_flags ** result) { int r; struct mail_flags * flags; struct mail_cache_db * cache_db_flags; char filename_flags[PATH_MAX]; int res; struct mh_cached_session_state_data * cached_data; MMAPString * mmapstr; if (msg_info->msg_flags != NULL) { * result = msg_info->msg_flags; return MAIL_NO_ERROR; } cached_data = get_cached_session_data(msg_info); flags = mail_flags_store_get(cached_data->mh_flags_store, msg_info->msg_index); if (flags == NULL) { if (cached_data->mh_quoted_mb == NULL) { res = MAIL_ERROR_BAD_STATE; goto err; } snprintf(filename_flags, PATH_MAX, "%s/%s/%s", cached_data->mh_flags_directory, cached_data->mh_quoted_mb, FLAGS_NAME); r = mail_cache_db_open_lock(filename_flags, &cache_db_flags); if (r < 0) { res = MAIL_ERROR_MEMORY; goto err; } diff --git a/kmicromail/libetpan/generic/mhdriver_message.c b/kmicromail/libetpan/generic/mhdriver_message.c index 2c023e7..aafd2d9 100644 --- a/kmicromail/libetpan/generic/mhdriver_message.c +++ b/kmicromail/libetpan/generic/mhdriver_message.c @@ -51,162 +51,163 @@ static int mh_prefetch(mailmessage * msg_info); static void mh_prefetch_free(struct generic_message_t * msg); static int mh_initialize(mailmessage * msg_info); static int mh_fetch_size(mailmessage * msg_info, size_t * result); static int mh_fetch_header(mailmessage * msg_info, char ** result, size_t * result_len); static mailmessage_driver local_mh_message_driver = { .msg_name = "mh", .msg_initialize = mh_initialize, .msg_uninitialize = mailmessage_generic_uninitialize, .msg_flush = mailmessage_generic_flush, .msg_check = NULL, .msg_fetch_result_free = mailmessage_generic_fetch_result_free, .msg_fetch = mailmessage_generic_fetch, .msg_fetch_header = mh_fetch_header, .msg_fetch_body = mailmessage_generic_fetch_body, .msg_fetch_size = mh_fetch_size, .msg_get_bodystructure = mailmessage_generic_get_bodystructure, .msg_fetch_section = mailmessage_generic_fetch_section, .msg_fetch_section_header = mailmessage_generic_fetch_section_header, .msg_fetch_section_mime = mailmessage_generic_fetch_section_mime, .msg_fetch_section_body = mailmessage_generic_fetch_section_body, .msg_fetch_envelope = mailmessage_generic_fetch_envelope, .msg_get_flags = NULL, }; mailmessage_driver * mh_message_driver = &local_mh_message_driver; static int mh_prefetch(mailmessage * msg_info) { struct generic_message_t * msg; int r; char * msg_content; size_t msg_length; r = mhdriver_fetch_message(msg_info->msg_session, msg_info->msg_index, &msg_content, &msg_length); if (r != MAIL_NO_ERROR) return r; msg = msg_info->msg_data; msg->msg_message = msg_content; msg->msg_length = msg_length; return MAIL_NO_ERROR; } static void mh_prefetch_free(struct generic_message_t * msg) { if (msg->msg_message != NULL) { mmap_string_unref(msg->msg_message); msg->msg_message = NULL; } } static inline struct mh_session_state_data * get_data(mailmessage * msg) { return msg->msg_session->sess_data; } static inline struct mailmh_folder * get_mh_cur_folder(mailmessage * msg) { return get_data(msg)->mh_cur_folder; } static int mh_initialize(mailmessage * msg_info) { struct generic_message_t * msg; int r; char * uid; char static_uid[PATH_MAX]; struct mailmh_msg_info * mh_msg_info; chashdatum key; chashdatum value; key.data = &msg_info->msg_index; key.len = sizeof(msg_info->msg_index); r = chash_get(get_mh_cur_folder(msg_info)->fl_msgs_hash, &key, &value); if (r < 0) return MAIL_ERROR_INVAL; mh_msg_info = value.data; - snprintf(static_uid, PATH_MAX, "%u-%lu-%u", msg_info->msg_index, - mh_msg_info->msg_mtime, mh_msg_info->msg_size); + snprintf(static_uid, PATH_MAX, "%u-%lu-%lu", msg_info->msg_index, + (unsigned long) mh_msg_info->msg_mtime, + (unsigned long) mh_msg_info->msg_size); uid = strdup(static_uid); if (uid == NULL) return MAIL_ERROR_MEMORY; r = mailmessage_generic_initialize(msg_info); if (r != MAIL_NO_ERROR) { free(uid); return r; } msg = msg_info->msg_data; msg->msg_prefetch = mh_prefetch; msg->msg_prefetch_free = mh_prefetch_free; msg_info->msg_uid = uid; return MAIL_NO_ERROR; } static int mh_fetch_size(mailmessage * msg_info, size_t * result) { int r; size_t size; r = mhdriver_fetch_size(msg_info->msg_session, msg_info->msg_index, &size); if (r != MAIL_NO_ERROR) return r; * result = size; return MAIL_NO_ERROR; } static int mh_fetch_header(mailmessage * msg_info, char ** result, size_t * result_len) { struct generic_message_t * msg; int r; char * msg_content; size_t msg_length; msg = msg_info->msg_data; if (msg->msg_message != NULL) { r = mailmessage_generic_fetch_header(msg_info, result, result_len); return r; } else { r = mhdriver_fetch_header(msg_info->msg_session, msg_info->msg_index, &msg_content, &msg_length); if (r != MAIL_NO_ERROR) return r; * result = msg_content; * result_len = msg_length; return MAIL_NO_ERROR; } } diff --git a/kmicromail/libetpan/generic/mhdriver_tools.c b/kmicromail/libetpan/generic/mhdriver_tools.c index cb863fa..c15bb6d 100644 --- a/kmicromail/libetpan/generic/mhdriver_tools.c +++ b/kmicromail/libetpan/generic/mhdriver_tools.c @@ -276,194 +276,195 @@ int mhdriver_fetch_header(mailsession * session, uint32_t index, else break; } mailimf_crlf_parse(str, size, &cur_token); mmapstr = mmap_string_new_len(str + begin, cur_token - begin); if (mmapstr == NULL) { res = MAIL_ERROR_MEMORY; goto unmap; } if (mmap_string_ref(mmapstr) != 0) { res = MAIL_ERROR_MEMORY; goto free_str; } munmap(str, size); close(fd); * result = mmapstr->str; * result_len = mmapstr->len; return MAIL_NO_ERROR; free_str: mmap_string_free(mmapstr); unmap: munmap(str, size); close: close(fd); err: return res; } int mhdriver_fetch_size(mailsession * session, uint32_t index, size_t * result) { struct mailmh_folder * folder; int r; struct stat buf; char * name; folder = get_mh_cur_folder(session); if (folder == NULL) return MAIL_ERROR_FETCH; r = mailmh_folder_get_message_filename(folder, index, &name); switch (r) { case MAILMH_NO_ERROR: break; default: return mhdriver_mh_error_to_mail_error(r); } r = stat(name, &buf); free(name); if (r == -1) return MAIL_ERROR_FETCH; * result = buf.st_size; return MAIL_NO_ERROR; } int mhdriver_get_cached_flags(struct mail_cache_db * cache_db, MMAPString * mmapstr, mailsession * session, uint32_t num, struct mail_flags ** result) { int r; char keyname[PATH_MAX]; struct mail_flags * flags; int res; struct mailmh_msg_info * msg_info; chashdatum key; chashdatum data; struct mailmh_folder * folder; folder = cached_get_mh_cur_folder(session); #if 0 msg_info = cinthash_find(mh_data->cur_folder->fl_msgs_hash, num); if (msg_info == NULL) return MAIL_ERROR_CACHE_MISS; #endif key.data = # key.len = sizeof(num); r = chash_get(folder->fl_msgs_hash, &key, &data); if (r < 0) return MAIL_ERROR_CACHE_MISS; msg_info = data.data; - snprintf(keyname, PATH_MAX, "%u-%u-%u-flags", - num, (uint32_t) msg_info->msg_mtime, msg_info->msg_size); + snprintf(keyname, PATH_MAX, "%u-%lu-%lu-flags", + num, (unsigned long) msg_info->msg_mtime, + (unsigned long) msg_info->msg_size); r = generic_cache_flags_read(cache_db, mmapstr, keyname, &flags); if (r != MAIL_NO_ERROR) { res = r; goto err; } * result = flags; return MAIL_NO_ERROR; err: return res; } int mhdriver_write_cached_flags(struct mail_cache_db * cache_db, MMAPString * mmapstr, char * uid, struct mail_flags * flags) { int r; char keyname[PATH_MAX]; int res; snprintf(keyname, PATH_MAX, "%s-flags", uid); r = generic_cache_flags_write(cache_db, mmapstr, keyname, flags); if (r != MAIL_NO_ERROR) { res = r; goto err; } return MAIL_NO_ERROR; err: return res; } int mh_get_messages_list(struct mailmh_folder * folder, mailsession * session, mailmessage_driver * driver, struct mailmessage_list ** result) { unsigned int i; struct mailmessage_list * env_list; int r; carray * tab; int res; tab = carray_new(128); if (tab == NULL) { res = MAIL_ERROR_MEMORY; goto err; } for(i = 0 ; i < carray_count(folder->fl_msgs_tab) ; i++) { struct mailmh_msg_info * mh_info; mailmessage * msg; mh_info = carray_get(folder->fl_msgs_tab, i); if (mh_info == NULL) continue; msg = mailmessage_new(); if (msg == NULL) { res = MAIL_ERROR_MEMORY; goto free_list; } r = mailmessage_init(msg, session, driver, mh_info->msg_index, mh_info->msg_size); if (r != MAIL_NO_ERROR) { res = r; goto free_list; } r = carray_add(tab, msg, NULL); if (r < 0) { mailmessage_free(msg); res = MAIL_ERROR_MEMORY; goto free_list; } } env_list = mailmessage_list_new(tab); if (env_list == NULL) { res = MAIL_ERROR_MEMORY; goto free_list; } * result = env_list; return MAIL_NO_ERROR; free_list: diff --git a/kmicromail/libetpan/generic/mhstorage.c b/kmicromail/libetpan/generic/mhstorage.c index 32fc26b..715b961 100644 --- a/kmicromail/libetpan/generic/mhstorage.c +++ b/kmicromail/libetpan/generic/mhstorage.c @@ -1,161 +1,161 @@ /* * libEtPan! -- a mail stuff library * * Copyright (C) 2001, 2002 - DINH Viet Hoa * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the libEtPan! project nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * $Id$ */ #include "mhstorage.h" #include "mhdriver.h" #include "mhdriver_cached.h" #include "mail.h" #include <stdlib.h> #include <string.h> /* mh storage */ static int mh_mailstorage_connect(struct mailstorage * storage); static int mh_mailstorage_get_folder_session(struct mailstorage * storage, char * pathname, mailsession ** result); static void mh_mailstorage_uninitialize(struct mailstorage * storage); static mailstorage_driver mh_mailstorage_driver = { .sto_name = "mh", .sto_connect = mh_mailstorage_connect, .sto_get_folder_session = mh_mailstorage_get_folder_session, .sto_uninitialize = mh_mailstorage_uninitialize, }; int mh_mailstorage_init(struct mailstorage * storage, char * mh_pathname, int mh_cached, char * mh_cache_directory, char * mh_flags_directory) { struct mh_mailstorage * mh_storage; - mh_storage = malloc(sizeof(struct mh_mailstorage)); + mh_storage = malloc(sizeof(* mh_storage)); if (mh_storage == NULL) goto err; mh_storage->mh_pathname = strdup(mh_pathname); if (mh_storage->mh_pathname == NULL) goto free; mh_storage->mh_cached = mh_cached; if (mh_cached && (mh_cache_directory != NULL) && (mh_flags_directory != NULL)) { mh_storage->mh_cache_directory = strdup(mh_cache_directory); if (mh_storage->mh_cache_directory == NULL) goto free_pathname; mh_storage->mh_flags_directory = strdup(mh_flags_directory); if (mh_storage->mh_flags_directory == NULL) goto free_cache_directory; } else { mh_storage->mh_cached = FALSE; mh_storage->mh_cache_directory = NULL; mh_storage->mh_flags_directory = NULL; } storage->sto_data = mh_storage; storage->sto_driver = &mh_mailstorage_driver; return MAIL_NO_ERROR; free_cache_directory: free(mh_storage->mh_cache_directory); free_pathname: free(mh_storage->mh_pathname); free: free(mh_storage); err: return MAIL_ERROR_MEMORY; } static void mh_mailstorage_uninitialize(struct mailstorage * storage) { struct mh_mailstorage * mh_storage; mh_storage = storage->sto_data; if (mh_storage->mh_flags_directory != NULL) free(mh_storage->mh_flags_directory); if (mh_storage->mh_cache_directory != NULL) free(mh_storage->mh_cache_directory); free(mh_storage->mh_pathname); free(mh_storage); storage->sto_data = NULL; } static int mh_mailstorage_connect(struct mailstorage * storage) { struct mh_mailstorage * mh_storage; mailsession_driver * driver; int r; int res; mailsession * session; mh_storage = storage->sto_data; if (mh_storage->mh_cached) driver = mh_cached_session_driver; else driver = mh_session_driver; session = mailsession_new(driver); if (session == NULL) { res = MAIL_ERROR_MEMORY; goto err; } if (mh_storage->mh_cached) { r = mailsession_parameters(session, MHDRIVER_CACHED_SET_CACHE_DIRECTORY, mh_storage->mh_cache_directory); if (r != MAIL_NO_ERROR) { res = r; goto free; } r = mailsession_parameters(session, MHDRIVER_CACHED_SET_FLAGS_DIRECTORY, mh_storage->mh_flags_directory); if (r != MAIL_NO_ERROR) { res = r; goto free; } } r = mailsession_connect_path(session, mh_storage->mh_pathname); switch (r) { case MAIL_NO_ERROR_NON_AUTHENTICATED: diff --git a/kmicromail/libetpan/generic/nntpdriver.c b/kmicromail/libetpan/generic/nntpdriver.c index fde5f1a..1b65838 100644 --- a/kmicromail/libetpan/generic/nntpdriver.c +++ b/kmicromail/libetpan/generic/nntpdriver.c @@ -1,227 +1,231 @@ /* * libEtPan! -- a mail stuff library * * Copyright (C) 2001, 2002 - DINH Viet Hoa * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the libEtPan! project nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * $Id$ */ #include "nntpdriver.h" #include <string.h> #include <stdlib.h> #include "mail.h" #include "mailmessage.h" #include "nntpdriver_tools.h" #include "maildriver_tools.h" #include "nntpdriver_message.h" static int nntpdriver_initialize(mailsession * session); static void nntpdriver_uninitialize(mailsession * session); static int nntpdriver_parameters(mailsession * session, int id, void * value); static int nntpdriver_connect_stream(mailsession * session, mailstream * s); static int nntpdriver_login(mailsession * session, char * userid, char * password); static int nntpdriver_logout(mailsession * session); static int nntpdriver_status_folder(mailsession * session, char * mb, uint32_t * result_messages, uint32_t * result_recent, uint32_t * result_unseen); static int nntpdriver_messages_number(mailsession * session, char * mb, uint32_t * result); static int nntpdriver_append_message(mailsession * session, char * message, size_t size); +static int nntpdriver_append_message_flags(mailsession * session, + char * message, size_t size, struct mail_flags * flags); + static int nntpdriver_get_envelopes_list(mailsession * session, struct mailmessage_list * env_list); static int nntpdriver_get_messages_list(mailsession * session, struct mailmessage_list ** result); static int nntpdriver_list_folders(mailsession * session, char * mb, struct mail_list ** result); static int nntpdriver_lsub_folders(mailsession * session, char * mb, struct mail_list ** result); static int nntpdriver_subscribe_folder(mailsession * session, char * mb); static int nntpdriver_unsubscribe_folder(mailsession * session, char * mb); static int nntpdriver_get_message(mailsession * session, uint32_t num, mailmessage ** result); static int nntpdriver_get_message_by_uid(mailsession * session, const char * uid, mailmessage ** result); static int nntpdriver_noop(mailsession * session); static mailsession_driver local_nntp_session_driver = { .sess_name = "nntp", .sess_initialize = nntpdriver_initialize, .sess_uninitialize = nntpdriver_uninitialize, .sess_parameters = nntpdriver_parameters, .sess_connect_stream = nntpdriver_connect_stream, .sess_connect_path = NULL, .sess_starttls = NULL, .sess_login = nntpdriver_login, .sess_logout = nntpdriver_logout, .sess_noop = nntpdriver_noop, .sess_build_folder_name = NULL, .sess_create_folder = NULL, .sess_delete_folder = NULL, .sess_rename_folder = NULL, .sess_check_folder = NULL, .sess_examine_folder = NULL, .sess_select_folder = nntpdriver_select_folder, .sess_expunge_folder = NULL, .sess_status_folder = nntpdriver_status_folder, .sess_messages_number = nntpdriver_messages_number, .sess_recent_number = nntpdriver_messages_number, .sess_unseen_number = nntpdriver_messages_number, .sess_list_folders = nntpdriver_list_folders, .sess_lsub_folders = nntpdriver_lsub_folders, .sess_subscribe_folder = nntpdriver_subscribe_folder, .sess_unsubscribe_folder = nntpdriver_unsubscribe_folder, .sess_append_message = nntpdriver_append_message, + .sess_append_message_flags = nntpdriver_append_message_flags, .sess_copy_message = NULL, .sess_move_message = NULL, .sess_get_messages_list = nntpdriver_get_messages_list, .sess_get_envelopes_list = nntpdriver_get_envelopes_list, .sess_remove_message = NULL, #if 0 .sess_search_messages = maildriver_generic_search_messages, #endif .sess_get_message = nntpdriver_get_message, .sess_get_message_by_uid = nntpdriver_get_message_by_uid, }; mailsession_driver * nntp_session_driver = &local_nntp_session_driver; static inline struct nntp_session_state_data * get_data(mailsession * session) { return session->sess_data; } static inline newsnntp * get_nntp_session(mailsession * session) { return get_data(session)->nntp_session; } static int nntpdriver_initialize(mailsession * session) { struct nntp_session_state_data * data; newsnntp * nntp; nntp = newsnntp_new(0, NULL); if (nntp == NULL) goto err; data = malloc(sizeof(* data)); if (data == NULL) goto free; data->nntp_session = nntp; data->nntp_userid = NULL; data->nntp_password = NULL; data->nntp_group_info = NULL; data->nntp_group_name = NULL; data->nntp_subscribed_list = clist_new(); if (data->nntp_subscribed_list == NULL) goto free_data; data->nntp_max_articles = 0; data->nntp_mode_reader = FALSE; session->sess_data = data; return MAIL_NO_ERROR; free_data: free(data); free: newsnntp_free(nntp); err: return MAIL_ERROR_MEMORY; } static void nntpdriver_uninitialize(mailsession * session) { struct nntp_session_state_data * data; data = get_data(session); clist_foreach(data->nntp_subscribed_list, (clist_func) free, NULL); clist_free(data->nntp_subscribed_list); if (data->nntp_group_info != NULL) newsnntp_group_free(data->nntp_group_info); if (data->nntp_group_name != NULL) free(data->nntp_group_name); if (data->nntp_userid != NULL) free(data->nntp_userid); if (data->nntp_password != NULL) free(data->nntp_password); newsnntp_free(data->nntp_session); free(data); session->sess_data = NULL; } @@ -537,192 +541,198 @@ static int nntpdriver_lsub_folders(mailsession * session, char * mb, for(cur = clist_begin(subscribed) ; cur != NULL ; cur = clist_next(cur)) { char * cur_mb; char * new_mb; cur_mb = clist_content(cur); if (strncmp(mb, cur_mb, length) == 0) { new_mb = strdup(cur_mb); if (new_mb == NULL) { res = MAIL_ERROR_MEMORY; goto free_list; } r = clist_append(lsub_result, new_mb); if (r < 0) { free(new_mb); res = MAIL_ERROR_MEMORY; goto free_list; } } } lsub = mail_list_new(lsub_result); if (lsub == NULL) { res = MAIL_ERROR_MEMORY; goto free_list; } * result = lsub; return MAIL_NO_ERROR; free_list: clist_foreach(lsub_result, (clist_func) free, NULL); clist_free(lsub_result); err: return res; } static int nntpdriver_subscribe_folder(mailsession * session, char * mb) { int r; r = add_to_list(session, mb); if (r < 0) return MAIL_ERROR_SUBSCRIBE; return MAIL_NO_ERROR; } static int nntpdriver_unsubscribe_folder(mailsession * session, char * mb) { int r; r = remove_from_list(session, mb); if (r < 0) return MAIL_ERROR_UNSUBSCRIBE; return MAIL_NO_ERROR; } /* messages operations */ static int nntpdriver_append_message(mailsession * session, char * message, size_t size) { int r; struct nntp_session_state_data * data; data = get_data(session); do { r = newsnntp_post(get_nntp_session(session), message, size); switch (r) { case NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_USERNAME: r = nntpdriver_authenticate_user(session); if (r != MAIL_NO_ERROR) return r; break; case NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_PASSWORD: r = nntpdriver_authenticate_password(session); if (r != MAIL_NO_ERROR) return r; break; default: return nntpdriver_nntp_error_to_mail_error(r); } } while (1); } +static int nntpdriver_append_message_flags(mailsession * session, + char * message, size_t size, struct mail_flags * flags) +{ + return nntpdriver_append_message(session, message, size); +} + static int xover_resp_to_fields(struct newsnntp_xover_resp_item * item, struct mailimf_fields ** result); static int nntpdriver_get_envelopes_list(mailsession * session, struct mailmessage_list * env_list) { newsnntp * nntp; int r; struct nntp_session_state_data * data; clist * list; int done; clistiter * cur; uint32_t first_seq; unsigned int i; nntp = get_nntp_session(session); data = get_data(session); if (data->nntp_group_info == NULL) return MAIL_ERROR_BAD_STATE; first_seq = data->nntp_group_info->grp_first; if (carray_count(env_list->msg_tab) > 0) { mailmessage * msg; msg = carray_get(env_list->msg_tab, 0); first_seq = msg->msg_index; } if (carray_count(env_list->msg_tab) > 0) { i = carray_count(env_list->msg_tab) - 1; while (1) { mailmessage * msg; msg = carray_get(env_list->msg_tab, i); if (msg->msg_fields != NULL) { first_seq = msg->msg_index + 1; break; } if (i == 0) break; i --; } } if (first_seq > data->nntp_group_info->grp_last) { list = NULL; } else { done = FALSE; do { r = newsnntp_xover_range(nntp, first_seq, data->nntp_group_info->grp_last, &list); switch (r) { case NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_USERNAME: r = nntpdriver_authenticate_user(session); if (r != MAIL_NO_ERROR) return r; break; case NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_PASSWORD: r = nntpdriver_authenticate_password(session); if (r != MAIL_NO_ERROR) return r; break; case NEWSNNTP_NO_ERROR: done = TRUE; break; default: return nntpdriver_nntp_error_to_mail_error(r); } } while (!done); } #if 0 i = 0; j = 0; if (list != NULL) { for(cur = clist_begin(list) ; cur != NULL ; cur = clist_next(cur)) { struct newsnntp_xover_resp_item * item; struct mailimf_fields * fields; diff --git a/kmicromail/libetpan/generic/nntpdriver_cached.c b/kmicromail/libetpan/generic/nntpdriver_cached.c index 1f8a8af..0343a65 100644 --- a/kmicromail/libetpan/generic/nntpdriver_cached.c +++ b/kmicromail/libetpan/generic/nntpdriver_cached.c @@ -3,255 +3,259 @@ * * Copyright (C) 2001, 2002 - DINH Viet Hoa * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the libEtPan! project nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * $Id$ */ #include "nntpdriver_cached.h" #include "libetpan-config.h" #include <string.h> #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <stdlib.h> #include "mail_cache_db.h" #include "mail.h" #include "mailmessage.h" #include "maildriver_tools.h" #include "nntpdriver.h" #include "maildriver.h" #include "newsnntp.h" #include "generic_cache.h" #include "imfcache.h" #include "maillock.h" #include "nntpdriver_cached_message.h" #include "nntpdriver_tools.h" static int nntpdriver_cached_initialize(mailsession * session); static void nntpdriver_cached_uninitialize(mailsession * session); static int nntpdriver_cached_parameters(mailsession * session, int id, void * value); static int nntpdriver_cached_connect_stream(mailsession * session, mailstream * s); static int nntpdriver_cached_login(mailsession * session, char * userid, char * password); static int nntpdriver_cached_logout(mailsession * session); static int nntpdriver_cached_check_folder(mailsession * session); static int nntpdriver_cached_select_folder(mailsession * session, char * mb); static int nntpdriver_cached_status_folder(mailsession * session, char * mb, uint32_t * result_messages, uint32_t * result_recent, uint32_t * result_unseen); static int nntpdriver_cached_messages_number(mailsession * session, char * mb, uint32_t * result); static int nntpdriver_cached_recent_number(mailsession * session, char * mb, uint32_t * result); static int nntpdriver_cached_unseen_number(mailsession * session, char * mb, uint32_t * result); static int nntpdriver_cached_append_message(mailsession * session, char * message, size_t size); +static int nntpdriver_cached_append_message_flags(mailsession * session, + char * message, size_t size, struct mail_flags * flags); + static int nntpdriver_cached_get_envelopes_list(mailsession * session, struct mailmessage_list * env_list); static int nntpdriver_cached_get_messages_list(mailsession * session, struct mailmessage_list ** result); static int nntpdriver_cached_list_folders(mailsession * session, char * mb, struct mail_list ** result); static int nntpdriver_cached_lsub_folders(mailsession * session, char * mb, struct mail_list ** result); static int nntpdriver_cached_subscribe_folder(mailsession * session, char * mb); static int nntpdriver_cached_unsubscribe_folder(mailsession * session, char * mb); static int nntpdriver_cached_get_message(mailsession * session, uint32_t num, mailmessage ** result); static int nntpdriver_cached_noop(mailsession * session); static int nntpdriver_cached_get_message_by_uid(mailsession * session, const char * uid, mailmessage ** result); static mailsession_driver local_nntp_cached_session_driver = { .sess_name = "nntp-cached", .sess_initialize = nntpdriver_cached_initialize, .sess_uninitialize = nntpdriver_cached_uninitialize, .sess_parameters = nntpdriver_cached_parameters, .sess_connect_stream = nntpdriver_cached_connect_stream, .sess_connect_path = NULL, .sess_starttls = NULL, .sess_login = nntpdriver_cached_login, .sess_logout = nntpdriver_cached_logout, .sess_noop = nntpdriver_cached_noop, .sess_build_folder_name = NULL, .sess_create_folder = NULL, .sess_delete_folder = NULL, .sess_rename_folder = NULL, .sess_check_folder = nntpdriver_cached_check_folder, .sess_examine_folder = NULL, .sess_select_folder = nntpdriver_cached_select_folder, .sess_expunge_folder = NULL, .sess_status_folder = nntpdriver_cached_status_folder, .sess_messages_number = nntpdriver_cached_messages_number, .sess_recent_number = nntpdriver_cached_recent_number, .sess_unseen_number = nntpdriver_cached_unseen_number, .sess_list_folders = nntpdriver_cached_list_folders, .sess_lsub_folders = nntpdriver_cached_lsub_folders, .sess_subscribe_folder = nntpdriver_cached_subscribe_folder, .sess_unsubscribe_folder = nntpdriver_cached_unsubscribe_folder, .sess_append_message = nntpdriver_cached_append_message, + .sess_append_message_flags = nntpdriver_cached_append_message_flags, .sess_copy_message = NULL, .sess_move_message = NULL, .sess_get_messages_list = nntpdriver_cached_get_messages_list, .sess_get_envelopes_list = nntpdriver_cached_get_envelopes_list, .sess_remove_message = NULL, #if 0 .sess_search_messages = maildriver_generic_search_messages, #endif .sess_get_message = nntpdriver_cached_get_message, .sess_get_message_by_uid = nntpdriver_cached_get_message_by_uid, }; mailsession_driver * nntp_cached_session_driver = &local_nntp_cached_session_driver; #define ENV_NAME "env.db" #define FLAGS_NAME "flags.db" static void read_article_seq(mailsession * session, uint32_t * pfirst, uint32_t * plast); static void write_article_seq(mailsession * session, uint32_t first, uint32_t last); static inline struct nntp_cached_session_state_data * get_cached_data(mailsession * session) { return session->sess_data; } static inline mailsession * get_ancestor(mailsession * session) { return get_cached_data(session)->nntp_ancestor; } static inline struct nntp_session_state_data * get_ancestor_data(mailsession * session) { return get_ancestor(session)->sess_data; } static inline newsnntp * get_nntp_session(mailsession * session) { return get_ancestor_data(session)->nntp_session; } static int nntpdriver_cached_initialize(mailsession * session) { struct nntp_cached_session_state_data * data; data = malloc(sizeof(* data)); if (data == NULL) goto err; data->nntp_flags_store = mail_flags_store_new(); if (data->nntp_flags_store == NULL) goto free; data->nntp_ancestor = mailsession_new(nntp_session_driver); if (data->nntp_ancestor == NULL) goto free_store; session->sess_data = data; return MAIL_NO_ERROR; free_store: mail_flags_store_free(data->nntp_flags_store); free: free(data); err: return MAIL_ERROR_MEMORY; } static int nntp_flags_store_process(char * flags_directory, char * group_name, struct mail_flags_store * flags_store) { char filename_flags[PATH_MAX]; struct mail_cache_db * cache_db_flags; MMAPString * mmapstr; unsigned int i; int r; int res; if (carray_count(flags_store->fls_tab) == 0) return MAIL_NO_ERROR; if (group_name == NULL) return MAIL_NO_ERROR; @@ -538,192 +542,198 @@ static int nntpdriver_cached_status_folder(mailsession * session, mail_cache_db_close_unlock(filename_flags, cache_db_flags); err: return res; } static int nntpdriver_cached_messages_number(mailsession * session, char * mb, uint32_t * result) { uint32_t messages; uint32_t recent; uint32_t unseen; int r; r = nntpdriver_cached_status_folder(session, mb, &messages, &recent, &unseen); if (r != MAIL_NO_ERROR) return r; * result = messages; return MAIL_NO_ERROR; } static int nntpdriver_cached_recent_number(mailsession * session, char * mb, uint32_t * result) { uint32_t messages; uint32_t recent; uint32_t unseen; int r; r = nntpdriver_cached_status_folder(session, mb, &messages, &recent, &unseen); if (r != MAIL_NO_ERROR) return r; * result = recent; return MAIL_NO_ERROR; } static int nntpdriver_cached_unseen_number(mailsession * session, char * mb, uint32_t * result) { uint32_t messages; uint32_t recent; uint32_t unseen; int r; r = nntpdriver_cached_status_folder(session, mb, &messages, &recent, &unseen); if (r != MAIL_NO_ERROR) return r; * result = unseen; return MAIL_NO_ERROR; } static int nntpdriver_cached_list_folders(mailsession * session, char * mb, struct mail_list ** result) { return mailsession_list_folders(get_ancestor(session), mb, result); } static int nntpdriver_cached_lsub_folders(mailsession * session, char * mb, struct mail_list ** result) { return mailsession_lsub_folders(get_ancestor(session), mb, result); } static int nntpdriver_cached_subscribe_folder(mailsession * session, char * mb) { return mailsession_subscribe_folder(get_ancestor(session), mb); } static int nntpdriver_cached_unsubscribe_folder(mailsession * session, char * mb) { return mailsession_unsubscribe_folder(get_ancestor(session), mb); } /* messages operations */ static int nntpdriver_cached_append_message(mailsession * session, char * message, size_t size) { return mailsession_append_message(get_ancestor(session), message, size); } +static int nntpdriver_cached_append_message_flags(mailsession * session, + char * message, size_t size, struct mail_flags * flags) +{ + return nntpdriver_cached_append_message(session, message, size); +} + static int get_cached_envelope(struct mail_cache_db * cache_db, MMAPString * mmapstr, mailsession * session, uint32_t num, struct mailimf_fields ** result) { char keyname[PATH_MAX]; int r; struct mailimf_fields * fields; int res; snprintf(keyname, PATH_MAX, "%i-envelope", num); r = generic_cache_fields_read(cache_db, mmapstr, keyname, &fields); if (r != MAIL_NO_ERROR) { res = r; goto err; } * result = fields; return MAIL_NO_ERROR; err: return res; } static int write_cached_envelope(struct mail_cache_db * cache_db, MMAPString * mmapstr, mailsession * session, uint32_t num, struct mailimf_fields * fields) { int r; int res; char keyname[PATH_MAX]; snprintf(keyname, PATH_MAX, "%i-envelope", num); r = generic_cache_fields_write(cache_db, mmapstr, keyname, fields); if (r != MAIL_NO_ERROR) { res = r; goto err; } return MAIL_NO_ERROR; err: return res; } #define SEQ_FILENAME "articles-seq" static void read_article_seq(mailsession * session, uint32_t * pfirst, uint32_t * plast) { FILE * f; struct nntp_session_state_data * ancestor_data; uint32_t first; uint32_t last; char seq_filename[PATH_MAX]; struct nntp_cached_session_state_data * cached_data; int r; first = 0; last = 0; cached_data = get_cached_data(session); ancestor_data = get_ancestor_data(session); if (ancestor_data->nntp_group_name == NULL) return; snprintf(seq_filename, PATH_MAX, "%s/%s/%s", cached_data->nntp_cache_directory, ancestor_data->nntp_group_name, SEQ_FILENAME); f = fopen(seq_filename, "r"); if (f != NULL) { int fd; fd = fileno(f); r = maillock_read_lock(seq_filename, fd); if (r == 0) { MMAPString * mmapstr; size_t cur_token; char buf[sizeof(uint32_t) * 2]; size_t read_size; read_size = fread(buf, 1, sizeof(uint32_t) * 2, f); mmapstr = mmap_string_new_len(buf, read_size); if (mmapstr != NULL) { cur_token = 0; r = mailimf_cache_int_read(mmapstr, &cur_token, &first); r = mailimf_cache_int_read(mmapstr, &cur_token, &last); diff --git a/kmicromail/libetpan/generic/nntpstorage.c b/kmicromail/libetpan/generic/nntpstorage.c index 5ba333b..89974cd 100644 --- a/kmicromail/libetpan/generic/nntpstorage.c +++ b/kmicromail/libetpan/generic/nntpstorage.c @@ -1,170 +1,170 @@ /* * libEtPan! -- a mail stuff library * * Copyright (C) 2001, 2002 - DINH Viet Hoa * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the libEtPan! project nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * $Id$ */ #include "nntpstorage.h" #include <stdlib.h> #include <string.h> #include "maildriver.h" #include "nntpdriver.h" #include "nntpdriver_cached.h" #include "mailstorage_tools.h" #include "mail.h" /* nntp storage */ #define NNTP_DEFAULT_PORT 119 #define NNTPS_DEFAULT_PORT 563 static int nntp_mailstorage_connect(struct mailstorage * storage); static int nntp_mailstorage_get_folder_session(struct mailstorage * storage, char * pathname, mailsession ** result); static void nntp_mailstorage_uninitialize(struct mailstorage * storage); static mailstorage_driver nntp_mailstorage_driver = { .sto_name = "nntp", .sto_connect = nntp_mailstorage_connect, .sto_get_folder_session = nntp_mailstorage_get_folder_session, .sto_uninitialize = nntp_mailstorage_uninitialize, }; int nntp_mailstorage_init(struct mailstorage * storage, char * nn_servername, uint16_t nn_port, char * nn_command, int nn_connection_type, int nn_auth_type, char * nn_login, char * nn_password, int nn_cached, char * nn_cache_directory, char * nn_flags_directory) { struct nntp_mailstorage * nntp_storage; int res; - nntp_storage = malloc(sizeof(struct nntp_mailstorage)); + nntp_storage = malloc(sizeof(* nntp_storage)); if (nntp_storage == NULL) { res = MAIL_ERROR_MEMORY; goto err; } nntp_storage->nntp_servername = strdup(nn_servername); if (nntp_storage->nntp_servername == NULL) { res = MAIL_ERROR_MEMORY; goto free; } nntp_storage->nntp_connection_type = nn_connection_type; if (nn_port == 0) { switch (nn_connection_type) { case CONNECTION_TYPE_PLAIN: case CONNECTION_TYPE_COMMAND: nn_port = NNTP_DEFAULT_PORT; break; case CONNECTION_TYPE_TLS: case CONNECTION_TYPE_COMMAND_TLS: nn_port = NNTPS_DEFAULT_PORT; break; default: res = MAIL_ERROR_INVAL; goto free_servername; } } nntp_storage->nntp_port = nn_port; if (nn_command != NULL) { nntp_storage->nntp_command = strdup(nn_command); if (nntp_storage->nntp_command == NULL) { res = MAIL_ERROR_MEMORY; goto free_servername; } } else nntp_storage->nntp_command = NULL; nntp_storage->nntp_auth_type = nn_auth_type; if (nn_login != NULL) { nntp_storage->nntp_login = strdup(nn_login); if (nntp_storage->nntp_login == NULL) { res = MAIL_ERROR_MEMORY; goto free_command; } } else nntp_storage->nntp_login = NULL; if (nn_password != NULL) { nntp_storage->nntp_password = strdup(nn_password); if (nntp_storage->nntp_password == NULL) { res = MAIL_ERROR_MEMORY; goto free_login; } } else nntp_storage->nntp_password = NULL; nntp_storage->nntp_cached = nn_cached; if (nn_cached && (nn_cache_directory != NULL) && (nn_flags_directory != NULL)) { nntp_storage->nntp_cache_directory = strdup(nn_cache_directory); if (nntp_storage->nntp_cache_directory == NULL) { res = MAIL_ERROR_MEMORY; goto free_password; } nntp_storage->nntp_flags_directory = strdup(nn_flags_directory); if (nntp_storage->nntp_flags_directory == NULL) { res = MAIL_ERROR_MEMORY; goto free_cache_directory; } } else { nntp_storage->nntp_cached = FALSE; nntp_storage->nntp_cache_directory = NULL; nntp_storage->nntp_flags_directory = NULL; } storage->sto_data = nntp_storage; storage->sto_driver = &nntp_mailstorage_driver; return MAIL_NO_ERROR; free_cache_directory: free(nntp_storage->nntp_cache_directory); free_password: free(nntp_storage->nntp_password); free_login: diff --git a/kmicromail/libetpan/generic/pop3driver.c b/kmicromail/libetpan/generic/pop3driver.c index 20b0fc2..375879e 100644 --- a/kmicromail/libetpan/generic/pop3driver.c +++ b/kmicromail/libetpan/generic/pop3driver.c @@ -16,192 +16,193 @@ * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * $Id$ */ #include "pop3driver.h" #include <string.h> #include <stdlib.h> #include "pop3driver_message.h" #include "maildriver_tools.h" #include "pop3driver_tools.h" #include "mailmessage.h" static int pop3driver_initialize(mailsession * session); static void pop3driver_uninitialize(mailsession * session); static int pop3driver_parameters(mailsession * session, int id, void * value); static int pop3driver_connect_stream(mailsession * session, mailstream * s); static int pop3driver_starttls(mailsession * session); static int pop3driver_login(mailsession * session, char * userid, char * password); static int pop3driver_logout(mailsession * session); static int pop3driver_noop(mailsession * session); static int pop3driver_status_folder(mailsession * session, char * mb, uint32_t * result_messages, uint32_t * result_recent, uint32_t * result_unseen); static int pop3driver_messages_number(mailsession * session, char * mb, uint32_t * result); static int pop3driver_remove_message(mailsession * session, uint32_t num); static int pop3driver_get_messages_list(mailsession * session, struct mailmessage_list ** result); static int pop3driver_get_message(mailsession * session, uint32_t num, mailmessage ** result); static mailsession_driver local_pop3_session_driver = { .sess_name = "pop3", .sess_initialize = pop3driver_initialize, .sess_uninitialize = pop3driver_uninitialize, .sess_parameters = pop3driver_parameters, .sess_connect_stream = pop3driver_connect_stream, .sess_connect_path = NULL, .sess_starttls = pop3driver_starttls, .sess_login = pop3driver_login, .sess_logout = pop3driver_logout, .sess_noop = pop3driver_noop, .sess_build_folder_name = NULL, .sess_create_folder = NULL, .sess_delete_folder = NULL, .sess_rename_folder = NULL, .sess_check_folder = NULL, .sess_examine_folder = NULL, .sess_select_folder = NULL, .sess_expunge_folder = NULL, .sess_status_folder = pop3driver_status_folder, .sess_messages_number = pop3driver_messages_number, .sess_recent_number = pop3driver_messages_number, .sess_unseen_number = pop3driver_messages_number, .sess_list_folders = NULL, .sess_lsub_folders = NULL, .sess_subscribe_folder = NULL, .sess_unsubscribe_folder = NULL, .sess_append_message = NULL, + .sess_append_message_flags = NULL, .sess_copy_message = NULL, .sess_move_message = NULL, .sess_get_messages_list = pop3driver_get_messages_list, .sess_get_envelopes_list = maildriver_generic_get_envelopes_list, .sess_remove_message = pop3driver_remove_message, #if 0 .sess_search_messages = maildriver_generic_search_messages, #endif .sess_get_message = pop3driver_get_message, .sess_get_message_by_uid = NULL, }; mailsession_driver * pop3_session_driver = &local_pop3_session_driver; static inline struct pop3_session_state_data * get_data(mailsession * session) { return session->sess_data; } static mailpop3 * get_pop3_session(mailsession * session) { return get_data(session)->pop3_session; } static int pop3driver_initialize(mailsession * session) { struct pop3_session_state_data * data; mailpop3 * pop3; pop3 = mailpop3_new(0, NULL); if (session == NULL) goto err; data = malloc(sizeof(* data)); if (data == NULL) goto free; data->pop3_session = pop3; data->pop3_auth_type = POP3DRIVER_AUTH_TYPE_PLAIN; session->sess_data = data; return MAIL_NO_ERROR; free: mailpop3_free(pop3); err: return MAIL_ERROR_MEMORY; } static void pop3driver_uninitialize(mailsession * session) { struct pop3_session_state_data * data; data = get_data(session); mailpop3_free(data->pop3_session); free(data); session->sess_data = data; } static int pop3driver_connect_stream(mailsession * session, mailstream * s) { int r; r = mailpop3_connect(get_pop3_session(session), s); switch (r) { case MAILPOP3_NO_ERROR: return MAIL_NO_ERROR_NON_AUTHENTICATED; default: return pop3driver_pop3_error_to_mail_error(r); } } static int pop3driver_starttls(mailsession * session) { int r; int fd; mailstream_low * low; mailstream_low * new_low; mailpop3 * pop3; pop3 = get_pop3_session(session); r = mailpop3_stls(pop3); switch (r) { case MAILPOP3_NO_ERROR: break; default: diff --git a/kmicromail/libetpan/generic/pop3driver_cached.c b/kmicromail/libetpan/generic/pop3driver_cached.c index 6f97303..24f624b 100644 --- a/kmicromail/libetpan/generic/pop3driver_cached.c +++ b/kmicromail/libetpan/generic/pop3driver_cached.c @@ -17,237 +17,241 @@ * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * $Id$ */ #include "pop3driver_cached.h" #include "libetpan-config.h" #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <string.h> #include <unistd.h> #include <stdlib.h> #include "mail.h" #include "mail_cache_db.h" #include "maildriver.h" #include "mailmessage.h" #include "pop3driver.h" #include "mailpop3.h" #include "generic_cache.h" #include "imfcache.h" #include "pop3driver_cached_message.h" #include "pop3driver_tools.h" #include "maildriver_tools.h" static int pop3driver_cached_initialize(mailsession * session); static void pop3driver_cached_uninitialize(mailsession * session); static int pop3driver_cached_parameters(mailsession * session, int id, void * value); static int pop3driver_cached_connect_stream(mailsession * session, mailstream * s); static int pop3driver_cached_starttls(mailsession * session); static int pop3driver_cached_login(mailsession * session, char * userid, char * password); static int pop3driver_cached_logout(mailsession * session); static int pop3driver_cached_check_folder(mailsession * session); static int pop3driver_cached_noop(mailsession * session); static int pop3driver_cached_expunge_folder(mailsession * session); static int pop3driver_cached_status_folder(mailsession * session, char * mb, uint32_t * result_messages, uint32_t * result_recent, uint32_t * result_unseen); static int pop3driver_cached_messages_number(mailsession * session, char * mb, uint32_t * result); static int pop3driver_cached_recent_number(mailsession * session, char * mb, uint32_t * result); static int pop3driver_cached_unseen_number(mailsession * session, char * mb, uint32_t * result); static int pop3driver_cached_remove_message(mailsession * session, uint32_t num); static int pop3driver_cached_get_messages_list(mailsession * session, struct mailmessage_list ** result); static int pop3driver_cached_get_envelopes_list(mailsession * session, struct mailmessage_list * env_list); static int pop3driver_cached_get_message(mailsession * session, uint32_t num, mailmessage ** result); +static int pop3driver_cached_get_message_by_uid(mailsession * session, + const char * uid, mailmessage ** result); + static mailsession_driver local_pop3_cached_session_driver = { .sess_name = "pop3-cached", .sess_initialize = pop3driver_cached_initialize, .sess_uninitialize = pop3driver_cached_uninitialize, .sess_parameters = pop3driver_cached_parameters, .sess_connect_stream = pop3driver_cached_connect_stream, .sess_connect_path = NULL, .sess_starttls = pop3driver_cached_starttls, .sess_login = pop3driver_cached_login, .sess_logout = pop3driver_cached_logout, .sess_noop = pop3driver_cached_noop, .sess_build_folder_name = NULL, .sess_create_folder = NULL, .sess_delete_folder = NULL, .sess_rename_folder = NULL, .sess_check_folder = pop3driver_cached_check_folder, .sess_examine_folder = NULL, .sess_select_folder = NULL, .sess_expunge_folder = pop3driver_cached_expunge_folder, .sess_status_folder = pop3driver_cached_status_folder, .sess_messages_number = pop3driver_cached_messages_number, .sess_recent_number = pop3driver_cached_recent_number, .sess_unseen_number = pop3driver_cached_unseen_number, .sess_list_folders = NULL, .sess_lsub_folders = NULL, .sess_subscribe_folder = NULL, .sess_unsubscribe_folder = NULL, .sess_append_message = NULL, + .sess_append_message_flags = NULL, .sess_copy_message = NULL, .sess_move_message = NULL, .sess_get_messages_list = pop3driver_cached_get_messages_list, .sess_get_envelopes_list = pop3driver_cached_get_envelopes_list, .sess_remove_message = pop3driver_cached_remove_message, #if 0 .sess_search_messages = maildriver_generic_search_messages, #endif .sess_get_message = pop3driver_cached_get_message, - .sess_get_message_by_uid = NULL, + .sess_get_message_by_uid = pop3driver_cached_get_message_by_uid, }; mailsession_driver * pop3_cached_session_driver = &local_pop3_cached_session_driver; #define ENV_NAME "env.db" #define FLAGS_NAME "flags.db" static inline struct pop3_cached_session_state_data * get_cached_data(mailsession * session) { return session->sess_data; } static inline mailsession * get_ancestor(mailsession * session) { return get_cached_data(session)->pop3_ancestor; } static inline struct pop3_session_state_data * get_ancestor_data(mailsession * session) { return get_ancestor(session)->sess_data; } static inline mailpop3 * get_pop3_session(mailsession * session) { return get_ancestor_data(session)->pop3_session; } static int pop3driver_cached_initialize(mailsession * session) { struct pop3_cached_session_state_data * data; data = malloc(sizeof(* data)); if (data == NULL) goto err; data->pop3_flags_store = mail_flags_store_new(); if (data->pop3_flags_store == NULL) goto free_data; data->pop3_ancestor = mailsession_new(pop3_session_driver); if (data->pop3_ancestor == NULL) goto free_store; data->pop3_flags_hash = chash_new(128, CHASH_COPYNONE); if (data->pop3_flags_hash == NULL) goto free_session; session->sess_data = data; return MAIL_NO_ERROR; free_session: mailsession_free(data->pop3_ancestor); free_store: mail_flags_store_free(data->pop3_flags_store); free_data: free(data); err: return MAIL_ERROR_MEMORY; } static int pop3_flags_store_process(char * flags_directory, struct mail_flags_store * flags_store) { char filename_flags[PATH_MAX]; struct mail_cache_db * cache_db_flags; MMAPString * mmapstr; unsigned int i; int r; int res; if (carray_count(flags_store->fls_tab) == 0) return MAIL_NO_ERROR; snprintf(filename_flags, PATH_MAX, "%s/%s", flags_directory, FLAGS_NAME); r = mail_cache_db_open_lock(filename_flags, &cache_db_flags); if (r < 0) { res = MAIL_ERROR_FILE; goto err; } mmapstr = mmap_string_new(""); if (mmapstr == NULL) { res = MAIL_ERROR_MEMORY; goto close_db_flags; } for(i = 0 ; i < carray_count(flags_store->fls_tab) ; i ++) { mailmessage * msg; @@ -762,96 +766,134 @@ pop3driver_cached_get_envelopes_list(mailsession * session, mail_cache_db_close_unlock(filename_flags, cache_db_flags); mail_cache_db_close_unlock(filename_env, cache_db_env); r = maildriver_generic_get_envelopes_list(session, env_list); if (r != MAIL_NO_ERROR) { res = r; goto free_mmapstr; } /* add flags */ for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) { mailmessage * msg; msg = carray_get(env_list->msg_tab, i); if (msg->msg_flags == NULL) msg->msg_flags = mail_flags_new_empty(); } r = mail_cache_db_open_lock(filename_env, &cache_db_env); if (r < 0) { res = MAIL_ERROR_MEMORY; goto free_mmapstr; } r = mail_cache_db_open_lock(filename_flags, &cache_db_flags); if (r < 0) { res = MAIL_ERROR_MEMORY; goto close_db_env; } /* must write cache */ for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) { mailmessage * msg; msg = carray_get(env_list->msg_tab, i); if (msg->msg_fields != NULL) { if (!msg->msg_cached) { r = write_cached_envelope(cache_db_env, mmapstr, session, msg->msg_index, msg->msg_fields); } } if (msg->msg_flags != NULL) { r = pop3driver_write_cached_flags(cache_db_flags, mmapstr, msg->msg_uid, msg->msg_flags); } } /* flush cache */ maildriver_cache_clean_up(cache_db_env, cache_db_flags, env_list); mail_cache_db_close_unlock(filename_flags, cache_db_flags); mail_cache_db_close_unlock(filename_env, cache_db_env); mmap_string_free(mmapstr); /* remove cache files */ maildriver_message_cache_clean_up(cached_data->pop3_cache_directory, env_list, get_uid_from_filename); return MAIL_NO_ERROR; close_db_env: mail_cache_db_close_unlock(filename_env, cache_db_env); free_mmapstr: mmap_string_free(mmapstr); err: return res; } static int pop3driver_cached_get_message(mailsession * session, uint32_t num, mailmessage ** result) { mailmessage * msg_info; int r; msg_info = mailmessage_new(); if (msg_info == NULL) return MAIL_ERROR_MEMORY; r = mailmessage_init(msg_info, session, pop3_cached_message_driver, num, 0); if (r != MAIL_NO_ERROR) { mailmessage_free(msg_info); return r; } * result = msg_info; return MAIL_NO_ERROR; } + +static int pop3driver_cached_get_message_by_uid(mailsession * session, + const char * uid, mailmessage ** result) +{ + mailpop3 * pop3; + struct mailpop3_msg_info * msg_info; + int found; + unsigned int i; + + if (uid == NULL) + return MAIL_ERROR_INVAL; + + pop3 = get_pop3_session(session); + + found = 0; + + /* iterate all messages and look for uid */ + for(i = 0 ; i < carray_count(pop3->pop3_msg_tab) ; i++) { + msg_info = carray_get(pop3->pop3_msg_tab, i); + + if (msg_info == NULL) + continue; + + if (msg_info->msg_deleted) + continue; + + /* uid found, stop looking */ + if (strcmp(msg_info->msg_uidl, uid) == 0) { + found = 1; + break; + } + } + + if (!found) + return MAIL_ERROR_MSG_NOT_FOUND; + + return pop3driver_cached_get_message(session, msg_info->msg_index, result); +} diff --git a/kmicromail/libetpan/generic/pop3driver_message.c b/kmicromail/libetpan/generic/pop3driver_message.c index 77bd94c..357bb2e 100644 --- a/kmicromail/libetpan/generic/pop3driver_message.c +++ b/kmicromail/libetpan/generic/pop3driver_message.c @@ -1,159 +1,193 @@ /* * libEtPan! -- a mail stuff library * * Copyright (C) 2001, 2002 - DINH Viet Hoa * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the libEtPan! project nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * $Id$ */ #include "pop3driver_message.h" #include "mailmessage_tools.h" #include "pop3driver_tools.h" #include "pop3driver.h" #include "mailpop3.h" +#include <stdlib.h> +#include <string.h> static int pop3_prefetch(mailmessage * msg_info); static void pop3_prefetch_free(struct generic_message_t * msg); static int pop3_initialize(mailmessage * msg_info); static int pop3_fetch_header(mailmessage * msg_info, char ** result, size_t * result_len); static int pop3_fetch_size(mailmessage * msg_info, size_t * result); static mailmessage_driver local_pop3_message_driver = { .msg_name = "pop3", .msg_initialize = pop3_initialize, .msg_uninitialize = mailmessage_generic_uninitialize, .msg_flush = mailmessage_generic_flush, .msg_check = NULL, .msg_fetch_result_free = mailmessage_generic_fetch_result_free, .msg_fetch = mailmessage_generic_fetch, .msg_fetch_header = pop3_fetch_header, .msg_fetch_body = mailmessage_generic_fetch_body, .msg_fetch_size = pop3_fetch_size, .msg_get_bodystructure = mailmessage_generic_get_bodystructure, .msg_fetch_section = mailmessage_generic_fetch_section, .msg_fetch_section_header = mailmessage_generic_fetch_section_header, .msg_fetch_section_mime = mailmessage_generic_fetch_section_mime, .msg_fetch_section_body = mailmessage_generic_fetch_section_body, .msg_fetch_envelope = mailmessage_generic_fetch_envelope, .msg_get_flags = NULL, }; mailmessage_driver * pop3_message_driver = &local_pop3_message_driver; +static inline struct pop3_session_state_data * +get_data(mailsession * session) +{ + return session->sess_data; +} + + +static mailpop3 * get_pop3_session(mailsession * session) +{ + return get_data(session)->pop3_session; +} + static int pop3_prefetch(mailmessage * msg_info) { char * msg_content; size_t msg_length; struct generic_message_t * msg; int r; r = pop3driver_retr(msg_info->msg_session, msg_info->msg_index, &msg_content, &msg_length); if (r != MAIL_NO_ERROR) return r; msg = msg_info->msg_data; msg->msg_message = msg_content; msg->msg_length = msg_length; return MAIL_NO_ERROR; } static void pop3_prefetch_free(struct generic_message_t * msg) { if (msg->msg_message != NULL) { mmap_string_unref(msg->msg_message); msg->msg_message = NULL; } } static int pop3_initialize(mailmessage * msg_info) { struct generic_message_t * msg; int r; + char * uid; + struct mailpop3_msg_info * info; + mailpop3 * pop3; + + pop3 = get_pop3_session(msg_info->msg_session); + + r = mailpop3_get_msg_info(pop3, msg_info->msg_index, &info); + switch (r) { + case MAILPOP3_NO_ERROR: + break; + default: + return pop3driver_pop3_error_to_mail_error(r); + } + + uid = strdup(info->msg_uidl); + if (uid == NULL) + return MAIL_ERROR_MEMORY; r = mailmessage_generic_initialize(msg_info); - if (r != MAIL_NO_ERROR) + if (r != MAIL_NO_ERROR) { + free(uid); return r; + } msg = msg_info->msg_data; msg->msg_prefetch = pop3_prefetch; msg->msg_prefetch_free = pop3_prefetch_free; + msg_info->msg_uid = uid; return MAIL_NO_ERROR; } static int pop3_fetch_header(mailmessage * msg_info, char ** result, size_t * result_len) { struct generic_message_t * msg; char * headers; size_t headers_length; int r; msg = msg_info->msg_data; if (msg->msg_message != NULL) return mailmessage_generic_fetch_header(msg_info, result, result_len); r = pop3driver_header(msg_info->msg_session, msg_info->msg_index, &headers, &headers_length); if (r != MAIL_NO_ERROR) return r; * result = headers; * result_len = headers_length; return MAIL_NO_ERROR; } static int pop3_fetch_size(mailmessage * msg_info, size_t * result) { return pop3driver_size(msg_info->msg_session, msg_info->msg_index, result); } diff --git a/kmicromail/libetpan/generic/pop3storage.c b/kmicromail/libetpan/generic/pop3storage.c index 8e7a94e..375aeaf 100644 --- a/kmicromail/libetpan/generic/pop3storage.c +++ b/kmicromail/libetpan/generic/pop3storage.c @@ -1,167 +1,167 @@ /* * libEtPan! -- a mail stuff library * * Copyright (C) 2001, 2002 - DINH Viet Hoa * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the libEtPan! project nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * $Id$ */ #include "pop3storage.h" #include <stdlib.h> #include <string.h> #include "mail.h" #include "mailstorage_tools.h" #include "maildriver.h" /* pop3 storage */ #define POP3_DEFAULT_PORT 110 #define POP3S_DEFAULT_PORT 995 static int pop3_mailstorage_connect(struct mailstorage * storage); static int pop3_mailstorage_get_folder_session(struct mailstorage * storage, char * pathname, mailsession ** result); static void pop3_mailstorage_uninitialize(struct mailstorage * storage); static mailstorage_driver pop3_mailstorage_driver = { .sto_name = "pop3", .sto_connect = pop3_mailstorage_connect, .sto_get_folder_session = pop3_mailstorage_get_folder_session, .sto_uninitialize = pop3_mailstorage_uninitialize, }; int pop3_mailstorage_init(struct mailstorage * storage, char * pop3_servername, uint16_t pop3_port, char * pop3_command, int pop3_connection_type, int pop3_auth_type, char * pop3_login, char * pop3_password, int pop3_cached, char * pop3_cache_directory, char * pop3_flags_directory) { struct pop3_mailstorage * pop3_storage; - pop3_storage = malloc(sizeof(struct pop3_mailstorage)); + pop3_storage = malloc(sizeof(* pop3_storage)); if (pop3_storage == NULL) goto err; pop3_storage->pop3_servername = strdup(pop3_servername); if (pop3_storage->pop3_servername == NULL) goto free; pop3_storage->pop3_connection_type = pop3_connection_type; if (pop3_port == 0) { switch (pop3_connection_type) { case CONNECTION_TYPE_PLAIN: case CONNECTION_TYPE_TRY_STARTTLS: case CONNECTION_TYPE_STARTTLS: case CONNECTION_TYPE_COMMAND: case CONNECTION_TYPE_COMMAND_TRY_STARTTLS: case CONNECTION_TYPE_COMMAND_STARTTLS: pop3_port = POP3_DEFAULT_PORT; break; case CONNECTION_TYPE_TLS: case CONNECTION_TYPE_COMMAND_TLS: pop3_port = POP3S_DEFAULT_PORT; break; } } pop3_storage->pop3_port = pop3_port; if (pop3_command != NULL) { pop3_storage->pop3_command = strdup(pop3_command); if (pop3_storage->pop3_command == NULL) goto free_servername; } else pop3_storage->pop3_command = NULL; pop3_storage->pop3_auth_type = pop3_auth_type; if (pop3_login != NULL) { pop3_storage->pop3_login = strdup(pop3_login); if (pop3_storage->pop3_login == NULL) goto free_command; } else pop3_storage->pop3_login = NULL; if (pop3_password != NULL) { pop3_storage->pop3_password = strdup(pop3_password); if (pop3_storage->pop3_password == NULL) goto free_login; } else pop3_storage->pop3_password = NULL; pop3_storage->pop3_cached = pop3_cached; if (pop3_cached && (pop3_cache_directory != NULL) && (pop3_flags_directory != NULL)) { pop3_storage->pop3_cache_directory = strdup(pop3_cache_directory); if (pop3_storage->pop3_cache_directory == NULL) goto free_password; pop3_storage->pop3_flags_directory = strdup(pop3_flags_directory); if (pop3_storage->pop3_flags_directory == NULL) goto free_cache_directory; } else { pop3_storage->pop3_cached = FALSE; pop3_storage->pop3_cache_directory = NULL; pop3_storage->pop3_flags_directory = NULL; } storage->sto_data = pop3_storage; storage->sto_driver = &pop3_mailstorage_driver; return MAIL_NO_ERROR; free_cache_directory: free(pop3_storage->pop3_cache_directory); free_password: if (pop3_storage->pop3_password != NULL) free(pop3_storage->pop3_password); free_login: if (pop3_storage->pop3_login != NULL) free(pop3_storage->pop3_login); free_command: if (pop3_storage->pop3_command != NULL) free(pop3_storage->pop3_command); free_servername: if (pop3_storage->pop3_servername != NULL) free(pop3_storage->pop3_servername); free: free(pop3_storage); err: return MAIL_ERROR_MEMORY; } diff --git a/kmicromail/libetpan/imap/mailimap.c b/kmicromail/libetpan/imap/mailimap.c index c8fbfee..76d9454 100644 --- a/kmicromail/libetpan/imap/mailimap.c +++ b/kmicromail/libetpan/imap/mailimap.c @@ -1814,193 +1814,193 @@ mailimap_uid_store(mailimap * session, return MAILIMAP_ERROR_BAD_STATE; r = send_current_tag(session); if (r != MAILIMAP_NO_ERROR) return r; r = mailimap_uid_store_send(session->imap_stream, set, store_att_flags); if (r != MAILIMAP_NO_ERROR) return r; r = mailimap_crlf_send(session->imap_stream); if (r != MAILIMAP_NO_ERROR) return r; if (mailstream_flush(session->imap_stream) == -1) return MAILIMAP_ERROR_STREAM; if (read_line(session) == NULL) return MAILIMAP_ERROR_STREAM; r = parse_response(session, &response); if (r != MAILIMAP_NO_ERROR) return r; error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type; mailimap_response_free(response); switch (error_code) { case MAILIMAP_RESP_COND_STATE_OK: return MAILIMAP_NO_ERROR; default: return MAILIMAP_ERROR_UID_STORE; } } int mailimap_subscribe(mailimap * session, const char * mb) { struct mailimap_response * response; int r; int error_code; if ((session->imap_state != MAILIMAP_STATE_AUTHENTICATED) && (session->imap_state != MAILIMAP_STATE_SELECTED)) return MAILIMAP_ERROR_BAD_STATE; r = send_current_tag(session); if (r != MAILIMAP_NO_ERROR) return r; r = mailimap_subscribe_send(session->imap_stream, mb); if (r != MAILIMAP_NO_ERROR) return r; r = mailimap_crlf_send(session->imap_stream); if (r != MAILIMAP_NO_ERROR) return r; if (mailstream_flush(session->imap_stream) == -1) return MAILIMAP_ERROR_STREAM; if (read_line(session) == NULL) return MAILIMAP_ERROR_STREAM; r = parse_response(session, &response); if (r != MAILIMAP_NO_ERROR) return r; error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type; mailimap_response_free(response); switch (error_code) { case MAILIMAP_RESP_COND_STATE_OK: return MAILIMAP_NO_ERROR; default: return MAILIMAP_ERROR_SUBSCRIBE; } } int mailimap_unsubscribe(mailimap * session, const char * mb) { struct mailimap_response * response; int r; int error_code; if ((session->imap_state != MAILIMAP_STATE_AUTHENTICATED) && (session->imap_state != MAILIMAP_STATE_SELECTED)) return MAILIMAP_ERROR_BAD_STATE; r = send_current_tag(session); if (r != MAILIMAP_NO_ERROR) return r; - r = mailimap_subscribe_send(session->imap_stream, mb); + r = mailimap_unsubscribe_send(session->imap_stream, mb); if (r != MAILIMAP_NO_ERROR) return r; r = mailimap_crlf_send(session->imap_stream); if (r != MAILIMAP_NO_ERROR) return r; if (mailstream_flush(session->imap_stream) == -1) return MAILIMAP_ERROR_STREAM; if (read_line(session) == NULL) return MAILIMAP_ERROR_STREAM; r = parse_response(session, &response); if (r != MAILIMAP_NO_ERROR) return r; error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type; mailimap_response_free(response); switch (error_code) { case MAILIMAP_RESP_COND_STATE_OK: return MAILIMAP_NO_ERROR; default: return MAILIMAP_ERROR_UNSUBSCRIBE; } } int mailimap_starttls(mailimap * session) { struct mailimap_response * response; int r; int error_code; r = send_current_tag(session); if (r != MAILIMAP_NO_ERROR) return r; r = mailimap_starttls_send(session->imap_stream); if (r != MAILIMAP_NO_ERROR) return r; r = mailimap_crlf_send(session->imap_stream); if (r != MAILIMAP_NO_ERROR) return r; if (mailstream_flush(session->imap_stream) == -1) return MAILIMAP_ERROR_STREAM; if (read_line(session) == NULL) return MAILIMAP_ERROR_STREAM; r = parse_response(session, &response); if (r != MAILIMAP_NO_ERROR) return r; error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type; mailimap_response_free(response); switch (error_code) { case MAILIMAP_RESP_COND_STATE_OK: return MAILIMAP_NO_ERROR; default: return MAILIMAP_ERROR_STARTTLS; } } static char * read_line(mailimap * session) { return mailstream_read_line(session->imap_stream, session->imap_stream_buffer); } static int send_current_tag(mailimap * session) { char tag_str[15]; int r; session->imap_tag ++; snprintf(tag_str, 15, "%i", session->imap_tag); r = mailimap_tag_send(session->imap_stream, tag_str); if (r != MAILIMAP_NO_ERROR) return r; r = mailimap_space_send(session->imap_stream); if (r != MAILIMAP_NO_ERROR) return r; return MAILIMAP_NO_ERROR; diff --git a/kmicromail/libetpan/imap/mailimap_keywords.c b/kmicromail/libetpan/imap/mailimap_keywords.c index b277aed..4ec156e 100644 --- a/kmicromail/libetpan/imap/mailimap_keywords.c +++ b/kmicromail/libetpan/imap/mailimap_keywords.c @@ -1,152 +1,152 @@ /* * libEtPan! -- a mail stuff library * * Copyright (C) 2001, 2002 - DINH Viet Hoa * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the libEtPan! project nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * $Id$ */ #include "mailimap_keywords.h" #include "mailimap_types.h" #include <string.h> #include <stdio.h> #ifndef UNSTRICT_SYNTAX #define UNSTRICT_SYNTAX #endif struct mailimap_token_value { int value; const char * str; }; int mailimap_token_case_insensitive_parse(mailstream * fd, MMAPString * buffer, size_t * index, const char * token) { int len; - int cur_token; + size_t cur_token; int r; cur_token = * index; len = strlen(token); #ifdef UNSTRICT_SYNTAX r = mailimap_space_parse(fd, buffer, &cur_token); if ((r != MAILIMAP_NO_ERROR) && (r != MAILIMAP_ERROR_PARSE)) return r; #endif if (strncasecmp(buffer->str + cur_token, token, len) == 0) { cur_token += len; * index = cur_token; return MAILIMAP_NO_ERROR; } else return MAILIMAP_ERROR_PARSE; } static int is_space_or_tab(char ch) { return (ch == ' ') || (ch == '\t'); } int mailimap_char_parse(mailstream * fd, MMAPString * buffer, size_t * index, char token) { int cur_token; cur_token = * index; if (buffer->str[cur_token] == token) { cur_token ++; * index = cur_token; return MAILIMAP_NO_ERROR; } else return MAILIMAP_ERROR_PARSE; } int mailimap_space_parse(mailstream * fd, MMAPString * buffer, size_t * index) { #ifdef UNSTRICT_SYNTAX /* can accept unstrict syntax */ size_t cur_token; cur_token = * index; while (is_space_or_tab(* (buffer->str + cur_token))) cur_token ++; if (cur_token == * index) return MAILIMAP_ERROR_PARSE; * index = cur_token; return MAILIMAP_NO_ERROR; #else return mailimap_char_parse(fd, buffer, index, ' '); #endif } #define mailimap_get_token_str(index, tab) \ mailimap_get_token_str_size(index, tab, \ sizeof(tab) / sizeof(struct mailimap_token_value)) #define mailimap_get_token_value(fd, buffer, index, tab) \ mailimap_get_token_value_size(fd, buffer, index, tab, \ sizeof(tab) / sizeof(struct mailimap_token_value)) static const char * mailimap_get_token_str_size(int index, struct mailimap_token_value * tab, size_t size) { size_t i; for(i = 0 ; i < size ; i++) if (index == tab[i].value) return tab[i].str; return NULL; } static int mailimap_get_token_value_size(mailstream * fd, MMAPString * buffer, size_t * index, struct mailimap_token_value * tab, diff --git a/kmicromail/libetpan/imf/mailimf.c b/kmicromail/libetpan/imf/mailimf.c index 84d81a1..e0164b8 100644 --- a/kmicromail/libetpan/imf/mailimf.c +++ b/kmicromail/libetpan/imf/mailimf.c @@ -1,147 +1,147 @@ /* * libEtPan! -- a mail stuff library * * Copyright (C) 2001, 2002 - DINH Viet Hoa * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the libEtPan! project nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * $Id$ */ #include "mailimf.h" /* RFC 2822 RFC 2821 ... A message-originating SMTP system SHOULD NOT send a message that already contains a Return-path header. SMTP servers performing a relay function MUST NOT inspect the message data, and especially not to the extent needed to determine if Return-path headers are present. SMTP servers making final delivery MAY remove Return-path headers before adding their own. */ #include <ctype.h> -#include <mmapstring.h> +#include "mmapstring.h" #include <stdlib.h> #include <string.h> #ifndef TRUE #define TRUE 1 #endif #ifndef FALSE #define FALSE 0 #endif static inline int is_dtext(char ch); static int mailimf_quoted_pair_parse(const char * message, size_t length, size_t * index, char * result); static int mailimf_ccontent_parse(const char * message, size_t length, size_t * index); static int mailimf_comment_fws_ccontent_parse(const char * message, size_t length, size_t * index); static inline int mailimf_comment_parse(const char * message, size_t length, size_t * index); static int mailimf_qcontent_parse(const char * message, size_t length, size_t * index, char * ch); static int mailimf_phrase_parse(const char * message, size_t length, size_t * index, char ** result); static int mailimf_unstructured_parse(const char * message, size_t length, size_t * index, char ** result); static int mailimf_ignore_unstructured_parse(const char * message, size_t length, size_t * index); static int mailimf_day_of_week_parse(const char * message, size_t length, size_t * index, int * result); static int mailimf_day_name_parse(const char * message, size_t length, size_t * index, int * result); static int mailimf_date_parse(const char * message, size_t length, size_t * index, int * pday, int * pmonth, int * pyear); static int mailimf_year_parse(const char * message, size_t length, size_t * index, int * result); static int mailimf_month_parse(const char * message, size_t length, size_t * index, int * result); static int mailimf_month_name_parse(const char * message, size_t length, size_t * index, int * result); static int mailimf_day_parse(const char * message, size_t length, size_t * index, int * result); static int mailimf_time_parse(const char * message, size_t length, size_t * index, int * phour, int * pmin, int * psec, int * zone); static int mailimf_time_of_day_parse(const char * message, size_t length, size_t * index, int * phour, int * pmin, int * psec); static int mailimf_hour_parse(const char * message, size_t length, size_t * index, int * result); static int mailimf_minute_parse(const char * message, size_t length, size_t * index, int * result); static int mailimf_second_parse(const char * message, size_t length, size_t * index, int * result); static int mailimf_zone_parse(const char * message, size_t length, size_t * index, int * result); static int mailimf_name_addr_parse(const char * message, size_t length, size_t * index, char ** pdisplay_name, char ** pangle_addr); static int mailimf_angle_addr_parse(const char * message, size_t length, size_t * index, char ** result); diff --git a/kmicromail/libetpan/include/libetpan/libetpan.h b/kmicromail/libetpan/include/libetpan/libetpan.h index 3b4a107..fe5637d 100644 --- a/kmicromail/libetpan/include/libetpan/libetpan.h +++ b/kmicromail/libetpan/include/libetpan/libetpan.h @@ -1,104 +1,116 @@ /* * libEtPan! -- a mail stuff library * * Copyright (C) 2001, 2002 - DINH Viet Hoa * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the libEtPan! project nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * $Id$ */ #ifndef LIBETPAN_H #define LIBETPAN_H #ifdef __cplusplus extern "C" { #endif #include <libetpan/libetpan_version.h> #include <libetpan/maildriver.h> #include <libetpan/mailmessage.h> +#include <libetpan/mailfolder.h> #include <libetpan/mailstorage.h> #include <libetpan/mailthread.h> #include <libetpan/mailsmtp.h> #include <libetpan/charconv.h> /* mbox driver */ #include <libetpan/mboxdriver.h> #include <libetpan/mboxdriver_message.h> #include <libetpan/mboxdriver_cached.h> #include <libetpan/mboxdriver_cached_message.h> #include <libetpan/mboxstorage.h> /* MH driver */ #include <libetpan/mhdriver.h> #include <libetpan/mhdriver_message.h> #include <libetpan/mhdriver_cached.h> #include <libetpan/mhdriver_cached_message.h> #include <libetpan/mhstorage.h> /* IMAP4rev1 driver */ #include <libetpan/imapdriver.h> #include <libetpan/imapdriver_message.h> #include <libetpan/imapdriver_cached.h> #include <libetpan/imapdriver_cached_message.h> #include <libetpan/imapstorage.h> /* POP3 driver */ #include <libetpan/pop3driver.h> #include <libetpan/pop3driver_message.h> #include <libetpan/pop3driver_cached.h> #include <libetpan/pop3driver_cached_message.h> #include <libetpan/pop3storage.h> /* NNTP driver */ #include <libetpan/nntpdriver.h> #include <libetpan/nntpdriver_message.h> #include <libetpan/nntpdriver_cached.h> #include <libetpan/nntpdriver_cached_message.h> #include <libetpan/nntpstorage.h> /* maildir driver */ #include <libetpan/maildirdriver.h> #include <libetpan/maildirdriver_message.h> #include <libetpan/maildirdriver_cached.h> #include <libetpan/maildirdriver_cached_message.h> #include <libetpan/maildirstorage.h> +/* db driver */ +#include <libetpan/dbdriver.h> +#include <libetpan/dbdriver_message.h> +#include <libetpan/dbstorage.h> + /* message which content is given by a MIME structure */ #include <libetpan/mime_message_driver.h> /* message which content given by a string */ #include <libetpan/data_message_driver.h> +/* engine */ +#include <libetpan/mailprivacy.h> +#include <libetpan/mailengine.h> +#include <libetpan/mailprivacy_gnupg.h> +#include <libetpan/mailprivacy_smime.h> + #ifdef __cplusplus } #endif #endif diff --git a/kmicromail/libetpan/include/libetpan/maildir.h b/kmicromail/libetpan/include/libetpan/maildir.h index b782484..268dda1 100644 --- a/kmicromail/libetpan/include/libetpan/maildir.h +++ b/kmicromail/libetpan/include/libetpan/maildir.h @@ -1,60 +1,67 @@ /* * libEtPan! -- a mail stuff library * * Copyright (C) 2001 - 2003 - DINH Viet Hoa * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the libEtPan! project nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * $Id$ */ #ifndef MAILDIR_H #define MAILDIR_H #include <libetpan/maildir_types.h> struct maildir * maildir_new(const char * path); void maildir_free(struct maildir * md); int maildir_update(struct maildir * md); +int maildir_message_add_uid(struct maildir * md, + const char * message, size_t size, + char * uid, size_t max_uid_len); + int maildir_message_add(struct maildir * md, const char * message, size_t size); +int maildir_message_add_file_uid(struct maildir * md, int fd, + char * uid, size_t max_uid_len); + int maildir_message_add_file(struct maildir * md, int fd); char * maildir_message_get(struct maildir * md, const char * uid); int maildir_message_remove(struct maildir * md, const char * uid); int maildir_message_change_flags(struct maildir * md, const char * uid, int new_flags); #endif diff --git a/kmicromail/libetpan/include/libetpan/maildirstorage.h b/kmicromail/libetpan/include/libetpan/maildirstorage.h index d17ea2c..73d7b20 100644 --- a/kmicromail/libetpan/include/libetpan/maildirstorage.h +++ b/kmicromail/libetpan/include/libetpan/maildirstorage.h @@ -1,69 +1,69 @@ /* * libEtPan! -- a mail stuff library * * Copyright (C) 2001, 2002 - DINH Viet Hoa * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the libEtPan! project nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * $Id$ */ #ifndef MAILDIRSTORAGE_H #define MAILDIRSTORAGE_H #include <libetpan/maildirdriver_types.h> #ifdef __cplusplus extern "C" { #endif /* - maildir_mailstorage_init is the constructor for a mbox storage. + maildir_mailstorage_init is the constructor for a maildir storage. @param storage this is the storage to initialize. @param pathname is the directory that contains the mailbox. @param cached if this value is != 0, a persistant cache will be stored on local system. @param cache_directory is the location of the cache @param flags_directory is the location of the flags */ int maildir_mailstorage_init(struct mailstorage * storage, char * md_pathname, int md_cached, char * md_cache_directory, char * md_flags_directory); #ifdef __cplusplus } #endif #endif diff --git a/kmicromail/libetpan/include/libetpan/maildriver.h b/kmicromail/libetpan/include/libetpan/maildriver.h index 7da9aea..c773190 100644 --- a/kmicromail/libetpan/include/libetpan/maildriver.h +++ b/kmicromail/libetpan/include/libetpan/maildriver.h @@ -307,192 +307,195 @@ int mailsession_messages_number(mailsession * session, char * mb, int mailsession_recent_number(mailsession * session, char * mb, uint32_t * result); /* mailsession_unseen_number queries the number of unseen messages in the folder @param session the session @param mb mailbox to query @param result the number of unseen messages is stored in (* result) @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned on error */ int mailsession_unseen_number(mailsession * session, char * mb, uint32_t * result); /* NOTE: driver's specific should be used mailsession_list_folders returns the list of all sub-mailboxes of the given mailbox @param session the session @param mb the mailbox @param result list of mailboxes if stored in (* result), this structure have to be freed with mail_list_free() @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned on error */ int mailsession_list_folders(mailsession * session, char * mb, struct mail_list ** result); /* NOTE: driver's specific should be used mailsession_lsub_folders returns the list of subscribed sub-mailboxes of the given mailbox @param session the session @param mb the mailbox @param result list of mailboxes if stored in (* result), this structure have to be freed with mail_list_free() @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned on error */ int mailsession_lsub_folders(mailsession * session, char * mb, struct mail_list ** result); /* NOTE: driver's specific should be used mailsession_subscribe_folder subscribes to the given mailbox @param session the session @param mb the mailbox @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned on error */ int mailsession_subscribe_folder(mailsession * session, char * mb); /* NOTE: driver's specific should be used mailsession_unsubscribe_folder unsubscribes to the given mailbox @param session the session @param mb the mailbox @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned on error */ int mailsession_unsubscribe_folder(mailsession * session, char * mb); /* mailsession_append_message adds a RFC 2822 message to the current given mailbox @param session the session @param message is a string that contains the RFC 2822 message @param size this is the size of the message @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned on error */ int mailsession_append_message(mailsession * session, char * message, size_t size); +int mailsession_append_message_flags(mailsession * session, + char * message, size_t size, struct mail_flags * flags); + /* NOTE: some drivers does not implement this mailsession_copy_message copies a message whose number is given to a given mailbox. The mailbox must be accessible from the same session. @param session the session @param num the message number @param mb the destination mailbox @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned on error */ int mailsession_copy_message(mailsession * session, uint32_t num, char * mb); /* NOTE: some drivers does not implement this mailsession_move_message copies a message whose number is given to a given mailbox. The mailbox must be accessible from the same session. @param session the session @param num the message number @param mb the destination mailbox @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned on error */ int mailsession_move_message(mailsession * session, uint32_t num, char * mb); /* mailsession_get_messages_list returns the list of message numbers of the current mailbox. @param session the session @param result the list of message numbers will be stored in (* result), this structure have to be freed with mailmessage_list_free() @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned on error */ int mailsession_get_messages_list(mailsession * session, struct mailmessage_list ** result); /* mailsession_get_envelopes_list fills the parsed fields in the mailmessage structures of the mailmessage_list. @param session the session @param result this is the list of mailmessage structures @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned on error */ int mailsession_get_envelopes_list(mailsession * session, struct mailmessage_list * result); /* NOTE: some drivers does not implement this mailsession_remove_message removes the given message from the mailbox. The message is permanently deleted. @param session the session @param num is the message number @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned on error */ int mailsession_remove_message(mailsession * session, uint32_t num); /* NOTE: this function is not implemented in most drivers mailsession_search_message returns a list of message numbers that corresponds to the given criteria. @param session the session @param charset is the charset to use (it can be NULL) @param key is the list of criteria @param result the search result is stored in (* result), this structure have to be freed with mail_search_result_free() @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned on error */ #if 0 diff --git a/kmicromail/libetpan/include/libetpan/maildriver_types.h b/kmicromail/libetpan/include/libetpan/maildriver_types.h index 3ff9440..9eab4d6 100644 --- a/kmicromail/libetpan/include/libetpan/maildriver_types.h +++ b/kmicromail/libetpan/include/libetpan/maildriver_types.h @@ -414,192 +414,194 @@ void mail_search_result_free(struct mail_search_result * search_result); mailmessage structures of the mailmessage_list. - remove_message() removes the given message from the mailbox. The message is permanently deleted. - search_message() returns a list of message numbers that corresponds to the given criteria. - get_message returns a mailmessage structure that corresponds to the given message number. - get_message_by_uid returns a mailmessage structure that corresponds to the given message unique identifier. * mandatory functions are the following : - connect_stream() of connect_path() - logout() - get_messages_list() - get_envelopes_list() * we advise you to implement these functions : - select_folder() (in case a session can access several folders) - noop() (to check if the server is responding) - check_folder() (to make a checkpoint of the session) - status_folder(), messages_number(), recent_number(), unseen_number() (to get stat of the folder) - append_message() (but can't be done in the case of POP3 at least) - login() in a case of an authenticated driver. - starttls() in a case of a stream driver, if the procotol supports STARTTLS. - get_message_by_uid() so that the application can remember the message by UID and build its own list of messages. * drivers' specific : Everything that is specific to the driver will be implemented in this function : - parameters() */ struct mailsession_driver { char * sess_name; int (* sess_initialize)(mailsession * session); void (* sess_uninitialize)(mailsession * session); int (* sess_parameters)(mailsession * session, int id, void * value); int (* sess_connect_stream)(mailsession * session, mailstream * s); int (* sess_connect_path)(mailsession * session, char * path); int (* sess_starttls)(mailsession * session); int (* sess_login)(mailsession * session, char * userid, char * password); int (* sess_logout)(mailsession * session); int (* sess_noop)(mailsession * session); /* folders operations */ int (* sess_build_folder_name)(mailsession * session, char * mb, char * name, char ** result); int (* sess_create_folder)(mailsession * session, char * mb); int (* sess_delete_folder)(mailsession * session, char * mb); int (* sess_rename_folder)(mailsession * session, char * mb, char * new_name); int (* sess_check_folder)(mailsession * session); int (* sess_examine_folder)(mailsession * session, char * mb); int (* sess_select_folder)(mailsession * session, char * mb); int (* sess_expunge_folder)(mailsession * session); int (* sess_status_folder)(mailsession * session, char * mb, uint32_t * result_num, uint32_t * result_recent, uint32_t * result_unseen); int (* sess_messages_number)(mailsession * session, char * mb, uint32_t * result); int (* sess_recent_number)(mailsession * session, char * mb, uint32_t * result); int (* sess_unseen_number)(mailsession * session, char * mb, uint32_t * result); int (* sess_list_folders)(mailsession * session, char * mb, struct mail_list ** result); int (* sess_lsub_folders)(mailsession * session, char * mb, struct mail_list ** result); int (* sess_subscribe_folder)(mailsession * session, char * mb); int (* sess_unsubscribe_folder)(mailsession * session, char * mb); /* messages operations */ int (* sess_append_message)(mailsession * session, char * message, size_t size); + int (* sess_append_message_flags)(mailsession * session, + char * message, size_t size, struct mail_flags * flags); int (* sess_copy_message)(mailsession * session, uint32_t num, char * mb); int (* sess_move_message)(mailsession * session, uint32_t num, char * mb); int (* sess_get_message)(mailsession * session, uint32_t num, mailmessage ** result); int (* sess_get_message_by_uid)(mailsession * session, const char * uid, mailmessage ** result); int (* sess_get_messages_list)(mailsession * session, struct mailmessage_list ** result); int (* sess_get_envelopes_list)(mailsession * session, struct mailmessage_list * env_list); int (* sess_remove_message)(mailsession * session, uint32_t num); #if 0 int (* sess_search_messages)(mailsession * session, char * charset, struct mail_search_key * key, struct mail_search_result ** result); #endif }; /* session is the data structure for a mail session. - data is the internal data structure used by the driver It is called when initializing the mailsession structure. - driver is the driver used for the session */ struct mailsession { void * sess_data; mailsession_driver * sess_driver; }; /* mailmessage_driver is the driver structure to get information from messages. - name is the name of the driver - initialize() is the function that will initializes a data structure specific to the driver, it returns a value that will be stored in the field data of the mailsession. The field data of the session is the state of the session, the internal data structure used by the driver. It is called when initializing the mailmessage structure with mailmessage_init(). - uninitialize() frees the structure created with initialize(). It will be called by mailmessage_free(). - flush() will free from memory all temporary structures of the message (for example, the MIME structure of the message). - fetch_result_free() will free all strings resulted by fetch() or any fetch_xxx() functions that returns a string. - fetch() returns the content of the message (headers and text). - fetch_header() returns the content of the headers. - fetch_body() returns the message text (message content without headers) - fetch_size() returns the size of the message content. - get_bodystructure() returns the MIME structure of the message. - fetch_section() returns the content of a given MIME part - fetch_section_header() returns the header of the message contained by the given MIME part. - fetch_section_mime() returns the MIME headers of the given MIME part. - fetch_section_body() returns the text (if this is a message, this is the message content without headers) of the given MIME part. - fetch_envelope() returns a mailimf_fields structure, with a list of fields chosen by the driver. - get_flags() returns a the flags related to the message. When you want to get flags of a message, you have to make sure to call get_flags() at least once before using directly message->flags. */ #define LIBETPAN_MAIL_MESSAGE_CHECK struct mailmessage_driver { char * msg_name; diff --git a/kmicromail/libetpan/include/libetpan/mailfolder.h b/kmicromail/libetpan/include/libetpan/mailfolder.h index 3ecad23..ff53470 100644 --- a/kmicromail/libetpan/include/libetpan/mailfolder.h +++ b/kmicromail/libetpan/include/libetpan/mailfolder.h @@ -1,32 +1,35 @@ #ifndef MAILFOLDER_H #define MAILFOLDER_H #include "mailstorage_types.h" int mailfolder_noop(struct mailfolder * folder); int mailfolder_check(struct mailfolder * folder); int mailfolder_expunge(struct mailfolder * folder); int mailfolder_status(struct mailfolder * folder, uint32_t * result_messages, uint32_t * result_recent, uint32_t * result_unseen); int mailfolder_append_message(struct mailfolder * folder, char * message, size_t size); +int mailfolder_append_message_flags(struct mailfolder * folder, + char * message, size_t size, struct mail_flags * flags); + int mailfolder_get_messages_list(struct mailfolder * folder, struct mailmessage_list ** result); int mailfolder_get_envelopes_list(struct mailfolder * folder, struct mailmessage_list * result); int mailfolder_get_message(struct mailfolder * folder, uint32_t num, mailmessage ** result); int mailfolder_get_message_by_uid(struct mailfolder * folder, const char * uid, mailmessage ** result); #endif diff --git a/kmicromail/libetpan/include/libetpan/mailmbox.h b/kmicromail/libetpan/include/libetpan/mailmbox.h index 8be086c..0427f1f 100644 --- a/kmicromail/libetpan/include/libetpan/mailmbox.h +++ b/kmicromail/libetpan/include/libetpan/mailmbox.h @@ -1,140 +1,144 @@ /* * libEtPan! -- a mail stuff library * * Copyright (C) 2001, 2002 - DINH Viet Hoa * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the libEtPan! project nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * $Id$ */ #ifndef MAILMBOX_H #define MAILMBOX_H #ifdef __cplusplus extern "C" { #endif #include <libetpan/mailmbox_types.h> int mailmbox_append_message_list(struct mailmbox_folder * folder, carray * append_tab); int mailmbox_append_message(struct mailmbox_folder * folder, const char * data, size_t len); +int +mailmbox_append_message_uid(struct mailmbox_folder * folder, + const char * data, size_t len, unsigned int * puid); + int mailmbox_fetch_msg(struct mailmbox_folder * folder, uint32_t num, char ** result, size_t * result_len); int mailmbox_fetch_msg_headers(struct mailmbox_folder * folder, uint32_t num, char ** result, size_t * result_len); void mailmbox_fetch_result_free(char * msg); int mailmbox_copy_msg_list(struct mailmbox_folder * dest_folder, struct mailmbox_folder * src_folder, carray * tab); int mailmbox_copy_msg(struct mailmbox_folder * dest_folder, struct mailmbox_folder * src_folder, uint32_t uid); int mailmbox_expunge(struct mailmbox_folder * folder); int mailmbox_delete_msg(struct mailmbox_folder * folder, uint32_t uid); int mailmbox_init(const char * filename, int force_readonly, int force_no_uid, uint32_t default_written_uid, struct mailmbox_folder ** result_folder); void mailmbox_done(struct mailmbox_folder * folder); /* low-level access primitives */ int mailmbox_write_lock(struct mailmbox_folder * folder); int mailmbox_write_unlock(struct mailmbox_folder * folder); int mailmbox_read_lock(struct mailmbox_folder * folder); int mailmbox_read_unlock(struct mailmbox_folder * folder); /* memory map */ int mailmbox_map(struct mailmbox_folder * folder); void mailmbox_unmap(struct mailmbox_folder * folder); void mailmbox_sync(struct mailmbox_folder * folder); /* open & close file */ int mailmbox_open(struct mailmbox_folder * folder); void mailmbox_close(struct mailmbox_folder * folder); /* validate cache */ int mailmbox_validate_write_lock(struct mailmbox_folder * folder); int mailmbox_validate_read_lock(struct mailmbox_folder * folder); /* fetch message */ int mailmbox_fetch_msg_no_lock(struct mailmbox_folder * folder, uint32_t num, char ** result, size_t * result_len); int mailmbox_fetch_msg_headers_no_lock(struct mailmbox_folder * folder, uint32_t num, char ** result, size_t * result_len); /* append message */ int mailmbox_append_message_list_no_lock(struct mailmbox_folder * folder, carray * append_tab); int mailmbox_expunge_no_lock(struct mailmbox_folder * folder); #ifdef __cplusplus } #endif #endif diff --git a/kmicromail/libetpan/include/libetpan/mailmbox_types.h b/kmicromail/libetpan/include/libetpan/mailmbox_types.h index dd6758c..bd6ee30 100644 --- a/kmicromail/libetpan/include/libetpan/mailmbox_types.h +++ b/kmicromail/libetpan/include/libetpan/mailmbox_types.h @@ -35,108 +35,109 @@ #ifndef MAILMBOX_TYPES_H #define MAILMBOX_TYPES_H #ifdef __cplusplus extern "C" { #endif #include <sys/types.h> #include <libetpan/libetpan-config.h> #include <libetpan/mailimf.h> #include <libetpan/carray.h> #include <libetpan/chash.h> enum { MAILMBOX_NO_ERROR = 0, MAILMBOX_ERROR_PARSE, MAILMBOX_ERROR_INVAL, MAILMBOX_ERROR_FILE_NOT_FOUND, MAILMBOX_ERROR_MEMORY, MAILMBOX_ERROR_TEMPORARY_FILE, MAILMBOX_ERROR_FILE, MAILMBOX_ERROR_MSG_NOT_FOUND, MAILMBOX_ERROR_READONLY, }; struct mailmbox_folder { char mb_filename[PATH_MAX]; time_t mb_mtime; int mb_fd; int mb_read_only; int mb_no_uid; int mb_changed; unsigned int mb_deleted_count; char * mb_mapping; size_t mb_mapping_size; uint32_t mb_written_uid; uint32_t mb_max_uid; chash * mb_hash; carray * mb_tab; }; struct mailmbox_folder * mailmbox_folder_new(const char * mb_filename); void mailmbox_folder_free(struct mailmbox_folder * folder); struct mailmbox_msg_info { unsigned int msg_index; uint32_t msg_uid; int msg_written_uid; int msg_deleted; size_t msg_start; size_t msg_start_len; size_t msg_headers; size_t msg_headers_len; size_t msg_body; size_t msg_body_len; size_t msg_size; size_t msg_padding; }; int mailmbox_msg_info_update(struct mailmbox_folder * folder, size_t msg_start, size_t msg_start_len, size_t msg_headers, size_t msg_headers_len, size_t msg_body, size_t msg_body_len, size_t msg_size, size_t msg_padding, uint32_t msg_uid); struct mailmbox_msg_info * mailmbox_msg_info_new(size_t msg_start, size_t msg_start_len, size_t msg_headers, size_t msg_headers_len, size_t msg_body, size_t msg_body_len, size_t msg_size, size_t msg_padding, uint32_t msg_uid); void mailmbox_msg_info_free(struct mailmbox_msg_info * info); struct mailmbox_append_info { const char * ai_message; size_t ai_size; + unsigned int ai_uid; }; struct mailmbox_append_info * mailmbox_append_info_new(const char * ai_message, size_t ai_size); void mailmbox_append_info_free(struct mailmbox_append_info * info); #ifdef __cplusplus } #endif #endif diff --git a/kmicromail/libetpan/include/libetpan/mailmh.h b/kmicromail/libetpan/include/libetpan/mailmh.h index 40432cb..00199b8 100644 --- a/kmicromail/libetpan/include/libetpan/mailmh.h +++ b/kmicromail/libetpan/include/libetpan/mailmh.h @@ -26,118 +26,125 @@ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * $Id$ */ #ifndef MAILMH_H #define MAILMH_H #ifdef __cplusplus extern "C" { #endif #include <sys/types.h> #include <inttypes.h> #include <libetpan/carray.h> #include <libetpan/cinthash.h> #include <libetpan/chash.h> enum { MAILMH_NO_ERROR = 0, MAILMH_ERROR_FOLDER, MAILMH_ERROR_MEMORY, MAILMH_ERROR_FILE, MAILMH_ERROR_COULD_NOT_ALLOC_MSG, MAILMH_ERROR_RENAME, MAILMH_ERROR_MSG_NOT_FOUND, }; struct mailmh { struct mailmh_folder * mh_main; }; struct mailmh_msg_info { unsigned int msg_array_index; uint32_t msg_index; size_t msg_size; time_t msg_mtime; }; struct mailmh_folder { char * fl_filename; unsigned int fl_array_index; char * fl_name; time_t fl_mtime; struct mailmh_folder * fl_parent; uint32_t fl_max_index; carray * fl_msgs_tab; #if 0 cinthash_t * fl_msgs_hash; #endif chash * fl_msgs_hash; carray * fl_subfolders_tab; chash * fl_subfolders_hash; }; struct mailmh * mailmh_new(const char * foldername); void mailmh_free(struct mailmh * f); struct mailmh_msg_info * mailmh_msg_info_new(uint32_t index, size_t size, time_t mtime); void mailmh_msg_info_free(struct mailmh_msg_info * msg_info); struct mailmh_folder * mailmh_folder_new(struct mailmh_folder * parent, const char * name); void mailmh_folder_free(struct mailmh_folder * folder); int mailmh_folder_add_subfolder(struct mailmh_folder * parent, const char * name); struct mailmh_folder * mailmh_folder_find(struct mailmh_folder * root, const char * filename); int mailmh_folder_remove_subfolder(struct mailmh_folder * folder); int mailmh_folder_rename_subfolder(struct mailmh_folder * src_folder, struct mailmh_folder * dst_folder, const char * new_name); int mailmh_folder_get_message_filename(struct mailmh_folder * folder, uint32_t index, char ** result); int mailmh_folder_get_message_fd(struct mailmh_folder * folder, uint32_t index, int flags, int * result); int mailmh_folder_get_message_size(struct mailmh_folder * folder, uint32_t index, size_t * result); +int mailmh_folder_add_message_uid(struct mailmh_folder * folder, + const char * message, size_t size, + uint32_t * pindex); + int mailmh_folder_add_message(struct mailmh_folder * folder, const char * message, size_t size); +int mailmh_folder_add_message_file_uid(struct mailmh_folder * folder, + int fd, uint32_t * pindex); + int mailmh_folder_add_message_file(struct mailmh_folder * folder, int fd); int mailmh_folder_remove_message(struct mailmh_folder * folder, uint32_t index); int mailmh_folder_move_message(struct mailmh_folder * dest_folder, struct mailmh_folder * src_folder, uint32_t index); int mailmh_folder_update(struct mailmh_folder * folder); unsigned int mailmh_folder_get_message_number(struct mailmh_folder * folder); #ifdef __cplusplus } #endif #endif diff --git a/kmicromail/libetpan/include/libetpan/mailstorage.h b/kmicromail/libetpan/include/libetpan/mailstorage.h index d56aef1..4c57883 100644 --- a/kmicromail/libetpan/include/libetpan/mailstorage.h +++ b/kmicromail/libetpan/include/libetpan/mailstorage.h @@ -1,98 +1,99 @@ /* * libEtPan! -- a mail stuff library * * Copyright (C) 2001, 2002 - DINH Viet Hoa * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the libEtPan! project nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * $Id$ */ #ifndef MAIL_STORAGE_H #define MAIL_STORAGE_H #include <libetpan/maildriver_types.h> #include <libetpan/mailstorage_types.h> #ifdef __cplusplus extern "C" { #endif /* storage */ /* mailstorage_new This function creates an empty storage. This storage have to be initialized. The "driver" and "data" fields should be initialized. @param id is the name of the storage. It can be NULL. The given parameter is no more needed when the creation is finished. The given string is duplicated. @return The mail storage is returned. */ struct mailstorage * mailstorage_new(char * sto_id); void mailstorage_free(struct mailstorage * storage); /* session will be initialized on success. */ int mailstorage_connect(struct mailstorage * storage); void mailstorage_disconnect(struct mailstorage * storage); +int mailstorage_noop(struct mailstorage * storage); + /* folder */ struct mailfolder * mailfolder_new(struct mailstorage * fld_storage, char * fld_pathname, char * fld_virtual_name); void mailfolder_free(struct mailfolder * folder); int mailfolder_add_child(struct mailfolder * parent, struct mailfolder * child); int mailfolder_detach_parent(struct mailfolder * folder); int mailfolder_connect(struct mailfolder * folder); void mailfolder_disconnect(struct mailfolder * folder); - #ifdef __cplusplus } #endif #endif diff --git a/kmicromail/libetpan/maildir/maildir.c b/kmicromail/libetpan/maildir/maildir.c index 320ef81..0e038b1 100644 --- a/kmicromail/libetpan/maildir/maildir.c +++ b/kmicromail/libetpan/maildir/maildir.c @@ -337,321 +337,340 @@ static int add_directory(struct maildir * md, char * path, int is_new) } closedir(d); return MAILDIR_NO_ERROR; err: return res; } int maildir_update(struct maildir * md) { struct stat stat_info; char path_new[PATH_MAX]; char path_cur[PATH_MAX]; int r; int res; snprintf(path_new, sizeof(path_new), "%s/new", md->mdir_path); snprintf(path_cur, sizeof(path_cur), "%s/cur", md->mdir_path); /* did new/ changed ? */ r = stat(path_new, &stat_info); if (r < 0) { res = MAILDIR_ERROR_DIRECTORY; goto free; } if (md->mdir_mtime_new != stat_info.st_mtime) { md->mdir_mtime_new = stat_info.st_mtime; maildir_flush(md, 1); /* messages in new */ r = add_directory(md, path_new, 1); if (r != MAILDIR_NO_ERROR) { res = r; goto free; } } /* did cur/ changed ? */ r = stat(path_cur, &stat_info); if (r < 0) { res = MAILDIR_ERROR_DIRECTORY; goto free; } if (md->mdir_mtime_cur != stat_info.st_mtime) { md->mdir_mtime_cur = stat_info.st_mtime; maildir_flush(md, 0); /* messages in cur */ r = add_directory(md, path_cur, 0); if (r != MAILDIR_NO_ERROR) { res = r; goto free; } } return MAILDIR_NO_ERROR; free: maildir_flush(md, 0); maildir_flush(md, 1); md->mdir_mtime_cur = (time_t) -1; md->mdir_mtime_new = (time_t) -1; return res; } #ifndef LIBETPAN_SYSTEM_BASENAME static char * libetpan_basename(char * filename) { char * next; char * p; p = filename; next = strchr(p, '/'); while (next != NULL) { p = next; next = strchr(p + 1, '/'); } if (p == filename) return filename; else return p + 1; } #else #define libetpan_basename(a) basename(a) #endif -int maildir_message_add(struct maildir * md, - const char * message, size_t size) +int maildir_message_add_uid(struct maildir * md, + const char * message, size_t size, + char * uid, size_t max_uid_len) { char path_new[PATH_MAX]; char tmpname[PATH_MAX]; int fd; int r; char * mapping; char * delivery_tmp_name; char * delivery_tmp_basename; char delivery_new_name[PATH_MAX]; char * delivery_new_basename; int res; struct stat stat_info; r = maildir_update(md); if (r != MAILDIR_NO_ERROR) { res = r; goto err; } /* write to tmp/ with a classic temporary file */ - snprintf(tmpname, sizeof(tmpname), "%s/tmp/etpan-maildir-XXXXXX", md->mdir_path); + snprintf(tmpname, sizeof(tmpname), "%s/tmp/etpan-maildir-XXXXXX", + md->mdir_path); fd = mkstemp(tmpname); if (fd < 0) { res = MAILDIR_ERROR_FILE; goto err; } r = ftruncate(fd, size); if (r < 0) { res = MAILDIR_ERROR_FILE; goto close; } mapping = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (mapping == MAP_FAILED) { res = MAILDIR_ERROR_FILE; goto close; } memcpy(mapping, message, size); msync(mapping, size, MS_SYNC); munmap(mapping, size); close(fd); /* write to tmp/ with maildir standard name */ delivery_tmp_name = maildir_get_new_message_filename(md, tmpname); if (delivery_tmp_name == NULL) { res = MAILDIR_ERROR_FILE; goto unlink; } /* write to new/ with maildir standard name */ strncpy(tmpname, delivery_tmp_name, sizeof(tmpname)); tmpname[sizeof(tmpname) - 1] = '\0'; delivery_tmp_basename = libetpan_basename(tmpname); snprintf(delivery_new_name, sizeof(delivery_new_name), "%s/new/%s", md->mdir_path, delivery_tmp_basename); r = link(delivery_tmp_name, delivery_new_name); if (r < 0) { res = MAILDIR_ERROR_FILE; goto unlink_tmp; } snprintf(path_new, sizeof(path_new), "%s/new", md->mdir_path); r = stat(path_new, &stat_info); if (r < 0) { unlink(delivery_new_name); res = MAILDIR_ERROR_FILE; goto unlink_tmp; } md->mdir_mtime_new = stat_info.st_mtime; delivery_new_basename = libetpan_basename(delivery_new_name); r = add_message(md, delivery_new_basename, 1); if (r != MAILDIR_NO_ERROR) { unlink(delivery_new_name); res = MAILDIR_ERROR_FILE; goto unlink_tmp; } + if (uid != NULL) + strncpy(uid, delivery_new_basename, max_uid_len); + unlink(delivery_tmp_name); free(delivery_tmp_name); return MAILDIR_NO_ERROR; unlink_tmp: unlink(delivery_tmp_name); free(delivery_tmp_name); goto err; close: close(fd); unlink: unlink(tmpname); err: return res; } -int maildir_message_add_file(struct maildir * md, int fd) +int maildir_message_add(struct maildir * md, + const char * message, size_t size) +{ + return maildir_message_add_uid(md, message, size, + NULL, 0); +} + +int maildir_message_add_file_uid(struct maildir * md, int fd, + char * uid, size_t max_uid_len) { char * message; struct stat buf; int r; if (fstat(fd, &buf) == -1) return MAILDIR_ERROR_FILE; message = mmap(NULL, buf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); if (message == MAP_FAILED) return MAILDIR_ERROR_FILE; - r = maildir_message_add(md, message, buf.st_size); + r = maildir_message_add_uid(md, message, buf.st_size, uid, max_uid_len); munmap(message, buf.st_size); return r; } +int maildir_message_add_file(struct maildir * md, int fd) +{ + return maildir_message_add_file_uid(md, fd, + NULL, 0); +} + char * maildir_message_get(struct maildir * md, const char * uid) { chashdatum key; chashdatum value; char filename[PATH_MAX]; char * dup_filename; struct maildir_msg * msg; char * dir; int r; key.data = (void *) uid; key.len = strlen(uid); r = chash_get(md->mdir_msg_hash, &key, &value); if (r < 0) return NULL; msg = value.data; if ((msg->msg_flags & MAILDIR_FLAG_NEW) != 0) dir = "new"; else dir = "cur"; snprintf(filename, sizeof(filename), "%s/%s/%s", md->mdir_path, dir, msg->msg_filename); dup_filename = strdup(filename); if (dup_filename == NULL) return NULL; return dup_filename; } int maildir_message_remove(struct maildir * md, const char * uid) { chashdatum key; chashdatum value; char filename[PATH_MAX]; struct maildir_msg * msg; char * dir; int r; int res; key.data = (void *) uid; key.len = strlen(uid); r = chash_get(md->mdir_msg_hash, &key, &value); if (r < 0) { res = MAILDIR_ERROR_NOT_FOUND; goto err; } msg = value.data; if ((msg->msg_flags & MAILDIR_FLAG_NEW) != 0) dir = "new"; else dir = "cur"; snprintf(filename, sizeof(filename), "%s/%s/%s", md->mdir_path, dir, msg->msg_filename); r = unlink(filename); if (r < 0) { res = MAILDIR_ERROR_FILE; goto err; } return MAILDIR_NO_ERROR; err: return res; } int maildir_message_change_flags(struct maildir * md, const char * uid, int new_flags) { chashdatum key; chashdatum value; char filename[PATH_MAX]; struct maildir_msg * msg; char * dir; int r; char new_filename[PATH_MAX]; char flag_str[5]; size_t i; int res; key.data = (void *) uid; key.len = strlen(uid); r = chash_get(md->mdir_msg_hash, &key, &value); if (r < 0) { res = MAILDIR_ERROR_NOT_FOUND; goto err; } msg = value.data; if ((msg->msg_flags & MAILDIR_FLAG_NEW) != 0) dir = "new"; diff --git a/kmicromail/libetpan/maildir/maildir.h b/kmicromail/libetpan/maildir/maildir.h index b782484..268dda1 100644 --- a/kmicromail/libetpan/maildir/maildir.h +++ b/kmicromail/libetpan/maildir/maildir.h @@ -1,60 +1,67 @@ /* * libEtPan! -- a mail stuff library * * Copyright (C) 2001 - 2003 - DINH Viet Hoa * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the libEtPan! project nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * $Id$ */ #ifndef MAILDIR_H #define MAILDIR_H #include <libetpan/maildir_types.h> struct maildir * maildir_new(const char * path); void maildir_free(struct maildir * md); int maildir_update(struct maildir * md); +int maildir_message_add_uid(struct maildir * md, + const char * message, size_t size, + char * uid, size_t max_uid_len); + int maildir_message_add(struct maildir * md, const char * message, size_t size); +int maildir_message_add_file_uid(struct maildir * md, int fd, + char * uid, size_t max_uid_len); + int maildir_message_add_file(struct maildir * md, int fd); char * maildir_message_get(struct maildir * md, const char * uid); int maildir_message_remove(struct maildir * md, const char * uid); int maildir_message_change_flags(struct maildir * md, const char * uid, int new_flags); #endif diff --git a/kmicromail/libetpan/mbox/mailmbox.c b/kmicromail/libetpan/mbox/mailmbox.c index 280c313..b3fce02 100644 --- a/kmicromail/libetpan/mbox/mailmbox.c +++ b/kmicromail/libetpan/mbox/mailmbox.c @@ -104,192 +104,195 @@ int mailmbox_read_lock(struct mailmbox_folder * folder) int r; r = maillock_read_lock(folder->mb_filename, folder->mb_fd); if (r == 0) return MAILMBOX_NO_ERROR; else return MAILMBOX_ERROR_FILE; } int mailmbox_read_unlock(struct mailmbox_folder * folder) { int r; r = maillock_read_unlock(folder->mb_filename, folder->mb_fd); if (r == 0) return MAILMBOX_NO_ERROR; else return MAILMBOX_ERROR_FILE; } /* map the file into memory. the file must be locked. */ int mailmbox_map(struct mailmbox_folder * folder) { char * str; struct stat buf; int res; int r; r = stat(folder->mb_filename, &buf); if (r < 0) { res = MAILMBOX_ERROR_FILE; goto err; } if (folder->mb_read_only) str = (char *) mmap(0, buf.st_size, PROT_READ, MAP_PRIVATE, folder->mb_fd, 0); else str = (char *) mmap(0, buf.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, folder->mb_fd, 0); if (str == MAP_FAILED) { res = MAILMBOX_ERROR_FILE; goto err; } folder->mb_mapping = str; folder->mb_mapping_size = buf.st_size; return MAILMBOX_NO_ERROR; err: return res; } /* unmap the file */ void mailmbox_unmap(struct mailmbox_folder * folder) { munmap(folder->mb_mapping, folder->mb_mapping_size); folder->mb_mapping = NULL; folder->mb_mapping_size = 0; } void mailmbox_sync(struct mailmbox_folder * folder) { msync(folder->mb_mapping, folder->mb_mapping_size, MS_SYNC); } void mailmbox_timestamp(struct mailmbox_folder * folder) { int r; struct stat buf; r = stat(folder->mb_filename, &buf); if (r < 0) folder->mb_mtime = (time_t) -1; else folder->mb_mtime = buf.st_mtime; } /* open the file */ int mailmbox_open(struct mailmbox_folder * folder) { int fd; int read_only; + fd = -1; + read_only = TRUE; + if (!folder->mb_read_only) { read_only = FALSE; fd = open(folder->mb_filename, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); } if (folder->mb_read_only || (fd < 0)) { read_only = TRUE; fd = open(folder->mb_filename, O_RDONLY); if (fd < 0) return MAILMBOX_ERROR_FILE_NOT_FOUND; } folder->mb_fd = fd; folder->mb_read_only = read_only; return MAILMBOX_NO_ERROR; } /* close the file */ void mailmbox_close(struct mailmbox_folder * folder) { close(folder->mb_fd); folder->mb_fd = -1; } static int mailmbox_validate_lock(struct mailmbox_folder * folder, int (* custom_lock)(struct mailmbox_folder *), int (* custom_unlock)(struct mailmbox_folder *)) { struct stat buf; int res; int r; r = stat(folder->mb_filename, &buf); if (r < 0) { buf.st_mtime = (time_t) -1; } if ((buf.st_mtime != folder->mb_mtime) || ((size_t) buf.st_size != folder->mb_mapping_size)) { int r; mailmbox_unmap(folder); mailmbox_close(folder); r = mailmbox_open(folder); if (r != MAILMBOX_NO_ERROR) { res = r; goto err; } r = custom_lock(folder); if (r != MAILMBOX_NO_ERROR) { res = r; goto err; } r = mailmbox_map(folder); if (r != MAILMBOX_NO_ERROR) { res = r; goto err_unlock; } r = mailmbox_parse(folder); if (r != MAILMBOX_NO_ERROR) { res = r; goto err_unlock; } folder->mb_mtime = buf.st_mtime; return MAILMBOX_NO_ERROR; } else { r = custom_lock(folder); if (r != MAILMBOX_NO_ERROR) { res = r; goto err; } } return MAILMBOX_NO_ERROR; err_unlock: custom_unlock(folder); err: return res; } int mailmbox_validate_write_lock(struct mailmbox_folder * folder) { @@ -524,360 +527,372 @@ static char * write_fixed_message(char * str, int ignore; ignore = FALSE; begin = cur_token; if (cur_token + strlen(UID_HEADER) <= size) { if (message[cur_token] == 'X') { if (strncasecmp(message + cur_token, UID_HEADER, strlen(UID_HEADER)) == 0) { ignore = TRUE; } } } r = mailimf_ignore_field_parse(message, size, &cur_token); switch (r) { case MAILIMF_NO_ERROR: if (!ignore) { memcpy(str, message + begin, cur_token - begin); str += cur_token - begin; } break; case MAILIMF_ERROR_PARSE: default: end = TRUE; break; } } if (!force_no_uid) { /* UID header */ memcpy(str, UID_HEADER " ", strlen(UID_HEADER " ")); str += strlen(UID_HEADER " "); numlen = snprintf(str, 20, "%i\r\n", uid); str += numlen; } /* body */ cur_src = message + cur_token; left = size - cur_token; while (left > 0) { size_t count; const char * next; str = write_fixed_line(str, cur_src, left, &next, &count); cur_src = next; left -= count; } return str; } #define DEFAULT_FROM_LINE "From - Wed Jun 30 21:49:08 1993\n" int mailmbox_append_message_list_no_lock(struct mailmbox_folder * folder, carray * append_tab) { size_t extra_size; int r; char from_line[MAX_FROM_LINE_SIZE] = DEFAULT_FROM_LINE; struct tm time_info; time_t date; int res; size_t old_size; char * str; unsigned int i; size_t from_size; size_t maxuid; size_t left; size_t crlf_count; if (folder->mb_read_only) { res = MAILMBOX_ERROR_READONLY; goto err; } date = time(NULL); from_size = strlen(DEFAULT_FROM_LINE); if (localtime_r(&date, &time_info) != NULL) from_size = strftime(from_line, MAX_FROM_LINE_SIZE, "From - %c\n", &time_info); maxuid = /* */ folder->mb_max_uid; extra_size = 0; for(i = 0 ; i < carray_count(append_tab) ; i ++) { struct mailmbox_append_info * info; info = carray_get(append_tab, i); extra_size += from_size; extra_size += get_fixed_message_size(info->ai_message, info->ai_size, folder->mb_max_uid + i + 1, folder->mb_no_uid); extra_size += 2; /* CR LF */ + + info->ai_uid = folder->mb_max_uid + i + 1; } left = folder->mb_mapping_size; crlf_count = 0; while (left >= 1) { if (folder->mb_mapping[left - 1] == '\n') { crlf_count ++; left --; } else if (folder->mb_mapping[left - 1] == '\r') { left --; } else break; if (crlf_count == 2) break; } old_size = folder->mb_mapping_size; mailmbox_unmap(folder); if (old_size != 0) { if (crlf_count != 2) extra_size += (2 - crlf_count) * 2; } r = ftruncate(folder->mb_fd, extra_size + old_size); if (r < 0) { mailmbox_map(folder); res = MAILMBOX_ERROR_FILE; goto err; } r = mailmbox_map(folder); if (r < 0) { ftruncate(folder->mb_fd, old_size); return MAILMBOX_ERROR_FILE; } str = folder->mb_mapping + old_size; if (old_size != 0) { for(i = 0 ; i < 2 - crlf_count ; i ++) { * str = '\r'; str ++; * str = '\n'; str ++; } } for(i = 0 ; i < carray_count(append_tab) ; i ++) { struct mailmbox_append_info * info; info = carray_get(append_tab, i); memcpy(str, from_line, from_size); str += strlen(from_line); str = write_fixed_message(str, info->ai_message, info->ai_size, folder->mb_max_uid + i + 1, folder->mb_no_uid); * str = '\r'; str ++; * str = '\n'; str ++; } folder->mb_max_uid += carray_count(append_tab); return MAILMBOX_NO_ERROR; err: return res; } int mailmbox_append_message_list(struct mailmbox_folder * folder, carray * append_tab) { int r; int res; size_t cur_token; r = mailmbox_validate_write_lock(folder); if (r != MAILMBOX_NO_ERROR) { res = r; goto err; } r = mailmbox_expunge_no_lock(folder); if (r != MAILMBOX_NO_ERROR) { res = r; goto unlock; } cur_token = folder->mb_mapping_size; r = mailmbox_append_message_list_no_lock(folder, append_tab); if (r != MAILMBOX_NO_ERROR) { res = r; goto unlock; } mailmbox_sync(folder); r = mailmbox_parse_additionnal(folder, &cur_token); if (r != MAILMBOX_NO_ERROR) { res = r; goto unlock; } mailmbox_timestamp(folder); mailmbox_write_unlock(folder); return MAILMBOX_NO_ERROR; unlock: mailmbox_write_unlock(folder); err: return res; } int -mailmbox_append_message(struct mailmbox_folder * folder, - const char * data, size_t len) +mailmbox_append_message_uid(struct mailmbox_folder * folder, + const char * data, size_t len, unsigned int * puid) { carray * tab; struct mailmbox_append_info * append_info; int res; int r; tab = carray_new(1); if (tab == NULL) { res = MAILMBOX_ERROR_MEMORY; goto err; } append_info = mailmbox_append_info_new(data, len); if (append_info == NULL) { res = MAILMBOX_ERROR_MEMORY; goto free_list; } r = carray_add(tab, append_info, NULL); if (r < 0) { res = MAILMBOX_ERROR_MEMORY; goto free_append_info; } r = mailmbox_append_message_list(folder, tab); + if (puid != NULL) + * puid = append_info->ai_uid; + mailmbox_append_info_free(append_info); carray_free(tab); return r; free_append_info: mailmbox_append_info_free(append_info); free_list: carray_free(tab); err: return res; } +int +mailmbox_append_message(struct mailmbox_folder * folder, + const char * data, size_t len) +{ + return mailmbox_append_message_uid(folder, data, len, NULL); +} + /* ********************************************************************** */ int mailmbox_fetch_msg_no_lock(struct mailmbox_folder * folder, uint32_t num, char ** result, size_t * result_len) { struct mailmbox_msg_info * info; int res; chashdatum key; chashdatum data; int r; key.data = # key.len = sizeof(num); r = chash_get(folder->mb_hash, &key, &data); if (r < 0) { res = MAILMBOX_ERROR_MSG_NOT_FOUND; goto err; } info = data.data; if (info->msg_deleted) { res = MAILMBOX_ERROR_MSG_NOT_FOUND; goto err; } * result = folder->mb_mapping + info->msg_headers; * result_len = info->msg_size - info->msg_start_len; return MAILMBOX_NO_ERROR; err: return res; } int mailmbox_fetch_msg_headers_no_lock(struct mailmbox_folder * folder, uint32_t num, char ** result, size_t * result_len) { struct mailmbox_msg_info * info; int res; chashdatum key; chashdatum data; int r; key.data = # key.len = sizeof(num); r = chash_get(folder->mb_hash, &key, &data); if (r < 0) { res = MAILMBOX_ERROR_MSG_NOT_FOUND; goto err; } info = data.data; if (info->msg_deleted) { res = MAILMBOX_ERROR_MSG_NOT_FOUND; goto err; } * result = folder->mb_mapping + info->msg_headers; * result_len = info->msg_headers_len; return MAILMBOX_NO_ERROR; err: return res; } int mailmbox_fetch_msg(struct mailmbox_folder * folder, uint32_t num, char ** result, size_t * result_len) { MMAPString * mmapstr; int res; char * data; size_t len; int r; size_t fixed_size; char * end; r = mailmbox_validate_read_lock(folder); if (r != MAILMBOX_NO_ERROR) { res = r; goto err; } r = mailmbox_fetch_msg_no_lock(folder, num, &data, &len); if (r != MAILMBOX_NO_ERROR) { res = r; goto unlock; } diff --git a/kmicromail/libetpan/mbox/mailmbox.h b/kmicromail/libetpan/mbox/mailmbox.h index 8be086c..0427f1f 100644 --- a/kmicromail/libetpan/mbox/mailmbox.h +++ b/kmicromail/libetpan/mbox/mailmbox.h @@ -1,140 +1,144 @@ /* * libEtPan! -- a mail stuff library * * Copyright (C) 2001, 2002 - DINH Viet Hoa * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the libEtPan! project nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * $Id$ */ #ifndef MAILMBOX_H #define MAILMBOX_H #ifdef __cplusplus extern "C" { #endif #include <libetpan/mailmbox_types.h> int mailmbox_append_message_list(struct mailmbox_folder * folder, carray * append_tab); int mailmbox_append_message(struct mailmbox_folder * folder, const char * data, size_t len); +int +mailmbox_append_message_uid(struct mailmbox_folder * folder, + const char * data, size_t len, unsigned int * puid); + int mailmbox_fetch_msg(struct mailmbox_folder * folder, uint32_t num, char ** result, size_t * result_len); int mailmbox_fetch_msg_headers(struct mailmbox_folder * folder, uint32_t num, char ** result, size_t * result_len); void mailmbox_fetch_result_free(char * msg); int mailmbox_copy_msg_list(struct mailmbox_folder * dest_folder, struct mailmbox_folder * src_folder, carray * tab); int mailmbox_copy_msg(struct mailmbox_folder * dest_folder, struct mailmbox_folder * src_folder, uint32_t uid); int mailmbox_expunge(struct mailmbox_folder * folder); int mailmbox_delete_msg(struct mailmbox_folder * folder, uint32_t uid); int mailmbox_init(const char * filename, int force_readonly, int force_no_uid, uint32_t default_written_uid, struct mailmbox_folder ** result_folder); void mailmbox_done(struct mailmbox_folder * folder); /* low-level access primitives */ int mailmbox_write_lock(struct mailmbox_folder * folder); int mailmbox_write_unlock(struct mailmbox_folder * folder); int mailmbox_read_lock(struct mailmbox_folder * folder); int mailmbox_read_unlock(struct mailmbox_folder * folder); /* memory map */ int mailmbox_map(struct mailmbox_folder * folder); void mailmbox_unmap(struct mailmbox_folder * folder); void mailmbox_sync(struct mailmbox_folder * folder); /* open & close file */ int mailmbox_open(struct mailmbox_folder * folder); void mailmbox_close(struct mailmbox_folder * folder); /* validate cache */ int mailmbox_validate_write_lock(struct mailmbox_folder * folder); int mailmbox_validate_read_lock(struct mailmbox_folder * folder); /* fetch message */ int mailmbox_fetch_msg_no_lock(struct mailmbox_folder * folder, uint32_t num, char ** result, size_t * result_len); int mailmbox_fetch_msg_headers_no_lock(struct mailmbox_folder * folder, uint32_t num, char ** result, size_t * result_len); /* append message */ int mailmbox_append_message_list_no_lock(struct mailmbox_folder * folder, carray * append_tab); int mailmbox_expunge_no_lock(struct mailmbox_folder * folder); #ifdef __cplusplus } #endif #endif diff --git a/kmicromail/libetpan/mbox/mailmbox_types.c b/kmicromail/libetpan/mbox/mailmbox_types.c index 1986182..4e3e521 100644 --- a/kmicromail/libetpan/mbox/mailmbox_types.c +++ b/kmicromail/libetpan/mbox/mailmbox_types.c @@ -85,166 +85,167 @@ int mailmbox_msg_info_update(struct mailmbox_folder * folder, if (msg_uid != 0) { chashdatum key; chashdatum data; key.data = &msg_uid; key.len = sizeof(msg_uid); data.data = info; data.len = 0; r = chash_set(folder->mb_hash, &key, &data, NULL); if (r < 0) { mailmbox_msg_info_free(info); carray_delete(folder->mb_tab, index); res = MAILMBOX_ERROR_MEMORY; goto err; } } info->msg_index = index; } else { info = data.data; info->msg_start = msg_start; info->msg_start_len = msg_start_len; info->msg_headers = msg_headers; info->msg_headers_len = msg_headers_len; info->msg_body = msg_body; info->msg_body_len = msg_body_len; info->msg_size = msg_size; info->msg_padding = msg_padding; } return MAILMBOX_NO_ERROR; err: return res; } struct mailmbox_msg_info * mailmbox_msg_info_new(size_t msg_start, size_t msg_start_len, size_t msg_headers, size_t msg_headers_len, size_t msg_body, size_t msg_body_len, size_t msg_size, size_t msg_padding, uint32_t msg_uid) { struct mailmbox_msg_info * info; info = malloc(sizeof(* info)); if (info == NULL) return NULL; info->msg_index = 0; info->msg_uid = msg_uid; if (msg_uid != 0) info->msg_written_uid = TRUE; else info->msg_written_uid = FALSE; info->msg_deleted = FALSE; info->msg_start = msg_start; info->msg_start_len = msg_start_len; info->msg_headers = msg_headers; info->msg_headers_len = msg_headers_len; info->msg_body = msg_body; info->msg_body_len = msg_body_len; info->msg_size = msg_size; info->msg_padding = msg_padding; return info; } void mailmbox_msg_info_free(struct mailmbox_msg_info * info) { free(info); } /* append info */ struct mailmbox_append_info * mailmbox_append_info_new(const char * ai_message, size_t ai_size) { struct mailmbox_append_info * info; info = malloc(sizeof(* info)); if (info == NULL) return NULL; info->ai_message = ai_message; info->ai_size = ai_size; + info->ai_uid = 0; return info; } void mailmbox_append_info_free(struct mailmbox_append_info * info) { free(info); } struct mailmbox_folder * mailmbox_folder_new(const char * mb_filename) { struct mailmbox_folder * folder; folder = malloc(sizeof(* folder)); if (folder == NULL) goto err; strncpy(folder->mb_filename, mb_filename, PATH_MAX); folder->mb_mtime = (time_t) -1; folder->mb_fd = -1; folder->mb_read_only = TRUE; folder->mb_no_uid = TRUE; folder->mb_changed = FALSE; folder->mb_deleted_count = 0; folder->mb_mapping = NULL; folder->mb_mapping_size = 0; folder->mb_written_uid = 0; folder->mb_max_uid = 0; folder->mb_hash = chash_new(CHASH_DEFAULTSIZE, CHASH_COPYKEY); if (folder->mb_hash == NULL) goto free; folder->mb_tab = carray_new(128); if (folder->mb_tab == NULL) goto free_hash; return folder; free_hash: chash_free(folder->mb_hash); free: free(folder); err: return NULL; } void mailmbox_folder_free(struct mailmbox_folder * folder) { unsigned int i; for(i = 0 ; i < carray_count(folder->mb_tab) ; i++) { struct mailmbox_msg_info * info; info = carray_get(folder->mb_tab, i); if (info != NULL) mailmbox_msg_info_free(info); } carray_free(folder->mb_tab); chash_free(folder->mb_hash); free(folder); } diff --git a/kmicromail/libetpan/mbox/mailmbox_types.h b/kmicromail/libetpan/mbox/mailmbox_types.h index dd6758c..bd6ee30 100644 --- a/kmicromail/libetpan/mbox/mailmbox_types.h +++ b/kmicromail/libetpan/mbox/mailmbox_types.h @@ -35,108 +35,109 @@ #ifndef MAILMBOX_TYPES_H #define MAILMBOX_TYPES_H #ifdef __cplusplus extern "C" { #endif #include <sys/types.h> #include <libetpan/libetpan-config.h> #include <libetpan/mailimf.h> #include <libetpan/carray.h> #include <libetpan/chash.h> enum { MAILMBOX_NO_ERROR = 0, MAILMBOX_ERROR_PARSE, MAILMBOX_ERROR_INVAL, MAILMBOX_ERROR_FILE_NOT_FOUND, MAILMBOX_ERROR_MEMORY, MAILMBOX_ERROR_TEMPORARY_FILE, MAILMBOX_ERROR_FILE, MAILMBOX_ERROR_MSG_NOT_FOUND, MAILMBOX_ERROR_READONLY, }; struct mailmbox_folder { char mb_filename[PATH_MAX]; time_t mb_mtime; int mb_fd; int mb_read_only; int mb_no_uid; int mb_changed; unsigned int mb_deleted_count; char * mb_mapping; size_t mb_mapping_size; uint32_t mb_written_uid; uint32_t mb_max_uid; chash * mb_hash; carray * mb_tab; }; struct mailmbox_folder * mailmbox_folder_new(const char * mb_filename); void mailmbox_folder_free(struct mailmbox_folder * folder); struct mailmbox_msg_info { unsigned int msg_index; uint32_t msg_uid; int msg_written_uid; int msg_deleted; size_t msg_start; size_t msg_start_len; size_t msg_headers; size_t msg_headers_len; size_t msg_body; size_t msg_body_len; size_t msg_size; size_t msg_padding; }; int mailmbox_msg_info_update(struct mailmbox_folder * folder, size_t msg_start, size_t msg_start_len, size_t msg_headers, size_t msg_headers_len, size_t msg_body, size_t msg_body_len, size_t msg_size, size_t msg_padding, uint32_t msg_uid); struct mailmbox_msg_info * mailmbox_msg_info_new(size_t msg_start, size_t msg_start_len, size_t msg_headers, size_t msg_headers_len, size_t msg_body, size_t msg_body_len, size_t msg_size, size_t msg_padding, uint32_t msg_uid); void mailmbox_msg_info_free(struct mailmbox_msg_info * info); struct mailmbox_append_info { const char * ai_message; size_t ai_size; + unsigned int ai_uid; }; struct mailmbox_append_info * mailmbox_append_info_new(const char * ai_message, size_t ai_size); void mailmbox_append_info_free(struct mailmbox_append_info * info); #ifdef __cplusplus } #endif #endif diff --git a/kmicromail/libetpan/mh/mailmh.c b/kmicromail/libetpan/mh/mailmh.c index d6ff950..119f217 100644 --- a/kmicromail/libetpan/mh/mailmh.c +++ b/kmicromail/libetpan/mh/mailmh.c @@ -630,321 +630,337 @@ static int mailmh_folder_alloc_msg(struct mailmh_folder * folder, r = mailmh_folder_update(folder); /* ignore errors */ } * result = max + k; folder->fl_max_index = max + k; return MAILMH_NO_ERROR; } else if (errno == EXDEV) { free(filename); return MAILMH_ERROR_FOLDER; } k ++; } free(new_filename); return MAILMH_ERROR_FOLDER; } int mailmh_folder_get_message_filename(struct mailmh_folder * folder, uint32_t index, char ** result) { char * filename; int len; #if 0 r = mailmh_folder_update(folder); if (r != MAILMH_NO_ERROR) return r; #endif len = strlen(folder->fl_filename) + 20; filename = malloc(len); if (filename == NULL) return MAILMH_ERROR_MEMORY; snprintf(filename, len, "%s%c%lu", folder->fl_filename, MAIL_DIR_SEPARATOR, (unsigned long) index); * result = filename; return MAILMH_NO_ERROR;; } int mailmh_folder_get_message_fd(struct mailmh_folder * folder, uint32_t index, int flags, int * result) { char * filename; int fd; int r; #if 0 r = mailmh_folder_update(folder); if (r != MAILMH_NO_ERROR) return r; #endif r = mailmh_folder_get_message_filename(folder, index, &filename); if (r != MAILMH_NO_ERROR) return r; fd = open(filename, flags); free(filename); if (fd == -1) return MAILMH_ERROR_MSG_NOT_FOUND; * result = fd; return MAILMH_NO_ERROR; } int mailmh_folder_get_message_size(struct mailmh_folder * folder, uint32_t index, size_t * result) { int r; char * filename; struct stat buf; r = mailmh_folder_get_message_filename(folder, index, &filename); if (r != MAILMH_NO_ERROR) return r; r = stat(filename, &buf); free(filename); if (r < 0) return MAILMH_ERROR_FILE; * result = buf.st_size; return MAILMH_NO_ERROR; } -int mailmh_folder_add_message(struct mailmh_folder * folder, - const char * message, size_t size) +int mailmh_folder_add_message_uid(struct mailmh_folder * folder, + const char * message, size_t size, + uint32_t * pindex) { char * tmpname; int fd; size_t namesize; size_t left; ssize_t res; struct mailmh_msg_info * msg_info; uint32_t index; int error; int r; unsigned int array_index; struct stat buf; chashdatum key; chashdatum data; #if 0 r = mailmh_folder_update(folder); if (r != MAILMH_NO_ERROR) { error = r; goto err; } #endif namesize = strlen(folder->fl_filename) + 20; tmpname = malloc(namesize); snprintf(tmpname, namesize, "%s%ctmpXXXXXX", folder->fl_filename, MAIL_DIR_SEPARATOR); fd = mkstemp(tmpname); if (fd < 0) { error = MAILMH_ERROR_FILE; goto free; } left = size; while (left > 0) { res = write(fd, message, left); if (res == -1) { close(fd); error = MAILMH_ERROR_FILE; goto free; } left -= res; } close(fd); r = stat(tmpname, &buf); if (r < 0) { error = MAILMH_ERROR_FILE; goto free; } r = mailmh_folder_alloc_msg(folder, tmpname, &index); if (r != MAILMH_NO_ERROR) { unlink(tmpname); error = MAILMH_ERROR_COULD_NOT_ALLOC_MSG; goto free; } free(tmpname); msg_info = mailmh_msg_info_new(index, size, buf.st_mtime); if (msg_info == NULL) { mailmh_folder_remove_message(folder, index); error = MAILMH_ERROR_MEMORY; goto err; } r = carray_add(folder->fl_msgs_tab, msg_info, &array_index); if (r < 0) { mailmh_folder_remove_message(folder, index); mailmh_msg_info_free(msg_info); error = MAILMH_ERROR_MEMORY; goto err; } msg_info->msg_array_index = array_index; #if 0 r = cinthash_add(folder->fl_msgs_hash, index, msg_info); #endif key.data = &index; key.len = sizeof(index); data.data = msg_info; data.len = 0; + if (pindex != NULL) + * pindex = index; + r = chash_set(folder->fl_msgs_hash, &key, &data, NULL); if (r < 0) { carray_delete_fast(folder->fl_msgs_tab, msg_info->msg_array_index); mailmh_msg_info_free(msg_info); error = MAILMH_ERROR_MEMORY; goto err; } return MAILMH_NO_ERROR; free: free(tmpname); err: return error; } -int mailmh_folder_add_message_file(struct mailmh_folder * folder, - int fd) +int mailmh_folder_add_message(struct mailmh_folder * folder, + const char * message, size_t size) +{ + return mailmh_folder_add_message_uid(folder, message, size, NULL); +} + +int mailmh_folder_add_message_file_uid(struct mailmh_folder * folder, + int fd, uint32_t * pindex) { char * message; struct stat buf; int r; #if 0 r = mailmh_folder_update(folder); if (r != MAILMH_NO_ERROR) return r; #endif if (fstat(fd, &buf) == -1) return MAILMH_ERROR_FILE; message = mmap(NULL, buf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); if (message == MAP_FAILED) return MAILMH_ERROR_FILE; - r = mailmh_folder_add_message(folder, message, buf.st_size); + r = mailmh_folder_add_message_uid(folder, message, buf.st_size, pindex); munmap(message, buf.st_size); return r; } +int mailmh_folder_add_message_file(struct mailmh_folder * folder, + int fd) +{ + return mailmh_folder_add_message_file_uid(folder, fd, NULL); +} + int mailmh_folder_remove_message(struct mailmh_folder * folder, uint32_t index) { char * filename; struct mailmh_msg_info * msg_info; int res; int r; chashdatum key; chashdatum data; #if 0 r = mailmh_folder_update(folder); if (r != MAILMH_NO_ERROR) { res = r; goto err; } #endif r = mailmh_folder_get_message_filename(folder, index, &filename); if (filename == NULL) { res = r; goto err; } if (unlink(filename) == -1) { res = MAILMH_ERROR_FILE; goto free; } key.data = &index; key.len = sizeof(index); r = chash_get(folder->fl_msgs_hash, &key, &data); #if 0 msg_info = cinthash_find(folder->fl_msgs_hash, index); #endif if (r == 0) { msg_info = data.data; carray_delete_fast(folder->fl_msgs_tab, msg_info->msg_array_index); #if 0 cinthash_remove(folder->fl_msgs_hash, index); #endif chash_delete(folder->fl_msgs_hash, &key, NULL); } return MAILMH_NO_ERROR; free: free(filename); err: return res; } int mailmh_folder_move_message(struct mailmh_folder * dest_folder, struct mailmh_folder * src_folder, uint32_t index) { int fd; char * filename; int r; #if 0 r = mailmh_folder_update(dest_folder); if (r != MAILMH_NO_ERROR) return r; r = mailmh_folder_update(src_folder); if (r != MAILMH_NO_ERROR) return r; #endif /* move on the same filesystem */ r = mailmh_folder_get_message_filename(src_folder, index, &filename); if (r != MAILMH_NO_ERROR) return r; r = mailmh_folder_alloc_msg(dest_folder, filename, &index); free(filename); if (r == MAILMH_NO_ERROR) return MAILMH_NO_ERROR; /* move on the different filesystems */ r = mailmh_folder_get_message_fd(src_folder, index, O_RDONLY, &fd); if (r != MAILMH_NO_ERROR) return r; r = mailmh_folder_add_message_file(dest_folder, fd); if (r != MAILMH_NO_ERROR) { close(fd); return r; } close(fd); r = mailmh_folder_remove_message(src_folder, index); diff --git a/kmicromail/libetpan/mh/mailmh.h b/kmicromail/libetpan/mh/mailmh.h index 40432cb..00199b8 100644 --- a/kmicromail/libetpan/mh/mailmh.h +++ b/kmicromail/libetpan/mh/mailmh.h @@ -26,118 +26,125 @@ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * $Id$ */ #ifndef MAILMH_H #define MAILMH_H #ifdef __cplusplus extern "C" { #endif #include <sys/types.h> #include <inttypes.h> #include <libetpan/carray.h> #include <libetpan/cinthash.h> #include <libetpan/chash.h> enum { MAILMH_NO_ERROR = 0, MAILMH_ERROR_FOLDER, MAILMH_ERROR_MEMORY, MAILMH_ERROR_FILE, MAILMH_ERROR_COULD_NOT_ALLOC_MSG, MAILMH_ERROR_RENAME, MAILMH_ERROR_MSG_NOT_FOUND, }; struct mailmh { struct mailmh_folder * mh_main; }; struct mailmh_msg_info { unsigned int msg_array_index; uint32_t msg_index; size_t msg_size; time_t msg_mtime; }; struct mailmh_folder { char * fl_filename; unsigned int fl_array_index; char * fl_name; time_t fl_mtime; struct mailmh_folder * fl_parent; uint32_t fl_max_index; carray * fl_msgs_tab; #if 0 cinthash_t * fl_msgs_hash; #endif chash * fl_msgs_hash; carray * fl_subfolders_tab; chash * fl_subfolders_hash; }; struct mailmh * mailmh_new(const char * foldername); void mailmh_free(struct mailmh * f); struct mailmh_msg_info * mailmh_msg_info_new(uint32_t index, size_t size, time_t mtime); void mailmh_msg_info_free(struct mailmh_msg_info * msg_info); struct mailmh_folder * mailmh_folder_new(struct mailmh_folder * parent, const char * name); void mailmh_folder_free(struct mailmh_folder * folder); int mailmh_folder_add_subfolder(struct mailmh_folder * parent, const char * name); struct mailmh_folder * mailmh_folder_find(struct mailmh_folder * root, const char * filename); int mailmh_folder_remove_subfolder(struct mailmh_folder * folder); int mailmh_folder_rename_subfolder(struct mailmh_folder * src_folder, struct mailmh_folder * dst_folder, const char * new_name); int mailmh_folder_get_message_filename(struct mailmh_folder * folder, uint32_t index, char ** result); int mailmh_folder_get_message_fd(struct mailmh_folder * folder, uint32_t index, int flags, int * result); int mailmh_folder_get_message_size(struct mailmh_folder * folder, uint32_t index, size_t * result); +int mailmh_folder_add_message_uid(struct mailmh_folder * folder, + const char * message, size_t size, + uint32_t * pindex); + int mailmh_folder_add_message(struct mailmh_folder * folder, const char * message, size_t size); +int mailmh_folder_add_message_file_uid(struct mailmh_folder * folder, + int fd, uint32_t * pindex); + int mailmh_folder_add_message_file(struct mailmh_folder * folder, int fd); int mailmh_folder_remove_message(struct mailmh_folder * folder, uint32_t index); int mailmh_folder_move_message(struct mailmh_folder * dest_folder, struct mailmh_folder * src_folder, uint32_t index); int mailmh_folder_update(struct mailmh_folder * folder); unsigned int mailmh_folder_get_message_number(struct mailmh_folder * folder); #ifdef __cplusplus } #endif #endif diff --git a/kmicromail/libetpan/mime/mailmime_decode.c b/kmicromail/libetpan/mime/mailmime_decode.c index 3025dcb..e48ec19 100644 --- a/kmicromail/libetpan/mime/mailmime_decode.c +++ b/kmicromail/libetpan/mime/mailmime_decode.c @@ -94,202 +94,212 @@ enum { int mailmime_encoded_phrase_parse(const char * default_fromcode, const char * message, size_t length, size_t * index, const char * tocode, char ** result) { MMAPString * gphrase; struct mailmime_encoded_word * word; int first; size_t cur_token; int r; int res; char * str; char * wordutf8; int type; cur_token = * index; gphrase = mmap_string_new(""); if (gphrase == NULL) { res = MAILIMF_ERROR_MEMORY; goto err; } first = TRUE; type = TYPE_ERROR; /* XXX - removes a gcc warning */ while (1) { r = mailmime_encoded_word_parse(message, length, &cur_token, &word); if (r == MAILIMF_NO_ERROR) { if (!first) { if (type != TYPE_ENCODED_WORD) { if (mmap_string_append_c(gphrase, ' ') == NULL) { mailmime_encoded_word_free(word); res = MAILIMF_ERROR_MEMORY; goto free; } } } type = TYPE_ENCODED_WORD; wordutf8 = NULL; r = charconv(tocode, word->wd_charset, word->wd_text, strlen(word->wd_text), &wordutf8); switch (r) { case MAIL_CHARCONV_ERROR_MEMORY: mailmime_encoded_word_free(word); res = MAILIMF_ERROR_MEMORY; goto free; case MAIL_CHARCONV_ERROR_UNKNOWN_CHARSET: case MAIL_CHARCONV_ERROR_CONV: mailmime_encoded_word_free(word); res = MAILIMF_ERROR_PARSE; goto free; } if (wordutf8 != NULL) { if (mmap_string_append(gphrase, wordutf8) == NULL) { mailmime_encoded_word_free(word); free(wordutf8); res = MAILIMF_ERROR_MEMORY; goto free; } free(wordutf8); } mailmime_encoded_word_free(word); first = FALSE; } else if (r == MAILIMF_ERROR_PARSE) { /* do nothing */ } else { res = r; goto free; } if (r == MAILIMF_ERROR_PARSE) { char * raw_word; r = mailmime_non_encoded_word_parse(message, length, &cur_token, &raw_word); if (r == MAILIMF_NO_ERROR) { if (!first) { if (mmap_string_append_c(gphrase, ' ') == NULL) { free(raw_word); res = MAILIMF_ERROR_MEMORY; goto free; } } type = TYPE_WORD; wordutf8 = NULL; r = charconv(tocode, default_fromcode, raw_word, strlen(raw_word), &wordutf8); - if (wordutf8 != NULL) { - if (mmap_string_append(gphrase, wordutf8) == NULL) { - free(wordutf8); + switch (r) { + case MAIL_CHARCONV_ERROR_MEMORY: free(raw_word); res = MAILIMF_ERROR_MEMORY; goto free; + + case MAIL_CHARCONV_ERROR_UNKNOWN_CHARSET: + case MAIL_CHARCONV_ERROR_CONV: + free(raw_word); + res = MAILIMF_ERROR_PARSE; + goto free; } + if (mmap_string_append(gphrase, wordutf8) == NULL) { free(wordutf8); + free(raw_word); + res = MAILIMF_ERROR_MEMORY; + goto free; } + free(raw_word); first = FALSE; } else if (r == MAILIMF_ERROR_PARSE) { break; } else { res = r; goto free; } } } if (first) { res = MAILIMF_ERROR_PARSE; goto free; } str = strdup(gphrase->str); if (str == NULL) { res = MAILIMF_ERROR_MEMORY; goto free; } mmap_string_free(gphrase); * result = str; * index = cur_token; return MAILIMF_NO_ERROR; free: mmap_string_free(gphrase); err: return res; } static int mailmime_non_encoded_word_parse(const char * message, size_t length, size_t * index, char ** result) { int end; size_t cur_token; int res; char * text; int r; size_t begin; cur_token = * index; r = mailimf_fws_parse(message, length, &cur_token); if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) { res = r; goto err; } begin = cur_token; end = FALSE; while (1) { if (cur_token >= length) break; switch (message[cur_token]) { case ' ': case '\t': case '\r': case '\n': end = TRUE; break; } if (end) break; cur_token ++; } if (cur_token - begin == 0) { res = MAILIMF_ERROR_PARSE; goto err; } text = malloc(cur_token - begin + 1); if (text == NULL) { res = MAILIMF_ERROR_MEMORY; goto err; } memcpy(text, message + begin, cur_token - begin); text[cur_token - begin] = '\0'; * index = cur_token; * result = text; return MAILIMF_NO_ERROR; diff --git a/kmicromail/libetpan/mime/mailmime_write.c b/kmicromail/libetpan/mime/mailmime_write.c index 5c3b1f7..208e3ba 100644 --- a/kmicromail/libetpan/mime/mailmime_write.c +++ b/kmicromail/libetpan/mime/mailmime_write.c @@ -348,193 +348,193 @@ static int mailmime_language_write(FILE * f, int * col, r = mailimf_string_write(f, col, "\r\n", 2); if (r != MAILIMF_NO_ERROR) return r; #if 0 * col = 0; #endif return MAILIMF_NO_ERROR; } static int mailmime_disposition_write(FILE * f, int * col, struct mailmime_disposition * disposition) { struct mailmime_disposition_type * dsp_type; int r; clistiter * cur; dsp_type = disposition->dsp_type; r = mailimf_string_write(f, col, "Content-Disposition: ", 21); if (r != MAILIMF_NO_ERROR) return r; switch (dsp_type->dsp_type) { case MAILMIME_DISPOSITION_TYPE_INLINE: r = mailimf_string_write(f, col, "inline", 6); break; case MAILMIME_DISPOSITION_TYPE_ATTACHMENT: r = mailimf_string_write(f, col, "attachment", 10); break; case MAILMIME_DISPOSITION_TYPE_EXTENSION: r = mailimf_string_write(f, col, dsp_type->dsp_extension, strlen(dsp_type->dsp_extension)); break; default: r = MAILIMF_ERROR_INVAL; break; } if (r != MAILIMF_NO_ERROR) return r; for(cur = clist_begin(disposition->dsp_parms) ; cur != NULL ; cur = clist_next(cur)) { struct mailmime_disposition_parm * param; param = cur->data; r = mailimf_string_write(f, col, "; ", 2); if (r != MAILIMF_NO_ERROR) return r; r = mailmime_disposition_param_write(f, col, param); if (r != MAILIMF_NO_ERROR) return r; } r = mailimf_string_write(f, col, "\r\n", 2); if (r != MAILIMF_NO_ERROR) return r; return MAILIMF_NO_ERROR; } static int mailmime_disposition_param_write(FILE * f, int * col, struct mailmime_disposition_parm * param) { size_t len; char sizestr[20]; int r; switch (param->pa_type) { case MAILMIME_DISPOSITION_PARM_FILENAME: len = strlen("filename=") + strlen(param->pa_data.pa_filename); break; case MAILMIME_DISPOSITION_PARM_CREATION_DATE: len = strlen("creation-date=") + strlen(param->pa_data.pa_creation_date); break; case MAILMIME_DISPOSITION_PARM_MODIFICATION_DATE: len = strlen("modification-date=") + strlen(param->pa_data.pa_modification_date); break; case MAILMIME_DISPOSITION_PARM_READ_DATE: len = strlen("read-date=") + strlen(param->pa_data.pa_read_date); break; case MAILMIME_DISPOSITION_PARM_SIZE: - snprintf(sizestr, 20, "%u", param->pa_data.pa_size); + snprintf(sizestr, 20, "%lu", (unsigned long) param->pa_data.pa_size); len = strlen("size=") + strlen(sizestr); break; case MAILMIME_DISPOSITION_PARM_PARAMETER: len = strlen(param->pa_data.pa_parameter->pa_name) + 1 + strlen(param->pa_data.pa_parameter->pa_value); break; default: return MAILIMF_ERROR_INVAL; } if (* col > 1) { if (* col + len > MAX_MAIL_COL) { r = mailimf_string_write(f, col, "\r\n ", 3); if (r != MAILIMF_NO_ERROR) return r; #if 0 * col = 1; #endif } } switch (param->pa_type) { case MAILMIME_DISPOSITION_PARM_FILENAME: r = mailimf_string_write(f, col, "filename=", 9); if (r != MAILIMF_NO_ERROR) return r; r = mailimf_quoted_string_write(f, col, param->pa_data.pa_filename, strlen(param->pa_data.pa_filename)); if (r != MAILIMF_NO_ERROR) return r; break; case MAILMIME_DISPOSITION_PARM_CREATION_DATE: r = mailimf_string_write(f, col, "creation-date=", 14); if (r != MAILIMF_NO_ERROR) return r; r = mailimf_quoted_string_write(f, col, param->pa_data.pa_creation_date, strlen(param->pa_data.pa_creation_date)); if (r != MAILIMF_NO_ERROR) return r; break; case MAILMIME_DISPOSITION_PARM_MODIFICATION_DATE: r = mailimf_string_write(f, col, "modification-date=", 18); if (r != MAILIMF_NO_ERROR) return r; r = mailimf_quoted_string_write(f, col, param->pa_data.pa_modification_date, strlen(param->pa_data.pa_modification_date)); if (r != MAILIMF_NO_ERROR) return r; break; case MAILMIME_DISPOSITION_PARM_READ_DATE: r = mailimf_string_write(f, col, "read-date=", 10); if (r != MAILIMF_NO_ERROR) return r; r = mailimf_quoted_string_write(f, col, param->pa_data.pa_read_date, strlen(param->pa_data.pa_read_date)); if (r != MAILIMF_NO_ERROR) return r; break; case MAILMIME_DISPOSITION_PARM_SIZE: r = mailimf_string_write(f, col, "size=", 5); if (r != MAILIMF_NO_ERROR) return r; r = mailimf_string_write(f, col, sizestr, strlen(sizestr)); if (r != MAILIMF_NO_ERROR) return r; break; case MAILMIME_DISPOSITION_PARM_PARAMETER: r = mailmime_parameter_write(f, col, param->pa_data.pa_parameter); if (r != MAILIMF_NO_ERROR) return r; break; } return MAILIMF_NO_ERROR; } static int mailmime_parameter_write(FILE * f, int * col, struct mailmime_parameter * param) { int r; r = mailimf_string_write(f, col, param->pa_name, diff --git a/kmicromail/libetpan/smtp/mailsmtp.c b/kmicromail/libetpan/smtp/mailsmtp.c index b3be432..3ab1d11 100644 --- a/kmicromail/libetpan/smtp/mailsmtp.c +++ b/kmicromail/libetpan/smtp/mailsmtp.c @@ -99,192 +99,194 @@ mailsmtp * mailsmtp_new(size_t progr_rate, session->esmtp = 0; session->auth = MAILSMTP_AUTH_NOT_CHECKED; return session; free_line_buffer: mmap_string_free(session->line_buffer); free_session: free(session); err: return NULL; } void mailsmtp_free(mailsmtp * session) { if (session->stream) mailsmtp_quit(session); mmap_string_free(session->line_buffer); mmap_string_free(session->response_buffer); free(session); } static int send_command(mailsmtp * f, char * command); static int read_response(mailsmtp * session); /* smtp operations */ int mailsmtp_connect(mailsmtp * session, mailstream * s) { int code; session->stream = s; code = read_response(session); switch (code) { case 220: return MAILSMTP_NO_ERROR; case 554: session->stream = NULL; mailstream_close(s); return MAILSMTP_ERROR_SERVICE_NOT_AVAILABLE; default: session->stream = NULL; mailstream_close(s); return MAILSMTP_ERROR_UNEXPECTED_CODE; } } #define SMTP_STRING_SIZE 513 int mailsmtp_quit(mailsmtp * session) { char command[SMTP_STRING_SIZE]; int r; snprintf(command, SMTP_STRING_SIZE, "QUIT\r\n"); r = send_command(session, command); if (r == -1) return MAILSMTP_ERROR_STREAM; r = read_response(session); if (r == 0) return MAILSMTP_ERROR_STREAM; mailstream_close(session->stream); session->stream = NULL; return MAILSMTP_NO_ERROR; } #define HOSTNAME_SIZE 256 int mailsmtp_helo(mailsmtp * session) { int r; char hostname[HOSTNAME_SIZE]; char command[SMTP_STRING_SIZE]; r = gethostname(hostname, HOSTNAME_SIZE); if (r < 0) return MAILSMTP_ERROR_HOSTNAME; snprintf(command, SMTP_STRING_SIZE, "HELO %s\r\n", hostname); r = send_command(session, command); if (r == -1) return MAILSMTP_ERROR_STREAM; r = read_response(session); switch (r) { case 250: + session->esmtp = 0; + session->auth = MAILSMTP_AUTH_NOT_CHECKED; return MAILSMTP_NO_ERROR; case 504: return MAILSMTP_ERROR_NOT_IMPLEMENTED; case 550: return MAILSMTP_ERROR_ACTION_NOT_TAKEN; case 0: return MAILSMTP_ERROR_STREAM; default: return MAILSMTP_ERROR_UNEXPECTED_CODE; } } int mailsmtp_mail(mailsmtp * session, const char * from) { int r; char command[SMTP_STRING_SIZE]; snprintf(command, SMTP_STRING_SIZE, "MAIL FROM:<%s>\r\n", from); r = send_command(session, command); if (r == -1) return MAILSMTP_ERROR_STREAM; r = read_response(session); switch (r) { case 250: return MAILSMTP_NO_ERROR; case 552: return MAILSMTP_ERROR_EXCEED_STORAGE_ALLOCATION; case 451: return MAILSMTP_ERROR_IN_PROCESSING; case 452: return MAILSMTP_ERROR_INSUFFICIENT_SYSTEM_STORAGE; case 550: return MAILSMTP_ERROR_MAILBOX_UNAVAILABLE; case 553: return MAILSMTP_ERROR_MAILBOX_NAME_NOT_ALLOWED; case 503: return MAILSMTP_ERROR_BAD_SEQUENCE_OF_COMMAND; case 0: return MAILSMTP_ERROR_STREAM; default: return MAILSMTP_ERROR_UNEXPECTED_CODE; } } int mailsmtp_rcpt(mailsmtp * session, const char * to) { return mailesmtp_rcpt(session, to, 0, NULL); } int mailsmtp_data(mailsmtp * session) { int r; char command[SMTP_STRING_SIZE]; snprintf(command, SMTP_STRING_SIZE, "DATA\r\n"); r = send_command(session, command); if (r == -1) return MAILSMTP_ERROR_STREAM; r = read_response(session); switch (r) { case 354: return MAILSMTP_NO_ERROR; case 451: return MAILSMTP_ERROR_IN_PROCESSING; case 554: return MAILSMTP_ERROR_TRANSACTION_FAILED; case 503: return MAILSMTP_ERROR_BAD_SEQUENCE_OF_COMMAND; default: return MAILSMTP_ERROR_UNEXPECTED_CODE; } } static int send_data(mailsmtp * session, const char * message, size_t size); int mailsmtp_data_message(mailsmtp * session, const char * message, size_t size) diff --git a/kmicromail/libetpan/smtp/mailsmtp_helper.c b/kmicromail/libetpan/smtp/mailsmtp_helper.c index 32d6564..7995377 100644 --- a/kmicromail/libetpan/smtp/mailsmtp_helper.c +++ b/kmicromail/libetpan/smtp/mailsmtp_helper.c @@ -1,152 +1,148 @@ /* * libEtPan! -- a mail stuff library * * Copyright (C) 2001, 2002 - DINH Viet Hoa * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the libEtPan! project nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * $Id$ */ #include "mailsmtp.h" #include <string.h> #include <stdlib.h> #include "mail.h" int mailsmtp_init(mailsmtp * session) { int r; - session->esmtp = 0; + r = mailesmtp_ehlo(session); - if (r == MAILSMTP_NO_ERROR) { - // session->esmtp = TRUE; + if (r == MAILSMTP_NO_ERROR) return MAILSMTP_NO_ERROR; - } r = mailsmtp_helo(session); - /* if (r == MAILSMTP_NO_ERROR) { */ -/* session->esmtp = FALSE; */ -/* return MAILSMTP_NO_ERROR; */ -/* } */ + if (r == MAILSMTP_NO_ERROR) + return MAILSMTP_NO_ERROR; return r; } int mailesmtp_send(mailsmtp * session, const char * from, int return_full, const char * envid, clist * addresses, const char * message, size_t size) { int r; clistiter * l; if (!session->esmtp) return mailsmtp_send(session, from, addresses, message, size); r = mailesmtp_mail(session, from, return_full, envid); if (r != MAILSMTP_NO_ERROR) return r; for(l = clist_begin(addresses) ; l != NULL; l = clist_next(l)) { struct esmtp_address * addr; addr = clist_content(l); r = mailesmtp_rcpt(session, addr->address, addr->notify, addr->orcpt); if (r != MAILSMTP_NO_ERROR) return r; } r = mailsmtp_data(session); if (r != MAILSMTP_NO_ERROR) return r; r = mailsmtp_data_message(session, message, size); if (r != MAILSMTP_NO_ERROR) return r; return MAILSMTP_NO_ERROR; } int mailsmtp_send(mailsmtp * session, const char * from, clist * addresses, const char * message, size_t size) { int r; clistiter * l; r = mailsmtp_mail(session, from); if (r != MAILSMTP_NO_ERROR) return r; for(l = clist_begin(addresses) ; l != NULL; l = clist_next(l)) { struct esmtp_address * addr; addr = clist_content(l); r = mailsmtp_rcpt(session, addr->address); if (r != MAILSMTP_NO_ERROR) return r; } r = mailsmtp_data(session); if (r != MAILSMTP_NO_ERROR) return r; r = mailsmtp_data_message(session, message, size); if (r != MAILSMTP_NO_ERROR) return r; return MAILSMTP_NO_ERROR; } /* esmtp addresses and smtp addresses */ static struct esmtp_address * esmtp_address_new(char * addr, int notify, char * orcpt) { struct esmtp_address * esmtpa; diff --git a/kmicromail/libmailwrapper/abstractmail.cpp b/kmicromail/libmailwrapper/abstractmail.cpp index 3998abd..3b0ca1f 100644 --- a/kmicromail/libmailwrapper/abstractmail.cpp +++ b/kmicromail/libmailwrapper/abstractmail.cpp @@ -1,187 +1,237 @@ // CHANGED 2004-09-31 Lutz Rogowski #include "abstractmail.h" #include "imapwrapper.h" #include "pop3wrapper.h" #include "nntpwrapper.h" #include "mhwrapper.h" #include "mailtypes.h" +#include <qprogressbar.h> +#include <qapplication.h> #include <kdecore/kstandarddirs.h> #include <qfile.h> #include <qtextstream.h> #include <stdlib.h> #include <libetpan/mailmime_content.h> #include <libetpan/mailmime.h> using namespace Opie::Core; AbstractMail* AbstractMail::getWrapper(IMAPaccount *a) { return new IMAPwrapper(a); } AbstractMail* AbstractMail::getWrapper(POP3account *a) { return new POP3wrapper(a); } AbstractMail* AbstractMail::getWrapper(NNTPaccount *a) { return new NNTPwrapper(a); } AbstractMail* AbstractMail::getWrapper(const QString&a,const QString&name) { return new MHwrapper(a,name); } AbstractMail* AbstractMail::getWrapper(Account*a) { if (!a) return 0; switch (a->getType()) { case MAILLIB::A_IMAP: return new IMAPwrapper((IMAPaccount*)a); break; case MAILLIB::A_POP3: return new POP3wrapper((POP3account*)a); break; case MAILLIB::A_NNTP: return new NNTPwrapper((NNTPaccount*)a); break; default: return 0; } } encodedString* AbstractMail::decode_String(const encodedString*text,const QString&enc) { // odebug << "Decode string start" << oendl; char*result_text; size_t index = 0; /* reset for recursive use! */ size_t target_length = 0; result_text = 0; int mimetype = MAILMIME_MECHANISM_7BIT; if (enc.lower()=="quoted-printable") { mimetype = MAILMIME_MECHANISM_QUOTED_PRINTABLE; } else if (enc.lower()=="base64") { mimetype = MAILMIME_MECHANISM_BASE64; } else if (enc.lower()=="8bit") { mimetype = MAILMIME_MECHANISM_8BIT; } else if (enc.lower()=="binary") { mimetype = MAILMIME_MECHANISM_BINARY; } int err = mailmime_part_parse(text->Content(),text->Length(),&index,mimetype, &result_text,&target_length); encodedString* result = new encodedString(); if (err == MAILIMF_NO_ERROR) { result->setContent(result_text,target_length); } //odebug << "Decode string finished" << oendl; return result; } QString AbstractMail::convert_String(const char*text) { //size_t index = 0; char*res = 0; int err = MAILIMF_NO_ERROR; QString result(text); /* due a bug in libetpan it isn't usable this moment */ /* int err = mailmime_encoded_phrase_parse("iso-8859-1", text, strlen(text),&index, "iso-8859-1",&res);*/ //odebug << "Input: " << text << "" << oendl; if (err == MAILIMF_NO_ERROR && res && strlen(res)) { // result = QString(res); // odebug << "Res: " << res << ", length: " << strlen(res) << "" << oendl; } if (res) free(res); return result; } /* cp & paste from launcher */ QString AbstractMail::gen_attachment_id() { QFile file( "/proc/sys/kernel/random/uuid" ); if (!file.open(IO_ReadOnly ) ) return QString::null; QTextStream stream(&file); return "{" + stream.read().stripWhiteSpace() + "}"; } int AbstractMail::createMbox(const QString&,const FolderP&,const QString& ,bool) { return 0; } QString AbstractMail::defaultLocalfolder() { // QString f = getenv( "HOME" ); QString f = locateLocal( "data", "kmicromail/localmail"); // f += "/Applications/opiemail/localmail"; return f; } QString AbstractMail::draftFolder() { return QString("Drafts"); } /* temporary - will be removed when implemented in all classes */ void AbstractMail::deleteMails(const QString &,const QValueList<Opie::Core::OSmartPointer<RecMail> > &) { } void AbstractMail::deleteMailList(const QValueList<RecMailP>&target) { - qDebug("AbstractMail::deleteMailList:: Please reimplement! "); - + //qDebug("AbstractMail::deleteMailList:: Please reimplement! "); + // this is currently re-implemented in pop3wrapper and imapwrapper + int iii = 0; + int count = target.count(); + QProgressBar bar( count,0 ); + bar.setCaption (("Removing mails - close to abort!") ); + int w = 300; + if ( QApplication::desktop()->width() < 320 ) + w = 220; + int h = bar.sizeHint().height() ; + int dw = QApplication::desktop()->width(); + int dh = QApplication::desktop()->height(); + bar.setGeometry( (dw-w)/2, (dh - h )/2 ,w,h ); + bar.show(); + int modulo = (count/10)+1; + int incCounter = 0; + while (iii < count ) { + if ( ! bar.isVisible() ) + return ; + if ( incCounter % modulo == 0 ) + bar.setProgress( incCounter ); + ++incCounter; + qApp->processEvents(); + RecMailP mail = (*target.at( iii )); + deleteMail(mail); + ++iii; + } } void AbstractMail::mvcpAllMails(const FolderP&fromFolder, const QString&targetFolder,AbstractMail*targetWrapper,bool moveit, int maxSizeInKb) { QValueList<RecMailP> t; listMessages(fromFolder->getName(),t, maxSizeInKb); mvcpMailList( t,targetFolder,targetWrapper,moveit); } void AbstractMail::mvcpMailList(const QValueList<RecMailP>& t, const QString&targetFolder,AbstractMail*targetWrapper,bool moveit) { - encodedString*st = 0; int iii = 0; int count = t.count(); + if ( count == 0 ) + return; + + QProgressBar bar( count,0 ); + bar.setCaption (("Copying mails - close to abort!") ); + int w = 300; + if ( QApplication::desktop()->width() < 320 ) + w = 220; + int h = bar.sizeHint().height() ; + int dw = QApplication::desktop()->width(); + int dh = QApplication::desktop()->height(); + bar.setGeometry( (dw-w)/2, (dh - h )/2 ,w,h ); + bar.show(); + int modulo = (count/10)+1; + int incCounter = 0; while (iii < count ) { + if ( ! bar.isVisible() ) + return ; + if ( incCounter % modulo == 0 ) + bar.setProgress( incCounter ); + ++incCounter; + bar.raise(); + qApp->processEvents(); + //qDebug("copy "); RecMailP r = (*t.at( iii )); st = fetchRawBody(r); if (st) { targetWrapper->storeMessage(st->Content(),st->Length(),targetFolder); delete st; } ++iii; } + bar.hide(); if (moveit) { deleteMailList( t ); //deleteAllMail(fromFolder); } } void AbstractMail::mvcpMail(const RecMailP&mail,const QString&targetFolder,AbstractMail*targetWrapper,bool moveit) { encodedString*st = 0; st = fetchRawBody(mail); if (st) { targetWrapper->storeMessage(st->Content(),st->Length(),targetFolder); delete st; } if (moveit) { deleteMail(mail); } } diff --git a/kmicromail/libmailwrapper/imapwrapper.cpp b/kmicromail/libmailwrapper/imapwrapper.cpp index bb8bbfc..11d3343 100644 --- a/kmicromail/libmailwrapper/imapwrapper.cpp +++ b/kmicromail/libmailwrapper/imapwrapper.cpp @@ -1,104 +1,105 @@ // CHANGED 2004-09-31 Lutz Rogowski #include <stdlib.h> #include <libetpan/libetpan.h> #include <qpe/global.h> #include <qapplication.h> #include "imapwrapper.h" #include "mailtypes.h" #include "logindialog.h" +#include <qprogressbar.h> using namespace Opie::Core; IMAPwrapper::IMAPwrapper( IMAPaccount *a ) : AbstractMail() { account = a; m_imap = 0; m_Lastmbox = ""; } IMAPwrapper::~IMAPwrapper() { logout(); } /* to avoid to often select statements in loops etc. we trust that we are logged in and connection is established!*/ int IMAPwrapper::selectMbox(const QString&mbox) { if (mbox == m_Lastmbox) { return MAILIMAP_NO_ERROR; } int err = mailimap_select( m_imap, (char*)mbox.latin1()); if ( err != MAILIMAP_NO_ERROR ) { m_Lastmbox = ""; return err; } m_Lastmbox = mbox; return err; } void IMAPwrapper::imap_progress( size_t current, size_t maximum ) { qApp->processEvents(); qDebug("imap progress %d of %d ",current,maximum ); } bool IMAPwrapper::start_tls(bool force_tls) { int err; bool try_tls; mailimap_capability_data * cap_data = 0; err = mailimap_capability(m_imap,&cap_data); if (err != MAILIMAP_NO_ERROR) { Global::statusMessage("error getting capabilities!"); return false; } clistiter * cur; for(cur = clist_begin(cap_data->cap_list) ; cur != NULL;cur = clist_next(cur)) { struct mailimap_capability * cap; cap = (struct mailimap_capability *)clist_content(cur); if (cap->cap_type == MAILIMAP_CAPABILITY_NAME) { if (strcasecmp(cap->cap_data.cap_name, "STARTTLS") == 0) { try_tls = true; break; } } } if (cap_data) { mailimap_capability_data_free(cap_data); } if (try_tls) { err = mailimap_starttls(m_imap); if (err != MAILIMAP_NO_ERROR && force_tls) { Global::statusMessage(tr("Server has no TLS support!")); try_tls = false; } else { mailstream_low * low; mailstream_low * new_low; low = mailstream_get_low(m_imap->imap_stream); if (!low) { try_tls = false; } else { int fd = mailstream_low_get_fd(low); if (fd > -1 && (new_low = mailstream_low_ssl_open(fd))!=0) { mailstream_low_free(low); mailstream_set_low(m_imap->imap_stream, new_low); } else { try_tls = false; } } } } return try_tls; } void IMAPwrapper::login() { const char *server, *user, *pass; uint16_t port; int err = MAILIMAP_NO_ERROR; if (account->getOffline()) return; /* we are connected this moment */ /* TODO: setup a timer holding the line or if connection closed - delete the value */ @@ -778,267 +779,296 @@ void IMAPwrapper::fillMultiPart(RecPartP&target_part,mailimap_body_type_mpart*wh target_part->addParameter(QString(param->pa_name).lower(),QString(param->pa_value)); } } } } void IMAPwrapper::fillSingleBasicPart(RecPartP&target_part,mailimap_body_type_basic*which) { if (!which) { return; } QString type,sub; switch (which->bd_media_basic->med_type) { case MAILIMAP_MEDIA_BASIC_APPLICATION: type = "application"; break; case MAILIMAP_MEDIA_BASIC_AUDIO: type = "audio"; break; case MAILIMAP_MEDIA_BASIC_IMAGE: type = "image"; break; case MAILIMAP_MEDIA_BASIC_MESSAGE: type = "message"; break; case MAILIMAP_MEDIA_BASIC_VIDEO: type = "video"; break; case MAILIMAP_MEDIA_BASIC_OTHER: default: if (which->bd_media_basic->med_basic_type) { type = which->bd_media_basic->med_basic_type; } else { type = ""; } break; } if (which->bd_media_basic->med_subtype) { sub = which->bd_media_basic->med_subtype; } else { sub = ""; } // odebug << "Type = " << type.latin1() << "/" << sub.latin1() << "" << oendl; target_part->setType(type.lower()); target_part->setSubtype(sub.lower()); fillBodyFields(target_part,which->bd_fields); } void IMAPwrapper::fillBodyFields(RecPartP&target_part,mailimap_body_fields*which) { if (!which) return; if (which->bd_parameter && which->bd_parameter->pa_list && which->bd_parameter->pa_list->count>0) { clistcell*cur; mailimap_single_body_fld_param*param=0; for (cur = clist_begin(which->bd_parameter->pa_list);cur!=NULL;cur=clist_next(cur)) { param = (mailimap_single_body_fld_param*)cur->data; if (param) { target_part->addParameter(QString(param->pa_name).lower(),QString(param->pa_value)); } } } mailimap_body_fld_enc*enc = which->bd_encoding; QString encoding(""); switch (enc->enc_type) { case MAILIMAP_BODY_FLD_ENC_7BIT: encoding = "7bit"; break; case MAILIMAP_BODY_FLD_ENC_8BIT: encoding = "8bit"; break; case MAILIMAP_BODY_FLD_ENC_BINARY: encoding="binary"; break; case MAILIMAP_BODY_FLD_ENC_BASE64: encoding="base64"; break; case MAILIMAP_BODY_FLD_ENC_QUOTED_PRINTABLE: encoding="quoted-printable"; break; case MAILIMAP_BODY_FLD_ENC_OTHER: default: if (enc->enc_value) { char*t=enc->enc_value; encoding=QString(enc->enc_value); enc->enc_value=0L; free(t); } } if (which->bd_description) { target_part->setDescription(QString(which->bd_description)); } target_part->setEncoding(encoding); target_part->setSize(which->bd_size); } void IMAPwrapper::deleteMailList(const QValueList<RecMailP>&target) { + //#if 0 mailimap_flag_list*flist; mailimap_set *set; mailimap_store_att_flags * store_flags; int err; login(); + //#endif if (!m_imap) { return; } int iii = 0; int count = target.count(); - qDebug("imap remove count %d ", count); + // qDebug("imap remove count %d ", count); + + QProgressBar bar( count,0 ); + bar.setCaption (("Removing mails - close to abort!") ); + int w = 300; + if ( QApplication::desktop()->width() < 320 ) + w = 220; + int h = bar.sizeHint().height() ; + int dw = QApplication::desktop()->width(); + int dh = QApplication::desktop()->height(); + bar.setGeometry( (dw-w)/2, (dh - h )/2 ,w,h ); + bar.show(); + int modulo = (count/10)+1; + int incCounter = 0; + while (iii < count ) { - qDebug("IMAP remove %d ", iii); + if ( ! bar.isVisible() ) + return ; + if ( incCounter % modulo == 0 ) + bar.setProgress( incCounter ); + ++incCounter; + qApp->processEvents(); RecMailP mail = (*target.at( iii )); - + //#if 0 + //qDebug("IMAP remove %d %d ", iii, mail->getNumber() ); err = selectMbox(mail->getMbox()); if ( err != MAILIMAP_NO_ERROR ) { return; } flist = mailimap_flag_list_new_empty(); mailimap_flag_list_add(flist,mailimap_flag_new_deleted()); store_flags = mailimap_store_att_flags_new_set_flags(flist); set = mailimap_set_new_single(mail->getNumber()); err = mailimap_store(m_imap,set,store_flags); mailimap_set_free( set ); mailimap_store_att_flags_free(store_flags); if (err != MAILIMAP_NO_ERROR) { // odebug << "error deleting mail: " << m_imap->imap_response << "" << oendl; return; } // odebug << "deleting mail: " << m_imap->imap_response << "" << oendl; /* should we realy do that at this moment? */ + // err = mailimap_expunge(m_imap); + //if (err != MAILIMAP_NO_ERROR) { + // Global::statusMessage(tr("Error deleting mails: %s").arg(m_imap->imap_response)); + // } + //#endif + //deleteMail( mail); + ++iii; + } + //qDebug("Deleting imap mails... "); err = mailimap_expunge(m_imap); if (err != MAILIMAP_NO_ERROR) { - Global::statusMessage(tr("error deleting mail: %s").arg(m_imap->imap_response)); - } - ++iii; + Global::statusMessage(tr("Error deleting mails: %s").arg(m_imap->imap_response)); } } void IMAPwrapper::deleteMail(const RecMailP&mail) { mailimap_flag_list*flist; mailimap_set *set; mailimap_store_att_flags * store_flags; int err; login(); if (!m_imap) { return; } err = selectMbox(mail->getMbox()); if ( err != MAILIMAP_NO_ERROR ) { return; } flist = mailimap_flag_list_new_empty(); mailimap_flag_list_add(flist,mailimap_flag_new_deleted()); store_flags = mailimap_store_att_flags_new_set_flags(flist); set = mailimap_set_new_single(mail->getNumber()); err = mailimap_store(m_imap,set,store_flags); mailimap_set_free( set ); mailimap_store_att_flags_free(store_flags); if (err != MAILIMAP_NO_ERROR) { // odebug << "error deleting mail: " << m_imap->imap_response << "" << oendl; return; } // odebug << "deleting mail: " << m_imap->imap_response << "" << oendl; /* should we realy do that at this moment? */ err = mailimap_expunge(m_imap); if (err != MAILIMAP_NO_ERROR) { Global::statusMessage(tr("error deleting mail: %s").arg(m_imap->imap_response)); } - qDebug("IMAPwrapper::deleteMail "); + //qDebug("IMAPwrapper::deleteMail 2"); } void IMAPwrapper::answeredMail(const RecMailP&mail) { mailimap_flag_list*flist; mailimap_set *set; mailimap_store_att_flags * store_flags; int err; login(); if (!m_imap) { return; } err = selectMbox(mail->getMbox()); if ( err != MAILIMAP_NO_ERROR ) { return; } flist = mailimap_flag_list_new_empty(); mailimap_flag_list_add(flist,mailimap_flag_new_answered()); store_flags = mailimap_store_att_flags_new_add_flags(flist); set = mailimap_set_new_single(mail->getNumber()); err = mailimap_store(m_imap,set,store_flags); mailimap_set_free( set ); mailimap_store_att_flags_free(store_flags); if (err != MAILIMAP_NO_ERROR) { // odebug << "error marking mail: " << m_imap->imap_response << "" << oendl; return; } } QString IMAPwrapper::fetchTextPart(const RecMailP&mail,const QValueList<int>&path,bool internal_call,const QString&enc) { QString body(""); encodedString*res = fetchRawPart(mail,path,internal_call); encodedString*r = decode_String(res,enc); delete res; if (r) { if (r->Length()>0) { body = r->Content(); } delete r; } return body; } QString IMAPwrapper::fetchTextPart(const RecMailP&mail,const RecPartP&part) { return fetchTextPart(mail,part->Positionlist(),false,part->Encoding()); } encodedString* IMAPwrapper::fetchDecodedPart(const RecMailP&mail,const RecPartP&part) { encodedString*res = fetchRawPart(mail,part->Positionlist(),false); encodedString*r = decode_String(res,part->Encoding()); delete res; return r; } encodedString* IMAPwrapper::fetchRawPart(const RecMailP&mail,const RecPartP&part) { return fetchRawPart(mail,part->Positionlist(),false); } int IMAPwrapper::deleteAllMail(const FolderP&folder) { login(); if (!m_imap) { return 0; } mailimap_flag_list*flist; mailimap_set *set; mailimap_store_att_flags * store_flags; int err = selectMbox(folder->getName()); if ( err != MAILIMAP_NO_ERROR ) { return 0; } int last = m_imap->imap_selection_info->sel_exists; if (last == 0) { Global::statusMessage(tr("Mailbox has no mails!")); return 0; } flist = mailimap_flag_list_new_empty(); mailimap_flag_list_add(flist,mailimap_flag_new_deleted()); store_flags = mailimap_store_att_flags_new_set_flags(flist); set = mailimap_set_new_interval( 1, last ); err = mailimap_store(m_imap,set,store_flags); mailimap_set_free( set ); mailimap_store_att_flags_free(store_flags); if (err != MAILIMAP_NO_ERROR) { Global::statusMessage(tr("error deleting mail: %s").arg(m_imap->imap_response)); return 0; } // odebug << "deleting mail: " << m_imap->imap_response << "" << oendl; /* should we realy do that at this moment? */ @@ -1096,135 +1126,135 @@ int IMAPwrapper::deleteMbox(const FolderP&folder) void IMAPwrapper::statusFolder(folderStat&target_stat,const QString & mailbox) { mailimap_status_att_list * att_list =0; mailimap_mailbox_data_status * status=0; clistiter * cur = 0; int r = 0; target_stat.message_count = 0; target_stat.message_unseen = 0; target_stat.message_recent = 0; login(); if (!m_imap) { return; } att_list = mailimap_status_att_list_new_empty(); if (!att_list) return; r = mailimap_status_att_list_add(att_list, MAILIMAP_STATUS_ATT_MESSAGES); r = mailimap_status_att_list_add(att_list, MAILIMAP_STATUS_ATT_RECENT); r = mailimap_status_att_list_add(att_list, MAILIMAP_STATUS_ATT_UNSEEN); r = mailimap_status(m_imap, mailbox.latin1(), att_list, &status); if (r==MAILIMAP_NO_ERROR&&status->st_info_list!=0) { for (cur = clist_begin(status->st_info_list); cur != NULL ; cur = clist_next(cur)) { mailimap_status_info * status_info; status_info = (mailimap_status_info *)clist_content(cur); switch (status_info->st_att) { case MAILIMAP_STATUS_ATT_MESSAGES: target_stat.message_count = status_info->st_value; break; case MAILIMAP_STATUS_ATT_RECENT: target_stat.message_recent = status_info->st_value; break; case MAILIMAP_STATUS_ATT_UNSEEN: target_stat.message_unseen = status_info->st_value; break; } } } else { // odebug << "Error retrieving status" << oendl; } if (status) mailimap_mailbox_data_status_free(status); if (att_list) mailimap_status_att_list_free(att_list); } void IMAPwrapper::storeMessage(const char*msg,size_t length, const QString&folder) { login(); if (!m_imap) return; if (!msg) return; int r = mailimap_append(m_imap,(char*)folder.latin1(),0,0,msg,length); if (r != MAILIMAP_NO_ERROR) { Global::statusMessage("Error storing mail!"); } } MAILLIB::ATYPE IMAPwrapper::getType()const { return account->getType(); } const QString&IMAPwrapper::getName()const { // odebug << "Get name: " << account->getAccountName().latin1() << "" << oendl; return account->getAccountName(); } encodedString* IMAPwrapper::fetchRawBody(const RecMailP&mail) { // dummy QValueList<int> path; return fetchRawPart(mail,path,false); } void IMAPwrapper::mvcpAllMails(const FolderP&fromFolder, const QString&targetFolder,AbstractMail*targetWrapper,bool moveit, int maxSizeInKb) { if (targetWrapper != this || maxSizeInKb > 0 ) { AbstractMail::mvcpAllMails(fromFolder,targetFolder,targetWrapper,moveit, maxSizeInKb); qDebug("IMAPwrapper::mvcpAllMails::Using generic"); // odebug << "Using generic" << oendl; return; } mailimap_set *set = 0; login(); if (!m_imap) { return; } int err = selectMbox(fromFolder->getName()); if ( err != MAILIMAP_NO_ERROR ) { return; } int last = m_imap->imap_selection_info->sel_exists; set = mailimap_set_new_interval( 1, last ); err = mailimap_copy(m_imap,set,targetFolder.latin1()); mailimap_set_free( set ); if ( err != MAILIMAP_NO_ERROR ) { - QString error_msg = tr("error copy mails: %1").arg(m_imap->imap_response); + QString error_msg = tr("Error copy mails: %1").arg(m_imap->imap_response); Global::statusMessage(error_msg); // odebug << error_msg << oendl; return; } if (moveit) { deleteAllMail(fromFolder); } } void IMAPwrapper::mvcpMail(const RecMailP&mail,const QString&targetFolder,AbstractMail*targetWrapper,bool moveit) { if (targetWrapper != this) { // odebug << "Using generic" << oendl; AbstractMail::mvcpMail(mail,targetFolder,targetWrapper,moveit); return; } mailimap_set *set = 0; login(); if (!m_imap) { return; } int err = selectMbox(mail->getMbox()); if ( err != MAILIMAP_NO_ERROR ) { return; } set = mailimap_set_new_single(mail->getNumber()); err = mailimap_copy(m_imap,set,targetFolder.latin1()); mailimap_set_free( set ); if ( err != MAILIMAP_NO_ERROR ) { QString error_msg = tr("error copy mail: %1").arg(m_imap->imap_response); Global::statusMessage(error_msg); // odebug << error_msg << oendl; return; } if (moveit) { deleteMail(mail); } } diff --git a/kmicromail/libmailwrapper/pop3wrapper.cpp b/kmicromail/libmailwrapper/pop3wrapper.cpp index 7a84b30..0e6612c 100644 --- a/kmicromail/libmailwrapper/pop3wrapper.cpp +++ b/kmicromail/libmailwrapper/pop3wrapper.cpp @@ -1,282 +1,321 @@ // CHANGED 2004-09-31 Lutz Rogowski #include <stdlib.h> #include "pop3wrapper.h" #include "mailtypes.h" #include "logindialog.h" #include <libetpan/libetpan.h> #include <qpe/global.h> #include <qfile.h> +#include <qprogressbar.h> +#include <qapplication.h> /* we don't fetch messages larger than 5 MB */ #define HARD_MSG_SIZE_LIMIT 5242880 using namespace Opie::Core; POP3wrapper::POP3wrapper( POP3account *a ) : Genericwrapper() { account = a; m_pop3 = NULL; msgTempName = a->getFileName()+"_msg_cache"; last_msg_id = 0; } POP3wrapper::~POP3wrapper() { logout(); QFile msg_cache(msgTempName); if (msg_cache.exists()) { msg_cache.remove(); } } void POP3wrapper::pop3_progress( size_t current, size_t maximum ) { ; // odebug << "POP3: " << current << " of " << maximum << "" << oendl; } RecBodyP POP3wrapper::fetchBody( const RecMailP &mail ) { int err = MAILPOP3_NO_ERROR; char *message = 0; size_t length = 0; RecBodyP body = new RecBody(); login(); if ( !m_pop3 ) { return body; } mailmessage * mailmsg; if (mail->Msgsize()>HARD_MSG_SIZE_LIMIT) { ; // odebug << "Message to large: " << mail->Msgsize() << "" << oendl; return body; } QFile msg_cache(msgTempName); cleanMimeCache(); if (mail->getNumber()!=last_msg_id) { if (msg_cache.exists()) { msg_cache.remove(); } msg_cache.open(IO_ReadWrite|IO_Truncate); last_msg_id = mail->getNumber(); err = mailsession_get_message(m_pop3->sto_session, mail->getNumber(), &mailmsg); err = mailmessage_fetch(mailmsg,&message,&length); msg_cache.writeBlock(message,length); } else { QString msg=""; msg_cache.open(IO_ReadOnly); message = new char[4096]; memset(message,0,4096); while (msg_cache.readBlock(message,4095)>0) { msg+=message; memset(message,0,4096); } delete message; message = (char*)malloc(msg.length()+1*sizeof(char)); memset(message,0,msg.length()+1); memcpy(message,msg.latin1(),msg.length()); /* transform to libetpan stuff */ mailmsg = mailmessage_new(); mailmessage_init(mailmsg, NULL, data_message_driver, 0, strlen(message)); generic_message_t * msg_data; msg_data = (generic_message_t *)mailmsg->msg_data; msg_data->msg_fetched = 1; msg_data->msg_message = message; msg_data->msg_length = strlen(message); } body = parseMail(mailmsg); /* clean up */ if (mailmsg) mailmessage_free(mailmsg); if (message) free(message); return body; } void POP3wrapper::listMessages(const QString &, QValueList<Opie::Core::OSmartPointer<RecMail> > &target, int maxSizeInKb ) { login(); if (!m_pop3) return; uint32_t res_messages,res_recent,res_unseen; mailsession_status_folder(m_pop3->sto_session,"INBOX",&res_messages,&res_recent,&res_unseen); parseList(target,m_pop3->sto_session,"INBOX", false, maxSizeInKb); Global::statusMessage( tr("Mailbox contains %1 mail(s)").arg(res_messages)); } void POP3wrapper::login() { if (account->getOffline()) return; /* we'll hold the line */ if ( m_pop3 != NULL ) return; const char *server, *user, *pass; uint16_t port; int err = MAILPOP3_NO_ERROR; server = account->getServer().latin1(); port = account->getPort().toUInt(); if ( account->getUser().isEmpty() || account->getPassword().isEmpty() ) { LoginDialog login( account->getUser(), account->getPassword(), NULL, 0, true ); login.show(); if ( QDialog::Accepted == login.exec() ) { // ok user = login.getUser().latin1(); pass = login.getPassword().latin1(); } else { // cancel ; // odebug << "POP3: Login canceled" << oendl; return; } } else { user = account->getUser().latin1(); pass = account->getPassword().latin1(); } // bool ssl = account->getSSL(); m_pop3=mailstorage_new(NULL); int conntypeset = account->ConnectionType(); int conntype = 0; if ( conntypeset == 3 ) { conntype = CONNECTION_TYPE_COMMAND; } else if ( conntypeset == 2 ) { conntype = CONNECTION_TYPE_TLS; } else if ( conntypeset == 1 ) { conntype = CONNECTION_TYPE_STARTTLS; } else if ( conntypeset == 0 ) { conntype = CONNECTION_TYPE_TRY_STARTTLS; } //(ssl?CONNECTION_TYPE_TLS:CONNECTION_TYPE_PLAIN); pop3_mailstorage_init(m_pop3,(char*)server, port, NULL, conntype, POP3_AUTH_TYPE_PLAIN, (char*)user,(char*)pass,0,0,0); err = mailstorage_connect(m_pop3); if (err != MAIL_NO_ERROR) { ; // odebug << QString( "FEHLERNUMMER %1" ).arg( err ) << oendl; Global::statusMessage(tr("Error initializing folder")); mailstorage_free(m_pop3); m_pop3 = 0; } else { mailsession * session = m_pop3->sto_session; mailpop3 * mail = ( ( pop3_session_state_data * )session->sess_data )->pop3_session; if (mail) { mail->pop3_progr_fun = &pop3_progress; } } } void POP3wrapper::logout() { if ( m_pop3 == NULL ) return; mailstorage_free(m_pop3); m_pop3 = 0; } QValueList<Opie::Core::OSmartPointer<Folder> >* POP3wrapper::listFolders() { QValueList<Opie::Core::OSmartPointer<Folder> >* folders = new QValueList<FolderP>(); FolderP inb=new Folder("INBOX","/"); folders->append(inb); return folders; } -void POP3wrapper::deleteMailList(QValueList<RecMailP>&target) +void POP3wrapper::deleteMailList(const QValueList<RecMailP>&target) { login(); if (!m_pop3) return; int iii = 0; int count = target.count(); + QProgressBar bar( count,0 ); + bar.setCaption (("Removing mails - close to abort!") ); + int w = 300; + if ( QApplication::desktop()->width() < 320 ) + w = 220; + int h = bar.sizeHint().height() ; + int dw = QApplication::desktop()->width(); + int dh = QApplication::desktop()->height(); + bar.setGeometry( (dw-w)/2, (dh - h )/2 ,w,h ); + bar.show(); + int modulo = (count/10)+1; + int incCounter = 0; while (iii < count ) { + if ( ! bar.isVisible() ) + return ; + if ( incCounter % modulo == 0 ) + bar.setProgress( incCounter ); + ++incCounter; + qApp->processEvents(); + //qDebug("delete "); RecMailP mail = (*target.at( iii )); int err = mailsession_remove_message(m_pop3->sto_session,mail->getNumber()); if (err != MAIL_NO_ERROR) { - Global::statusMessage(tr("error deleting mail")); + Global::statusMessage(tr("Error deleting mail")); } ++iii; } } void POP3wrapper::deleteMail(const RecMailP&mail) { login(); if (!m_pop3) return; int err = mailsession_remove_message(m_pop3->sto_session,mail->getNumber()); if (err != MAIL_NO_ERROR) { Global::statusMessage(tr("error deleting mail")); } } void POP3wrapper::answeredMail(const RecMailP&) {} int POP3wrapper::deleteAllMail(const FolderP&) { login(); if (!m_pop3) return 0; int res = 1; uint32_t result = 0; int err = mailsession_messages_number(m_pop3->sto_session,NULL,&result); if (err != MAIL_NO_ERROR) { Global::statusMessage(tr("Error getting folder info")); return 0; } + QProgressBar bar( result,0 ); + bar.setCaption (("Deleting mails - close to abort!") ); + int w = 300; + if ( QApplication::desktop()->width() < 320 ) + w = 220; + int h = bar.sizeHint().height() ; + int dw = QApplication::desktop()->width(); + int dh = QApplication::desktop()->height(); + bar.setGeometry( (dw-w)/2, (dh - h )/2 ,w,h ); + bar.show(); + int modulo = (result/10)+1; + int incCounter = 0; for (unsigned int i = 0; i < result; ++i) { + if ( ! bar.isVisible() ) + return 0; + if ( incCounter % modulo == 0 ) + bar.setProgress( incCounter ); + ++incCounter; + qApp->processEvents(); err = mailsession_remove_message(m_pop3->sto_session,i+1); if (err != MAIL_NO_ERROR) { Global::statusMessage(tr("Error deleting mail %1").arg(i+1)); res=0; } break; } return res; } void POP3wrapper::statusFolder(folderStat&target_stat,const QString&) { login(); target_stat.message_count = 0; target_stat.message_unseen = 0; target_stat.message_recent = 0; if (!m_pop3) return; int r = mailsession_status_folder(m_pop3->sto_session,0,&target_stat.message_count, &target_stat.message_recent,&target_stat.message_unseen); if (r != MAIL_NO_ERROR) { ; // odebug << "error getting folter status." << oendl; } } encodedString* POP3wrapper::fetchRawBody(const RecMailP&mail) { char*target=0; size_t length=0; encodedString*res = 0; mailmessage * mailmsg = 0; int err = mailsession_get_message(m_pop3->sto_session, mail->getNumber(), &mailmsg); err = mailmessage_fetch(mailmsg,&target,&length); if (mailmsg) mailmessage_free(mailmsg); if (target) { res = new encodedString(target,length); } return res; } MAILLIB::ATYPE POP3wrapper::getType()const { return account->getType(); } const QString&POP3wrapper::getName()const{ return account->getAccountName(); } diff --git a/kmicromail/libmailwrapper/pop3wrapper.h b/kmicromail/libmailwrapper/pop3wrapper.h index ee754a4..7c70942 100644 --- a/kmicromail/libmailwrapper/pop3wrapper.h +++ b/kmicromail/libmailwrapper/pop3wrapper.h @@ -1,44 +1,44 @@ // CHANGED 2004-09-31 Lutz Rogowski #ifndef __POP3WRAPPER #define __POP3WRAPPER #include "mailwrapper.h" #include "genericwrapper.h" #include <qstring.h> class encodedString; struct mailstorage; struct mailfolder; class POP3wrapper : public Genericwrapper { Q_OBJECT public: POP3wrapper( POP3account *a ); virtual ~POP3wrapper(); /* mailbox will be ignored */ virtual void listMessages(const QString & mailbox, QValueList<Opie::Core::OSmartPointer<RecMail> > &target, int maxSizeInKb = 0 ); virtual QValueList<Opie::Core::OSmartPointer<Folder> >* listFolders(); /* mailbox will be ignored */ virtual void statusFolder(folderStat&target_stat,const QString & mailbox="INBOX"); virtual void deleteMail(const RecMailP&mail); + virtual void deleteMailList(const QValueList<RecMailP>&target); virtual void answeredMail(const RecMailP&mail); - virtual void deleteMailList(QValueList<RecMailP>&target); virtual int deleteAllMail(const Opie::Core::OSmartPointer<Folder>&); virtual RecBodyP fetchBody( const RecMailP &mail ); virtual encodedString* fetchRawBody(const RecMailP&mail); virtual void logout(); virtual MAILLIB::ATYPE getType()const; virtual const QString&getName()const; static void pop3_progress( size_t current, size_t maximum ); protected: void login(); POP3account *account; mailstorage*m_pop3; }; #endif diff --git a/kmicromail/opiemail.cpp b/kmicromail/opiemail.cpp index 3fbdcec..251f15a 100644 --- a/kmicromail/opiemail.cpp +++ b/kmicromail/opiemail.cpp @@ -1,117 +1,117 @@ // CHANGED 2004-09-31 Lutz Rogowski // CHANGED 2004-08-06 Lutz Rogowski #include "settingsdialog.h" #include "opiemail.h" #include "editaccounts.h" #include "composemail.h" #include "mailistviewitem.h" #include "viewmail.h" #include "selectstore.h" #include "selectsmtp.h" #include <qmessagebox.h> #include <qpe/qpeapplication.h> #include <libmailwrapper/smtpwrapper.h> #include <libmailwrapper/mailtypes.h> #include <libmailwrapper/abstractmail.h> /* OPIE */ //#include <qpe/resource.h> -#include <qpe/qpeapplication.h> +//#include <qpe/qpeapplication.h> /* QT */ using namespace Opie::Core; OpieMail::OpieMail( QWidget *parent, const char *name, WFlags flags ) : MainWindow( parent, name) //, WStyle_ContextHelp ) { settings = new Settings(); folderView->populate( settings->getAccounts() ); } OpieMail::~OpieMail() { if (settings) delete settings; } void OpieMail::appMessage(const QCString &msg, const QByteArray &data) { } #include <stdlib.h> void OpieMail::message(const QCString &msg, const QByteArray &data) { // copied from old mail2 static int ii = 0; // block second call if ( ii < 2 ) { ++ii; if ( ii > 1 ) { qDebug("qcop call blocked "); return; } } //qDebug("KM:appMessage %d *%s* %x", ii, msg.data(), this); if (msg == "writeMail(QString,QString)") { QDataStream stream(data,IO_ReadOnly); QString name, email; stream >> name >> email; // removing the whitespaces at beginning and end is needed! slotwriteMail(name.stripWhiteSpace(),email.stripWhiteSpace()); } else if (msg == "newMail()") { slotComposeMail(); } else if (msg == "newMail(QString)") { QDataStream stream(data,IO_ReadOnly); QString nameemail; stream >> nameemail; // the format is // NAME <EMAIL>:SUBJECT //qDebug("message %s ", nameemail.latin1()); slotwriteMail2( nameemail ); } } void OpieMail::slotwriteMail2(const QString& namemail ) { // qDebug("OpieMail::slotwriteMail2 "); qApp->processEvents(); ComposeMail compose( settings, this, 0, true ); if ( !namemail.isEmpty() ) { QString to = namemail; if ( namemail.find( " <") > 1 ) { to = "\"" +to.replace( QRegExp( " <"), "\" <") ; } else if ( namemail.find( "<") > 1 ) { to = "\"" +to.replace( QRegExp( "<"), "\" <") ; } int sub = to.find( ">:"); if ( sub > 0 ) { compose.setTo( to.left(sub+1) ); compose.setSubject( to.mid(sub+2) ); } else compose.setTo( to ); } compose.slotAdjustColumns(); compose.showMaximized(); compose.exec(); //qDebug("retttich "); } void OpieMail::slotwriteMail(const QString&name,const QString&email) { // qDebug("OpieMail::slotwriteMail "); ComposeMail compose( settings, this, 0, true , WStyle_ContextHelp ); if (!email.isEmpty()) { if (!name.isEmpty()) { compose.setTo("\"" + name + "\"" + " " + "<"+ email + ">"); @@ -144,265 +144,278 @@ void OpieMail::slotSendQueued() { if ( it->getType() == MAILLIB::A_SMTP ) { smtp = static_cast<SMTPaccount *>(it); smtpList.append(smtp); } } if (smtpList.count()==0) { QMessageBox::information(0,tr("Info"),tr("Define a smtp account first!\n")); return; } if (smtpList.count()==1) { smtp = smtpList.at(0); } else { smtp = 0; selectsmtp selsmtp; selsmtp.setSelectionlist(&smtpList); selsmtp.showMaximized(); if ( selsmtp.exec() == QDialog::Accepted ) { smtp = selsmtp.selected_smtp(); } } if (smtp) { SMTPwrapper * wrap = new SMTPwrapper(smtp); if ( wrap->flushOutbox() ) { QMessageBox::information(0,tr("Info"),tr("Mail queue flushed")); } delete wrap; } } void OpieMail::slotSearchMails() { qDebug("OpieMail::slotSearchMails():not implemented "); } void OpieMail::slotEditSettings() { SettingsDialog settingsDialog( this, 0, true, WStyle_ContextHelp ); settingsDialog.showMaximized(); settingsDialog.exec(); } void OpieMail::slotEditAccounts() { EditAccounts eaDialog( settings, this, 0, true, WStyle_ContextHelp ); eaDialog.slotAdjustColumns(); eaDialog.showMaximized(); eaDialog.exec(); if ( settings ) delete settings; settings = new Settings(); folderView->populate( settings->getAccounts() ); } void OpieMail::displayMail() { QListViewItem*item = mailView->currentItem(); if (!item) return; RecMailP mail = ((MailListViewItem*)item)->data(); RecBodyP body = folderView->fetchBody(mail); ViewMail readMail( this,"", Qt::WType_Modal | WStyle_ContextHelp ); readMail.setBody( body ); readMail.setMail( mail ); readMail.showMaximized(); readMail.exec(); if ( readMail.deleted ) { folderView->refreshCurrent(); } else { ( (MailListViewItem*)item )->setPixmap( 0, QPixmap() ); } } void OpieMail::slotDeleteMail() { if (!mailView->currentItem()) return; RecMailP mail = ((MailListViewItem*)mailView->currentItem() )->data(); if ( QMessageBox::warning(this, tr("Delete Mail"), QString( tr("<p>Do you really want to delete this mail? <br><br>" ) + mail->getFrom() + " - " + mail->getSubject() ) , QMessageBox::Yes, QMessageBox::No ) == QMessageBox::Yes ) { mail->Wrapper()->deleteMail( mail ); folderView->refreshCurrent(); } } void OpieMail::slotDeleteAllMail() { - if (!mailView->currentItem()) return; - RecMailP mail = ((MailListViewItem*)mailView->currentItem() )->data(); + + QValueList<RecMailP> t; if ( QMessageBox::warning(this, tr("Delete All Mails"), tr("Do you really want to delete\nall selected mails?" ) , QMessageBox::Yes, QMessageBox::No ) == QMessageBox::Yes ) { MailListViewItem* item = (MailListViewItem*)mailView->firstChild (); while ( item ) { if ( item->isSelected() ) { - RecMailP mail = item->data(); - mail->Wrapper()->deleteMail( mail ); + t.append( item->data() ); } item = (MailListViewItem*)item->nextSibling(); } - folderView->refreshCurrent(); } + else + return; + if ( t.count() == 0 ) + return; + RecMailP mail = t.first(); + mail->Wrapper()->deleteMailList(t); + folderView->refreshCurrent(); + + } void OpieMail::clearSelection() { mailView->clearSelection(); } void OpieMail::mailHold(int button, QListViewItem *item,const QPoint&,int ) { if (!mailView->currentItem()) return; MAILLIB::ATYPE mailtype = ((MailListViewItem*)mailView->currentItem() )->wrapperType(); /* just the RIGHT button - or hold on pda */ if (button!=2) {return;} if (!item) return; QPopupMenu *m = new QPopupMenu(0); if (m) { if (mailtype==MAILLIB::A_NNTP) { m->insertItem(tr("Read this posting"),this,SLOT(displayMail())); // m->insertItem(tr("Copy this posting"),this,SLOT(slotMoveCopyMail())); } else { if (folderView->currentisDraft()) { m->insertItem(tr("Edit this mail"),this,SLOT(reEditMail())); } m->insertItem(tr("Read this mail"),this,SLOT(displayMail())); - m->insertItem(tr("Copy/Move this mail"),this,SLOT(slotMoveCopyMail())); + m->insertItem(tr("Move/Copy this mail"),this,SLOT(slotMoveCopyMail())); m->insertItem(tr("Delete this mail"),this,SLOT(slotDeleteMail())); m->insertSeparator(); - m->insertItem(tr("Copy/Move all selected mail"),this,SLOT(slotMoveCopyAllMail())); + m->insertItem(tr("Move/Copy all selected mail"),this,SLOT(slotMoveCopyAllMail())); m->insertItem(tr("Delete all selected mails"),this,SLOT(slotDeleteAllMail())); m->insertItem(tr("Clear selection"),this,SLOT(clearSelection())); } m->setFocus(); m->exec( QPoint( QCursor::pos().x(), QCursor::pos().y()) ); delete m; } } void OpieMail::slotShowFolders( bool show ) { if ( show && folderView->isHidden() ) { folderView->show(); } else if ( !show && !folderView->isHidden() ) { folderView->hide(); } } void OpieMail::refreshMailView(const QValueList<RecMailP>&list) { MailListViewItem*item = 0; mailView->clear(); QValueList<RecMailP>::ConstIterator it; for (it = list.begin(); it != list.end();++it) { item = new MailListViewItem(mailView,item); item->storeData((*it)); item->showEntry(); } } void OpieMail::mailLeftClicked( QListViewItem *item ) { mailView->clearSelection(); /* just LEFT button - or tap with stylus on pda */ //if (button!=1) return; if (!item) return; if (folderView->currentisDraft()) { reEditMail(); } else { displayMail(); } } void OpieMail::slotMoveCopyMail() { if (!mailView->currentItem()) return; RecMailP mail = ((MailListViewItem*)mailView->currentItem() )->data(); AbstractMail*targetMail = 0; QString targetFolder = ""; Selectstore sels; folderView->setupFolderselect(&sels); if (!sels.exec()) return; targetMail = sels.currentMail(); targetFolder = sels.currentFolder(); if ( (mail->Wrapper()==targetMail && mail->getMbox()==targetFolder) || targetFolder.isEmpty()) { return; } if (sels.newFolder() && !targetMail->createMbox(targetFolder)) { QMessageBox::critical(0,tr("Error creating new Folder"), tr("<center>Error while creating<br>new folder - breaking.</center>")); return; } + sels.hide(); + qApp->processEvents(); + // qDebug("hiding sels "); mail->Wrapper()->mvcpMail(mail,targetFolder,targetMail,sels.moveMails()); folderView->refreshCurrent(); } void OpieMail::slotMoveCopyAllMail() { if (!mailView->currentItem()) return; QValueList<RecMailP> t; - if ( QMessageBox::warning(this, tr("Copy/Move all selected mails"), tr("Do you really want to copy/move\nall selected mails?" ) , QMessageBox::Yes, QMessageBox::No ) == QMessageBox::Yes ) + // if ( QMessageBox::warning(this, tr("Move/Copy all selected mails"), tr("Do you really want to copy/move\nall selected mails?" ) , QMessageBox::Yes, QMessageBox::No ) == QMessageBox::Yes ) { MailListViewItem* item = (MailListViewItem*)mailView->firstChild (); while ( item ) { if ( item->isSelected() ) { t.append( item->data() ); } item = (MailListViewItem*)item->nextSibling(); } } - else - return; + // else + // return; if ( t.count() == 0 ) return; RecMailP mail = t.first(); AbstractMail*targetMail = 0; QString targetFolder = ""; Selectstore sels; folderView->setupFolderselect(&sels); if (!sels.exec()) return; targetMail = sels.currentMail(); targetFolder = sels.currentFolder(); if ( (mail->Wrapper()==targetMail && mail->getMbox()==targetFolder) || targetFolder.isEmpty()) { return; } if (sels.newFolder() && !targetMail->createMbox(targetFolder)) { QMessageBox::critical(0,tr("Error creating new Folder"), tr("<center>Error while creating<br>new folder - breaking.</center>")); return; } + sels.hide(); + qApp->processEvents(); + //qDebug("hiding sels "); mail->Wrapper()->mvcpMailList(t,targetFolder,targetMail,sels.moveMails()); folderView->refreshCurrent(); } void OpieMail::reEditMail() { if (!mailView->currentItem()) return; ComposeMail compose( settings, this, 0, true , WStyle_ContextHelp ); compose.reEditMail(((MailListViewItem*)mailView->currentItem() )->data()); compose.slotAdjustColumns(); compose.showMaximized(); compose.exec(); } |