summaryrefslogtreecommitdiffabout
path: root/libetpan/src/driver/implementation/pop3
Side-by-side diff
Diffstat (limited to 'libetpan/src/driver/implementation/pop3') (more/less context) (ignore whitespace changes)
-rw-r--r--libetpan/src/driver/implementation/pop3/pop3driver.c388
-rw-r--r--libetpan/src/driver/implementation/pop3/pop3driver.h52
-rw-r--r--libetpan/src/driver/implementation/pop3/pop3driver_cached.c899
-rw-r--r--libetpan/src/driver/implementation/pop3/pop3driver_cached.h52
-rw-r--r--libetpan/src/driver/implementation/pop3/pop3driver_cached_message.c355
-rw-r--r--libetpan/src/driver/implementation/pop3/pop3driver_cached_message.h52
-rw-r--r--libetpan/src/driver/implementation/pop3/pop3driver_message.c193
-rw-r--r--libetpan/src/driver/implementation/pop3/pop3driver_message.h52
-rw-r--r--libetpan/src/driver/implementation/pop3/pop3driver_tools.c344
-rw-r--r--libetpan/src/driver/implementation/pop3/pop3driver_tools.h82
-rw-r--r--libetpan/src/driver/implementation/pop3/pop3driver_types.h153
-rw-r--r--libetpan/src/driver/implementation/pop3/pop3storage.c284
-rw-r--r--libetpan/src/driver/implementation/pop3/pop3storage.h95
13 files changed, 3001 insertions, 0 deletions
diff --git a/libetpan/src/driver/implementation/pop3/pop3driver.c b/libetpan/src/driver/implementation/pop3/pop3driver.c
new file mode 100644
index 0000000..ea69923
--- a/dev/null
+++ b/libetpan/src/driver/implementation/pop3/pop3driver.c
@@ -0,0 +1,388 @@
+/*
+ * libEtPan! -- a mail stuff library
+ *
+ * Copyright (C) 2001, 2005 - 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 AUTHORS 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 AUTHORS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * $Id$
+ */
+
+#include "pop3driver.h"
+
+#include <string.h>
+#include <stdlib.h>
+
+#include "pop3driver_message.h"
+#include "maildriver_tools.h"
+#include "pop3driver_tools.h"
+#include "mailmessage.h"
+
+static int pop3driver_initialize(mailsession * session);
+
+static void pop3driver_uninitialize(mailsession * session);
+
+static int pop3driver_parameters(mailsession * session,
+ int id, void * value);
+
+static int pop3driver_connect_stream(mailsession * session, mailstream * s);
+
+static int pop3driver_starttls(mailsession * session);
+
+static int pop3driver_login(mailsession * session,
+ char * userid, char * password);
+
+static int pop3driver_logout(mailsession * session);
+
+static int pop3driver_noop(mailsession * session);
+
+static int pop3driver_status_folder(mailsession * session, char * mb,
+ uint32_t * result_messages, uint32_t * result_recent,
+ uint32_t * result_unseen);
+
+static int pop3driver_messages_number(mailsession * session, char * mb,
+ uint32_t * result);
+
+static int pop3driver_remove_message(mailsession * session, uint32_t num);
+
+static int pop3driver_get_messages_list(mailsession * session,
+ struct mailmessage_list ** result);
+
+static int pop3driver_get_message(mailsession * session,
+ uint32_t num, mailmessage ** result);
+
+static mailsession_driver local_pop3_session_driver = {
+ .sess_name = "pop3",
+
+ .sess_initialize = pop3driver_initialize,
+ .sess_uninitialize = pop3driver_uninitialize,
+
+ .sess_parameters = pop3driver_parameters,
+
+ .sess_connect_stream = pop3driver_connect_stream,
+ .sess_connect_path = NULL,
+ .sess_starttls = pop3driver_starttls,
+ .sess_login = pop3driver_login,
+ .sess_logout = pop3driver_logout,
+ .sess_noop = pop3driver_noop,
+
+ .sess_build_folder_name = NULL,
+ .sess_create_folder = NULL,
+ .sess_delete_folder = NULL,
+ .sess_rename_folder = NULL,
+ .sess_check_folder = NULL,
+ .sess_examine_folder = NULL,
+ .sess_select_folder = NULL,
+ .sess_expunge_folder = NULL,
+ .sess_status_folder = pop3driver_status_folder,
+ .sess_messages_number = pop3driver_messages_number,
+ .sess_recent_number = pop3driver_messages_number,
+ .sess_unseen_number = pop3driver_messages_number,
+ .sess_list_folders = NULL,
+ .sess_lsub_folders = NULL,
+ .sess_subscribe_folder = NULL,
+ .sess_unsubscribe_folder = NULL,
+
+ .sess_append_message = NULL,
+ .sess_append_message_flags = NULL,
+ .sess_copy_message = NULL,
+ .sess_move_message = NULL,
+
+ .sess_get_messages_list = pop3driver_get_messages_list,
+ .sess_get_envelopes_list = maildriver_generic_get_envelopes_list,
+ .sess_remove_message = pop3driver_remove_message,
+#if 0
+ .sess_search_messages = maildriver_generic_search_messages,
+#endif
+
+ .sess_get_message = pop3driver_get_message,
+ .sess_get_message_by_uid = NULL,
+};
+
+mailsession_driver * pop3_session_driver = &local_pop3_session_driver;
+
+static inline struct pop3_session_state_data *
+get_data(mailsession * session)
+{
+ return session->sess_data;
+}
+
+static mailpop3 * get_pop3_session(mailsession * session)
+{
+ return get_data(session)->pop3_session;
+}
+
+static int pop3driver_initialize(mailsession * session)
+{
+ struct pop3_session_state_data * data;
+ mailpop3 * pop3;
+
+ pop3 = mailpop3_new(0, NULL);
+ if (session == NULL)
+ goto err;
+
+ data = malloc(sizeof(* data));
+ if (data == NULL)
+ goto free;
+
+ data->pop3_session = pop3;
+ data->pop3_auth_type = POP3DRIVER_AUTH_TYPE_PLAIN;
+
+ session->sess_data = data;
+
+ return MAIL_NO_ERROR;
+
+ free:
+ mailpop3_free(pop3);
+ err:
+ return MAIL_ERROR_MEMORY;
+}
+
+static void pop3driver_uninitialize(mailsession * session)
+{
+ struct pop3_session_state_data * data;
+
+ data = get_data(session);
+
+ mailpop3_free(data->pop3_session);
+ free(data);
+
+ session->sess_data = data;
+}
+
+static int pop3driver_connect_stream(mailsession * session, mailstream * s)
+{
+ int r;
+
+ r = mailpop3_connect(get_pop3_session(session), s);
+
+ switch (r) {
+ case MAILPOP3_NO_ERROR:
+ return MAIL_NO_ERROR_NON_AUTHENTICATED;
+
+ default:
+ return pop3driver_pop3_error_to_mail_error(r);
+ }
+}
+
+static int pop3driver_starttls(mailsession * session)
+{
+ int r;
+ int fd;
+ mailstream_low * low;
+ mailstream_low * new_low;
+ mailpop3 * pop3;
+
+ pop3 = get_pop3_session(session);
+
+ r = mailpop3_stls(pop3);
+
+ switch (r) {
+ case MAILPOP3_NO_ERROR:
+ break;
+ default:
+ return pop3driver_pop3_error_to_mail_error(r);
+ }
+
+ low = mailstream_get_low(pop3->pop3_stream);
+ fd = mailstream_low_get_fd(low);
+ if (fd == -1)
+ return MAIL_ERROR_STREAM;
+
+ new_low = mailstream_low_ssl_open(fd);
+ if (new_low == NULL)
+ return MAIL_ERROR_STREAM;
+ mailstream_low_free(low);
+ mailstream_set_low(pop3->pop3_stream, new_low);
+
+ return MAIL_NO_ERROR;
+}
+
+static int pop3driver_parameters(mailsession * session,
+ int id, void * value)
+{
+ struct pop3_session_state_data * data;
+
+ data = get_data(session);
+
+ switch (id) {
+ case POP3DRIVER_SET_AUTH_TYPE:
+ {
+ int * param;
+
+ param = value;
+
+ data->pop3_auth_type = * param;
+ return MAIL_NO_ERROR;
+ }
+ }
+
+ return MAIL_ERROR_INVAL;
+}
+
+static int pop3driver_login(mailsession * session,
+ char * userid, char * password)
+{
+ int r;
+ carray * msg_tab;
+ struct pop3_session_state_data * data;
+
+ data = get_data(session);
+
+ switch (data->pop3_auth_type) {
+ case POP3DRIVER_AUTH_TYPE_TRY_APOP:
+ r = mailpop3_login_apop(get_pop3_session(session), userid, password);
+ if (r != MAILPOP3_NO_ERROR)
+ r = mailpop3_login(get_pop3_session(session), userid, password);
+ break;
+
+ case POP3DRIVER_AUTH_TYPE_APOP:
+ r = mailpop3_login_apop(get_pop3_session(session), userid, password);
+ break;
+
+ default:
+ case POP3DRIVER_AUTH_TYPE_PLAIN:
+ r = mailpop3_login(get_pop3_session(session), userid, password);
+ break;
+ }
+
+ mailpop3_list(get_pop3_session(session), &msg_tab);
+
+ return pop3driver_pop3_error_to_mail_error(r);
+}
+
+static int pop3driver_logout(mailsession * session)
+{
+ int r;
+
+ r = mailpop3_quit(get_pop3_session(session));
+
+ return pop3driver_pop3_error_to_mail_error(r);
+}
+
+static int pop3driver_noop(mailsession * session)
+{
+ int r;
+
+ r = mailpop3_noop(get_pop3_session(session));
+
+ return pop3driver_pop3_error_to_mail_error(r);
+}
+
+static int pop3driver_status_folder(mailsession * session, char * mb,
+ uint32_t * result_messages,
+ uint32_t * result_recent,
+ uint32_t * result_unseen)
+{
+ uint32_t count;
+ int r;
+
+ r = pop3driver_messages_number(session, mb, &count);
+ if (r != MAIL_NO_ERROR)
+ return r;
+
+ * result_messages = count;
+ * result_recent = count;
+ * result_unseen = count;
+
+ return MAIL_NO_ERROR;
+}
+
+static int pop3driver_messages_number(mailsession * session, char * mb,
+ uint32_t * result)
+{
+ carray * msg_tab;
+
+ mailpop3_list(get_pop3_session(session), &msg_tab);
+
+ * result = carray_count(msg_tab) -
+ get_pop3_session(session)->pop3_deleted_count;
+
+ return MAIL_NO_ERROR;
+}
+
+
+/* messages operations */
+
+static int pop3driver_remove_message(mailsession * session, uint32_t num)
+{
+ mailpop3 * pop3;
+ int r;
+
+ pop3 = get_pop3_session(session);
+
+ r = mailpop3_dele(pop3, num);
+ switch (r) {
+ case MAILPOP3_ERROR_BAD_STATE:
+ return MAIL_ERROR_BAD_STATE;
+
+ case MAILPOP3_ERROR_NO_SUCH_MESSAGE:
+ return MAIL_ERROR_MSG_NOT_FOUND;
+
+ case MAILPOP3_ERROR_STREAM:
+ return MAIL_ERROR_STREAM;
+
+ case MAILPOP3_NO_ERROR:
+ return MAIL_NO_ERROR;
+
+ default:
+ return MAIL_ERROR_REMOVE;
+ }
+}
+
+static int pop3driver_get_messages_list(mailsession * session,
+ struct mailmessage_list ** result)
+{
+ mailpop3 * pop3;
+
+ pop3 = get_pop3_session(session);
+
+ return pop3_get_messages_list(pop3, session,
+ pop3_message_driver, result);
+}
+
+static int pop3driver_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_message_driver, num, 0);
+ if (r != MAIL_NO_ERROR) {
+ mailmessage_free(msg_info);
+ return r;
+ }
+
+ * result = msg_info;
+
+ return MAIL_NO_ERROR;
+}
diff --git a/libetpan/src/driver/implementation/pop3/pop3driver.h b/libetpan/src/driver/implementation/pop3/pop3driver.h
new file mode 100644
index 0000000..b70f69e
--- a/dev/null
+++ b/libetpan/src/driver/implementation/pop3/pop3driver.h
@@ -0,0 +1,52 @@
+/*
+ * libEtPan! -- a mail stuff library
+ *
+ * Copyright (C) 2001, 2005 - 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 AUTHORS 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 AUTHORS 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 POP3DRIVER_H
+
+#define POP3DRIVER_H
+
+#include <libetpan/pop3driver_types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern mailsession_driver * pop3_session_driver;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libetpan/src/driver/implementation/pop3/pop3driver_cached.c b/libetpan/src/driver/implementation/pop3/pop3driver_cached.c
new file mode 100644
index 0000000..d3cc98e
--- a/dev/null
+++ b/libetpan/src/driver/implementation/pop3/pop3driver_cached.c
@@ -0,0 +1,899 @@
+/*
+ * libEtPan! -- a mail stuff library
+ *
+ * Copyright (C) 2001, 2005 - 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 AUTHORS 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 AUTHORS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * $Id$
+ */
+
+#include "pop3driver_cached.h"
+
+#include "libetpan-config.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+#include "mail.h"
+#include "mail_cache_db.h"
+
+#include "maildriver.h"
+#include "mailmessage.h"
+#include "pop3driver.h"
+#include "mailpop3.h"
+#include "generic_cache.h"
+#include "imfcache.h"
+#include "pop3driver_cached_message.h"
+#include "pop3driver_tools.h"
+#include "maildriver_tools.h"
+
+static int pop3driver_cached_initialize(mailsession * session);
+
+static void pop3driver_cached_uninitialize(mailsession * session);
+
+static int pop3driver_cached_parameters(mailsession * session,
+ int id, void * value);
+
+static int pop3driver_cached_connect_stream(mailsession * session,
+ mailstream * s);
+
+static int pop3driver_cached_starttls(mailsession * session);
+
+static int pop3driver_cached_login(mailsession * session,
+ char * userid, char * password);
+
+static int pop3driver_cached_logout(mailsession * session);
+
+static int pop3driver_cached_check_folder(mailsession * session);
+
+static int pop3driver_cached_noop(mailsession * session);
+
+static int pop3driver_cached_expunge_folder(mailsession * session);
+
+static int pop3driver_cached_status_folder(mailsession * session,
+ char * mb, uint32_t * result_messages, uint32_t * result_recent,
+ uint32_t * result_unseen);
+
+static int pop3driver_cached_messages_number(mailsession * session,
+ char * mb,
+ uint32_t * result);
+
+static int pop3driver_cached_recent_number(mailsession * session,
+ char * mb,
+ uint32_t * result);
+
+static int pop3driver_cached_unseen_number(mailsession * session,
+ char * mb,
+ uint32_t * result);
+
+static int pop3driver_cached_remove_message(mailsession * session,
+ uint32_t num);
+
+static int
+pop3driver_cached_get_messages_list(mailsession * session,
+ struct mailmessage_list ** result);
+
+static int
+pop3driver_cached_get_envelopes_list(mailsession * session,
+ struct mailmessage_list * env_list);
+
+static int pop3driver_cached_get_message(mailsession * session,
+ uint32_t num, mailmessage ** result);
+
+static int pop3driver_cached_get_message_by_uid(mailsession * session,
+ const char * uid, mailmessage ** result);
+
+static mailsession_driver local_pop3_cached_session_driver = {
+ .sess_name = "pop3-cached",
+
+ .sess_initialize = pop3driver_cached_initialize,
+ .sess_uninitialize = pop3driver_cached_uninitialize,
+
+ .sess_parameters = pop3driver_cached_parameters,
+
+ .sess_connect_stream = pop3driver_cached_connect_stream,
+ .sess_connect_path = NULL,
+ .sess_starttls = pop3driver_cached_starttls,
+ .sess_login = pop3driver_cached_login,
+ .sess_logout = pop3driver_cached_logout,
+ .sess_noop = pop3driver_cached_noop,
+
+ .sess_build_folder_name = NULL,
+ .sess_create_folder = NULL,
+ .sess_delete_folder = NULL,
+ .sess_rename_folder = NULL,
+ .sess_check_folder = pop3driver_cached_check_folder,
+ .sess_examine_folder = NULL,
+ .sess_select_folder = NULL,
+ .sess_expunge_folder = pop3driver_cached_expunge_folder,
+ .sess_status_folder = pop3driver_cached_status_folder,
+ .sess_messages_number = pop3driver_cached_messages_number,
+ .sess_recent_number = pop3driver_cached_recent_number,
+ .sess_unseen_number = pop3driver_cached_unseen_number,
+ .sess_list_folders = NULL,
+ .sess_lsub_folders = NULL,
+ .sess_subscribe_folder = NULL,
+ .sess_unsubscribe_folder = NULL,
+
+ .sess_append_message = NULL,
+ .sess_append_message_flags = NULL,
+ .sess_copy_message = NULL,
+ .sess_move_message = NULL,
+
+ .sess_get_messages_list = pop3driver_cached_get_messages_list,
+ .sess_get_envelopes_list = pop3driver_cached_get_envelopes_list,
+ .sess_remove_message = pop3driver_cached_remove_message,
+#if 0
+ .sess_search_messages = maildriver_generic_search_messages,
+#endif
+
+ .sess_get_message = pop3driver_cached_get_message,
+ .sess_get_message_by_uid = pop3driver_cached_get_message_by_uid,
+};
+
+mailsession_driver * pop3_cached_session_driver =
+&local_pop3_cached_session_driver;
+
+#define ENV_NAME "env.db"
+#define FLAGS_NAME "flags.db"
+
+
+static inline struct pop3_cached_session_state_data *
+get_cached_data(mailsession * session)
+{
+ return session->sess_data;
+}
+
+static inline mailsession * get_ancestor(mailsession * session)
+{
+ return get_cached_data(session)->pop3_ancestor;
+}
+
+static inline struct pop3_session_state_data *
+get_ancestor_data(mailsession * session)
+{
+ return get_ancestor(session)->sess_data;
+}
+
+static inline mailpop3 * get_pop3_session(mailsession * session)
+{
+ return get_ancestor_data(session)->pop3_session;
+}
+
+static int pop3driver_cached_initialize(mailsession * session)
+{
+ struct pop3_cached_session_state_data * data;
+
+ data = malloc(sizeof(* data));
+ if (data == NULL)
+ goto err;
+
+ data->pop3_flags_store = mail_flags_store_new();
+ if (data->pop3_flags_store == NULL)
+ goto free_data;
+
+ data->pop3_ancestor = mailsession_new(pop3_session_driver);
+ if (data->pop3_ancestor == NULL)
+ goto free_store;
+
+ data->pop3_flags_hash = chash_new(128, CHASH_COPYNONE);
+ if (data->pop3_flags_hash == NULL)
+ goto free_session;
+
+ session->sess_data = data;
+
+ return MAIL_NO_ERROR;
+
+ free_session:
+ mailsession_free(data->pop3_ancestor);
+ free_store:
+ mail_flags_store_free(data->pop3_flags_store);
+ free_data:
+ free(data);
+ err:
+ return MAIL_ERROR_MEMORY;
+}
+
+static int pop3_flags_store_process(char * flags_directory,
+ struct mail_flags_store * flags_store)
+{
+ char filename_flags[PATH_MAX];
+ struct mail_cache_db * cache_db_flags;
+ MMAPString * mmapstr;
+ unsigned int i;
+ int r;
+ int res;
+
+ if (carray_count(flags_store->fls_tab) == 0)
+ return MAIL_NO_ERROR;
+
+ snprintf(filename_flags, PATH_MAX, "%s/%s",
+ flags_directory, FLAGS_NAME);
+
+ r = mail_cache_db_open_lock(filename_flags, &cache_db_flags);
+ if (r < 0) {
+ res = MAIL_ERROR_FILE;
+ goto err;
+ }
+
+ mmapstr = mmap_string_new("");
+ if (mmapstr == NULL) {
+ res = MAIL_ERROR_MEMORY;
+ goto close_db_flags;
+ }
+
+ for(i = 0 ; i < carray_count(flags_store->fls_tab) ; i ++) {
+ mailmessage * msg;
+
+ msg = carray_get(flags_store->fls_tab, i);
+
+ r = pop3driver_write_cached_flags(cache_db_flags, mmapstr,
+ msg->msg_uid, msg->msg_flags);
+ }
+
+ mmap_string_free(mmapstr);
+ mail_cache_db_close_unlock(filename_flags, cache_db_flags);
+
+ mail_flags_store_clear(flags_store);
+
+ return MAIL_NO_ERROR;
+
+ close_db_flags:
+ mail_cache_db_close_unlock(filename_flags, cache_db_flags);
+ err:
+ return res;
+}
+
+static void pop3driver_cached_uninitialize(mailsession * session)
+{
+ struct pop3_cached_session_state_data * data;
+
+ data = get_cached_data(session);
+
+ pop3_flags_store_process(data->pop3_flags_directory,
+ data->pop3_flags_store);
+
+ mail_flags_store_free(data->pop3_flags_store);
+
+ chash_free(data->pop3_flags_hash);
+ mailsession_free(data->pop3_ancestor);
+ free(data);
+
+ session->sess_data = data;
+}
+
+static int pop3driver_cached_check_folder(mailsession * session)
+{
+ struct pop3_cached_session_state_data * pop3_data;
+
+ pop3_data = get_cached_data(session);
+
+ pop3_flags_store_process(pop3_data->pop3_flags_directory,
+ pop3_data->pop3_flags_store);
+
+ return MAIL_NO_ERROR;
+}
+
+static int pop3driver_cached_parameters(mailsession * session,
+ int id, void * value)
+{
+ struct pop3_cached_session_state_data * data;
+ int r;
+
+ data = get_cached_data(session);
+
+ switch (id) {
+ case POP3DRIVER_CACHED_SET_CACHE_DIRECTORY:
+ strncpy(data->pop3_cache_directory, value, PATH_MAX);
+ data->pop3_cache_directory[PATH_MAX - 1] = '\0';
+
+ r = generic_cache_create_dir(data->pop3_cache_directory);
+ if (r != MAIL_NO_ERROR)
+ return r;
+
+ return MAIL_NO_ERROR;
+
+ case POP3DRIVER_CACHED_SET_FLAGS_DIRECTORY:
+ strncpy(data->pop3_flags_directory, value, PATH_MAX);
+ data->pop3_flags_directory[PATH_MAX - 1] = '\0';
+
+ r = generic_cache_create_dir(data->pop3_flags_directory);
+ if (r != MAIL_NO_ERROR)
+ return r;
+
+ return MAIL_NO_ERROR;
+
+ default:
+ return mailsession_parameters(data->pop3_ancestor, id, value);
+ }
+}
+
+static int pop3driver_cached_connect_stream(mailsession * session,
+ mailstream * s)
+{
+ int r;
+
+ r = mailsession_connect_stream(get_ancestor(session), s);
+ if (r != MAIL_NO_ERROR)
+ return r;
+
+ return MAIL_NO_ERROR;
+}
+
+static int pop3driver_cached_starttls(mailsession * session)
+{
+ return mailsession_starttls(get_ancestor(session));
+}
+
+
+static int pop3driver_cached_login(mailsession * session,
+ char * userid, char * password)
+{
+ return mailsession_login(get_ancestor(session), userid, password);
+}
+
+static int pop3driver_cached_logout(mailsession * session)
+{
+ struct pop3_cached_session_state_data * cached_data;
+
+ cached_data = get_cached_data(session);
+
+ pop3_flags_store_process(cached_data->pop3_flags_directory,
+ cached_data->pop3_flags_store);
+
+ return mailsession_logout(get_ancestor(session));
+}
+
+static int pop3driver_cached_noop(mailsession * session)
+{
+ return mailsession_noop(get_ancestor(session));
+}
+
+static int pop3driver_cached_expunge_folder(mailsession * session)
+{
+ int res;
+ struct pop3_cached_session_state_data * cached_data;
+ char filename_flags[PATH_MAX];
+ struct mail_cache_db * cache_db_flags;
+ MMAPString * mmapstr;
+ unsigned int i;
+ int r;
+ carray * msg_tab;
+ mailpop3 * pop3;
+
+ pop3 = get_pop3_session(session);
+
+ cached_data = get_cached_data(session);
+
+ pop3_flags_store_process(cached_data->pop3_flags_directory,
+ cached_data->pop3_flags_store);
+
+ snprintf(filename_flags, PATH_MAX, "%s/%s",
+ cached_data->pop3_flags_directory, FLAGS_NAME);
+
+ r = mail_cache_db_open_lock(filename_flags, &cache_db_flags);
+ if (r < 0) {
+ res = MAIL_ERROR_MEMORY;
+ goto err;
+ }
+
+ mmapstr = mmap_string_new("");
+ if (mmapstr == NULL) {
+ res = MAIL_ERROR_MEMORY;
+ goto close_db_flags;
+ }
+
+ mailpop3_list(pop3, &msg_tab);
+
+ for(i = 0 ; i < carray_count(msg_tab) ; i++) {
+ struct mailpop3_msg_info * pop3_info;
+ struct mail_flags * flags;
+
+ pop3_info = carray_get(msg_tab, i);
+ if (pop3_info == NULL)
+ continue;
+
+ if (pop3_info->msg_deleted)
+ continue;
+
+ r = pop3driver_get_cached_flags(cache_db_flags, mmapstr,
+ session, pop3_info->msg_index, &flags);
+ if (r != MAIL_NO_ERROR)
+ continue;
+
+ if (flags->fl_flags & MAIL_FLAG_DELETED) {
+ r = mailpop3_dele(pop3, pop3_info->msg_index);
+ }
+
+ mail_flags_free(flags);
+ }
+
+ mmap_string_free(mmapstr);
+ mail_cache_db_close_unlock(filename_flags, cache_db_flags);
+
+ return MAIL_NO_ERROR;
+
+ close_db_flags:
+ mail_cache_db_close_unlock(filename_flags, cache_db_flags);
+ err:
+ return res;
+}
+
+static int pop3driver_cached_status_folder(mailsession * session,
+ char * mb, uint32_t * result_messages, uint32_t * result_recent,
+ uint32_t * result_unseen)
+{
+ int res;
+ struct pop3_cached_session_state_data * cached_data;
+ char filename_flags[PATH_MAX];
+ struct mail_cache_db * cache_db_flags;
+ MMAPString * mmapstr;
+ unsigned int i;
+ int r;
+ carray * msg_tab;
+ mailpop3 * pop3;
+ uint32_t recent;
+ uint32_t unseen;
+
+ recent = 0;
+ unseen = 0;
+
+ pop3 = get_pop3_session(session);
+
+ cached_data = get_cached_data(session);
+
+ pop3_flags_store_process(cached_data->pop3_flags_directory,
+ cached_data->pop3_flags_store);
+
+ snprintf(filename_flags, PATH_MAX, "%s/%s",
+ cached_data->pop3_flags_directory, FLAGS_NAME);
+
+ r = mail_cache_db_open_lock(filename_flags, &cache_db_flags);
+ if (r < 0) {
+ res = MAIL_ERROR_MEMORY;
+ goto err;
+ }
+
+ mmapstr = mmap_string_new("");
+ if (mmapstr == NULL) {
+ res = MAIL_ERROR_MEMORY;
+ goto close_db_flags;
+ }
+
+ mailpop3_list(pop3, &msg_tab);
+
+ for(i = 0 ; i < carray_count(msg_tab) ; i++) {
+ struct mailpop3_msg_info * pop3_info;
+ struct mail_flags * flags;
+
+ pop3_info = carray_get(msg_tab, i);
+ if (pop3_info == NULL)
+ continue;
+
+ if (pop3_info->msg_deleted)
+ continue;
+
+ r = pop3driver_get_cached_flags(cache_db_flags, mmapstr,
+ session, pop3_info->msg_index, &flags);
+ if (r != MAIL_NO_ERROR) {
+ recent ++;
+ unseen ++;
+ continue;
+ }
+
+ if ((flags->fl_flags & MAIL_FLAG_NEW) != 0) {
+ recent ++;
+ }
+ if ((flags->fl_flags & MAIL_FLAG_SEEN) == 0) {
+ unseen ++;
+ }
+ mail_flags_free(flags);
+
+ }
+
+ mmap_string_free(mmapstr);
+ mail_cache_db_close_unlock(filename_flags, cache_db_flags);
+
+ * result_messages = carray_count(msg_tab) - pop3->pop3_deleted_count;
+ * result_recent = recent;
+ * result_unseen = unseen;
+
+ return MAIL_NO_ERROR;
+
+ close_db_flags:
+ mail_cache_db_close_unlock(filename_flags, cache_db_flags);
+ err:
+ return res;
+}
+
+static int pop3driver_cached_messages_number(mailsession * session,
+ char * mb,
+ uint32_t * result)
+{
+ return mailsession_messages_number(get_ancestor(session), mb, result);
+}
+
+static int pop3driver_cached_recent_number(mailsession * session,
+ char * mb,
+ uint32_t * result)
+{
+ uint32_t messages;
+ uint32_t recent;
+ uint32_t unseen;
+ int r;
+
+ r = pop3driver_cached_status_folder(session, mb,
+ &messages, &recent, &unseen);
+ if (r != MAIL_NO_ERROR)
+ return r;
+
+ * result = recent;
+
+ return MAIL_NO_ERROR;
+}
+
+static int pop3driver_cached_unseen_number(mailsession * session,
+ char * mb,
+ uint32_t * result)
+{
+ uint32_t messages;
+ uint32_t recent;
+ uint32_t unseen;
+ int r;
+
+ r = pop3driver_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 pop3driver_cached_remove_message(mailsession * session,
+ uint32_t num)
+{
+ return mailsession_remove_message(get_ancestor(session), num);
+}
+
+static int
+pop3driver_cached_get_messages_list(mailsession * session,
+ struct mailmessage_list ** result)
+{
+ mailpop3 * pop3;
+
+ pop3 = get_pop3_session(session);
+
+ return pop3_get_messages_list(pop3, session,
+ pop3_cached_message_driver, result);
+}
+
+
+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 mailpop3_msg_info * info;
+ struct mailimf_fields * fields;
+ int res;
+ mailpop3 * pop3;
+
+ pop3 = get_pop3_session(session);
+
+ r = mailpop3_get_msg_info(pop3, num, &info);
+ switch (r) {
+ case MAILPOP3_ERROR_BAD_STATE:
+ return MAIL_ERROR_BAD_STATE;
+ case MAILPOP3_ERROR_NO_SUCH_MESSAGE:
+ return MAIL_ERROR_MSG_NOT_FOUND;
+ case MAILPOP3_NO_ERROR:
+ break;
+ default:
+ return MAIL_ERROR_FETCH;
+ }
+
+ snprintf(keyname, PATH_MAX, "%s-envelope", info->msg_uidl);
+
+ 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 mailpop3_msg_info * info;
+ mailpop3 * pop3;
+
+ pop3 = get_pop3_session(session);
+
+ r = mailpop3_get_msg_info(pop3, num, &info);
+ switch (r) {
+ case MAILPOP3_ERROR_BAD_STATE:
+ return MAIL_ERROR_BAD_STATE;
+ case MAILPOP3_ERROR_NO_SUCH_MESSAGE:
+ return MAIL_ERROR_MSG_NOT_FOUND;
+ case MAILPOP3_NO_ERROR:
+ break;
+ default:
+ return MAIL_ERROR_FETCH;
+ }
+
+ snprintf(keyname, PATH_MAX, "%s-envelope", info->msg_uidl);
+
+ 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 void get_uid_from_filename(char * filename)
+{
+ char * p;
+
+ p = strstr(filename, "-header");
+ if (p != NULL)
+ * p = 0;
+}
+
+static int
+pop3driver_cached_get_envelopes_list(mailsession * session,
+ struct mailmessage_list * env_list)
+{
+ int r;
+ unsigned int i;
+ struct pop3_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;
+
+ cached_data = get_cached_data(session);
+
+ pop3_flags_store_process(cached_data->pop3_flags_directory,
+ cached_data->pop3_flags_store);
+
+ snprintf(filename_env, PATH_MAX, "%s/%s",
+ cached_data->pop3_cache_directory, ENV_NAME);
+
+ mmapstr = mmap_string_new("");
+ if (mmapstr == NULL) {
+ res = MAIL_ERROR_MEMORY;
+ goto err;
+ }
+
+ r = mail_cache_db_open_lock(filename_env, &cache_db_env);
+ if (r < 0) {
+ res = MAIL_ERROR_MEMORY;
+ goto free_mmapstr;
+ }
+
+ snprintf(filename_flags, PATH_MAX, "%s/%s",
+ cached_data->pop3_flags_directory, FLAGS_NAME);
+
+ r = mail_cache_db_open_lock(filename_flags, &cache_db_flags);
+ if (r < 0) {
+ res = MAIL_ERROR_MEMORY;
+ goto close_db_env;
+ }
+
+ /* fill with cached */
+
+ for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) {
+ mailmessage * msg;
+ struct mailimf_fields * fields;
+ struct mail_flags * flags;
+
+ msg = carray_get(env_list->msg_tab, i);
+
+ if (msg->msg_fields == NULL) {
+ r = get_cached_envelope(cache_db_env, mmapstr,
+ session, msg->msg_index, &fields);
+ if (r == MAIL_NO_ERROR) {
+ msg->msg_cached = TRUE;
+ msg->msg_fields = fields;
+ }
+ }
+
+ if (msg->msg_flags == NULL) {
+ r = pop3driver_get_cached_flags(cache_db_flags, mmapstr,
+ session, msg->msg_index, &flags);
+ if (r == MAIL_NO_ERROR) {
+ msg->msg_flags = flags;
+ }
+ }
+ }
+
+ mail_cache_db_close_unlock(filename_flags, cache_db_flags);
+ mail_cache_db_close_unlock(filename_env, cache_db_env);
+
+ r = maildriver_generic_get_envelopes_list(session, env_list);
+
+ if (r != MAIL_NO_ERROR) {
+ res = r;
+ goto free_mmapstr;
+ }
+
+ /* add flags */
+
+ for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) {
+ mailmessage * msg;
+
+ msg = carray_get(env_list->msg_tab, i);
+
+ if (msg->msg_flags == NULL)
+ msg->msg_flags = mail_flags_new_empty();
+ }
+
+ r = mail_cache_db_open_lock(filename_env, &cache_db_env);
+ if (r < 0) {
+ res = MAIL_ERROR_MEMORY;
+ goto free_mmapstr;
+ }
+
+ r = mail_cache_db_open_lock(filename_flags, &cache_db_flags);
+ if (r < 0) {
+ res = MAIL_ERROR_MEMORY;
+ goto close_db_env;
+ }
+
+ /* must write cache */
+
+ for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) {
+ mailmessage * msg;
+
+ msg = carray_get(env_list->msg_tab, i);
+
+ if (msg->msg_fields != NULL) {
+ if (!msg->msg_cached) {
+ r = write_cached_envelope(cache_db_env, mmapstr,
+ session, msg->msg_index, msg->msg_fields);
+ }
+ }
+
+ if (msg->msg_flags != NULL) {
+ r = pop3driver_write_cached_flags(cache_db_flags, mmapstr,
+ msg->msg_uid, msg->msg_flags);
+ }
+ }
+
+ /* flush cache */
+
+ maildriver_cache_clean_up(cache_db_env, cache_db_flags, env_list);
+
+ mail_cache_db_close_unlock(filename_flags, cache_db_flags);
+ mail_cache_db_close_unlock(filename_env, cache_db_env);
+ mmap_string_free(mmapstr);
+
+ /* remove cache files */
+
+ maildriver_message_cache_clean_up(cached_data->pop3_cache_directory,
+ env_list, get_uid_from_filename);
+
+ return MAIL_NO_ERROR;
+
+ close_db_env:
+ mail_cache_db_close_unlock(filename_env, cache_db_env);
+ free_mmapstr:
+ mmap_string_free(mmapstr);
+ err:
+ return res;
+}
+
+static int pop3driver_cached_get_message(mailsession * session,
+ uint32_t num, mailmessage ** result)
+{
+ mailmessage * msg_info;
+ int r;
+
+ msg_info = mailmessage_new();
+ if (msg_info == NULL)
+ return MAIL_ERROR_MEMORY;
+
+ r = mailmessage_init(msg_info, session, pop3_cached_message_driver, num, 0);
+ if (r != MAIL_NO_ERROR) {
+ mailmessage_free(msg_info);
+ return r;
+ }
+
+ * result = msg_info;
+
+ return MAIL_NO_ERROR;
+}
+
+static int pop3driver_cached_get_message_by_uid(mailsession * session,
+ const char * uid, mailmessage ** result)
+{
+ mailpop3 * pop3;
+ struct mailpop3_msg_info * msg_info;
+ int found;
+ unsigned int i;
+
+ if (uid == NULL)
+ return MAIL_ERROR_INVAL;
+
+ pop3 = get_pop3_session(session);
+
+ found = 0;
+
+ /* iterate all messages and look for uid */
+ for(i = 0 ; i < carray_count(pop3->pop3_msg_tab) ; i++) {
+ msg_info = carray_get(pop3->pop3_msg_tab, i);
+
+ if (msg_info == NULL)
+ continue;
+
+ if (msg_info->msg_deleted)
+ continue;
+
+ /* uid found, stop looking */
+ if (strcmp(msg_info->msg_uidl, uid) == 0) {
+ found = 1;
+ break;
+ }
+ }
+
+ if (!found)
+ return MAIL_ERROR_MSG_NOT_FOUND;
+
+ return pop3driver_cached_get_message(session, msg_info->msg_index, result);
+}
diff --git a/libetpan/src/driver/implementation/pop3/pop3driver_cached.h b/libetpan/src/driver/implementation/pop3/pop3driver_cached.h
new file mode 100644
index 0000000..4f4b6c9
--- a/dev/null
+++ b/libetpan/src/driver/implementation/pop3/pop3driver_cached.h
@@ -0,0 +1,52 @@
+/*
+ * libEtPan! -- a mail stuff library
+ *
+ * Copyright (C) 2001, 2005 - 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 AUTHORS 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 AUTHORS 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 POP3DRIVER_CACHED_H
+
+#define POP3DRIVER_CACHED_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <libetpan/pop3driver_types.h>
+
+extern mailsession_driver * pop3_cached_session_driver;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libetpan/src/driver/implementation/pop3/pop3driver_cached_message.c b/libetpan/src/driver/implementation/pop3/pop3driver_cached_message.c
new file mode 100644
index 0000000..4eed0db
--- a/dev/null
+++ b/libetpan/src/driver/implementation/pop3/pop3driver_cached_message.c
@@ -0,0 +1,355 @@
+/*
+ * libEtPan! -- a mail stuff library
+ *
+ * Copyright (C) 2001, 2005 - 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 AUTHORS 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 AUTHORS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * $Id$
+ */
+
+#include "pop3driver_cached_message.h"
+
+#include <string.h>
+#include <stdlib.h>
+
+#include "mail_cache_db.h"
+
+#include "mailmessage.h"
+#include "mailmessage_tools.h"
+#include "pop3driver.h"
+#include "pop3driver_tools.h"
+#include "pop3driver_cached.h"
+#include "pop3driver_message.h"
+#include "generic_cache.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 void pop3_flush(mailmessage * msg_info);
+
+static void pop3_check(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 int pop3_get_flags(mailmessage * msg_info,
+ struct mail_flags ** result);
+
+static void pop3_uninitialize(mailmessage * msg_info);
+
+static mailmessage_driver local_pop3_cached_message_driver = {
+ .msg_name = "pop3-cached",
+
+ .msg_initialize = pop3_initialize,
+ .msg_uninitialize = pop3_uninitialize,
+
+ .msg_flush = pop3_flush,
+ .msg_check = pop3_check,
+
+ .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 = pop3_get_flags,
+};
+
+mailmessage_driver * pop3_cached_message_driver =
+&local_pop3_cached_message_driver;
+
+
+static inline struct pop3_cached_session_state_data *
+get_cached_session_data(mailmessage * msg)
+{
+ return msg->msg_session->sess_data;
+}
+
+static inline mailsession * get_ancestor_session(mailmessage * msg)
+{
+ return get_cached_session_data(msg)->pop3_ancestor;
+}
+
+static inline struct pop3_session_state_data *
+get_ancestor_session_data(mailmessage * msg)
+{
+ return get_ancestor_session(msg)->sess_data;
+}
+
+static inline mailpop3 * get_pop3_session(mailmessage * msg)
+{
+ return get_ancestor_session_data(msg)->pop3_session;
+}
+
+
+static int pop3_prefetch(mailmessage * msg_info)
+{
+ char * msg_content;
+ size_t msg_length;
+ struct generic_message_t * msg;
+ int r;
+ struct pop3_cached_session_state_data * cached_data;
+ char filename[PATH_MAX];
+
+ /* we try the cached message */
+
+ cached_data = get_cached_session_data(msg_info);
+
+ snprintf(filename, PATH_MAX, "%s/%s",
+ cached_data->pop3_cache_directory, msg_info->msg_uid);
+
+ r = generic_cache_read(filename, &msg_content, &msg_length);
+ if (r == MAIL_NO_ERROR) {
+ msg = msg_info->msg_data;
+
+ msg->msg_message = msg_content;
+ msg->msg_length = msg_length;
+
+ return MAIL_NO_ERROR;
+ }
+
+ /* we get the message through the network */
+
+ r = pop3driver_retr(get_ancestor_session(msg_info), msg_info->msg_index,
+ &msg_content, &msg_length);
+ if (r != MAIL_NO_ERROR)
+ return r;
+
+ /* we write the message cache */
+
+ generic_cache_store(filename, msg_content, msg_length);
+
+ 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);
+
+ 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) {
+ 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 void pop3_uninitialize(mailmessage * msg_info)
+{
+ mailmessage_generic_uninitialize(msg_info);
+}
+
+#define FLAGS_NAME "flags.db"
+
+static void pop3_flush(mailmessage * msg_info)
+{
+ mailmessage_generic_flush(msg_info);
+}
+
+static void pop3_check(mailmessage * msg_info)
+{
+ int r;
+
+ if (msg_info->msg_flags != NULL) {
+ r = mail_flags_store_set(get_cached_session_data(msg_info)->pop3_flags_store,
+ msg_info);
+ }
+}
+
+
+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;
+ struct pop3_cached_session_state_data * cached_data;
+ char filename[PATH_MAX];
+
+ msg = msg_info->msg_data;
+
+ if (msg->msg_message != NULL)
+ return mailmessage_generic_fetch_header(msg_info,
+ result, result_len);
+
+ /* we try the cached message */
+
+ cached_data = get_cached_session_data(msg_info);
+
+ snprintf(filename, PATH_MAX, "%s/%s-header",
+ cached_data->pop3_cache_directory, msg_info->msg_uid);
+
+ r = generic_cache_read(filename, &headers, &headers_length);
+ if (r == MAIL_NO_ERROR) {
+ * result = headers;
+ * result_len = headers_length;
+
+ return MAIL_NO_ERROR;
+ }
+
+ /* we get the message trough the network */
+
+ r = pop3driver_header(get_ancestor_session(msg_info), msg_info->msg_index,
+ &headers, &headers_length);
+ if (r != MAIL_NO_ERROR)
+ return r;
+
+ generic_cache_store(filename, headers, headers_length);
+
+ * result = headers;
+ * result_len = headers_length;
+
+ return MAIL_NO_ERROR;
+}
+
+static int pop3_fetch_size(mailmessage * msg_info,
+ size_t * result)
+{
+ return pop3driver_size(get_ancestor_session(msg_info),
+ msg_info->msg_index, result);
+}
+
+static int pop3_get_flags(mailmessage * msg_info,
+ struct mail_flags ** result)
+{
+ int r;
+ struct mail_flags * flags;
+ struct mail_cache_db * cache_db_flags;
+ char filename_flags[PATH_MAX];
+ int res;
+ struct pop3_cached_session_state_data * cached_data;
+ MMAPString * mmapstr;
+
+ if (msg_info->msg_flags != NULL) {
+ * result = msg_info->msg_flags;
+
+ return MAIL_NO_ERROR;
+ }
+
+ cached_data = get_cached_session_data(msg_info);
+
+ flags = mail_flags_store_get(cached_data->pop3_flags_store,
+ msg_info->msg_index);
+
+ if (flags == NULL) {
+ snprintf(filename_flags, PATH_MAX, "%s/%s",
+ cached_data->pop3_flags_directory, FLAGS_NAME);
+
+ r = mail_cache_db_open_lock(filename_flags, &cache_db_flags);
+ if (r < 0) {
+ res = MAIL_ERROR_MEMORY;
+ goto err;
+ }
+
+ mmapstr = mmap_string_new("");
+ if (mmapstr == NULL) {
+ res = MAIL_ERROR_MEMORY;
+ goto close_db_flags;
+ }
+
+ r = pop3driver_get_cached_flags(cache_db_flags, mmapstr,
+ msg_info->msg_session, msg_info->msg_index, &flags);
+ if (r != MAIL_NO_ERROR) {
+ flags = mail_flags_new_empty();
+ if (flags == NULL) {
+ res = MAIL_ERROR_MEMORY;
+ goto free_mmapstr;
+ }
+ }
+
+ mmap_string_free(mmapstr);
+ mail_cache_db_close_unlock(filename_flags, cache_db_flags);
+ }
+
+ msg_info->msg_flags = flags;
+
+ * result = flags;
+
+ return MAIL_NO_ERROR;
+
+ free_mmapstr:
+ mmap_string_free(mmapstr);
+ close_db_flags:
+ mail_cache_db_close_unlock(filename_flags, cache_db_flags);
+ err:
+ return res;
+}
diff --git a/libetpan/src/driver/implementation/pop3/pop3driver_cached_message.h b/libetpan/src/driver/implementation/pop3/pop3driver_cached_message.h
new file mode 100644
index 0000000..f13cec7
--- a/dev/null
+++ b/libetpan/src/driver/implementation/pop3/pop3driver_cached_message.h
@@ -0,0 +1,52 @@
+/*
+ * libEtPan! -- a mail stuff library
+ *
+ * Copyright (C) 2001, 2005 - 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 AUTHORS 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 AUTHORS 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 POP3DRIVER_CACHED_MESSAGE_H
+
+#define POP3DRIVER_CACHED_MESSAGE_H
+
+#include <libetpan/pop3driver_types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern mailmessage_driver * pop3_cached_message_driver;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libetpan/src/driver/implementation/pop3/pop3driver_message.c b/libetpan/src/driver/implementation/pop3/pop3driver_message.c
new file mode 100644
index 0000000..6ea8979
--- a/dev/null
+++ b/libetpan/src/driver/implementation/pop3/pop3driver_message.c
@@ -0,0 +1,193 @@
+/*
+ * libEtPan! -- a mail stuff library
+ *
+ * Copyright (C) 2001, 2005 - 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 AUTHORS 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 AUTHORS 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) {
+ 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/libetpan/src/driver/implementation/pop3/pop3driver_message.h b/libetpan/src/driver/implementation/pop3/pop3driver_message.h
new file mode 100644
index 0000000..ad0a01b
--- a/dev/null
+++ b/libetpan/src/driver/implementation/pop3/pop3driver_message.h
@@ -0,0 +1,52 @@
+/*
+ * libEtPan! -- a mail stuff library
+ *
+ * Copyright (C) 2001, 2005 - 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 AUTHORS 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 AUTHORS 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 POP3DRIVER_MESSAGE_H
+
+#define POP3DRIVER_MESSAGE_H
+
+#include <libetpan/pop3driver_types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern mailmessage_driver * pop3_message_driver;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libetpan/src/driver/implementation/pop3/pop3driver_tools.c b/libetpan/src/driver/implementation/pop3/pop3driver_tools.c
new file mode 100644
index 0000000..73dd22a
--- a/dev/null
+++ b/libetpan/src/driver/implementation/pop3/pop3driver_tools.c
@@ -0,0 +1,344 @@
+/*
+ * libEtPan! -- a mail stuff library
+ *
+ * Copyright (C) 2001, 2005 - 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 AUTHORS 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 AUTHORS 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_tools.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include "maildriver_types.h"
+#include "mailpop3.h"
+#include "pop3driver.h"
+#include "pop3driver_cached.h"
+#include "generic_cache.h"
+#include "imfcache.h"
+#include "mailmessage.h"
+#include "mail_cache_db.h"
+
+int pop3driver_pop3_error_to_mail_error(int error)
+{
+ switch (error) {
+ case MAILPOP3_NO_ERROR:
+ return MAIL_NO_ERROR;
+
+ case MAILPOP3_ERROR_BAD_STATE:
+ return MAIL_ERROR_BAD_STATE;
+
+ case MAILPOP3_ERROR_UNAUTHORIZED:
+ return MAIL_ERROR_CONNECT;
+
+ case MAILPOP3_ERROR_STREAM:
+ return MAIL_ERROR_STREAM;
+
+ case MAILPOP3_ERROR_DENIED:
+ return MAIL_ERROR_CONNECT;
+
+ case MAILPOP3_ERROR_BAD_USER:
+ case MAILPOP3_ERROR_BAD_PASSWORD:
+ return MAIL_ERROR_LOGIN;
+
+ case MAILPOP3_ERROR_CANT_LIST:
+ return MAIL_ERROR_LIST;
+
+ case MAILPOP3_ERROR_NO_SUCH_MESSAGE:
+ return MAIL_ERROR_MSG_NOT_FOUND;
+
+ case MAILPOP3_ERROR_MEMORY:
+ return MAIL_ERROR_MEMORY;
+
+ case MAILPOP3_ERROR_CONNECTION_REFUSED:
+ return MAIL_ERROR_CONNECT;
+
+ case MAILPOP3_ERROR_APOP_NOT_SUPPORTED:
+ return MAIL_ERROR_NO_APOP;
+
+ case MAILPOP3_ERROR_CAPA_NOT_SUPPORTED:
+ return MAIL_ERROR_CAPABILITY;
+
+ case MAILPOP3_ERROR_STLS_NOT_SUPPORTED:
+ return MAIL_ERROR_NO_TLS;
+
+ default:
+ return MAIL_ERROR_INVAL;
+ }
+};
+
+static inline struct pop3_session_state_data *
+session_get_data(mailsession * session)
+{
+ return session->sess_data;
+}
+
+static inline mailpop3 * session_get_pop3_session(mailsession * session)
+{
+ return session_get_data(session)->pop3_session;
+}
+
+static inline struct pop3_cached_session_state_data *
+cached_session_get_data(mailsession * session)
+{
+ return session->sess_data;
+}
+
+static inline mailsession *
+cached_session_get_ancestor(mailsession * session)
+{
+ return cached_session_get_data(session)->pop3_ancestor;
+}
+
+static inline struct pop3_session_state_data *
+cached_session_get_ancestor_data(mailsession * session)
+{
+ return session_get_data(cached_session_get_ancestor(session));
+}
+
+static inline mailpop3 *
+cached_session_get_pop3_session(mailsession * session)
+{
+ return session_get_pop3_session(cached_session_get_ancestor(session));
+}
+
+
+int pop3driver_retr(mailsession * session, uint32_t index,
+ char ** result, size_t * result_len)
+{
+ char * msg_content;
+ size_t msg_length;
+ int r;
+
+ r = mailpop3_retr(session_get_pop3_session(session), index,
+ &msg_content, &msg_length);
+
+ switch (r) {
+ case MAILPOP3_NO_ERROR:
+ break;
+ default:
+ return pop3driver_pop3_error_to_mail_error(r);
+ }
+
+ * result = msg_content;
+ * result_len = msg_length;
+
+ return MAIL_NO_ERROR;
+}
+
+int pop3driver_header(mailsession * session, uint32_t index,
+ char ** result,
+ size_t * result_len)
+{
+ char * headers;
+ size_t headers_length;
+ int r;
+
+ r = mailpop3_header(session_get_pop3_session(session),
+ index, &headers, &headers_length);
+
+ switch (r) {
+ case MAILPOP3_NO_ERROR:
+ break;
+ default:
+ return pop3driver_pop3_error_to_mail_error(r);
+ }
+
+ * result = headers;
+ * result_len = headers_length;
+
+ return MAIL_NO_ERROR;
+}
+
+int pop3driver_size(mailsession * session, uint32_t index,
+ size_t * result)
+{
+ mailpop3 * pop3;
+ carray * msg_tab;
+ struct mailpop3_msg_info * info;
+ int r;
+
+ pop3 = session_get_pop3_session(session);
+
+ mailpop3_list(pop3, &msg_tab);
+
+ r = mailpop3_get_msg_info(pop3, index, &info);
+ switch (r) {
+ case MAILPOP3_NO_ERROR:
+ break;
+ default:
+ return pop3driver_pop3_error_to_mail_error(r);
+ }
+
+ * result = info->msg_size;
+
+ return MAIL_NO_ERROR;
+}
+
+int
+pop3driver_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 mailpop3_msg_info * info;
+
+ r = mailpop3_get_msg_info(cached_session_get_pop3_session(session),
+ num, &info);
+ switch (r) {
+ case MAILPOP3_ERROR_BAD_STATE:
+ return MAIL_ERROR_BAD_STATE;
+ case MAILPOP3_ERROR_NO_SUCH_MESSAGE:
+ return MAIL_ERROR_MSG_NOT_FOUND;
+ case MAILPOP3_NO_ERROR:
+ break;
+ default:
+ return MAIL_ERROR_FETCH;
+ }
+
+ snprintf(keyname, PATH_MAX, "%s-flags", info->msg_uidl);
+
+ 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
+pop3driver_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 pop3_get_messages_list(mailpop3 * pop3,
+ mailsession * session,
+ mailmessage_driver * driver,
+ struct mailmessage_list ** result)
+{
+ carray * msg_tab;
+ carray * tab;
+ struct mailmessage_list * env_list;
+ unsigned int i;
+ int res;
+ int r;
+
+ mailpop3_list(pop3, &msg_tab);
+
+ tab = carray_new(128);
+ if (tab == NULL) {
+ res = MAIL_ERROR_MEMORY;
+ goto err;
+ }
+
+ for(i = 0 ; i < carray_count(msg_tab) ; i++) {
+ struct mailpop3_msg_info * pop3_info;
+ mailmessage * msg;
+
+ pop3_info = carray_get(msg_tab, i);
+
+ if (pop3_info == NULL)
+ continue;
+
+ if (pop3_info->msg_deleted)
+ continue;
+
+ msg = mailmessage_new();
+ if (msg == NULL) {
+ res = MAIL_ERROR_MEMORY;
+ goto free_list;
+ }
+
+ r = mailmessage_init(msg, session, driver,
+ (uint32_t) pop3_info->msg_index, pop3_info->msg_size);
+ if (r != MAIL_NO_ERROR) {
+ mailmessage_free(msg);
+ res = r;
+ goto free_list;
+ }
+
+ r = carray_add(tab, msg, NULL);
+ if (r < 0) {
+ mailmessage_free(msg);
+ res = MAIL_ERROR_MEMORY;
+ goto free_list;
+ }
+ }
+
+ env_list = mailmessage_list_new(/*list*/ tab);
+ if (env_list == NULL) {
+ res = MAIL_ERROR_MEMORY;
+ goto free_list;
+ }
+
+ * result = env_list;
+
+ return MAIL_NO_ERROR;
+
+ free_list:
+ for(i = 0 ; i < carray_count(tab) ; i ++)
+ mailmessage_free(carray_get(tab, i));
+ carray_free(tab);
+ err:
+ return res;
+}
diff --git a/libetpan/src/driver/implementation/pop3/pop3driver_tools.h b/libetpan/src/driver/implementation/pop3/pop3driver_tools.h
new file mode 100644
index 0000000..e6413aa
--- a/dev/null
+++ b/libetpan/src/driver/implementation/pop3/pop3driver_tools.h
@@ -0,0 +1,82 @@
+/*
+ * libEtPan! -- a mail stuff library
+ *
+ * Copyright (C) 2001, 2005 - 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 AUTHORS 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 AUTHORS 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 POP3DRIVER_TOOLS_H
+
+#define POP3DRIVER_TOOLS_H
+
+#include "mail_cache_db_types.h"
+#include "pop3driver_types.h"
+#include "mailpop3.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int pop3driver_pop3_error_to_mail_error(int error);
+
+int pop3driver_retr(mailsession * session, uint32_t index,
+ char ** result, size_t * result_len);
+
+int pop3driver_header(mailsession * session, uint32_t index,
+ char ** result,
+ size_t * result_len);
+
+int pop3driver_size(mailsession * session, uint32_t index,
+ size_t * result);
+
+int
+pop3driver_get_cached_flags(struct mail_cache_db * cache_db,
+ MMAPString * mmapstr,
+ mailsession * session,
+ uint32_t num,
+ struct mail_flags ** result);
+
+int
+pop3driver_write_cached_flags(struct mail_cache_db * cache_db,
+ MMAPString * mmapstr,
+ char * uid,
+ struct mail_flags * flags);
+
+int pop3_get_messages_list(mailpop3 * pop3,
+ mailsession * session,
+ mailmessage_driver * driver,
+ struct mailmessage_list ** result);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libetpan/src/driver/implementation/pop3/pop3driver_types.h b/libetpan/src/driver/implementation/pop3/pop3driver_types.h
new file mode 100644
index 0000000..4bb872c
--- a/dev/null
+++ b/libetpan/src/driver/implementation/pop3/pop3driver_types.h
@@ -0,0 +1,153 @@
+/*
+ * libEtPan! -- a mail stuff library
+ *
+ * Copyright (C) 2001, 2005 - 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 AUTHORS 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 AUTHORS 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 POP3DRIVER_TYPES_H
+
+#define POP3DRIVER_TYPES_H
+
+#include <libetpan/libetpan-config.h>
+
+#include <libetpan/maildriver_types.h>
+#include <libetpan/mailpop3.h>
+#include <libetpan/maildriver_types.h>
+#include <libetpan/chash.h>
+#include <libetpan/mailstorage_types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* POP3 driver for session */
+
+enum {
+ POP3DRIVER_SET_AUTH_TYPE = 1,
+};
+
+enum {
+ POP3DRIVER_AUTH_TYPE_PLAIN = 0,
+ POP3DRIVER_AUTH_TYPE_APOP,
+ POP3DRIVER_AUTH_TYPE_TRY_APOP,
+};
+
+struct pop3_session_state_data {
+ int pop3_auth_type;
+ mailpop3 * pop3_session;
+};
+
+/* cached POP3 driver for session */
+
+enum {
+ /* the mapping of the parameters should be the same as for pop3 */
+ POP3DRIVER_CACHED_SET_AUTH_TYPE = 1,
+ /* cache specific */
+ POP3DRIVER_CACHED_SET_CACHE_DIRECTORY,
+ POP3DRIVER_CACHED_SET_FLAGS_DIRECTORY,
+};
+
+struct pop3_cached_session_state_data {
+ mailsession * pop3_ancestor;
+ char pop3_cache_directory[PATH_MAX];
+ char pop3_flags_directory[PATH_MAX];
+ chash * pop3_flags_hash;
+ carray * pop3_flags_array;
+ struct mail_flags_store * pop3_flags_store;
+};
+
+/* pop3 storage */
+
+/*
+ pop3_mailstorage is the state data specific to the POP3 storage.
+
+ - servername this is the name of the POP3 server
+
+ - port is the port to connect to, on the server.
+ you give 0 to use the default port.
+
+ - connection_type is the type of socket layer to use.
+ The value can be CONNECTION_TYPE_PLAIN, CONNECTION_TYPE_STARTTLS,
+ CONNECTION_TYPE_TRY_STARTTLS or CONNECTION_TYPE_TLS.
+
+ - auth_type is the authenticate mechanism to use.
+ The value can be POP3_AUTH_TYPE_PLAIN, POP3_AUTH_TYPE_APOP
+ or POP3_AUTH_TYPE_TRY_APOP. Other values are not yet implemented.
+
+ - login is the login of the POP3 account.
+
+ - password is the password of the POP3 account.
+
+ - cached if this value is != 0, a persistant cache will be
+ stored on local system.
+
+ - cache_directory is the location of the cache.
+
+ - flags_directory is the location of the flags.
+*/
+
+struct pop3_mailstorage {
+ 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;
+};
+
+/* this is the type of POP3 authentication */
+
+enum {
+ POP3_AUTH_TYPE_PLAIN, /* plain text authentication */
+ POP3_AUTH_TYPE_APOP, /* APOP authentication */
+ POP3_AUTH_TYPE_TRY_APOP, /* first, try APOP, if it fails,
+ try plain text */
+ POP3_AUTH_TYPE_SASL_ANONYMOUS, /* SASL anonymous */
+ POP3_AUTH_TYPE_SASL_CRAM_MD5, /* SASL CRAM MD5 */
+ POP3_AUTH_TYPE_SASL_KERBEROS_V4, /* SASL KERBEROS V4 */
+ POP3_AUTH_TYPE_SASL_PLAIN, /* SASL plain */
+ POP3_AUTH_TYPE_SASL_SCRAM_MD5, /* SASL SCRAM MD5 */
+ POP3_AUTH_TYPE_SASL_GSSAPI, /* SASL GSSAPI */
+ POP3_AUTH_TYPE_SASL_DIGEST_MD5, /* SASL digest MD5 */
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libetpan/src/driver/implementation/pop3/pop3storage.c b/libetpan/src/driver/implementation/pop3/pop3storage.c
new file mode 100644
index 0000000..1cff650
--- a/dev/null
+++ b/libetpan/src/driver/implementation/pop3/pop3storage.c
@@ -0,0 +1,284 @@
+/*
+ * libEtPan! -- a mail stuff library
+ *
+ * Copyright (C) 2001, 2005 - 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 AUTHORS 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 AUTHORS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * $Id$
+ */
+
+#include "pop3storage.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "mail.h"
+#include "mailstorage_tools.h"
+#include "maildriver.h"
+
+/* pop3 storage */
+
+#define POP3_DEFAULT_PORT 110
+#define POP3S_DEFAULT_PORT 995
+
+static int pop3_mailstorage_connect(struct mailstorage * storage);
+static int pop3_mailstorage_get_folder_session(struct mailstorage * storage,
+ char * pathname, mailsession ** result);
+static void pop3_mailstorage_uninitialize(struct mailstorage * storage);
+
+static mailstorage_driver pop3_mailstorage_driver = {
+ .sto_name = "pop3",
+ .sto_connect = pop3_mailstorage_connect,
+ .sto_get_folder_session = pop3_mailstorage_get_folder_session,
+ .sto_uninitialize = pop3_mailstorage_uninitialize,
+};
+
+int pop3_mailstorage_init(struct mailstorage * storage,
+ char * pop3_servername, uint16_t pop3_port,
+ char * pop3_command,
+ int pop3_connection_type, int pop3_auth_type,
+ char * pop3_login, char * pop3_password,
+ int pop3_cached, char * pop3_cache_directory, char * pop3_flags_directory)
+{
+ struct pop3_mailstorage * pop3_storage;
+
+ pop3_storage = malloc(sizeof(* pop3_storage));
+ if (pop3_storage == NULL)
+ goto err;
+
+ pop3_storage->pop3_servername = strdup(pop3_servername);
+ if (pop3_storage->pop3_servername == NULL)
+ goto free;
+
+ pop3_storage->pop3_connection_type = pop3_connection_type;
+
+ if (pop3_port == 0) {
+ switch (pop3_connection_type) {
+ case CONNECTION_TYPE_PLAIN:
+ case CONNECTION_TYPE_TRY_STARTTLS:
+ case CONNECTION_TYPE_STARTTLS:
+ case CONNECTION_TYPE_COMMAND:
+ case CONNECTION_TYPE_COMMAND_TRY_STARTTLS:
+ case CONNECTION_TYPE_COMMAND_STARTTLS:
+ pop3_port = POP3_DEFAULT_PORT;
+ break;
+
+ case CONNECTION_TYPE_TLS:
+ case CONNECTION_TYPE_COMMAND_TLS:
+ pop3_port = POP3S_DEFAULT_PORT;
+ break;
+ }
+ }
+
+ pop3_storage->pop3_port = pop3_port;
+
+ if (pop3_command != NULL) {
+ pop3_storage->pop3_command = strdup(pop3_command);
+ if (pop3_storage->pop3_command == NULL)
+ goto free_servername;
+ }
+ else
+ pop3_storage->pop3_command = NULL;
+
+ pop3_storage->pop3_auth_type = pop3_auth_type;
+
+ if (pop3_login != NULL) {
+ pop3_storage->pop3_login = strdup(pop3_login);
+ if (pop3_storage->pop3_login == NULL)
+ goto free_command;
+ }
+ else
+ pop3_storage->pop3_login = NULL;
+
+ if (pop3_password != NULL) {
+ pop3_storage->pop3_password = strdup(pop3_password);
+ if (pop3_storage->pop3_password == NULL)
+ goto free_login;
+ }
+ else
+ pop3_storage->pop3_password = NULL;
+
+ pop3_storage->pop3_cached = pop3_cached;
+
+ if (pop3_cached && (pop3_cache_directory != NULL) &&
+ (pop3_flags_directory != NULL)) {
+ pop3_storage->pop3_cache_directory = strdup(pop3_cache_directory);
+ if (pop3_storage->pop3_cache_directory == NULL)
+ goto free_password;
+ pop3_storage->pop3_flags_directory = strdup(pop3_flags_directory);
+ if (pop3_storage->pop3_flags_directory == NULL)
+ goto free_cache_directory;
+ }
+ else {
+ pop3_storage->pop3_cached = FALSE;
+ pop3_storage->pop3_cache_directory = NULL;
+ pop3_storage->pop3_flags_directory = NULL;
+ }
+
+ storage->sto_data = pop3_storage;
+ storage->sto_driver = &pop3_mailstorage_driver;
+
+ return MAIL_NO_ERROR;
+
+ free_cache_directory:
+ free(pop3_storage->pop3_cache_directory);
+ free_password:
+ if (pop3_storage->pop3_password != NULL)
+ free(pop3_storage->pop3_password);
+ free_login:
+ if (pop3_storage->pop3_login != NULL)
+ free(pop3_storage->pop3_login);
+ free_command:
+ if (pop3_storage->pop3_command != NULL)
+ free(pop3_storage->pop3_command);
+ free_servername:
+ if (pop3_storage->pop3_servername != NULL)
+ free(pop3_storage->pop3_servername);
+ free:
+ free(pop3_storage);
+ err:
+ return MAIL_ERROR_MEMORY;
+}
+
+static void pop3_mailstorage_uninitialize(struct mailstorage * storage)
+{
+ struct pop3_mailstorage * pop3_storage;
+
+ pop3_storage = storage->sto_data;
+
+ if (pop3_storage->pop3_flags_directory != NULL)
+ free(pop3_storage->pop3_flags_directory);
+ if (pop3_storage->pop3_cache_directory != NULL)
+ free(pop3_storage->pop3_cache_directory);
+ if (pop3_storage->pop3_password != NULL)
+ free(pop3_storage->pop3_password);
+ if (pop3_storage->pop3_login != NULL)
+ free(pop3_storage->pop3_login);
+ if (pop3_storage->pop3_command != NULL)
+ free(pop3_storage->pop3_command);
+ free(pop3_storage->pop3_servername);
+ free(pop3_storage);
+
+ storage->sto_data = pop3_storage;
+}
+
+static int pop3_mailstorage_connect(struct mailstorage * storage)
+{
+ struct pop3_mailstorage * pop3_storage;
+ mailsession_driver * driver;
+ int r;
+ int res;
+ mailsession * session;
+ int auth_type;
+
+ pop3_storage = storage->sto_data;
+
+ if (pop3_storage->pop3_cached)
+ driver = pop3_cached_session_driver;
+ else
+ driver = pop3_session_driver;
+
+ r = mailstorage_generic_connect(driver,
+ pop3_storage->pop3_servername,
+ pop3_storage->pop3_port, pop3_storage->pop3_command,
+ pop3_storage->pop3_connection_type,
+ POP3DRIVER_CACHED_SET_CACHE_DIRECTORY,
+ pop3_storage->pop3_cache_directory,
+ POP3DRIVER_CACHED_SET_FLAGS_DIRECTORY,
+ pop3_storage->pop3_flags_directory,
+ &session);
+ switch (r) {
+ case MAIL_NO_ERROR_NON_AUTHENTICATED:
+ case MAIL_NO_ERROR_AUTHENTICATED:
+ case MAIL_NO_ERROR:
+ break;
+ default:
+ res = r;
+ goto err;
+ }
+
+ auth_type = -1;
+ switch (pop3_storage->pop3_auth_type) {
+ case POP3_AUTH_TYPE_PLAIN:
+ auth_type = POP3DRIVER_AUTH_TYPE_PLAIN;
+ break;
+ case POP3_AUTH_TYPE_APOP:
+ auth_type = POP3DRIVER_AUTH_TYPE_APOP;
+ break;
+ case POP3_AUTH_TYPE_TRY_APOP:
+ auth_type = POP3DRIVER_AUTH_TYPE_TRY_APOP;
+ break;
+ }
+
+ if (auth_type != -1) {
+ mailsession_parameters(session, POP3DRIVER_SET_AUTH_TYPE, &auth_type);
+ }
+
+ r = mailstorage_generic_auth(session, r,
+ pop3_storage->pop3_auth_type,
+ pop3_storage->pop3_login,
+ pop3_storage->pop3_password);
+ if (r != MAIL_NO_ERROR) {
+ if (pop3_storage->pop3_auth_type == POP3_AUTH_TYPE_TRY_APOP) {
+ /* try in clear authentication */
+ mailsession_free(session);
+
+ pop3_storage->pop3_auth_type = POP3_AUTH_TYPE_PLAIN;
+ r = mailstorage_connect(storage);
+ if (r != MAIL_NO_ERROR) {
+ res = r;
+ return res;
+ }
+ pop3_storage->pop3_auth_type = POP3_AUTH_TYPE_TRY_APOP;
+
+ return MAIL_NO_ERROR;
+ }
+
+ res = r;
+ goto free;
+ }
+
+ storage->sto_session = session;
+
+ return MAIL_NO_ERROR;
+
+ free:
+ mailsession_free(session);
+ err:
+ return res;
+}
+
+static int pop3_mailstorage_get_folder_session(struct mailstorage * storage,
+ char * pathname, mailsession ** result)
+{
+ * result = storage->sto_session;
+
+ return MAIL_NO_ERROR;
+}
+
diff --git a/libetpan/src/driver/implementation/pop3/pop3storage.h b/libetpan/src/driver/implementation/pop3/pop3storage.h
new file mode 100644
index 0000000..e8cd513
--- a/dev/null
+++ b/libetpan/src/driver/implementation/pop3/pop3storage.h
@@ -0,0 +1,95 @@
+/*
+ * libEtPan! -- a mail stuff library
+ *
+ * Copyright (C) 2001, 2005 - 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 AUTHORS 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 AUTHORS 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 POP3STORAGE_H
+
+#define POP3STORAGE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <libetpan/pop3driver_types.h>
+#include <libetpan/pop3driver.h>
+#include <libetpan/pop3driver_cached.h>
+
+/*
+ pop3_mailstorage_init is the constructor for a POP3 storage
+
+ @param storage this is the storage to initialize.
+
+ @param servername this is the name of the POP3 server
+
+ @param port is the port to connect to, on the server.
+ you give 0 to use the default port.
+
+ @param command the command used to connect to the server instead of
+ allowing normal TCP connections to be used.
+
+ @param connection_type is the type of socket layer to use.
+ The value can be CONNECTION_TYPE_PLAIN, CONNECTION_TYPE_STARTTLS,
+ CONNECTION_TYPE_TRY_STARTTLS, CONNECTION_TYPE_TLS,
+ CONNECTION_TYPE_COMMAND, CONNECTION_TYPE_COMMAND_STARTTLS,
+ CONNECTION_TYPE_COMMAND_TRY_STARTTLS, CONNECTION_TYPE_COMMAND_TLS,.
+
+ @param auth_type is the authenticate mechanism to use.
+ The value can be POP3_AUTH_TYPE_PLAIN, POP3_AUTH_TYPE_APOP
+ or POP3_AUTH_TYPE_TRY_APOP. Other values are not yet implemented.
+
+ @param login is the login of the POP3 account.
+
+ @param password is the password of the POP3 account.
+
+ @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 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);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif