Diffstat (limited to 'kmicromail/libetpan/generic/nntpdriver_tools.c') (more/less context) (ignore whitespace changes)
-rw-r--r-- | kmicromail/libetpan/generic/nntpdriver_tools.c | 563 |
1 files changed, 563 insertions, 0 deletions
diff --git a/kmicromail/libetpan/generic/nntpdriver_tools.c b/kmicromail/libetpan/generic/nntpdriver_tools.c new file mode 100644 index 0000000..26be916 --- a/dev/null +++ b/kmicromail/libetpan/generic/nntpdriver_tools.c @@ -0,0 +1,563 @@ +/* + * libEtPan! -- a mail stuff library + * + * Copyright (C) 2001, 2002 - DINH Viet Hoa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the libEtPan! project nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * $Id$ + */ + +#include "nntpdriver_tools.h" + +#include "mail.h" +#include "nntpdriver.h" +#include "nntpdriver_cached.h" +#include "newsnntp.h" +#include "maildriver_types.h" +#include "generic_cache.h" +#include "imfcache.h" +#include "mailmessage.h" +#include "mail_cache_db.h" + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> +#include <string.h> +#include <stdlib.h> + +int nntpdriver_nntp_error_to_mail_error(int error) +{ + switch (error) { + case NEWSNNTP_NO_ERROR: + return MAIL_NO_ERROR; + + case NEWSNNTP_ERROR_STREAM: + return MAIL_ERROR_STREAM; + + case NEWSNNTP_ERROR_UNEXPECTED: + return MAIL_ERROR_PROGRAM_ERROR; + + case NEWSNNTP_ERROR_NO_NEWSGROUP_SELECTED: + return MAIL_ERROR_FOLDER_NOT_FOUND; + + case NEWSNNTP_ERROR_NO_ARTICLE_SELECTED: + case NEWSNNTP_ERROR_INVALID_ARTICLE_NUMBER: + case NEWSNNTP_ERROR_ARTICLE_NOT_FOUND: + return MAIL_ERROR_MSG_NOT_FOUND; + + case NEWSNNTP_ERROR_UNEXPECTED_RESPONSE: + case NEWSNNTP_ERROR_INVALID_RESPONSE: + return MAIL_ERROR_PARSE; + + case NEWSNNTP_ERROR_NO_SUCH_NEWS_GROUP: + return MAIL_ERROR_FOLDER_NOT_FOUND; + + case NEWSNNTP_ERROR_POSTING_NOT_ALLOWED: + return MAIL_ERROR_READONLY; + + case NEWSNNTP_ERROR_POSTING_FAILED: + return MAIL_ERROR_APPEND; + + case NEWSNNTP_ERROR_PROGRAM_ERROR: + return MAIL_ERROR_PROGRAM_ERROR; + + case NEWSNNTP_ERROR_NO_PERMISSION: + return MAIL_ERROR_NO_PERMISSION; + + case NEWSNNTP_ERROR_COMMAND_NOT_UNDERSTOOD: + case NEWSNNTP_ERROR_COMMAND_NOT_SUPPORTED: + return MAIL_ERROR_COMMAND_NOT_SUPPORTED; + + case NEWSNNTP_ERROR_CONNECTION_REFUSED: + return MAIL_ERROR_CONNECT; + + case NEWSNNTP_ERROR_MEMORY: + return MAIL_ERROR_MEMORY; + + case NEWSNNTP_ERROR_AUTHENTICATION_REJECTED: + return MAIL_ERROR_LOGIN; + + case NEWSNNTP_ERROR_BAD_STATE: + return MAIL_ERROR_BAD_STATE; + + case NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_USERNAME: + case NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_PASSWORD: + default: + return MAIL_ERROR_INVAL; + } +} + +static inline struct nntp_session_state_data * +session_get_data(mailsession * session) +{ + return session->sess_data; +} + +static inline newsnntp * session_get_nntp_session(mailsession * session) +{ + return session_get_data(session)->nntp_session; +} + +static inline struct nntp_cached_session_state_data * +cached_session_get_data(mailsession * session) +{ + return session->sess_data; +} + +static inline mailsession * cached_session_get_ancestor(mailsession * session) +{ + return cached_session_get_data(session)->nntp_ancestor; +} + +static inline struct nntp_session_state_data * +cached_session_get_ancestor_data(mailsession * session) +{ + return session_get_data(cached_session_get_ancestor(session)); +} + +static inline newsnntp * cached_session_get_nntp_session(mailsession * session) +{ + return session_get_nntp_session(cached_session_get_ancestor(session)); +} + + +int nntpdriver_authenticate_password(mailsession * session) +{ + struct nntp_session_state_data * data; + int r; + + data = session_get_data(session); + + if (data->nntp_password == NULL) + return MAIL_ERROR_LOGIN; + + r = newsnntp_authinfo_password(session_get_nntp_session(session), + data->nntp_password); + + return nntpdriver_nntp_error_to_mail_error(r); +} + +int nntpdriver_mode_reader(mailsession * session) +{ + int done; + int r; + + done = FALSE; + + do { + r = newsnntp_mode_reader(session_get_nntp_session(session)); + + switch (r) { + case NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_USERNAME: + r = nntpdriver_authenticate_user(session); + if (r != MAIL_NO_ERROR) + return r; + break; + + case NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_PASSWORD: + r = nntpdriver_authenticate_password(session); + if (r != MAIL_NO_ERROR) + return r; + break; + + case NEWSNNTP_NO_ERROR: + done = TRUE; + break; + + default: + done = TRUE; + break; + } + } + while (!done); + + return MAIL_NO_ERROR; +} + +int nntpdriver_authenticate_user(mailsession * session) +{ + struct nntp_session_state_data * data; + int r; + + data = session_get_data(session); + + if (data->nntp_userid == NULL) + return MAIL_ERROR_LOGIN; + + r = newsnntp_authinfo_username(session_get_nntp_session(session), + data->nntp_userid); + + switch (r) { + case NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_PASSWORD: + return nntpdriver_authenticate_password(session); + + default: + return nntpdriver_nntp_error_to_mail_error(r); + } +} + +int nntpdriver_article(mailsession * session, uint32_t index, + char ** result, + size_t * result_len) +{ + char * msg_content; + size_t msg_length; + int r; + int done; + + done = FALSE; + do { + r = newsnntp_article(session_get_nntp_session(session), + index, &msg_content, &msg_length); + + switch (r) { + case NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_USERNAME: + r = nntpdriver_authenticate_user(session); + if (r != MAIL_NO_ERROR) + return r; + break; + + case NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_PASSWORD: + r = nntpdriver_authenticate_password(session); + if (r != MAIL_NO_ERROR) + return r; + break; + + case NEWSNNTP_NO_ERROR: + done = TRUE; + break; + + default: + return nntpdriver_nntp_error_to_mail_error(r); + } + } + while (!done); + + * result = msg_content; + * result_len = msg_length; + + return MAIL_NO_ERROR; +} + +int nntpdriver_head(mailsession * session, uint32_t index, + char ** result, + size_t * result_len) +{ + char * headers; + size_t headers_length; + int r; + int done; + + done = FALSE; + do { + r = newsnntp_head(session_get_nntp_session(session), + index, &headers, &headers_length); + + switch (r) { + case NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_USERNAME: + r = nntpdriver_authenticate_user(session); + if (r != MAIL_NO_ERROR) + return r; + break; + + case NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_PASSWORD: + r = nntpdriver_authenticate_password(session); + if (r != MAIL_NO_ERROR) + return r; + break; + + case NEWSNNTP_NO_ERROR: + done = TRUE; + break; + + default: + return nntpdriver_nntp_error_to_mail_error(r); + } + } + while (!done); + + * result = headers; + * result_len = headers_length; + + return MAIL_NO_ERROR; +} + +int nntpdriver_size(mailsession * session, uint32_t index, + size_t * result) +{ + newsnntp * nntp; + struct newsnntp_xover_resp_item * item; + int r; + int done; + + nntp = session_get_nntp_session(session); + + done = FALSE; + do { + r = newsnntp_xover_single(nntp, index, &item); + switch (r) { + case NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_USERNAME: + r = nntpdriver_authenticate_user(session); + if (r != MAIL_NO_ERROR) + return r; + break; + + case NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_PASSWORD: + r = nntpdriver_authenticate_password(session); + if (r != MAIL_NO_ERROR) + return r; + break; + + case NEWSNNTP_NO_ERROR: + done = TRUE; + break; + + default: + return nntpdriver_nntp_error_to_mail_error(r); + } + } + while (!done); + + * result = item->ovr_size; + + xover_resp_item_free(item); + + return MAIL_NO_ERROR; +} + +int +nntpdriver_get_cached_flags(struct mail_cache_db * cache_db, + MMAPString * mmapstr, + uint32_t num, + struct mail_flags ** result) +{ + int r; + char keyname[PATH_MAX]; + struct mail_flags * flags; + int res; + + snprintf(keyname, PATH_MAX, "%u-flags", num); + + r = generic_cache_flags_read(cache_db, mmapstr, keyname, &flags); + if (r != MAIL_NO_ERROR) { + res = r; + goto err; + } + + * result = flags; + + return MAIL_NO_ERROR; + + err: + return res; +} + +int +nntpdriver_write_cached_flags(struct mail_cache_db * cache_db, + MMAPString * mmapstr, + uint32_t num, + struct mail_flags * flags) +{ + int r; + char keyname[PATH_MAX]; + int res; + + snprintf(keyname, PATH_MAX, "%u-flags", num); + + r = generic_cache_flags_write(cache_db, mmapstr, keyname, flags); + if (r != MAIL_NO_ERROR) { + res = r; + goto err; + } + + return MAIL_NO_ERROR; + + err: + return res; +} + + + +int nntpdriver_select_folder(mailsession * session, char * mb) +{ + int r; + struct newsnntp_group_info * info; + newsnntp * nntp_session; + struct nntp_session_state_data * data; + char * new_name; + int done; + + data = session_get_data(session); + + if (!data->nntp_mode_reader) { + r = nntpdriver_mode_reader(session); + if (r != MAIL_NO_ERROR) + return r; + + data->nntp_mode_reader = TRUE; + } + + if (data->nntp_group_name != NULL) + if (strcmp(data->nntp_group_name, mb) == 0) + return MAIL_NO_ERROR; + + nntp_session = session_get_nntp_session(session); + + done = FALSE; + do { + r = newsnntp_group(nntp_session, mb, &info); + + switch (r) { + case NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_USERNAME: + r = nntpdriver_authenticate_user(session); + if (r != MAIL_NO_ERROR) + return r; + break; + + case NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_PASSWORD: + r = nntpdriver_authenticate_password(session); + if (r != MAIL_NO_ERROR) + return r; + break; + + case NEWSNNTP_NO_ERROR: + done = TRUE; + break; + + default: + return nntpdriver_nntp_error_to_mail_error(r); + } + + } + while (!done); + + new_name = strdup(mb); + if (new_name == NULL) + return MAIL_ERROR_MEMORY; + + if (data->nntp_group_name != NULL) + free(data->nntp_group_name); + data->nntp_group_name = new_name; + if (data->nntp_group_info != NULL) + newsnntp_group_free(data->nntp_group_info); + data->nntp_group_info = info; + + return MAIL_NO_ERROR; +} + + +int nntp_get_messages_list(mailsession * nntp_session, + mailsession * session, + mailmessage_driver * driver, + struct mailmessage_list ** result) +{ + carray * tab; + struct mailmessage_list * env_list; + uint32_t i; + int res; + int r; + struct nntp_session_state_data * data; + struct newsnntp_group_info * group_info; + uint32_t max; + unsigned int cur; + + data = session_get_data(nntp_session); + + if (data->nntp_group_name == NULL) { + res = MAIL_ERROR_BAD_STATE; + goto err; + } + + r = nntpdriver_select_folder(nntp_session, data->nntp_group_name); + if (r != MAIL_NO_ERROR) { + res = r; + goto err; + } + + group_info = data->nntp_group_info; + + if (group_info == NULL) { + res = MAIL_ERROR_BAD_STATE; + goto err; + } + + max = group_info->grp_first; + if (data->nntp_max_articles != 0) { + if (group_info->grp_last - data->nntp_max_articles + 1 > max) + max = group_info->grp_last - data->nntp_max_articles + 1; + } + + tab = carray_new(128); + if (tab == NULL) { + res = MAIL_ERROR_MEMORY; + goto err; + } + + for(i = max ; i <= group_info->grp_last ; i++) { + mailmessage * msg; + + msg = mailmessage_new(); + if (msg == NULL) { + res = MAIL_ERROR_MEMORY; + goto free_list; + } + + r = mailmessage_init(msg, session, driver, i, 0); + if (r != MAIL_NO_ERROR) { + mailmessage_free(msg); + res = r; + goto free_list; + } + + r = carray_add(tab, msg, NULL); + if (r < 0) { + mailmessage_free(msg); + res = MAIL_ERROR_MEMORY; + goto free_list; + } + } + + env_list = mailmessage_list_new(tab); + if (env_list == NULL) { + res = MAIL_ERROR_MEMORY; + goto free_list; + } + + * result = env_list; + + return MAIL_NO_ERROR; + + free_list: + for(cur = 0 ; cur < carray_count(tab) ; cur ++) + mailmessage_free(carray_get(tab, cur)); + carray_free(tab); + err: + return res; +} |