summaryrefslogtreecommitdiffabout
path: root/libetpan/src/driver/interface
Side-by-side diff
Diffstat (limited to 'libetpan/src/driver/interface') (more/less context) (ignore whitespace changes)
-rw-r--r--libetpan/src/driver/interface/maildriver.c383
-rw-r--r--libetpan/src/driver/interface/maildriver.h546
-rw-r--r--libetpan/src/driver/interface/maildriver_errors.h102
-rw-r--r--libetpan/src/driver/interface/maildriver_tools.c841
-rw-r--r--libetpan/src/driver/interface/maildriver_tools.h81
-rw-r--r--libetpan/src/driver/interface/maildriver_types.c340
-rw-r--r--libetpan/src/driver/interface/maildriver_types.h795
-rw-r--r--libetpan/src/driver/interface/maildriver_types_helper.c104
-rw-r--r--libetpan/src/driver/interface/maildriver_types_helper.h99
-rw-r--r--libetpan/src/driver/interface/mailfolder.c138
-rw-r--r--libetpan/src/driver/interface/mailfolder.h70
-rw-r--r--libetpan/src/driver/interface/mailmessage.c240
-rw-r--r--libetpan/src/driver/interface/mailmessage.h379
-rw-r--r--libetpan/src/driver/interface/mailmessage_tools.c600
-rw-r--r--libetpan/src/driver/interface/mailmessage_tools.h103
-rw-r--r--libetpan/src/driver/interface/mailmessage_types.c92
-rw-r--r--libetpan/src/driver/interface/mailmessage_types.h50
-rw-r--r--libetpan/src/driver/interface/mailstorage.c341
-rw-r--r--libetpan/src/driver/interface/mailstorage.h99
-rw-r--r--libetpan/src/driver/interface/mailstorage_tools.c372
-rw-r--r--libetpan/src/driver/interface/mailstorage_tools.h67
-rw-r--r--libetpan/src/driver/interface/mailstorage_types.h203
22 files changed, 6045 insertions, 0 deletions
diff --git a/libetpan/src/driver/interface/maildriver.c b/libetpan/src/driver/interface/maildriver.c
new file mode 100644
index 0000000..5b6c4f2
--- a/dev/null
+++ b/libetpan/src/driver/interface/maildriver.c
@@ -0,0 +1,383 @@
+/*
+ * 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 "maildriver.h"
+#include <ctype.h>
+#include <string.h>
+#include <stdlib.h>
+
+/* *********************************************************************** */
+/* mail session */
+
+mailsession * mailsession_new(mailsession_driver * sess_driver)
+{
+ mailsession * session;
+ int r;
+
+ session = malloc(sizeof(* session));
+
+ session->sess_data = NULL;
+
+ if (sess_driver->sess_initialize != NULL) {
+ r = sess_driver->sess_initialize(session);
+ if (r != MAIL_NO_ERROR)
+ goto free;
+ }
+
+ session->sess_driver = sess_driver;
+
+ return session;
+
+ free:
+ free(session);
+ return NULL;
+}
+
+void mailsession_free(mailsession * session)
+{
+ if (session->sess_driver->sess_uninitialize != NULL)
+ session->sess_driver->sess_uninitialize(session);
+ free(session);
+}
+
+int mailsession_parameters(mailsession * session,
+ int id, void * value)
+{
+ if (session->sess_driver->sess_parameters == NULL)
+ return MAIL_ERROR_NOT_IMPLEMENTED;
+
+ return session->sess_driver->sess_parameters(session, id, value);
+}
+
+int mailsession_connect_stream(mailsession * session, mailstream * s)
+{
+ if (session->sess_driver->sess_connect_stream == NULL)
+ return MAIL_ERROR_NOT_IMPLEMENTED;
+
+ return session->sess_driver->sess_connect_stream(session, s);
+}
+
+int mailsession_connect_path(mailsession * session, char * path)
+{
+ if (session->sess_driver->sess_connect_path == NULL)
+ return MAIL_ERROR_NOT_IMPLEMENTED;
+
+ return session->sess_driver->sess_connect_path(session, path);
+}
+
+int mailsession_starttls(mailsession * session)
+{
+ if (session->sess_driver->sess_starttls == NULL)
+ return MAIL_ERROR_NOT_IMPLEMENTED;
+
+ return session->sess_driver->sess_starttls(session);
+}
+
+int mailsession_login(mailsession * session,
+ char * userid, char * password)
+{
+ if (session->sess_driver->sess_login == NULL)
+ return MAIL_ERROR_NOT_IMPLEMENTED;
+
+ return session->sess_driver->sess_login(session, userid, password);
+}
+
+int mailsession_logout(mailsession * session)
+{
+ if (session->sess_driver->sess_logout == NULL)
+ return MAIL_ERROR_NOT_IMPLEMENTED;
+
+ return session->sess_driver->sess_logout(session);
+}
+
+int mailsession_noop(mailsession * session)
+{
+ if (session->sess_driver->sess_noop == NULL)
+ return MAIL_ERROR_NOT_IMPLEMENTED;
+
+ return session->sess_driver->sess_noop(session);
+}
+
+/* folders operations */
+
+int mailsession_build_folder_name(mailsession * session, char * mb,
+ char * name, char ** result)
+{
+ if (session->sess_driver->sess_build_folder_name == NULL)
+ return MAIL_ERROR_NOT_IMPLEMENTED;
+
+ return session->sess_driver->sess_build_folder_name(session,
+ mb, name, result);
+}
+
+int mailsession_create_folder(mailsession * session, char * mb)
+{
+ if (session->sess_driver->sess_create_folder == NULL)
+ return MAIL_ERROR_NOT_IMPLEMENTED;
+
+ return session->sess_driver->sess_create_folder(session, mb);
+}
+
+int mailsession_delete_folder(mailsession * session, char * mb)
+{
+ if (session->sess_driver->sess_delete_folder == NULL)
+ return MAIL_ERROR_NOT_IMPLEMENTED;
+
+ return session->sess_driver->sess_delete_folder(session, mb);
+}
+
+int mailsession_rename_folder(mailsession * session,
+ char * mb, char * new_name)
+{
+ if (session->sess_driver->sess_rename_folder == NULL)
+ return MAIL_ERROR_NOT_IMPLEMENTED;
+
+ return session->sess_driver->sess_rename_folder(session, mb, new_name);
+}
+
+int mailsession_check_folder(mailsession * session)
+{
+ if (session->sess_driver->sess_check_folder == NULL)
+ return MAIL_ERROR_NOT_IMPLEMENTED;
+
+ return session->sess_driver->sess_check_folder(session);
+}
+
+int mailsession_examine_folder(mailsession * session, char * mb)
+{
+ if (session->sess_driver->sess_examine_folder == NULL)
+ return MAIL_ERROR_NOT_IMPLEMENTED;
+
+ return session->sess_driver->sess_examine_folder(session, mb);
+}
+
+int mailsession_select_folder(mailsession * session, char * mb)
+{
+ if (session->sess_driver->sess_select_folder == NULL)
+ return MAIL_ERROR_NOT_IMPLEMENTED;
+
+ return session->sess_driver->sess_select_folder(session, mb);
+}
+
+int mailsession_expunge_folder(mailsession * session)
+{
+ if (session->sess_driver->sess_expunge_folder == NULL)
+ return MAIL_ERROR_NOT_IMPLEMENTED;
+
+ return session->sess_driver->sess_expunge_folder(session);
+}
+
+int mailsession_status_folder(mailsession * session, char * mb,
+ uint32_t * result_messages, uint32_t * result_recent,
+ uint32_t * result_unseen)
+{
+ if (session->sess_driver->sess_status_folder == NULL)
+ return MAIL_ERROR_NOT_IMPLEMENTED;
+
+ return session->sess_driver->sess_status_folder(session, mb,
+ result_messages, result_recent, result_unseen);
+}
+
+int mailsession_messages_number(mailsession * session, char * mb,
+ uint32_t * result)
+{
+ if (session->sess_driver->sess_messages_number == NULL)
+ return MAIL_ERROR_NOT_IMPLEMENTED;
+
+ return session->sess_driver->sess_messages_number(session, mb, result);
+}
+
+int mailsession_recent_number(mailsession * session, char * mb,
+ uint32_t * result)
+{
+ if (session->sess_driver->sess_recent_number == NULL)
+ return MAIL_ERROR_NOT_IMPLEMENTED;
+
+ return session->sess_driver->sess_recent_number(session, mb, result);
+}
+
+int mailsession_unseen_number(mailsession * session, char * mb,
+ uint32_t * result)
+{
+ if (session->sess_driver->sess_unseen_number == NULL)
+ return MAIL_ERROR_NOT_IMPLEMENTED;
+
+ return session->sess_driver->sess_recent_number(session, mb, result);
+}
+
+int mailsession_list_folders(mailsession * session, char * mb,
+ struct mail_list ** result)
+{
+ if (session->sess_driver->sess_list_folders == NULL)
+ return MAIL_ERROR_NOT_IMPLEMENTED;
+
+ return session->sess_driver->sess_list_folders(session, mb, result);
+}
+
+int mailsession_lsub_folders(mailsession * session, char * mb,
+ struct mail_list ** result)
+{
+ if (session->sess_driver->sess_lsub_folders == NULL)
+ return MAIL_ERROR_NOT_IMPLEMENTED;
+
+ return session->sess_driver->sess_lsub_folders(session, mb, result);
+}
+
+int mailsession_subscribe_folder(mailsession * session, char * mb)
+{
+ if (session->sess_driver->sess_subscribe_folder == NULL)
+ return MAIL_ERROR_NOT_IMPLEMENTED;
+
+ return session->sess_driver->sess_subscribe_folder(session, mb);
+}
+
+int mailsession_unsubscribe_folder(mailsession * session, char * mb)
+{
+ if (session->sess_driver->sess_unsubscribe_folder == NULL)
+ return MAIL_ERROR_NOT_IMPLEMENTED;
+
+ return session->sess_driver->sess_unsubscribe_folder(session, mb);
+}
+
+/* message */
+
+int mailsession_append_message(mailsession * session,
+ char * message, size_t size)
+{
+ if (session->sess_driver->sess_append_message == NULL)
+ return MAIL_ERROR_NOT_IMPLEMENTED;
+
+ return session->sess_driver->sess_append_message(session, message, size);
+}
+
+int mailsession_append_message_flags(mailsession * session,
+ char * message, size_t size, struct mail_flags * flags)
+{
+ if (session->sess_driver->sess_append_message_flags == NULL)
+ return MAIL_ERROR_NOT_IMPLEMENTED;
+
+ return session->sess_driver->sess_append_message_flags(session,
+ message, size, flags);
+}
+
+int mailsession_copy_message(mailsession * session,
+ uint32_t num, char * mb)
+{
+ if (session->sess_driver->sess_copy_message == NULL)
+ return MAIL_ERROR_NOT_IMPLEMENTED;
+
+ return session->sess_driver->sess_copy_message(session, num, mb);
+}
+
+int mailsession_move_message(mailsession * session,
+ uint32_t num, char * mb)
+{
+ if (session->sess_driver->sess_move_message == NULL) {
+ int r;
+
+ if ((session->sess_driver->sess_copy_message == NULL) &&
+ (session->sess_driver->sess_remove_message == NULL))
+ return MAIL_ERROR_NOT_IMPLEMENTED;
+
+ r = mailsession_copy_message(session, num, mb);
+ if (r != MAIL_NO_ERROR)
+ return r;
+
+ r = mailsession_remove_message(session, num);
+ if (r != MAIL_NO_ERROR)
+ return r;
+
+ return MAIL_NO_ERROR;
+ }
+
+ return session->sess_driver->sess_move_message(session, num, mb);
+}
+
+int mailsession_get_envelopes_list(mailsession * session,
+ struct mailmessage_list * env_list)
+{
+ if (session->sess_driver->sess_get_envelopes_list == NULL)
+ return MAIL_ERROR_NOT_IMPLEMENTED;
+
+ return session->sess_driver->sess_get_envelopes_list(session, env_list);
+}
+
+int mailsession_get_messages_list(mailsession * session,
+ struct mailmessage_list ** result)
+{
+ if (session->sess_driver->sess_get_messages_list == NULL)
+ return MAIL_ERROR_NOT_IMPLEMENTED;
+
+ return session->sess_driver->sess_get_messages_list(session, result);
+}
+
+int mailsession_remove_message(mailsession * session, uint32_t num)
+{
+ if (session->sess_driver->sess_remove_message == NULL)
+ return MAIL_ERROR_NOT_IMPLEMENTED;
+
+ return session->sess_driver->sess_remove_message(session, num);
+}
+
+#if 0
+int mailsession_search_messages(mailsession * session, char * charset,
+ struct mail_search_key * key,
+ struct mail_search_result ** result)
+{
+ if (session->sess_driver->sess_search_messages == NULL)
+ return MAIL_ERROR_NOT_IMPLEMENTED;
+
+ return session->sess_driver->sess_search_messages(session,
+ charset, key, result);
+}
+#endif
+
+int mailsession_get_message(mailsession * session,
+ uint32_t num, mailmessage ** result)
+{
+ if (session->sess_driver->sess_get_message == NULL)
+ return MAIL_ERROR_NOT_IMPLEMENTED;
+
+ return session->sess_driver->sess_get_message(session, num, result);
+}
+
+int mailsession_get_message_by_uid(mailsession * session,
+ const char * uid, mailmessage ** result)
+{
+ if (session->sess_driver->sess_get_message_by_uid == NULL)
+ return MAIL_ERROR_NOT_IMPLEMENTED;
+
+ return session->sess_driver->sess_get_message_by_uid(session, uid, result);
+}
diff --git a/libetpan/src/driver/interface/maildriver.h b/libetpan/src/driver/interface/maildriver.h
new file mode 100644
index 0000000..16e830b
--- a/dev/null
+++ b/libetpan/src/driver/interface/maildriver.h
@@ -0,0 +1,546 @@
+/*
+ * 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 MAILDRIVER_H
+
+#define MAILDRIVER_H
+
+#include <libetpan/maildriver_types.h>
+#include <libetpan/maildriver_types_helper.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* mailsession */
+
+/*
+ mailsession_new creates a new session, using the given driver
+
+ @return the created session is returned
+*/
+
+mailsession * mailsession_new(mailsession_driver * sess_driver);
+
+/*
+ mailsession_free release the memory used by the session
+*/
+
+void mailsession_free(mailsession * session);
+
+/*
+ mailsession_parameters is used to make calls specific to the driver
+
+ @param id is the command to send to the driver,
+ usually, commands can be found in the header of the driver
+
+ @param value is the parameter of the specific call
+
+ @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
+ on error
+*/
+
+int mailsession_parameters(mailsession * session,
+ int id, void * value);
+
+/*
+ There are drivers of two kinds : stream drivers (driver that connects
+ to servers through TCP or other means of connection) and file drivers
+ (driver that are based on filesystem)
+
+ The following function can only be used by stream drivers.
+ mailsession_connect_stream connects a stream to the session
+
+ @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
+ on error
+*/
+
+int mailsession_connect_stream(mailsession * session, mailstream * s);
+
+/*
+ The following function can only be used by file drivers.
+ mailsession_connect_path selects the main path of the session
+
+ @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
+ on error
+*/
+
+int mailsession_connect_path(mailsession * session, char * path);
+
+/*
+ NOTE: works only on stream drivers
+
+ mailsession_starttls switches the current connection to TLS (secure layer)
+
+ @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
+ on error
+*/
+
+int mailsession_starttls(mailsession * session);
+
+/*
+ mailsession_login notifies the login and the password to authenticate
+ to the session
+
+ @param userid the given string is only needed at this function call
+ (it will be duplicated if necessary)
+ @param password the given string is only needed at this function call
+ (it will be duplicated if necessary)
+
+ @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
+ on error
+*/
+
+int mailsession_login(mailsession * session,
+ char * userid, char * password);
+
+/*
+ NOTE: this function doesn't often work on filsystem drivers
+
+ mailsession_logout deconnects the session and closes the stream.
+
+ @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
+ on error
+*/
+
+int mailsession_logout(mailsession * session);
+
+/*
+ mailsession_noop does no operation on the session, but it can be
+ used to poll for the status of the connection.
+
+ @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
+ on error
+*/
+
+int mailsession_noop(mailsession * session);
+
+/*
+ NOTE: driver's specific should be used
+
+ mailsession_build_folder_name will return an allocated string with
+ that contains the complete path of the folder to create
+
+ @param session the sesion
+ @param mb is the parent mailbox
+ @param name is the name of the folder to create
+ @param result the complete path of the folder to create will be
+ stored in (* result), this name have to be freed with free()
+
+ @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
+ on error
+*/
+
+int mailsession_build_folder_name(mailsession * session, char * mb,
+ char * name, char ** result);
+
+/*
+ NOTE: driver's specific should be used
+
+ mailsession_create_folder creates the folder that corresponds to the
+ given name
+
+ @param session the session
+ @param mb is the name of the mailbox
+
+ @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
+ on error
+*/
+
+int mailsession_create_folder(mailsession * session, char * mb);
+
+
+/*
+ NOTE: driver's specific should be used
+
+ mailsession_delete_folder deletes the folder that corresponds to the
+ given name
+
+ @param session the session
+ @param mb is the name of the mailbox
+
+ @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
+ on error
+*/
+
+int mailsession_delete_folder(mailsession * session, char * mb);
+
+
+/*
+ mailsession_rename_folder changes the name of the folder
+
+ @param session the session
+ @param mb is the name of the mailbox whose name has to be changed
+ @param new_name is the destination name (the parent
+ of the new folder folder can be other)
+
+ @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
+ on error
+*/
+
+int mailsession_rename_folder(mailsession * session,
+ char * mb, char * new_name);
+
+/*
+ mailsession_check_folder makes a checkpoint of the session
+
+ @param session the session
+
+ @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
+ on error
+*/
+
+int mailsession_check_folder(mailsession * session);
+
+
+/*
+ NOTE: this function is not implemented in most drivers
+
+ mailsession_examine_folder selects a mailbox as readonly
+
+ @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
+ on error
+*/
+
+int mailsession_examine_folder(mailsession * session, char * mb);
+
+
+/*
+ mailsession_select_folder selects a mailbox
+
+ @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
+ on error
+*/
+
+int mailsession_select_folder(mailsession * session, char * mb);
+
+
+/*
+ mailsession_expunge_folder deletes all messages marked \Deleted
+
+ @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
+ on error
+*/
+
+int mailsession_expunge_folder(mailsession * session);
+
+
+/*
+ mailsession_status_folder queries the status of the folder
+ (number of messages, number of recent messages, number of unseen messages)
+
+ @param session the session
+ @param mb mailbox to query
+ @param result_messages the number of messages is stored
+ in (* result_messages)
+ @param result_recent the number of messages is stored
+ in (* result_recent)
+ @param result_unseen the number of messages is stored
+ in (* result_unseen)
+
+ @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
+ on error
+*/
+
+int mailsession_status_folder(mailsession * session, char * mb,
+ uint32_t * result_messages, uint32_t * result_recent,
+ uint32_t * result_unseen);
+
+
+/*
+ mailsession_messages_number queries the number of messages in the folder
+
+ @param session the session
+ @param mb mailbox to query
+ @param result the number of messages is stored in (* result)
+
+ @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
+ on error
+*/
+
+int mailsession_messages_number(mailsession * session, char * mb,
+ uint32_t * result);
+
+/*
+ mailsession_recent_number queries the number of recent messages in the folder
+
+ @param session the session
+ @param mb mailbox to query
+ @param result the number of recent messages is stored in (* result)
+
+ @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
+ on error
+*/
+
+int mailsession_recent_number(mailsession * session,
+ char * mb, uint32_t * result);
+
+/*
+ mailsession_unseen_number queries the number of unseen messages in the folder
+
+ @param session the session
+ @param mb mailbox to query
+ @param result the number of unseen messages is stored in (* result)
+
+ @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
+ on error
+*/
+
+int mailsession_unseen_number(mailsession * session, char * mb,
+ uint32_t * result);
+
+/*
+ NOTE: driver's specific should be used
+
+ mailsession_list_folders returns the list of all sub-mailboxes
+ of the given mailbox
+
+ @param session the session
+ @param mb the mailbox
+ @param result list of mailboxes if stored in (* result),
+ this structure have to be freed with mail_list_free()
+
+ @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
+ on error
+*/
+
+int mailsession_list_folders(mailsession * session, char * mb,
+ struct mail_list ** result);
+
+/*
+ NOTE: driver's specific should be used
+
+ mailsession_lsub_folders returns the list of subscribed
+ sub-mailboxes of the given mailbox
+
+ @param session the session
+ @param mb the mailbox
+ @param result list of mailboxes if stored in (* result),
+ this structure have to be freed with mail_list_free()
+
+ @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
+ on error
+*/
+
+int mailsession_lsub_folders(mailsession * session, char * mb,
+ struct mail_list ** result);
+
+/*
+ NOTE: driver's specific should be used
+
+ mailsession_subscribe_folder subscribes to the given mailbox
+
+ @param session the session
+ @param mb the mailbox
+
+ @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
+ on error
+*/
+
+int mailsession_subscribe_folder(mailsession * session, char * mb);
+
+/*
+ NOTE: driver's specific should be used
+
+ mailsession_unsubscribe_folder unsubscribes to the given mailbox
+
+ @param session the session
+ @param mb the mailbox
+
+ @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
+ on error
+*/
+
+int mailsession_unsubscribe_folder(mailsession * session, char * mb);
+
+/*
+ mailsession_append_message adds a RFC 2822 message to the current
+ given mailbox
+
+ @param session the session
+ @param message is a string that contains the RFC 2822 message
+ @param size this is the size of the message
+
+ @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
+ on error
+*/
+
+int mailsession_append_message(mailsession * session,
+ char * message, size_t size);
+
+int mailsession_append_message_flags(mailsession * session,
+ char * message, size_t size, struct mail_flags * flags);
+
+/*
+ NOTE: some drivers does not implement this
+
+ mailsession_copy_message copies a message whose number is given to
+ a given mailbox. The mailbox must be accessible from the same session.
+
+ @param session the session
+ @param num the message number
+ @param mb the destination mailbox
+
+ @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
+ on error
+*/
+
+int mailsession_copy_message(mailsession * session,
+ uint32_t num, char * mb);
+
+/*
+ NOTE: some drivers does not implement this
+
+ mailsession_move_message copies a message whose number is given to
+ a given mailbox. The mailbox must be accessible from the same session.
+
+ @param session the session
+ @param num the message number
+ @param mb the destination mailbox
+
+ @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
+ on error
+*/
+
+int mailsession_move_message(mailsession * session,
+ uint32_t num, char * mb);
+
+/*
+ mailsession_get_messages_list returns the list of message numbers
+ of the current mailbox.
+
+ @param session the session
+ @param result the list of message numbers will be stored in (* result),
+ this structure have to be freed with mailmessage_list_free()
+
+ @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
+ on error
+*/
+
+int mailsession_get_messages_list(mailsession * session,
+ struct mailmessage_list ** result);
+
+/*
+ mailsession_get_envelopes_list fills the parsed fields in the
+ mailmessage structures of the mailmessage_list.
+
+ @param session the session
+ @param result this is the list of mailmessage structures
+
+ @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
+ on error
+*/
+
+int mailsession_get_envelopes_list(mailsession * session,
+ struct mailmessage_list * result);
+
+/*
+ NOTE: some drivers does not implement this
+
+ mailsession_remove_message removes the given message from the mailbox.
+ The message is permanently deleted.
+
+ @param session the session
+ @param num is the message number
+
+ @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
+ on error
+*/
+
+int mailsession_remove_message(mailsession * session, uint32_t num);
+
+
+/*
+ NOTE: this function is not implemented in most drivers
+
+ mailsession_search_message returns a list of message numbers that
+ corresponds to the given criteria.
+
+ @param session the session
+ @param charset is the charset to use (it can be NULL)
+ @param key is the list of criteria
+ @param result the search result is stored in (* result),
+ this structure have to be freed with mail_search_result_free()
+
+ @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
+ on error
+*/
+
+#if 0
+int mailsession_search_messages(mailsession * session, char * charset,
+ struct mail_search_key * key,
+ struct mail_search_result ** result);
+#endif
+
+/*
+ mailsession_get_message returns a mailmessage structure that corresponds
+ to the given message number.
+ * WARNING * mailsession_get_message_by_uid() should be used instead.
+
+ @param session the session
+ @param num the message number
+ @param result the allocated mailmessage structure will be stored
+ in (* result), this structure have to be freed with mailmessage_free()
+
+ @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
+ on error
+*/
+
+int mailsession_get_message(mailsession * session,
+ uint32_t num, mailmessage ** result);
+
+/*
+ mailsession_get_message_by_uid returns a mailmessage structure
+ that corresponds to the given message unique identifier.
+ This is currently implemented only for cached drivers.
+ * WARNING * That will deprecates the use of mailsession_get_message()
+
+ @param session the session
+ @param uid the message unique identifier
+ @param result the allocated mailmessage structure will be stored
+ in (* result), this structure have to be freed with mailmessage_free()
+
+ @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
+ on error
+*/
+
+int mailsession_get_message_by_uid(mailsession * session,
+ const char * uid, mailmessage ** result);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libetpan/src/driver/interface/maildriver_errors.h b/libetpan/src/driver/interface/maildriver_errors.h
new file mode 100644
index 0000000..99ec25c
--- a/dev/null
+++ b/libetpan/src/driver/interface/maildriver_errors.h
@@ -0,0 +1,102 @@
+/*
+ * 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 MAILDRIVER_ERRORS_H
+
+#define MAILDRIVER_ERRORS_H
+
+enum {
+ MAIL_NO_ERROR = 0,
+ MAIL_NO_ERROR_AUTHENTICATED,
+ MAIL_NO_ERROR_NON_AUTHENTICATED,
+ MAIL_ERROR_NOT_IMPLEMENTED,
+ MAIL_ERROR_UNKNOWN,
+ MAIL_ERROR_CONNECT,
+ MAIL_ERROR_BAD_STATE,
+ MAIL_ERROR_FILE,
+ MAIL_ERROR_STREAM,
+ MAIL_ERROR_LOGIN,
+ MAIL_ERROR_CREATE, /* 10 */
+ MAIL_ERROR_DELETE,
+ MAIL_ERROR_LOGOUT,
+ MAIL_ERROR_NOOP,
+ MAIL_ERROR_RENAME,
+ MAIL_ERROR_CHECK,
+ MAIL_ERROR_EXAMINE,
+ MAIL_ERROR_SELECT,
+ MAIL_ERROR_MEMORY,
+ MAIL_ERROR_STATUS,
+ MAIL_ERROR_SUBSCRIBE, /* 20 */
+ MAIL_ERROR_UNSUBSCRIBE,
+ MAIL_ERROR_LIST,
+ MAIL_ERROR_LSUB,
+ MAIL_ERROR_APPEND,
+ MAIL_ERROR_COPY,
+ MAIL_ERROR_FETCH,
+ MAIL_ERROR_STORE,
+ MAIL_ERROR_SEARCH,
+ MAIL_ERROR_DISKSPACE,
+ MAIL_ERROR_MSG_NOT_FOUND, /* 30 */
+ MAIL_ERROR_PARSE,
+ MAIL_ERROR_INVAL,
+ MAIL_ERROR_PART_NOT_FOUND,
+ MAIL_ERROR_REMOVE,
+ MAIL_ERROR_FOLDER_NOT_FOUND,
+ MAIL_ERROR_MOVE,
+ MAIL_ERROR_STARTTLS,
+ MAIL_ERROR_CACHE_MISS,
+ MAIL_ERROR_NO_TLS,
+ MAIL_ERROR_EXPUNGE, /* 40 */
+ /* misc errors */
+ MAIL_ERROR_MISC,
+ MAIL_ERROR_PROTOCOL,
+ MAIL_ERROR_CAPABILITY,
+ MAIL_ERROR_CLOSE,
+ MAIL_ERROR_FATAL,
+ MAIL_ERROR_READONLY,
+ MAIL_ERROR_NO_APOP,
+ MAIL_ERROR_COMMAND_NOT_SUPPORTED,
+ MAIL_ERROR_NO_PERMISSION,
+ MAIL_ERROR_PROGRAM_ERROR, /* 50 */
+ MAIL_ERROR_SUBJECT_NOT_FOUND,
+ MAIL_ERROR_CHAR_ENCODING_FAILED,
+ MAIL_ERROR_SEND,
+ MAIL_ERROR_COMMAND,
+ MAIL_ERROR_SYSTEM,
+ MAIL_ERROR_UNABLE,
+ MAIL_ERROR_FOLDER,
+};
+
+#endif
diff --git a/libetpan/src/driver/interface/maildriver_tools.c b/libetpan/src/driver/interface/maildriver_tools.c
new file mode 100644
index 0000000..4501b23
--- a/dev/null
+++ b/libetpan/src/driver/interface/maildriver_tools.c
@@ -0,0 +1,841 @@
+/*
+ * 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 "maildriver_tools.h"
+
+#include "libetpan-config.h"
+
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+#include <dirent.h>
+#include <unistd.h>
+
+#include "maildriver.h"
+#include "mailmessage.h"
+#include "mailstream.h"
+#include "mailmime.h"
+#include "mail_cache_db.h"
+
+/* ********************************************************************* */
+/* tools */
+
+
+int
+maildriver_generic_get_envelopes_list(mailsession * session,
+ struct mailmessage_list * env_list)
+{
+ int r;
+ unsigned i;
+#if 0
+ uint32_t j;
+ uint32_t last_msg;
+
+ last_msg = 0;
+#endif
+
+#if 0
+ j = 0;
+ i = 0;
+ while (i < env_list->tab->len) {
+ mailmessage * msg;
+ uint32_t index;
+
+ msg = carray_get(env_list->tab, i);
+
+ index = msg->index;
+
+ if (msg->fields == NULL) {
+ struct mailimf_fields * fields;
+
+ r = mailmessage_fetch_envelope(msg, &fields);
+ if (r != MAIL_NO_ERROR) {
+ /* do nothing */
+ }
+ else {
+ msg->fields = fields;
+
+ carray_set(env_list->tab, j, msg);
+
+ j ++;
+ last_msg = i + 1;
+ }
+ mailmessage_flush(msg);
+ }
+ else {
+ j ++;
+ last_msg = i + 1;
+ }
+
+ i ++;
+ }
+
+ for(i = last_msg ; i < env_list->tab->len ; i ++) {
+ mailmessage_free(carray_get(env_list->tab, i));
+ carray_set(env_list->tab, i, NULL);
+ }
+
+ r = carray_set_size(env_list->tab, j);
+ if (r < 0)
+ return MAIL_ERROR_MEMORY;
+#endif
+
+ 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) {
+ struct mailimf_fields * fields;
+
+ r = mailmessage_fetch_envelope(msg, &fields);
+ if (r != MAIL_NO_ERROR) {
+ /* do nothing */
+ }
+ else {
+ msg->msg_fields = fields;
+ }
+ mailmessage_flush(msg);
+ }
+ }
+
+ return MAIL_NO_ERROR;
+}
+
+
+#if 0
+static int is_search_header_only(struct mail_search_key * key)
+{
+ clistiter * cur;
+ int result;
+
+ switch (key->type) {
+ case MAIL_SEARCH_KEY_ANSWERED:
+ case MAIL_SEARCH_KEY_BCC:
+ case MAIL_SEARCH_KEY_BEFORE:
+ case MAIL_SEARCH_KEY_CC:
+ case MAIL_SEARCH_KEY_DELETED:
+ case MAIL_SEARCH_KEY_FLAGGED:
+ case MAIL_SEARCH_KEY_FROM:
+ case MAIL_SEARCH_KEY_NEW:
+ case MAIL_SEARCH_KEY_OLD:
+ case MAIL_SEARCH_KEY_ON:
+ case MAIL_SEARCH_KEY_RECENT:
+ case MAIL_SEARCH_KEY_SEEN:
+ case MAIL_SEARCH_KEY_SINCE:
+ case MAIL_SEARCH_KEY_SUBJECT:
+ case MAIL_SEARCH_KEY_TO:
+ case MAIL_SEARCH_KEY_UNANSWERED:
+ case MAIL_SEARCH_KEY_UNDELETED:
+ case MAIL_SEARCH_KEY_UNFLAGGED:
+ case MAIL_SEARCH_KEY_UNSEEN:
+ case MAIL_SEARCH_KEY_HEADER:
+ case MAIL_SEARCH_KEY_LARGER:
+ case MAIL_SEARCH_KEY_NOT:
+ case MAIL_SEARCH_KEY_SMALLER:
+ case MAIL_SEARCH_KEY_ALL:
+ return TRUE;
+
+ case MAIL_SEARCH_KEY_BODY:
+ case MAIL_SEARCH_KEY_TEXT:
+ return FALSE;
+
+ case MAIL_SEARCH_KEY_OR:
+ return (is_search_header_only(key->or1) &&
+ is_search_header_only(key->or2));
+
+ case MAIL_SEARCH_KEY_MULTIPLE:
+ result = TRUE;
+ for (cur = clist_begin(key->multiple) ; cur != NULL ;
+ cur = clist_next(cur))
+ result = result && is_search_header_only(clist_content(cur));
+ return result;
+
+ default:
+ return TRUE;
+ }
+}
+
+static int match_header(struct mailimf_fields * fields,
+ char * name, char * value)
+{
+ clistiter * cur;
+
+ for(cur = clist_begin(fields->list) ; cur != NULL ;
+ cur = clist_content(cur)) {
+ struct mailimf_field * field;
+ struct mailimf_optional_field * opt_field;
+
+ field = clist_content(cur);
+ opt_field = field->optional_field;
+ if ((char) toupper((unsigned char) opt_field->name[0]) ==
+ (char) toupper((unsigned char) name[0])) {
+ if (strcasecmp(opt_field->name, name) == 0)
+ if (strstr(opt_field->value, value) != NULL)
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+static int comp_date(struct mailimf_fields * fields,
+ struct mailimf_date_time * ref_date)
+{
+ clistiter * cur;
+ struct mailimf_date_time * date;
+ int r;
+
+ date = NULL;
+ for(cur = clist_begin(fields->list) ; cur != NULL ;
+ cur = clist_content(cur)) {
+ struct mailimf_field * field;
+ struct mailimf_optional_field * opt_field;
+
+ field = clist_content(cur);
+ opt_field = field->optional_field;
+ if ((char) toupper((unsigned char) opt_field->name[0]) == 'D') {
+ if (strcasecmp(opt_field->name, "Date") == 0) {
+ size_t cur_token;
+
+ cur_token = 0;
+ r = mailimf_date_time_parse(opt_field->value, strlen(opt_field->value),
+ &cur_token, &date);
+ if (r == MAILIMF_NO_ERROR)
+ break;
+ else if (r == MAILIMF_ERROR_PARSE) {
+ /* do nothing */
+ }
+ else
+ break;
+ }
+ }
+ }
+
+ if (date == NULL)
+ return 0;
+
+ return mailimf_date_time_comp(date, ref_date);
+}
+
+static int match_messages(char * message,
+ size_t size,
+ struct mailimf_fields * fields,
+ int32_t flags,
+ char * charset,
+ struct mail_search_key * key)
+{
+ clistiter * cur;
+ size_t length;
+ size_t cur_token;
+ int r;
+
+ switch (key->type) {
+
+ /* flags */
+ case MAIL_SEARCH_KEY_ANSWERED:
+ return ((flags & MAIL_FLAG_ANSWERED) != 0);
+
+ case MAIL_SEARCH_KEY_FLAGGED:
+ return ((flags & MAIL_FLAG_FLAGGED) != 0);
+
+ case MAIL_SEARCH_KEY_DELETED:
+ return ((flags & MAIL_FLAG_DELETED) != 0);
+
+ case MAIL_SEARCH_KEY_RECENT:
+ return ((flags & MAIL_FLAG_NEW) != 0) &&
+ ((flags & MAIL_FLAG_SEEN) == 0);
+
+ case MAIL_SEARCH_KEY_SEEN:
+ return ((flags & MAIL_FLAG_SEEN) != 0);
+
+ case MAIL_SEARCH_KEY_NEW:
+ return ((flags & MAIL_FLAG_NEW) != 0);
+
+ case MAIL_SEARCH_KEY_OLD:
+ return ((flags & MAIL_FLAG_NEW) == 0);
+
+ case MAIL_SEARCH_KEY_UNANSWERED:
+ return ((flags & MAIL_FLAG_ANSWERED) == 0);
+
+ case MAIL_SEARCH_KEY_UNDELETED:
+ return ((flags & MAIL_FLAG_DELETED) == 0);
+
+ case MAIL_SEARCH_KEY_UNFLAGGED:
+ return ((flags & MAIL_FLAG_FLAGGED) == 0);
+
+ case MAIL_SEARCH_KEY_UNSEEN:
+ return ((flags & MAIL_FLAG_SEEN) == 0);
+
+ /* headers */
+ case MAIL_SEARCH_KEY_BCC:
+ return match_header(fields, "Bcc", key->bcc);
+
+ case MAIL_SEARCH_KEY_CC:
+ return match_header(fields, "Cc", key->cc);
+
+ case MAIL_SEARCH_KEY_FROM:
+ return match_header(fields, "From", key->from);
+
+ case MAIL_SEARCH_KEY_SUBJECT:
+ return match_header(fields, "Subject", key->subject);
+
+ case MAIL_SEARCH_KEY_TO:
+ return match_header(fields, "To", key->to);
+
+ case MAIL_SEARCH_KEY_HEADER:
+ return match_header(fields, key->header_name, key->header_value);
+
+ /* date */
+ case MAIL_SEARCH_KEY_BEFORE:
+ return (comp_date(fields, key->before) <= 0);
+
+ case MAIL_SEARCH_KEY_ON:
+ return (comp_date(fields, key->before) == 0);
+
+ case MAIL_SEARCH_KEY_SINCE:
+ return (comp_date(fields, key->before) >= 0);
+
+ /* boolean */
+ case MAIL_SEARCH_KEY_NOT:
+ return (!match_messages(message, size, fields, flags, charset, key->not));
+ case MAIL_SEARCH_KEY_OR:
+ return (match_messages(message, size, fields, flags, charset, key->or1) ||
+ match_messages(message, size, fields, flags, charset, key->or2));
+
+ case MAIL_SEARCH_KEY_MULTIPLE:
+ for(cur = clist_begin(key->multiple) ; cur != NULL ;
+ cur = clist_next(cur)) {
+ if (!match_messages(message, size, fields, flags, charset,
+ clist_content(cur)))
+ return FALSE;
+ }
+
+ return TRUE;
+
+ /* size */
+ case MAIL_SEARCH_KEY_SMALLER:
+ return (size <= key->smaller);
+
+ case MAIL_SEARCH_KEY_LARGER:
+ return (size >= key->larger);
+
+ case MAIL_SEARCH_KEY_BODY:
+ length = strlen(message);
+
+ cur_token = 0;
+ while (1) {
+ r = mailimf_ignore_field_parse(message, length, &cur_token);
+ if (r == MAILIMF_NO_ERROR) {
+ /* do nothing */
+ }
+ else
+ break;
+ }
+
+ return (strstr(message + cur_token, key->body) != NULL);
+
+ case MAIL_SEARCH_KEY_TEXT:
+ return (strstr(message, key->body) != NULL);
+
+ case MAIL_SEARCH_KEY_ALL:
+ default:
+ return TRUE;
+ }
+}
+
+int maildriver_generic_search_messages(mailsession * session, char * charset,
+ struct mail_search_key * key,
+ struct mail_search_result ** result)
+{
+ int header;
+ clist * list;
+ struct mail_search_result * search_result;
+ int r;
+ struct mailmessage_list * env_list;
+ int res;
+ unsigned int i;
+
+ header = is_search_header_only(key);
+
+ r = mailsession_get_messages_list(session, &env_list);
+ if (r != MAIL_NO_ERROR)
+ return r;
+
+ list = NULL;
+ for(i = 0 ; i < carray_count(env_list->tab) ; i ++) {
+ char * message;
+ size_t length;
+ struct mail_info * info;
+ uint32_t flags;
+ struct mailimf_fields * fields;
+ size_t cur_token;
+
+ info = carray_get(env_list->tab, i);
+
+ if (!header) {
+ r = mailsession_fetch_message(session, info->index, &message, &length);
+ if (r != MAIL_NO_ERROR) {
+ res = r;
+ goto free_list;
+ }
+
+ cur_token = 0;
+ r = mailimf_optional_fields_parse(message, length,
+ &cur_token, &fields);
+ if (r != MAILIMF_NO_ERROR) {
+ res = MAIL_ERROR_PARSE;
+ goto free_list;
+ }
+ }
+ else {
+ char * msg_header;
+ int r;
+ size_t cur_token;
+ size_t header_len;
+
+ r = mailsession_fetch_message_header(session, info->index, &msg_header,
+ &header_len);
+ if (r != MAIL_NO_ERROR) {
+ res = r;
+ goto free_list;
+ }
+
+ message = NULL;
+ cur_token = 0;
+ r = mailimf_optional_fields_parse(msg_header, header_len,
+ &cur_token, &fields);
+ if (r != MAILIMF_NO_ERROR) {
+ res = MAIL_ERROR_PARSE;
+ goto free_list;
+ }
+
+ mailsession_fetch_result_free(session, msg_header);
+ }
+
+ r = mailsession_get_message_flags(session, info->index, &flags);
+ if (r != MAIL_NO_ERROR) {
+ res = r;
+ goto free_list;
+ }
+
+ if (match_messages(message, info->size, fields, flags,
+ charset, key)) {
+ uint32_t * pnum;
+
+ pnum = malloc(sizeof(* pnum));
+ if (pnum == NULL) {
+ if (message != NULL)
+ mailsession_fetch_result_free(session, message);
+ res = MAIL_ERROR_MEMORY;
+ goto free_list;
+ }
+
+ * pnum = info->index;
+
+ r = clist_append(list, pnum);
+ if (r < 0) {
+ free(pnum);
+ if (message != NULL)
+ mailsession_fetch_result_free(session, message);
+ res = MAIL_ERROR_MEMORY;
+ goto free_list;
+ }
+ }
+
+ if (message != NULL)
+ mailsession_fetch_result_free(session, message);
+ }
+
+ search_result = mail_search_result_new(list);
+ if (search_result == NULL) {
+ res = MAIL_ERROR_MEMORY;
+ goto free_list;
+ }
+
+ * result = search_result;
+
+ return MAIL_NO_ERROR;
+
+ free_list:
+ clist_foreach(list, (clist_func) free, NULL);
+ clist_free(list);
+ mailmessage_list_free(env_list);
+ return res;
+}
+#endif
+
+#if 0
+int maildriver_generic_search_messages(mailsession * session, char * charset,
+ struct mail_search_key * key,
+ struct mail_search_result ** result)
+{
+ return MAIL_ERROR_NOT_IMPLEMENTED;
+}
+#endif
+
+int
+maildriver_env_list_to_msg_list(struct mailmessage_list * env_list,
+ clist ** result)
+{
+ clist * msg_list;
+ int r;
+ int res;
+ unsigned int i;
+
+ msg_list = clist_new();
+ if (msg_list == NULL) {
+ res = MAIL_ERROR_MEMORY;
+ goto err;
+ }
+
+ 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) {
+ uint32_t * pindex;
+
+ pindex = malloc(sizeof(* pindex));
+ if (pindex == NULL) {
+ res = MAIL_ERROR_MEMORY;
+ goto free_msg_list;
+ }
+
+ * pindex = msg->msg_index;
+
+ r = clist_append(msg_list, pindex);
+ if (r < 0) {
+ free(pindex);
+ res = MAIL_ERROR_MEMORY;
+ goto free_msg_list;
+ }
+
+ }
+ }
+
+ * result = msg_list;
+
+ return MAIL_NO_ERROR;
+
+ free_msg_list:
+ clist_foreach(msg_list, (clist_func) free, NULL);
+ clist_free(msg_list);
+ err:
+ return res;
+}
+
+
+int
+maildriver_env_list_to_msg_list_no_flags(struct mailmessage_list * env_list,
+ clist ** result)
+{
+ clist * msg_list;
+ int r;
+ int res;
+ unsigned int i;
+
+ msg_list = clist_new();
+ if (msg_list == NULL) {
+ res = MAIL_ERROR_MEMORY;
+ goto err;
+ }
+
+ 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) {
+ uint32_t * pindex;
+
+ pindex = malloc(sizeof(* pindex));
+ if (pindex == NULL) {
+ res = MAIL_ERROR_MEMORY;
+ goto free_msg_list;
+ }
+
+ * pindex = msg->msg_index;
+
+ r = clist_append(msg_list, pindex);
+ if (r < 0) {
+ free(pindex);
+ res = MAIL_ERROR_MEMORY;
+ goto free_msg_list;
+ }
+
+ }
+ }
+
+ * result = msg_list;
+
+ return MAIL_NO_ERROR;
+
+ free_msg_list:
+ clist_foreach(msg_list, (clist_func) free, NULL);
+ clist_free(msg_list);
+ err:
+ return res;
+}
+
+
+
+int maildriver_imf_error_to_mail_error(int error)
+{
+ switch (error) {
+ case MAILIMF_NO_ERROR:
+ return MAIL_NO_ERROR;
+
+ case MAILIMF_ERROR_PARSE:
+ return MAIL_ERROR_PARSE;
+
+ case MAILIMF_ERROR_MEMORY:
+ return MAIL_ERROR_MEMORY;
+
+ case MAILIMF_ERROR_INVAL:
+ return MAIL_ERROR_INVAL;
+
+ case MAILIMF_ERROR_FILE:
+ return MAIL_ERROR_FILE;
+
+ default:
+ return MAIL_ERROR_INVAL;
+ }
+}
+
+char * maildriver_quote_mailbox(char * mb)
+{
+ MMAPString * gstr;
+ char * str;
+
+ gstr = mmap_string_new("");
+ if (gstr == NULL)
+ return NULL;
+
+ while (* mb != 0) {
+ char hex[3];
+
+ if (((* mb >= 'a') && (* mb <= 'z')) ||
+ ((* mb >= 'A') && (* mb <= 'Z')) ||
+ ((* mb >= '0') && (* mb <= '9')))
+ mmap_string_append_c(gstr, * mb);
+ else {
+ if (mmap_string_append_c(gstr, '%') == NULL)
+ goto free;
+ snprintf(hex, 3, "%02x", (unsigned char) (* mb));
+ if (mmap_string_append(gstr, hex) == NULL)
+ goto free;
+ }
+ mb ++;
+ }
+
+ str = strdup(gstr->str);
+ if (str == NULL)
+ goto free;
+
+ mmap_string_free(gstr);
+
+ return str;
+
+ free:
+ mmap_string_free(gstr);
+ return NULL;
+}
+
+
+
+int maildriver_cache_clean_up(struct mail_cache_db * cache_db_env,
+ struct mail_cache_db * cache_db_flags,
+ struct mailmessage_list * env_list)
+{
+ chash * hash_exist;
+ int res;
+ int r;
+ char keyname[PATH_MAX];
+ unsigned int i;
+
+ /* flush cache */
+
+ hash_exist = chash_new(CHASH_DEFAULTSIZE, CHASH_COPYALL);
+ if (hash_exist == NULL) {
+ res = MAIL_ERROR_MEMORY;
+ goto err;
+ }
+
+ for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) {
+ mailmessage * msg;
+ chashdatum key;
+ chashdatum value;
+
+ msg = carray_get(env_list->msg_tab, i);
+
+ value.data = NULL;
+ value.len = 0;
+
+ if (cache_db_env != NULL) {
+ snprintf(keyname, PATH_MAX, "%s-envelope", msg->msg_uid);
+
+ key.data = keyname;
+ key.len = strlen(keyname);
+ r = chash_set(hash_exist, &key, &value, NULL);
+ if (r < 0) {
+ res = MAIL_ERROR_MEMORY;
+ goto free;
+ }
+ }
+
+ if (cache_db_flags != NULL) {
+ snprintf(keyname, PATH_MAX, "%s-flags", msg->msg_uid);
+
+ key.data = keyname;
+ key.len = strlen(keyname);
+ r = chash_set(hash_exist, &key, &value, NULL);
+ if (r < 0) {
+ res = MAIL_ERROR_MEMORY;
+ goto free;
+ }
+ }
+ }
+
+ /* clean up */
+ if (cache_db_env != NULL)
+ mail_cache_db_clean_up(cache_db_env, hash_exist);
+ if (cache_db_flags != NULL)
+ mail_cache_db_clean_up(cache_db_flags, hash_exist);
+
+ chash_free(hash_exist);
+
+ return MAIL_NO_ERROR;
+
+ free:
+ chash_free(hash_exist);
+ err:
+ return res;
+}
+
+
+/*
+ maildriver_message_cache_clean_up()
+
+ remove files in cache_dir that does not correspond to a message.
+
+ get_uid_from_filename() modifies the given filename so that it
+ is a uid when returning from the function. If get_uid_from_filename()
+ clears the content of file (set to empty string), this means that
+ this file should not be deleted.
+*/
+
+int maildriver_message_cache_clean_up(char * cache_dir,
+ struct mailmessage_list * env_list,
+ void (* get_uid_from_filename)(char *))
+{
+ chash * hash_exist;
+ DIR * d;
+ char cached_filename[PATH_MAX];
+ struct dirent * ent;
+ char keyname[PATH_MAX];
+ unsigned int i;
+ int res;
+ int r;
+
+ /* remove files */
+
+ hash_exist = chash_new(CHASH_DEFAULTSIZE, CHASH_COPYALL);
+ if (hash_exist == NULL) {
+ res = MAIL_ERROR_MEMORY;
+ goto err;
+ }
+
+ for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) {
+ mailmessage * msg;
+ chashdatum key;
+ chashdatum value;
+
+ msg = carray_get(env_list->msg_tab, i);
+
+ key.data = msg->msg_uid;
+ key.len = strlen(msg->msg_uid);
+ value.data = NULL;
+ value.len = 0;
+ r = chash_set(hash_exist, &key, &value, NULL);
+ if (r < 0) {
+ res = MAIL_ERROR_MEMORY;
+ goto free;
+ }
+ }
+
+ d = opendir(cache_dir);
+ while ((ent = readdir(d)) != NULL) {
+ chashdatum key;
+ chashdatum value;
+
+ if (strcmp(ent->d_name, ".") == 0)
+ continue;
+
+ if (strcmp(ent->d_name, "..") == 0)
+ continue;
+
+ if (strstr(ent->d_name, ".db") != NULL)
+ continue;
+
+ strncpy(keyname, ent->d_name, sizeof(keyname));
+ keyname[sizeof(keyname) - 1] = '\0';
+
+ get_uid_from_filename(keyname);
+
+ if (* keyname == '\0')
+ continue;
+
+ key.data = keyname;
+ key.len = strlen(keyname);
+
+ r = chash_get(hash_exist, &key, &value);
+ if (r < 0) {
+ snprintf(cached_filename, sizeof(cached_filename),
+ "%s/%s", cache_dir, ent->d_name);
+ unlink(cached_filename);
+ }
+ }
+ closedir(d);
+
+ chash_free(hash_exist);
+
+ return MAIL_NO_ERROR;
+
+ free:
+ chash_free(hash_exist);
+ err:
+ return res;
+}
diff --git a/libetpan/src/driver/interface/maildriver_tools.h b/libetpan/src/driver/interface/maildriver_tools.h
new file mode 100644
index 0000000..a92af42
--- a/dev/null
+++ b/libetpan/src/driver/interface/maildriver_tools.h
@@ -0,0 +1,81 @@
+/*
+ * 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 MAILDRIVER_TOOLS_H
+
+#define MAILDRIVER_TOOLS_H
+
+#include "maildriver_types.h"
+#include "mail_cache_db_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int
+maildriver_generic_get_envelopes_list(mailsession * session,
+ struct mailmessage_list * env_list);
+
+#if 0
+int maildriver_generic_search_messages(mailsession * session, char * charset,
+ struct mail_search_key * key,
+ struct mail_search_result ** result);
+#endif
+
+int
+maildriver_env_list_to_msg_list(struct mailmessage_list * env_list,
+ clist ** result);
+
+int maildriver_imf_error_to_mail_error(int error);
+
+char * maildriver_quote_mailbox(char * mb);
+
+int
+maildriver_env_list_to_msg_list_no_flags(struct mailmessage_list * env_list,
+ clist ** result);
+
+int maildriver_cache_clean_up(struct mail_cache_db * cache_db_env,
+ struct mail_cache_db * cache_db_flags,
+ struct mailmessage_list * env_list);
+
+int maildriver_message_cache_clean_up(char * cache_dir,
+ struct mailmessage_list * env_list,
+ void (* get_uid_from_filename)(char *));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libetpan/src/driver/interface/maildriver_types.c b/libetpan/src/driver/interface/maildriver_types.c
new file mode 100644
index 0000000..43f5c4f
--- a/dev/null
+++ b/libetpan/src/driver/interface/maildriver_types.c
@@ -0,0 +1,340 @@
+/*
+ * 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 "maildriver_types.h"
+#include <time.h>
+#include <stdlib.h>
+#include "mailmessage.h"
+
+struct mailmessage_list * mailmessage_list_new(carray * msg_tab)
+{
+ struct mailmessage_list * env_list;
+
+ env_list = malloc(sizeof(* env_list));
+ if (env_list == NULL)
+ return NULL;
+
+ env_list->msg_tab = msg_tab;
+
+ return env_list;
+}
+
+void mailmessage_list_free(struct mailmessage_list * env_list)
+{
+ unsigned int i;
+
+ for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) {
+ mailmessage * msg;
+
+ msg = carray_get(env_list->msg_tab, i);
+ if (msg != NULL)
+ mailmessage_free(msg);
+ }
+ carray_free(env_list->msg_tab);
+ free(env_list);
+}
+
+struct mail_list * mail_list_new(clist * list)
+{
+ struct mail_list * resp;
+
+ resp = malloc(sizeof(* resp));
+ if (resp == NULL)
+ return NULL;
+ resp->mb_list = list;
+
+ return resp;
+}
+
+void mail_list_free(struct mail_list * resp)
+{
+ clist_foreach(resp->mb_list, (clist_func) free, NULL);
+ clist_free(resp->mb_list);
+ free(resp);
+}
+
+static int32_t mailimf_date_time_to_int(struct mailimf_date_time * date)
+{
+ return date->dt_year * 12 * 30 * 24 * 60 * 60 +
+ date->dt_month * 30 * 24 * 60 * 60 + date->dt_day * 24 * 60 * 60 +
+ (date->dt_hour - date->dt_zone) * 60 * 60 +
+ date->dt_min * 60 + date->dt_sec;
+}
+
+int32_t mailimf_date_time_comp(struct mailimf_date_time * date1,
+ struct mailimf_date_time * date2)
+{
+ return mailimf_date_time_to_int(date1) - mailimf_date_time_to_int(date2);
+}
+
+
+
+
+
+
+
+#if 0
+struct mail_search_key *
+mail_search_key_new(int sk_type,
+ char * sk_bcc,
+ struct mailimf_date_time * sk_before,
+ char * sk_body,
+ char * sk_cc,
+ char * sk_from,
+ struct mailimf_date_time * sk_on,
+ struct mailimf_date_time * sk_since,
+ char * sk_subject,
+ char * sk_text,
+ char * sk_to,
+ char * sk_header_name,
+ char * sk_header_value,
+ size_t sk_larger,
+ struct mail_search_key * sk_not,
+ struct mail_search_key * sk_or1,
+ struct mail_search_key * sk_or2,
+ size_t sk_smaller,
+ clist * sk_multiple)
+{
+ struct mail_search_key * key;
+
+ key = malloc(sizeof(* key));
+ if (key == NULL)
+ return NULL;
+
+ key->sk_type = sk_type;
+ key->sk_bcc = sk_bcc;
+ key->sk_before = sk_before;
+ key->sk_body = sk_body;
+ key->sk_cc = sk_cc;
+ key->sk_from = sk_from;
+ key->sk_on = sk_on;
+ key->sk_since = sk_since;
+ key->sk_subject = sk_subject;
+ key->sk_text = sk_text;
+ key->sk_to = sk_to;
+ key->sk_header_name = sk_header_name;
+ key->sk_header_value = sk_header_value;
+ key->sk_larger = sk_larger;
+ key->sk_not = sk_not;
+ key->sk_or1 = sk_or1;
+ key->sk_or2 = sk_or2;
+ key->sk_smaller = sk_smaller;
+ key->sk_multiple = sk_multiple;
+
+ return key;
+}
+
+
+void mail_search_key_free(struct mail_search_key * key)
+{
+ if (key->sk_bcc)
+ free(key->sk_bcc);
+ if (key->sk_before)
+ mailimf_date_time_free(key->sk_before);
+ if (key->sk_body)
+ free(key->sk_body);
+ if (key->sk_cc)
+ free(key->sk_cc);
+ if (key->sk_from)
+ free(key->sk_from);
+ if (key->sk_on)
+ mailimf_date_time_free(key->sk_on);
+ if (key->sk_since)
+ mailimf_date_time_free(key->sk_since);
+ if (key->sk_subject)
+ free(key->sk_subject);
+ if (key->sk_text)
+ free(key->sk_text);
+ if (key->sk_to)
+ free(key->sk_to);
+ if (key->sk_header_name)
+ free(key->sk_header_name);
+ if (key->sk_header_value)
+ free(key->sk_header_value);
+ if (key->sk_not)
+ mail_search_key_free(key->sk_not);
+ if (key->sk_or1)
+ mail_search_key_free(key->sk_or1);
+ if (key->sk_or2)
+ mail_search_key_free(key->sk_or2);
+ if (key->sk_multiple) {
+ clist_foreach(key->sk_multiple, (clist_func) mail_search_key_free, NULL);
+ clist_free(key->sk_multiple);
+ }
+
+ free(key);
+}
+
+
+struct mail_search_result * mail_search_result_new(clist * list)
+{
+ struct mail_search_result * search_result;
+
+ search_result = malloc(sizeof(* search_result));
+ if (search_result == NULL)
+ return NULL;
+ search_result->list = list;
+
+ return search_result;
+}
+
+void mail_search_result_free(struct mail_search_result * search_result)
+{
+ clist_foreach(search_result->list, (clist_func) free, NULL);
+ clist_free(search_result->list);
+ free(search_result);
+}
+#endif
+
+struct error_message {
+ int code;
+ char * message;
+};
+
+static struct error_message message_tab[] = {
+{ MAIL_NO_ERROR, "no error" },
+{ MAIL_NO_ERROR_AUTHENTICATED, "no error - authenticated" },
+{ MAIL_NO_ERROR_NON_AUTHENTICATED, "no error - not authenticated" },
+{ MAIL_ERROR_NOT_IMPLEMENTED, "not implemented" },
+{ MAIL_ERROR_UNKNOWN, "unknown"},
+{ MAIL_ERROR_CONNECT, "connect"},
+{ MAIL_ERROR_BAD_STATE, "bad state"},
+{ MAIL_ERROR_FILE, "file error - file could not be accessed" },
+{ MAIL_ERROR_STREAM, "stream error - socket could not be read or written" },
+{ MAIL_ERROR_LOGIN, "login error" },
+{ MAIL_ERROR_CREATE, "create error" },
+{ MAIL_ERROR_DELETE, /* 10 */ "delete error" },
+{ MAIL_ERROR_LOGOUT, "logout error" },
+{ MAIL_ERROR_NOOP, "noop error" },
+{ MAIL_ERROR_RENAME, "rename error" },
+{ MAIL_ERROR_CHECK, "check error" },
+{ MAIL_ERROR_EXAMINE, "examine error" },
+{ MAIL_ERROR_SELECT, "select error - folder does not exist" },
+{ MAIL_ERROR_MEMORY, "not enough memory" },
+{ MAIL_ERROR_STATUS, "status error" },
+{ MAIL_ERROR_SUBSCRIBE, "subscribe error" },
+{ MAIL_ERROR_UNSUBSCRIBE, /* 20 */ "unsubscribe error" },
+{ MAIL_ERROR_LIST, "list error" },
+{ MAIL_ERROR_LSUB, "lsub error" },
+{ MAIL_ERROR_APPEND, "append error - mail could not be appended" },
+{ MAIL_ERROR_COPY, "copy error" },
+{ MAIL_ERROR_FETCH, "fetch error" },
+{ MAIL_ERROR_STORE, "store error" },
+{ MAIL_ERROR_SEARCH, "search error" },
+{ MAIL_ERROR_DISKSPACE, " error: not enough diskspace" },
+{ MAIL_ERROR_MSG_NOT_FOUND, "message not found" },
+{ MAIL_ERROR_PARSE, /* 30 */ "parse error" },
+{ MAIL_ERROR_INVAL, "invalid parameter for the function" },
+{ MAIL_ERROR_PART_NOT_FOUND, "mime part of the message is not found" },
+{ MAIL_ERROR_REMOVE, "remove error - the message did not exist" },
+{ MAIL_ERROR_FOLDER_NOT_FOUND, "folder not found" },
+{ MAIL_ERROR_MOVE, "move error" },
+{ MAIL_ERROR_STARTTLS, "starttls error" },
+{ MAIL_ERROR_CACHE_MISS, "mail cache missed" },
+{ MAIL_ERROR_NO_TLS, "no starttls" },
+{ MAIL_ERROR_EXPUNGE, "expunge error" },
+{ MAIL_ERROR_PROTOCOL, "protocol error - server did not respect the protocol" },
+{ MAIL_ERROR_CAPABILITY, "capability error" },
+{ MAIL_ERROR_CLOSE, "close error" },
+{ MAIL_ERROR_FATAL, "fatal error" },
+{ MAIL_ERROR_READONLY, "mailbox is readonly" },
+{ MAIL_ERROR_NO_APOP, "pop3 error - no apop" },
+{ MAIL_ERROR_COMMAND_NOT_SUPPORTED, "nntp error - command not supported" },
+{ MAIL_ERROR_NO_PERMISSION, "nntp error - no permission" },
+{ MAIL_ERROR_PROGRAM_ERROR, "nntp error - program error" },
+{ MAIL_ERROR_SUBJECT_NOT_FOUND, "internal threading error - subject not found" }};
+
+const char * maildriver_strerror(int err)
+{
+ int count;
+ int i;
+
+ count = sizeof(message_tab) / sizeof(struct error_message);
+
+ for(i = 0 ; i < count ; i++) {
+ if (message_tab[i].code == err) {
+ return message_tab[i].message;
+ }
+ }
+
+ return "unknown error";
+}
+
+
+struct mail_flags * mail_flags_new_empty(void)
+{
+ struct mail_flags * flags;
+
+ flags = malloc(sizeof(* flags));
+ if (flags == NULL)
+ goto err;
+
+ flags->fl_flags = MAIL_FLAG_NEW;
+ flags->fl_extension = clist_new();
+ if (flags->fl_extension == NULL)
+ goto free;
+
+ return flags;
+
+ free:
+ free(flags);
+ err:
+ return NULL;
+}
+
+struct mail_flags * mail_flags_new(uint32_t fl_flags, clist * fl_extension)
+{
+ struct mail_flags * flags;
+
+ flags = malloc(sizeof(* flags));
+ if (flags == NULL)
+ goto err;
+
+ flags->fl_flags = fl_flags;
+ flags->fl_extension = fl_extension;
+
+ return flags;
+
+err:
+ return NULL;
+}
+
+void mail_flags_free(struct mail_flags * flags)
+{
+ clist_foreach(flags->fl_extension, (clist_func) free, NULL);
+ clist_free(flags->fl_extension);
+ free(flags);
+}
+
diff --git a/libetpan/src/driver/interface/maildriver_types.h b/libetpan/src/driver/interface/maildriver_types.h
new file mode 100644
index 0000000..2225236
--- a/dev/null
+++ b/libetpan/src/driver/interface/maildriver_types.h
@@ -0,0 +1,795 @@
+/*
+ * 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 MAILDRIVER_TYPES_H
+
+#define MAILDRIVER_TYPES_H
+
+#include <inttypes.h>
+#include <sys/types.h>
+
+#include <libetpan/mailstream.h>
+#include <libetpan/mailimf.h>
+#include <libetpan/mailmime.h>
+#include <libetpan/carray.h>
+
+#include <libetpan/mailthread_types.h>
+#include <libetpan/maildriver_errors.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct mailsession_driver mailsession_driver;
+
+typedef struct mailsession mailsession;
+
+typedef struct mailmessage_driver mailmessage_driver;
+
+typedef struct mailmessage mailmessage;
+
+
+/*
+ mailmessage_list is a list of mailmessage
+
+ - tab is an array of mailmessage structures
+*/
+
+struct mailmessage_list {
+ carray * msg_tab; /* elements are (mailmessage *) */
+};
+
+struct mailmessage_list * mailmessage_list_new(carray * msg_tab);
+void mailmessage_list_free(struct mailmessage_list * env_list);
+
+/*
+ mail_list is a list of mailbox names
+
+ - list is a list of mailbox names
+*/
+
+struct mail_list {
+ clist * mb_list; /* elements are (char *) */
+};
+
+struct mail_list * mail_list_new(clist * mb_list);
+void mail_list_free(struct mail_list * resp);
+
+/*
+ This is a flag value.
+ Flags can be combined with OR operation
+*/
+
+enum {
+ MAIL_FLAG_NEW = 1 << 0,
+ MAIL_FLAG_SEEN = 1 << 1,
+ MAIL_FLAG_FLAGGED = 1 << 2,
+ MAIL_FLAG_DELETED = 1 << 3,
+ MAIL_FLAG_ANSWERED = 1 << 4,
+ MAIL_FLAG_FORWARDED = 1 << 5,
+ MAIL_FLAG_CANCELLED = 1 << 6,
+};
+
+/*
+ mail_flags is the value of a flag related to a message.
+
+ - flags is the standard flags value
+
+ - extension is a list of unknown flags for libEtPan!
+*/
+
+struct mail_flags {
+ uint32_t fl_flags;
+ clist * fl_extension; /* elements are (char *) */
+};
+
+struct mail_flags * mail_flags_new(uint32_t fl_flags, clist * fl_ext);
+void mail_flags_free(struct mail_flags * flags);
+
+/*
+ This function creates a flag for a new message
+*/
+
+struct mail_flags * mail_flags_new_empty(void);
+
+
+/*
+ mailimf_date_time_comp compares two dates
+
+
+*/
+
+int32_t mailimf_date_time_comp(struct mailimf_date_time * date1,
+ struct mailimf_date_time * date2);
+
+/*
+ this is type type of the search criteria
+*/
+
+enum {
+ MAIL_SEARCH_KEY_ALL, /* all messages correspond */
+ MAIL_SEARCH_KEY_ANSWERED, /* messages with flag \Answered */
+ MAIL_SEARCH_KEY_BCC, /* messages which Bcc field contains
+ a given string */
+ MAIL_SEARCH_KEY_BEFORE, /* messages which internal date is earlier
+ than the specified date */
+ MAIL_SEARCH_KEY_BODY, /* message that contains the given string
+ (in header and text parts) */
+ MAIL_SEARCH_KEY_CC, /* messages whose Cc field contains the
+ given string */
+ MAIL_SEARCH_KEY_DELETED, /* messages with the flag \Deleted */
+ MAIL_SEARCH_KEY_FLAGGED, /* messages with the flag \Flagged */
+ MAIL_SEARCH_KEY_FROM, /* messages whose From field contains the
+ given string */
+ MAIL_SEARCH_KEY_NEW, /* messages with the flag \Recent and not
+ the \Seen flag */
+ MAIL_SEARCH_KEY_OLD, /* messages that do not have the
+ \Recent flag set */
+ MAIL_SEARCH_KEY_ON, /* messages whose internal date is the
+ specified date */
+ MAIL_SEARCH_KEY_RECENT, /* messages with the flag \Recent */
+ MAIL_SEARCH_KEY_SEEN, /* messages with the flag \Seen */
+ MAIL_SEARCH_KEY_SINCE, /* messages whose internal date is later
+ than specified date */
+ MAIL_SEARCH_KEY_SUBJECT, /* messages whose Subject field contains the
+ given string */
+ MAIL_SEARCH_KEY_TEXT, /* messages whose text part contains the
+ given string */
+ MAIL_SEARCH_KEY_TO, /* messages whose To field contains the
+ given string */
+ MAIL_SEARCH_KEY_UNANSWERED, /* messages with no flag \Answered */
+ MAIL_SEARCH_KEY_UNDELETED, /* messages with no flag \Deleted */
+ MAIL_SEARCH_KEY_UNFLAGGED, /* messages with no flag \Flagged */
+ MAIL_SEARCH_KEY_UNSEEN, /* messages with no flag \Seen */
+ MAIL_SEARCH_KEY_HEADER, /* messages whose given field
+ contains the given string */
+ MAIL_SEARCH_KEY_LARGER, /* messages whose size is larger then
+ the given size */
+ MAIL_SEARCH_KEY_NOT, /* not operation of the condition */
+ MAIL_SEARCH_KEY_OR, /* or operation between two conditions */
+ MAIL_SEARCH_KEY_SMALLER, /* messages whose size is smaller than
+ the given size */
+ MAIL_SEARCH_KEY_MULTIPLE /* the boolean operator between the
+ conditions is AND */
+};
+
+/*
+ mail_search_key is the condition on the messages to return
+
+ - type is the type of the condition
+
+ - bcc is the text to search in the Bcc field when type is
+ MAIL_SEARCH_KEY_BCC, should be allocated with malloc()
+
+ - before is a date when type is MAIL_SEARCH_KEY_BEFORE
+
+ - body is the text to search in the message when type is
+ MAIL_SEARCH_KEY_BODY, should be allocated with malloc()
+
+ - cc is the text to search in the Cc field when type is
+ MAIL_SEARCH_KEY_CC, should be allocated with malloc()
+
+ - from is the text to search in the From field when type is
+ MAIL_SEARCH_KEY_FROM, should be allocated with malloc()
+
+ - on is a date when type is MAIL_SEARCH_KEY_ON
+
+ - since is a date when type is MAIL_SEARCH_KEY_SINCE
+
+ - subject is the text to search in the Subject field when type is
+ MAILIMAP_SEARCH_KEY_SUBJECT, should be allocated with malloc()
+
+ - text is the text to search in the text part of the message when
+ type is MAILIMAP_SEARCH_KEY_TEXT, should be allocated with malloc()
+
+ - to is the text to search in the To field when type is
+ MAILIMAP_SEARCH_KEY_TO, should be allocated with malloc()
+
+ - header_name is the header name when type is MAILIMAP_SEARCH_KEY_HEADER,
+ should be allocated with malloc()
+
+ - header_value is the text to search in the given header when type is
+ MAILIMAP_SEARCH_KEY_HEADER, should be allocated with malloc()
+
+ - larger is a size when type is MAILIMAP_SEARCH_KEY_LARGER
+
+ - not is a condition when type is MAILIMAP_SEARCH_KEY_NOT
+
+ - or1 is a condition when type is MAILIMAP_SEARCH_KEY_OR
+
+ - or2 is a condition when type is MAILIMAP_SEARCH_KEY_OR
+
+ - sentbefore is a date when type is MAILIMAP_SEARCH_KEY_SENTBEFORE
+
+ - senton is a date when type is MAILIMAP_SEARCH_KEY_SENTON
+
+ - sentsince is a date when type is MAILIMAP_SEARCH_KEY_SENTSINCE
+
+ - smaller is a size when type is MAILIMAP_SEARCH_KEY_SMALLER
+
+ - multiple is a set of message when type is MAILIMAP_SEARCH_KEY_MULTIPLE
+*/
+
+#if 0
+struct mail_search_key {
+ int sk_type;
+ union {
+ char * sk_bcc;
+ struct mailimf_date_time * sk_before;
+ char * sk_body;
+ char * sk_cc;
+ char * sk_from;
+ struct mailimf_date_time * sk_on;
+ struct mailimf_date_time * sk_since;
+ char * sk_subject;
+ char * sk_text;
+ char * sk_to;
+ char * sk_header_name;
+ char * sk_header_value;
+ size_t sk_larger;
+ struct mail_search_key * sk_not;
+ struct mail_search_key * sk_or1;
+ struct mail_search_key * sk_or2;
+ size_t sk_smaller;
+ clist * sk_multiple; /* list of (struct mailimap_search_key *) */
+ } sk_data;
+};
+
+
+struct mail_search_key *
+mail_search_key_new(int sk_type,
+ char * sk_bcc, struct mailimf_date_time * sk_before,
+ char * sk_body, char * sk_cc, char * sk_from,
+ struct mailimf_date_time * sk_on, struct mailimf_date_time * sk_since,
+ char * sk_subject, char * sk_text, char * sk_to,
+ char * sk_header_name, char * sk_header_value, size_t sk_larger,
+ struct mail_search_key * sk_not, struct mail_search_key * sk_or1,
+ struct mail_search_key * sk_or2, size_t sk_smaller,
+ clist * sk_multiple);
+
+void mail_search_key_free(struct mail_search_key * key);
+#endif
+
+/*
+ mail_search_result is a list of message numbers that is returned
+ by the mailsession_search_messages function()
+*/
+
+#if 0
+struct mail_search_result {
+ clist * sr_list; /* list of (uint32_t *) */
+};
+
+struct mail_search_result * mail_search_result_new(clist * sr_list);
+
+void mail_search_result_free(struct mail_search_result * search_result);
+#endif
+
+
+/*
+ There is three kinds of identities :
+ - storage
+ - folders
+ - session
+
+ A storage (struct mailstorage) represents whether a server or
+ a main path,
+
+ A storage can be an IMAP server, the root path of a MH or a mbox file.
+
+ Folders (struct mailfolder) are the mailboxes we can
+ choose in the server or as sub-folder of the main path.
+
+ Folders for IMAP are the IMAP mailboxes, for MH this is one of the
+ folder of the MH storage, for mbox, there is only one folder, the
+ mbox file content;
+
+ A mail session (struct mailsession) is whether a connection to a server
+ or a path that is open. It is the abstraction lower folders and storage.
+ It allow us to send commands.
+
+ We have a session driver for mail session for each kind of storage.
+
+ From a session, we can get a message (struct mailmessage) to read.
+ We have a message driver for each kind of storage.
+*/
+
+/*
+ maildriver is the driver structure for mail sessions
+
+ - name is the name of the driver
+
+ - initialize() is the function that will initializes a data structure
+ specific to the driver, it returns a value that will be stored
+ in the field data of the session.
+ The field data of the session is the state of the session,
+ the internal data structure used by the driver.
+ It is called when creating the mailsession structure with
+ mailsession_new().
+
+ - uninitialize() frees the structure created with initialize()
+
+ - parameters() implements functions specific to the given mail access
+
+ - connect_stream() connects a stream to the session
+
+ - connect_path() notify a main path to the session
+
+ - starttls() changes the current stream to a TLS stream
+
+ - login() notifies the user and the password to authenticate to the
+ session
+
+ - logout() exits the session and closes the stream
+
+ - noop() does no operation on the session, but it can be
+ used to poll for the status of the connection.
+
+ - build_folder_name() will return an allocated string with
+ that contains the complete path of the folder to create
+
+ - create_folder() creates the folder that corresponds to the
+ given name
+
+ - delete_folder() deletes the folder that corresponds to the
+ given name
+
+ - rename_folder() change the name of the folder
+
+ - check_folder() makes a checkpoint of the session
+
+ - examine_folder() selects a mailbox as readonly
+
+ - select_folder() selects a mailbox
+
+ - expunge_folder() deletes all messages marked \Deleted
+
+ - status_folder() queries the status of the folder
+ (number of messages, number of recent messages, number of
+ unseen messages)
+
+ - messages_number() queries the number of messages in the folder
+
+ - recent_number() queries the number of recent messages in the folder
+
+ - unseen_number() queries the number of unseen messages in the folder
+
+ - list_folders() returns the list of all sub-mailboxes
+ of the given mailbox
+
+ - lsub_folders() returns the list of subscribed
+ sub-mailboxes of the given mailbox
+
+ - subscribe_folder() subscribes to the given mailbox
+
+ - unsubscribe_folder() unsubscribes to the given mailbox
+
+ - append_message() adds a RFC 2822 message to the current
+ given mailbox
+
+ - copy_message() copies a message whose number is given to
+ a given mailbox. The mailbox must be accessible from
+ the same session.
+
+ - move_message() copies a message whose number is given to
+ a given mailbox. The mailbox must be accessible from the
+ same session.
+
+ - get_messages_list() returns the list of message numbers
+ of the current mailbox.
+
+ - get_envelopes_list() fills the parsed fields in the
+ mailmessage structures of the mailmessage_list.
+
+ - remove_message() removes the given message from the mailbox.
+ The message is permanently deleted.
+
+ - search_message() returns a list of message numbers that
+ corresponds to the given criteria.
+
+ - get_message returns a mailmessage structure that corresponds
+ to the given message number.
+
+ - get_message_by_uid returns a mailmessage structure that corresponds
+ to the given message unique identifier.
+
+ * mandatory functions are the following :
+
+ - connect_stream() of connect_path()
+ - logout()
+ - get_messages_list()
+ - get_envelopes_list()
+
+ * we advise you to implement these functions :
+
+ - select_folder() (in case a session can access several folders)
+ - noop() (to check if the server is responding)
+ - check_folder() (to make a checkpoint of the session)
+ - status_folder(), messages_number(), recent_number(), unseen_number()
+ (to get stat of the folder)
+ - append_message() (but can't be done in the case of POP3 at least)
+ - login() in a case of an authenticated driver.
+ - starttls() in a case of a stream driver, if the procotol supports
+ STARTTLS.
+ - get_message_by_uid() so that the application can remember the message
+ by UID and build its own list of messages.
+
+ * drivers' specific :
+
+ Everything that is specific to the driver will be implemented in this
+ function :
+
+ - parameters()
+*/
+
+struct mailsession_driver {
+ char * sess_name;
+
+ int (* sess_initialize)(mailsession * session);
+ void (* sess_uninitialize)(mailsession * session);
+
+ int (* sess_parameters)(mailsession * session,
+ int id, void * value);
+
+ int (* sess_connect_stream)(mailsession * session, mailstream * s);
+ int (* sess_connect_path)(mailsession * session, char * path);
+
+ int (* sess_starttls)(mailsession * session);
+
+ int (* sess_login)(mailsession * session, char * userid, char * password);
+ int (* sess_logout)(mailsession * session);
+ int (* sess_noop)(mailsession * session);
+
+ /* folders operations */
+
+ int (* sess_build_folder_name)(mailsession * session, char * mb,
+ char * name, char ** result);
+
+ int (* sess_create_folder)(mailsession * session, char * mb);
+ int (* sess_delete_folder)(mailsession * session, char * mb);
+ int (* sess_rename_folder)(mailsession * session, char * mb,
+ char * new_name);
+ int (* sess_check_folder)(mailsession * session);
+ int (* sess_examine_folder)(mailsession * session, char * mb);
+ int (* sess_select_folder)(mailsession * session, char * mb);
+ int (* sess_expunge_folder)(mailsession * session);
+ int (* sess_status_folder)(mailsession * session, char * mb,
+ uint32_t * result_num, uint32_t * result_recent,
+ uint32_t * result_unseen);
+ int (* sess_messages_number)(mailsession * session, char * mb,
+ uint32_t * result);
+ int (* sess_recent_number)(mailsession * session, char * mb,
+ uint32_t * result);
+ int (* sess_unseen_number)(mailsession * session, char * mb,
+ uint32_t * result);
+
+ int (* sess_list_folders)(mailsession * session, char * mb,
+ struct mail_list ** result);
+ int (* sess_lsub_folders)(mailsession * session, char * mb,
+ struct mail_list ** result);
+
+ int (* sess_subscribe_folder)(mailsession * session, char * mb);
+ int (* sess_unsubscribe_folder)(mailsession * session, char * mb);
+
+ /* messages operations */
+
+ int (* sess_append_message)(mailsession * session,
+ char * message, size_t size);
+ int (* sess_append_message_flags)(mailsession * session,
+ char * message, size_t size, struct mail_flags * flags);
+ int (* sess_copy_message)(mailsession * session,
+ uint32_t num, char * mb);
+ int (* sess_move_message)(mailsession * session,
+ uint32_t num, char * mb);
+
+ int (* sess_get_message)(mailsession * session,
+ uint32_t num, mailmessage ** result);
+
+ int (* sess_get_message_by_uid)(mailsession * session,
+ const char * uid, mailmessage ** result);
+
+ int (* sess_get_messages_list)(mailsession * session,
+ struct mailmessage_list ** result);
+ int (* sess_get_envelopes_list)(mailsession * session,
+ struct mailmessage_list * env_list);
+ int (* sess_remove_message)(mailsession * session, uint32_t num);
+#if 0
+ int (* sess_search_messages)(mailsession * session, char * charset,
+ struct mail_search_key * key,
+ struct mail_search_result ** result);
+#endif
+};
+
+
+/*
+ session is the data structure for a mail session.
+
+ - data is the internal data structure used by the driver
+ It is called when initializing the mailsession structure.
+
+ - driver is the driver used for the session
+*/
+
+struct mailsession {
+ void * sess_data;
+ mailsession_driver * sess_driver;
+};
+
+
+
+
+/*
+ mailmessage_driver is the driver structure to get information from messages.
+
+ - name is the name of the driver
+
+ - initialize() is the function that will initializes a data structure
+ specific to the driver, it returns a value that will be stored
+ in the field data of the mailsession.
+ The field data of the session is the state of the session,
+ the internal data structure used by the driver.
+ It is called when initializing the mailmessage structure with
+ mailmessage_init().
+
+ - uninitialize() frees the structure created with initialize().
+ It will be called by mailmessage_free().
+
+ - flush() will free from memory all temporary structures of the message
+ (for example, the MIME structure of the message).
+
+ - fetch_result_free() will free all strings resulted by fetch() or
+ any fetch_xxx() functions that returns a string.
+
+ - fetch() returns the content of the message (headers and text).
+
+ - fetch_header() returns the content of the headers.
+
+ - fetch_body() returns the message text (message content without headers)
+
+ - fetch_size() returns the size of the message content.
+
+ - get_bodystructure() returns the MIME structure of the message.
+
+ - fetch_section() returns the content of a given MIME part
+
+ - fetch_section_header() returns the header of the message
+ contained by the given MIME part.
+
+ - fetch_section_mime() returns the MIME headers of the
+ given MIME part.
+
+ - fetch_section_body() returns the text (if this is a message, this is the
+ message content without headers) of the given MIME part.
+
+ - fetch_envelope() returns a mailimf_fields structure, with a list of
+ fields chosen by the driver.
+
+ - get_flags() returns a the flags related to the message.
+ When you want to get flags of a message, you have to make sure to
+ call get_flags() at least once before using directly message->flags.
+*/
+
+#define LIBETPAN_MAIL_MESSAGE_CHECK
+
+struct mailmessage_driver {
+ char * msg_name;
+
+ int (* msg_initialize)(mailmessage * msg_info);
+
+ void (* msg_uninitialize)(mailmessage * msg_info);
+
+ void (* msg_flush)(mailmessage * msg_info);
+
+ void (* msg_check)(mailmessage * msg_info);
+
+ void (* msg_fetch_result_free)(mailmessage * msg_info,
+ char * msg);
+
+ int (* msg_fetch)(mailmessage * msg_info,
+ char ** result,
+ size_t * result_len);
+
+ int (* msg_fetch_header)(mailmessage * msg_info,
+ char ** result,
+ size_t * result_len);
+
+ int (* msg_fetch_body)(mailmessage * msg_info,
+ char ** result, size_t * result_len);
+
+ int (* msg_fetch_size)(mailmessage * msg_info,
+ size_t * result);
+
+ int (* msg_get_bodystructure)(mailmessage * msg_info,
+ struct mailmime ** result);
+
+ int (* msg_fetch_section)(mailmessage * msg_info,
+ struct mailmime * mime,
+ char ** result, size_t * result_len);
+
+ int (* msg_fetch_section_header)(mailmessage * msg_info,
+ struct mailmime * mime,
+ char ** result,
+ size_t * result_len);
+
+ int (* msg_fetch_section_mime)(mailmessage * msg_info,
+ struct mailmime * mime,
+ char ** result,
+ size_t * result_len);
+
+ int (* msg_fetch_section_body)(mailmessage * msg_info,
+ struct mailmime * mime,
+ char ** result,
+ size_t * result_len);
+
+ int (* msg_fetch_envelope)(mailmessage * msg_info,
+ struct mailimf_fields ** result);
+
+ int (* msg_get_flags)(mailmessage * msg_info,
+ struct mail_flags ** result);
+};
+
+
+/*
+ mailmessage is a data structure to get information from messages
+
+ - session is the session linked to the given message, it can be NULL
+
+ - driver is the message driver
+
+ - index is the message number
+
+ - uid, when it is not NULL, it means that the folder
+ the folder has persistant message numbers, the string is
+ the unique message number in the folder.
+ uid should be implemented if possible.
+ for drivers where we cannot generate real uid,
+ a suggestion is "AAAA-IIII" where AAAA is some
+ random session number and IIII the content of index field.
+
+ - size, when it is not 0, is the size of the message content.
+
+ - fields, when it is not NULL, are the header fields of the message.
+
+ - flags, when it is not NULL, are the flags related to the message.
+
+ - single_fields, when resolved != 0, is filled with the data of fields.
+
+ - mime, when it is not NULL
+
+ - cached is != 0 when the header fields were read from the cache.
+
+ - data is data specific to the driver, this is internal data structure,
+ some state of the message.
+*/
+
+struct mailmessage {
+ mailsession * msg_session;
+ mailmessage_driver * msg_driver;
+ uint32_t msg_index;
+ char * msg_uid;
+
+ size_t msg_size;
+ struct mailimf_fields * msg_fields;
+ struct mail_flags * msg_flags;
+
+ int msg_resolved;
+ struct mailimf_single_fields msg_single_fields;
+ struct mailmime * msg_mime;
+
+ /* internal data */
+
+ int msg_cached;
+ void * msg_data;
+
+ /*
+ msg_folder field :
+ used to reference the mailfolder, this is a workaround due
+ to the problem with initial conception, where folder notion
+ did not exist.
+ */
+ void * msg_folder;
+ /* user data */
+ void * msg_user_data;
+};
+
+
+/*
+ mailmessage_tree is a node in the messages tree (thread)
+
+ - parent is the parent of the message, it is NULL if the message
+ is the root of the message tree.
+
+ - date is the date of the message in number of second elapsed
+ since 00:00:00 on January 1, 1970, Coordinated Universal Time (UTC).
+
+ - msg is the message structure that is stored referenced by the node.
+ is msg is NULL, this is a dummy node.
+
+ - children is an array that contains all the children of the node.
+ children are mailmessage_tree structures.
+
+ - is_reply is != 0 when the message is a reply or a forward
+
+ - base_subject is the extracted subject of the message.
+
+ - index is the message number.
+*/
+
+struct mailmessage_tree {
+ struct mailmessage_tree * node_parent;
+ char * node_msgid;
+ time_t node_date;
+ mailmessage * node_msg;
+ carray * node_children; /* array of (struct mailmessage_tree *) */
+
+ /* private, used for threading */
+ int node_is_reply;
+ char * node_base_subject;
+};
+
+
+struct mailmessage_tree *
+mailmessage_tree_new(char * node_msgid, time_t node_date,
+ mailmessage * node_msg);
+
+void mailmessage_tree_free(struct mailmessage_tree * tree);
+
+/*
+ mailmessage_tree_free_recursive
+
+ if you want to release memory of the given tree and all the sub-trees,
+ you can use this function.
+*/
+
+void mailmessage_tree_free_recursive(struct mailmessage_tree * tree);
+
+
+struct generic_message_t {
+ int (* msg_prefetch)(mailmessage * msg_info);
+ void (* msg_prefetch_free)(struct generic_message_t * msg);
+ int msg_fetched;
+ char * msg_message;
+ size_t msg_length;
+ void * msg_data;
+};
+
+
+const char * maildriver_strerror(int err);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libetpan/src/driver/interface/maildriver_types_helper.c b/libetpan/src/driver/interface/maildriver_types_helper.c
new file mode 100644
index 0000000..6e3abf4
--- a/dev/null
+++ b/libetpan/src/driver/interface/maildriver_types_helper.c
@@ -0,0 +1,104 @@
+/*
+ * libEtPan! -- a mail stuff library
+ *
+ * Copyright (C) 2001, 200 - 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 "maildriver_types_helper.h"
+
+#include "mail.h"
+
+#include "clist.h"
+#include <string.h>
+#include <stdlib.h>
+
+int mail_flags_add_extension(struct mail_flags * flags,
+ char * ext_flag)
+{
+ char * str;
+ int r;
+
+ if (mail_flags_has_extension(flags, ext_flag))
+ return MAIL_NO_ERROR;
+
+ str = strdup(ext_flag);
+ if (str == NULL)
+ return MAIL_ERROR_MEMORY;
+
+ r = clist_append(flags->fl_extension, str);
+ if (r < 0) {
+ free(str);
+ return MAIL_ERROR_MEMORY;
+ }
+
+ return MAIL_NO_ERROR;
+}
+
+int mail_flags_remove_extension(struct mail_flags * flags,
+ char * ext_flag)
+{
+ clistiter * cur;
+
+ cur = clist_begin(flags->fl_extension);
+ while (cur != NULL) {
+ char * flag_name;
+
+ flag_name = clist_content(cur);
+
+ if (strcasecmp(flag_name, ext_flag) == 0) {
+ free(flag_name);
+ cur = clist_delete(flags->fl_extension, cur);
+ }
+ else
+ cur = clist_next(cur);
+ }
+
+ return MAIL_NO_ERROR;
+}
+
+int mail_flags_has_extension(struct mail_flags * flags,
+ char * ext_flag)
+{
+ clistiter * cur;
+
+ for(cur = clist_begin(flags->fl_extension) ; cur != NULL ;
+ cur = clist_next(cur)) {
+ char * flag_name;
+
+ flag_name = clist_content(cur);
+
+ if (strcasecmp(flag_name, ext_flag) == 0)
+ return TRUE;
+ }
+
+ return FALSE;
+}
diff --git a/libetpan/src/driver/interface/maildriver_types_helper.h b/libetpan/src/driver/interface/maildriver_types_helper.h
new file mode 100644
index 0000000..50ccc70
--- a/dev/null
+++ b/libetpan/src/driver/interface/maildriver_types_helper.h
@@ -0,0 +1,99 @@
+/*
+ * 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 MAILDRIVER_TYPES_HELPER_H
+
+#define MAILDRIVER_TYPES_HELPER_H
+
+#include <libetpan/maildriver_types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ mail_flags_add_extension adds the given flag if it does not exists in
+ the flags.
+
+ @param flags this is the flag to change
+
+ @param ext_flag this is the name of an extension flag
+ the given flag name is duplicated and is no more needed after
+ the function call.
+
+ @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
+ on error
+*/
+
+int mail_flags_add_extension(struct mail_flags * flags,
+ char * ext_flag);
+
+/*
+ mail_flags_remove_extension removes the given flag if it does not exists in
+ the flags.
+
+ @param flags this is the flag to change
+
+ @param ext_flag this is the name of an extension flag
+ the given flag name is no more needed after the function call.
+
+ @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
+ on error
+*/
+
+int mail_flags_remove_extension(struct mail_flags * flags,
+ char * ext_flag);
+
+/*
+ mail_flags_has_extension returns 1 if the flags is in the given flags,
+ 0 is returned otherwise.
+
+ @param flags this is the flag to change
+
+ @param ext_flag this is the name of an extension flag
+ the given flag name is no more needed after the function call.
+
+ @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
+ on error
+*/
+
+int mail_flags_has_extension(struct mail_flags * flags,
+ char * ext_flag);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libetpan/src/driver/interface/mailfolder.c b/libetpan/src/driver/interface/mailfolder.c
new file mode 100644
index 0000000..eb69d7f
--- a/dev/null
+++ b/libetpan/src/driver/interface/mailfolder.c
@@ -0,0 +1,138 @@
+/*
+ * 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 "mailfolder.h"
+
+#include "maildriver.h"
+
+int mailfolder_noop(struct mailfolder * folder)
+{
+ return mailsession_noop(folder->fld_session);
+}
+
+int mailfolder_check(struct mailfolder * folder)
+{
+ return mailsession_check_folder(folder->fld_session);
+}
+
+int mailfolder_expunge(struct mailfolder * folder)
+{
+ return mailsession_expunge_folder(folder->fld_session);
+}
+
+int mailfolder_status(struct mailfolder * folder,
+ uint32_t * result_messages, uint32_t * result_recent,
+ uint32_t * result_unseen)
+{
+ return mailsession_status_folder(folder->fld_session,
+ folder->fld_pathname, result_messages,
+ result_recent, result_unseen);
+}
+
+int mailfolder_append_message(struct mailfolder * folder,
+ char * message, size_t size)
+{
+ return mailsession_append_message(folder->fld_session, message, size);
+}
+
+int mailfolder_append_message_flags(struct mailfolder * folder,
+ char * message, size_t size, struct mail_flags * flags)
+{
+ return mailsession_append_message_flags(folder->fld_session, message,
+ size, flags);
+}
+
+int mailfolder_get_messages_list(struct mailfolder * folder,
+ struct mailmessage_list ** result)
+{
+ int r;
+ struct mailmessage_list * msg_list;
+ unsigned int i;
+
+ r = mailsession_get_messages_list(folder->fld_session, &msg_list);
+ if (r != MAIL_NO_ERROR)
+ return r;
+
+ for(i = 0 ; i < carray_count(msg_list->msg_tab) ; i ++) {
+ mailmessage * msg;
+
+ msg = carray_get(msg_list->msg_tab, i);
+ msg->msg_folder = folder;
+ }
+
+ * result = msg_list;
+
+ return MAIL_NO_ERROR;
+}
+
+int mailfolder_get_envelopes_list(struct mailfolder * folder,
+ struct mailmessage_list * result)
+{
+ return mailsession_get_envelopes_list(folder->fld_session, result);
+}
+
+int mailfolder_get_message(struct mailfolder * folder,
+ uint32_t num, mailmessage ** result)
+{
+ mailmessage * msg;
+ int r;
+
+ r = mailsession_get_message(folder->fld_session, num, &msg);
+ if (r != MAIL_NO_ERROR)
+ return r;
+
+ msg->msg_folder = folder;
+
+ * result = msg;
+
+ return MAIL_NO_ERROR;
+}
+
+int mailfolder_get_message_by_uid(struct mailfolder * folder,
+ const char * uid, mailmessage ** result)
+{
+ mailmessage * msg;
+ int r;
+
+ r = mailsession_get_message_by_uid(folder->fld_session, uid, &msg);
+ if (r != MAIL_NO_ERROR)
+ return r;
+
+ msg->msg_folder = folder;
+
+ * result = msg;
+
+ return MAIL_NO_ERROR;
+}
diff --git a/libetpan/src/driver/interface/mailfolder.h b/libetpan/src/driver/interface/mailfolder.h
new file mode 100644
index 0000000..55ea3be
--- a/dev/null
+++ b/libetpan/src/driver/interface/mailfolder.h
@@ -0,0 +1,70 @@
+/*
+ * 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 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/libetpan/src/driver/interface/mailmessage.c b/libetpan/src/driver/interface/mailmessage.c
new file mode 100644
index 0000000..b4921e5
--- a/dev/null
+++ b/libetpan/src/driver/interface/mailmessage.c
@@ -0,0 +1,240 @@
+/*
+ * 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 "mailmessage.h"
+
+#include "mail.h"
+
+#include <string.h>
+
+int mailmessage_init(mailmessage * msg_info,
+ mailsession * msg_session,
+ mailmessage_driver * msg_driver,
+ uint32_t msg_index, size_t msg_size)
+{
+ int r;
+ int res;
+
+ msg_info->msg_driver = msg_driver;
+ msg_info->msg_session = msg_session;
+ msg_info->msg_index = msg_index;
+ msg_info->msg_uid = NULL;
+
+ msg_info->msg_cached = FALSE;
+ msg_info->msg_size = msg_size;
+ msg_info->msg_fields = NULL;
+ memset(&msg_info->msg_single_fields, 0,
+ sizeof(struct mailimf_single_fields));
+ msg_info->msg_resolved = FALSE;
+ msg_info->msg_flags = NULL;
+
+ msg_info->msg_mime = NULL;
+ msg_info->msg_data = NULL;
+ msg_info->msg_folder = NULL;
+ msg_info->msg_user_data = NULL;
+
+ if (msg_driver->msg_initialize != NULL) {
+ r = msg_driver->msg_initialize(msg_info);
+ if (r != MAIL_NO_ERROR) {
+ res = r;
+ goto err;
+ }
+ }
+
+ return MAIL_NO_ERROR;
+
+ err:
+ msg_info->msg_driver = NULL;
+ msg_info->msg_session = NULL;
+ return res;
+}
+
+int mailmessage_flush(mailmessage * msg_info)
+{
+ if (msg_info->msg_driver->msg_flush == NULL)
+ return MAIL_ERROR_NOT_IMPLEMENTED;
+
+ msg_info->msg_driver->msg_flush(msg_info);
+
+ return MAIL_NO_ERROR;
+}
+
+int mailmessage_check(mailmessage * msg_info)
+{
+ if (msg_info->msg_driver->msg_check == NULL)
+ return MAIL_ERROR_NOT_IMPLEMENTED;
+
+ msg_info->msg_driver->msg_check(msg_info);
+
+ return MAIL_NO_ERROR;
+}
+
+int mailmessage_fetch_result_free(mailmessage * msg_info,
+ char * msg)
+{
+ if (msg_info->msg_driver->msg_fetch_result_free == NULL)
+ return MAIL_ERROR_NOT_IMPLEMENTED;
+
+ msg_info->msg_driver->msg_fetch_result_free(msg_info, msg);
+
+ return MAIL_NO_ERROR;
+}
+
+int mailmessage_fetch(mailmessage * msg_info,
+ char ** result,
+ size_t * result_len)
+{
+ if (msg_info->msg_driver->msg_fetch == NULL)
+ return MAIL_ERROR_NOT_IMPLEMENTED;
+
+ return msg_info->msg_driver->msg_fetch(msg_info, result, result_len);
+}
+
+int mailmessage_fetch_header(mailmessage * msg_info,
+ char ** result,
+ size_t * result_len)
+{
+ if (msg_info->msg_driver->msg_fetch_header == NULL)
+ return MAIL_ERROR_NOT_IMPLEMENTED;
+
+ return msg_info->msg_driver->msg_fetch_header(msg_info, result, result_len);
+}
+
+int mailmessage_fetch_body(mailmessage * msg_info,
+ char ** result, size_t * result_len)
+{
+ if (msg_info->msg_driver->msg_fetch_body == NULL)
+ return MAIL_ERROR_NOT_IMPLEMENTED;
+
+ return msg_info->msg_driver->msg_fetch_body(msg_info, result, result_len);
+}
+
+int mailmessage_fetch_size(mailmessage * msg_info,
+ size_t * result)
+{
+ if (msg_info->msg_driver->msg_fetch_size == NULL)
+ return MAIL_ERROR_NOT_IMPLEMENTED;
+
+ return msg_info->msg_driver->msg_fetch_size(msg_info, result);
+}
+
+int mailmessage_get_bodystructure(mailmessage * msg_info,
+ struct mailmime ** result)
+{
+ if (msg_info->msg_driver->msg_get_bodystructure == NULL)
+ return MAIL_ERROR_NOT_IMPLEMENTED;
+
+ return msg_info->msg_driver->msg_get_bodystructure(msg_info, result);
+}
+
+int mailmessage_fetch_section(mailmessage * msg_info,
+ struct mailmime * mime,
+ char ** result, size_t * result_len)
+{
+ if (msg_info->msg_driver->msg_fetch_section == NULL)
+ return MAIL_ERROR_NOT_IMPLEMENTED;
+
+ return msg_info->msg_driver->msg_fetch_section(msg_info, mime, result, result_len);
+}
+
+int mailmessage_fetch_section_header(mailmessage * msg_info,
+ struct mailmime * mime,
+ char ** result,
+ size_t * result_len)
+{
+ if (msg_info->msg_driver->msg_fetch_section_header == NULL)
+ return MAIL_ERROR_NOT_IMPLEMENTED;
+
+ return msg_info->msg_driver->msg_fetch_section_header(msg_info, mime,
+ result, result_len);
+}
+
+int mailmessage_fetch_section_mime(mailmessage * msg_info,
+ struct mailmime * mime,
+ char ** result,
+ size_t * result_len)
+{
+ if (msg_info->msg_driver->msg_fetch_section_mime == NULL)
+ return MAIL_ERROR_NOT_IMPLEMENTED;
+
+ return msg_info->msg_driver->msg_fetch_section_mime(msg_info, mime,
+ result, result_len);
+}
+
+int mailmessage_fetch_section_body(mailmessage * msg_info,
+ struct mailmime * mime,
+ char ** result,
+ size_t * result_len)
+{
+ if (msg_info->msg_driver->msg_fetch_section_body == NULL)
+ return MAIL_ERROR_NOT_IMPLEMENTED;
+
+ return msg_info->msg_driver->msg_fetch_section_body(msg_info, mime,
+ result, result_len);
+}
+
+int mailmessage_fetch_envelope(mailmessage * msg_info,
+ struct mailimf_fields ** result)
+{
+ if (msg_info->msg_driver->msg_fetch_envelope == NULL)
+ return MAIL_ERROR_NOT_IMPLEMENTED;
+
+ return msg_info->msg_driver->msg_fetch_envelope(msg_info, result);
+}
+
+int mailmessage_get_flags(mailmessage * msg_info,
+ struct mail_flags ** result)
+{
+ struct mail_flags * dummy;
+
+ if (msg_info->msg_driver->msg_get_flags == NULL)
+ return MAIL_ERROR_NOT_IMPLEMENTED;
+
+ if (result != NULL)
+ return msg_info->msg_driver->msg_get_flags(msg_info, result);
+ else
+ return msg_info->msg_driver->msg_get_flags(msg_info, &dummy);
+}
+
+void mailmessage_resolve_single_fields(mailmessage * msg_info)
+{
+ if (!msg_info->msg_resolved) {
+ if (msg_info->msg_fields != NULL) {
+ mailimf_single_fields_init(&msg_info->msg_single_fields,
+ msg_info->msg_fields);
+ msg_info->msg_resolved = TRUE;
+ }
+ }
+}
diff --git a/libetpan/src/driver/interface/mailmessage.h b/libetpan/src/driver/interface/mailmessage.h
new file mode 100644
index 0000000..02b351b
--- a/dev/null
+++ b/libetpan/src/driver/interface/mailmessage.h
@@ -0,0 +1,379 @@
+/*
+ * 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 <libetpan/mailmessage_types.h>
+
+#ifndef MAILMESSAGE_H
+
+#define MAILMESSAGE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ mailmessage_new
+
+ This function will initializes a new empty message.
+
+ @return a new empty message will be returned.
+*/
+
+mailmessage * mailmessage_new(void);
+
+/*
+ mailmessage_free
+
+ This function will release the memory used by this message.
+*/
+
+void mailmessage_free(mailmessage * info);
+
+/*
+ mailmessage_init
+
+ This function will initializes a mailmessage structure
+ with a message from a given session.
+
+ @param msg_info This is the message to initialize.
+
+ @param session This is the source session of the message. It
+ can be NULL if the message does not get the information
+ through the session.
+
+ @param driver This is the driver to use for the message.
+
+ @param index This is the message number in the session. 0 can
+ be given if the message is not attached to a session.
+
+ @param size is an optional parameter, 0 can be given.
+ This is informational. This is the size of message content.
+
+ @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
+ on error
+*/
+
+int mailmessage_init(mailmessage * msg_info,
+ mailsession * session,
+ mailmessage_driver * driver,
+ uint32_t index, size_t size);
+
+/*
+ mailmessage_flush
+
+ This function will release all the temporary resources that are not
+ necessary to use the mailmessage structure from memory. These
+ resources are for example cached information, such as the MIME
+ structure.
+
+ @param info is the message to clean.
+
+ @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
+ on error. We can assume that MAIL_NO_ERROR is always returned.
+*/
+
+int mailmessage_flush(mailmessage * info);
+
+/*
+ mailmessage_check
+
+ This function will notify the new value of the flags to the session,
+ it must be called before mailsession_check_folder() in case the flags have
+ been changed.
+
+ @param info is the message to checkpoint.
+
+ @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
+ on error. We can assume that MAIL_NO_ERROR is always returned.
+*/
+
+int mailmessage_check(mailmessage * info);
+
+/*
+ mailmessage_fetch_result_free
+
+ This function releases the memory used by a message returned
+ by any of the fetch function that returns a (char *).
+
+ @param msg_info is the message which the given buffer is from.
+
+ @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
+ on error. We can assume that MAIL_NO_ERROR is always returned.
+*/
+
+int mailmessage_fetch_result_free(mailmessage * msg_info,
+ char * msg);
+
+/*
+ mailmessage_fetch
+
+ This function returns the content of the message (headers and text).
+
+ @param msg_info is the message from which we want to fetch information.
+
+ @param result The content of the message is returned in (* result)
+
+ @param result_len The length of the returned string is stored
+ in (* result_len).
+
+ @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
+ on error.
+*/
+
+int mailmessage_fetch(mailmessage * msg_info,
+ char ** result,
+ size_t * result_len);
+
+/*
+ mailmessage_fetch_header
+
+ This function returns the header of the message as a string.
+
+ @param msg_info is the message from which we want to fetch information.
+
+ @param result The header of the message is returned in (* result)
+
+ @param result_len The length of the returned string is stored
+ in (* result_len).
+
+ @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
+ on error.
+*/
+
+int mailmessage_fetch_header(mailmessage * msg_info,
+ char ** result,
+ size_t * result_len);
+
+/*
+ mailmessage_fetch_body
+
+ This function returns the content of the message (without headers).
+
+ @param msg_info is the message from which we want to fetch information.
+ @param result The message text (without headers) is returned
+ in (* result)
+ @param result_len The length of the returned string is stored
+ in (* result_len).
+
+ @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
+ on error.
+*/
+
+int mailmessage_fetch_body(mailmessage * msg_info,
+ char ** result, size_t * result_len);
+
+/*
+ mailmessage_fetch_size
+
+ This function returns the size of the message content.
+
+ @param msg_info is the message from which we want to fetch information.
+
+ @param result The length of the message content is stored in (* result).
+
+ @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
+ on error.
+*/
+
+int mailmessage_fetch_size(mailmessage * msg_info,
+ size_t * result);
+
+/*
+ mailmessage_get_bodystructure
+
+ This functions returns the MIME structure of the message.
+ The returned information MUST not be freed by hand. It is freed by
+ mailmessage_flush() or mailmessage_free().
+
+ @param msg_info is the message from which we want to fetch information.
+
+ @param result The MIME structure is stored in (* result).
+
+ @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
+ on error.
+*/
+
+int mailmessage_get_bodystructure(mailmessage * msg_info,
+ struct mailmime ** result);
+
+/*
+ mailmessage_fetch_section
+
+ This function returns the content of a MIME part.
+
+ @param msg_info is the message from which we want to fetch information.
+
+ @param mime is the MIME part identifier.
+
+ @param result The content is returned in (* result)
+
+ @param result_len The length of the returned string is stored
+ in (* result_len).
+
+ @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
+ on error.
+ */
+
+int mailmessage_fetch_section(mailmessage * msg_info,
+ struct mailmime * mime,
+ char ** result, size_t * result_len);
+
+/*
+ mailmessage_fetch_section_header
+
+ This function returns the header of the message contained
+ in the given MIME part.
+
+ @param msg_info is the message from which we want to fetch information.
+
+ @param mime is the MIME part identifier.
+
+ @param result The header is returned in (* result)
+
+ @param result_len The length of the returned string is stored
+ in (* result_len).
+
+ @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
+ on error.
+*/
+
+int mailmessage_fetch_section_header(mailmessage * msg_info,
+ struct mailmime * mime,
+ char ** result,
+ size_t * result_len);
+
+/*
+ mailmessage_fetch_section_mime
+
+ This function returns the MIME header of the given MIME part.
+
+ @param msg_info is the message from which we want to fetch information.
+
+ @param mime is the MIME part identifier.
+
+ @param result The MIME header is returned in (* result)
+
+ @param result_len The length of the returned string is stored
+ in (* result_len).
+
+ @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
+ on error.
+*/
+
+int mailmessage_fetch_section_mime(mailmessage * msg_info,
+ struct mailmime * mime,
+ char ** result,
+ size_t * result_len);
+
+/*
+ mailmessage_fetch_section_body
+
+ This function returns the text part of the message contained
+ in the given MIME part.
+
+ @param msg_info is the message from which we want to fetch information.
+
+ @param mime is the MIME part identifier.
+
+ @param result The message text is returned in (* result)
+
+ @param result_len The length of the returned string is stored
+ in (* result_len).
+
+ @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
+ on error.
+ */
+
+int mailmessage_fetch_section_body(mailmessage * msg_info,
+ struct mailmime * mime,
+ char ** result,
+ size_t * result_len);
+
+/*
+ mailmessage_fetch_envelope
+
+ This function returns a list of parsed fields of the message,
+ chosen by the driver.
+ The returned structure must be freed with mailimf_fields_free().
+
+ @param msg_info is the message from which we want to fetch information.
+
+ @param result The headers list is returned in (* result)
+
+ @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
+ on error.
+ */
+
+int mailmessage_fetch_envelope(mailmessage * msg_info,
+ struct mailimf_fields ** result);
+
+
+/*
+ mailmessage_get_flags
+
+ This function returns the flags related to the message.
+ The returned information MUST not be freed by hand. It is freed by
+ mailmessage_free().
+
+ @param msg_info is the message from which we want to fetch information.
+
+ @param result The flags are stored in (* result).
+
+ @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
+ on error.
+*/
+
+int mailmessage_get_flags(mailmessage * msg_info,
+ struct mail_flags ** result);
+
+/*
+ mailmessage_resolve_single_fields
+
+ This function will use the fields information to fill the single_fields
+ structure in the mailmessage structure.
+
+ @param msg_info This is the msg_info to process.
+
+ @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
+ on error.
+*/
+
+void mailmessage_resolve_single_fields(mailmessage * msg_info);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libetpan/src/driver/interface/mailmessage_tools.c b/libetpan/src/driver/interface/mailmessage_tools.c
new file mode 100644
index 0000000..9e53173
--- a/dev/null
+++ b/libetpan/src/driver/interface/mailmessage_tools.c
@@ -0,0 +1,600 @@
+/*
+ * 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 "mailmessage_tools.h"
+#include "mailmessage.h"
+
+#include <stdlib.h>
+
+#include "maildriver.h"
+#include "maildriver_tools.h"
+
+int
+mailmessage_generic_initialize(mailmessage * msg_info)
+{
+ struct generic_message_t * msg;
+
+ msg = malloc(sizeof(* msg));
+
+ if (msg == NULL) {
+ return MAIL_ERROR_MEMORY;
+ }
+
+ msg->msg_fetched = 0;
+ msg->msg_message = NULL;
+ msg->msg_length = 0;
+
+ msg->msg_prefetch = NULL;
+ msg->msg_prefetch_free = NULL;
+ msg->msg_data = NULL;
+
+ msg_info->msg_data = msg;
+
+ return MAIL_NO_ERROR;
+}
+
+void mailmessage_generic_flush(mailmessage * msg_info)
+{
+ struct generic_message_t * msg;
+
+ if (msg_info->msg_mime != NULL) {
+ mailmime_free(msg_info->msg_mime);
+ msg_info->msg_mime = NULL;
+ }
+ msg = msg_info->msg_data;
+ if (msg != NULL) {
+ if (msg->msg_prefetch_free != NULL)
+ msg->msg_prefetch_free(msg);
+ msg->msg_fetched = 0;
+ }
+}
+
+void mailmessage_generic_uninitialize(mailmessage * msg_info)
+{
+ struct generic_message_t * msg;
+
+ mailmessage_generic_flush(msg_info);
+
+ msg = msg_info->msg_data;
+ msg_info->msg_data = NULL;
+ free(msg);
+}
+
+static inline int
+mailmessage_generic_prefetch(mailmessage * msg_info)
+{
+ struct generic_message_t * msg;
+ int r;
+
+ msg = msg_info->msg_data;
+
+ if (msg->msg_fetched)
+ return MAIL_NO_ERROR;
+
+#if 0
+ if (msg->message != NULL)
+ return MAIL_NO_ERROR;
+#endif
+
+ r = msg->msg_prefetch(msg_info);
+ if (r != MAIL_NO_ERROR)
+ return r;
+
+ msg->msg_fetched = 1;
+
+ return MAIL_NO_ERROR;
+}
+
+static int
+mailmessage_generic_prefetch_bodystructure(mailmessage * msg_info)
+{
+ size_t length;
+ char * message;
+ size_t cur_token;
+ struct mailmime * mime;
+ int r;
+ int res;
+ struct generic_message_t * msg;
+
+ if (msg_info->msg_mime != NULL) {
+ /* it has already been fetched */
+ return MAIL_NO_ERROR;
+ }
+
+#if 0
+ msg = msg_info->data;
+ if (msg->message == NULL) {
+ r = mailmessage_generic_prefetch(msg_info);
+ if (r != MAIL_NO_ERROR) {
+ res = r;
+ goto err;
+ }
+ }
+#endif
+ r = mailmessage_generic_prefetch(msg_info);
+ if (r != MAIL_NO_ERROR) {
+ res = r;
+ goto err;
+ }
+
+ msg = msg_info->msg_data;
+ message = msg->msg_message;
+ length = msg->msg_length;
+ cur_token = 0;
+ r = mailmime_parse(message, length, &cur_token, &mime);
+ if (r != MAILIMF_NO_ERROR) {
+ res = MAIL_ERROR_PARSE;
+ goto err;
+ }
+
+ msg_info->msg_mime = mime;
+
+ return MAIL_NO_ERROR;
+
+ err:
+ return res;
+}
+
+void
+mailmessage_generic_fetch_result_free(mailmessage * msg_info, char * msg)
+{
+ int r;
+
+ r = mmap_string_unref(msg);
+}
+
+int mailmessage_generic_fetch(mailmessage * msg_info,
+ char ** result,
+ size_t * result_len)
+{
+ int r;
+ char * message;
+ size_t cur_token;
+ size_t length;
+ MMAPString * mmapstr;
+ int res;
+ struct generic_message_t * msg;
+
+ msg = msg_info->msg_data;
+ r = mailmessage_generic_prefetch(msg_info);
+ if (r != MAIL_NO_ERROR) {
+ res = r;
+ goto err;
+ }
+
+ message = msg->msg_message;
+ length = msg->msg_length;
+ cur_token = 0;
+
+ mmapstr = mmap_string_new_len(message, length);
+ if (mmapstr == NULL) {
+ res = MAIL_ERROR_MEMORY;
+ goto err;
+ }
+
+ r = mmap_string_ref(mmapstr);
+ if (r < 0) {
+ res = MAIL_ERROR_MEMORY;
+ goto free_mmap;
+ }
+
+ * result = mmapstr->str;
+ * result_len = length;
+
+ return MAIL_NO_ERROR;
+
+ free_mmap:
+ mmap_string_free(mmapstr);
+ err:
+ return res;
+}
+
+int mailmessage_generic_fetch_header(mailmessage * msg_info,
+ char ** result,
+ size_t * result_len)
+{
+ int r;
+ char * message;
+ size_t cur_token;
+ size_t length;
+ MMAPString * mmapstr;
+ char * headers;
+ int res;
+ struct generic_message_t * msg;
+
+ msg = msg_info->msg_data;
+ r = mailmessage_generic_prefetch(msg_info);
+ if (r != MAIL_NO_ERROR) {
+ res = r;
+ goto err;
+ }
+
+ message = msg->msg_message;
+ length = msg->msg_length;
+ cur_token = 0;
+
+ while (1) {
+ r = mailimf_ignore_field_parse(message, length, &cur_token);
+ if (r == MAILIMF_NO_ERROR) {
+ /* do nothing */
+ }
+ else
+ break;
+ }
+ mailimf_crlf_parse(message, length, &cur_token);
+
+ mmapstr = mmap_string_new_len(message, cur_token);
+ if (mmapstr == NULL) {
+ res = MAIL_ERROR_MEMORY;
+ goto err;
+ }
+
+ r = mmap_string_ref(mmapstr);
+ if (r < 0) {
+ res = MAIL_ERROR_MEMORY;
+ goto free_mmap;
+ }
+
+ headers = mmapstr->str;
+
+ * result = headers;
+ * result_len = cur_token;
+
+ return MAIL_NO_ERROR;
+
+ free_mmap:
+ mmap_string_free(mmapstr);
+ err:
+ return res;
+}
+
+int mailmessage_generic_fetch_body(mailmessage * msg_info,
+ char ** result, size_t * result_len)
+{
+ int r;
+ char * message;
+ size_t cur_token;
+ MMAPString * mmapstr;
+ size_t length;
+ int res;
+ struct generic_message_t * msg;
+
+ msg = msg_info->msg_data;
+ r = mailmessage_generic_prefetch(msg_info);
+ if (r != MAIL_NO_ERROR) {
+ res = r;
+ goto err;
+ }
+
+ message = msg->msg_message;
+ length = msg->msg_length;
+ cur_token = 0;
+
+ while (1) {
+ r = mailimf_ignore_field_parse(message, length, &cur_token);
+ if (r == MAILIMF_NO_ERROR) {
+ /* do nothing */
+ }
+ else
+ break;
+ }
+ mailimf_crlf_parse(message, length, &cur_token);
+
+ mmapstr = mmap_string_new_len(message + cur_token, length - cur_token);
+ if (mmapstr == NULL) {
+ res = MAIL_ERROR_MEMORY;
+ goto err;
+ }
+
+ r = mmap_string_ref(mmapstr);
+ if (r < 0) {
+ res = MAIL_ERROR_MEMORY;
+ goto free_mmap;
+ }
+
+ * result = mmapstr->str;
+ * result_len = length - cur_token;
+
+ return MAIL_NO_ERROR;
+
+ free_mmap:
+ mmap_string_free(mmapstr);
+ err:
+ return res;
+}
+
+
+
+
+int
+mailmessage_generic_get_bodystructure(mailmessage * msg_info,
+ struct mailmime ** result)
+{
+ int r;
+
+ r = mailmessage_generic_prefetch_bodystructure(msg_info);
+ if (r != MAIL_NO_ERROR)
+ return r;
+
+ * result = msg_info->msg_mime;
+
+ return MAIL_NO_ERROR;
+}
+
+
+
+
+int
+mailmessage_generic_fetch_section(mailmessage * msg_info,
+ struct mailmime * mime,
+ char ** result, size_t * result_len)
+{
+ MMAPString * mmapstr;
+ int r;
+ int res;
+
+ mmapstr = mmap_string_new_len(mime->mm_body->dt_data.dt_text.dt_data,
+ mime->mm_body->dt_data.dt_text.dt_length);
+ if (mmapstr == NULL) {
+ res = MAIL_ERROR_MEMORY;
+ goto err;
+ }
+
+ r = mmap_string_ref(mmapstr);
+ if (r < 0) {
+ res = MAIL_ERROR_MEMORY;
+ goto free_mmap;
+ }
+
+ * result = mmapstr->str;
+ * result_len = mmapstr->len;
+
+ return MAIL_NO_ERROR;
+
+ free_mmap:
+ mmap_string_free(mmapstr);
+ err:
+ return res;
+}
+
+int
+mailmessage_generic_fetch_section_header(mailmessage * msg_info,
+ struct mailmime * mime,
+ char ** result,
+ size_t * result_len)
+{
+ MMAPString * mmapstr;
+ int r;
+ int res;
+ size_t cur_token;
+
+ /* skip mime */
+
+ cur_token = 0;
+
+ if (mime->mm_type == MAILMIME_MESSAGE) {
+
+ while (1) {
+ r = mailimf_ignore_field_parse(mime->mm_body->dt_data.dt_text.dt_data,
+ mime->mm_body->dt_data.dt_text.dt_length, &cur_token);
+ if (r == MAILIMF_NO_ERROR) {
+ /* do nothing */
+ }
+ else
+ break;
+ }
+
+ r = mailimf_crlf_parse(mime->mm_body->dt_data.dt_text.dt_data,
+ mime->mm_body->dt_data.dt_text.dt_length, &cur_token);
+ if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
+ res = maildriver_imf_error_to_mail_error(r);
+ goto err;
+ }
+ }
+
+ mmapstr = mmap_string_new_len(mime->mm_body->dt_data.dt_text.dt_data,
+ cur_token);
+ if (mmapstr == NULL) {
+ res = MAIL_ERROR_MEMORY;
+ goto err;
+ }
+
+ r = mmap_string_ref(mmapstr);
+ if (r < 0) {
+ res = MAIL_ERROR_MEMORY;
+ goto free_mmap;
+ }
+
+ * result = mmapstr->str;
+ * result_len = mmapstr->len;
+
+ return MAIL_NO_ERROR;
+
+ free_mmap:
+ mmap_string_free(mmapstr);
+ err:
+ return res;
+}
+
+int
+mailmessage_generic_fetch_section_mime(mailmessage * msg_info,
+ struct mailmime * mime,
+ char ** result,
+ size_t * result_len)
+{
+ MMAPString * mmapstr;
+ int r;
+ int res;
+ size_t cur_token;
+
+ cur_token = 0;
+
+ /* skip header */
+
+ while (1) {
+ r = mailimf_ignore_field_parse(mime->mm_mime_start,
+ mime->mm_length, &cur_token);
+ if (r == MAILIMF_NO_ERROR) {
+ /* do nothing */
+ }
+ else
+ break;
+ }
+
+ r = mailimf_crlf_parse(mime->mm_mime_start, mime->mm_length, &cur_token);
+ if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
+ res = maildriver_imf_error_to_mail_error(r);
+ goto err;
+ }
+
+ mmapstr = mmap_string_new_len(mime->mm_mime_start, cur_token);
+ if (mmapstr == NULL) {
+ res = MAIL_ERROR_MEMORY;
+ goto err;
+ }
+
+ r = mmap_string_ref(mmapstr);
+ if (r < 0) {
+ res = MAIL_ERROR_MEMORY;
+ goto free_mmap;
+ }
+
+ * result = mmapstr->str;
+ * result_len = mmapstr->len;
+
+ return MAIL_NO_ERROR;
+
+ free_mmap:
+ mmap_string_free(mmapstr);
+ err:
+ return res;
+}
+
+int
+mailmessage_generic_fetch_section_body(mailmessage * msg_info,
+ struct mailmime * mime,
+ char ** result,
+ size_t * result_len)
+{
+ MMAPString * mmapstr;
+ int r;
+ int res;
+ size_t cur_token;
+
+ cur_token = 0;
+
+ if (mime->mm_type == MAILMIME_MESSAGE) {
+
+ /* skip header */
+
+ while (1) {
+ r = mailimf_ignore_field_parse(mime->mm_body->dt_data.dt_text.dt_data,
+ mime->mm_body->dt_data.dt_text.dt_length, &cur_token);
+ if (r == MAILIMF_NO_ERROR) {
+ /* do nothing */
+ }
+ else
+ break;
+ }
+
+ r = mailimf_crlf_parse(mime->mm_body->dt_data.dt_text.dt_data,
+ mime->mm_body->dt_data.dt_text.dt_length, &cur_token);
+ if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
+ res = maildriver_imf_error_to_mail_error(r);
+ goto err;
+ }
+ }
+
+ mmapstr = mmap_string_new_len(mime->mm_body->dt_data.dt_text.dt_data +
+ cur_token, mime->mm_body->dt_data.dt_text.dt_length - cur_token);
+ if (mmapstr == NULL) {
+ res = MAIL_ERROR_MEMORY;
+ goto err;
+ }
+
+ r = mmap_string_ref(mmapstr);
+ if (r < 0) {
+ res = MAIL_ERROR_MEMORY;
+ goto free_mmap;
+ }
+
+ * result = mmapstr->str;
+ * result_len = mmapstr->len;
+
+ return MAIL_NO_ERROR;
+
+ free_mmap:
+ mmap_string_free(mmapstr);
+ err:
+ return res;
+}
+
+int mailmessage_generic_fetch_envelope(mailmessage * msg_info,
+ struct mailimf_fields ** result)
+{
+ int r;
+ int res;
+ size_t cur_token;
+ char * header;
+ size_t length;
+ struct mailimf_fields * fields;
+
+ r = mailmessage_fetch_header(msg_info, &header, &length);
+ if (r != MAIL_NO_ERROR) {
+ res = r;
+ goto err;
+ }
+
+ cur_token = 0;
+
+ r = mailimf_envelope_fields_parse(header, length, &cur_token,
+ &fields);
+ if (r != MAILIMF_NO_ERROR) {
+ res = maildriver_imf_error_to_mail_error(r);
+ goto free;
+ /* do nothing */
+ }
+
+ mailmessage_fetch_result_free(msg_info, header);
+
+ * result = fields;
+
+ return MAIL_NO_ERROR;
+
+ free:
+ mailmessage_fetch_result_free(msg_info, header);
+ err:
+ return res;
+}
diff --git a/libetpan/src/driver/interface/mailmessage_tools.h b/libetpan/src/driver/interface/mailmessage_tools.h
new file mode 100644
index 0000000..fd055c7
--- a/dev/null
+++ b/libetpan/src/driver/interface/mailmessage_tools.h
@@ -0,0 +1,103 @@
+/*
+ * 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 MAILMESSAGE_TOOLS_H
+
+#define MAILMESSAGE_TOOLS_H
+
+#include "mailmessage_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int
+mailmessage_generic_initialize(mailmessage *
+ msg_info);
+
+void mailmessage_generic_uninitialize(mailmessage *
+ msg_info);
+
+void mailmessage_generic_flush(mailmessage * msg_info);
+
+void mailmessage_generic_fetch_result_free(mailmessage * msg_info,
+ char * msg);
+
+int mailmessage_generic_fetch(mailmessage * msg_info,
+ char ** result,
+ size_t * result_len);
+
+int mailmessage_generic_fetch_header(mailmessage * msg_info,
+ char ** result,
+ size_t * result_len);
+
+int mailmessage_generic_fetch_body(mailmessage * msg_info,
+ char ** result, size_t * result_len);
+
+int mailmessage_generic_get_bodystructure(mailmessage *
+ msg_info,
+ struct mailmime ** result);
+
+int
+mailmessage_generic_fetch_section(mailmessage * msg_info,
+ struct mailmime * mime,
+ char ** result, size_t * result_len);
+
+int
+mailmessage_generic_fetch_section_header(mailmessage * msg_info,
+ struct mailmime * mime,
+ char ** result,
+ size_t * result_len);
+
+int
+mailmessage_generic_fetch_section_mime(mailmessage * msg_info,
+ struct mailmime * mime,
+ char ** result,
+ size_t * result_len);
+
+int
+mailmessage_generic_fetch_section_body(mailmessage * msg_info,
+ struct mailmime * mime,
+ char ** result,
+ size_t * result_len);
+
+int mailmessage_generic_fetch_envelope(mailmessage * msg_info,
+ struct mailimf_fields ** result);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libetpan/src/driver/interface/mailmessage_types.c b/libetpan/src/driver/interface/mailmessage_types.c
new file mode 100644
index 0000000..e0955e4
--- a/dev/null
+++ b/libetpan/src/driver/interface/mailmessage_types.c
@@ -0,0 +1,92 @@
+/*
+ * 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 "mailmessage_types.h"
+
+#include "mail.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+mailmessage * mailmessage_new(void)
+{
+ mailmessage * msg_info;
+
+ msg_info = malloc(sizeof(* msg_info));
+ if (msg_info == NULL)
+ goto err;
+
+ msg_info->msg_driver = NULL;
+ msg_info->msg_session = NULL;
+ msg_info->msg_index = 0;
+ msg_info->msg_uid = NULL;
+
+ msg_info->msg_cached = FALSE;
+ msg_info->msg_size = 0;
+ msg_info->msg_fields = NULL;
+ memset(&msg_info->msg_single_fields,
+ 0, sizeof(struct mailimf_single_fields));
+ msg_info->msg_resolved = FALSE;
+ msg_info->msg_flags = NULL;
+
+ msg_info->msg_mime = NULL;
+ msg_info->msg_data = NULL;
+
+ msg_info->msg_folder = NULL;
+ msg_info->msg_user_data = NULL;
+
+ return msg_info;
+
+ err:
+ return NULL;
+}
+
+void mailmessage_free(mailmessage * msg_info)
+{
+ if (msg_info->msg_driver != NULL) {
+ if (msg_info->msg_driver->msg_uninitialize != NULL)
+ msg_info->msg_driver->msg_uninitialize(msg_info);
+ }
+
+ if (msg_info->msg_fields != NULL)
+ mailimf_fields_free(msg_info->msg_fields);
+ if (msg_info->msg_mime != NULL)
+ mailmime_free(msg_info->msg_mime);
+ if (msg_info->msg_flags != NULL)
+ mail_flags_free(msg_info->msg_flags);
+ if (msg_info->msg_uid != NULL)
+ free(msg_info->msg_uid);
+ free(msg_info);
+}
diff --git a/libetpan/src/driver/interface/mailmessage_types.h b/libetpan/src/driver/interface/mailmessage_types.h
new file mode 100644
index 0000000..c3ed2c4
--- a/dev/null
+++ b/libetpan/src/driver/interface/mailmessage_types.h
@@ -0,0 +1,50 @@
+/*
+ * 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 MAILMESSAGE_TYPES_H
+
+#define MAILMESSAGE_TYPES_H
+
+#include <libetpan/maildriver_types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libetpan/src/driver/interface/mailstorage.c b/libetpan/src/driver/interface/mailstorage.c
new file mode 100644
index 0000000..2e2ddcb
--- a/dev/null
+++ b/libetpan/src/driver/interface/mailstorage.c
@@ -0,0 +1,341 @@
+/*
+ * 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 "mailstorage.h"
+
+#include "maildriver.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+static int mailstorage_get_folder(struct mailstorage * storage,
+ char * pathname, mailsession ** result);
+
+struct mailfolder * mailfolder_new(struct mailstorage * storage,
+ char * pathname, char * virtual_name)
+{
+ struct mailfolder * folder;
+
+ folder = malloc(sizeof(struct mailfolder));
+ if (folder == NULL)
+ goto err;
+
+ if (pathname != NULL) {
+ folder->fld_pathname = strdup(pathname);
+ if (folder->fld_pathname == NULL)
+ goto free;
+ }
+ else
+ folder->fld_pathname = NULL;
+
+ if (virtual_name != NULL) {
+ folder->fld_virtual_name = strdup(virtual_name);
+ if (folder->fld_virtual_name == NULL)
+ goto free_pathname;
+ }
+ else
+ folder->fld_virtual_name = NULL;
+
+ folder->fld_storage = storage;
+
+ folder->fld_session = NULL;
+ folder->fld_shared_session = 0;
+ folder->fld_pos = NULL;
+
+ folder->fld_parent = NULL;
+ folder->fld_sibling_index = 0;
+ folder->fld_children = carray_new(128);
+ if (folder->fld_children == NULL)
+ goto free_virtualname;
+
+ return folder;
+
+free_virtualname:
+ if (folder->fld_virtual_name != NULL)
+ free(folder->fld_virtual_name);
+free_pathname:
+ if (folder->fld_pathname != NULL)
+ free(folder->fld_pathname);
+free:
+ free(folder);
+err:
+ return NULL;
+}
+
+void mailfolder_free(struct mailfolder * folder)
+{
+ if (folder->fld_parent != NULL)
+ mailfolder_detach_parent(folder);
+
+ while (carray_count(folder->fld_children) > 0) {
+ struct mailfolder * child;
+
+ child = carray_get(folder->fld_children, 0);
+ mailfolder_detach_parent(child);
+ }
+
+ carray_free(folder->fld_children);
+
+ if (folder->fld_session != NULL)
+ mailfolder_disconnect(folder);
+
+ if (folder->fld_virtual_name != NULL)
+ free(folder->fld_virtual_name);
+ if (folder->fld_pathname != NULL)
+ free(folder->fld_pathname);
+ free(folder);
+}
+
+int mailfolder_connect(struct mailfolder * folder)
+{
+ mailsession * session;
+ int res;
+ int r;
+
+ if (folder->fld_storage == NULL) {
+ res = MAIL_ERROR_INVAL;
+ goto err;
+ }
+
+ if (folder->fld_storage->sto_session == NULL) {
+ r = mailstorage_connect(folder->fld_storage);
+ if (r != MAIL_NO_ERROR) {
+ res = r;
+ goto err;
+ }
+ }
+
+ if (folder->fld_session != NULL) {
+ if ((folder->fld_pathname != NULL) && (folder->fld_shared_session)) {
+ if (folder->fld_session->sess_driver->sess_select_folder != NULL) {
+ r = mailsession_select_folder(folder->fld_session,
+ folder->fld_pathname);
+ if (r != MAIL_NO_ERROR) {
+ res = r;
+ goto err;
+ }
+ }
+ }
+
+ return MAIL_NO_ERROR;
+ }
+
+ r = mailstorage_get_folder(folder->fld_storage, folder->fld_pathname,
+ &session);
+ if (r != MAIL_NO_ERROR) {
+ res = r;
+ goto err;
+ }
+ folder->fld_session = session;
+ folder->fld_shared_session = (session == folder->fld_storage->sto_session);
+ if (folder->fld_shared_session) {
+ r = clist_append(folder->fld_storage->sto_shared_folders, folder);
+ if (r < 0) {
+ folder->fld_session = NULL;
+ res = MAIL_ERROR_MEMORY;
+ goto err;
+ }
+ folder->fld_pos = clist_end(folder->fld_storage->sto_shared_folders);
+ }
+
+ return MAIL_NO_ERROR;
+
+err:
+ return res;
+}
+
+void mailfolder_disconnect(struct mailfolder * folder)
+{
+ if (folder->fld_session == NULL)
+ return;
+
+ if (folder->fld_shared_session) {
+ clist_delete(folder->fld_storage->sto_shared_folders, folder->fld_pos);
+ folder->fld_pos = NULL;
+ }
+ else {
+ mailsession_logout(folder->fld_session);
+ mailsession_free(folder->fld_session);
+ }
+
+ folder->fld_session = NULL;
+}
+
+int mailfolder_add_child(struct mailfolder * parent,
+ struct mailfolder * child)
+{
+ unsigned int index;
+ int r;
+
+ r = carray_add(parent->fld_children, child, &index);
+ if (r < 0)
+ return MAIL_ERROR_MEMORY;
+
+ child->fld_sibling_index = index;
+ child->fld_parent = parent;
+
+ return MAIL_NO_ERROR;
+}
+
+int mailfolder_detach_parent(struct mailfolder * folder)
+{
+ unsigned int i;
+ int r;
+
+ if (folder->fld_parent == NULL)
+ return MAIL_ERROR_INVAL;
+
+ r = carray_delete_slow(folder->fld_parent->fld_children,
+ folder->fld_sibling_index);
+ if (r < 0)
+ return MAIL_ERROR_INVAL;
+
+ for(i = 0 ; i < carray_count(folder->fld_parent->fld_children) ; i ++) {
+ struct mailfolder * child;
+
+ child = carray_get(folder->fld_parent->fld_children, i);
+ child->fld_sibling_index = i;
+ }
+
+ folder->fld_parent = NULL;
+ folder->fld_sibling_index = 0;
+
+ return MAIL_NO_ERROR;
+}
+
+struct mailstorage * mailstorage_new(char * sto_id)
+{
+ struct mailstorage * storage;
+
+ storage = malloc(sizeof(struct mailstorage));
+ if (storage == NULL)
+ goto err;
+
+ if (sto_id != NULL) {
+ storage->sto_id = strdup(sto_id);
+ if (storage->sto_id == NULL)
+ goto free;
+ }
+ else
+ storage->sto_id = NULL;
+
+ storage->sto_data = NULL;
+ storage->sto_session = NULL;
+ storage->sto_driver = NULL;
+ storage->sto_shared_folders = clist_new();
+ if (storage->sto_shared_folders == NULL)
+ goto free_id;
+
+ return storage;
+
+ free_id:
+ if (storage->sto_id != NULL)
+ free(storage->sto_id);
+ free:
+ free(storage);
+ err:
+ return NULL;
+}
+
+void mailstorage_free(struct mailstorage * storage)
+{
+ if (storage->sto_session != NULL)
+ mailstorage_disconnect(storage);
+
+ if (storage->sto_driver != NULL) {
+ if (storage->sto_driver->sto_uninitialize != NULL)
+ storage->sto_driver->sto_uninitialize(storage);
+ }
+
+ clist_free(storage->sto_shared_folders);
+
+ if (storage->sto_id != NULL)
+ free(storage->sto_id);
+
+ free(storage);
+}
+
+int mailstorage_connect(struct mailstorage * storage)
+{
+ if (storage->sto_session != NULL)
+ return MAIL_NO_ERROR;
+
+ if (!clist_isempty(storage->sto_shared_folders))
+ return MAIL_ERROR_BAD_STATE;
+
+ if (storage->sto_driver->sto_connect == NULL)
+ return MAIL_ERROR_NOT_IMPLEMENTED;
+
+ return storage->sto_driver->sto_connect(storage);
+}
+
+
+void mailstorage_disconnect(struct mailstorage * storage)
+{
+ int r;
+ clistiter * cur;
+
+ while ((cur = clist_begin(storage->sto_shared_folders)) != NULL) {
+ struct mailfolder * folder;
+
+ folder = cur->data;
+ mailfolder_disconnect(folder);
+ }
+
+ if (storage->sto_session == NULL)
+ return;
+
+ r = mailsession_logout(storage->sto_session);
+
+ mailsession_free(storage->sto_session);
+ storage->sto_session = NULL;
+}
+
+
+int mailstorage_noop(struct mailstorage * storage)
+{
+ return mailsession_noop(storage->sto_session);
+}
+
+
+static int mailstorage_get_folder(struct mailstorage * storage,
+ char * pathname, mailsession ** result)
+{
+ if (storage->sto_driver->sto_get_folder_session == NULL)
+ return MAIL_ERROR_NOT_IMPLEMENTED;
+
+ return storage->sto_driver->sto_get_folder_session(storage,
+ pathname, result);
+}
diff --git a/libetpan/src/driver/interface/mailstorage.h b/libetpan/src/driver/interface/mailstorage.h
new file mode 100644
index 0000000..e8cbda3
--- a/dev/null
+++ b/libetpan/src/driver/interface/mailstorage.h
@@ -0,0 +1,99 @@
+/*
+ * 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 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/libetpan/src/driver/interface/mailstorage_tools.c b/libetpan/src/driver/interface/mailstorage_tools.c
new file mode 100644
index 0000000..9d39cab
--- a/dev/null
+++ b/libetpan/src/driver/interface/mailstorage_tools.c
@@ -0,0 +1,372 @@
+/*
+ * 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 "mailstorage_tools.h"
+
+#include "libetpan-config.h"
+
+#include <sys/types.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/wait.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <string.h>
+
+#include "mail.h"
+#include "mailmessage.h"
+#include "maildriver.h"
+
+/* tools */
+
+/* connection to TCP/IP server */
+
+static int tcp_connect(char * server, uint16_t port)
+{
+ struct hostent * remotehost;
+ struct sockaddr_in sa;
+ int s;
+ int r;
+
+ s = socket(PF_INET, SOCK_STREAM, 0);
+ if (s == -1)
+ goto err;
+
+ remotehost = gethostbyname(server);
+ if (remotehost == NULL)
+ goto close_socket;
+
+ sa.sin_family = AF_INET;
+ sa.sin_port = htons(port);
+ memcpy(&sa.sin_addr, remotehost->h_addr, remotehost->h_length);
+
+ r = connect(s, (struct sockaddr *) &sa, sizeof(struct sockaddr_in));
+ if (r == -1)
+ goto close_socket;
+
+ return s;
+
+ close_socket:
+ close(s);
+ err:
+ return -1;
+}
+
+
+/* connection through a shell command */
+
+static void do_exec_command(int fd, const char *command,
+ char *servername, uint16_t port)
+{
+ int i, maxopen;
+
+ if (fork() > 0) {
+ /* Fork again to become a child of init rather than
+ the etpan client. */
+ exit(0);
+ }
+
+ if (servername)
+ setenv("ETPANSERVER", servername, 1);
+ else
+ unsetenv("ETPANSERVER");
+
+ if (port) {
+ char porttext[20];
+
+ snprintf(porttext, sizeof(porttext), "%d", port);
+ setenv("ETPANPORT", porttext, 1);
+ }
+ else {
+ unsetenv("ETPANPORT");
+ }
+
+ /* Not a lot we can do if there's an error other than bail. */
+ if (dup2(fd, 0) == -1)
+ exit(1);
+ if (dup2(fd, 1) == -1)
+ exit(1);
+
+ /* Should we close stderr and reopen /dev/null? */
+
+ maxopen = sysconf(_SC_OPEN_MAX);
+ for (i=3; i < maxopen; i++)
+ close(i);
+
+#ifdef TIOCNOTTY
+ /* Detach from the controlling tty if we have one. Otherwise,
+ SSH might do something stupid like trying to use it instead
+ of running $SSH_ASKPASS. Doh. */
+ fd = open("/dev/tty", O_RDONLY);
+ if (fd != -1) {
+ ioctl(fd, TIOCNOTTY, NULL);
+ close(fd);
+ }
+#endif /* TIOCNOTTY */
+
+ execl("/bin/sh", "/bin/sh", "-c", command, NULL);
+
+ /* Eep. Shouldn't reach this */
+ exit(1);
+}
+
+static int subcommand_connect(char *command, char *servername, uint16_t port)
+{
+ int sockfds[2];
+ pid_t childpid;
+
+ if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockfds))
+ return -1;
+
+ childpid = fork();
+ if (!childpid) {
+ do_exec_command(sockfds[1], command, servername, port);
+ }
+ else if (childpid == -1) {
+ close(sockfds[0]);
+ close(sockfds[1]);
+ return -1;
+ }
+
+ close(sockfds[1]);
+
+ /* Reap child, leaving grandchild process to run */
+ waitpid(childpid, NULL, 0);
+
+ return sockfds[0];
+}
+
+int mailstorage_generic_connect(mailsession_driver * driver,
+ char * servername,
+ uint16_t port,
+ char * command,
+ int connection_type,
+ int cache_function_id,
+ char * cache_directory,
+ int flags_function_id,
+ char * flags_directory,
+ mailsession ** result)
+{
+ int r;
+ int res;
+ mailstream * stream;
+ int fd;
+ mailsession * session;
+ int connect_result;
+
+ switch (connection_type) {
+ case CONNECTION_TYPE_PLAIN:
+ case CONNECTION_TYPE_TRY_STARTTLS:
+ case CONNECTION_TYPE_STARTTLS:
+ case CONNECTION_TYPE_TLS:
+ fd = tcp_connect(servername, port);
+ if (fd == -1) {
+ res = MAIL_ERROR_CONNECT;
+ goto err;
+ }
+ break;
+
+ case CONNECTION_TYPE_COMMAND:
+ case CONNECTION_TYPE_COMMAND_TRY_STARTTLS:
+ case CONNECTION_TYPE_COMMAND_STARTTLS:
+ case CONNECTION_TYPE_COMMAND_TLS:
+ fd = subcommand_connect(command, servername, port);
+ break;
+
+ default:
+ fd = -1;
+ break;
+ }
+
+ if (fd == -1) {
+ res = MAIL_ERROR_INVAL;
+ goto err;
+ }
+
+ switch (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:
+ stream = mailstream_socket_open(fd);
+ break;
+
+ case CONNECTION_TYPE_TLS:
+ case CONNECTION_TYPE_COMMAND_TLS:
+ stream = mailstream_ssl_open(fd);
+ break;
+
+ default:
+ stream = NULL;
+ break;
+ }
+
+ if (stream == NULL) {
+ res = MAIL_ERROR_STREAM;
+ close(fd);
+ goto err;
+ }
+
+ session = mailsession_new(driver);
+ if (session == NULL) {
+ res = MAIL_ERROR_MEMORY;
+ goto close_stream;
+ }
+
+ if (cache_directory != NULL) {
+ char cache_directory_server[PATH_MAX];
+
+ snprintf(cache_directory_server, PATH_MAX, "%s/%s",
+ cache_directory, servername);
+
+ r = mailsession_parameters(session,
+ cache_function_id,
+ cache_directory_server);
+ if (r != MAIL_NO_ERROR) {
+ res = r;
+ goto close_stream;
+ }
+ }
+
+ if (flags_directory != NULL) {
+ char flags_directory_server[PATH_MAX];
+
+ snprintf(flags_directory_server, PATH_MAX, "%s/%s",
+ flags_directory, servername);
+
+ r = mailsession_parameters(session,
+ flags_function_id,
+ flags_directory_server);
+ if (r != MAIL_NO_ERROR) {
+ res = r;
+ goto close_stream;
+ }
+ }
+
+ r = mailsession_connect_stream(session, stream);
+ switch (r) {
+ case MAIL_NO_ERROR_NON_AUTHENTICATED:
+ case MAIL_NO_ERROR_AUTHENTICATED:
+ case MAIL_NO_ERROR:
+ break;
+ default:
+ res = r;
+ goto free;
+ }
+
+ connect_result = r;
+
+ switch (connection_type) {
+ case CONNECTION_TYPE_TRY_STARTTLS:
+ case CONNECTION_TYPE_COMMAND_TRY_STARTTLS:
+ r = mailsession_starttls(session);
+ if ((r != MAIL_NO_ERROR) && (r != MAIL_ERROR_NO_TLS)) {
+ res = r;
+ goto free;
+ }
+ break;
+
+ case CONNECTION_TYPE_STARTTLS:
+ case CONNECTION_TYPE_COMMAND_STARTTLS:
+ r = mailsession_starttls(session);
+ if (r != MAIL_NO_ERROR) {
+ res = r;
+ goto free;
+ }
+ }
+
+ * result = session;
+
+ return connect_result;
+
+ close_stream:
+ mailstream_close(stream);
+ free:
+ mailsession_free(session);
+ err:
+ return res;
+}
+
+
+
+
+
+int mailstorage_generic_auth(mailsession * session,
+ int connect_result,
+ int auth_type,
+ char * login,
+ char * password)
+{
+ int must_auth;
+ int r;
+ int res;
+
+ r = connect_result;
+
+ must_auth = FALSE;
+ switch (r) {
+ case MAIL_NO_ERROR_NON_AUTHENTICATED:
+ must_auth = TRUE;
+ break;
+ case MAIL_NO_ERROR_AUTHENTICATED:
+ case MAIL_NO_ERROR:
+ break;
+ default:
+ res = r;
+ goto err;
+ }
+
+ if ((login == NULL) || (password == NULL))
+ must_auth = FALSE;
+
+ if (must_auth) {
+ r = mailsession_login(session, login, password);
+ if (r != MAIL_NO_ERROR) {
+ mailsession_logout(session);
+ res = r;
+ goto err;
+ }
+ }
+
+ return MAIL_NO_ERROR;
+
+ err:
+ return res;
+}
diff --git a/libetpan/src/driver/interface/mailstorage_tools.h b/libetpan/src/driver/interface/mailstorage_tools.h
new file mode 100644
index 0000000..113dcdf
--- a/dev/null
+++ b/libetpan/src/driver/interface/mailstorage_tools.h
@@ -0,0 +1,67 @@
+/*
+ * 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 "mailstorage.h"
+
+#ifndef MAILSTORAGE_TOOLS_H
+
+#define MAILSTORAGE_TOOLS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int mailstorage_generic_connect(mailsession_driver * driver,
+ char * servername,
+ uint16_t port,
+ char * command,
+ int connection_type,
+ int cache_function_id,
+ char * cache_directory,
+ int flags_function_id,
+ char * flags_directory,
+ mailsession ** result);
+
+int mailstorage_generic_auth(mailsession * session,
+ int connect_result,
+ int auth_type,
+ char * login,
+ char * password);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libetpan/src/driver/interface/mailstorage_types.h b/libetpan/src/driver/interface/mailstorage_types.h
new file mode 100644
index 0000000..d0d18c8
--- a/dev/null
+++ b/libetpan/src/driver/interface/mailstorage_types.h
@@ -0,0 +1,203 @@
+/*
+ * 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 MAILSTORAGE_TYPES_H
+
+#define MAILSTORAGE_TYPES_H
+
+#include <libetpan/maildriver_types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct mailstorage;
+
+typedef struct mailstorage_driver mailstorage_driver;
+
+
+/*
+ There is three kinds of identities :
+ - storage
+ - folders
+ - session
+
+ A storage (struct mailstorage) represents whether a server or
+ a main path,
+
+ A storage can be an IMAP server, the root path of a MH or a mbox file.
+
+ Folders (struct mailfolder) are the mailboxes we can
+ choose in the server or as sub-folder of the main path.
+
+ Folders for IMAP are the IMAP mailboxes, for MH this is one of the
+ folder of the MH storage, for mbox, there is only one folder, the
+ mbox file content;
+
+ A mail session (struct mailsession) is whether a connection to a server
+ or a path that is open. It is the abstraction lower folders and storage.
+ It allow us to send commands.
+
+ We have a session driver for mail session for each kind of storage.
+
+ From a session, we can get a message (struct mailmessage) to read.
+ We have a message driver for each kind of storage.
+*/
+
+/*
+ mailstorage_driver is the driver structure for mail storages
+
+ - name is the name of the driver
+
+ - connect() connects the storage to the remote access or to
+ the path in the local filesystem.
+
+ - get_folder() can have two kinds of behaviour.
+ Either it creates a new session and independant from the session
+ used by the storage and select the given mailbox or
+ it selects the given mailbox in the current session.
+ It depends on the efficiency of the mail driver.
+
+ - uninitialize() frees the data created with mailstorage constructor.
+*/
+
+struct mailstorage_driver {
+ char * sto_name;
+ int (* sto_connect)(struct mailstorage * storage);
+ int (* sto_get_folder_session)(struct mailstorage * storage,
+ char * pathname, mailsession ** result);
+ void (* sto_uninitialize)(struct mailstorage * storage);
+};
+
+/*
+ mailstorage is the data structure for a storage
+
+ - id is the name of the storage, it can be NULL.
+
+ - data is the data specific to the driver.
+ This is the internal state of the storage.
+
+ - session is the session related to the storage.
+
+ - driver is the driver for the storage.
+
+ - shared_folders is the list of folders returned by the storage.
+*/
+
+struct mailstorage {
+ char * sto_id;
+ void * sto_data;
+ mailsession * sto_session;
+ mailstorage_driver * sto_driver;
+ clist * sto_shared_folders; /* list of (struct mailfolder *) */
+
+ void * sto_user_data;
+};
+
+
+
+/*
+ mailfolder is the data structure for a mailbox
+
+ - pathname is the path of the mailbox on the storage
+
+ - virtual_name is the folder identifier, it can be a path,
+ a name or NULL.
+
+ - storage is the storage to which the folder belongs to.
+
+ - session is the session related to the folder. It can be
+ different of the session of the storage.
+
+ - shared_session is != 0 if the session is the same as the
+ session of the storage.
+
+ - pos is the position of the folder in the "shared_folders" field
+ of the storage.
+
+ folders can be chained into a tree.
+
+ - parent is the parent of the folder.
+
+ - sibling_index is the index of the folder in the list of children
+ of the parent.
+
+ - children is the folder.
+*/
+
+struct mailfolder {
+ char * fld_pathname;
+ char * fld_virtual_name;
+
+ struct mailstorage * fld_storage;
+
+ mailsession * fld_session;
+ int fld_shared_session;
+ clistiter * fld_pos;
+
+ struct mailfolder * fld_parent;
+ unsigned int fld_sibling_index;
+ carray * fld_children; /* array of (struct mailfolder *) */
+
+ void * fld_user_data;
+};
+
+/*
+ this is the type of socket connection
+*/
+
+enum {
+ CONNECTION_TYPE_PLAIN, /* when the connection is plain text */
+ CONNECTION_TYPE_STARTTLS, /* when the connection is first plain,
+ then, we want to switch to
+ TLS (secure connection) */
+ CONNECTION_TYPE_TRY_STARTTLS, /* the connection is first plain,
+ then, we will try to switch to TLS */
+ CONNECTION_TYPE_TLS, /* the connection is over TLS */
+ CONNECTION_TYPE_COMMAND, /* the connection is over a shell command */
+ CONNECTION_TYPE_COMMAND_STARTTLS, /* the connection is over a shell
+ command and STARTTLS will be used */
+ CONNECTION_TYPE_COMMAND_TRY_STARTTLS, /* the connection is over
+ a shell command and STARTTLS will
+ be tried */
+ CONNECTION_TYPE_COMMAND_TLS, /* the connection is over a shell
+ command in TLS */
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif