From 9e549686b23b6dffdcbd09c9b10dc2cb795fbcdf Mon Sep 17 00:00:00 2001 From: zautrix Date: Fri, 18 Mar 2005 20:17:03 +0000 Subject: Initial revision --- (limited to 'libetpan/src/driver/interface') 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 +#include +#include + +/* *********************************************************************** */ +/* 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 +#include + +#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 +#include +#include +#include +#include + +#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 +#include +#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 +#include + +#include +#include +#include +#include + +#include +#include + +#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 +#include + +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 + +#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 + +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 + +#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 + +#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 +#include + +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 + +#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 +#include + +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 +#include + +#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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 + +#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 -- cgit v0.9.0.2