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/implementation/pop3/pop3driver.c') diff --git a/libetpan/src/driver/implementation/pop3/pop3driver.c b/libetpan/src/driver/implementation/pop3/pop3driver.c new file mode 100644 index 0000000..ea69923 --- a/dev/null +++ b/libetpan/src/driver/implementation/pop3/pop3driver.c @@ -0,0 +1,388 @@ +/* + * libEtPan! -- a mail stuff library + * + * Copyright (C) 2001, 2005 - DINH Viet Hoa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the libEtPan! project nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * $Id$ + */ + +#include "pop3driver.h" + +#include +#include + +#include "pop3driver_message.h" +#include "maildriver_tools.h" +#include "pop3driver_tools.h" +#include "mailmessage.h" + +static int pop3driver_initialize(mailsession * session); + +static void pop3driver_uninitialize(mailsession * session); + +static int pop3driver_parameters(mailsession * session, + int id, void * value); + +static int pop3driver_connect_stream(mailsession * session, mailstream * s); + +static int pop3driver_starttls(mailsession * session); + +static int pop3driver_login(mailsession * session, + char * userid, char * password); + +static int pop3driver_logout(mailsession * session); + +static int pop3driver_noop(mailsession * session); + +static int pop3driver_status_folder(mailsession * session, char * mb, + uint32_t * result_messages, uint32_t * result_recent, + uint32_t * result_unseen); + +static int pop3driver_messages_number(mailsession * session, char * mb, + uint32_t * result); + +static int pop3driver_remove_message(mailsession * session, uint32_t num); + +static int pop3driver_get_messages_list(mailsession * session, + struct mailmessage_list ** result); + +static int pop3driver_get_message(mailsession * session, + uint32_t num, mailmessage ** result); + +static mailsession_driver local_pop3_session_driver = { + .sess_name = "pop3", + + .sess_initialize = pop3driver_initialize, + .sess_uninitialize = pop3driver_uninitialize, + + .sess_parameters = pop3driver_parameters, + + .sess_connect_stream = pop3driver_connect_stream, + .sess_connect_path = NULL, + .sess_starttls = pop3driver_starttls, + .sess_login = pop3driver_login, + .sess_logout = pop3driver_logout, + .sess_noop = pop3driver_noop, + + .sess_build_folder_name = NULL, + .sess_create_folder = NULL, + .sess_delete_folder = NULL, + .sess_rename_folder = NULL, + .sess_check_folder = NULL, + .sess_examine_folder = NULL, + .sess_select_folder = NULL, + .sess_expunge_folder = NULL, + .sess_status_folder = pop3driver_status_folder, + .sess_messages_number = pop3driver_messages_number, + .sess_recent_number = pop3driver_messages_number, + .sess_unseen_number = pop3driver_messages_number, + .sess_list_folders = NULL, + .sess_lsub_folders = NULL, + .sess_subscribe_folder = NULL, + .sess_unsubscribe_folder = NULL, + + .sess_append_message = NULL, + .sess_append_message_flags = NULL, + .sess_copy_message = NULL, + .sess_move_message = NULL, + + .sess_get_messages_list = pop3driver_get_messages_list, + .sess_get_envelopes_list = maildriver_generic_get_envelopes_list, + .sess_remove_message = pop3driver_remove_message, +#if 0 + .sess_search_messages = maildriver_generic_search_messages, +#endif + + .sess_get_message = pop3driver_get_message, + .sess_get_message_by_uid = NULL, +}; + +mailsession_driver * pop3_session_driver = &local_pop3_session_driver; + +static inline struct pop3_session_state_data * +get_data(mailsession * session) +{ + return session->sess_data; +} + +static mailpop3 * get_pop3_session(mailsession * session) +{ + return get_data(session)->pop3_session; +} + +static int pop3driver_initialize(mailsession * session) +{ + struct pop3_session_state_data * data; + mailpop3 * pop3; + + pop3 = mailpop3_new(0, NULL); + if (session == NULL) + goto err; + + data = malloc(sizeof(* data)); + if (data == NULL) + goto free; + + data->pop3_session = pop3; + data->pop3_auth_type = POP3DRIVER_AUTH_TYPE_PLAIN; + + session->sess_data = data; + + return MAIL_NO_ERROR; + + free: + mailpop3_free(pop3); + err: + return MAIL_ERROR_MEMORY; +} + +static void pop3driver_uninitialize(mailsession * session) +{ + struct pop3_session_state_data * data; + + data = get_data(session); + + mailpop3_free(data->pop3_session); + free(data); + + session->sess_data = data; +} + +static int pop3driver_connect_stream(mailsession * session, mailstream * s) +{ + int r; + + r = mailpop3_connect(get_pop3_session(session), s); + + switch (r) { + case MAILPOP3_NO_ERROR: + return MAIL_NO_ERROR_NON_AUTHENTICATED; + + default: + return pop3driver_pop3_error_to_mail_error(r); + } +} + +static int pop3driver_starttls(mailsession * session) +{ + int r; + int fd; + mailstream_low * low; + mailstream_low * new_low; + mailpop3 * pop3; + + pop3 = get_pop3_session(session); + + r = mailpop3_stls(pop3); + + switch (r) { + case MAILPOP3_NO_ERROR: + break; + default: + return pop3driver_pop3_error_to_mail_error(r); + } + + low = mailstream_get_low(pop3->pop3_stream); + fd = mailstream_low_get_fd(low); + if (fd == -1) + return MAIL_ERROR_STREAM; + + new_low = mailstream_low_ssl_open(fd); + if (new_low == NULL) + return MAIL_ERROR_STREAM; + mailstream_low_free(low); + mailstream_set_low(pop3->pop3_stream, new_low); + + return MAIL_NO_ERROR; +} + +static int pop3driver_parameters(mailsession * session, + int id, void * value) +{ + struct pop3_session_state_data * data; + + data = get_data(session); + + switch (id) { + case POP3DRIVER_SET_AUTH_TYPE: + { + int * param; + + param = value; + + data->pop3_auth_type = * param; + return MAIL_NO_ERROR; + } + } + + return MAIL_ERROR_INVAL; +} + +static int pop3driver_login(mailsession * session, + char * userid, char * password) +{ + int r; + carray * msg_tab; + struct pop3_session_state_data * data; + + data = get_data(session); + + switch (data->pop3_auth_type) { + case POP3DRIVER_AUTH_TYPE_TRY_APOP: + r = mailpop3_login_apop(get_pop3_session(session), userid, password); + if (r != MAILPOP3_NO_ERROR) + r = mailpop3_login(get_pop3_session(session), userid, password); + break; + + case POP3DRIVER_AUTH_TYPE_APOP: + r = mailpop3_login_apop(get_pop3_session(session), userid, password); + break; + + default: + case POP3DRIVER_AUTH_TYPE_PLAIN: + r = mailpop3_login(get_pop3_session(session), userid, password); + break; + } + + mailpop3_list(get_pop3_session(session), &msg_tab); + + return pop3driver_pop3_error_to_mail_error(r); +} + +static int pop3driver_logout(mailsession * session) +{ + int r; + + r = mailpop3_quit(get_pop3_session(session)); + + return pop3driver_pop3_error_to_mail_error(r); +} + +static int pop3driver_noop(mailsession * session) +{ + int r; + + r = mailpop3_noop(get_pop3_session(session)); + + return pop3driver_pop3_error_to_mail_error(r); +} + +static int pop3driver_status_folder(mailsession * session, char * mb, + uint32_t * result_messages, + uint32_t * result_recent, + uint32_t * result_unseen) +{ + uint32_t count; + int r; + + r = pop3driver_messages_number(session, mb, &count); + if (r != MAIL_NO_ERROR) + return r; + + * result_messages = count; + * result_recent = count; + * result_unseen = count; + + return MAIL_NO_ERROR; +} + +static int pop3driver_messages_number(mailsession * session, char * mb, + uint32_t * result) +{ + carray * msg_tab; + + mailpop3_list(get_pop3_session(session), &msg_tab); + + * result = carray_count(msg_tab) - + get_pop3_session(session)->pop3_deleted_count; + + return MAIL_NO_ERROR; +} + + +/* messages operations */ + +static int pop3driver_remove_message(mailsession * session, uint32_t num) +{ + mailpop3 * pop3; + int r; + + pop3 = get_pop3_session(session); + + r = mailpop3_dele(pop3, num); + switch (r) { + case MAILPOP3_ERROR_BAD_STATE: + return MAIL_ERROR_BAD_STATE; + + case MAILPOP3_ERROR_NO_SUCH_MESSAGE: + return MAIL_ERROR_MSG_NOT_FOUND; + + case MAILPOP3_ERROR_STREAM: + return MAIL_ERROR_STREAM; + + case MAILPOP3_NO_ERROR: + return MAIL_NO_ERROR; + + default: + return MAIL_ERROR_REMOVE; + } +} + +static int pop3driver_get_messages_list(mailsession * session, + struct mailmessage_list ** result) +{ + mailpop3 * pop3; + + pop3 = get_pop3_session(session); + + return pop3_get_messages_list(pop3, session, + pop3_message_driver, result); +} + +static int pop3driver_get_message(mailsession * session, + uint32_t num, mailmessage ** result) +{ + mailmessage * msg_info; + int r; + + msg_info = mailmessage_new(); + if (msg_info == NULL) + return MAIL_ERROR_MEMORY; + + r = mailmessage_init(msg_info, session, pop3_message_driver, num, 0); + if (r != MAIL_NO_ERROR) { + mailmessage_free(msg_info); + return r; + } + + * result = msg_info; + + return MAIL_NO_ERROR; +} -- cgit v0.9.0.2