summaryrefslogtreecommitdiffabout
path: root/kmicromail/libetpan
Side-by-side diff
Diffstat (limited to 'kmicromail/libetpan') (more/less context) (ignore whitespace changes)
-rw-r--r--kmicromail/libetpan/generic/imapdriver.c28
-rw-r--r--kmicromail/libetpan/generic/imapdriver_cached.c16
-rw-r--r--kmicromail/libetpan/generic/imapdriver_cached_message.c2
-rw-r--r--kmicromail/libetpan/generic/imapdriver_tools.c38
-rw-r--r--kmicromail/libetpan/generic/imapdriver_tools.h3
-rw-r--r--kmicromail/libetpan/generic/imapstorage.c2
-rw-r--r--kmicromail/libetpan/generic/maildirdriver.c51
-rw-r--r--kmicromail/libetpan/generic/maildirdriver_cached.c78
-rw-r--r--kmicromail/libetpan/generic/maildirdriver_cached_message.c88
-rw-r--r--kmicromail/libetpan/generic/maildirdriver_message.c58
-rw-r--r--kmicromail/libetpan/generic/maildirstorage.c3
-rw-r--r--kmicromail/libetpan/generic/maildirstorage.h2
-rw-r--r--kmicromail/libetpan/generic/maildriver.c10
-rw-r--r--kmicromail/libetpan/generic/maildriver.h3
-rw-r--r--kmicromail/libetpan/generic/maildriver_types.h2
-rw-r--r--kmicromail/libetpan/generic/mailfolder.c7
-rw-r--r--kmicromail/libetpan/generic/mailfolder.h3
-rw-r--r--kmicromail/libetpan/generic/mailstorage.c7
-rw-r--r--kmicromail/libetpan/generic/mailstorage.h3
-rw-r--r--kmicromail/libetpan/generic/mboxdriver.c10
-rw-r--r--kmicromail/libetpan/generic/mboxdriver_cached.c90
-rw-r--r--kmicromail/libetpan/generic/mboxdriver_cached_message.c3
-rw-r--r--kmicromail/libetpan/generic/mboxdriver_message.c6
-rw-r--r--kmicromail/libetpan/generic/mboxdriver_tools.c3
-rw-r--r--kmicromail/libetpan/generic/mboxstorage.c2
-rw-r--r--kmicromail/libetpan/generic/mhdriver.c11
-rw-r--r--kmicromail/libetpan/generic/mhdriver_cached.c93
-rw-r--r--kmicromail/libetpan/generic/mhdriver_cached_message.c4
-rw-r--r--kmicromail/libetpan/generic/mhdriver_message.c5
-rw-r--r--kmicromail/libetpan/generic/mhdriver_tools.c5
-rw-r--r--kmicromail/libetpan/generic/mhstorage.c2
-rw-r--r--kmicromail/libetpan/generic/nntpdriver.c10
-rw-r--r--kmicromail/libetpan/generic/nntpdriver_cached.c10
-rw-r--r--kmicromail/libetpan/generic/nntpstorage.c2
-rw-r--r--kmicromail/libetpan/generic/pop3driver.c1
-rw-r--r--kmicromail/libetpan/generic/pop3driver_cached.c44
-rw-r--r--kmicromail/libetpan/generic/pop3driver_message.c36
-rw-r--r--kmicromail/libetpan/generic/pop3storage.c2
-rw-r--r--kmicromail/libetpan/imap/mailimap.c2
-rw-r--r--kmicromail/libetpan/imap/mailimap_keywords.c2
-rw-r--r--kmicromail/libetpan/imf/mailimf.c2
-rw-r--r--kmicromail/libetpan/include/libetpan/libetpan.h12
-rw-r--r--kmicromail/libetpan/include/libetpan/maildir.h7
-rw-r--r--kmicromail/libetpan/include/libetpan/maildirstorage.h2
-rw-r--r--kmicromail/libetpan/include/libetpan/maildriver.h3
-rw-r--r--kmicromail/libetpan/include/libetpan/maildriver_types.h2
-rw-r--r--kmicromail/libetpan/include/libetpan/mailfolder.h3
-rw-r--r--kmicromail/libetpan/include/libetpan/mailmbox.h4
-rw-r--r--kmicromail/libetpan/include/libetpan/mailmbox_types.h1
-rw-r--r--kmicromail/libetpan/include/libetpan/mailmh.h7
-rw-r--r--kmicromail/libetpan/include/libetpan/mailstorage.h3
-rw-r--r--kmicromail/libetpan/maildir/maildir.c33
-rw-r--r--kmicromail/libetpan/maildir/maildir.h7
-rw-r--r--kmicromail/libetpan/mbox/mailmbox.c21
-rw-r--r--kmicromail/libetpan/mbox/mailmbox.h4
-rw-r--r--kmicromail/libetpan/mbox/mailmbox_types.c3
-rw-r--r--kmicromail/libetpan/mbox/mailmbox_types.h1
-rw-r--r--kmicromail/libetpan/mh/mailmh.c28
-rw-r--r--kmicromail/libetpan/mh/mailmh.h7
-rw-r--r--kmicromail/libetpan/mime/mailmime_decode.c24
-rw-r--r--kmicromail/libetpan/mime/mailmime_write.c2
-rw-r--r--kmicromail/libetpan/smtp/mailsmtp.c2
-rw-r--r--kmicromail/libetpan/smtp/mailsmtp_helper.c12
63 files changed, 859 insertions, 78 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
@@ -55,153 +55,156 @@ 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;
@@ -726,96 +729,121 @@ static int imapdriver_list_lsub_folders(mailsession * session, int type,
}
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;
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
@@ -60,156 +60,159 @@
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;
@@ -731,96 +734,109 @@ static int imapdriver_cached_list_folders(mailsession * session, char * mb,
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);
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
@@ -167,97 +167,97 @@ 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)
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
@@ -3062,106 +3062,105 @@ static int imap_flags_to_flags(struct mailimap_msg_att_dynamic * att_dyn,
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) {
@@ -3194,107 +3193,132 @@ static int flags_to_imap_flags(struct mail_flags * flags,
}
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) {
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
@@ -61,53 +61,56 @@ int imap_get_msg_att_info(struct mailimap_msg_att * msg_att,
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
@@ -26,97 +26,97 @@
* 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) {
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
@@ -40,140 +40,144 @@
*/
#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;
@@ -310,108 +314,155 @@ static int messages_number(mailsession * session, char * mb,
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);
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
@@ -41,143 +41,147 @@
#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;
@@ -409,99 +413,173 @@ 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;
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,129 +1,134 @@
/*
* 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;
}
@@ -201,48 +206,129 @@ static int prefetch(mailmessage * msg_info)
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,129 +1,133 @@
/*
* 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;
}
@@ -152,48 +156,100 @@ static int prefetch(mailmessage * msg_info)
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,116 +1,117 @@
/*
* 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)
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
@@ -237,96 +237,106 @@ int mailsession_unseen_number(mailsession * session, char * mb,
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;
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
@@ -355,96 +355,99 @@ int mailsession_list_folders(mailsession * session, char * mb,
*/
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);
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
@@ -462,96 +462,98 @@ struct mailsession_driver {
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
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,82 +1,89 @@
#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)
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
@@ -278,57 +278,64 @@ void mailstorage_free(struct mailstorage * storage)
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
@@ -26,73 +26,74 @@
* 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
@@ -32,145 +32,149 @@
/*
* $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)
@@ -299,96 +303,102 @@ static int mboxdriver_status_folder(mailsession * session, char * mb,
* 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)
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
@@ -41,147 +41,152 @@
#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:
@@ -861,197 +866,276 @@ static int mboxdriver_cached_status_folder(mailsession * session, char * mb,
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 = &num;
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 = &num;
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;
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
@@ -137,97 +137,98 @@ static int mbox_prefetch(mailmessage * msg_info)
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 */
}
}
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,84 +1,84 @@
/*
* 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,
@@ -111,98 +111,98 @@ static int mbox_prefetch(mailmessage * msg_info)
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;
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
@@ -172,97 +172,98 @@ int mboxdriver_fetch_size(mailsession * session, uint32_t index,
}
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 = &num;
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;
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
@@ -20,97 +20,97 @@
* 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)
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
@@ -44,147 +44,150 @@
#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 = 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;
}
@@ -639,96 +642,102 @@ static int mhdriver_lsub_folders(mailsession * session, char * mb,
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;
}
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
@@ -63,153 +63,156 @@ 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;
@@ -838,213 +841,293 @@ static int mhdriver_cached_recent_number(mailsession * session, char * mb,
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 = &num;
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 = &num;
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);
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
@@ -134,98 +134,98 @@ 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;
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
@@ -99,98 +99,99 @@ static int mh_prefetch(mailmessage * msg_info)
&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) {
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
@@ -324,98 +324,99 @@ int mhdriver_fetch_size(mailsession * session, uint32_t index,
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 = &num;
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;
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
@@ -17,97 +17,97 @@
* 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);
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
@@ -24,156 +24,160 @@
* 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;
@@ -585,96 +589,102 @@ static int nntpdriver_subscribe_folder(mailsession * session, char * mb)
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)
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
@@ -51,159 +51,163 @@
#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)
@@ -586,96 +590,102 @@ static int nntpdriver_cached_unseen_number(mailsession * session,
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:
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
@@ -26,97 +26,97 @@
* 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) {
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
@@ -64,96 +64,97 @@ 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:
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
@@ -65,141 +65,145 @@ 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);
@@ -810,48 +814,86 @@ pop3driver_cached_get_envelopes_list(mailsession * session,
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
@@ -23,97 +23,97 @@
* 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) {
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
@@ -1862,97 +1862,97 @@ int mailimap_subscribe(mailimap * session, const char * mb)
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;
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
@@ -8,97 +8,97 @@
* 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 */
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
@@ -3,97 +3,97 @@
*
* 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,
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
@@ -355,96 +355,99 @@ int mailsession_list_folders(mailsession * session, char * mb,
*/
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);
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
@@ -462,96 +462,98 @@ struct mailsession_driver {
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
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
@@ -6,96 +6,100 @@
*
* 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);
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
@@ -83,60 +83,61 @@ struct mailmbox_folder {
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
@@ -74,70 +74,77 @@ struct mailmh_folder {
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
@@ -26,73 +26,74 @@
* 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
@@ -385,225 +385,244 @@ int maildir_update(struct maildir * md)
}
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;
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
@@ -152,96 +152,99 @@ int mailmbox_map(struct mailmbox_folder * folder)
}
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);
@@ -572,96 +575,98 @@ static char * write_fixed_message(char * str,
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 ++;
@@ -699,137 +704,147 @@ 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 = &num;
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 = &num;
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
@@ -6,96 +6,100 @@
*
* 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);
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
@@ -133,97 +133,98 @@ mailmbox_msg_info_new(size_t msg_start, size_t msg_start_len,
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:
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
@@ -83,60 +83,61 @@ struct mailmbox_folder {
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
@@ -678,225 +678,241 @@ int mailmh_folder_get_message_filename(struct mailmh_folder * folder,
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:
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
@@ -74,70 +74,77 @@ struct mailmh_folder {
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
@@ -142,106 +142,116 @@ int mailmime_encoded_phrase_parse(const char * default_fromcode,
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);
- free(raw_word);
- res = MAILIMF_ERROR_MEMORY;
- goto free;
- }
+ 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;
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
@@ -396,97 +396,97 @@ static int mailmime_disposition_write(FILE * f, int * col,
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:
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
@@ -147,96 +147,98 @@ int mailsmtp_connect(mailsmtp * session, mailstream * s)
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;
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,104 +1,100 @@
/*
* 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)