author | zautrix <zautrix> | 2005-03-18 20:17:03 (UTC) |
---|---|---|
committer | zautrix <zautrix> | 2005-03-18 20:17:03 (UTC) |
commit | 9e549686b23b6dffdcbd09c9b10dc2cb795fbcdf (patch) (side-by-side diff) | |
tree | 2528e6cc740225ca0f47d5ac8ff70f7d3bb10621 /libetpan/src/driver/implementation/db | |
parent | 9319998f20f03dcc217fbb39656755dc65226276 (diff) | |
download | kdepimpi-9e549686b23b6dffdcbd09c9b10dc2cb795fbcdf.zip kdepimpi-9e549686b23b6dffdcbd09c9b10dc2cb795fbcdf.tar.gz kdepimpi-9e549686b23b6dffdcbd09c9b10dc2cb795fbcdf.tar.bz2 |
Initial revision
Diffstat (limited to 'libetpan/src/driver/implementation/db') (more/less context) (ignore whitespace changes)
-rw-r--r-- | libetpan/src/driver/implementation/db/dbdriver.c | 1134 | ||||
-rw-r--r-- | libetpan/src/driver/implementation/db/dbdriver.h | 53 | ||||
-rw-r--r-- | libetpan/src/driver/implementation/db/dbdriver_message.c | 308 | ||||
-rw-r--r-- | libetpan/src/driver/implementation/db/dbdriver_message.h | 52 | ||||
-rw-r--r-- | libetpan/src/driver/implementation/db/dbdriver_types.h | 71 | ||||
-rw-r--r-- | libetpan/src/driver/implementation/db/dbstorage.c | 144 | ||||
-rw-r--r-- | libetpan/src/driver/implementation/db/dbstorage.h | 61 |
7 files changed, 1823 insertions, 0 deletions
diff --git a/libetpan/src/driver/implementation/db/dbdriver.c b/libetpan/src/driver/implementation/db/dbdriver.c new file mode 100644 index 0000000..e374e64 --- a/dev/null +++ b/libetpan/src/driver/implementation/db/dbdriver.c @@ -0,0 +1,1134 @@ +/* + * 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 "dbdriver.h" +#include "imfcache.h" +#include "generic_cache.h" +#include "libetpan-config.h" +#include "dbdriver_message.h" +#include "mail_cache_db.h" +#include <string.h> +#include <stdlib.h> +#include "mailmessage.h" + +static int initialize(mailsession * session); + +static void uninitialize(mailsession * session); + +static int connect_path(mailsession * session, char * path); + +static int logout(mailsession * session); + +static int expunge_folder(mailsession * session); + +static int status_folder(mailsession * session, char * mb, + uint32_t * result_messages, uint32_t * result_recent, + uint32_t * result_unseen); + +static int recent_number(mailsession * session, char * mb, + uint32_t * result); + +static int unseen_number(mailsession * session, char * mb, + uint32_t * result); + +static int messages_number(mailsession * session, char * mb, + uint32_t * result); + +static int append_message(mailsession * session, + char * message, size_t size); + +static int append_message_flags(mailsession * session, + char * message, size_t size, struct mail_flags * flags); + +static int get_messages_list(mailsession * session, + struct mailmessage_list ** result); + +static int get_envelopes_list(mailsession * session, + struct mailmessage_list * env_list); + +static int check_folder(mailsession * session); + +static int get_message(mailsession * session, + uint32_t num, mailmessage ** result); + +static int get_message_by_uid(mailsession * session, + const char * uid, mailmessage ** result); + +static mailsession_driver local_db_session_driver = { + .sess_name = "db", + + .sess_initialize = initialize, + .sess_uninitialize = uninitialize, + + .sess_parameters = NULL, + + .sess_connect_stream = NULL, + .sess_connect_path = connect_path, + .sess_starttls = NULL, + .sess_login = NULL, + .sess_logout = logout, + .sess_noop = NULL, + + .sess_build_folder_name = NULL, + .sess_create_folder = NULL, + .sess_delete_folder = NULL, + .sess_rename_folder = NULL, + .sess_check_folder = check_folder, + .sess_examine_folder = NULL, + .sess_select_folder = NULL, + .sess_expunge_folder = expunge_folder, + .sess_status_folder = status_folder, + .sess_messages_number = messages_number, + .sess_recent_number = recent_number, + .sess_unseen_number = unseen_number, + .sess_list_folders = NULL, + .sess_lsub_folders = NULL, + .sess_subscribe_folder = NULL, + .sess_unsubscribe_folder = NULL, + + .sess_append_message = append_message, + .sess_append_message_flags = append_message_flags, + .sess_copy_message = NULL, + .sess_move_message = NULL, + + .sess_get_messages_list = get_messages_list, + .sess_get_envelopes_list = get_envelopes_list, + .sess_remove_message = NULL, + + .sess_get_message = get_message, + .sess_get_message_by_uid = get_message_by_uid, +}; + +mailsession_driver * db_session_driver = &local_db_session_driver; + +static inline struct db_session_state_data * get_data(mailsession * session) +{ + return session->sess_data; +} + +static int flags_store_process(mailsession * session) +{ + unsigned int i; + MMAPString * mmapstr; + int r; + int res; + struct mail_cache_db * maildb; + struct db_session_state_data * data; + struct mail_flags_store * flags_store; + + data = get_data(session); + + flags_store = data->db_flags_store; + + if (carray_count(flags_store->fls_tab) == 0) + return MAIL_NO_ERROR; + + mmapstr = mmap_string_new(""); + if (mmapstr == NULL) { + res = MAIL_ERROR_MEMORY; + goto err; + } + + r = mail_cache_db_open_lock(data->db_filename, &maildb); + if (r < 0) { + res = MAIL_ERROR_FILE; + goto free_mmapstr; + } + + for(i = 0 ; i < carray_count(flags_store->fls_tab) ; i ++) { + mailmessage * msg; + char key[PATH_MAX]; + + msg = carray_get(flags_store->fls_tab, i); + + snprintf(key, sizeof(key), "%lu-flags", (unsigned long) msg->msg_index); + + r = generic_cache_flags_write(maildb, mmapstr, + key, msg->msg_flags); + } + + mail_flags_store_clear(flags_store); + + mail_cache_db_close_unlock(data->db_filename, maildb); + mmap_string_free(mmapstr); + + return MAIL_NO_ERROR; + + free_mmapstr: + mmap_string_free(mmapstr); + err: + return res; +} + +static int db_get_next_validity(struct mail_cache_db * maildb, + uint32_t * p_validity) +{ + int r; + char key_value[PATH_MAX]; + uint32_t validity; + void * serialized; + size_t serialized_len; + int res; + MMAPString * mmapstr; + size_t cur_token; + + mmapstr = mmap_string_new_len(serialized, serialized_len); + if (mmapstr == NULL) { + res = MAIL_ERROR_MEMORY; + goto err; + } + + snprintf(key_value, sizeof(key_value), "next-validity"); + + r = mail_cache_db_get(maildb, key_value, strlen(key_value), + &serialized, &serialized_len); + + if (r >= 0) { + size_t cur_token; + + cur_token = 0; + r = mailimf_cache_int_read(mmapstr, &cur_token, &validity); + if (r < 0) + validity = 0; + } + else { + validity = 0; + } + + mmap_string_set_size(mmapstr, 0); + cur_token = 0; + r = mailimf_cache_int_write(mmapstr, &cur_token, validity + 1); + if (r < 0) { + res = MAIL_ERROR_MEMORY; + goto free_mmapstr; + } + + r = mail_cache_db_put(maildb, key_value, strlen(key_value), + mmapstr->str, mmapstr->len); + if (r < 0) { + res = MAIL_ERROR_FILE; + goto free_mmapstr; + } + + mmap_string_free(mmapstr); + + * p_validity = validity; + + return MAIL_NO_ERROR; + + free_mmapstr: + mmap_string_free(mmapstr); + err: + return res; +} + +static int db_get_next_msg_number(struct mail_cache_db * maildb, + uint32_t * p_num) +{ + int r; + char key_value[PATH_MAX]; + uint32_t num; + void * serialized; + size_t serialized_len; + int res; + MMAPString * mmapstr; + size_t cur_token; + + mmapstr = mmap_string_new(""); + if (mmapstr == NULL) { + res = MAIL_ERROR_MEMORY; + goto err; + } + + snprintf(key_value, sizeof(key_value), "next-msg"); + + r = mail_cache_db_get(maildb, key_value, strlen(key_value), + &serialized, &serialized_len); + + if (r >= 0) { + size_t cur_token; + + if (mmap_string_append_len(mmapstr, serialized, serialized_len) == NULL) { + res = MAIL_ERROR_MEMORY; + goto err; + } + + cur_token = 0; + r = mailimf_cache_int_read(mmapstr, &cur_token, &num); + if (r < 0) + num = 1; + } + else { + num = 1; + } + + mmap_string_set_size(mmapstr, 0); + cur_token = 0; + r = mailimf_cache_int_write(mmapstr, &cur_token, num + 1); + if (r < 0) { + res = MAIL_ERROR_MEMORY; + goto free_mmapstr; + } + + r = mail_cache_db_put(maildb, key_value, strlen(key_value), + mmapstr->str, mmapstr->len); + if (r < 0) { + res = MAIL_ERROR_FILE; + goto free_mmapstr; + } + + mmap_string_free(mmapstr); + + * p_num = num; + + return MAIL_NO_ERROR; + + free_mmapstr: + mmap_string_free(mmapstr); + err: + return res; +} + +static int db_set_message_list(struct mail_cache_db * maildb, + carray * msglist) +{ + MMAPString * mmapstr; + char key_value[PATH_MAX]; + int r; + unsigned int i; + size_t cur_token; + int res; + + mmapstr = mmap_string_new(""); + if (mmapstr == NULL) { + res = MAIL_ERROR_MEMORY; + goto err; + } + + cur_token = 0; + for(i = 0 ; i < carray_count(msglist) ; i ++) { + uint32_t * msg; + + msg = carray_get(msglist, i); + r = mailimf_cache_int_write(mmapstr, &cur_token, * msg); + if (r != MAIL_NO_ERROR) { + res = r; + goto free_mmapstr; + } + } + + snprintf(key_value, sizeof(key_value), "message-list"); + r = mail_cache_db_put(maildb, key_value, strlen(key_value), + mmapstr->str, mmapstr->len); + if (r < 0) { + res = MAIL_ERROR_FILE; + goto err; + } + + mmap_string_free(mmapstr); + + return MAIL_NO_ERROR; + + free_mmapstr: + mmap_string_free(mmapstr); + err: + return res; +} + +static int db_get_message_list(struct mail_cache_db * maildb, + carray ** p_msglist) +{ + carray * msglist; + void * serialized; + size_t serialized_len; + int r; + char key_value[PATH_MAX]; + int res; + unsigned int i; + + msglist = carray_new(16); + if (msglist == NULL) { + res = MAIL_ERROR_MEMORY; + goto err; + } + + snprintf(key_value, sizeof(key_value), "message-list"); + r = mail_cache_db_get(maildb, key_value, strlen(key_value), + &serialized, &serialized_len); + if (r >= 0) { + MMAPString * mmapstr; + size_t cur_token; + + /* collect message list */ + + mmapstr = mmap_string_new_len(serialized, serialized_len); + if (mmapstr == NULL) { + res = MAIL_ERROR_MEMORY; + goto free_msglist; + } + + cur_token = 0; + do { + uint32_t num; + uint32_t * msg; + + r = mailimf_cache_int_read(mmapstr, &cur_token, &num); + if (r != MAIL_NO_ERROR) + break; + + msg = malloc(sizeof(* msg)); + if (msg == NULL) { + res = MAIL_ERROR_MEMORY; + mmap_string_free(mmapstr); + goto free_msglist; + } + * msg = num; + + r = carray_add(msglist, msg, NULL); + if (r < 0) { + res = MAIL_ERROR_MEMORY; + free(msg); + mmap_string_free(mmapstr); + goto free_msglist; + } + } while (1); + + mmap_string_free(mmapstr); + } + + * p_msglist = msglist; + + return MAIL_NO_ERROR; + + free_msglist: + for(i = 0 ; i < carray_count(msglist) ; i ++) { + uint32_t * msg; + + msg = carray_get(msglist, i); + free(msg); + } + carray_free(msglist); + err: + return res; +} + +static int initialize(mailsession * session) +{ + struct db_session_state_data * data; + + data = malloc(sizeof(* data)); + if (data == NULL) + goto err; + + data->db_filename[0] = '\0'; + + data->db_flags_store = mail_flags_store_new(); + if (data->db_flags_store == NULL) + goto free; + + session->sess_data = data; + + return MAIL_NO_ERROR; + + free: + free(data); + err: + return MAIL_ERROR_MEMORY; +} + +static void uninitialize(mailsession * session) +{ + struct db_session_state_data * data; + + data = get_data(session); + + flags_store_process(session); + + mail_flags_store_free(data->db_flags_store); + + free(data); + + session->sess_data = NULL; +} + +static int connect_path(mailsession * session, char * path) +{ + struct db_session_state_data * data; + + data = get_data(session); + + strncpy(data->db_filename, path, sizeof(data->db_filename)); + + return MAIL_NO_ERROR; +} + +static int logout(mailsession * session) +{ + return MAIL_NO_ERROR; +} + +static int expunge_folder(mailsession * session) +{ + int r; + char key_value[PATH_MAX]; + struct mail_cache_db * maildb; + carray * msglist; + unsigned int i; + struct db_session_state_data * data; + int res; + chash * msg_table; + MMAPString * mmapstr; + + data = get_data(session); + + flags_store_process(session); + + r = mail_cache_db_open_lock(data->db_filename, &maildb); + if (r < 0) { + res = MAIL_ERROR_FILE; + goto err; + } + + r = db_get_message_list(maildb, &msglist); + if (r != MAIL_NO_ERROR) { + res = r; + goto close_db; + } + + msg_table = chash_new(CHASH_DEFAULTSIZE, CHASH_COPYKEY); + if (msg_table == NULL) { + res = MAIL_ERROR_MEMORY; + goto free_msglist; + } + + mmapstr = mmap_string_new(""); + if (mmapstr == NULL) { + res = MAIL_ERROR_MEMORY; + goto free_msgtable; + } + + i = 0; + while (i < carray_count(msglist)) { + uint32_t num; + uint32_t * msg; + chashdatum key; + chashdatum value; + struct mail_flags * flags; + int deleted; + + msg = carray_get(msglist, i); + num = * msg; + + deleted = 0; + snprintf(key_value, sizeof(key_value), "%lu-flags", + (unsigned long) num); + r = generic_cache_flags_read(maildb, mmapstr, key_value, &flags); + if (r == MAIL_NO_ERROR) { + if ((flags->fl_flags & MAIL_FLAG_DELETED) != 0) + deleted = 1; + } + + if (!deleted) { + snprintf(key_value, sizeof(key_value), "%lu", (unsigned long) num); + key.data = key_value; + key.len = strlen(key_value); + chash_set(msg_table, &key, &value, NULL); + + snprintf(key_value, sizeof(key_value), "%lu-envelope", + (unsigned long) num); + key.data = key_value; + key.len = strlen(key_value); + chash_set(msg_table, &key, &value, NULL); + + snprintf(key_value, sizeof(key_value), "%lu-flags", + (unsigned long) num); + key.data = key_value; + key.len = strlen(key_value); + chash_set(msg_table, &key, &value, NULL); + + i ++; + } + else { + free(msg); + carray_delete(msglist, i); + } + } + + mmap_string_free(mmapstr); + + r = mail_cache_db_clean_up(maildb, msg_table); + + chash_free(msg_table); + + r = db_set_message_list(maildb, msglist); + + for(i = 0 ; i < carray_count(msglist) ; i ++) { + uint32_t * msg; + + msg = carray_get(msglist, i); + free(msg); + } + carray_free(msglist); + + mail_cache_db_close_unlock(data->db_filename, maildb); + + return MAIL_NO_ERROR; + + free_msgtable: + chash_free(msg_table); + free_msglist: + for(i = 0 ; i < carray_count(msglist) ; i ++) { + uint32_t * msg; + + msg = carray_get(msglist, i); + free(msg); + } + close_db: + mail_cache_db_close_unlock(data->db_filename, maildb); + err: + return res; +} + +static int status_folder(mailsession * session, char * mb, + uint32_t * result_messages, uint32_t * result_recent, + uint32_t * result_unseen) +{ + struct mail_cache_db * maildb; + char key_value[PATH_MAX]; + MMAPString * mmapstr; + uint32_t messages; + uint32_t recent; + uint32_t unseen; + struct db_session_state_data * data; + int r; + int res; + carray * msglist; + unsigned int i; + + data = get_data(session); + + flags_store_process(session); + + r = mail_cache_db_open_lock(data->db_filename, &maildb); + if (r < 0) { + res = MAIL_ERROR_FILE; + goto err; + } + + r = db_get_message_list(maildb, &msglist); + if (r != MAIL_NO_ERROR) { + res = r; + goto close_db; + } + + mmapstr = mmap_string_new(""); + if (mmapstr == NULL) { + res = MAIL_ERROR_MEMORY; + goto free_list; + } + + messages = 0; + recent = 0; + unseen = 0; + for(i = 0 ; i < carray_count(msglist) ; i ++) { + uint32_t num; + uint32_t * msg; + int r; + struct mail_flags * flags; + + msg = carray_get(msglist, i); + num = * msg; + free(msg); + carray_set(msglist, i, NULL); + + messages ++; + + snprintf(key_value, sizeof(key_value), "%lu-flags", (unsigned long) num); + + r = generic_cache_flags_read(maildb, mmapstr, key_value, &flags); + if (r == MAIL_NO_ERROR) { + if ((flags->fl_flags & MAIL_FLAG_NEW) != 0) { + recent ++; + } + if ((flags->fl_flags & MAIL_FLAG_SEEN) == 0) { + unseen ++; + } + mail_flags_free(flags); + } + } + + mmap_string_free(mmapstr); + + carray_free(msglist); + + mail_cache_db_close_unlock(data->db_filename, maildb); + + * result_messages = messages; + * result_unseen = unseen; + * result_recent = recent; + + return MAIL_NO_ERROR; + + free_list: + for(i = 0 ; i < carray_count(msglist) ; i ++) { + uint32_t * msg; + + msg = carray_get(msglist, i); + if (msg != NULL) + free(msg); + } + carray_free(msglist); + close_db: + mail_cache_db_close_unlock(data->db_filename, maildb); + err: + return res; +} + +static int recent_number(mailsession * session, char * mb, + uint32_t * result) +{ + uint32_t dummy_messages; + uint32_t dummy_unseen; + + return status_folder(session, mb, + &dummy_messages, result, &dummy_unseen); +} + +static int unseen_number(mailsession * session, char * mb, + uint32_t * result) +{ + uint32_t dummy_messages; + uint32_t dummy_recent; + + return status_folder(session, mb, + &dummy_messages, &dummy_recent, result); +} + +static int messages_number(mailsession * session, char * mb, + uint32_t * result) +{ + uint32_t dummy_unseen; + uint32_t dummy_recent; + + return status_folder(session, mb, + result, &dummy_recent, &dummy_unseen); +} + +static int append_message(mailsession * session, + char * message, size_t size) +{ + return append_message_flags(session, message, size, NULL); +} + +static int append_message_flags(mailsession * session, + char * message, size_t size, struct mail_flags * flags) +{ + carray * msglist; + unsigned int i; + uint32_t * msg; + uint32_t num; + char key_value[PATH_MAX]; + MMAPString * mmapstr; + struct mail_cache_db * maildb; + struct db_session_state_data * data; + size_t cur_token; + struct mailimf_fields * fields; + int r; + int res; + + data = get_data(session); + + r = mail_cache_db_open_lock(data->db_filename, &maildb); + if (r < 0) { + res = MAIL_ERROR_FILE; + goto err; + } + + r = db_get_next_msg_number(maildb, &num); + if (r != MAIL_NO_ERROR) { + res = r; + goto err; + } + + r = db_get_message_list(maildb, &msglist); + if (r != MAIL_NO_ERROR) { + res = r; + goto close_db; + } + + msg = malloc(sizeof(* msg)); + if (msg == NULL) { + res = MAIL_ERROR_MEMORY; + goto free_msglist; + } + + * msg = num; + + r = carray_add(msglist, msg, NULL); + if (r < 0) { + res = MAIL_ERROR_MEMORY; + free(msg); + goto free_msglist; + } + + r = db_set_message_list(maildb, msglist); + if (r != MAIL_NO_ERROR) { + res = r; + goto free_msglist; + } + + /* free msglist */ + + for(i = 0 ; i < carray_count(msglist) ; i ++) { + uint32_t * msg; + + msg = carray_get(msglist, i); + free(msg); + } + carray_free(msglist); + + snprintf(key_value, sizeof(key_value), "%lu", (unsigned long) num); + + r = mail_cache_db_put(maildb, key_value, strlen(key_value), + message, size); + if (r < 0) { + res = MAIL_ERROR_FILE; + goto close_db; + } + + /* write envelope */ + + cur_token = 0; + r = mailimf_envelope_fields_parse(message, size, &cur_token, &fields); + if (r != MAILIMF_NO_ERROR) { + res = MAIL_ERROR_PARSE; + goto close_db; + } + + mmapstr = mmap_string_new(""); + if (mmapstr == NULL) { + res = MAIL_ERROR_MEMORY; + goto close_db; + } + + cur_token = 0; + r = mailimf_cache_fields_write(mmapstr, &cur_token, fields); + if (r != MAIL_NO_ERROR) { + res = r; + mmap_string_free(mmapstr); + goto close_db; + } + + snprintf(key_value, sizeof(key_value), "%lu-envelope", (unsigned long) num); + + r = mail_cache_db_put(maildb, key_value, strlen(key_value), + mmapstr->str, mmapstr->len); + + mmap_string_free(mmapstr); + + mailimf_fields_free(fields); + + /* write flags */ + + if (flags != NULL) { + snprintf(key_value, sizeof(key_value), "%lu-flags", (unsigned long) num); + + mmapstr = mmap_string_new(""); + if (mmapstr == NULL) { + res = MAIL_ERROR_MEMORY; + goto close_db; + } + + r = generic_cache_flags_write(maildb, mmapstr, + key_value, flags); + + mmap_string_free(mmapstr); + + if (r != MAIL_NO_ERROR) { + res = MAIL_ERROR_FILE; + goto close_db; + } + } + + mail_cache_db_close_unlock(data->db_filename, maildb); + + return MAIL_NO_ERROR; + + free_msglist: + for(i = 0 ; i < carray_count(msglist) ; i ++) { + uint32_t * msg; + + msg = carray_get(msglist, i); + free(msg); + } + carray_free(msglist); + close_db: + mail_cache_db_close_unlock(data->db_filename, maildb); + err: + return res; +} + +static int get_messages_list(mailsession * session, + struct mailmessage_list ** result) +{ + int r; + char key[PATH_MAX]; + struct mail_cache_db * maildb; + struct db_session_state_data * data; + int res; + carray * msglist; + unsigned int i; + carray * msgtab; + struct mailmessage_list * driver_msglist; + + data = get_data(session); + + r = mail_cache_db_open_lock(data->db_filename, &maildb); + if (r < 0) { + res = MAIL_ERROR_FILE; + goto err; + } + + r = db_get_message_list(maildb, &msglist); + if (r != MAIL_NO_ERROR) { + res = r; + goto close_db; + } + + msgtab = carray_new(16); + if (msgtab == NULL) { + res = MAIL_ERROR_MEMORY; + goto close_db; + } + + for(i = 0 ; i < carray_count(msglist) ; i ++) { + uint32_t msg_num; + uint32_t * pmsg_num; + mailmessage * msg; + size_t size; + + pmsg_num = carray_get(msglist, i); + msg_num = * pmsg_num; + free(pmsg_num); + carray_set(msglist, i, NULL); + + snprintf(key, sizeof(key), "%lu", (unsigned long) msg_num); + r = mail_cache_db_get_size(maildb, key, strlen(key), &size); + if (r < 0) { + continue; + } + + msg = mailmessage_new(); + if (msg == NULL) { + res = MAIL_ERROR_MEMORY; + goto free_list; + } + + r = mailmessage_init(msg, session, db_message_driver, + msg_num, size); + if (r != MAIL_NO_ERROR) { + mailmessage_free(msg); + res = r; + goto free_list; + } + + r = carray_add(msgtab, msg, NULL); + if (r < 0) { + mailmessage_free(msg); + res = MAIL_ERROR_MEMORY; + goto free_list; + } + } + carray_free(msglist); + + driver_msglist = mailmessage_list_new(msgtab); + if (driver_msglist == NULL) { + res = MAIL_ERROR_MEMORY; + goto free_list; + } + + mail_cache_db_close_unlock(data->db_filename, maildb); + + * result = driver_msglist; + + return MAIL_NO_ERROR; + + free_list: + for(i = 0 ; i < carray_count(msgtab) ; i ++) { + mailmessage * msg; + + msg = carray_get(msgtab, i); + mailmessage_free(msg); + } + carray_free(msgtab); + + for(i = 0 ; i < carray_count(msglist) ; i ++) { + uint32_t * msg; + + msg = carray_get(msglist, i); + if (msg != NULL) + free(msg); + } + carray_free(msglist); + close_db: + mail_cache_db_close_unlock(data->db_filename, maildb); + err: + return res; +} + +static int get_envelopes_list(mailsession * session, + struct mailmessage_list * env_list) +{ + unsigned int i; + char key[PATH_MAX]; + int r; + struct mail_cache_db * maildb; + int res; + struct db_session_state_data * data; + MMAPString * mmapstr; + + data = get_data(session); + + flags_store_process(session); + + r = mail_cache_db_open_lock(data->db_filename, &maildb); + if (r < 0) { + res = MAIL_ERROR_FILE; + goto err; + } + + mmapstr = mmap_string_new(""); + if (mmapstr == NULL) { + res = MAIL_ERROR_MEMORY; + goto close_db; + } + + 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) { + snprintf(key, sizeof(key), "%lu-envelope", + (unsigned long) msg->msg_index); + + r = generic_cache_fields_read(maildb, mmapstr, + key, &msg->msg_fields); + } + + if (msg->msg_flags == NULL) { + snprintf(key, sizeof(key), "%lu-flags", + (unsigned long) msg->msg_index); + + r = generic_cache_flags_read(maildb, mmapstr, + key, &msg->msg_flags); + } + } + + mmap_string_free(mmapstr); + + mail_cache_db_close_unlock(data->db_filename, maildb); + + return MAIL_NO_ERROR; + + close_db: + mail_cache_db_close_unlock(data->db_filename, maildb); + err: + return res; +} + +static int check_folder(mailsession * session) +{ + flags_store_process(session); + + return MAIL_NO_ERROR; +} + +static int get_message(mailsession * session, + uint32_t num, mailmessage ** result) +{ + mailmessage * msg; + int r; + size_t size; + char key[PATH_MAX]; + struct db_session_state_data * data; + struct mail_cache_db * maildb; + int res; + + data = get_data(session); + + r = mail_cache_db_open_lock(data->db_filename, &maildb); + if (r < 0) { + res = MAIL_ERROR_FILE; + goto err; + } + + msg = mailmessage_new(); + if (msg == NULL) { + res = MAIL_ERROR_MEMORY; + goto close_db; + } + + size = 0; + snprintf(key, sizeof(key), "%lu", (unsigned long) num); + r = mail_cache_db_get_size(maildb, key, strlen(key), &size); + /* ignore error */ + + r = mailmessage_init(msg, session, db_message_driver, + num, size); + if (r != MAIL_NO_ERROR) { + mailmessage_free(msg); + res = r; + goto close_db; + } + + mail_cache_db_close_unlock(data->db_filename, maildb); + + return MAIL_NO_ERROR; + + close_db: + mail_cache_db_close_unlock(data->db_filename, maildb); + err: + return res; +} + +static int get_message_by_uid(mailsession * session, + const char * uid, mailmessage ** result) +{ + uint32_t msg_num; + + msg_num = strtoul(uid, NULL, 10); + + return get_message(session, msg_num, result); +} diff --git a/libetpan/src/driver/implementation/db/dbdriver.h b/libetpan/src/driver/implementation/db/dbdriver.h new file mode 100644 index 0000000..1c2a96d --- a/dev/null +++ b/libetpan/src/driver/implementation/db/dbdriver.h @@ -0,0 +1,53 @@ +/* + * 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 DBDRIVER_H + +#define DBDRIVER_H + +#include <libetpan/dbdriver_message.h> +#include <libetpan/dbdriver_types.h> + +#ifdef __cplusplus +extern "C" { +#endif + +extern mailsession_driver * db_session_driver; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libetpan/src/driver/implementation/db/dbdriver_message.c b/libetpan/src/driver/implementation/db/dbdriver_message.c new file mode 100644 index 0000000..70e9dca --- a/dev/null +++ b/libetpan/src/driver/implementation/db/dbdriver_message.c @@ -0,0 +1,308 @@ +/* + * 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 "dbdriver_message.h" +#include "dbdriver.h" +#include "mail_cache_db.h" + +#include "mailmessage_tools.h" +#include "generic_cache.h" + +#include <unistd.h> +#include <sys/mman.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <string.h> +#include <stdlib.h> + +static int fetch_envelope(mailmessage * msg_info, + struct mailimf_fields ** result); + +static int get_flags(mailmessage * msg_info, + struct mail_flags ** result); + +static int prefetch(mailmessage * msg_info); + +static void prefetch_free(struct generic_message_t * msg); + +static int initialize(mailmessage * msg_info); + +static void check(mailmessage * msg_info); + +static mailmessage_driver local_db_message_driver = { + .msg_name = "db", + + .msg_initialize = initialize, + .msg_uninitialize = mailmessage_generic_uninitialize, + + .msg_flush = mailmessage_generic_flush, + .msg_check = check, + + .msg_fetch_result_free = mailmessage_generic_fetch_result_free, + + .msg_fetch = mailmessage_generic_fetch, + .msg_fetch_header = mailmessage_generic_fetch_header, + .msg_fetch_body = mailmessage_generic_fetch_header, + .msg_fetch_size = NULL, + .msg_get_bodystructure = mailmessage_generic_get_bodystructure, + .msg_fetch_section = mailmessage_generic_fetch_section, + .msg_fetch_section_header = mailmessage_generic_fetch_section_header, + .msg_fetch_section_mime = mailmessage_generic_fetch_section_mime, + .msg_fetch_section_body = mailmessage_generic_fetch_section_body, + .msg_fetch_envelope = fetch_envelope, + + .msg_get_flags = get_flags, +}; + +mailmessage_driver * db_message_driver = &local_db_message_driver; + +struct db_msg_data { + MMAPString * msg_content; +}; + +static inline struct db_session_state_data * +get_session_data(mailmessage * msg) +{ + return msg->msg_session->sess_data; +} + +static int prefetch(mailmessage * msg_info) +{ + struct generic_message_t * msg; + int res; + struct db_msg_data * data; + struct db_session_state_data * sess_data; + MMAPString * msg_content; + struct mail_cache_db * maildb; + int r; + char key[PATH_MAX]; + void * msg_data; + size_t msg_data_len; + + sess_data = get_session_data(msg_info); + + r = mail_cache_db_open_lock(sess_data->db_filename, &maildb); + if (r < 0) { + res = MAIL_ERROR_FILE; + goto err; + } + + snprintf(key, sizeof(key), "%lu", (unsigned long) msg_info->msg_index); + r = mail_cache_db_get(maildb, key, strlen(key), &msg_data, &msg_data_len); + if (r < 0) { + res = MAIL_ERROR_MSG_NOT_FOUND; + goto close_db; + } + + msg_content = mmap_string_new_len(msg_data, msg_data_len); + if (msg_content == NULL) { + res = MAIL_ERROR_MEMORY; + goto close_db; + } + + data = malloc(sizeof(* data)); + if (data == NULL) { + res = MAIL_ERROR_MEMORY; + goto free_mmapstr; + } + + data->msg_content = msg_content; + + msg = msg_info->msg_data; + + msg->msg_data = data; + msg->msg_message = msg_content->str; + msg->msg_length = msg_content->len; + + mail_cache_db_close_unlock(sess_data->db_filename, maildb); + + return MAIL_NO_ERROR; + + free_mmapstr: + mmap_string_free(msg_content); + close_db: + mail_cache_db_close_unlock(sess_data->db_filename, maildb); + err: + return res; +} + +static void prefetch_free(struct generic_message_t * msg) +{ + if (msg->msg_message != NULL) { + struct db_msg_data * data; + + data = msg->msg_data; + mmap_string_free(data->msg_content); + data->msg_content = NULL; + free(data); + msg->msg_message = NULL; + } +} + +static int initialize(mailmessage * msg_info) +{ + struct generic_message_t * msg; + int r; + char key[PATH_MAX]; + + snprintf(key, sizeof(key), "%lu", (unsigned long) msg_info->msg_index); + msg_info->msg_uid = strdup(key); + if (msg_info->msg_uid == NULL) + return MAIL_ERROR_MEMORY; + + r = mailmessage_generic_initialize(msg_info); + if (r != MAIL_NO_ERROR) + return r; + + msg = msg_info->msg_data; + msg->msg_prefetch = prefetch; + msg->msg_prefetch_free = prefetch_free; + + return MAIL_NO_ERROR; +} + +static void check(mailmessage * msg_info) +{ + int r; + + if (msg_info->msg_flags != NULL) { + r = mail_flags_store_set(get_session_data(msg_info)->db_flags_store, + msg_info); + /* ignore errors */ + } +} + +static int fetch_envelope(mailmessage * msg_info, + struct mailimf_fields ** result) +{ + char key[PATH_MAX]; + int r; + struct db_session_state_data * sess_data; + struct mail_cache_db * maildb; + int res; + struct mailimf_fields * fields; + MMAPString * mmapstr; + + sess_data = get_session_data(msg_info); + + r = mail_cache_db_open_lock(sess_data->db_filename, &maildb); + if (r < 0) { + res = MAIL_ERROR_FILE; + goto err; + } + + snprintf(key, sizeof(key), "%lu-envelope", + (unsigned long) msg_info->msg_index); + + mmapstr = mmap_string_new(""); + if (mmapstr == NULL) { + res = MAIL_ERROR_MEMORY; + goto close_db; + } + + r = generic_cache_fields_read(maildb, mmapstr, + key, &fields); + + mmap_string_free(mmapstr); + + if (r != MAIL_NO_ERROR) { + res = MAIL_ERROR_MSG_NOT_FOUND; + goto close_db; + } + + mail_cache_db_close_unlock(sess_data->db_filename, maildb); + + * result = fields; + + return MAIL_NO_ERROR; + + close_db: + mail_cache_db_close_unlock(sess_data->db_filename, maildb); + err: + return res; +} + +static int get_flags(mailmessage * msg_info, + struct mail_flags ** result) +{ + char key[PATH_MAX]; + int r; + struct db_session_state_data * sess_data; + struct mail_cache_db * maildb; + int res; + MMAPString * mmapstr; + + sess_data = get_session_data(msg_info); + + r = mail_cache_db_open_lock(sess_data->db_filename, &maildb); + if (r < 0) { + res = MAIL_ERROR_FILE; + goto err; + } + + snprintf(key, sizeof(key), "%lu-flags", (unsigned long) msg_info->msg_index); + + mmapstr = mmap_string_new(""); + if (mmapstr == NULL) { + res = MAIL_ERROR_MEMORY; + goto close_db; + } + + r = generic_cache_flags_read(maildb, mmapstr, + key, &msg_info->msg_flags); + + mmap_string_free(mmapstr); + + if (r != MAIL_NO_ERROR) { + msg_info->msg_flags = mail_flags_new_empty(); + if (msg_info->msg_flags == NULL) { + res = MAIL_ERROR_MEMORY; + goto close_db; + } + } + + mail_cache_db_close_unlock(sess_data->db_filename, maildb); + + * result = msg_info->msg_flags; + + return MAIL_NO_ERROR; + + close_db: + mail_cache_db_close_unlock(sess_data->db_filename, maildb); + err: + return res; +} + diff --git a/libetpan/src/driver/implementation/db/dbdriver_message.h b/libetpan/src/driver/implementation/db/dbdriver_message.h new file mode 100644 index 0000000..f634775 --- a/dev/null +++ b/libetpan/src/driver/implementation/db/dbdriver_message.h @@ -0,0 +1,52 @@ +/* + * libEtPan! -- a mail stuff library + * + * Copyright (C) 2001, 2005 - DINH Viet Hoa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the libEtPan! project nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * $Id$ + */ + +#ifndef DBDRIVER_MESSAGE_H + +#define DBDRIVER_MESSAGE_H + +#include <libetpan/dbdriver_types.h> + +#ifdef __cplusplus +extern "C" { +#endif + +extern mailmessage_driver * db_message_driver; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libetpan/src/driver/implementation/db/dbdriver_types.h b/libetpan/src/driver/implementation/db/dbdriver_types.h new file mode 100644 index 0000000..052e3db --- a/dev/null +++ b/libetpan/src/driver/implementation/db/dbdriver_types.h @@ -0,0 +1,71 @@ +/* + * 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 DBDRIVER_TYPES_H + +#define DBDRIVER_TYPES_H + +#include <libetpan/libetpan-config.h> + +#include <libetpan/maildriver_types.h> +#include <libetpan/generic_cache_types.h> +#include <libetpan/mailstorage_types.h> + +#ifdef __cplusplus +extern "C" { +#endif + +struct db_session_state_data { + char db_filename[PATH_MAX]; + struct mail_flags_store * db_flags_store; +}; + +/* db storage */ + +/* + db_mailstorage is the state data specific to the db storage. + + - pathname is the path of the db storage. +*/ + +struct db_mailstorage { + char * db_pathname; +}; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libetpan/src/driver/implementation/db/dbstorage.c b/libetpan/src/driver/implementation/db/dbstorage.c new file mode 100644 index 0000000..c4be63c --- a/dev/null +++ b/libetpan/src/driver/implementation/db/dbstorage.c @@ -0,0 +1,144 @@ +/* + * 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 "dbstorage.h" +#include "mailstorage.h" + +#include "mail.h" +#include "mailmessage.h" +#include "dbdriver.h" +#include "maildriver.h" + +#include <stdlib.h> +#include <string.h> + +/* db storage */ + +static int db_mailstorage_connect(struct mailstorage * storage); +static int +db_mailstorage_get_folder_session(struct mailstorage * storage, + char * pathname, mailsession ** result); +static void db_mailstorage_uninitialize(struct mailstorage * storage); + +static mailstorage_driver db_mailstorage_driver = { + .sto_name = "db", + .sto_connect = db_mailstorage_connect, + .sto_get_folder_session = db_mailstorage_get_folder_session, + .sto_uninitialize = db_mailstorage_uninitialize, +}; + +int db_mailstorage_init(struct mailstorage * storage, + char * db_pathname) +{ + struct db_mailstorage * db_storage; + + db_storage = malloc(sizeof(* db_storage)); + if (db_storage == NULL) + goto err; + + db_storage->db_pathname = strdup(db_pathname); + if (db_storage->db_pathname == NULL) + goto free; + + storage->sto_data = db_storage; + storage->sto_driver = &db_mailstorage_driver; + + return MAIL_NO_ERROR; + + free: + free(db_storage); + err: + return MAIL_ERROR_MEMORY; +} + +static void db_mailstorage_uninitialize(struct mailstorage * storage) +{ + struct db_mailstorage * db_storage; + + db_storage = storage->sto_data; + free(db_storage->db_pathname); + free(db_storage); + + storage->sto_data = NULL; +} + +static int db_mailstorage_connect(struct mailstorage * storage) +{ + struct db_mailstorage * db_storage; + mailsession_driver * driver; + int r; + int res; + mailsession * session; + + db_storage = storage->sto_data; + + driver = db_session_driver; + + session = mailsession_new(driver); + if (session == NULL) { + res = MAIL_ERROR_MEMORY; + goto err; + } + + r = mailsession_connect_path(session, db_storage->db_pathname); + switch (r) { + case MAIL_NO_ERROR_NON_AUTHENTICATED: + case MAIL_NO_ERROR_AUTHENTICATED: + case MAIL_NO_ERROR: + break; + default: + res = r; + goto free; + } + + storage->sto_session = session; + + return MAIL_NO_ERROR; + + free: + mailsession_free(session); + err: + return res; +} + +static int +db_mailstorage_get_folder_session(struct mailstorage * storage, + char * pathname, mailsession ** result) +{ + * result = storage->sto_session; + + return MAIL_NO_ERROR; +} + diff --git a/libetpan/src/driver/implementation/db/dbstorage.h b/libetpan/src/driver/implementation/db/dbstorage.h new file mode 100644 index 0000000..5fa9659 --- a/dev/null +++ b/libetpan/src/driver/implementation/db/dbstorage.h @@ -0,0 +1,61 @@ +/* + * 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 DBSTORAGE_H + +#define DBSTORAGE_H + +#include <libetpan/dbdriver_types.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* + db_mailstorage_init is the constructor for a DB storage. + + @param storage this is the storage to initialize. + + @param pathname is the directory that contains the mailbox. +*/ + +int db_mailstorage_init(struct mailstorage * storage, + char * db_pathname); + +#ifdef __cplusplus +} +#endif + +#endif |