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/libetpan/generic | |
parent | b9257cb225cd29bab5d96fcdaf557926603ee587 (diff) | |
download | kdepimpi-6cefbdc9c8f3f3001373f10715361e2740c45395.zip kdepimpi-6cefbdc9c8f3f3001373f10715361e2740c45395.tar.gz kdepimpi-6cefbdc9c8f3f3001373f10715361e2740c45395.tar.bz2 |
Mail fixes and libetpan updated
38 files changed, 703 insertions, 40 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 @@ -97,12 +97,14 @@ static int imapdriver_list_folders(mailsession * session, char * mb, 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); @@ -154,12 +156,13 @@ static mailsession_driver local_imap_session_driver = { .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, @@ -768,12 +771,37 @@ static int imapdriver_append_message(mailsession * 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; 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 @@ -102,12 +102,14 @@ static int imapdriver_cached_lsub_folders(mailsession * session, char * mb, 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); @@ -162,12 +164,13 @@ static mailsession_driver local_imap_cached_session_driver = { .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, @@ -773,12 +776,25 @@ static int imapdriver_cached_append_message(mailsession * session, 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); 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 @@ -209,13 +209,13 @@ static void generate_key_from_mime_section(char * key, size_t size, 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) { 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 @@ -3104,22 +3104,21 @@ static int imap_flags_to_flags(struct mailimap_msg_att_dynamic * att_dyn, 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; } @@ -3236,23 +3235,48 @@ static int flags_to_imap_flags(struct mail_flags * flags, 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; } 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 @@ -103,11 +103,14 @@ imapdriver_get_cached_envelope(struct mail_cache_db * cache_db, 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 @@ -68,13 +68,13 @@ int imap_mailstorage_init(struct mailstorage * storage, 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; 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 @@ -82,12 +82,15 @@ static int unseen_number(mailsession * session, char * mb, 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); @@ -126,12 +129,13 @@ static mailsession_driver local_maildir_session_driver = { .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, @@ -352,24 +356,71 @@ static int recent_number(mailsession * session, char * mb, /* 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; 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 @@ -83,12 +83,15 @@ static int unseen_number(mailsession * session, char * mb, 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); @@ -130,12 +133,13 @@ static mailsession_driver local_maildir_cached_session_driver = { .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, @@ -451,15 +455,89 @@ static int recent_number(mailsession * session, char * mb, } 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) { 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 @@ -36,21 +36,26 @@ #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); @@ -75,13 +80,13 @@ static mailmessage_driver local_maildir_cached_message_driver = { .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 { @@ -243,6 +248,87 @@ static void check(mailmessage * msg_info) 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 @@ -31,12 +31,13 @@ /* * $Id$ */ #include "maildirdriver_message.h" +#include "maildirdriver_tools.h" #include "mailmessage_tools.h" #include "maildirdriver.h" #include "maildir.h" #include "generic_cache.h" @@ -45,12 +46,15 @@ #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); @@ -75,13 +79,13 @@ static mailmessage_driver local_maildir_message_driver = { .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; @@ -194,6 +198,58 @@ static void check(mailmessage * msg_info) 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 @@ -30,12 +30,13 @@ */ /* * $Id$ */ +#include "maildirstorage.h" #include "mailstorage.h" #include "mail.h" #include "mailmessage.h" #include "maildirdriver.h" #include "maildirdriver_cached.h" @@ -62,13 +63,13 @@ static mailstorage_driver maildir_mailstorage_driver = { 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; 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 @@ -41,13 +41,13 @@ #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 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 @@ -279,12 +279,22 @@ int mailsession_append_message(mailsession * session, 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; 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 @@ -397,12 +397,15 @@ int mailsession_unsubscribe_folder(mailsession * session, char * mb); 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. 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 @@ -504,12 +504,14 @@ struct mailsession_driver { 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, 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 @@ -29,12 +29,19 @@ int mailfolder_status(struct mailfolder * folder, 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; 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 @@ -14,12 +14,15 @@ 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); 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 @@ -320,12 +320,19 @@ void mailstorage_disconnect(struct mailstorage * storage) 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; 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 @@ -68,12 +68,14 @@ void mailstorage_free(struct mailstorage * storage); */ 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); @@ -85,13 +87,12 @@ int mailfolder_add_child(struct mailfolder * parent, 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 @@ -74,12 +74,15 @@ static int mboxdriver_status_folder(mailsession * session, char * mb, 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); @@ -123,12 +126,13 @@ static mailsession_driver local_mbox_session_driver = { .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, @@ -341,12 +345,18 @@ static int mboxdriver_append_message(mailsession * session, 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; 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 @@ -83,12 +83,15 @@ static int mboxdriver_cached_recent_number(mailsession * session, char * mb, 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, @@ -134,12 +137,14 @@ static mailsession_driver local_mbox_cached_session_driver = { .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, @@ -903,13 +908,90 @@ static int mboxdriver_cached_unseen_number(mailsession * session, char * mb, /* 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) { @@ -957,13 +1039,14 @@ get_cached_envelope(struct mail_cache_db * cache_db, MMAPString * mmapstr, 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; } @@ -1003,13 +1086,14 @@ write_cached_envelope(struct mail_cache_db * cache_db, MMAPString * mmapstr, 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; } 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 @@ -179,13 +179,14 @@ static int mbox_initialize(mailmessage * msg_info) 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; } 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 @@ -30,13 +30,13 @@ */ /* * $Id$ */ -#include "mhdriver_message.h" +#include "mboxdriver_message.h" #include "mailmessage_tools.h" #include "mboxdriver_tools.h" #include "mboxdriver.h" #include "mailmbox.h" @@ -153,14 +153,14 @@ static int mbox_initialize(mailmessage * msg_info) 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; } 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 @@ -214,13 +214,14 @@ mboxdriver_get_cached_flags(struct mail_cache_db * cache_db, 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; } 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 @@ -62,13 +62,13 @@ static mailstorage_driver mbox_mailstorage_driver = { 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; 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 @@ -86,12 +86,14 @@ static int mhdriver_lsub_folders(mailsession * session, char * mb, 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, @@ -136,13 +138,14 @@ static mailsession_driver local_mh_session_driver = { .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 = 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, @@ -681,12 +684,18 @@ static int mhdriver_append_message(mailsession * session, 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; 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 @@ -105,12 +105,14 @@ 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); @@ -162,12 +164,13 @@ static mailsession_driver local_mh_cached_session_driver = { .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, @@ -880,13 +883,91 @@ static int mhdriver_cached_unsubscribe_folder(mailsession * session, /* 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); @@ -950,14 +1031,15 @@ get_cached_envelope(struct mail_cache_db * cache_db, MMAPString * mmapstr, 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; } @@ -995,14 +1077,15 @@ write_cached_envelope(struct mail_cache_db * cache_db, MMAPString * mmapstr, 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; } 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 @@ -176,14 +176,14 @@ static int mh_initialize(mailmessage * msg_info) 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) { 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 @@ -141,14 +141,15 @@ static int mh_initialize(mailmessage * msg_info) 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) { 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 @@ -366,14 +366,15 @@ mhdriver_get_cached_flags(struct mail_cache_db * cache_db, 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; } 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 @@ -59,13 +59,13 @@ static mailstorage_driver mh_mailstorage_driver = { 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; 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 @@ -66,12 +66,15 @@ static int nntpdriver_status_folder(mailsession * session, char * mb, 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, @@ -126,12 +129,13 @@ static mailsession_driver local_nntp_session_driver = { .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, @@ -627,12 +631,18 @@ static int nntpdriver_append_message(mailsession * session, 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 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 @@ -93,12 +93,15 @@ static int nntpdriver_cached_recent_number(mailsession * session, char * mb, 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 @@ -156,12 +159,13 @@ static mailsession_driver local_nntp_cached_session_driver = { .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, @@ -628,12 +632,18 @@ static int nntpdriver_cached_unsubscribe_folder(mailsession * session, 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) 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 @@ -68,13 +68,13 @@ int nntp_mailstorage_init(struct mailstorage * storage, 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); 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 @@ -106,12 +106,13 @@ static mailsession_driver local_pop3_session_driver = { .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, 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 @@ -107,12 +107,15 @@ 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, @@ -140,24 +143,25 @@ static mailsession_driver local_pop3_cached_session_driver = { .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" @@ -852,6 +856,44 @@ static int pop3driver_cached_get_message(mailsession * session, } * 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 @@ -36,12 +36,14 @@ #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); @@ -77,12 +79,24 @@ static mailmessage_driver local_pop3_message_driver = { .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; @@ -110,20 +124,40 @@ static void pop3_prefetch_free(struct generic_message_t * msg) } 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, 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 @@ -65,13 +65,13 @@ int pop3_mailstorage_init(struct mailstorage * storage, 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; |