diff options
author | Kibum Kim <kb0929.kim@samsung.com> | 2012-02-27 21:15:52 +0900 |
---|---|---|
committer | Kibum Kim <kb0929.kim@samsung.com> | 2012-02-27 21:15:52 +0900 |
commit | 4c73c3e1e4085d17f8f9cfe0ec4c41bc9e0cb826 (patch) | |
tree | f86bd5ef488a8497efc5022d4f614cd0bba133d4 /email-core | |
download | email-service-4c73c3e1e4085d17f8f9cfe0ec4c41bc9e0cb826.tar.gz email-service-4c73c3e1e4085d17f8f9cfe0ec4c41bc9e0cb826.tar.bz2 email-service-4c73c3e1e4085d17f8f9cfe0ec4c41bc9e0cb826.zip |
tizen beta release
Diffstat (limited to 'email-core')
37 files changed, 50379 insertions, 0 deletions
diff --git a/email-core/CMakeLists.txt b/email-core/CMakeLists.txt new file mode 100755 index 0000000..fb8dfe6 --- /dev/null +++ b/email-core/CMakeLists.txt @@ -0,0 +1,171 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +PROJECT(email-storage) + +SET(CMAKE_SKIP_BUILD_RPATH TRUE) + +IF("${CMAKE_BUILD_TYPE}" STREQUAL "") + SET(CMAKE_BUILD_TYPE "Debug") +ENDIF("${CMAKE_BUILD_TYPE}" STREQUAL "") + +MESSAGE("") +MESSAGE(">>> current directory: ${CMAKE_CURRENT_SOURCE_DIR}") +MESSAGE(">>> Build type: ${CMAKE_BUILD_TYPE}") + + +SET(VISIBILITY "-DEXPORT_API=\"__attribute__((visibility(\\\"default\\\")))\"") +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${VISIBILITY} -fvisibility=hidden") + +########################################################## +# Define STORAGE lib +########################################################## + +SET(STORAGE-LIB "email-storage") +SET(STORAGE-SRCS + ./em-storage/em-storage-noti.c + ./em-storage/em-storage.c + ${CMAKE_SOURCE_DIR}/emf-emn-storage/emf-emn-storage.c +) + +INCLUDE_DIRECTORIES( + ${CMAKE_ROOT_DIR}/include/common/include + ${CMAKE_ROOT_DIR}/include + ${CMAKE_SOURCE_DIR}/include + ${CMAKE_SOURCE_DIR}/em-storage/include +) + + +INCLUDE(FindPkgConfig) +pkg_check_modules(storage_pkgs REQUIRED drm-service glib-2.0 dlog db-util openssl vconf secure-storage dbus-1 contacts-service) + +set(EXTRA_CFLAGS "") +FOREACH(flag ${storage_pkgs_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) + +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") + +#message(">>> extra_cflags ${EXTRA_CFLAGS}") +#message(">>> result ${CMAKE_C_FLAGS}") + + +SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed") + +ADD_LIBRARY(${STORAGE-LIB} SHARED ${STORAGE-SRCS}) +TARGET_LINK_LIBRARIES(${STORAGE-LIB} ${storage_LDFLAGS} ${BASE-LIB} ss-client) +SET_TARGET_PROPERTIES(${STORAGE-LIB} PROPERTIES SOVERSION ${VERSION_MAJOR}) +SET_TARGET_PROPERTIES(${STORAGE-LIB} PROPERTIES VERSION ${VERSION}) + +#INSTALL(TARGETS ${STORAGE-LIB} LIBRARY DESTINATION lib) +INSTALL(TARGETS ${STORAGE-LIB} DESTINATION lib COMPONENT RuntimeLibraries) + + +########################################################## +# Define network lib +########################################################## + +SET(NETWORK-LIB "email-network") +SET(NETWORK-SRCS + ./em-network/em-network.c +) + +INCLUDE_DIRECTORIES( + ${CMAKE_SOURCE_DIR}/include/common/include + ${CMAKE_SOURCE_DIR}/include + ${CMAKE_SOURCE_DIR}/email-core/include + ${CMAKE_SOURCE_DIR}/email-core/em-storage/include +) + +INCLUDE(FindPkgConfig) +pkg_check_modules(network_pkgs REQUIRED glib-2.0 uw-imap-toolkit dbus-1 vconf dlog openssl) + +FOREACH(flag ${network_pkgs_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) + +#message(">> net extra raw: ${core_proxy_pkgs_CFLAGS}") + +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") + +SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed") + +ADD_LIBRARY(${NETWORK-LIB} SHARED ${NETWORK-SRCS}) +TARGET_LINK_LIBRARIES(${NETWORK-LIB} ${network_pkgs_LDFLAGS} ${BASE-LIB} ${STORAGE-LIB} dl) +SET_TARGET_PROPERTIES(${NETWORK-LIB} PROPERTIES SOVERSION ${VERSION_MAJOR}) +SET_TARGET_PROPERTIES(${NETWORK-LIB} PROPERTIES VERSION ${VERSION}) + +INSTALL(TARGETS ${NETWORK-LIB} DESTINATION lib COMPONENT RuntimeLibraries) + +########################################################## +# Define Core lib +########################################################## + +SET(CORE-LIB "email-core") +SET(CORE-SRCS + ${CMAKE_SOURCE_DIR}/email-core/em-core-event.c + ${CMAKE_SOURCE_DIR}/email-core/em-core-imap-mailbox.c + ${CMAKE_SOURCE_DIR}/email-core/em-core-mailbox.c + ${CMAKE_SOURCE_DIR}/email-core/em-core-mailbox-sync.c + ${CMAKE_SOURCE_DIR}/email-core/em-core-mesg.c + ${CMAKE_SOURCE_DIR}/email-core/em-core-mm-callbacks.c + ${CMAKE_SOURCE_DIR}/email-core/em-core-utils.c + ${CMAKE_SOURCE_DIR}/email-core/em-core-api.c + ${CMAKE_SOURCE_DIR}/email-core/em-core-smtp.c + ${CMAKE_SOURCE_DIR}/email-core/em-core-timer.c + ${CMAKE_SOURCE_DIR}/email-core/em-core-imap-idle.c + ${CMAKE_SOURCE_DIR}/email-core/em-core-global.c + ${CMAKE_SOURCE_DIR}/email-core/em-core-account.c + ${CMAKE_SOURCE_DIR}/email-core/em-core-mime.c + ${CMAKE_SOURCE_DIR}/email-core/em-core-sound.c +) + +INCLUDE_DIRECTORIES( + ${CMAKE_SOURCE_DIR}/include/common/include + ${CMAKE_SOURCE_DIR}/include/ + ${CMAKE_SOURCE_DIR}/email-core/em-storage/include + ${CMAKE_SOURCE_DIR}/email-core/include + ${CMAKE_SOURCE_DIR}/Common/include + ${CMAKE_SOURCE_DIR}/email-core/em-network/include +) + + +INCLUDE(FindPkgConfig) +pkg_check_modules(core_pkgs REQUIRED glib-2.0 drm-service dlog dbus-1 gthread-2.0 uw-imap-toolkit vconf contacts-service secure-storage openssl accounts-svc mm-player mm-session devman_haptic alarm-service notification libcurl libxml-2.0) + +set(EXTRA_CFLAGS "") +FOREACH(flag ${core_pkgs_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) + +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") + +#message(">> core extra raw: ${core_pkgs_CFLAGS}") +#message(">> core extra : ${EXTRA_CFLAGS}") +#message(">> core result: ${CMAKE_C_FLAGS}") + +ADD_DEFINITIONS("-DCREATEPROTO=unixproto") +ADD_DEFINITIONS("-DEMPTYPROTO=unixproto") +ADD_DEFINITIONS("-DMAILSPOOL=\"/var/spool/mail\"") +ADD_DEFINITIONS("-DANONYMOUSHOME=\"/var/spool/mail/anonymous\"") +ADD_DEFINITIONS("-DACTIVEFILE=\"/var/lib/news/active\"") +ADD_DEFINITIONS("-DNEWSSPOOL=\"/var/spool/news\"") +ADD_DEFINITIONS("-DRSHPATH=\"/usr/bin/rsh\"") +ADD_DEFINITIONS("-DMD5ENABLE=\"/etc/cram-md5.pwd\"") +ADD_DEFINITIONS("-DSSL_CERT_DIRECTORY=\"/opt/etc/ssl/certs\"") +ADD_DEFINITIONS("-DSSL_KEY_DIRECTORY=\"/opt/etc/ssl/certs\"") +ADD_DEFINITIONS("-DCHUNKSIZE=65536") +ADD_DEFINITIONS("-DLOCKPGM=\"\"") +ADD_DEFINITIONS("-DLOCKPGM1=\"/usr/libexec/mlock\"") +ADD_DEFINITIONS("-DLOCKPGM2=\"/usr/sbin/mlock\"") +ADD_DEFINITIONS("-DLOCKPGM3=\"/usr/etc/mlock\"") +SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed") + +ADD_LIBRARY(${CORE-LIB} SHARED ${CORE-SRCS}) + +TARGET_LINK_LIBRARIES(${CORE-LIB} ${core_pkgs_LDFLAGS} ${STORAGE-LIB} ${NETWORK-LIB}) + +SET_TARGET_PROPERTIES(${CORE-LIB} PROPERTIES SOVERSION ${VERSION_MAJOR}) +SET_TARGET_PROPERTIES(${CORE-LIB} PROPERTIES VERSION ${VERSION}) + +INSTALL(TARGETS ${CORE-LIB} DESTINATION lib COMPONENT RuntimeLibraries) + + diff --git a/email-core/em-core-account.c b/email-core/em-core-account.c new file mode 100755 index 0000000..cfb7ee3 --- /dev/null +++ b/email-core/em-core-account.c @@ -0,0 +1,1107 @@ +/* +* email-service +* +* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. +* +* Contact: Kyuho Jo <kyuho.jo@samsung.com>, Sunghyun Kwon <sh0701.kwon@samsung.com> +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + + +/****************************************************************************** + * File : em-core-account.c + * Desc : Account Management + * + * Auth : Kyuho Jo + * + * History : + * 2010.08.25 : created + *****************************************************************************/ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include <sys/types.h> +#include <vconf.h> + +#include "Msg_Convert.h" +#include "emf-types.h" +#include "emflib.h" +#include "emf-dbglog.h" +#include "em-storage.h" +#include "em-network.h" +#include "em-core-utils.h" +#include "em-core-event.h" +#include "em-core-global.h" +#include "em-core-account.h" +#include "em-core-mailbox.h" +#include "em-core-imap-mailbox.h" + +#ifdef __FEATURE_USING_MY_ACCOUNT__ +#include "account.h" +#endif /* FEATURE_USING_MY_ACCOUN */ + +char *g_default_mbox_alias[MAILBOX_COUNT] = +{ + EMF_INBOX_DISPLAY_NAME, + EMF_DRAFTBOX_DISPLAY_NAME, + EMF_OUTBOX_DISPLAY_NAME, + EMF_SENTBOX_DISPLAY_NAME, + EMF_TRASH_DISPLAY_NAME, + EMF_SPAMBOX_DISPLAY_NAME, +}; + +char *g_default_mbox_name[MAILBOX_COUNT] = +{ + EMF_INBOX_NAME, + EMF_DRAFTBOX_NAME, + EMF_OUTBOX_NAME, + EMF_SENTBOX_NAME, + EMF_TRASH_DISPLAY_NAME, + EMF_SPAMBOX_NAME, +}; + +emf_mailbox_type_e g_default_mbox_type[MAILBOX_COUNT] = +{ + EMF_MAILBOX_TYPE_INBOX, + EMF_MAILBOX_TYPE_DRAFT, + EMF_MAILBOX_TYPE_OUTBOX, + EMF_MAILBOX_TYPE_SENTBOX, + EMF_MAILBOX_TYPE_TRASH, + EMF_MAILBOX_TYPE_SPAMBOX, +}; + +EXPORT_API emf_account_t* em_core_get_account_reference(int account_id) +{ + EM_DEBUG_FUNC_BEGIN("account_id[%d]", account_id); + EM_PROFILE_BEGIN(profile_em_core_get_account_reference); + emf_account_list_t **p; + + if (account_id == NEW_ACCOUNT_ID) + return em_core_account_get_new_account_ref(); + + if (account_id > 0) { + p = &g_account_list; + while (*p) { + if ((*p)->account->account_id == account_id) + return ((*p)->account); + p = &(*p)->next; + } + + /* refresh and check once agai */ + if (em_core_refresh_account_reference() == true) { + p = &g_account_list; + while (*p) { + if ((*p)->account->account_id == account_id) + return ((*p)->account); + + p = &(*p)->next; + } + } + } + + EM_PROFILE_END(profile_em_core_get_account_reference); + EM_DEBUG_FUNC_END(); + return NULL; +} + + +EXPORT_API int em_core_account_validate_with_account_info(emf_account_t *account, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account[%p], err_code[%p], receiving_server_addr [%s]", account, err_code, account->receiving_server_addr); + + int ret = false; + int err = EMF_ERROR_NONE; + emf_session_t *session = NULL; + SENDSTREAM *stream = NULL; + MAILSTREAM *tmp_stream = NULL; + + if (!em_core_check_thread_status()) { + err = EMF_ERROR_CANCELLED; + goto FINISH_OFF; + } + + if (!em_core_check_network_status(&err)) { + EM_DEBUG_EXCEPTION("em_core_check_network_status failed [%d]", err); + goto FINISH_OFF; + } + EM_DEBUG_LOG("Network available"); + + if (!em_core_check_thread_status()) { + err = EMF_ERROR_CANCELLED; + goto FINISH_OFF; + } + + if (!em_core_get_empty_session(&session)) { + EM_DEBUG_EXCEPTION("em_core_get_empty_session failed..."); + err = EMF_ERROR_SESSION_NOT_FOUND; + goto FINISH_OFF; + } + +#ifdef _SMTP_ACCOUNT_VALIDATION_ + /* validate connection for smt */ + EM_DEBUG_LOG(" >>>>>>>>>> Validate connection for SMTP"); + + if (!em_core_check_thread_status()) { + err = EMF_ERROR_CANCELLED; + goto FINISH_OFF; + } + if (!em_core_mailbox_open_with_account_info(account, (char *)ENCODED_PATH_SMTP, (void **)&stream, &err) || !stream) { + EM_DEBUG_EXCEPTION("\t em_core_mailbox_open failed 1 - %d", err); + if (EMF_ERROR_AUTHENTICATE == err || EMF_ERROR_LOGIN_FAILURE == err) { /* wrong password or etc */ + EM_DEBUG_EXCEPTION("\t em_core_mailbox_open failed : Login or Authentication fail 1- %d", err); + goto FINISH_OFF; + } + + if (account->sending_security == 0x01) /* 0x01 == ss */ { + /* retry with tl */ + EM_DEBUG_LOG(" >>>>>>>>>> Retry with TLS"); + account->sending_security = 0x02; /* 0x02 == tl */ + if (!em_core_check_thread_status()) { + err = EMF_ERROR_CANCELLED; + goto FINISH_OFF; + } + + if (!em_core_mailbox_open_with_account_info(account, (char *)ENCODED_PATH_SMTP, (void **)&stream, &err) || !stream) { + EM_DEBUG_EXCEPTION("\t em_core_mailbox_open failed 2 - %d", err); + if (EMF_ERROR_AUTHENTICATE == err || EMF_ERROR_LOGIN_FAILURE == err) { /* wrong password or etc */ + EM_DEBUG_EXCEPTION("\t em_core_mailbox_open failed : Login or Authentication fail 2 - %d", err); + } + else if (EMF_ERROR_CONNECTION_FAILURE != err) { + err = EMF_ERROR_VALIDATE_ACCOUNT; + } + account->sending_security = 0x01; /* restore to the previous value */ + goto FINISH_OFF; + } + + if (!em_core_check_thread_status()) { + err = EMF_ERROR_CANCELLED; + goto FINISH_OFF; + } + + /* save sending_security = 0x02 (tls) to the d */ + if (!em_storage_update_account(account_id, (emf_mail_account_tbl_t *)account, true, &err)) { + EM_DEBUG_EXCEPTION("\t em_storage_update_account failed - %d", err); + account->sending_security = 0x01; /* restore to the previous value */ + err = EMF_ERROR_VALIDATE_ACCOUNT; + goto FINISH_OFF; + } + } + else { + if (EMF_ERROR_CONNECTION_FAILURE != err) + err = EMF_ERROR_VALIDATE_ACCOUNT; + goto FINISH_OFF; + } + } +#endif + + /* validate connection for pop3/ima */ + EM_DEBUG_LOG("Validate connection for POP3/IMAP4"); + if (EMF_ERROR_NONE == err) { + if (!em_core_check_thread_status()) { + err = EMF_ERROR_CANCELLED; + goto FINISH_OFF; + } + + if (!em_core_mailbox_open_with_account_info(account, NULL, (void **)&tmp_stream, &err) || !tmp_stream) + { + EM_DEBUG_EXCEPTION("em_core_mailbox_open failed - %d", err); + if (EMF_ERROR_AUTHENTICATE == err || EMF_ERROR_LOGIN_FAILURE == err) { /* wrong password or etc */ + EM_DEBUG_EXCEPTION("em_core_mailbox_open failed : Login or Authentication fail - %d", err); + } + else if (EMF_ERROR_CONNECTION_FAILURE != err) { + /* err = EMF_ERROR_VALIDATE_ACCOUNT */ + } + goto FINISH_OFF; + } + } + + if (!em_core_check_thread_status()) { + if (!em_core_account_delete(account->account_id, NULL)) + EM_DEBUG_EXCEPTION("emf_account_delete failed [%d]", account->account_id); + err = EMF_ERROR_CANCELLED; + goto FINISH_OFF; + } + + ret = true; + err = EMF_SUCCESS_VALIDATE_ACCOUNT; + +FINISH_OFF: + if (stream) + smtp_close(stream); + + if (tmp_stream) + em_core_mailbox_close(0 , tmp_stream); + + if (err_code != NULL) + *err_code = err; + em_core_clear_session(session); + + EM_DEBUG_FUNC_END(); + + return ret; +} + + +EXPORT_API int em_core_account_validate(int account_id, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id[%d], err_code[%p]", account_id, err_code); + + int err = EMF_ERROR_NONE, ret = false; + emf_account_t *ref_account = NULL; + + + if (account_id <= 0) + { + EM_DEBUG_EXCEPTION("account_id[%p]", account_id); + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + ref_account = em_core_get_account_reference(account_id); + + if (ref_account && em_core_account_validate_with_account_info(ref_account, &err) == false) { + EM_DEBUG_EXCEPTION("em_core_account_validate_with_account_info failed (%d)", err); + goto FINISH_OFF; + } + + ret = true; + +FINISH_OFF: + + if (err_code) + *err_code = err; + + EM_DEBUG_FUNC_END(); + + return ret; +} + +EXPORT_API int em_core_account_delete(int account_id, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id[%d], err_code[%p]", account_id, err_code); + + /* default variabl */ + int ret = false; + int err = EMF_ERROR_NONE; + + if (account_id < FIRST_ACCOUNT_ID) { + EM_DEBUG_EXCEPTION("account_id[%d]", account_id); + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } +#ifdef __LOCAL_ACTIVITY__ + /* Delete all local activities of previous account */ + emf_activity_tbl_t activity; + memset(&activity, 0x00, sizeof(emf_activity_tbl_t)); + activity.account_id = account_id; + + if (!em_core_activity_delete(&activity, &err)) { + EM_DEBUG_LOG("\t em_core_activity_delete failed - %d", err); + + goto FINISH_OFF; + } +#endif + +#ifdef __FEATURE_PARTIAL_BODY_DOWNLOAD__ + if (false == em_core_clear_partial_body_thd_event_que(&err)) + EM_DEBUG_EXCEPTION(" em_core_clear_partial_body_thd_event_que [%d]", err); + + if (false == em_storage_delete_full_pbd_activity_data(account_id, true, &err)) + EM_DEBUG_EXCEPTION("em_storage_delete_full_pbd_activity_data failed [%d]", err); + +#endif + +#ifdef __FEATURE_USING_MY_ACCOUNT__ + { + int error_code; + emf_account_t *account_to_be_deleted; + + account_to_be_deleted = em_core_get_account_reference(account_id); + if (account_to_be_deleted && account_to_be_deleted->receiving_server_type != EMF_SERVER_TYPE_ACTIVE_SYNC) { + EM_DEBUG_LOG("Calling account_svc_delete with my_account_id[%d]", account_to_be_deleted->my_account_id); + error_code = account_connect(); + EM_DEBUG_LOG("account_connect returns [%d]", error_code); + account_delete_from_db_by_id(account_to_be_deleted->my_account_id); + error_code = account_disconnect(); + EM_DEBUG_LOG("account_disconnect returns [%d]", error_code); + } + } +#endif + if (em_core_cancel_all_threads_of_an_account(account_id) < EMF_ERROR_NONE) { + EM_DEBUG_EXCEPTION("There are some remaining jobs. I couldn't stop them."); + err = EMF_ERROR_CANNOT_STOP_THREAD; + goto FINISH_OFF; + } + + emf_mailbox_t mbox; + + /* BEGIN TRANSACTION; */ + em_storage_begin_transaction(NULL, NULL, NULL); + + if (!em_storage_delete_account(account_id, false, &err)) { + EM_DEBUG_EXCEPTION("em_storage_delete_account failed - %d", err); + goto FINISH_OFF; + } + +#ifdef __FEATURE_KEEP_CONNECTION__ + /* em_core_reset_streams(); */ + em_core_remove_connection_info(account_id); +#endif + + mbox.account_id = account_id; + mbox.name = NULL; + + if (!em_core_mail_delete_all(&mbox, 0, &err)) { + EM_DEBUG_EXCEPTION("em_core_mail_delete_all failed - %d", err); + goto FINISH_OFF; + } + + /* delete all mailboxe */ + if (!em_storage_delete_mailbox(account_id, -1, NULL, false, &err)) { + EM_DEBUG_EXCEPTION("em_storage_delete_mailbox failed - %d", err); + goto FINISH_OFF; + } + + /* delete local imap sync mailbox from imap mailbox tabl */ + if (!em_storage_remove_downloaded_mail(account_id, NULL, NULL, false, &err)) { + EM_DEBUG_EXCEPTION("em_storage_remove_downloaded_mail failed - %d", err); + goto FINISH_OFF; + } + + em_core_check_unread_mail(); + em_core_delete_notification_by_account(account_id); + em_core_refresh_account_reference(); + + ret = true; + +FINISH_OFF: + if (ret == true) { /* COMMIT TRANSACTION; */ + if (em_storage_commit_transaction(NULL, NULL, NULL) == false) { + err = em_storage_get_emf_error_from_em_storage_error(EM_STORAGE_ERROR_DB_FAILURE); + ret = false; + } + if (!em_storage_notify_storage_event(NOTI_ACCOUNT_DELETE, account_id, 0, NULL, 0)) + EM_DEBUG_EXCEPTION(" em_storage_notify_storage_event[ NOTI_ACCOUNT_DELETE] : Notification Failed >>> "); + + } + else { /* ROLLBACK TRANSACTION; */ + if (em_storage_rollback_transaction(NULL, NULL, NULL) == false) + err = em_storage_get_emf_error_from_em_storage_error(EM_STORAGE_ERROR_DB_FAILURE); + if (!em_storage_notify_storage_event(NOTI_ACCOUNT_DELETE_FAIL, account_id, err, NULL, 0)) + EM_DEBUG_EXCEPTION(" em_storage_notify_storage_event[ NOTI_ACCOUNT_DELETE] : Notification Failed >>> "); + } + + if (err_code) + *err_code = err; + + EM_DEBUG_FUNC_END(); + + return ret; +} + +EXPORT_API int em_core_account_create(emf_account_t *account, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account[%p], err_code[%p]", account, err_code); + + int ret = false; + int err = EMF_ERROR_NONE; + int i, count = 0, is_preset_IMAP_account = false; + emf_mailbox_t local_mailbox = {0}; + emf_mail_account_tbl_t *temp_account_tbl = NULL; + + if (!account) { + EM_DEBUG_EXCEPTION("account[%p]", account); + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + if (!em_storage_get_account_count(&count, true, &err)) { + EM_DEBUG_EXCEPTION("em_storage_get_account_count failed - %d", err); + goto FINISH_OFF; + } + + + if (count >= EMF_ACCOUNT_MAX) { + EM_DEBUG_EXCEPTION("too many accounts..."); + err = EMF_ERROR_ACCOUNT_MAX_COUNT; + goto FINISH_OFF; + } + + account->account_id = 0; + + /* check for email address validation */ + EM_DEBUG_LOG("account->email_addr[%s]", account->email_addr); + if (account->email_addr) { + if (!em_core_verify_email_address(account->email_addr, true, &err)) { + err = EMF_ERROR_INVALID_ADDRESS; + EM_DEBUG_EXCEPTION("Invalid Email Address"); + goto FINISH_OFF; + } + } + +#ifdef __FEATURE_USING_MY_ACCOUNT__ + if (account->receiving_server_type != EMF_SERVER_TYPE_ACTIVE_SYNC) { + int account_svc_id = 0; + int error_code; + account_h account_handle = NULL; + + error_code = account_connect(); + error_code = account_create(&account_handle); + + if(error_code != ACCOUNT_ERROR_NONE) { + EM_DEBUG_EXCEPTION("account_create failed [%d]", error_code); + err = error_code; + goto FINISH_OFF; + } + + account_set_user_name(account_handle, account->user_name); + account_set_domain_name(account_handle, account->account_name); + account_set_email_address(account_handle, account->email_addr); + account_set_source(account_handle, "EMAIL"); + account_set_package_name(account_handle, "email-setting-efl"); + account_set_capability(account_handle , ACCOUNT_CAPABILITY_EMAIL, ACCOUNT_CAPABILITY_ENABLED); + if (account->logo_icon_path) + account_set_icon_path(account_handle, account->logo_icon_path); + error_code = account_insert_to_db(account_handle, &account_svc_id); + + if (error_code != ACCOUNT_ERROR_NONE) { + EM_DEBUG_EXCEPTION("account_insert_to_db failed [%d]", error_code); + err = error_code; + goto FINISH_OFF; + } + + account->my_account_id = account_svc_id; + + EM_DEBUG_LOG("account_insert_to_db succeed"); + + account_disconnect(); + } +#endif /* __FEATURE_USING_MY_ACCOUNT__ */ + + temp_account_tbl = em_core_malloc(sizeof(emf_mail_account_tbl_t)); + if (!temp_account_tbl) { + EM_DEBUG_EXCEPTION("allocation failed [%d]", err); + goto FINISH_OFF; + } + em_convert_account_to_account_tbl(account, temp_account_tbl); + + if (!em_storage_add_account(temp_account_tbl, true, &err)) { + EM_DEBUG_EXCEPTION("em_storage_add_account failed - %d", err); + goto FINISH_OFF; + } + account->account_id = temp_account_tbl->account_id; + is_preset_IMAP_account = ((account->receiving_server_type == EMF_SERVER_TYPE_IMAP4)) ? true : false;/* && (account->preset_account)) ? true : false */ + + EM_DEBUG_LOG("is_preset_IMAP_account : %d", is_preset_IMAP_account); + + if ((account->receiving_server_type != EMF_SERVER_TYPE_ACTIVE_SYNC) && (!is_preset_IMAP_account)) { + /* 1. create default local mailbox + * (Inbox, Draft, Outbox, Sentbox) */ + for (i = 0; i < MAILBOX_COUNT; i++) { + EM_DEBUG_LOG("g_default_mbox_name [%d/%d] is [%s]", i, MAILBOX_COUNT, g_default_mbox_name[i]); + local_mailbox.account_id = temp_account_tbl->account_id; + local_mailbox.name = g_default_mbox_name[i]; + local_mailbox.mailbox_type = g_default_mbox_type[i]; + if (local_mailbox.mailbox_type == EMF_MAILBOX_TYPE_INBOX) { + local_mailbox.local = EMF_MAILBOX_FROM_SERVER; + local_mailbox.synchronous = 1; + } + else { + local_mailbox.local = EMF_MAILBOX_FROM_LOCAL; + local_mailbox.synchronous = 0; + } + local_mailbox.alias = g_default_mbox_alias[i]; + em_core_mailbox_get_default_mail_slot_count(&local_mailbox.mail_slot_size, NULL); + + if (!em_core_mailbox_create(&local_mailbox, 0, &err)) { + EM_DEBUG_EXCEPTION("em_core_mailbox_create failed - %d", err); + goto FINISH_OFF; + } + + } + } + + + + ret = true; + +FINISH_OFF: + if (temp_account_tbl) + em_storage_free_account(&temp_account_tbl, 1, NULL); + + if (ret == false && account != NULL) { + if (!em_core_account_delete(account->account_id, NULL)) + EM_DEBUG_EXCEPTION("emf_account_delete Failed [%d]", account->account_id); + } + + if (err_code) + *err_code = err; + + EM_DEBUG_FUNC_END("Return value [%d]", ret); + return ret; +} + + +EXPORT_API int em_core_init_account_reference() +{ + EM_DEBUG_FUNC_BEGIN(); + + int ret = false; + int err = EMF_ERROR_NONE; + + emf_account_list_t *account_list = NULL; + emf_account_list_t **p = NULL; + emf_account_t *account = NULL; + emf_mail_account_tbl_t *account_tbl_array = NULL; + int count = 0; + int i = 0; + + if (!g_account_retrieved) { + count = 1000; + if (!em_storage_get_account_list(&count, &account_tbl_array, true, true, &err)) { + EM_DEBUG_EXCEPTION("em_storage_get_account_list failed - %d", err); + goto FINISH_OFF; + } + + for (p = &account_list, i = 0; i < count; i++) { + account = malloc(sizeof(emf_account_t)); + if (!account) { + EM_DEBUG_EXCEPTION("malloc failed..."); + err = EMF_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + em_convert_account_tbl_to_account(account_tbl_array + i, account); + + /* memcpy(account, accounts + i, sizeof(emf_account_t)) */ + /* memset(accounts + i, 0x00, sizeof(emf_account_t)) */ + + (*p) = malloc(sizeof(emf_account_list_t)); + if (!(*p)) { + EM_DEBUG_EXCEPTION("malloc failed..."); + err = EMF_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + memset((*p), 0x00, sizeof(emf_account_list_t)); + + (*p)->account = account; + + p = &(*p)->next; + } + if (g_account_num) + em_core_free_account_reference(); + g_account_retrieved = 1; + g_account_num = count; + g_account_list = account_list; + } + + ret = true; + +FINISH_OFF: + if (account_tbl_array != NULL) + em_storage_free_account(&account_tbl_array, count, NULL); + + if (!ret) { + g_account_list = account_list; + em_core_free_account_reference(); + } + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API int em_core_refresh_account_reference() +{ + EM_DEBUG_FUNC_BEGIN(); + + if (g_account_retrieved && g_account_num) + em_core_free_account_reference(); + + g_account_retrieved = 0; + g_account_num = 0; + g_account_list = NULL; + + if (!em_core_init_account_reference()) { + EM_DEBUG_EXCEPTION("em_core_init_account_reference failed..."); + return false; + } + EM_DEBUG_FUNC_END(); + return true; +} + +EXPORT_API int em_core_free_account_reference() +{ + EM_DEBUG_FUNC_BEGIN(); + + emf_account_list_t *p = g_account_list, *p_next; + while (p) { + em_core_account_free(&p->account, 1, NULL); + + p_next = p->next; + free(p); + p = p_next; + } + + g_account_retrieved = 0; + g_account_num = 0; + g_account_list = NULL; + EM_DEBUG_FUNC_END(); + return true; +} + +EXPORT_API int em_core_account_free(emf_account_t **account_list, int count, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_list[%p], count[%d], err_code[%p]", account_list, count, err_code); + + /* default variabl */ + int ret = false; + int err = EMF_ERROR_NONE; + + if (count > 0) { + if (!account_list || !*account_list) { + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + emf_account_t *p = *account_list; + int i; + + for (i = 0; i < count; i++) { + EM_SAFE_FREE(p[i].account_name); + EM_SAFE_FREE(p[i].receiving_server_addr); + EM_SAFE_FREE(p[i].email_addr); + EM_SAFE_FREE(p[i].user_name); + EM_SAFE_FREE(p[i].password); + EM_SAFE_FREE(p[i].sending_server_addr); + EM_SAFE_FREE(p[i].sending_user); + EM_SAFE_FREE(p[i].sending_password); + EM_SAFE_FREE(p[i].display_name); + EM_SAFE_FREE(p[i].reply_to_addr); + EM_SAFE_FREE(p[i].return_addr); + EM_SAFE_FREE(p[i].logo_icon_path); + EM_SAFE_FREE(p[i].options.display_name_from); + EM_SAFE_FREE(p[i].options.signature); + } + + EM_SAFE_FREE(p); *account_list = NULL; + } + + ret = true; + +FINISH_OFF: + if (err_code) + *err_code = err; + EM_DEBUG_FUNC_END(); + return ret; +} + + +EXPORT_API int em_core_account_get_list_refer(emf_account_t **account_list, int *count, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_list[%p], count[%p], err_code[%p]", account_list, count, err_code); + int i, countOfAccounts = 0; + int ret = false; + int err = EMF_ERROR_NONE; + emf_account_t *accountRef; + emf_account_list_t *p; + + if (!account_list || !count) { + EM_DEBUG_EXCEPTION("account_list[%p], count[%p]", account_list, count); + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + p = g_account_list; + + while (p) { + countOfAccounts++; + p = p->next; + } + + EM_DEBUG_LOG("Result count[%d]", countOfAccounts); + *count = countOfAccounts; + + if (countOfAccounts > 0) { + *account_list = malloc(sizeof(emf_account_t) * countOfAccounts); + if (!*account_list) { + EM_DEBUG_LOG("malloc failed..."); + err = EMF_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + } + + p = g_account_list; + for (i = 0; i < countOfAccounts; i++) { + accountRef = (*account_list) + i; + memcpy(accountRef, p->account , sizeof(emf_account_t)); + p = p->next; + } + + for (i = 0; i < countOfAccounts; i++) { + accountRef = (*account_list) + i; + EM_DEBUG_LOG("Result account id[%d], name[%s]", accountRef->account_id, accountRef->account_name); + } + + ret = true; + +FINISH_OFF: + if (ret == false) { + if (account_list) /* Warn! this is not *account_list. Just account_list */ + EM_SAFE_FREE(*account_list); + } + + if (err_code != NULL) + *err_code = err; + EM_DEBUG_FUNC_END(); + return ret; +} + + +#ifdef __FEATURE_BACKUP_ACCOUNT__ +#include <ss_manager.h> + +static int append_data_into_buffer(char **target_buffer, int *target_buffer_lenth, char *input_data, int input_data_length, int *error_code) +{ + EM_DEBUG_FUNC_BEGIN("target_buffer [%p], target_buffer_lenth [%p], input_data [%p], input_data_length[%d]", target_buffer, target_buffer_lenth, input_data, input_data_length); + int local_error_code = EMF_ERROR_NONE, ret_code = false; + + if (!target_buffer || !target_buffer_lenth || !input_data) { + EM_DEBUG_EXCEPTION("EMF_ERROR_INVALID_PARAM"); + local_error_code = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + if (*target_buffer_lenth > 0 && input_data_length) { + EM_DEBUG_LOG("*target_buffer_lenth [%d]", *target_buffer_lenth); + *target_buffer = realloc(*target_buffer, (*target_buffer_lenth) + input_data_length); + if (!*target_buffer) { + EM_DEBUG_EXCEPTION("realloc failed"); + local_error_code = EMF_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + memcpy(*target_buffer + (*target_buffer_lenth), input_data, input_data_length); + *target_buffer_lenth += input_data_length; + EM_DEBUG_LOG("*target_buffer_lenth [%d] input_data_length [%d]", *target_buffer_lenth, input_data_length); + } + else { + EM_DEBUG_EXCEPTION("EMF_ERROR_INVALID_PARAM"); + local_error_code = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + ret_code = true; + +FINISH_OFF: + + if (error_code) + *error_code = local_error_code; + EM_DEBUG_FUNC_END("ret_code [%d]", ret_code); + + return ret_code; +} + + +static int em_core_write_account_into_buffer(char **target_buffer, int *target_buffer_lenth, emf_mail_account_tbl_t *account_tbl_ptr, int *error_code) +{ + EM_DEBUG_FUNC_BEGIN("target_buffer [%p], target_buffer_lenth [%p], account_tbl_ptr [%p], error_code [%p]", target_buffer, target_buffer_lenth, account_tbl_ptr, error_code); + int local_error_code = EMF_ERROR_NONE, ret_code = false, stream_length = 0; + emf_account_t *temp_account = NULL; + char *byte_stream = NULL; + + temp_account = em_core_malloc(sizeof(emf_account_t)); + memset(temp_account, 0, sizeof(emf_account_t)); + + if (em_convert_account_tbl_to_account(account_tbl_ptr, temp_account)) { + byte_stream = em_convert_account_to_byte_stream(temp_account, &stream_length); + EM_DEBUG_LOG("stream_length [%d]", stream_length); + /* EM_DEBUG_LOG("password [%s]", temp_account->password) */ + + if (byte_stream) { + if (!append_data_into_buffer(target_buffer, target_buffer_lenth, (char *)&stream_length, sizeof(int), &local_error_code)) { + EM_DEBUG_EXCEPTION("append_data_into_buffer failed"); + goto FINISH_OFF; + } + EM_DEBUG_LOG("append_data_into_buffer succeed for stream_length"); + + if (!append_data_into_buffer(target_buffer, target_buffer_lenth, byte_stream, stream_length, &local_error_code)) { + EM_DEBUG_EXCEPTION("append_data_into_buffer failed"); + goto FINISH_OFF; + } + EM_DEBUG_LOG("append_data_into_buffer succeed for byte_stream"); + } + } + else { + EM_DEBUG_EXCEPTION("em_convert_account_tbl_to_account failed"); + local_error_code = EM_STORAGE_ERROR_SYSTEM_FAILURE; + goto FINISH_OFF; + } + + ret_code = true; +FINISH_OFF: + if (temp_account) + em_core_account_free(&temp_account, 1, NULL); + if (error_code) + *error_code = local_error_code; + + EM_SAFE_FREE(byte_stream); + + EM_DEBUG_FUNC_END("ret_code [%d]", ret_code); + return ret_code; +} + +EXPORT_API int em_core_backup_accounts(const char *file_path, int *error_code) +{ + EM_DEBUG_FUNC_BEGIN("file_path [%s], error_code [%p]", file_path, error_code); + int local_error_code = EMF_ERROR_NONE, local_error_code_2 = EMF_ERROR_NONE, ret_code = false; + int select_num, i, target_buff_length = 0; + char *target_buffer = NULL; + emf_mail_account_tbl_t *account_list = NULL; + + if (!file_path) { + local_error_code = EMF_ERROR_INVALID_PARAM; + EM_DEBUG_EXCEPTION("EMF_ERROR_INVALID_PARAM"); + goto FINISH_OFF; + } + + select_num = 1000; + + if (!em_storage_get_account_list(&select_num, &account_list, true, true, &local_error_code)) { + EM_DEBUG_EXCEPTION("em_storage_get_account_list failed [%d]", local_error_code); + goto FINISH_OFF; + } + + EM_DEBUG_LOG("select_num [%d]", select_num); + + if (account_list) { + target_buffer = malloc(sizeof(int)); + if (!target_buffer) { + EM_DEBUG_EXCEPTION("malloc failed"); + local_error_code = EMF_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + memcpy(target_buffer, (char *)&select_num, sizeof(int)); + target_buff_length = sizeof(int); + + for (i = 0; i < select_num; i++) { + if (!em_core_write_account_into_buffer(&target_buffer, &target_buff_length, account_list + i, &local_error_code)) { + EM_DEBUG_EXCEPTION("em_core_write_account_into_buffer failed [%d]", local_error_code); + goto FINISH_OFF; + } + } + + EM_DEBUG_LOG("target_buff_length [%d]", target_buff_length); + + ssm_delete_file(file_path, SSM_FLAG_SECRET_OPERATION, NULL); + + if (ssm_write_buffer(target_buffer, target_buff_length, file_path, SSM_FLAG_SECRET_OPERATION, NULL) < 0) { + EM_DEBUG_EXCEPTION("ssm_write_buffer failed [%d]", local_error_code); + local_error_code = EM_STORAGE_ERROR_SYSTEM_FAILURE; + goto FINISH_OFF; + } + + } + + ret_code = true; +FINISH_OFF: + + EM_SAFE_FREE(target_buffer); + if (account_list) + em_storage_free_account(&account_list, select_num, &local_error_code_2); + + if (error_code) + *error_code = local_error_code; + + EM_DEBUG_FUNC_END("ret_code [%d]", ret_code); + return ret_code; +} + +EXPORT_API int em_core_restore_accounts(const char *file_path, int *error_code) +{ + EM_DEBUG_FUNC_BEGIN("file_path [%s], error_code [%p]", file_path, error_code); + int local_error_code = EMF_ERROR_NONE, ret_code = false, buffer_length = 0, read_length = 0; + int account_count = 0, i = 0, account_stream_length = 0; + char *temp_buffer = NULL, *account_stream = NULL, *buffer_ptr = NULL; + emf_account_t *temp_account = NULL, *account_list = NULL; + + ssm_file_info_t sfi; + + if (!file_path) { + local_error_code = EMF_ERROR_INVALID_PARAM; + EM_DEBUG_EXCEPTION("EMF_ERROR_INVALID_PARAM"); + goto FINISH_OFF; + } + + if (em_core_account_get_list_refer(&account_list, &account_count, &ret_code)) { + for (i = 0; i < account_count; i++) { + if (!em_core_account_delete(account_list[i].account_id, &ret_code)) { + local_error_code = EMF_ERROR_INVALID_ACCOUNT; + EM_DEBUG_EXCEPTION("em_core_account_delete failed"); + goto FINISH_OFF; + } + } + } + + if (ssm_getinfo(file_path, &sfi, SSM_FLAG_SECRET_OPERATION, NULL) < 0) { + EM_DEBUG_EXCEPTION("ssm_getinfo() failed."); + ret_code = EM_STORAGE_ERROR_SYSTEM_FAILURE; + goto FINISH_OFF; + } + + buffer_length = sfi.originSize; + EM_DEBUG_LOG("account buffer_length[%d]", buffer_length); + if ((temp_buffer = (char *)em_core_malloc(buffer_length + 1)) == NULL) { + EM_DEBUG_EXCEPTION("em_core_malloc failed..."); + ret_code = EM_STORAGE_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + if (ssm_read(file_path, temp_buffer, buffer_length, (size_t *)&read_length, SSM_FLAG_SECRET_OPERATION, NULL) < 0) { + EM_DEBUG_EXCEPTION("ssm_read() failed."); + ret_code = EM_STORAGE_ERROR_SYSTEM_FAILURE; + goto FINISH_OFF; + } + + EM_DEBUG_LOG("read_length[%d]", read_length); + + if (buffer_length == read_length) { + memcpy((void *)&account_count, temp_buffer, sizeof(int)); + buffer_ptr = temp_buffer + sizeof(int); + + EM_DEBUG_LOG("account_count[%d]", account_count); + + for (i = 0; i < account_count; i++) { + memcpy((void *)&account_stream_length, buffer_ptr, sizeof(int)); + buffer_ptr += sizeof(int); + EM_DEBUG_LOG("account_stream_length [%d]", account_stream_length); + if (account_stream_length) { + account_stream = em_core_malloc(account_stream_length); + if (!account_stream) { + EM_DEBUG_EXCEPTION("em_core_malloc() failed."); + ret_code = EMF_ERROR_OUT_OF_MEMORY ; + goto FINISH_OFF; + } + memcpy(account_stream, buffer_ptr, account_stream_length); + + temp_account = em_core_malloc(sizeof(emf_account_t)); + + if (!temp_account) { + EM_DEBUG_EXCEPTION("em_core_malloc() failed."); + ret_code = EMF_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + em_convert_byte_stream_to_account(account_stream, temp_account); + EM_SAFE_FREE(account_stream); + + if (!em_core_account_create(temp_account, &ret_code)) { + EM_DEBUG_EXCEPTION("em_core_account_create() failed."); + goto FINISH_OFF; + } + + em_core_account_free(&temp_account, 1, &ret_code); + temp_account = NULL; + } + buffer_ptr += account_stream_length; + account_stream_length = 0; + } + } else { + EM_DEBUG_EXCEPTION("ssm_read() failed."); + ret_code = EMF_ERROR_SYSTEM_FAILURE; + goto FINISH_OFF; + } + ret_code = true; +FINISH_OFF: + if (temp_account) + em_core_account_free(&temp_account, 1, NULL); + EM_SAFE_FREE(account_stream); + EM_SAFE_FREE(temp_buffer); + + EM_DEBUG_FUNC_END("ret_code [%d]", ret_code); + return ret_code; +} + +#endif /* __FEATURE_BACKUP_ACCOUNT_ */ + +EXPORT_API int em_core_query_server_info(const char* domain_name, emf_server_info_t **result_server_info) +{ + EM_DEBUG_FUNC_BEGIN("domain_name [%s], result_server_info [%p]", domain_name, result_server_info); + int ret_code = EMF_ERROR_NONE; + + + EM_DEBUG_FUNC_END("ret_code [%d]", ret_code); + return ret_code; +} + + +EXPORT_API int em_core_free_server_info(emf_server_info_t **target_server_info) +{ + EM_DEBUG_FUNC_BEGIN("result_server_info [%p]", target_server_info); + int i, ret_code = EMF_ERROR_NONE; + emf_server_info_t *server_info = NULL; + + if(target_server_info && *target_server_info) { + server_info = *target_server_info; + EM_SAFE_FREE(server_info->service_name); + for(i = 0; i < server_info->protocol_conf_count; i++) { + EM_SAFE_FREE(server_info->protocol_config_array[i].server_addr); + } + EM_SAFE_FREE(server_info->protocol_config_array); + EM_SAFE_FREE(server_info); + } + EM_DEBUG_FUNC_END("ret_code [%d]", ret_code); + return ret_code; +} + +EXPORT_API int em_core_save_default_account_id(int input_account_id) +{ + EM_DEBUG_FUNC_BEGIN("account_id [%d]", input_account_id); + int ret_code = EMF_ERROR_NONE, result_value = 0; + + result_value = vconf_set_int(VCONF_KEY_DEFAULT_ACCOUNT_ID, input_account_id); + if (result_value < 0) { + EM_DEBUG_EXCEPTION("vconf_set_int failed [%d]", result_value); + ret_code = EMF_ERROR_SYSTEM_FAILURE; + } + + EM_DEBUG_FUNC_END("ret_code [%d]", ret_code); + return ret_code; +} + +EXPORT_API int em_core_load_default_account_id(int *output_account_id) +{ + EM_DEBUG_FUNC_BEGIN("account_id [%p]", output_account_id); + int ret_code = EMF_ERROR_NONE, result_value = 0; + + if (output_account_id == NULL) { + ret_code = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + result_value = vconf_get_int(VCONF_KEY_DEFAULT_ACCOUNT_ID, output_account_id); + + if (result_value < 0) { + EM_DEBUG_EXCEPTION("vconf_get_int() failed [%d]", result_value); + ret_code = EMF_ERROR_SYSTEM_FAILURE; + *output_account_id = 0; + } + +FINISH_OFF: + + EM_DEBUG_FUNC_END("ret_code [%d]", ret_code); + return ret_code; +} diff --git a/email-core/em-core-api.c b/email-core/em-core-api.c new file mode 100755 index 0000000..4dfef10 --- /dev/null +++ b/email-core/em-core-api.c @@ -0,0 +1,239 @@ +/*
+* email-service
+*
+* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+*
+* Contact: Kyuho Jo <kyuho.jo@samsung.com>, Sunghyun Kwon <sh0701.kwon@samsung.com>
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+
+/******************************************************************************
+ * File : em-core-api.h
+ * Desc : Mail Engine API
+ *
+ * Auth :
+ *
+ * History :
+ * 2006.08.16 : created
+ *****************************************************************************/
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "c-client.h"
+#include "em-core-global.h"
+#include "em-network.h"
+#include "em-core-event.h"
+#include "em-core-mailbox.h"
+#include "em-core-utils.h"
+#include "emf-dbglog.h"
+
+extern void *
+pop3_parameters(long function, void *value);
+extern void *
+imap_parameters(long function, void *value);
+
+/*
+ * encoding base64
+ */
+int em_core_encode_base64(char *src, unsigned long src_len, char **enc, unsigned long* enc_len, int *err_code)
+{
+ EM_DEBUG_FUNC_BEGIN();
+
+ unsigned char *content;
+ int ret = true, err = EMF_ERROR_NONE;
+
+ if (err_code != NULL) {
+ *err_code = EMF_ERROR_NONE;
+ }
+
+ content = rfc822_binary(src, src_len, enc_len);
+
+ if (content)
+ *enc = (char *)content;
+ else {
+ err = EMF_ERROR_UNKNOWN;
+ ret = false;
+ }
+
+ if (err_code)
+ *err_code = err;
+
+ EM_DEBUG_FUNC_END();
+ return ret;
+}
+
+/*
+ * decoding quoted-printable
+ */
+int em_core_decode_quotedprintable(unsigned char *enc_text, unsigned long enc_len, char **dec_text, unsigned long* dec_len, int *err_code)
+{
+ unsigned char *text = enc_text;
+ unsigned long size = enc_len;
+ unsigned char *content;
+ int ret = true, err = EMF_ERROR_NONE;
+
+ if (err_code != NULL) {
+ *err_code = EMF_ERROR_NONE;
+ }
+
+ EM_DEBUG_FUNC_BEGIN();
+
+ content = rfc822_qprint(text, size, dec_len);
+
+ if (content)
+ *dec_text = (char *)content;
+ else
+ {
+ err = EMF_ERROR_UNKNOWN;
+ ret = false;
+ }
+
+ if (err_code)
+ *err_code = err;
+
+ return ret;
+}
+
+/*
+ * decoding base64
+ */
+int em_core_decode_base64(unsigned char *enc_text, unsigned long enc_len, char **dec_text, unsigned long* dec_len, int *err_code)
+{
+ unsigned char *text = enc_text;
+ unsigned long size = enc_len;
+ unsigned char *content;
+ int ret = true, err = EMF_ERROR_NONE;
+
+ if (err_code != NULL) {
+ *err_code = EMF_ERROR_NONE;
+ }
+
+ EM_DEBUG_FUNC_BEGIN();
+
+ content = rfc822_base64(text, size, dec_len);
+ if (content)
+ *dec_text = (char *)content;
+ else
+ {
+ err = EMF_ERROR_UNKNOWN;
+ ret = false;
+ }
+
+ if (err_code)
+ *err_code = err;
+
+ return ret;
+}
+
+/**
+ * em_core_get_logout_status - Get the logout status
+ **/
+EXPORT_API void
+em_core_get_logout_status(int *status)
+{
+ EM_DEBUG_FUNC_BEGIN();
+ int logout_status = 0;
+ *status = logout_status;
+ EM_DEBUG_LOG("em_core_get_logout_status is not implemented");
+ EM_DEBUG_FUNC_END("status [%d]", logout_status);
+}
+
+
+/**
+ * em_core_set_logout_status - Set the logout status
+ **/
+EXPORT_API void
+em_core_set_logout_status(int status)
+{
+ EM_DEBUG_FUNC_BEGIN();
+ EM_DEBUG_LOG("em_core_set_logout_status is not implemented");
+ EM_DEBUG_FUNC_END("status [%d] ", status);
+}
+
+#define EM_BATTERY_RECOVER_TEMP 6
+#define EM_BATTERY_ONLINE 1
+int _check_charger_status(int *charging_status, int *err_code)
+{
+ EM_DEBUG_FUNC_BEGIN("err_code[%p] ", err_code);
+
+ int ret = false;
+ int err = EMF_ERROR_NONE;
+ int ps_value = 0;
+
+ *charging_status = ps_value;
+
+ ret = true;
+
+ if (err_code != NULL)
+ *err_code = err;
+ EM_DEBUG_FUNC_END();
+ return ret;
+}
+
+EXPORT_API
+int em_low_battery_noti_init()
+{
+ EM_DEBUG_FUNC_BEGIN();
+ EM_DEBUG_LOG("Not implemented");
+ EM_DEBUG_FUNC_END();
+ return 0;
+}
+
+/* initialize mail core */
+EXPORT_API int em_core_init(int *err_code)
+{
+ EM_DEBUG_FUNC_BEGIN();
+
+ if (err_code != NULL) {
+ *err_code = EMF_ERROR_NONE;
+ }
+
+ mail_link(&imapdriver); /* link in the imap driver */
+ mail_link(&pop3driver); /* link in the pop3 driver */
+
+ mail_link(&unixdriver); /* link in the unix driver */
+ mail_link(&dummydriver); /* link in the dummy driver */
+
+ ssl_onceonlyinit();
+
+ auth_link(&auth_md5); /* link in the md5 authenticator */
+ auth_link(&auth_pla); /* link in the pla authenticator */
+ auth_link(&auth_log); /* link in the log authenticator */
+
+ /* Disabled to authenticate with plain text */
+ mail_parameters(NIL, SET_DISABLEPLAINTEXT, (void *) 2);
+
+ /* Set max trials for login */
+ imap_parameters(SET_MAXLOGINTRIALS, (void *)1);
+ pop3_parameters(SET_MAXLOGINTRIALS, (void *)1);
+ smtp_parameters(SET_MAXLOGINTRIALS, (void *)1);
+
+ mail_parameters(NIL, SET_SSLCERTIFICATEQUERY, (void *)em_core_ssl_cert_query_cb);
+ mail_parameters(NIL, SET_SSLCAPATH, (void *)SSL_CERT_DIRECTORY);
+
+ /* Set time out in second */
+ mail_parameters(NIL, SET_OPENTIMEOUT , (void *)50);
+ mail_parameters(NIL, SET_READTIMEOUT , (void *)180);
+ mail_parameters(NIL, SET_WRITETIMEOUT , (void *)180);
+ mail_parameters(NIL, SET_CLOSETIMEOUT , (void *)30);
+
+ if (err_code)
+ *err_code = EMF_ERROR_NONE;
+
+ return true;
+}
+
diff --git a/email-core/em-core-event.c b/email-core/em-core-event.c new file mode 100755 index 0000000..57f720d --- /dev/null +++ b/email-core/em-core-event.c @@ -0,0 +1,3701 @@ +/* +* email-service +* +* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. +* +* Contact: Kyuho Jo <kyuho.jo@samsung.com>, Sunghyun Kwon <sh0701.kwon@samsung.com> +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + + + +/****************************************************************************** + * File : em-core-event_data.h + * Desc : Mail Engine Event + * + * Auth : + * + * History : + * 2006.08.16 : created + *****************************************************************************/ +#include <stdio.h> +#include <glib.h> +#include <malloc.h> +#include <vconf.h> + +#include <signal.h> +#include <contacts-svc.h> +#include "Msg_Convert.h" +#include "c-client.h" +#include "em-storage.h" +#include "em-network.h" +#include "emf-auto-poll.h" +#include "em-core-global.h" +#include "em-core-account.h" +#include "em-core-event.h" +#include "em-core-utils.h" +#include "em-core-mailbox.h" +#include "em-core-imap-mailbox.h" +#include "em-core-mesg.h" +#include "em-core-mailbox-sync.h" +#include "em-core-smtp.h" +#include "em-core-utils.h" +#include "em-core-sound.h" +#include "emf-dbglog.h" + + +#ifdef __FEATURE_PARTIAL_BODY_DOWNLOAD__ + +/*[h.gahlaut] - All static variable declaration for partial body download thread are done here */ + +#define TOTAL_PARTIAL_BODY_EVENTS 100 + +static emf_event_partial_body_thd g_partial_body_thd_event_que[TOTAL_PARTIAL_BODY_EVENTS]; + +static int g_partial_body_thd_next_event_idx = 0; /* Index of Next Event to be processed in the queue*/ +static int g_partial_body_thd_loop = 1; /* Variable to make a continuos while loop */ +static int g_partial_body_thd_queue_empty = true; /* Variable to determine if event queue is empty.True means empty*/ +static int g_partial_body_thd_queue_full = false; /* Variable to determine if event queue is full. True means full*/ +static int g_pb_thd_local_activity_continue = true; /* Variable to control local activity sync */ +int g_pbd_thd_state = false; /* false : thread is sleeping , true : thread is working */ + +#ifdef __FEATURE_USE_PTHREAD__ +static pthread_mutex_t _partial_body_thd_event_queue_lock = PTHREAD_MUTEX_INITIALIZER; /* Mutex to protect event queue */ +static pthread_cond_t _partial_body_thd_cond = PTHREAD_COND_INITIALIZER; /* Condition variable on which partial body thread is waiting */ +thread_t g_partial_body_thd ; /* Determines if thread is created or not. Non Null means thread is created */ +#else /* __FEATURE_USE_PTHREAD__ */ +static GMutex *_partial_body_thd_event_queue_lock = NULL; /* Mutex to protect event queue */ +static GCond *_partial_body_thd_cond = NULL; /* Condition variable on which partial body thread is waiting */ +thread_t g_partial_body_thd = NULL; /* Determines if thread is created or not. Non Null means thread is created */ +#endif /* __FEATURE_USE_PTHREAD__ */ + +emf_event_partial_body_thd g_partial_body_bulk_dwd_que[BULK_PARTIAL_BODY_DOWNLOAD_COUNT]; +static int g_partial_body_bulk_dwd_next_event_idx = 0; /* Index of Next Event to be processed in the queue*/ +static int g_partial_body_bulk_dwd_queue_empty = true; + +#ifdef __FEATURE_USE_PTHREAD__ +static pthread_mutex_t _state_variables_lock; +#else /* __FEATURE_USE_PTHREAD__ */ +static GMutex *_state_variables_lock = NULL; /*Mutex for maintaining credibility of state variable */ +#endif /* __FEATURE_USE_PTHREAD__ */ + + +/*[h.gahlaut] - All static function declaration for partial body download thread are done here */ + +static int em_core_retrieve_partial_body_thread_event(emf_event_partial_body_thd *partial_body_thd_event, int *error_code); +static int em_core_copy_partial_body_thd_event(emf_event_partial_body_thd *src, emf_event_partial_body_thd *dest, int *error_code); +static void em_core_pb_thd_set_local_activity_continue(int flag); +static int em_core_set_pbd_thd_state(int flag); +static int em_core_clear_bulk_pbd_que(int *err_code); +int em_core_mail_partial_body_download(emf_event_partial_body_thd *pbd_event, int *error_code); + +#endif + +#ifdef ENABLE_IMAP_IDLE_THREAD +extern int g_imap_idle_thread_alive; +extern int imap_idle_thread; +#endif /* ENABLE_IMAP_IDLE_THREAD */ +EXPORT_API int g_client_count = 0; +EXPORT_API int g_client_run = 0 ; + +#ifdef __LOCAL_ACTIVITY__ +EXPORT_API int g_local_activity_run = 0; +EXPORT_API int g_save_local_activity_run = 0; +#endif + + +#define EVENT_QUEUE_MAX 32 + +typedef struct EVENT_CALLBACK_ELEM +{ + emf_event_callback callback; + void *event_data; + struct EVENT_CALLBACK_ELEM *next; +} EVENT_CALLBACK_LIST; + +#ifdef __FEATURE_USE_PTHREAD__ +static pthread_mutex_t _event_available_lock = PTHREAD_MUTEX_INITIALIZER; +static pthread_cond_t _event_available_signal = PTHREAD_COND_INITIALIZER; +static pthread_mutex_t *_event_queue_lock = NULL; +static pthread_mutex_t *_event_callback_table_lock = NULL; +#else /* __FEATURE_USE_PTHREAD__ */ +static GMutex *_event_available_lock = NULL; +static GCond *_event_available_signal = NULL; +static GStaticRecMutex _event_queue_lock; +static GStaticRecMutex _event_callback_table_lock; +#endif /* __FEATURE_USE_PTHREAD__ */ +static EVENT_CALLBACK_LIST *_event_callback_table[EMF_ACTION_NUM]; /* array of singly-linked list for event callbacks */ + +void *thread_func_branch_command(void *arg); + + +static emf_event_t g_event_que[EVENT_QUEUE_MAX]; + +int send_thread_run = 0; +int recv_thread_run = 0; + +#ifdef __FEATURE_USE_PTHREAD__ +static pthread_mutex_t _send_event_available_lock = PTHREAD_MUTEX_INITIALIZER; +static pthread_mutex_t *_send_event_queue_lock = NULL; /* MUST BE "recursive" */ +static pthread_cond_t _send_event_available_signal = PTHREAD_COND_INITIALIZER; +static thread_t g_send_srv_thread; +static thread_t g_srv_thread; +#else /* __FEATURE_USE_PTHREAD__ */ +static GMutex *_send_event_available_lock = NULL; +static GStaticRecMutex _send_event_queue_lock; /* MUST BE "recursive" */ +static GCond *_send_event_available_signal = NULL; +static thread_t g_send_srv_thread = NULL; +static thread_t g_srv_thread = NULL; +#endif /* __FEATURE_USE_PTHREAD__ */ + + +static emf_event_t g_send_event_que[EVENT_QUEUE_MAX]; +static int g_send_event_que_idx = 1; +static int g_send_event_loop = 1; +static int g_send_active_que = 0; +static int g_event_que_idx = 1; +static int g_event_loop = 1; +static int g_active_que = 0; +static int g_sending_busy_cnt = 0; +static int g_receiving_busy_cnt = 0; + + +EXPORT_API int em_core_get_current_thread_type() +{ + EM_DEBUG_FUNC_BEGIN(); + thread_t thread_id = THREAD_SELF(); + int thread_type = -1; + + if (thread_id == g_srv_thread) + thread_type = _SERVICE_THREAD_TYPE_RECEIVING; + else if (thread_id == g_send_srv_thread) + thread_type = _SERVICE_THREAD_TYPE_SENDING; +#ifdef __FEATURE_PARTIAL_BODY_DOWNLOAD__ + else if (thread_id == g_partial_body_thd) + thread_type = _SERVICE_THREAD_TYPE_PBD; +#endif + EM_DEBUG_FUNC_END("thread_type [%d]", thread_type); + return thread_type; +} + +static int is_gdk_lock_needed() +{ + if (g_event_loop) { + return (THREAD_SELF() == g_srv_thread); + } + return false; +} + +EXPORT_API int em_core_get_pending_event(emf_action_t action, int account_id, int mail_id, emf_event_status_type_t *status) +{ + EM_DEBUG_FUNC_BEGIN("action[%d], account_id[%d], mail_id[%d]", action, account_id, mail_id); + + int found = false; + int i; + + ENTER_RECURSIVE_CRITICAL_SECTION(_event_queue_lock); + + for (i = 1; i < EVENT_QUEUE_MAX; i++) { + switch (g_event_que[i].type) { + case EMF_EVENT_SEND_MAIL: + case EMF_EVENT_SEND_MAIL_SAVED: + if (action == EMF_ACTION_SEND_MAIL && account_id == g_event_que[i].account_id && mail_id == g_event_que[i].event_param_data_4) { + found = true; + goto EXIT; + } + break; + case EMF_EVENT_SAVE_MAIL: + if (action == EMF_ACTION_SAVE_MAIL && account_id == g_event_que[i].account_id && mail_id == g_event_que[i].event_param_data_4) { + found = true; + goto EXIT; + } + break; + + case EMF_EVENT_SYNC_HEADER: + if (action == EMF_ACTION_SYNC_HEADER && account_id == g_event_que[i].account_id) { + found = true; + goto EXIT; + } + break; + + case EMF_EVENT_SYNC_HEADER_OMA: + if (action == EMF_ACTION_SYNC_HEADER_OMA && account_id == g_event_que[i].account_id) { + found = true; + goto EXIT; + } + break; + + case EMF_EVENT_DOWNLOAD_BODY: + if (action == EMF_ACTION_DOWNLOAD_BODY && account_id == g_event_que[i].account_id && mail_id == g_event_que[i].event_param_data_4) { + found = true; + goto EXIT; + } + break; + case EMF_EVENT_SYNC_MAIL_FLAG_TO_SERVER: + if (action == EMF_ACTION_SYNC_MAIL_FLAG_TO_SERVER && account_id == g_event_que[i].account_id && mail_id == g_event_que[i].event_param_data_4) { + found = true; + goto EXIT; + } + break; + case EMF_EVENT_SYNC_FLAGS_FIELD_TO_SERVER: + if (action == EMF_ACTION_SYNC_FLAGS_FIELD_TO_SERVER && account_id == g_event_que[i].account_id && mail_id == g_event_que[i].event_param_data_4) { + found = true; + goto EXIT; + } + break; + case EMF_EVENT_DOWNLOAD_ATTACHMENT: + if (action == EMF_ACTION_DOWNLOAD_ATTACHMENT && account_id == g_event_que[i].account_id && mail_id == g_event_que[i].event_param_data_4) { + found = true; + goto EXIT; + } + break; + case EMF_EVENT_DELETE_MAIL: + case EMF_EVENT_DELETE_MAIL_ALL: + if (action == EMF_ACTION_DELETE_MAIL && account_id == g_event_que[i].account_id) { + found = true; + goto EXIT; + } + break; + + case EMF_EVENT_CREATE_MAILBOX: + if (action == EMF_ACTION_CREATE_MAILBOX && account_id == g_event_que[i].account_id) { + found = true; + goto EXIT; + } + break; + + case EMF_EVENT_DELETE_MAILBOX: + if (action == EMF_ACTION_DELETE_MAILBOX && account_id == g_event_que[i].account_id) { + found = true; + goto EXIT; + } + break; + + case EMF_EVENT_MOVE_MAIL: + if (action == EMF_ACTION_MOVE_MAIL && account_id == g_event_que[i].account_id && mail_id == g_event_que[i].event_param_data_4) { + found = true; + goto EXIT; + } + break; + + case EMF_EVENT_VALIDATE_ACCOUNT: + if (action == EMF_ACTION_VALIDATE_ACCOUNT && account_id == g_event_que[i].account_id) { + found = true; + goto EXIT; + } + break; + + case EMF_EVENT_VALIDATE_AND_UPDATE_ACCOUNT: + if (action == EMF_ACTION_VALIDATE_AND_UPDATE_ACCOUNT && account_id == 0) { + found = true; + goto EXIT; + } + break; + + case EMF_EVENT_VALIDATE_AND_CREATE_ACCOUNT: + if (action == EMF_ACTION_VALIDATE_AND_CREATE_ACCOUNT && account_id == 0) { + found = true; + goto EXIT; + } + break; + + case EMF_EVENT_UPDATE_MAIL_OLD: + case EMF_EVENT_UPDATE_MAIL: + if (action == EMF_ACTION_UPDATE_MAIL) { + found = true; + goto EXIT; + } + break; + + case EMF_EVENT_SET_MAIL_SLOT_SIZE: + if (action == EMF_ACTION_SET_MAIL_SLOT_SIZE) { + found = true; + goto EXIT; + } + break; + + default: + break; + } + } + +EXIT: + LEAVE_RECURSIVE_CRITICAL_SECTION(_event_queue_lock); + + if (found) { + if (status) + *status = g_event_que[i].status; + + return i; + } + + return FAILURE; +} + +EXPORT_API void em_core_get_event_queue_status(int *on_sending, int *on_receiving) +{ + if (on_sending != NULL) + *on_sending = g_sending_busy_cnt; + + if (on_receiving != NULL) + *on_receiving = g_receiving_busy_cnt; +} + +static void _sending_busy_ref(void) +{ + g_sending_busy_cnt++; +} + +static void _sending_busy_unref(void) +{ + g_sending_busy_cnt--; +} + +static void _receiving_busy_ref(void) +{ + g_receiving_busy_cnt++; +} + +static void _receiving_busy_unref(void) +{ + g_receiving_busy_cnt--; +} + +static void waiting_status_notify(emf_event_t *event_data, int queue_idx) +{ + EM_DEBUG_FUNC_BEGIN("event_data[%p], queue_idx[%d]", event_data, queue_idx); + + int account_id = event_data->account_id; + int mail_id = event_data->event_param_data_4; /* NOT ALWAYS */ + + switch (event_data->type) { + case EMF_EVENT_SEND_MAIL: + em_core_execute_event_callback(EMF_ACTION_SEND_MAIL, 0, 0, EMF_SEND_WAITING, account_id, mail_id, queue_idx, EMF_ERROR_NONE); + break; + + case EMF_EVENT_SYNC_HEADER: + em_core_execute_event_callback(EMF_ACTION_SYNC_HEADER, 0, 0, EMF_LIST_WAITING, account_id, 0, queue_idx, EMF_ERROR_NONE); + break; + + case EMF_EVENT_SYNC_HEADER_OMA: + em_core_execute_event_callback(EMF_ACTION_SYNC_HEADER_OMA, 0, 0, EMF_LIST_WAITING, account_id, 0, queue_idx, EMF_ERROR_NONE); + break; + + case EMF_EVENT_DOWNLOAD_BODY: + em_core_execute_event_callback(EMF_ACTION_DOWNLOAD_BODY, 0, 0, EMF_DOWNLOAD_WAITING, account_id, mail_id, queue_idx, EMF_ERROR_NONE); + break; + +#ifdef __FEATURE_SYNC_CLIENT_TO_SERVER__ + case EMF_EVENT_SYNC_MAIL_FLAG_TO_SERVER: + em_core_execute_event_callback(EMF_ACTION_SYNC_MAIL_FLAG_TO_SERVER, 0, 0, EMF_SYNC_WAITING, account_id, mail_id, queue_idx, EMF_ERROR_NONE); + break; +#endif + + case EMF_EVENT_DOWNLOAD_ATTACHMENT: + em_core_execute_event_callback(EMF_ACTION_DOWNLOAD_ATTACHMENT, 0, 0, EMF_DOWNLOAD_WAITING, account_id, mail_id, queue_idx, EMF_ERROR_NONE); + break; + + case EMF_EVENT_DELETE_MAIL: + case EMF_EVENT_DELETE_MAIL_ALL: + em_core_execute_event_callback(EMF_ACTION_DELETE_MAIL, 0, 0, EMF_DELETE_WAITING, account_id, 0, queue_idx, EMF_ERROR_NONE); + break; + + case EMF_EVENT_VALIDATE_ACCOUNT: + em_core_execute_event_callback(EMF_ACTION_VALIDATE_ACCOUNT, 0, 0, EMF_VALIDATE_ACCOUNT_WAITING, account_id, 0, queue_idx, EMF_ERROR_NONE); + break; + + case EMF_EVENT_VALIDATE_AND_CREATE_ACCOUNT: + em_core_execute_event_callback(EMF_ACTION_VALIDATE_AND_CREATE_ACCOUNT, 0, 0, EMF_VALIDATE_ACCOUNT_WAITING, account_id, 0, queue_idx, EMF_ERROR_NONE); + break; + + case EMF_EVENT_MOVE_MAIL: + em_core_execute_event_callback(EMF_ACTION_MOVE_MAIL, 0, 0, EMF_LIST_WAITING, account_id, 0, queue_idx, EMF_ERROR_NONE); + break; + + case EMF_EVENT_CREATE_MAILBOX: + em_core_execute_event_callback(EMF_ACTION_CREATE_MAILBOX, 0, 0, EMF_LIST_WAITING, account_id, 0, queue_idx, EMF_ERROR_NONE); + break; + + case EMF_EVENT_VALIDATE_AND_UPDATE_ACCOUNT: + em_core_execute_event_callback(EMF_ACTION_VALIDATE_AND_UPDATE_ACCOUNT, 0, 0, EMF_VALIDATE_ACCOUNT_WAITING, account_id, 0, queue_idx, EMF_ERROR_NONE); + break; + + case EMF_EVENT_UPDATE_MAIL_OLD: + case EMF_EVENT_UPDATE_MAIL: + break; + + case EMF_EVENT_SET_MAIL_SLOT_SIZE: + em_core_execute_event_callback(EMF_ACTION_SET_MAIL_SLOT_SIZE, 0, 0, EMF_SET_SLOT_SIZE_WAITING, account_id, 0, queue_idx, EMF_ERROR_NONE); + break; + default: + break; + } + EM_DEBUG_FUNC_END(); +} + +static void fail_status_notify(emf_event_t *event_data, int error) +{ + EM_DEBUG_FUNC_BEGIN(); + int account_id, mail_id; + + if(!event_data) { + EM_DEBUG_EXCEPTION("EMF_ERROR_INVALID_PARAM"); + return; + } + account_id = event_data->account_id; + mail_id = event_data->event_param_data_4; + + EM_DEBUG_LOG("account_id[%d], mail_id[%d], error[%d]", account_id, mail_id, error); + + switch (event_data->type) { + case EMF_EVENT_SEND_MAIL: + /* case EMF_EVENT_SEND_MAIL_SAVED: */ + /* em_core_execute_event_callback(EMF_ACTION_SEND_MAIL, 0, 0, EMF_SEND_FAIL, account_id, mail_id, -1, error); */ + em_core_show_popup(mail_id, EMF_ACTION_SEND_MAIL, error); + break; + + case EMF_EVENT_SYNC_HEADER: + em_core_execute_event_callback(EMF_ACTION_SYNC_HEADER, 0, 0, EMF_LIST_FAIL, account_id, 0, -1, error); + em_core_show_popup(account_id, EMF_ACTION_SYNC_HEADER, error); + break; + + case EMF_EVENT_DOWNLOAD_BODY: + em_core_execute_event_callback(EMF_ACTION_DOWNLOAD_BODY, 0, 0, EMF_DOWNLOAD_FAIL, account_id, mail_id, -1, error); + em_core_show_popup(account_id, EMF_ACTION_DOWNLOAD_BODY, error); + break; + + case EMF_EVENT_DOWNLOAD_ATTACHMENT: + em_core_execute_event_callback(EMF_ACTION_DOWNLOAD_ATTACHMENT, 0, 0, EMF_DOWNLOAD_FAIL, account_id, mail_id, -1, error); + em_core_show_popup(account_id, EMF_ACTION_DOWNLOAD_ATTACHMENT, error); + break; + + case EMF_EVENT_DELETE_MAIL: + case EMF_EVENT_DELETE_MAIL_ALL: + em_core_execute_event_callback(EMF_ACTION_DELETE_MAIL, 0, 0, EMF_DELETE_FAIL, account_id, 0, -1, error); + em_core_show_popup(account_id, EMF_ACTION_DELETE_MAIL, error); + break; + + case EMF_EVENT_VALIDATE_ACCOUNT: + em_core_execute_event_callback(EMF_ACTION_VALIDATE_ACCOUNT, 0, 0, EMF_VALIDATE_ACCOUNT_FAIL, account_id, 0, -1, error); + em_core_show_popup(account_id, EMF_ACTION_VALIDATE_ACCOUNT, error); + break; + + case EMF_EVENT_VALIDATE_AND_CREATE_ACCOUNT: + em_core_execute_event_callback(EMF_ACTION_VALIDATE_AND_CREATE_ACCOUNT, 0, 0, EMF_VALIDATE_ACCOUNT_FAIL, account_id, 0, -1, error); + em_core_show_popup(account_id, EMF_ACTION_VALIDATE_AND_CREATE_ACCOUNT, error); + break; + + case EMF_EVENT_CREATE_MAILBOX: + em_core_execute_event_callback(EMF_ACTION_CREATE_MAILBOX, 0, 0, EMF_LIST_FAIL, account_id, 0, -1, error); + em_core_show_popup(account_id, EMF_ACTION_CREATE_MAILBOX, error); + break; + case EMF_EVENT_DELETE_MAILBOX: + em_core_execute_event_callback(EMF_ACTION_DELETE_MAILBOX, 0, 0, EMF_LIST_FAIL, account_id, 0, -1, error); + em_core_show_popup(account_id, EMF_ACTION_DELETE_MAILBOX, error); + break; + + case EMF_EVENT_VALIDATE_AND_UPDATE_ACCOUNT: + em_core_execute_event_callback(EMF_ACTION_VALIDATE_AND_UPDATE_ACCOUNT, 0, 0, EMF_VALIDATE_ACCOUNT_FAIL, account_id, 0, -1, error); + em_core_show_popup(account_id, EMF_ACTION_VALIDATE_AND_UPDATE_ACCOUNT, error); + break; + + case EMF_EVENT_SET_MAIL_SLOT_SIZE: + em_core_execute_event_callback(EMF_ACTION_SET_MAIL_SLOT_SIZE, 0, 0, EMF_SET_SLOT_SIZE_FAIL, account_id, 0, -1, EMF_ERROR_NONE); + break; + + case EMF_EVENT_UPDATE_MAIL_OLD: + case EMF_EVENT_UPDATE_MAIL: + break; + + default: + break; + } + EM_DEBUG_FUNC_END(); +} + + +static void em_core_initialize_event_callback_table() +{ + ENTER_RECURSIVE_CRITICAL_SECTION(_event_callback_table_lock); + + int i; + + for (i = 0; i < EMF_ACTION_NUM; i++) + _event_callback_table[i] = NULL; + + LEAVE_RECURSIVE_CRITICAL_SECTION(_event_callback_table_lock); +} + +int em_core_register_event_callback(emf_action_t action, emf_event_callback callback, void *event_data) +{ + EM_DEBUG_FUNC_BEGIN("action[%d], callback[%p], event_data[%p]", action, callback, event_data); + + if (callback == NULL) + return false; + + int ret = false; + + ENTER_RECURSIVE_CRITICAL_SECTION(_event_callback_table_lock); + + EVENT_CALLBACK_LIST *node = _event_callback_table[action]; + + while (node != NULL) { + if (node->callback == callback && node->event_data == event_data) /* already registered */ + goto EXIT; + + node = node->next; + } + + /* not found, so keep going */ + + node = malloc(sizeof(EVENT_CALLBACK_LIST)); + + if (node == NULL) /* not enough memory */ + goto EXIT; + + node->callback = callback; + node->event_data = event_data; + node->next = _event_callback_table[action]; + + _event_callback_table[action] = node; + + ret = true; + +EXIT : + LEAVE_RECURSIVE_CRITICAL_SECTION(_event_callback_table_lock); + EM_DEBUG_FUNC_END(); + return ret; +} + +int em_core_unregister_event_callback(emf_action_t action, emf_event_callback callback) +{ + EM_DEBUG_FUNC_BEGIN("action[%d], callback[%p]", action, callback); + + if (callback == NULL) + return false; + + int ret = false; + + ENTER_RECURSIVE_CRITICAL_SECTION(_event_callback_table_lock); + + EVENT_CALLBACK_LIST *prev = NULL; + EVENT_CALLBACK_LIST *node = _event_callback_table[action]; + + while (node != NULL) { + if (node->callback == callback) { + if (prev != NULL) + prev->next = node->next; + else + _event_callback_table[action] = node->next; + + free(node); + + ret = true; + break; + } + + prev = node; + node = node->next; + } + + LEAVE_RECURSIVE_CRITICAL_SECTION(_event_callback_table_lock); + EM_DEBUG_FUNC_END(); + return ret; +} + +void em_core_execute_event_callback(emf_action_t action, int total, int done, int status, int account_id, int mail_id, int handle, int error) +{ + EM_DEBUG_FUNC_BEGIN("action[%d], total[%d], done[%d], status[%d], account_id[%d], mail_id[%d], handle[%d], error[%d]", action, total, done, status, account_id, mail_id, handle, error); + + int lock_needed = 0; + lock_needed = is_gdk_lock_needed(); + + if (lock_needed) { + /* Todo : g_thread_yield */ + } + + ENTER_RECURSIVE_CRITICAL_SECTION(_event_callback_table_lock); + + EVENT_CALLBACK_LIST *node = _event_callback_table[action]; + + while (node != NULL) { + if (node->callback != NULL) + node->callback(total, done, status, account_id, mail_id, (handle == -1 ? em_core_get_active_queue_idx() : handle), node->event_data, error); + node = node->next; + } + + LEAVE_RECURSIVE_CRITICAL_SECTION(_event_callback_table_lock); + + if (lock_needed) { + } + EM_DEBUG_FUNC_END(); +} + +/* insert a event to event queue */ +EXPORT_API int em_core_insert_event(emf_event_t *event_data, int *handle, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("event_data[%p], handle[%p], err_code[%p]", event_data, handle, err_code); + + if (!event_data) { + EM_DEBUG_EXCEPTION("Invalid Parameter"); + if (err_code != NULL) + *err_code = EMF_ERROR_INVALID_PARAM; + return false; + } + + if (!g_srv_thread) { + EM_DEBUG_EXCEPTION("email-service is not ready"); + if (err_code != NULL) + *err_code = EMF_ERROR_LOAD_ENGINE_FAILURE; + return false; + } + + int ret = true; + int error = EMF_ERROR_NONE; + + ENTER_RECURSIVE_CRITICAL_SECTION(_event_queue_lock); + + if (!g_event_que[g_event_que_idx].type) { /* if current buffer has not event, insert event data to current buffer */ + EM_DEBUG_LOG("Current buffer has not a event. [%d]", g_event_que_idx); + memcpy(g_event_que+g_event_que_idx, event_data, sizeof(emf_event_t)); + g_event_que[g_event_que_idx].status = EMF_EVENT_STATUS_WAIT; + waiting_status_notify(event_data, g_event_que_idx); + if (handle) + *handle = g_event_que_idx; + } + else { /* if current buffer has event, find the empty buffer */ + EM_DEBUG_LOG("Current buffer has a event. [%d]", g_event_que_idx); + int i, j = g_event_que_idx + 1; + + for (i = 1; i < EVENT_QUEUE_MAX; i++, j++) { + if (j >= EVENT_QUEUE_MAX) + j = 1; + + if (!g_event_que[j].type) + break; + } + + if (i < EVENT_QUEUE_MAX) { + EM_DEBUG_LOG("I found available buffer. [%d]", g_event_que + j); + memcpy(g_event_que+j, event_data, sizeof(emf_event_t)); + g_event_que[j].status = EMF_EVENT_STATUS_WAIT; + waiting_status_notify(event_data, j); + + if (handle) + *handle = j; + } + else { + EM_DEBUG_EXCEPTION("event que is full..."); + error = EMF_ERROR_EVENT_QUEUE_FULL; + ret = false; + } + } + + LEAVE_RECURSIVE_CRITICAL_SECTION(_event_queue_lock); + + if (ret == true) { + event_data->event_param_data_1 = NULL; /* MUST BE - to prevent double-free */ + + switch (event_data->type) { + case EMF_EVENT_SEND_MAIL: + case EMF_EVENT_SEND_MAIL_SAVED: + _sending_busy_ref(); + break; + + case EMF_EVENT_SYNC_HEADER: + case EMF_EVENT_SAVE_MAIL: + case EMF_EVENT_DOWNLOAD_BODY: + case EMF_EVENT_DOWNLOAD_ATTACHMENT: + case EMF_EVENT_SYNC_MAIL_FLAG_TO_SERVER: + case EMF_EVENT_SYNC_FLAGS_FIELD_TO_SERVER: + case EMF_EVENT_ISSUE_IDLE: + case EMF_EVENT_SYNC_IMAP_MAILBOX: + case EMF_EVENT_VALIDATE_ACCOUNT: + case EMF_EVENT_VALIDATE_AND_CREATE_ACCOUNT: + case EMF_EVENT_MOVE_MAIL: + case EMF_EVENT_DELETE_MAIL: + case EMF_EVENT_DELETE_MAIL_ALL: + case EMF_EVENT_SYNC_HEADER_OMA: + case EMF_EVENT_CREATE_MAILBOX: + case EMF_EVENT_DELETE_MAILBOX: + case EMF_EVENT_VALIDATE_AND_UPDATE_ACCOUNT: + case EMF_EVENT_SET_MAIL_SLOT_SIZE: + case EMF_EVENT_UPDATE_MAIL_OLD: + case EMF_EVENT_UPDATE_MAIL: + _receiving_busy_ref(); + break; + default: + break; + } + + ENTER_CRITICAL_SECTION(_event_available_lock); + WAKE_CONDITION_VARIABLE(_event_available_signal); + LEAVE_CRITICAL_SECTION(_event_available_lock); + } + +#ifdef __FEATURE_PARTIAL_BODY_DOWNLOAD__ + { + int is_local_activity_event_inserted = false; + + if (false == em_core_partial_body_thd_local_activity_sync(&is_local_activity_event_inserted, &error)) + EM_DEBUG_EXCEPTION("em_core_partial_body_thd_local_activity_sync failed [%d]", error); + else { + if (true == is_local_activity_event_inserted) + em_core_pb_thd_set_local_activity_continue(false); + } + } +#endif + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_LOG("Finish with [%d]", ret); + return ret; +} + +/* get a event from event_data queue */ +static int em_core_retrieve_event(emf_event_t *event_data, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("event_data[%p], err_code[%p]", event_data, err_code); + + int ret = false; + int error = EMF_ERROR_NONE; + + ENTER_RECURSIVE_CRITICAL_SECTION(_event_queue_lock); + + /* get a event_data if this queue is not empty */ + if (g_event_que[g_event_que_idx].type) { + memcpy(event_data, g_event_que+g_event_que_idx, sizeof(emf_event_t)); + + if (event_data->status != EMF_EVENT_STATUS_WAIT) { /* EMF_EVENT_STATUS_CANCELED */ + memset(g_event_que+g_event_que_idx, 0x00, sizeof(emf_event_t)); + g_active_que = 0; + } + else { + EM_DEBUG_LINE; + g_event_que[g_event_que_idx].status = EMF_EVENT_STATUS_STARTED; + g_active_que = g_event_que_idx; + ret = true; + } + + if (++g_event_que_idx >= EVENT_QUEUE_MAX) + g_event_que_idx = 1; + + EM_DEBUG_LOG("g_event_que[%d].type [%d]", g_active_que, g_event_que[g_active_que].type); + } + else { + g_active_que = 0; + error = EMF_ERROR_EVENT_QUEUE_EMPTY; + } + + LEAVE_RECURSIVE_CRITICAL_SECTION(_event_queue_lock); + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +/* check that event_data loop is continuous */ +static int em_core_event_loop_continue() +{ + return g_event_loop; +} + + + +EXPORT_API int em_core_insert_send_event(emf_event_t *event_data, int *handle, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("event_data[%p], handle[%p], err_code[%p]", event_data, handle, err_code); + + if (!event_data) { + EM_DEBUG_EXCEPTION("\t event_data[%p], handle[%p]", event_data, handle); + + if (err_code != NULL) + *err_code = EMF_ERROR_INVALID_PARAM; + return false; + } + + int ret = true; + int error = EMF_ERROR_NONE; + + ENTER_RECURSIVE_CRITICAL_SECTION(_send_event_queue_lock); + + if (!g_send_event_que[g_send_event_que_idx].type) { + /* if current buffer has not event_data, insert event_data data to current buffer */ + EM_DEBUG_LOG("Current buffer has not a event_data. [%d]", g_send_event_que_idx); + memcpy(g_send_event_que+g_send_event_que_idx, event_data, sizeof(emf_event_t)); + + g_send_event_que[g_send_event_que_idx].status = EMF_EVENT_STATUS_WAIT; + + if (handle) + *handle = g_send_event_que_idx; + } + else { + /* if current buffer has event_data, find the empty buffer */ + EM_DEBUG_LOG("Current buffer has a event_data. [%d]", g_send_event_que_idx); + int i, j = g_send_event_que_idx + 1; + + for (i = 1; i < EVENT_QUEUE_MAX; i++, j++) { + if (j >= EVENT_QUEUE_MAX) + j = 1; + + if (!g_send_event_que[j].type) + break; + } + + if (i < EVENT_QUEUE_MAX) { + EM_DEBUG_LOG("I found available buffer. [%d]", j); + memcpy(g_send_event_que+j, event_data, sizeof(emf_event_t)); + g_send_event_que[j].status = EMF_EVENT_STATUS_WAIT; + if (handle) *handle = j; + } + else { + EM_DEBUG_EXCEPTION("event_data queue is full..."); + error = EMF_ERROR_EVENT_QUEUE_FULL; + ret = false; + } + } + + LEAVE_RECURSIVE_CRITICAL_SECTION(_send_event_queue_lock); + + if (ret == true) { + ENTER_CRITICAL_SECTION(_send_event_available_lock); + WAKE_CONDITION_VARIABLE(_send_event_available_signal); + LEAVE_CRITICAL_SECTION(_send_event_available_lock); + } + + if (handle) + EM_DEBUG_LOG("em_core_insert_send_event-handle[%d]", *handle); + + if (err_code != NULL) + *err_code = error; + + /* EM_DEBUG_FUNC_BEGIN(); */ + return ret; +} + + +static int em_core_retrieve_send_event(emf_event_t *event_data, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN(); + + int ret = false; + int error = EMF_ERROR_NONE; + + ENTER_RECURSIVE_CRITICAL_SECTION(_send_event_queue_lock); +/* get a event_data if this queue is not empty */ + if (g_send_event_que[g_send_event_que_idx].type) { + memcpy(event_data, g_send_event_que+g_send_event_que_idx, sizeof(emf_event_t)); + + if (event_data->status != EMF_EVENT_STATUS_WAIT) { + memset(g_send_event_que+g_send_event_que_idx, 0x00, sizeof(emf_event_t)); + g_send_active_que = 0; + } + else { + g_send_event_que[g_send_event_que_idx].status = EMF_EVENT_STATUS_STARTED; + EM_DEBUG_LOG("g_send_event_que_idx[%d]", g_send_event_que_idx); + g_send_active_que = g_send_event_que_idx; + + ret = true; + } + + if (++g_send_event_que_idx >= EVENT_QUEUE_MAX) + g_send_event_que_idx = 1; + + EM_DEBUG_LOG("\t g_send_event_que[%d].type = %d", g_send_active_que, g_send_event_que[g_send_active_que].type); + } + else { + EM_DEBUG_LOG("\t send event_data queue is empty..."); + g_send_active_que = 0; + error = EMF_ERROR_EVENT_QUEUE_EMPTY; + } + + LEAVE_RECURSIVE_CRITICAL_SECTION(_send_event_queue_lock); + + if (err_code != NULL) + *err_code = error; + + return ret; +} + + +void* +send_event_handler(void *arg) +{ + EM_DEBUG_FUNC_BEGIN(); + int err = EMF_ERROR_NONE; + emf_event_t event_data; + emf_session_t *session = NULL; + + if (!em_storage_open(&err)) { + EM_DEBUG_EXCEPTION("\t em_storage_open falied - %d", err); + return NULL; + } + + while (g_send_event_loop) { + if (!em_core_get_empty_session(&session)) + EM_DEBUG_EXCEPTION("\t SEND THREAD em_core_get_empty_session failed..."); + + if (!em_core_retrieve_send_event(&event_data, NULL)) { + EM_DEBUG_LOG(">>>> waiting for send event_data>>>>>>>>>"); +#ifdef __LOCAL_ACTIVITY__ + if (send_thread_run && g_save_local_activity_run) { + emf_mail_account_tbl_t *account_list = NULL; + int count = 0, i; + if (!em_storage_get_account_list(&count, &account_list, true, true, &err)) { + EM_DEBUG_LOG("\t em_storage_get_account_list failed - %d", err); + } + else { + for (i = 0; i < count; i++) { + if (em_core_save_local_activity_sync(account_list[i].account_id, &err)) { + EM_DEBUG_LOG("Found local activity...!"); + EM_DEBUG_LOG("Resetting g_save_local_activity_run "); + g_save_local_activity_run = 0; + em_core_clear_session(session); + } + } + + em_storage_free_account(&account_list, count, &err); + + if (!g_save_local_activity_run) { + continue; + } + } + } +#endif + send_thread_run = 0; + + ENTER_CRITICAL_SECTION(_send_event_available_lock); + SLEEP_CONDITION_VARIABLE(_send_event_available_signal, _send_event_available_lock); + LEAVE_CRITICAL_SECTION(_send_event_available_lock); + } + else { + EM_DEBUG_LOG(">>>>>>>>>>>>>>Got SEND event_data>>>>>>>>>>>>>>>>"); + send_thread_run = 1; + g_client_run = 1; + emf_option_t *option = NULL; + + if (!em_core_check_network_status( &err)) { + EM_DEBUG_EXCEPTION("em_core_check_network_status failed [%d]", err); + + if (event_data.type != EMF_EVENT_SAVE_MAIL) { + em_core_show_popup(event_data.event_param_data_4, EMF_ACTION_SEND_MAIL, err); + if (!em_storage_notify_network_event(NOTI_SEND_FAIL, event_data.account_id, NULL , event_data.event_param_data_4, err)) + EM_DEBUG_EXCEPTION(" em_storage_notify_network_event [ NOTI_SEND_FAIL] Failed >>>> "); + } + goto FINISH_OFF; + } + + switch (event_data.type) { + + case EMF_EVENT_SAVE_MAIL: + em_storage_dimming_on_off(false, NULL); +#ifdef __FEATURE_SYNC_CLIENT_TO_SERVER__ + if (!em_core_mail_sync_from_client_to_server(event_data.account_id, event_data.event_param_data_4, &err)) + EM_DEBUG_EXCEPTION("em_core_mail_sync_from_client_to_server failed - %d", err); +#endif + em_storage_dimming_on_off(true, NULL); + break; + + case EMF_EVENT_SEND_MAIL: + em_storage_dimming_on_off(false, NULL); + option = (emf_option_t *)event_data.event_param_data_1; + + if (!em_core_mail_send(event_data.account_id, event_data.event_param_data_3, event_data.event_param_data_4, option, &err)) + EM_DEBUG_EXCEPTION("em_core_mail_send failed [%d]", err); + + if (option) + EM_SAFE_FREE(option->display_name_from); + em_storage_dimming_on_off(true, NULL); + break; + + case EMF_EVENT_SEND_MAIL_SAVED: /* send mails to been saved in offline-mode */ + em_storage_dimming_on_off(false, NULL); + + emf_option_t *option = (emf_option_t *)event_data.event_param_data_1; + + if (!em_core_mail_send_saved(event_data.account_id, event_data.event_param_data_3, option, &err)) + EM_DEBUG_EXCEPTION("em_core_mail_send_saved failed - %d", err); + + if (option) + EM_SAFE_FREE(option->display_name_from); + + em_storage_dimming_on_off(true, NULL); + break; +#ifdef __LOCAL_ACTIVITY__ + + case EMF_EVENT_LOCAL_ACTIVITY: { + em_storage_dimming_on_off(false, NULL); + emf_activity_tbl_t *local_activity = NULL; + int activity_id_count = 0; + int activity_chunk_count = 0; + int *activity_id_list = NULL; + int i = 0; + + if (false == em_storage_get_activity_id_list(event_data.account_id, &activity_id_list, &activity_id_count, ACTIVITY_SAVEMAIL, ACTIVITY_DELETEMAIL_SEND, true, &err)) { + EM_DEBUG_EXCEPTION("em_storage_get_activity_id_list failed [%d]", err); + } + else { + for (i = 0; i < activity_id_count; ++i) { + if ((false == em_storage_get_activity(event_data.account_id, activity_id_list[i], &local_activity, &activity_chunk_count, true, &err)) || (NULL == local_activity) || (0 == activity_chunk_count)) { + EM_DEBUG_EXCEPTION(" em_storage_get_activity Failed [ %d] or local_activity is NULL [%p] or activity_chunk_count is 0[%d]", err, local_activity, activity_chunk_count); + } + else { + EM_DEBUG_LOG("Found local activity type - %d", local_activity[0].activity_type); + switch (local_activity[0].activity_type) { + case ACTIVITY_SAVEMAIL: { + if (!em_core_mail_sync_from_client_to_server(event_data.account_id, local_activity[0].mail_id, &err)) { + EM_DEBUG_EXCEPTION("em_core_mail_sync_from_client_to_server failed - %d ", err); + } + } + break; + + case ACTIVITY_DELETEMAIL_SEND: /* New Activity Type Added for Race Condition and Crash Fix */ { + if (!em_core_mail_delete(local_activity[0].account_id, + &local_activity[0].mail_id, + EMF_DELETE_FOR_SEND_THREAD, + true, + EMF_DELETED_BY_COMMAND, + false, + &err)) { + EM_DEBUG_LOG("\t em_core_mail_delete failed - %d", err); + } + } + break; + + default: { + EM_DEBUG_LOG(">>>> No such Local Activity Handled by this thread [ %d ] >>> ", local_activity[0].activity_type); + } + break; + } + + em_storage_free_local_activity(&local_activity, activity_chunk_count, NULL); + + if (g_save_local_activity_run == 1) { + EM_DEBUG_LOG(" Network event_data found.. Local sync Stopped..! "); + break; + } + } + + } + if (false == em_storage_free_activity_id_list(activity_id_list, &err)) { + EM_DEBUG_LOG("em_storage_free_activity_id_list failed"); + } + } + + em_storage_dimming_on_off(true, NULL); + } + break; +#endif /* __LOCAL_ACTIVITY__ */ + default: + EM_DEBUG_LOG("Others not supported by Send Thread..! "); + break; + + } + + ENTER_RECURSIVE_CRITICAL_SECTION(_send_event_queue_lock); + + memset(g_send_event_que+g_send_active_que, 0x00, sizeof(emf_event_t)); + + LEAVE_RECURSIVE_CRITICAL_SECTION(_send_event_queue_lock); + +FINISH_OFF: + ; + } + em_core_clear_session(session); + } + + if (!em_storage_close(&err)) + EM_DEBUG_EXCEPTION("em_storage_close falied [%d]", err); + + EM_DEBUG_FUNC_END(); + return NULL; +} + + +int event_handler_EMF_EVENT_SYNC_HEADER(int input_account_id, char *input_mailbox_name, int handle_to_be_published, int *error) +{ + EM_DEBUG_FUNC_BEGIN("input_account_id [%d], input_mailbox_name [%p], handle_to_be_published [%d], error[%p]", input_account_id, input_mailbox_name, handle_to_be_published, error); + + int err = EMF_ERROR_NONE, sync_type = 0, ret = false; + int mailbox_count = 0, account_count = 0; + int counter, account_index; + int unread = 0, total_unread = 0; + em_core_uid_list *uid_list = NULL; + emf_mail_account_tbl_t *account_tbl_array = NULL; + emf_mailbox_tbl_t *mailbox_tbl_target = NULL, *mailbox_tbl_spam = NULL, *mailbox_tbl_list = NULL; +#ifndef __FEATURE_KEEP_CONNECTION__ + MAILSTREAM *stream = NULL; +#endif + + if (input_mailbox_name == NULL) + sync_type = EMF_SYNC_ALL_MAILBOX; + else { + if (!em_storage_get_mailbox_by_name(input_account_id, -1, input_mailbox_name, &mailbox_tbl_target, true, &err) || !mailbox_tbl_target) { + EM_DEBUG_EXCEPTION("em_storage_get_mailbox_by_name failed [%d]", err); + goto FINISH_OFF; + } + } + + if (!em_storage_notify_network_event(NOTI_DOWNLOAD_START, input_account_id, input_mailbox_name, handle_to_be_published, 0)) + EM_DEBUG_EXCEPTION(" em_storage_notify_network_event [ NOTI_DOWNLOAD_START] Failed >>>> "); + + if (!em_core_check_network_status(&err)) { + EM_DEBUG_EXCEPTION("em_core_check_network_status failed [%d]", err); + + if (!em_storage_notify_network_event(NOTI_DOWNLOAD_FAIL, input_account_id, input_mailbox_name, handle_to_be_published, err)) + EM_DEBUG_EXCEPTION(" em_storage_notify_network_event [ NOTI_DOWNLOAD_FAIL] Failed >>>> "); + } + else { + if (sync_type != EMF_SYNC_ALL_MAILBOX) { /* Sync only particular mailbox */ + + if (!em_storage_update_sync_status_of_account(input_account_id, SET_TYPE_SET, SYNC_STATUS_SYNCING, true, &err)) + EM_DEBUG_EXCEPTION("em_storage_update_sync_status_of_account failed [%d]", err); + + if (!em_storage_get_mailbox_by_mailbox_type(input_account_id, EMF_MAILBOX_TYPE_SPAMBOX, &mailbox_tbl_spam, false, &err)) { + err = em_storage_get_emf_error_from_em_storage_error(err); + EM_DEBUG_LOG("em_storage_get_mailbox_by_mailbox_type failed [%d]", err); + } + + if (!em_core_mailbox_sync_header(mailbox_tbl_target, mailbox_tbl_spam, NULL, &uid_list, &unread, &err)) { + EM_DEBUG_EXCEPTION("em_core_mailbox_sync_header failed [%d]", err); + if (!em_storage_notify_network_event(NOTI_DOWNLOAD_FAIL, mailbox_tbl_target->account_id, mailbox_tbl_target->mailbox_name, handle_to_be_published, err)) + EM_DEBUG_EXCEPTION(" em_storage_notify_network_event [NOTI_DOWNLOAD_FAIL] Failed >>>> "); + } + else { + EM_DEBUG_LOG("em_core_mailbox_sync_header succeeded [%d]", err); + if (!em_storage_notify_network_event(NOTI_DOWNLOAD_FINISH, mailbox_tbl_target->account_id, mailbox_tbl_target->mailbox_name, handle_to_be_published, 0)) + EM_DEBUG_EXCEPTION("em_storage_notify_network_event [NOTI_DOWNLOAD_FINISH] Failed >>>> "); + } + + total_unread = total_unread + unread; + + if (total_unread > 0 && !em_storage_update_sync_status_of_account(input_account_id, SET_TYPE_UNION, SYNC_STATUS_HAVE_NEW_MAILS, true, &err)) + EM_DEBUG_EXCEPTION("em_storage_update_sync_status_of_account failed [%d]", err); + + if (!em_core_finalize_sync(input_account_id, &err)) + EM_DEBUG_EXCEPTION("em_core_finalize_sync failed [%d]", err); + } + else /* All Foder */ { + EM_DEBUG_LOG(">>>> SYNC ALL MAILBOX "); + /* Sync of all mailbox */ + + if (input_account_id == ALL_ACCOUNT) { + if (!em_storage_update_sync_status_of_account(ALL_ACCOUNT, SET_TYPE_SET, SYNC_STATUS_SYNCING, true, &err)) + EM_DEBUG_EXCEPTION("em_storage_update_sync_status_of_account failed [%d]", err); + + if (!em_storage_get_account_list(&account_count, &account_tbl_array , true, false, &err)) { + EM_DEBUG_EXCEPTION("em_storage_get_account_list failed [ %d ] ", err); + em_storage_get_emf_error_from_em_storage_error(err); + if (!em_storage_notify_network_event(NOTI_DOWNLOAD_FAIL, input_account_id, NULL, handle_to_be_published, err)) + EM_DEBUG_EXCEPTION(" em_storage_notify_network_event [ NOTI_DOWNLOAD_FAIL] Failed >>>> "); + goto FINISH_OFF; + } + } + else { + EM_DEBUG_LOG("Sync all mailbox of an account[%d].", input_account_id); + + if (!em_storage_update_sync_status_of_account(input_account_id, SET_TYPE_SET, SYNC_STATUS_SYNCING, true, &err)) + EM_DEBUG_EXCEPTION("em_storage_update_sync_status_of_account failed [%d]", err); + + if (!em_storage_get_account_by_id(input_account_id, EMF_ACC_GET_OPT_DEFAULT, &account_tbl_array, true, &err)) { + EM_DEBUG_EXCEPTION("em_storage_get_account_by_id failed [ %d ] ", err); + em_storage_get_emf_error_from_em_storage_error(err); + if (!em_storage_notify_network_event(NOTI_DOWNLOAD_FAIL, input_account_id, input_mailbox_name, handle_to_be_published, err)) + EM_DEBUG_EXCEPTION(" em_storage_notify_network_event [ NOTI_DOWNLOAD_FAIL] Failed >>>> "); + goto FINISH_OFF; + } + account_count = 1; + } + + for (account_index = 0 ; account_index < account_count; account_index++) { + if (account_tbl_array[account_index].receiving_server_type == EMF_SERVER_TYPE_ACTIVE_SYNC) { + EM_DEBUG_LOG("account[%d] is for ActiveSync. Skip ", account_index); + continue; + } + + + if (!em_storage_get_mailbox(account_tbl_array[account_index].account_id, 0, EMAIL_MAILBOX_SORT_BY_TYPE_ASC, &mailbox_count, &mailbox_tbl_list, true, &err) || mailbox_count <= 0) { + EM_DEBUG_EXCEPTION("em_storage_get_mailbox failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + if (!em_storage_notify_network_event(NOTI_DOWNLOAD_FAIL, account_tbl_array[account_index].account_id, input_mailbox_name, handle_to_be_published, err)) + EM_DEBUG_EXCEPTION(" em_storage_notify_network_event [ NOTI_DOWNLOAD_FAIL] Failed >>>> "); + goto FINISH_OFF; + } + + EM_DEBUG_LOG("em_core_mailbox_get_list_to_be_sync returns [%d] mailboxes", mailbox_count); + + if(mailbox_tbl_spam) { + if (!em_storage_free_mailbox(&mailbox_tbl_spam, 1, &err)) { + err = em_storage_get_emf_error_from_em_storage_error(err); + EM_DEBUG_EXCEPTION("em_storage_free_mailbox failed [%d]", err); + } + mailbox_tbl_spam = NULL; + } + + if (!em_storage_get_mailbox_by_mailbox_type(account_tbl_array[account_index].account_id, EMF_MAILBOX_TYPE_SPAMBOX, &mailbox_tbl_spam, false, &err)) { + err = em_storage_get_emf_error_from_em_storage_error(err); + EM_DEBUG_LOG("em_storage_get_mailbox_by_mailbox_type failed [%d]", err); + } + + if (mailbox_count > 0) { +#ifndef __FEATURE_KEEP_CONNECTION__ + if (account_tbl_array[account_index].receiving_server_type == EMF_SERVER_TYPE_IMAP4) { + if (!em_core_mailbox_open(account_tbl_array[account_index].account_id, mailbox_tbl_list[0].mailbox_name, (void **)&stream, &err)) { + EM_DEBUG_EXCEPTION("em_core_mailbox_open failed [%d]", err); + if (err == EMF_ERROR_LOGIN_FAILURE) + EM_DEBUG_EXCEPTION("EMF_ERROR_LOGIN_FAILURE "); + /* continue; */ + if (!em_storage_notify_network_event(NOTI_DOWNLOAD_FAIL, account_tbl_array[account_index].account_id, mailbox_tbl_list[0].mailbox_name, handle_to_be_published, err)) + EM_DEBUG_EXCEPTION(" em_storage_notify_network_event [NOTI_DOWNLOAD_FAIL] Failed >>>> "); + goto FINISH_OFF; + } + EM_DEBUG_LOG("em_core_mailbox_open returns [%d] : ", err); + } + else + stream = NULL; +#endif + } + + for (counter = 0; counter < mailbox_count; counter++) { + if ( mailbox_tbl_list[counter].mailbox_type == EMF_MAILBOX_TYPE_ALL_EMAILS + || mailbox_tbl_list[counter].mailbox_type == EMF_MAILBOX_TYPE_TRASH + /*|| mailbox_tbl_list[counter].mailbox_type == EMF_MAILBOX_TYPE_SPAMBOX */) + EM_DEBUG_LOG("Skipped for all emails or trash"); + else if ((mailbox_tbl_list[counter].sync_with_server_yn)) { + EM_DEBUG_LOG("..........syncing %s mailbox......", mailbox_tbl_list[counter].mailbox_name); +#ifdef __FEATURE_KEEP_CONNECTION__ + if (!em_core_mailbox_sync_header((mailbox_tbl_list + counter) , mailbox_tbl_spam, NULL, &uid_list, &unread, &err)) { +#else /* __FEATURE_KEEP_CONNECTION__ */ + if (!em_core_mailbox_sync_header((mailbox_tbl_list + counter) , mailbox_tbl_spam, (void *)stream, &uid_list, &unread, &err)) { +#endif /* __FEATURE_KEEP_CONNECTION__ */ + EM_DEBUG_EXCEPTION("em_core_mailbox_sync_header for %s failed [%d]", mailbox_tbl_list[counter].mailbox_name, err); + +#ifndef __FEATURE_KEEP_CONNECTION__ + if (err == EMF_ERROR_CONNECTION_BROKEN || err == EMF_ERROR_NO_SUCH_HOST || err == EMF_ERROR_SOCKET_FAILURE) + stream = NULL; /* Don't retry to connect for broken connection. It might cause crash. */ +#endif /* __FEATURE_KEEP_CONNECTION__ */ + if (!em_storage_notify_network_event(NOTI_DOWNLOAD_FAIL, account_tbl_array[account_index].account_id, mailbox_tbl_list[counter].mailbox_name, handle_to_be_published, err)) + EM_DEBUG_EXCEPTION(" em_storage_notify_network_event [ NOTI_DOWNLOAD_FAIL] Failed >>>> "); + + goto FINISH_OFF; + } + } + total_unread += unread; + } + + EM_DEBUG_LOG("Sync for account_id(%d) is completed....!", account_tbl_array[account_index].account_id); + if (!em_storage_notify_network_event(NOTI_DOWNLOAD_FINISH, account_tbl_array[account_index].account_id, NULL, handle_to_be_published, 0)) + EM_DEBUG_EXCEPTION(" em_storage_notify_network_event [ NOTI_DOWNLOAD_FINISH] Failed >>>> "); + + if (total_unread > 0 && !em_storage_update_sync_status_of_account(account_tbl_array[account_index].account_id, SET_TYPE_UNION, SYNC_STATUS_HAVE_NEW_MAILS, true, &err)) + EM_DEBUG_EXCEPTION("em_storage_update_sync_status_of_account failed [%d]", err); + + if (!em_core_finalize_sync(account_tbl_array[account_index].account_id, &err)) + EM_DEBUG_EXCEPTION("em_core_finalize_sync failed [%d]", err); +#ifndef __FEATURE_KEEP_CONNECTION__ + if (stream) { + em_core_mailbox_close(0, stream); + stream = NULL; + } +#endif + if (mailbox_tbl_list) { + em_storage_free_mailbox(&mailbox_tbl_list, mailbox_count, NULL); + mailbox_tbl_list = NULL; + mailbox_count = 0; + } + } + } + + ret = true; + +FINISH_OFF: + + if(ret == false) { + } + +#ifndef __FEATURE_KEEP_CONNECTION__ + if (stream) + em_core_mailbox_close(0, stream); +#endif + if(mailbox_tbl_target) + em_storage_free_mailbox(&mailbox_tbl_target, 1, NULL); + + if (mailbox_tbl_list) + em_storage_free_mailbox(&mailbox_tbl_list, mailbox_count, NULL); + + if (account_tbl_array) + em_storage_free_account(&account_tbl_array, account_count, NULL); + } + + EM_DEBUG_FUNC_END(); + return ret; +} + +int event_handler_EMF_EVENT_VALIDATE_AND_CREATE_ACCOUNT(emf_account_t *account, int handle_to_be_published, int *error) +{ + EM_DEBUG_FUNC_BEGIN("account [%p]", account); + int err, ret = false; + + if(!account) { + EM_DEBUG_EXCEPTION("EMF_ERROR_INVALID_PARAM"); + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + EM_DEBUG_LOG("receiving_server_addr : %s", account->receiving_server_addr); + + if (!em_core_check_network_status(&err)) { + EM_DEBUG_EXCEPTION("em_core_check_network_status failed [%d]", err); + + if (!em_storage_notify_network_event(NOTI_VALIDATE_AND_CREATE_ACCOUNT_FAIL, account->account_id, NULL, handle_to_be_published, err)) + EM_DEBUG_EXCEPTION(" em_storage_notify_network_event [ NOTI_VALIDATE_ACCOUNT_FAIL] Failed >>>> "); + goto FINISH_OFF; + } + else { + EM_DEBUG_LOG("receiving_server_addr : %s", account->receiving_server_addr); + + if (!em_core_account_validate_with_account_info(account, &err)) { + EM_DEBUG_EXCEPTION("em_core_account_validate_with_account_info failed err : %d", err); + if (err == EMF_ERROR_CANCELLED) { + EM_DEBUG_EXCEPTION(" notify : NOTI_VALIDATE_AND_CREATE_ACCOUNT_CANCEL "); + if (!em_storage_notify_network_event(NOTI_VALIDATE_AND_CREATE_ACCOUNT_CANCEL, account->account_id, NULL, handle_to_be_published, err)) + EM_DEBUG_EXCEPTION(" em_storage_notify_network_event [ NOTI_VALIDATE_AND_CREATE_ACCOUNT_CANCEL] Failed"); + goto FINISH_OFF; + } + else + goto FINISH_OFF; + } + else { + if (em_core_account_create(account, &err) == false) { + EM_DEBUG_EXCEPTION(" emf_account_create failed - %d", err); + goto FINISH_OFF; + } + + em_core_refresh_account_reference(); + + if ((EMF_SERVER_TYPE_IMAP4 == account->receiving_server_type)) { + if (!em_core_mailbox_sync_mailbox_list(account->account_id, "", &err)) { + EM_DEBUG_EXCEPTION("em_core_mailbox_get_list_to_be_sync falied [%d]", err); + /* delete account whose mailbox couldn't be obtained from server */ + em_core_account_delete(account->account_id, NULL); + goto FINISH_OFF; + } + + } + + EM_DEBUG_EXCEPTION("validating and creating an account are succeeded for account id [%d] err [%d]", account->account_id, err); + if (!em_storage_notify_network_event(NOTI_VALIDATE_AND_CREATE_ACCOUNT_FINISH, account->account_id, NULL, handle_to_be_published, err)) + EM_DEBUG_EXCEPTION("em_storage_notify_network_event [ NOTI_VALIDATE_ACCOUNT_FINISH] Success"); + } + } + + ret = true; + +FINISH_OFF: + + if (ret == false && err != EMF_ERROR_CANCELLED) { + if (!em_storage_notify_network_event(NOTI_VALIDATE_AND_CREATE_ACCOUNT_FAIL, account->account_id, NULL, handle_to_be_published, err)) + EM_DEBUG_EXCEPTION(" em_storage_notify_network_event [ NOTI_VALIDATE_AND_CREATE_ACCOUNT_FAIL] Failed"); + } + if (error) + *error = err; + + EM_DEBUG_FUNC_END(); + return ret; +} + +int event_handler_EMF_EVENT_VALIDATE_AND_UPDATE_ACCOUNT(int account_id, emf_account_t *new_account_info, int handle_to_be_published, int *error) +{ + EM_DEBUG_FUNC_BEGIN("account_id [%d], new_account_info [%p]", account_id, new_account_info); + int err, ret = false; + emf_mail_account_tbl_t *old_account_tbl = NULL, *new_account_tbl = NULL; + + if (!new_account_info) { + EM_DEBUG_EXCEPTION("Invalid Parameter"); + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + if (!em_core_check_network_status(&err)) { + EM_DEBUG_EXCEPTION("em_core_check_network_status failed [%d]", err); + + if (!em_storage_notify_network_event(NOTI_VALIDATE_AND_UPDATE_ACCOUNT_FAIL, new_account_info->account_id, NULL, handle_to_be_published, err)) + EM_DEBUG_EXCEPTION("em_storage_notify_network_event [ NOTI_VALIDATE_AND_UPDATE_ACCOUNT_FAIL] Failed >>>> "); + goto FINISH_OFF; + } + else { + EM_DEBUG_LOG("receiving_server_addr : %s", new_account_info->receiving_server_addr); + + if (!em_core_account_validate_with_account_info(new_account_info, &err)) { + EM_DEBUG_EXCEPTION("\t em_core_account_validate_with_account_info failed err : %d", err); + if (err == EMF_ERROR_CANCELLED) { + EM_DEBUG_EXCEPTION(" notify : NOTI_VALIDATE_AND_CREATE_ACCOUNT_CANCEL "); + if (!em_storage_notify_network_event(NOTI_VALIDATE_AND_UPDATE_ACCOUNT_CANCEL, new_account_info->account_id, NULL, handle_to_be_published, err)) + EM_DEBUG_EXCEPTION(" em_storage_notify_network_event [ NOTI_VALIDATE_AND_UPDATE_ACCOUNT_CANCEL] Failed"); + goto FINISH_OFF; + } + else { + goto FINISH_OFF; + } + } + else { + if (!em_storage_get_account_by_id(account_id, WITHOUT_OPTION, &old_account_tbl, true, &err)) { + EM_DEBUG_EXCEPTION("em_storage_get_account_by_id failed [%d]", err); + /* goto FINISH_OFF; */ + } + + new_account_tbl = em_core_malloc(sizeof(emf_mail_account_tbl_t)); + if (!new_account_tbl) { + EM_DEBUG_EXCEPTION("allocation failed [%d]", err); + goto FINISH_OFF; + } + + em_convert_account_to_account_tbl(new_account_info, new_account_tbl); + + if (em_storage_update_account(account_id, new_account_tbl, true, &err)) { + em_core_refresh_account_reference(); + } + + EM_DEBUG_EXCEPTION("validating and updating an account are succeeded for account id [%d], err [%d]", new_account_info->account_id, err); + if (!em_storage_notify_network_event(NOTI_VALIDATE_AND_UPDATE_ACCOUNT_FINISH, new_account_info->account_id, NULL, handle_to_be_published, err)) + EM_DEBUG_EXCEPTION(" em_storage_notify_network_event [NOTI_VALIDATE_AND_UPDATE_ACCOUNT_FINISH] Success"); + } + } + + ret = true; + +FINISH_OFF: + if (old_account_tbl) + em_storage_free_account(&old_account_tbl, 1, NULL); + if (new_account_tbl) + em_storage_free_account(&new_account_tbl, 1, NULL); + + if (ret == false && err != EMF_ERROR_CANCELLED) { + if (!em_storage_notify_network_event(NOTI_VALIDATE_AND_UPDATE_ACCOUNT_FAIL, new_account_info->account_id, NULL, handle_to_be_published, err)) + EM_DEBUG_EXCEPTION(" em_storage_notify_network_event [ NOTI_VALIDATE_AND_CREATE_ACCOUNT_FAIL] Failed"); + } + + if (error) + *error = err; + + EM_DEBUG_FUNC_END(); + return ret; +} + +int event_handler_EMF_EVENT_SET_MAIL_SLOT_SIZE(int account_id, char *mailbox_name, int new_slot_size, int handle_to_be_published, int *error) +{ + EM_DEBUG_FUNC_BEGIN(); + + em_core_mailbox_set_mail_slot_size(account_id, mailbox_name, new_slot_size, error); + + EM_DEBUG_FUNC_END(); + return true; +} + + +#ifdef __LOCAL_ACTIVITY__ +int event_handler_EMF_EVENT_LOCAL_ACTIVITY(int account_id, int *error) +{ + EM_DEBUG_FUNC_BEGIN(); + + int err = EMF_ERROR_NONE; + emf_mailbox_t mailbox; + emf_activity_tbl_t *local_activity = NULL; + int activity_id_count = 0; + int activity_chunk_count = 0; + int *activity_id_list = NULL; + int i = 0; + + if (!em_core_check_network_status(&err)) + EM_DEBUG_EXCEPTION("em_core_check_network_status failed [%d]", err); + else { + if (false == em_storage_get_activity_id_list(account_id, &activity_id_list, &activity_id_count, ACTIVITY_DELETEMAIL, ACTIVITY_COPYMAIL, true, &err)) { + EM_DEBUG_EXCEPTION("em_storage_get_activity_id_list failed [%d]", err); + } + else { + for (i = 0; i < activity_id_count; ++i) { + if ((false == em_storage_get_activity(account_id , activity_id_list[i], &local_activity, &activity_chunk_count, true, &err)) || (NULL == local_activity) || (0 == activity_chunk_count)) + EM_DEBUG_EXCEPTION(" em_storage_get_activity Failed [ %d] or local_activity is NULL [%p] or activity_chunk_count is 0[%d]", err, local_activity, activity_chunk_count); + else { + EM_DEBUG_LOG("Found local activity type - %d", local_activity[0].activity_type); + switch (local_activity[0].activity_type) { + case ACTIVITY_MODIFYFLAG: { + if (em_core_mail_sync_flag_with_server(local_activity[0].mail_id , &err)) { + if (!em_core_activity_delete(&local_activity[0], &err)) + EM_DEBUG_EXCEPTION(">>>>>>Local Activity [ACTIVITY_MODIFYFLAG] [%d] ", err); + } + } + break; + + case ACTIVITY_DELETEMAIL: + case ACTIVITY_MOVEMAIL: + case ACTIVITY_MODIFYSEENFLAG: + case ACTIVITY_COPYMAIL: { + + int j = 0, k = 0; + int total_mail_ids = activity_chunk_count; + + int *mail_id_list = NULL; + + mail_id_list = (int *)em_core_malloc(sizeof(int) * total_mail_ids); + + if (NULL == mail_id_list) { + EM_DEBUG_EXCEPTION("malloc failed... "); + break; + } + + do { + + for (j = 0; j < BULK_OPERATION_COUNT && (k < total_mail_ids); ++j, ++k) + mail_id_list[j] = local_activity[k].mail_id; + + switch (local_activity[k-1].activity_type) { + case ACTIVITY_DELETEMAIL: { + if (!em_core_mail_delete(local_activity[k-1].account_id, + mail_id_list, + j, + EMF_DELETE_LOCAL_AND_SERVER, + EMF_DELETED_BY_COMMAND, + false, + &err)) + EM_DEBUG_LOG("\t em_core_mail_delete failed - %d", err); + } + break; + + case ACTIVITY_MOVEMAIL: { + if (!em_core_mail_move_from_server_ex(local_activity[k-1].account_id , + local_activity[k-1].src_mbox, + mail_id_list, + j, + local_activity[k-1].dest_mbox, + &err)) + EM_DEBUG_LOG("\t em_core_mail_move_from_server_ex failed - %d", err); + } + break; + case ACTIVITY_MODIFYSEENFLAG: { + int seen_flag = atoi(local_activity[0].src_mbox); + if (!em_core_mail_sync_seen_flag_with_server_ex(mail_id_list, j , seen_flag , &err)) /* local_activity[0].src_mbox points to the seen flag */ + EM_DEBUG_EXCEPTION("\t em_core_mail_sync_seen_flag_with_server_ex failed - %d", err); + } + break; + } + + } while (k < total_mail_ids); + + EM_SAFE_FREE(mail_id_list); + } + + break; + + default: + EM_DEBUG_LOG(">>>> No such Local Activity Handled by this thread [ %d ] >>> ", local_activity[0].activity_type); + break; + } + + em_storage_free_local_activity(&local_activity, activity_chunk_count, NULL); + + if (g_local_activity_run == 1) { + EM_DEBUG_LOG(" Network event_data found.. Local sync Stopped..! "); + break; + } + } + } + } + } + if (activity_id_list) { + if (false == em_storage_free_activity_id_list(activity_id_list, &err)) + EM_DEBUG_EXCEPTION("em_storage_free_activity_id_list failed"); + } + + if (error) + *error = err; + + EM_DEBUG_FUNC_END(); + + return true; +} +#endif /* __LOCAL_ACTIVITY__ */ + +int event_handler_EMF_EVENT_DOWNLOAD_BODY(int account_id, char *mailbox_name, int mail_id, int option, int handle_to_be_published, int *error) +{ + EM_DEBUG_FUNC_BEGIN(); + + int err = EMF_ERROR_NONE; + emf_mailbox_t mailbox; + + memset(&mailbox, 0x00, sizeof(mailbox)); + mailbox.account_id = account_id; + mailbox.name = mailbox_name; + + if (!em_core_check_network_status(&err)) { + EM_DEBUG_EXCEPTION("em_core_check_network_status failed [%d]", err); + + em_storage_notify_network_event(NOTI_DOWNLOAD_BODY_FAIL, mail_id, NULL, handle_to_be_published, err); + } + else { + if (!em_core_mail_download_body_multi_sections_bulk(NULL, + mailbox.account_id, + mail_id, + option >> 1, /* 0 : silent, 1 : verbose */ + option & 0x01, /* 0 : without attachments, 1 : with attachments */ + NO_LIMITATION, + handle_to_be_published, + &err)) + EM_DEBUG_EXCEPTION("em_core_mail_download_body_multi_sections_bulk failed - %d", err); + } + + if (error) + *error = err; + + EM_DEBUG_FUNC_END(); + return true; +} + +int event_handler_EMF_EVENT_DOWNLOAD_ATTACHMENT(int account_id, char *mailbox_name, int mail_id, char *attachment_no, int handle_to_be_published, int *error) +{ + EM_DEBUG_FUNC_BEGIN(); + + int err = EMF_ERROR_NONE; + emf_mailbox_t mailbox; + + EM_DEBUG_LOG("attachment_no is %d", atoi(attachment_no)); + + if (!em_core_check_network_status(&err)) { + EM_DEBUG_EXCEPTION("em_core_check_network_status failed [%d]", err); + em_storage_notify_network_event(NOTI_DOWNLOAD_ATTACH_FAIL, mail_id, NULL, atoi(attachment_no), err); + } + else { + memset(&mailbox, 0x00, sizeof(mailbox)); + mailbox.account_id = account_id; + mailbox.name = mailbox_name; + +#ifdef __ATTACHMENT_OPTI__ + if (!em_core_mail_download_attachment_bulk(mailbox.account_id, mail_id, (char *)attachment_no, &err)) + EM_DEBUG_EXCEPTION("\t em_core_mail_download_attachment failed - %d", err); +#else + if (!em_core_mail_download_attachment(mailbox.account_id, mail_id, (char *)attachment_no, &err)) + EM_DEBUG_EXCEPTION("\t em_core_mail_download_attachment failed - %d", err); +#endif + } + + if (error) + *error = err; + + EM_DEBUG_FUNC_END(); + return true; +} + +int event_handler_EMF_EVENT_SYNC_FLAGS_FIELD_TO_SERVER(int mail_ids[], int num, emf_flags_field_type field_type, int value, int *error) +{ + EM_DEBUG_FUNC_BEGIN(); + + int err = EMF_ERROR_NONE; + + if (!em_core_check_network_status(&err)) + EM_DEBUG_EXCEPTION("dnet_init failed [%d]", err); + else if (!em_core_mail_sync_flags_field_with_server(mail_ids, num, field_type, value, &err)) + EM_DEBUG_EXCEPTION("em_core_mail_sync_flags_field_with_server failed [%d]", err); + + if (error) + *error = err; + + EM_DEBUG_FUNC_END(); + return true; +} + +int event_handler_EMF_EVENT_VALIDATE_ACCOUNT(int account_id, int handle_to_be_published, int *error) +{ + EM_DEBUG_FUNC_BEGIN(); + + int err = EMF_ERROR_NONE; + + if (!em_core_check_network_status(&err)) { + EM_DEBUG_EXCEPTION("em_core_check_network_status failed [%d]", err); + + if (!em_storage_notify_network_event(NOTI_VALIDATE_ACCOUNT_FAIL, account_id, NULL, handle_to_be_published, err)) + EM_DEBUG_EXCEPTION("em_storage_notify_network_event [ NOTI_VALIDATE_ACCOUNT_FAIL] Failed >>>>"); + } + else { + + if (!em_core_account_validate(account_id, &err)) { + EM_DEBUG_EXCEPTION("em_core_account_validate failed account id : %d err : %d", account_id, err); + + if (err == EMF_ERROR_CANCELLED) { + EM_DEBUG_EXCEPTION("notify : NOTI_VALIDATE_ACCOUNT_CANCEL "); + if (!em_storage_notify_network_event(NOTI_VALIDATE_ACCOUNT_CANCEL, account_id, NULL, handle_to_be_published, err)) + EM_DEBUG_EXCEPTION(" em_storage_notify_network_event [ NOTI_VALIDATE_ACCOUNT_CANCEL] Failed >>>> "); + } + else { + if (!em_storage_notify_network_event(NOTI_VALIDATE_ACCOUNT_FAIL, account_id, NULL, handle_to_be_published, err)) + EM_DEBUG_EXCEPTION("em_storage_notify_network_event [ NOTI_VALIDATE_ACCOUNT_FAIL] Failed >>>> "); + } + } + else { + emf_account_t *account_ref; + account_ref = em_core_get_account_reference(account_id); + + if (account_ref) { + EM_DEBUG_LOG("account_ref->receiving_server_type[%d]", account_ref->receiving_server_type); + EM_DEBUG_LOG("account_ref->preset_account[%d]", account_ref->preset_account); + if ((EMF_SERVER_TYPE_IMAP4 == account_ref->receiving_server_type) && (account_ref->preset_account)) { + if (!em_core_check_thread_status()) + err = EMF_ERROR_CANCELLED; + else if (!em_core_mailbox_sync_mailbox_list(account_id, "", &err)) + EM_DEBUG_EXCEPTION("\t em_core_mailbox_get_list_to_be_sync falied - %d", err); + } + + if (err > 0) { + EM_DEBUG_EXCEPTION("em_core_account_validate succeeded account id : %d err : %d", account_id, err); + if (!em_storage_notify_network_event(NOTI_VALIDATE_ACCOUNT_FINISH, account_id, NULL, handle_to_be_published, err)) + EM_DEBUG_EXCEPTION("em_storage_notify_network_event [ NOTI_VALIDATE_ACCOUNT_FINISH] Success >>>>"); + } + } + } + } + + if (error) + *error = err; + + EM_DEBUG_FUNC_END(); + return true; +} + +int event_handler_EMF_EVENT_UPDATE_MAIL_OLD(int mail_id, emf_mail_t *mail, emf_meeting_request_t *meeting_req, int handle_to_be_published, int *error) +{ + EM_DEBUG_FUNC_BEGIN(); + int err = EMF_ERROR_NONE; + + if (!em_core_mail_update_old(mail_id, mail, meeting_req, &err)) + EM_DEBUG_EXCEPTION("em_core_mail_update_old failed [%d]", err); + em_core_mail_free(&mail, 1, NULL); + EM_SAFE_FREE(meeting_req); + + if (error) + *error = err; + + EM_DEBUG_FUNC_END(); + return true; +} + +int event_handler_EMF_EVENT_UPDATE_MAIL(emf_mail_data_t *input_mail_data, emf_attachment_data_t *input_attachment_data_list, int input_attachment_count, emf_meeting_request_t* input_meeting_request, int input_sync_server, int handle_to_be_published) +{ + EM_DEBUG_FUNC_BEGIN("input_mail_data[%p], input_attachment_data_list[%p], input_attachment_count[%d], input_meeting_request[%p], input_sync_server[%d]", input_mail_data, input_attachment_data_list, input_attachment_count, input_meeting_request, input_sync_server); + int err = EMF_ERROR_NONE; + + if ( (err = em_core_update_mail(input_mail_data, input_attachment_data_list, input_attachment_count, input_meeting_request, input_sync_server)) != EMF_ERROR_NONE) + EM_DEBUG_EXCEPTION("em_core_update_mail failed [%d]", err); + + if(input_mail_data) + em_core_free_mail_data(&input_mail_data, 1, NULL); + + if(input_attachment_data_list) + em_core_free_attachment_data(&input_attachment_data_list, input_attachment_count, NULL); + + if(input_meeting_request) + em_storage_free_meeting_request(&input_meeting_request, 1, NULL); + + EM_DEBUG_FUNC_END("err [%d", err); + return err; +} + +int event_handler_EMF_EVENT_MOVE_MAIL(int account_id, char *srt_mailbox_name, int *mail_ids, int mail_id_count, char *dest_mailbox_name, int handle_to_be_published, int *error) +{ + EM_DEBUG_FUNC_BEGIN(); + int err = EMF_ERROR_NONE, ret = false; + emf_mailbox_t dest_mailbox; + emf_account_t *account_ref = NULL; + + if (!(account_ref = em_core_get_account_reference(account_id))) { + EM_DEBUG_EXCEPTION("em_core_get_account_reference failed [%d]", account_id); + err = EMF_ERROR_INVALID_ACCOUNT; + goto FINISH_OFF; + } + + memset(&dest_mailbox, 0, sizeof(emf_mailbox_t)); + dest_mailbox.name = dest_mailbox_name; + + /* Remove mail local */ + /* + if (!em_core_mail_move(mail_ids, mail_id_count, dest_mailbox.name, EMF_MOVED_BY_COMMAND, 0, &err)) { + EM_DEBUG_EXCEPTION("em_core_mail_move failed [%d]", err); + goto FINISH_OFF; + } + */ + + if (account_ref->receiving_server_type == EMF_SERVER_TYPE_IMAP4) { + /* Remove mail on server */ + if (!em_core_check_network_status(&err)) + EM_DEBUG_EXCEPTION("em_core_check_network_status failed [%d]", err); + else { +#ifdef __FEATURE_BULK_DELETE_MOVE_UPDATE_REQUEST_OPTI__ + if (!em_core_mail_move_from_server_ex(account_id , srt_mailbox_name, mail_ids, mail_id_count, dest_mailbox_name, &err)) + EM_DEBUG_EXCEPTION("em_core_mail_move_from_server_ex failed - %d", err); +#else + if (!em_core_mail_move_from_server(account_id , srt_mailbox_name, mail_ids, mail_id_count, dest_mailbox_name, &err)) + EM_DEBUG_EXCEPTION("\t em_core_mail_move_from_server failed - %d", err); +#endif + } + } + + ret = true; +FINISH_OFF: + + if (error) + *error = err; + + EM_DEBUG_FUNC_END(); + return ret; +} + +int event_handler_EMF_EVENT_DELETE_MAILBOX(int account_id, char *mailbox_name, int on_server, int handle_to_be_published, int *error) +{ + EM_DEBUG_FUNC_BEGIN(); + int err = EMF_ERROR_NONE; + emf_mailbox_t mailbox; + + memset(&mailbox, 0x00, sizeof(mailbox)); + mailbox.account_id = account_id; + mailbox.name = mailbox_name; + + if (!em_core_check_network_status(&err)) + EM_DEBUG_EXCEPTION("em_core_check_network_status failed [%d]", err); + else { + if (!em_core_mailbox_delete(&mailbox, on_server, &err)) + EM_DEBUG_LOG("em_core_mailbox_delete failed - %d", err); + } + + if (error) + *error = err; + + EM_DEBUG_FUNC_END(); + return true; +} + +int event_handler_EMF_EVENT_CREATE_MAILBOX(int account_id, char *mailbox_name, char *mailbox_alias, int mailbox_type, int on_server, int handle_to_be_published, int *error) +{ + EM_DEBUG_FUNC_BEGIN(); + int err = EMF_ERROR_NONE; + emf_mailbox_t mailbox; + + memset(&mailbox, 0x00, sizeof(mailbox)); + + mailbox.account_id = account_id; + mailbox.name = mailbox_name; + mailbox.alias = mailbox_alias; + mailbox.mailbox_type = mailbox_type; + + if (!em_core_check_network_status(&err)) { + EM_DEBUG_EXCEPTION("em_core_check_network_status failed [%d]", err); + } + else { + if (!em_core_mailbox_create(&mailbox, on_server, &err)) + EM_DEBUG_EXCEPTION("em_core_mailbox_create failed - %d", err); + } + + + if (error) + *error = err; + + EM_DEBUG_FUNC_END(); + return true; +} + +int event_handler_EMF_EVENT_SYNC_MAIL_FLAG_TO_SERVER(int mail_id, int *error) +{ + EM_DEBUG_FUNC_BEGIN("mail_id [%d], error [%p]", mail_id, error); + + int err = EMF_ERROR_NONE; + + if (!em_core_check_network_status(&err)) + EM_DEBUG_EXCEPTION("em_core_check_network_status failed [%d]", err); + else { + if (!em_core_mail_sync_flag_with_server(mail_id, &err)) + EM_DEBUG_EXCEPTION("em_core_mail_sync_flag_with_server failed [%d]", err); +#ifdef __LOCAL_ACTIVITY__ + else { + emf_activity_tbl_t new_activity; + memset(&new_activity, 0x00, sizeof(emf_activity_tbl_t)); + new_activity.activity_type = ACTIVITY_MODIFYFLAG; + new_activity.account_id = event_data.account_id; + new_activity.mail_id = event_data.event_param_data_4; + new_activity.dest_mbox = NULL; + new_activity.server_mailid = NULL; + new_activity.src_mbox = NULL; + + if (!em_core_activity_delete(&new_activity, &err)) + EM_DEBUG_EXCEPTION(">>>>>>Local Activity [ACTIVITY_MODIFYFLAG] [%d] ", err); + } +#endif /* __LOCAL_ACTIVITY__ */ + } + + if (error) + *error = err; + + EM_DEBUG_FUNC_END(); + return true; +} + +int event_handler_EMF_EVENT_DELETE_MAIL_ALL(int account_id, char *mailbox_name, int with_server, int *error) +{ + EM_DEBUG_FUNC_BEGIN("account_id [%d], mailbox_name [%p], with_server [%d], error [%p]", account_id, mailbox_name, with_server, error); + int err = EMF_ERROR_NONE; + emf_mailbox_t temp_mailbox = { 0 }; + + temp_mailbox.account_id = account_id; + temp_mailbox.name = mailbox_name; + + if (!em_core_mail_delete_all(&temp_mailbox, with_server, &err)) + EM_DEBUG_EXCEPTION("em_core_mail_delete_all failed [%d]", err); + + if (error) + *error = err; + + EM_DEBUG_FUNC_END("err [%d]", err); + return true; +} + +int event_handler_EMF_EVENT_DELETE_MAIL(int account_id, int *mail_id_list, int mail_id_count, char *mailbox_name, int *error) +{ + EM_DEBUG_FUNC_BEGIN(); + int mail_id = 0, err = EMF_ERROR_NONE, ret = false; + emf_account_t *account_ref = NULL; + + if (!(account_ref = em_core_get_account_reference(account_id))) { + EM_DEBUG_EXCEPTION("em_core_get_account_reference failed [%d]", account_id); + err = EMF_ERROR_INVALID_ACCOUNT; + goto FINISH_OFF; + } + + if (account_ref->receiving_server_type == EMF_SERVER_TYPE_IMAP4) { + if (!em_core_check_network_status(&err)) { + EM_DEBUG_EXCEPTION("em_core_check_network_status failed [%d]", err); + + if (!em_storage_notify_network_event(NOTI_MAIL_DELETE_ON_SERVER_FAIL, account_id, mailbox_name, mail_id, err)) + EM_DEBUG_EXCEPTION(" em_storage_notify_network_event [NOTI_MAIL_DELETE_ON_SERVER_FAIL] Failed"); + + } + else if (!em_core_mail_delete(account_id, mail_id_list, mail_id_count, EMF_DELETE_LOCAL_AND_SERVER, EMF_DELETED_BY_COMMAND, false, &err)) { + EM_DEBUG_EXCEPTION("em_core_mail_delete failed [%d]", err); + + if (!em_storage_notify_network_event(NOTI_MAIL_DELETE_ON_SERVER_FAIL, account_id, mailbox_name, mail_id, err)) + EM_DEBUG_EXCEPTION("em_storage_notify_network_event [NOTI_MAIL_DELETE_ON_SERVER_FAIL] Failed"); + } + } + + ret = true; +FINISH_OFF: + + if (error) + *error = err; + + EM_DEBUG_FUNC_END(); + return ret; +} + +int event_hanlder_EMF_EVENT_SYNC_HEADER_OMA(int account_id, char *maibox_name, int *error) +{ + EM_DEBUG_FUNC_BEGIN(); + int err = EMF_ERROR_NONE; + + if (!em_core_check_network_status(&err)) { + EM_DEBUG_EXCEPTION("em_core_check_network_status failed [%d]", err); + if (!em_storage_notify_network_event(NOTI_DOWNLOAD_FAIL, account_id, maibox_name, 0, err)) + EM_DEBUG_EXCEPTION("em_storage_notify_network_event [NOTI_DOWNLOAD_FAIL] Failed"); + } + else { + EM_DEBUG_LOG("Sync of all mailbox"); + if (!em_core_mailbox_sync_mailbox_list(account_id, "", &err)) + EM_DEBUG_EXCEPTION("em_core_mailbox_sync_mailbox_list failed [%d]", err); + } + + if (error) + *error = err; + + EM_DEBUG_FUNC_END(); + return true; +} + +void* thread_func_branch_command(void *arg) +{ + EM_DEBUG_FUNC_BEGIN(); + + int err = EMF_ERROR_NONE, is_storage_full = false, noti_id; + emf_event_t event_data; + emf_session_t *session = NULL; + int handle_to_be_published = 0; + + if (!em_storage_open(&err)) { + EM_DEBUG_EXCEPTION("em_storage_open falied [%d]", err); + return false; + } + + /* check that event_data loop is continuous */ + while (em_core_event_loop_continue()) { + if (!em_core_get_empty_session(&session)) + EM_DEBUG_EXCEPTION("em_core_get_empty_session failed..."); + + /* get a event_data from event_data queue */ + if (!em_core_retrieve_event(&event_data, NULL)) { /* no event_data pending */ + EM_DEBUG_LOG("For handle g_event_que[g_event_que_idx].type [%d], g_event_que_idx [%d]", g_event_que[g_event_que_idx].type, g_event_que_idx); +#ifdef ENABLE_IMAP_IDLE_THREAD + if ( !em_core_check_network_status(&err)) { + EM_DEBUG_LOG(">>>> Data Networking ON "); + if (g_client_run) { + if (g_imap_idle_thread_alive) { + /* em_core_imap_idle_thread_kill(NULL); */ + /* em_core_imap_idle_thread_create(NULL); */ + } + else { + if (!send_thread_run) + em_core_imap_idle_thread_create(event_data.account_id, NULL); + } + } + } +#endif /* ENABLE_IMAP_IDLE_THREAD */ +#ifdef __LOCAL_ACTIVITY__ + /* Local activity sync */ + if (g_client_run && g_local_activity_run) { + emf_mail_account_tbl_t *account_list = NULL; + int count = 0, i; + if (!em_storage_get_account_list(&count, &account_list, true, true, &err)) + EM_DEBUG_EXCEPTION("em_storage_get_account_list failed [%d]", err); + else { + for (i = 0; i < count; i++) { + if (em_core_local_activity_sync(account_list[i].account_id, &err)) { + EM_DEBUG_LOG("Found local activity...!"); + EM_DEBUG_LOG("Resetting g_local_activity_run "); + g_local_activity_run = 0; + em_core_clear_session(session); + } + } + + em_storage_free_account(&account_list, count, &err); + + if (!g_local_activity_run) + continue; + } + } +#endif + + recv_thread_run = 0; + + ENTER_CRITICAL_SECTION(_event_available_lock); + SLEEP_CONDITION_VARIABLE(_event_available_signal, _event_available_lock); + EM_DEBUG_LOG("Wake up by _event_available_signal"); + LEAVE_CRITICAL_SECTION(_event_available_lock); + } + else { + EM_DEBUG_LOG(">>>>>>>>>>>>>>> Got event_data !!! <<<<<<<<<<<<<<<"); + EM_DEBUG_LOG("For handle g_event_que_idx - %d", g_event_que_idx); + + if (g_event_que_idx == 1) + handle_to_be_published = 31; + else + handle_to_be_published = g_event_que_idx - 1 ; + + EM_DEBUG_LOG("Handle to be Published [%d]", handle_to_be_published); + recv_thread_run = 1; + g_client_run = 1; + + /* Handling storage full */ + is_storage_full = false; + if (event_data.type == EMF_EVENT_SYNC_HEADER || event_data.type == EMF_EVENT_SYNC_HEADER_OMA || + event_data.type == EMF_EVENT_DOWNLOAD_BODY || event_data.type == EMF_EVENT_DOWNLOAD_ATTACHMENT) { + if (em_core_is_storage_full(&err) == true) { + EM_DEBUG_EXCEPTION("Storage is full"); + switch (event_data.type) { + case EMF_EVENT_SYNC_HEADER: + case EMF_EVENT_SYNC_HEADER_OMA: + noti_id = NOTI_DOWNLOAD_FAIL; + break; + case EMF_EVENT_DOWNLOAD_BODY: + noti_id = NOTI_DOWNLOAD_BODY_FAIL; + break; + case EMF_EVENT_DOWNLOAD_ATTACHMENT: + noti_id = NOTI_DOWNLOAD_ATTACH_FAIL; + break; + default: + break; + } + + if (!em_storage_notify_network_event(noti_id, event_data.account_id, NULL, handle_to_be_published, err)) + EM_DEBUG_EXCEPTION(" em_storage_notify_network_event [NOTI_DOWNLOAD_FAIL] Failed >>>> "); + is_storage_full = true; + } + } + + em_storage_dimming_on_off(false, NULL); + + switch (event_data.type) { + case EMF_EVENT_SYNC_IMAP_MAILBOX: /* get imap mailbox list */ + if (!em_core_check_network_status(&err)) + EM_DEBUG_EXCEPTION("em_core_check_network_status failed [%d]", err); + else { + if (!em_core_mailbox_sync_mailbox_list(event_data.account_id, event_data.event_param_data_3, &err)) + EM_DEBUG_EXCEPTION("em_core_mailbox_sync_mailbox_list failed [%d]", err); + } + EM_SAFE_FREE(event_data.event_param_data_3); + break; + + case EMF_EVENT_SYNC_HEADER: /* synchronize mail header */ + if (is_storage_full == false) + event_handler_EMF_EVENT_SYNC_HEADER(event_data.account_id, event_data.event_param_data_1, handle_to_be_published, &err); + EM_SAFE_FREE(event_data.event_param_data_1); + break; + + case EMF_EVENT_SYNC_HEADER_OMA: /* synchronize mail header for OMA */ + if (is_storage_full == false) + event_hanlder_EMF_EVENT_SYNC_HEADER_OMA(event_data.account_id, event_data.event_param_data_1, &err); + EM_SAFE_FREE(event_data.event_param_data_1); + break; + + case EMF_EVENT_DOWNLOAD_BODY: /* download mail body */ + if (is_storage_full == false) + event_handler_EMF_EVENT_DOWNLOAD_BODY(event_data.account_id, event_data.event_param_data_1, (int)event_data.event_param_data_4, (int)event_data.event_param_data_3, handle_to_be_published, &err); + event_data.event_param_data_3 = NULL; /* MUST BE */ + EM_SAFE_FREE(event_data.event_param_data_1); + break; + + case EMF_EVENT_DOWNLOAD_ATTACHMENT: /* download attachment */ + if (is_storage_full == false) + event_handler_EMF_EVENT_DOWNLOAD_ATTACHMENT(event_data.account_id, event_data.event_param_data_1, (int)event_data.event_param_data_4, event_data.event_param_data_3, handle_to_be_published, &err); + EM_SAFE_FREE(event_data.event_param_data_3); + break; + + case EMF_EVENT_SYNC_FLAGS_FIELD_TO_SERVER: /* Sync flags field */ + event_handler_EMF_EVENT_SYNC_FLAGS_FIELD_TO_SERVER((int*)event_data.event_param_data_3, event_data.event_param_data_4 , event_data.event_param_data_5, event_data.event_param_data_6, &err); + EM_SAFE_FREE(event_data.event_param_data_3); + break; + + case EMF_EVENT_DELETE_MAIL: /* delete mails */ + event_handler_EMF_EVENT_DELETE_MAIL(event_data.account_id, (int *)event_data.event_param_data_3, event_data.event_param_data_4, event_data.event_param_data_1, &err); + EM_SAFE_FREE(event_data.event_param_data_1); + EM_SAFE_FREE(event_data.event_param_data_3); + break; + + case EMF_EVENT_DELETE_MAIL_ALL: /* delete all mails */ + event_handler_EMF_EVENT_DELETE_MAIL_ALL((int)event_data.account_id, (char *)event_data.event_param_data_1, (int)event_data.event_param_data_4, &err); + EM_SAFE_FREE(event_data.event_param_data_1); + break; +#ifdef __FEATURE_SYNC_CLIENT_TO_SERVER__ + case EMF_EVENT_SYNC_MAIL_FLAG_TO_SERVER: + event_handler_EMF_EVENT_SYNC_MAIL_FLAG_TO_SERVER((int)event_data.event_param_data_4, &err); + break; +#endif + + case EMF_EVENT_CREATE_MAILBOX: + event_handler_EMF_EVENT_CREATE_MAILBOX(event_data.account_id, event_data.event_param_data_1, event_data.event_param_data_2, GPOINTER_TO_INT(event_data.event_param_data_3), event_data.event_param_data_4, handle_to_be_published, &err); + EM_SAFE_FREE(event_data.event_param_data_1); + EM_SAFE_FREE(event_data.event_param_data_2); + break; + + case EMF_EVENT_DELETE_MAILBOX: + event_handler_EMF_EVENT_DELETE_MAILBOX(event_data.account_id, event_data.event_param_data_1, event_data.event_param_data_4, handle_to_be_published, &err); + EM_SAFE_FREE(event_data.event_param_data_1); + break; + + case EMF_EVENT_MOVE_MAIL: + event_handler_EMF_EVENT_MOVE_MAIL(event_data.account_id, event_data.event_param_data_2, (int *)event_data.event_param_data_3, event_data.event_param_data_4, event_data.event_param_data_1, handle_to_be_published, &err); + + EM_SAFE_FREE(event_data.event_param_data_1); + EM_SAFE_FREE(event_data.event_param_data_2); + EM_SAFE_FREE(event_data.event_param_data_3); + break; + + case EMF_EVENT_VALIDATE_ACCOUNT: + event_handler_EMF_EVENT_VALIDATE_ACCOUNT(event_data.account_id, handle_to_be_published, &err); + break; + + case EMF_EVENT_VALIDATE_AND_CREATE_ACCOUNT: + event_handler_EMF_EVENT_VALIDATE_AND_CREATE_ACCOUNT(em_core_account_get_new_account_ref(), handle_to_be_published, &err); + break; + + case EMF_EVENT_VALIDATE_AND_UPDATE_ACCOUNT: { + emf_account_t *pAccount = (emf_account_t *)event_data.event_param_data_1; + event_handler_EMF_EVENT_VALIDATE_AND_UPDATE_ACCOUNT(event_data.account_id, pAccount, handle_to_be_published, &err); + em_core_account_free(&pAccount, 1, NULL); + } + break; + + case EMF_EVENT_UPDATE_MAIL_OLD: + event_handler_EMF_EVENT_UPDATE_MAIL_OLD((int)event_data.event_param_data_4, (emf_mail_t *)event_data.event_param_data_1, (emf_meeting_request_t *)event_data.event_param_data_2, handle_to_be_published, &err); + event_data.event_param_data_1 = NULL; + event_data.event_param_data_2 = NULL; + break; + + case EMF_EVENT_UPDATE_MAIL: + event_handler_EMF_EVENT_UPDATE_MAIL((emf_mail_data_t*)event_data.event_param_data_1, (emf_attachment_data_t*)event_data.event_param_data_2, event_data.event_param_data_4, (emf_meeting_request_t*)event_data.event_param_data_3, event_data.event_param_data_5, handle_to_be_published); + + event_data.event_param_data_1 = NULL; + event_data.event_param_data_2 = NULL; + event_data.event_param_data_3 = NULL; + break; + + case EMF_EVENT_SET_MAIL_SLOT_SIZE: + event_handler_EMF_EVENT_SET_MAIL_SLOT_SIZE(event_data.account_id, event_data.event_param_data_3, event_data.event_param_data_4, handle_to_be_published, &err); + EM_SAFE_FREE(event_data.event_param_data_3); + break; + +#ifdef __LOCAL_ACTIVITY__ + case EMF_EVENT_LOCAL_ACTIVITY: + event_handler_EMF_EVENT_LOCAL_ACTIVITY(event_data.account_id, &err); + break; +#endif /* __LOCAL_ACTIVITY__*/ + + default: + break; + } + + em_storage_dimming_on_off(true, NULL); + em_core_flush_memory(); + + switch (event_data.type) { + case EMF_EVENT_SEND_MAIL: + case EMF_EVENT_SEND_MAIL_SAVED: + _sending_busy_unref(); + break; + + case EMF_EVENT_SYNC_HEADER: + case EMF_EVENT_SYNC_HEADER_OMA: + case EMF_EVENT_DOWNLOAD_BODY: + case EMF_EVENT_DOWNLOAD_ATTACHMENT: + case EMF_EVENT_SYNC_MAIL_FLAG_TO_SERVER: + case EMF_EVENT_SYNC_FLAGS_FIELD_TO_SERVER: + case EMF_EVENT_DELETE_MAIL: + case EMF_EVENT_DELETE_MAIL_ALL: + case EMF_EVENT_VALIDATE_ACCOUNT: + case EMF_EVENT_SYNC_IMAP_MAILBOX: + case EMF_EVENT_MOVE_MAIL: + case EMF_EVENT_CREATE_MAILBOX: + case EMF_EVENT_DELETE_MAILBOX: + case EMF_EVENT_SET_MAIL_SLOT_SIZE: + _receiving_busy_unref(); + break; + + default: + break; + } + + event_data.type = 0; + + ENTER_RECURSIVE_CRITICAL_SECTION(_event_queue_lock); + memset(g_event_que+g_active_que, 0x00, sizeof(emf_event_t)); + LEAVE_RECURSIVE_CRITICAL_SECTION(_event_queue_lock); + } + + em_core_clear_session(session); + } + + if (!em_storage_close(&err)) + EM_DEBUG_EXCEPTION("em_storage_close falied [%d]", err); + + EM_DEBUG_FUNC_END(); + return SUCCESS; +} +/*Send event_data loop*/ +EXPORT_API int em_core_send_event_loop_start(int *err_code) +{ + EM_DEBUG_FUNC_BEGIN(); + int thread_error = -1; + + if (err_code != NULL) + *err_code = EMF_ERROR_NONE; + + memset(&g_send_event_que, 0x00, sizeof(g_send_event_que)); + + if (g_send_srv_thread) { + EM_DEBUG_EXCEPTION("\t send service thread is already running..."); + if (err_code != NULL) + *err_code = EMF_ERROR_UNKNOWN; + return true; + } + + g_send_event_que_idx = 1; + g_send_event_loop = 1; + g_send_active_que = 0; + + /* initialize lock */ + /* INITIALIZE_CRITICAL_SECTION(_send_event_available_lock); */ + INITIALIZE_RECURSIVE_CRITICAL_SECTION(_send_event_queue_lock); + INITIALIZE_CONDITION_VARIABLE(_send_event_available_signal); + + /* create thread */ + THREAD_CREATE_JOINABLE(g_send_srv_thread, send_event_handler, thread_error); + + if (thread_error != 0) { + EM_DEBUG_EXCEPTION("cannot make thread..."); + if (err_code != NULL) + *err_code = EMF_ERROR_UNKNOWN; + return FAILURE; + } + + if (err_code != NULL) + *err_code = EMF_ERROR_NONE; + EM_DEBUG_FUNC_END(); + return SUCCESS; +} + +/* finish api event_data loop */ +EXPORT_API int em_core_send_event_loop_stop(int *err_code) +{ + EM_DEBUG_FUNC_BEGIN(); + + if (err_code != NULL) + *err_code = EMF_ERROR_NONE; + + if (!g_send_srv_thread) { + if (err_code != NULL) + *err_code = EMF_ERROR_UNKNOWN; + return false; + } + + /* stop event_data loop */ + g_send_event_loop = 0; + + em_core_cancel_send_mail_thread(g_send_active_que, NULL, err_code); + ENTER_CRITICAL_SECTION(_send_event_available_lock); + WAKE_CONDITION_VARIABLE(_send_event_available_signal); /* MUST BE HERE */ + LEAVE_CRITICAL_SECTION(_send_event_available_lock); + + /* wait for thread finished */ + THREAD_JOIN(g_send_srv_thread); + + g_send_srv_thread = 0; + + DELETE_RECURSIVE_CRITICAL_SECTION(_send_event_queue_lock); + DELETE_CRITICAL_SECTION(_send_event_available_lock); + DELETE_CONDITION_VARIABLE(_send_event_available_signal); + + g_send_event_que_idx = 1; + g_send_active_que = 0; + + if (err_code != NULL) + *err_code = EMF_ERROR_NONE; + + return true; +} + +/* start api event_data loop */ +EXPORT_API int em_core_event_loop_start(int *err_code) +{ + EM_DEBUG_FUNC_BEGIN(); + int thread_error; + + if (err_code != NULL) + *err_code = EMF_ERROR_NONE; + + memset(&g_event_que, 0x00, sizeof(g_event_que)); + + if (g_srv_thread) { + EM_DEBUG_EXCEPTION("service thread is already running..."); + if (err_code != NULL) + *err_code = EMF_ERROR_UNKNOWN; + return true; + } + + g_event_que_idx = 1; + g_event_loop = 1; + g_active_que = 0; + + /* initialize lock */ + INITIALIZE_RECURSIVE_CRITICAL_SECTION(_event_queue_lock); + INITIALIZE_RECURSIVE_CRITICAL_SECTION(_event_callback_table_lock); + + em_core_initialize_event_callback_table(); + + /* create thread */ + THREAD_CREATE(g_srv_thread, thread_func_branch_command, NULL, thread_error); + + if (thread_error != 0) { + EM_DEBUG_EXCEPTION("cannot create thread"); + if (err_code != NULL) + *err_code = EMF_ERROR_SYSTEM_FAILURE; + return FAILURE; + } + + if (err_code != NULL) + *err_code = EMF_ERROR_NONE; + + return false; +} + +/* finish api event_data loop */ +EXPORT_API int em_core_event_loop_stop(int *err_code) +{ + EM_DEBUG_FUNC_BEGIN(); + + if (err_code != NULL) + *err_code = EMF_ERROR_NONE; + + if (!g_srv_thread) { + if (err_code != NULL) + *err_code = EMF_ERROR_UNKNOWN; + return false; + } + + /* stop event_data loop */ + g_event_loop = 0; + + /* pthread_kill(g_srv_thread, SIGINT); */ + em_core_cancel_thread(g_active_que, NULL, err_code); + + ENTER_CRITICAL_SECTION(_event_available_lock); + WAKE_CONDITION_VARIABLE(_event_available_signal); + LEAVE_CRITICAL_SECTION(_event_available_lock); + + /* wait for thread finished */ + THREAD_JOIN(g_srv_thread); + + g_srv_thread = 0; + + DELETE_RECURSIVE_CRITICAL_SECTION(_event_queue_lock); + DELETE_CRITICAL_SECTION(_event_available_lock); + DELETE_CONDITION_VARIABLE(_event_available_signal); + DELETE_RECURSIVE_CRITICAL_SECTION(_event_callback_table_lock); + + g_event_que_idx = 1; + g_active_que = 0; + + if (err_code != NULL) + *err_code = EMF_ERROR_NONE; + EM_DEBUG_FUNC_END(); + return true; +} + + +int em_core_get_active_queue_idx() +{ + return g_send_active_que; +} + +/* check thread status +* 0 : stop job 1 : continue job +*/ +EXPORT_API int em_core_check_thread_status() +{ + if (g_active_que <= 0) + return true; + + return (g_event_que[g_active_que].status == EMF_EVENT_STATUS_STARTED); +} + +/* cancel a job */ +EXPORT_API int em_core_cancel_thread(int handle, void *arg, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("handle[%d], arg[%p], err_code[%p]", handle, arg, err_code); + + int ret = false; + int err = EMF_ERROR_NONE; + + if (handle <= 0 || handle > (EVENT_QUEUE_MAX - 1)) { + EM_DEBUG_EXCEPTION("handle[%d], arg[%p]", handle, arg); + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + ENTER_RECURSIVE_CRITICAL_SECTION(_event_queue_lock); + + EM_DEBUG_LOG("status[%d], type[%d], handle[%d]", g_event_que[handle].status, g_event_que[handle].type, handle); + + if (g_event_que[handle].status == EMF_EVENT_STATUS_WAIT) { + fail_status_notify(&g_event_que[handle], EMF_ERROR_CANCELLED); + + switch (g_event_que[handle].type) { + case EMF_EVENT_SEND_MAIL: + case EMF_EVENT_SEND_MAIL_SAVED: + EM_DEBUG_LOG("EMF_EVENT_SEND_MAIL or EMF_EVENT_SEND_MAIL_SAVED"); + _sending_busy_unref(); + if (!em_storage_notify_network_event(NOTI_SEND_CANCEL, g_event_que[handle].account_id, NULL , g_event_que[handle].event_param_data_4, err)) + EM_DEBUG_EXCEPTION(" em_storage_notify_network_event [ NOTI_SEND_CANCEL] Failed >>>> "); + break; + case EMF_EVENT_DOWNLOAD_BODY: + EM_DEBUG_LOG("EMF_EVENT_DOWNLOAD_BODY"); + _receiving_busy_unref(); + if (!em_storage_notify_network_event(NOTI_DOWNLOAD_BODY_CANCEL, g_event_que[handle].account_id, NULL , g_event_que[handle].event_param_data_4, err)) + EM_DEBUG_EXCEPTION(" em_storage_notify_network_event [ NOTI_SEND_CANCEL] Failed >>>> "); + break; + + case EMF_EVENT_SYNC_HEADER: + case EMF_EVENT_SYNC_HEADER_OMA: + case EMF_EVENT_DOWNLOAD_ATTACHMENT: + case EMF_EVENT_SYNC_MAIL_FLAG_TO_SERVER: + case EMF_EVENT_SYNC_FLAGS_FIELD_TO_SERVER: + EM_DEBUG_LOG("EMF_EVENT_SYNC_HEADER, EMF_EVENT_DOWNLOAD_ATTACHMENT"); + _receiving_busy_unref(); + break; + + case EMF_EVENT_VALIDATE_ACCOUNT: + EM_DEBUG_LOG(" validate account waiting : cancel acc id : %d", g_event_que[handle].account_id); + _receiving_busy_unref(); + if (!em_storage_notify_network_event(NOTI_VALIDATE_ACCOUNT_CANCEL, g_event_que[handle].account_id, NULL , g_event_que[handle].event_param_data_4, err)) + EM_DEBUG_EXCEPTION(" em_storage_notify_network_event [ NOTI_VALIDATE_ACCOUNT_CANCEL] Failed >>>> "); + break; + + case EMF_EVENT_DELETE_MAIL: + case EMF_EVENT_DELETE_MAIL_ALL: + case EMF_EVENT_SYNC_IMAP_MAILBOX: + case EMF_EVENT_MOVE_MAIL: + case EMF_EVENT_CREATE_MAILBOX: + case EMF_EVENT_DELETE_MAILBOX: + case EMF_EVENT_SET_MAIL_SLOT_SIZE: + EM_DEBUG_LOG("EMF_EVENT_DELETE_MAIL, EMF_EVENT_SYNC_IMAP_MAILBOX"); + _receiving_busy_unref(); + break; + default: + break; + } + } + + memset(g_event_que+handle, 0x00, sizeof(emf_event_t)); + g_event_que[handle].status = EMF_EVENT_STATUS_CANCELED; + + LEAVE_RECURSIVE_CRITICAL_SECTION(_event_queue_lock); + + ret = true; + +FINISH_OFF: + if (err_code != NULL) + *err_code = err; + EM_DEBUG_FUNC_END(); + return ret; +} + +EXPORT_API int em_core_cancel_all_threads_of_an_account(int account_id) +{ + EM_DEBUG_FUNC_BEGIN(); + int error_code = EMF_ERROR_NONE; + int i, event_count = EVENT_QUEUE_MAX, exit_flag = 0, sleep_count = 0; + + for (i = 0 ; i < event_count; i++) { + if (g_event_que[i].type && g_event_que[i].status != EMF_EVENT_STATUS_UNUSED) { + EM_DEBUG_LOG("There is a live thread. %d", i); + if (g_event_que[i].account_id == account_id || g_event_que[i].account_id == ALL_ACCOUNT) { + EM_DEBUG_LOG("And it is for account %d", g_event_que[i].account_id); + em_core_cancel_thread(i, NULL, &error_code); + } + } + } + + while (exit_flag == 0 && sleep_count < 30) { + EM_DEBUG_LOG("Sleeping..."); + usleep(100000); + EM_DEBUG_LOG("Wake up!"); + sleep_count++; + exit_flag = 1; + for (i = 0 ; i < event_count; i++) { + if (g_event_que[i].type && g_event_que[i].status != EMF_EVENT_STATUS_UNUSED) { + EM_DEBUG_LOG("There is still a live thread. %d", i); + if (g_event_que[i].account_id == account_id || g_event_que[i].account_id == ALL_ACCOUNT) { + EM_DEBUG_LOG("And it is for account %d. So, I should sleep for a while.", g_event_que[i].account_id); + exit_flag = 0; + } + } + } + } + + EM_DEBUG_LOG("Sleep count %d", sleep_count); + + if (sleep_count >= 30) + error_code = EMF_ERROR_CANNOT_STOP_THREAD; + else + error_code = EMF_ERROR_NONE; + EM_DEBUG_FUNC_END(); + return error_code; +} + +/* check thread status +* 0 : stop job 1 : continue job +*/ +EXPORT_API int em_core_check_send_mail_thread_status() +{ + EM_DEBUG_FUNC_BEGIN(); + + if (g_send_active_que <= 0) + return true; + EM_DEBUG_LOG("g_send_event_que[g_send_active_que[%d]].status[%d]", g_send_active_que, g_send_event_que[g_send_active_que].status); + EM_DEBUG_FUNC_END(); + return (g_send_event_que[g_send_active_que].status == EMF_EVENT_STATUS_STARTED); +} + + +/* cancel send mail job */ +EXPORT_API int em_core_cancel_send_mail_thread(int handle, void *arg, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("handle[%d], arg[%p], err_code[%p]", handle, arg, err_code); + + int ret = false; + int err = EMF_ERROR_NONE; + + if (handle <= 0 || handle > (EVENT_QUEUE_MAX - 1)) { + EM_DEBUG_EXCEPTION("handle[%d], arg[%p]", handle, arg); + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + ENTER_RECURSIVE_CRITICAL_SECTION(_send_event_queue_lock); + + EM_DEBUG_LOG("event_data.status[%d], handle[%d]", g_send_event_que[handle].status, handle); + + if (g_send_event_que[handle].status == EMF_EVENT_STATUS_WAIT) { + fail_status_notify(&g_send_event_que[handle], EMF_ERROR_CANCELLED); + + switch (g_send_event_que[handle].type) { + case EMF_EVENT_SEND_MAIL: + case EMF_EVENT_SEND_MAIL_SAVED: + _sending_busy_unref(); + g_send_event_que[handle].status = EMF_EVENT_STATUS_CANCELED; + if (!em_storage_notify_network_event(NOTI_SEND_CANCEL, g_send_event_que[handle].account_id, NULL , g_send_event_que[handle].event_param_data_4, err)) + EM_DEBUG_EXCEPTION(" em_storage_notify_network_event [ NOTI_SEND_CANCEL] Failed >>>> "); + break; + default: + break; + } + } + + EM_DEBUG_LOG("send_mail_cancel"); + memset(g_send_event_que+handle, 0x00, sizeof(emf_event_t)); + g_send_event_que[handle].status = EMF_EVENT_STATUS_CANCELED; + + EM_DEBUG_LOG("event_data.status[%d], handle[%d]", g_send_event_que[handle].status, handle); + + + LEAVE_RECURSIVE_CRITICAL_SECTION(_send_event_queue_lock); + + ret = true; + +FINISH_OFF: + if (err_code != NULL) + *err_code = err; + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + + +EXPORT_API int em_core_get_receiving_event_queue(emf_event_t **event_queue, int *event_active_queue, int *err) +{ + if (event_queue == NULL || event_active_queue == NULL) { + EM_DEBUG_EXCEPTION("EMF_ERROR_INVALID_PARAM event_queue[%p] event_active_queue[%p]", event_queue, event_active_queue); + + if (err) + *err = EMF_ERROR_INVALID_PARAM; + + return false; + } + + *event_queue = g_event_que; + *event_active_queue = g_active_que; + + return true; +} + +EXPORT_API int em_core_free_event(emf_event_t *event_data) +{ + EM_DEBUG_FUNC_BEGIN("event_data [%p]", event_data); + + if(event_data) { + EM_SAFE_FREE(event_data->event_param_data_1); + EM_SAFE_FREE(event_data->event_param_data_2); + EM_SAFE_FREE(event_data->event_param_data_3); + } + + EM_DEBUG_FUNC_END(); + return true; +} + +#ifdef _CONTACT_SUBSCRIBE_CHANGE_ +static int g_last_sync_time = 0; + +EXPORT_API int em_core_init_last_sync_time(void) +{ + EM_DEBUG_FUNC_BEGIN(); + return em_core_get_last_sync_time(); +} + +EXPORT_API int em_core_set_last_sync_time(int sync_time) +{ + EM_DEBUG_FUNC_BEGIN(); + int ret; + + if (sync_time == 0) + g_last_sync_time = time(NULL); + else + g_last_sync_time = sync_time; + + ret = vconf_set_int(VCONF_KEY_LAST_SYNC_TIME, g_last_sync_time); + if (ret != 0) { + EM_DEBUG_EXCEPTION("vconf_set_int() Failed(%d)", ret); + } + + return g_last_sync_time; +} + +EXPORT_API int em_core_get_last_sync_time(void) +{ + EM_DEBUG_FUNC_BEGIN(); + int ret; + if (g_last_sync_time == 0) { + ret = vconf_get_int(VCONF_KEY_LAST_SYNC_TIME, &g_last_sync_time); + if (ret < 0) { + EM_DEBUG_EXCEPTION("vconf_get_int() Failed(%d)", ret); + g_last_sync_time = 0; + } + } + + return g_last_sync_time; +} + +EXPORT_API int em_core_contact_sync_handler() +{ + EM_DEBUG_FUNC_BEGIN(); + + int ret = false; + int contact_ret; + int err = EMF_ERROR_NONE; + CTSiter iter; + int type; + int change_time; + int created_time; + + int contact_index; + char *display_name = NULL; + CTSstruct *contact = NULL; + CTSvalue *base = NULL; + CTSvalue *row_info = NULL; + CTSvalue *contact_name_value = NULL; + GSList *email_list = NULL; + + int last_sync_time = em_core_get_last_sync_time(); + + EM_DEBUG_LOG("last_sync_time[%d]", last_sync_time); + + if (em_storage_begin_transaction(NULL, NULL, &err) == false) { + EM_DEBUG_EXCEPTION("em_storage_begin_transaction() error[%d]", err); + goto FINISH_OFF; + } + + if ((err = contacts_svc_get_updated_contacts(0, last_sync_time, &iter)) != CTS_SUCCESS) { + EM_DEBUG_EXCEPTION("contacts_svc_get_updated_contacts() error[%d]", err); + goto FINISH_OFF; + } + contact_ret = contacts_svc_iter_next(iter); + while (CTS_SUCCESS == contact_ret) { + contact = NULL; + base = NULL; + row_info = NULL; + contact_name_value = NULL; + email_list = NULL; + + if ((row_info = contacts_svc_iter_get_info(iter)) == NULL) { + EM_DEBUG_EXCEPTION("contacts_svc_iter_get_info() failed."); + } + else { /* sync */ + contact_index = contacts_svc_value_get_int(row_info, CTS_LIST_CHANGE_ID_INT); + type = contacts_svc_value_get_int(row_info, CTS_LIST_CHANGE_TYPE_INT); + change_time = contacts_svc_value_get_int(row_info, CTS_LIST_CHANGE_TIME_INT); + EM_DEBUG_LOG("Change ID[%d] Type[%d], change_time[%d]", contact_index, type, change_time); + + switch (type) { + case CTS_OPERATION_INSERTED: + case CTS_OPERATION_UPDATED: + EM_DEBUG_LOG("CTS_OPERATION_INSERTED or CTS_OPERATION_TYPE_UPDATED: [%d]", type); + if ((err = contacts_svc_get_contact(contact_index, &contact)) < 0) { + EM_DEBUG_LOG("contacts_svc_get_contact() failed. err[%d]", err); + contacts_svc_iter_remove(iter); + goto FINISH_OFF; + } + if ((err = contacts_svc_struct_get_value(contact, CTS_CF_BASE_INFO_VALUE, &base)) < 0) { + EM_DEBUG_LOG("contacts_svc_struct_get_value() failed. CTS_CF_BASE_INFO_VALUE : err[%d]", err); + contacts_svc_iter_remove(iter); + goto FINISH_OFF; + } + created_time = contacts_svc_value_get_int(base, CTS_BASE_VAL_CREATED_TIME_INT); + + if ((err = contacts_svc_struct_get_value(contact, CTS_CF_NAME_VALUE, &contact_name_value)) < 0) { + EM_DEBUG_LOG("contacts_svc_struct_get_value() failed. CTS_CF_NAME_VALUE err[%d]", err); + contacts_svc_iter_remove(iter); + goto FINISH_OFF; + } + em_core_mail_get_display_name(contact_name_value, &display_name); + + err = contacts_svc_struct_get_list(contact, CTS_CF_EMAIL_LIST, &email_list); + if (err == CTS_ERR_NO_DATA) { + EM_DEBUG_LOG("contacts_svc_struct_get_list() : NO EMAIL LIST"); + break; + } + else if (err < 0) { + EM_DEBUG_LOG("contacts_svc_struct_get_list() failed. err[%d]", err); + contacts_svc_iter_remove(iter); + goto FINISH_OFF; + } + + /* contact id, display name, email list */ + /* if (created_time >= last_sync_time) */ + if (type == CTS_OPERATION_INSERTED) { + EM_DEBUG_LOG("Contact Added Time : %d", change_time); + if (em_storage_contact_sync_insert(contact_index, display_name, email_list, &err) == false) { + EM_DEBUG_LOG("em_storage_contact_sync_insert() failed. err[%d]", err); + contacts_svc_iter_remove(iter); + goto FINISH_OFF; + } + } + else if (type == CTS_OPERATION_UPDATED) { + EM_DEBUG_LOG("Contact Updated Time : %d", change_time); + if (em_storage_contact_sync_update(contact_index, display_name, email_list, &err) == false) { + EM_DEBUG_LOG("em_storage_contact_sync_update() failed. err[%d]", err); + contacts_svc_iter_remove(iter); + goto FINISH_OFF; + } + } + contacts_svc_struct_free(contact); + contact = NULL; + EM_SAFE_FREE(display_name); + break; + case CTS_OPERATION_DELETED: + EM_DEBUG_LOG("CTS_OPERATION_TYPE_DELETED"); + if (em_storage_contact_sync_delete(contact_index, &err) == false) { + EM_DEBUG_LOG("em_storage_contact_sync_delete() failed. err[%d]", err); + contacts_svc_iter_remove(iter); + goto FINISH_OFF; + } + break; + default: + EM_DEBUG_EXCEPTION("Unknown CTS OPERATION [%d]", type); + break; + } + } + + /* Next changing */ + contacts_svc_value_free(row_info); + row_info = NULL; + contact_ret = contacts_svc_iter_next(iter); + } + + ret = true; +FINISH_OFF: + if (ret == true) { + if (em_storage_commit_transaction(NULL, NULL, NULL) == false) + ret = false; + else + em_core_set_last_sync_time(change_time); /* save changed time */ + } + else { + em_storage_rollback_transaction(NULL, NULL, NULL); + } + + if (row_info != NULL) + contacts_svc_value_free(row_info); + if (contact != NULL) + contacts_svc_struct_free(contact); + + return ret; +} + +#endif /* _CONTACT_SUBSCRIBE_CHANGE_ */ + + + +#ifdef __FEATURE_KEEP_CONNECTION__ + +EXPORT_API unsigned int em_core_get_receiving_thd_id() +{ + return (unsigned int)g_srv_thread; +} + +#endif /* __FEATURE_KEEP_CONNECTION__ */ + + + +#ifdef __FEATURE_PARTIAL_BODY_DOWNLOAD__ + +EXPORT_API int em_core_get_pbd_thd_state() +{ + int pbd_thd_state = false; + ENTER_CRITICAL_SECTION(_state_variables_lock); + pbd_thd_state = g_pbd_thd_state; + LEAVE_CRITICAL_SECTION(_state_variables_lock); + return pbd_thd_state; +} + +static int em_core_set_pbd_thd_state(int flag) +{ + ENTER_CRITICAL_SECTION(_state_variables_lock); + g_pbd_thd_state = flag; + LEAVE_CRITICAL_SECTION(_state_variables_lock); + + return g_pbd_thd_state; +} + +EXPORT_API unsigned int em_core_get_partial_body_thd_id() +{ + EM_DEBUG_FUNC_BEGIN(); + EM_DEBUG_FUNC_END(); + return (unsigned int)g_partial_body_thd; +} + +static int em_core_clear_bulk_pbd_que(int *err_code) +{ + EM_DEBUG_FUNC_BEGIN(); + + int ret = true; + int error = EMF_ERROR_NONE; + int i = 0; + + for (i = 0; i < BULK_PARTIAL_BODY_DOWNLOAD_COUNT; ++i) { + if (g_partial_body_bulk_dwd_que[i].event_type) { + if (false == em_core_free_partial_body_thd_event(g_partial_body_bulk_dwd_que + i, &error)) { + EM_DEBUG_EXCEPTION("em_core_free_partial_body_thd_event_cell failed [%d]", error); + ret = false; + break; + } + } + } + + if (NULL != err_code) + *err_code = error; + EM_DEBUG_FUNC_END(); + return ret; +} + +static void em_core_pb_thd_set_local_activity_continue(int flag) +{ + EM_DEBUG_FUNC_BEGIN("flag [%d]", flag); + + ENTER_CRITICAL_SECTION(_partial_body_thd_event_queue_lock); + + g_pb_thd_local_activity_continue = flag; + + if (true == flag) { + WAKE_CONDITION_VARIABLE(_partial_body_thd_cond); + } + + LEAVE_CRITICAL_SECTION(_partial_body_thd_event_queue_lock); + EM_DEBUG_FUNC_END(); +} + +static +int em_core_pb_thd_can_local_activity_continue() +{ + EM_DEBUG_FUNC_BEGIN(); + + int ret = false; + + ENTER_CRITICAL_SECTION(_partial_body_thd_event_queue_lock); + + ret = g_pb_thd_local_activity_continue; + + LEAVE_CRITICAL_SECTION(_partial_body_thd_event_queue_lock); + EM_DEBUG_FUNC_END(); + return ret; + +} + +EXPORT_API int em_core_clear_partial_body_thd_event_que(int *err_code) +{ + EM_DEBUG_FUNC_BEGIN(); + + int ret = true; + int error = EMF_ERROR_NONE; + int i = 0; + + ENTER_CRITICAL_SECTION(_partial_body_thd_event_queue_lock); + + if (true == g_partial_body_thd_queue_empty) { + EM_DEBUG_LOG(" Partial Body Thread Event Queue Already empty "); + } + else { + for (i = 0; i < TOTAL_PARTIAL_BODY_EVENTS; ++i) { + if (g_partial_body_thd_event_que[i].event_type) { + if (false == em_core_free_partial_body_thd_event(g_partial_body_thd_event_que + i, &error)) { + EM_DEBUG_EXCEPTION("em_core_free_partial_body_thd_event_cell failed [%d]", error); + ret = false; + break; + } + } + } + + g_partial_body_thd_queue_empty = true; + g_partial_body_thd_queue_full = false; + } + LEAVE_CRITICAL_SECTION(_partial_body_thd_event_queue_lock); + + if (NULL != err_code) + *err_code = error; + EM_DEBUG_FUNC_END(); + return ret; +} + +EXPORT_API int em_core_is_partial_body_thd_que_empty() +{ + EM_DEBUG_FUNC_BEGIN(); + + int ret = false; + + ENTER_CRITICAL_SECTION(_partial_body_thd_event_queue_lock); + + ret = g_partial_body_thd_queue_empty; + + LEAVE_CRITICAL_SECTION(_partial_body_thd_event_queue_lock); + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} +EXPORT_API int em_core_is_partial_body_thd_que_full() +{ + EM_DEBUG_FUNC_BEGIN(); + + int ret = false; + + ENTER_CRITICAL_SECTION(_partial_body_thd_event_queue_lock); + + ret = g_partial_body_thd_queue_full; + + LEAVE_CRITICAL_SECTION(_partial_body_thd_event_queue_lock); + EM_DEBUG_FUNC_END(); + return ret; +} + +/* +Himanshu[h.gahalut] : If either src pointer or dest pointer points to a cell of global partial body thread event_data queue, +then em_core_copy_partial_body_thd_event API should only be called from a portion of code which is protected +through _partial_body_thd_event_queue_lock mutex. + +No mutex is used inside this API so that we can also use it to copy partial body events which are not a part of global event_data queue + +Precautions : + +_partial_body_thd_event_queue_lock mutex should never be used inside this API otherwise it will be a deadlock. +Also never call any function from this API which uses _partial_body_thd_event_queue_lock mutex. + +*/ + +static int em_core_copy_partial_body_thd_event(emf_event_partial_body_thd *src, emf_event_partial_body_thd *dest, int *error_code) +{ + EM_DEBUG_FUNC_BEGIN(); + int error = EMF_ERROR_NONE; + int ret = false; + + if (NULL == src || NULL == dest) { + EM_DEBUG_LOG(" Invalid Parameter src [%p] dest [%p]", src, dest); + error = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + dest->account_id = src->account_id; + dest->mail_id = src->mail_id; + dest->server_mail_id = src->server_mail_id; + dest->activity_id = src->activity_id; + dest->mailbox_name = EM_SAFE_STRDUP(src->mailbox_name); + dest->activity_type = src->activity_type; + dest->event_type = src->event_type; + + EM_DEBUG_LOG("dest->account_id[%d], dest->mail_id[%d], dest->server_mail_id [%lu]", dest->account_id, dest->mail_id , dest->server_mail_id); + + ret = true; + + FINISH_OFF: + + if (NULL != error_code) + *error_code = error; + + return ret; + +} + +/* +Himanshu[h.gahalut] : If em_core_free_partial_body_thd_event_cell API is used to free a cell of partial body thread event_data queue, +it should only be called from a portion of code which is protected through _partial_body_thd_event_queue_lock mutex. + +No mutex is used inside this API so that we can also use it to free partial body events which are not a part of global event_data queue + +Precautions : + +_partial_body_thd_event_queue_lock mutex should never be used inside this API otherwise it will be a deadlock. +Also never call any function from this API which uses _partial_body_thd_event_queue_lock mutex. + +*/ + +EXPORT_API int em_core_free_partial_body_thd_event(emf_event_partial_body_thd *partial_body_thd_event, int *error_code) +{ + EM_DEBUG_FUNC_BEGIN(); + + if (NULL == partial_body_thd_event) { + *error_code = EMF_ERROR_INVALID_PARAM; + return false; + } + + emf_event_partial_body_thd *pbd_event = partial_body_thd_event; + + /*Free character pointers in event_data cell */ + EM_SAFE_FREE(pbd_event->mailbox_name); + memset(pbd_event, 0x00, sizeof(emf_event_partial_body_thd)); + EM_DEBUG_FUNC_END(); + return true; +} + +EXPORT_API int em_core_insert_partial_body_thread_event(emf_event_partial_body_thd *partial_body_thd_event, int *error_code) +{ + EM_DEBUG_FUNC_BEGIN(); + + if (NULL == partial_body_thd_event) { + EM_DEBUG_EXCEPTION("\t partial_body_thd_event [%p] ", partial_body_thd_event); + + if (error_code != NULL) { + *error_code = EMF_ERROR_INVALID_PARAM; + } + return false; + } + + int ret = false; + int error = EMF_ERROR_NONE; + int empty_cell_index = -1; + int index = 0; + int count = 0; + + ENTER_CRITICAL_SECTION(_partial_body_thd_event_queue_lock); + + /* find a cell in queue which is empty */ + + for (count = 0, index = g_partial_body_thd_next_event_idx; count < TOTAL_PARTIAL_BODY_EVENTS;) { + if (g_partial_body_thd_event_que[index].event_type) { + ++index; + ++count; + + if (index == TOTAL_PARTIAL_BODY_EVENTS) { + index = 0; + } + } + else { + /*Found empty Cell*/ + + empty_cell_index = index; + break; + } + } + + if (-1 != empty_cell_index) { + if (false == em_core_copy_partial_body_thd_event(partial_body_thd_event, g_partial_body_thd_event_que+empty_cell_index , &error)) { + EM_DEBUG_LOG("em_core_copy_partial_body_thd_event failed [%d]", error); + } + else { + g_partial_body_thd_queue_empty = false; + + if (count == (TOTAL_PARTIAL_BODY_EVENTS - 1)) { + /*This is the last event_data inserted in queue after its insertion, queue is full */ + g_partial_body_thd_queue_full = true; + + } + + WAKE_CONDITION_VARIABLE(_partial_body_thd_cond); + + ret = true; + } + } + else { + EM_DEBUG_LOG(" partial body thread event_data queue is full "); + error = EMF_ERROR_EVENT_QUEUE_FULL; + + g_partial_body_thd_queue_full = true; + g_partial_body_thd_queue_empty = false; + + } + + LEAVE_CRITICAL_SECTION(_partial_body_thd_event_queue_lock); + + if (NULL != error_code) { + *error_code = error; + } + + return ret; + +} + +/* h.gahlaut : Return true only if event_data is retrieved successfully */ + +static int em_core_retrieve_partial_body_thread_event(emf_event_partial_body_thd *partial_body_thd_event, int *error_code) +{ + EM_DEBUG_FUNC_BEGIN(); + + int ret = false; + int error = EMF_ERROR_NONE; + int index = 0; + + /* Lock Mutex to protect event_data queue and associated global variables variables*/ + + ENTER_CRITICAL_SECTION(_partial_body_thd_event_queue_lock); + + index = g_partial_body_thd_next_event_idx; + + if (0 == g_partial_body_thd_event_que[index].event_type) { + error = EMF_ERROR_EVENT_QUEUE_EMPTY; + g_partial_body_thd_queue_empty = true; + g_partial_body_thd_queue_full = false; + } + else { + /*Copy the event_data from queue to return it and free the event_data in queue */ + if (false == em_core_copy_partial_body_thd_event(g_partial_body_thd_event_que + index, partial_body_thd_event, &error)) + EM_DEBUG_EXCEPTION("em_core_copy_partial_body_thd_event failed [%d]", error); + else { + if (false == em_core_free_partial_body_thd_event(g_partial_body_thd_event_que + index, &error)) + EM_DEBUG_EXCEPTION("em_core_free_partial_body_thd_event_cell failed [%d]", error); + else { + + g_partial_body_thd_queue_full = false; + g_partial_body_thd_next_event_idx = ++index; + + if (g_partial_body_thd_next_event_idx == TOTAL_PARTIAL_BODY_EVENTS) + g_partial_body_thd_next_event_idx = 0; + + /* If the event_data retrieved was the only event_data present in queue, + we need to set g_partial_body_thd_queue_empty to true + */ + + if (0 == g_partial_body_thd_event_que[g_partial_body_thd_next_event_idx].event_type) { + g_partial_body_thd_queue_empty = true; + } + + ret = true; + } + } + } + + /* Unlock Mutex */ + + LEAVE_CRITICAL_SECTION(_partial_body_thd_event_queue_lock); + + if (error_code) + *error_code = error; + + return ret; + +} + +gpointer partial_body_download_thread(gpointer data) +{ + EM_DEBUG_FUNC_BEGIN(); + + int err = EMF_ERROR_NONE; + emf_session_t *session = NULL; + emf_event_partial_body_thd partial_body_thd_event; + + EM_DEBUG_LOG(" ************ PB THREAD ID IS ALIVE. ID IS [%d] ********************" , THREAD_SELF()); + + /* Open connection with DB */ + + if (false == em_storage_open(&err)) { + EM_DEBUG_EXCEPTION("em_storage_open failed [%d]", err); + return false; + } + + /* Start the continuous loop */ + + while (g_partial_body_thd_loop) { + /* Get an empty session */ + /* TODO : Mutex should be used in session APIs */ + + if (false == em_core_get_empty_session(&session)) + EM_DEBUG_EXCEPTION("em_core_get_empty_session failed..."); + else { /* Get and Event from the Partial Body thread Event Queue */ + memset(&partial_body_thd_event, 0x00, sizeof(emf_event_partial_body_thd)); + + if (false == em_core_retrieve_partial_body_thread_event(&partial_body_thd_event, &err)) { + if (EMF_ERROR_EVENT_QUEUE_EMPTY != err) + EM_DEBUG_EXCEPTION("em_core_retrieve_partial_body_thread_event failed [%d]", err); + else { + EM_DEBUG_LOG(" partial body thread event_data queue is empty."); + + /* Flush the que before starting local activity sync to clear the events in queue which are less than 10 in count */ + if (!g_partial_body_bulk_dwd_queue_empty) { + partial_body_thd_event.event_type = 0; + partial_body_thd_event.account_id = g_partial_body_bulk_dwd_que[0].account_id; + partial_body_thd_event.mailbox_name = EM_SAFE_STRDUP(g_partial_body_bulk_dwd_que[0].mailbox_name); + + if (false == em_core_mail_partial_body_download(&partial_body_thd_event, &err)) + EM_DEBUG_EXCEPTION("em_core_mail_partial_body_download from event_data queue failed [%d]", err); + + em_core_pb_thd_set_local_activity_continue(true); + } + + if (true == em_core_pb_thd_can_local_activity_continue()) { + /*Check for local Activities */ + int is_local_activity_event_inserted = false; + + if (false == em_core_partial_body_thd_local_activity_sync(&is_local_activity_event_inserted, &err)) { + EM_DEBUG_EXCEPTION("em_core_partial_body_thd_local_activity_sync failed [%d]", err); + } + else { + if (true == is_local_activity_event_inserted) { + em_core_pb_thd_set_local_activity_continue(false); + + em_core_clear_session(session); + continue; + } + } + } + + EM_DEBUG_LOG(" Partial Body Thread is going to sleep"); + + em_core_set_pbd_thd_state(false); + + ENTER_CRITICAL_SECTION(_partial_body_thd_event_queue_lock); + SLEEP_CONDITION_VARIABLE(_partial_body_thd_cond, _partial_body_thd_event_queue_lock); + LEAVE_CRITICAL_SECTION(_partial_body_thd_event_queue_lock); + + EM_DEBUG_LOG(" Partial Body Thread wakes up "); + + em_core_set_pbd_thd_state(true); + } + + } + else { + EM_DEBUG_LOG(" Event Received from Partial Body Event Queue "); + + /* Since all events are network operations dnet init and sleep control is + done before entering switch block*/ + + em_storage_dimming_on_off(false, NULL); + + if (!em_core_check_network_status( &err)) { + EM_DEBUG_EXCEPTION("em_core_check_network_status failed [%d]", err);; + } + else { + /* Process events */ + EM_DEBUG_LOG("partial_body_thd_event.account_id[%d]", partial_body_thd_event.account_id); + + switch (partial_body_thd_event.event_type) { + case EMF_EVENT_BULK_PARTIAL_BODY_DOWNLOAD: { + if (false == em_core_mail_partial_body_download(&partial_body_thd_event, &err)) { + EM_DEBUG_EXCEPTION("em_core_mail_partial_body_download from event_data queue failed [%d]", err); + } + break; + } + case EMF_EVENT_LOCAL_ACTIVITY_SYNC_BULK_PBD: { + partial_body_thd_event.event_type = 0; + + /* Both the checks below make sure that before starting local activity there is no new/pending event_data in + * g_partial_body_thd_event_que and g_partial_body_bulk_dwd_que */ + if (false == em_core_is_partial_body_thd_que_empty()) + break; + if (!g_partial_body_bulk_dwd_queue_empty) + break; + + if (false == em_core_mail_partial_body_download(&partial_body_thd_event, &err)) + EM_DEBUG_EXCEPTION("em_core_mail_partial_body_download from activity table failed [%d]", err); + break; + } + default: + EM_DEBUG_EXCEPTION(" Warning : Default case entered. This should not happen "); + break; + } + } + + if (false == em_core_free_partial_body_thd_event(&partial_body_thd_event, &err)) + EM_DEBUG_EXCEPTION("em_core_free_partial_body_thd_event_cell failed [%d]", err); + + em_storage_dimming_on_off(true, NULL); + } + + em_core_clear_session(session); + } + } + + /* If something is added to end thread in future for any case then if thread is holding any resources + define a function em_core_partial_body_thd_loop_stop to release resources and call it + here to end thread */ + return SUCCESS; +} + +EXPORT_API int em_core_partial_body_thread_loop_start(int *err_code) +{ + EM_DEBUG_FUNC_BEGIN(); + + int i = 0, thread_error = -1; + + /* Clear Partial Body Event Queue*/ + memset(&g_partial_body_thd_event_que, 0x00, sizeof(g_partial_body_thd_event_que)); + + for (i = 0; i < TOTAL_PARTIAL_BODY_EVENTS; ++i) + g_partial_body_thd_event_que[i].mailbox_name = NULL; + + if (g_partial_body_thd) { + EM_DEBUG_EXCEPTION("partial body thread is already running..."); + if (err_code != NULL) + *err_code = EMF_ERROR_UNKNOWN; + + return true; + } + + g_partial_body_thd_next_event_idx = 0; + g_partial_body_thd_loop = 1; + g_partial_body_thd_queue_empty = true; + g_partial_body_thd_queue_full = false; + + INITIALIZE_CONDITION_VARIABLE(_partial_body_thd_cond); + + /* create thread */ + /* THREAD_CREATE_JOINABLE(g_partial_body_thd, partial_body_download_thread, thread_error); */ + THREAD_CREATE(g_partial_body_thd, partial_body_download_thread, NULL, thread_error); + + if (thread_error != 0) { + EM_DEBUG_EXCEPTION("cannot make thread..."); + if (err_code != NULL) + *err_code = EMF_ERROR_UNKNOWN; + return FAILURE; + } + + if (err_code != NULL) + *err_code = EMF_ERROR_NONE; + + return false; + +} + +/*Function to flush the bulk partial body download queue [santosh.br@samsung.com]*/ +static int em_core_partial_body_bulk_flush(int *error_code) +{ + EM_DEBUG_FUNC_BEGIN(); + int error = EMF_ERROR_NONE; + int ret = false; + MAILSTREAM *stream = NULL; + void *tmp_stream = NULL; + + if (!em_core_mailbox_open(g_partial_body_bulk_dwd_que[0].account_id, g_partial_body_bulk_dwd_que[0].mailbox_name, (void **)&tmp_stream, &error) || (NULL == tmp_stream)) { + EM_DEBUG_EXCEPTION("em_core_mailbox_open failed [%d]", error); + goto FINISH_OFF; + } + stream = (MAILSTREAM *)tmp_stream; + + /* Call bulk download here */ + if (false == em_core_bulk_partial_mailbody_download(stream, g_partial_body_bulk_dwd_que, g_partial_body_bulk_dwd_next_event_idx, &error)) { + EM_DEBUG_EXCEPTION(" em_core_bulk_partial_mailbody_download failed.. [%d]", error); + goto FINISH_OFF; + } + + ret = true; +FINISH_OFF: + + em_core_mailbox_close(0, stream); + stream = NULL; + + g_partial_body_bulk_dwd_next_event_idx = 0; + g_partial_body_bulk_dwd_queue_empty = true; + + if (false == em_core_clear_bulk_pbd_que(&error)) + EM_DEBUG_EXCEPTION("em_core_clear_bulk_pbd_que failed [%d]", error); + + if (NULL != error_code) + *error_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + + +/* Function to pass UID list and Data for bulk partial body download [santosh.br@samsung.com]/[h.gahlaut@samsung.com] */ +EXPORT_API int em_core_mail_partial_body_download(emf_event_partial_body_thd *pbd_event, int *error_code) +{ + EM_DEBUG_FUNC_BEGIN(); + int error = EMF_ERROR_NONE; + int num_activity = 0; + int ret = false; + int count = 0; + int i = 0, m = 0; + MAILSTREAM *stream = NULL; + void *tmp_stream = NULL; + emf_event_partial_body_thd *activity_data_list = NULL; + char **mailbox_list = NULL; + + if (NULL == pbd_event) + { + EM_DEBUG_EXCEPTION("Invalid Parameter pbd_event [%p] ", pbd_event); + + error = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + /*Check if the event_data is to flush the event_data que array */ + if (EMF_EVENT_BULK_PARTIAL_BODY_DOWNLOAD == pbd_event->event_type) { + EM_DEBUG_LOG("pbd_event->event_type is EMF_EVENT_BULK_PARTIAL_BODY_DOWNLOAD"); + /*Check if the mailbox name and account id for this event_data is same as the mailbox name and account id for earlier events saved in download que array + then append this event_data also to download que array */ + if ((NULL != g_partial_body_bulk_dwd_que[0].mailbox_name) && (0 == strncmp(g_partial_body_bulk_dwd_que[0].mailbox_name, pbd_event->mailbox_name, strlen(g_partial_body_bulk_dwd_que[0].mailbox_name))) && \ + (g_partial_body_bulk_dwd_que[0].account_id == pbd_event->account_id)) { + EM_DEBUG_LOG("Event is for the same mailbox and same account as the already present events in download que"); + EM_DEBUG_LOG("Check if the download que reached its limit. If yes then first flush the que."); + if (g_partial_body_bulk_dwd_next_event_idx == BULK_PARTIAL_BODY_DOWNLOAD_COUNT) { + if (false == em_core_partial_body_bulk_flush(&error)) { + EM_DEBUG_EXCEPTION("Partial Body thread em_core_partial_body_bulk_flush failed - %d", error); + goto FINISH_OFF; + } + } + } + else { + EM_DEBUG_LOG("Event is not for the same mailbox and same account as the already present events in download que"); + EM_DEBUG_LOG("Flush the current que if not empty"); + EM_DEBUG_LOG("g_partial_body_bulk_dwd_queue_empty [%d]", g_partial_body_bulk_dwd_queue_empty); + if (!g_partial_body_bulk_dwd_queue_empty) { + if (false == em_core_partial_body_bulk_flush(&error)) { + EM_DEBUG_EXCEPTION("Partial Body thread em_core_partial_body_bulk_flush failed - %d", error); + goto FINISH_OFF; + } + } + } + /*Add the event_data to the download que array */ + if (false == em_core_copy_partial_body_thd_event(pbd_event, g_partial_body_bulk_dwd_que+(g_partial_body_bulk_dwd_next_event_idx), &error)) + EM_DEBUG_EXCEPTION("\t Partial Body thread em_core_copy_partial_body_thd_event failed - %d", error); + else { + g_partial_body_bulk_dwd_queue_empty = false; + g_partial_body_bulk_dwd_next_event_idx++; + EM_DEBUG_LOG("g_partial_body_bulk_dwd_next_event_idx [%d]", g_partial_body_bulk_dwd_next_event_idx); + } + } + else if (pbd_event->activity_type) { + int *account_list = NULL; + int account_count = 0; + + EM_DEBUG_LOG("Event is coming from local activity."); + /* Get all the accounts for which local activities are pending */ + if (false == em_storage_get_pbd_account_list(&account_list, &account_count, false, &error)) { + EM_DEBUG_EXCEPTION(" em_storage_get_mailbox_list failed.. [%d]", error); + error = EMF_ERROR_MAILBOX_NOT_FOUND; + goto FINISH_OFF; + } + + for (m = 0; m < account_count; ++m) { + /* Get the mailbox list for the account to start bulk partial body fetch for mails in each mailbox of accounts one by one*/ + if (false == em_storage_get_pbd_mailbox_list(account_list[m], &mailbox_list, &count, false, &error)) { + EM_DEBUG_EXCEPTION(" em_storage_get_mailbox_list failed.. [%d]", error); + error = EMF_ERROR_MAILBOX_NOT_FOUND; + goto FINISH_OFF; + } + + for (i = 0; i < count; i++) { + int k = 0; + int activity_count = 0; + + if (!em_core_mailbox_open(account_list[m], mailbox_list[i], (void **)&tmp_stream, &error)) { + EM_DEBUG_EXCEPTION("em_core_mailbox_open failed [%d]", error); + stream = NULL; + goto FINISH_OFF; + } + + stream = (MAILSTREAM *)tmp_stream; + + if (false == em_storage_get_mailbox_pbd_activity_count(account_list[m], mailbox_list[i], &activity_count, false, &error)) { + EM_DEBUG_EXCEPTION(" em_storage_get_mailbox_pbd_activity_count failed.. [%d]", error); + continue; + } + + if (activity_count > 0) { + int temp_error = EMF_ERROR_NONE; + int j = 0; + int iter = 0; + int remainder = 0; + int num = BULK_PARTIAL_BODY_DOWNLOAD_COUNT; + int index = 0; + + if (false == em_storage_get_pbd_activity_data(account_list[j], mailbox_list[i], &activity_data_list, &num_activity, false, &error)) + EM_DEBUG_EXCEPTION(" em_storage_get_pbd_activity_data failed.. [%d]", error); + + if (NULL == activity_data_list) { + EM_DEBUG_EXCEPTION(" activity_data_list is null.."); + continue; + } + + remainder = num_activity%BULK_PARTIAL_BODY_DOWNLOAD_COUNT; + iter = num_activity/BULK_PARTIAL_BODY_DOWNLOAD_COUNT + ((num_activity%BULK_PARTIAL_BODY_DOWNLOAD_COUNT) ? 1 : 0); + + for (j = 0; j < iter; j++) { + if ((iter == (j+1)) && (remainder != 0)) + num = remainder; + + /*Call bulk download here */ + if (false == em_core_bulk_partial_mailbody_download(stream, activity_data_list+index, num, &error)) { + EM_DEBUG_EXCEPTION(" em_core_bulk_partial_mailbody_download failed.. [%d]", error); + temp_error = EMF_ERROR_NO_RESPONSE; + } + + for (k = 0; k < num; k++) { + if (activity_data_list[index + k].activity_type) + em_core_free_partial_body_thd_event(activity_data_list + index + k, &error); + else + break; + } + index += num; + + if (false == em_core_is_partial_body_thd_que_empty()) { + ret = true; + goto FINISH_OFF; /* Stop Local Activity Sync */ + } + if (EMF_ERROR_NO_RESPONSE == temp_error) { + temp_error = EMF_ERROR_NONE; + break; + } + } + } + } + em_core_mailbox_close(0, stream); + stream = NULL; + tmp_stream = NULL; + } + + /* After completing one cycle of local activity sync , + local activity continue variable should be set to false. */ + + em_core_pb_thd_set_local_activity_continue(false); + } + else /* Event-type is 0 which means Event is to flush the que when no more events are present in g_partial_body_thd_event_que */ { + /*Check if events have arrived in g_partial_body_thd_event_que */ + if (false == em_core_is_partial_body_thd_que_empty()) { + EM_DEBUG_LOG("em_core_is_partial_body_thd_que_empty retured true"); + ret = true; + goto FINISH_OFF; /* Stop Local Activity Sync */ + } + if (false == em_core_partial_body_bulk_flush(&error)) { + EM_DEBUG_EXCEPTION("\t Partial Body thread em_core_partial_body_bulk_flush failed - %d", error); + goto FINISH_OFF; + } + } + + ret = true; + +FINISH_OFF: + + if (mailbox_list) { + for (i = 0; i < count; i++) + EM_SAFE_FREE(mailbox_list[i]); + EM_SAFE_FREE(mailbox_list); + } + + if (activity_data_list) { + for (i = 0; i < num_activity; i++) { + if (activity_data_list[i].activity_type) + em_core_free_partial_body_thd_event(activity_data_list + i, &error); + else + break; + } + } + + em_core_mailbox_close(0, stream); + stream = NULL; + + if (NULL != error_code) + *error_code = error; + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +#endif /* __FEATURE_PARTIAL_BODY_DOWNLOAD__ */ diff --git a/email-core/em-core-global.c b/email-core/em-core-global.c new file mode 100755 index 0000000..b4d522f --- /dev/null +++ b/email-core/em-core-global.c @@ -0,0 +1,53 @@ +/* +* email-service +* +* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. +* +* Contact: Kyuho Jo <kyuho.jo@samsung.com>, Sunghyun Kwon <sh0701.kwon@samsung.com> +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + + + +/****************************************************************************** + * File : em-core-global.c + * Desc : Mail Engine Global + * + * Auth : Kyuho Jo + * + * History : + * 2010.08.25 : created + *****************************************************************************/ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "emf-types.h" + + + +emf_account_t g_new_account; +emf_account_list_t *g_account_list = NULL; +int g_account_num = 0; +int g_account_retrieved = 0; + +EXPORT_API emf_account_t *em_core_account_get_new_account_ref() +{ + return &g_new_account; +} + + + + + diff --git a/email-core/em-core-imap-idle.c b/email-core/em-core-imap-idle.c new file mode 100755 index 0000000..2d06c9a --- /dev/null +++ b/email-core/em-core-imap-idle.c @@ -0,0 +1,648 @@ +/* +* email-service +* +* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. +* +* Contact: Kyuho Jo <kyuho.jo@samsung.com>, Sunghyun Kwon <sh0701.kwon@samsung.com> +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** + * + * This file contains functinality related to IMAP IDLE. + * to interact with Email Engine. + * @file em_core-imap-idle.c + * @author + * @version 0.1 + * @brief This file contains functionality to provide IMAP IDLE support in email-service. + */ + +#include <em-core-types.h> + +#ifdef _FEATURE_IMAP_IDLE +#include <pthread.h> +#include <glib.h> +#include <openssl/ssl.h> +#include "c-client.h" +#include "lnx_inc.h" +#include "em-core-imap-idle.h" +#include "emf-dbglog.h" +#include "em-storage.h" +#include "em-network.h" +#include "em-core-utils.h" +#include "em-core-mailbox.h" +#include "em-core-event.h" +#include "em-core-account.h" + +static int idle_pipe[2] = {0, 0}; + +static int wait_on_pipe(int *pipe_fd) +{ + fd_set rfds; + fd_set wfds; + struct timeval timeout_value; + int ret_value; + + FD_ZERO(&rfds); + FD_ZERO(&wfds); + FD_SET(pipe_fd[0], &rfds); + + EM_DEBUG_LOG("wait...till dnet fills some data in pipe - %d", pipe_fd[0]); + + /* timeout_value.tv_sec = 10; */ /* 10 seconds. */ + timeout_value.tv_sec = 180; /* 160 + a seconds. */ + timeout_value.tv_usec = 0; + EM_DEBUG_LOG("wait_on_pipe() : timeout_value (%d) sec, (%d) usec", timeout_value.tv_sec, timeout_value.tv_usec); + + ret_value = select(pipe_fd[0]+1, &rfds, &wfds, NULL, &timeout_value); + + switch (ret_value){ + case 0: + EM_DEBUG_LOG("wait_on_pipe() : select timer expired!!! "); + break; + case -1: + EM_DEBUG_LOG("wait_on_pipe() : There is an error on calling select. "); + break; + default: + EM_DEBUG_LOG("wait_on_pipe() : got response from DNET. "); + break; + } + + return ret_value; +} + +static int read_from_pipe(int *pipe_fd) +{ + int activation = 0; + + read(pipe_fd[0], &activation, sizeof(int)); + + return activation; +} + +static void write_to_pipe(int *pipe_fd, int result) +{ + write(pipe_fd[1], (char *)&result, sizeof(int)); +} + + +static void _idle_thread_cm_evt_cb(const NetEventInfo_t *event) +{ + EM_DEBUG_FUNC_BEGIN(); + + /* This callback will be called when any event is recd from datacom */ + + switch (event->Event) { + /* Response from Datacom for PDP Activation Request */ + case NET_EVENT_OPEN_RSP: + if (event->Error == NET_ERR_NONE) { /* Successful PDP Activation */ + EM_DEBUG_LOG("\t IMAP IDLE Successful PDP Activation"); + + NetDevInfo_t devInfo; + memset(&devInfo, 0x00, sizeof(devInfo)); + + if (net_get_device_info(&devInfo) != NET_ERR_NONE) + EM_DEBUG_EXCEPTION("\t net_get_device_info failed - %d", event->Error); + write_to_pipe(idle_pipe, 1); + } + else { /* PDP Activation failure */ + EM_DEBUG_EXCEPTION("\t PDP Activation Failure %d", event->Error); + write_to_pipe(idle_pipe, 0); + } + break; + + /* Response from Datacom for PDP Dectivation Request */ + case NET_EVENT_CLOSE_RSP: + if (event->Error == NET_ERR_NONE) { /* Successful PDP Dectivation */ + EM_DEBUG_LOG("\t Successful PDP DeActivation"); + + write_to_pipe(idle_pipe, 1); + } + else { /* PDP Dectivation failure */ + EM_DEBUG_EXCEPTION("\t PDP DeActivation Failure %d", event->Error); + + if (event->Error == NET_ERR_TRANSPORT) + { + /* TODO : add a process to deal an error */ + /* NetCMGetTransportError(&err_code); */ + } + + write_to_pipe(idle_pipe, 0); + } + break; + + case NET_EVENT_CLOSE_IND: + EM_DEBUG_LOG("NET_EVENT_CLOSE_IND recieved"); + break; + + case NET_EVENT_KILL_RSP: + break; + + case NET_EVENT_SUSPEND_IND: + /* TODO */ + /* think over what can we do... */ + break; + + case NET_EVENT_RESUME_IND: + /* TODO */ + /* think over what can we do... */ + break; + + default: + break; + } +} + + +/*Definitions copied temperorily from ssl_unix.c */ +#define SSLBUFLEN 8192 + +typedef struct ssl_stream { + TCPSTREAM *tcpstream; /* TCP stream */ + SSL_CTX *context; /* SSL context */ + SSL *con; /* SSL connection */ + int ictr; /* input counter */ + char *iptr; /* input pointer */ + char ibuf[SSLBUFLEN]; /* input buffer */ +} SSLSTREAM; +/*Definitions copied temperorily from ssl_unix.c - end*/ + +thread_t imap_idle_thread = NULL; +int g_imap_idle_thread_alive = 0; + + +int em_core_imap_idle_thread_create(int accountID, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN(); + int ret = false; + int thread_error = -1; + +#ifdef ENABLE_IMAP_IDLE_THREAD + + g_imap_idle_thread_alive = 1; + THREAD_CREATE(imap_idle_thread, em_core_imap_idle_run, NULL, thread_error); + if (thread_error != 0) + { + EM_DEBUG_EXCEPTION("cannot make IMAP IDLE thread..."); + if (err_code != NULL) + *err_code = EMF_ERROR_UNKNOWN; + g_imap_idle_thread_alive = 0; + goto FINISH_OFF; + } + + ret = true; +FINISH_OFF: + +#else /* ENABLE_IMAP_IDLE_THREAD */ + EM_DEBUG_LOG(">>>>>>>> DISABLED IMAP IDLE THREAD"); +#endif /* ENABLE_IMAP_IDLE_THREAD */ + + return ret; +} + +/* +Need to identify various scenarios where thread needs to be killed +1. After the timer set to 10 min expires. +2. When No sim, thread is created and em_core_check_network_status() fails. +*/ +int em_core_imap_idle_thread_kill(int *err_code) +{ + EM_DEBUG_FUNC_BEGIN(); + int ret = true; + int err = EMF_ERROR_NONE; + + EM_DEBUG_LOG(">>>>>>>>>>>>killing thread>>>>>>>>>"); + + /* kill the thread */ + EM_DEBUG_LOG(">>>>>>>>>Before g_thread_exit"); + g_imap_idle_thread_alive = 0; + EM_DEBUG_LOG(">>>>>>>>>After g_thread_exit"); + + EM_DEBUG_LOG(">>>>>>>>>>>>>>>>>> Making imap idle NULL>>>>>>>>>>>>>>>>>"); + imap_idle_thread = NULL; + EM_DEBUG_LOG(">>>>>>>>>>>>>>>>>> killed IMAP IDLE >>>>>>>>>>>>>>>>>"); + if (err_code) + *err_code = err; + return ret; +} + + + +int em_core_imap_idle_run(int accountID) +{ + EM_DEBUG_FUNC_BEGIN(); + char *mailbox_list[3]; /* Temperory - To be modified to char ***/ + int mailbox_num = 0; + emf_mailbox_t *mail_box_list = NULL; + emf_mailbox_t *curr_mailbox = NULL; + emf_mailbox_t *prev_mailbox = NULL; + int counter = 0; + emf_mailbox_tbl_t *local_mailbox = NULL; + int err = EMF_ERROR_NONE; + int flag = true; + int num = 0; + emf_session_t *session = NULL; + int ret = false; + + if ( !em_core_check_network_status(&err)) { + EM_DEBUG_EXCEPTION("em_core_check_network_status failed [%d]", err); + return ret; + } + /* Connect to DB */ + if (!em_storage_open(&err)) { + EM_DEBUG_EXCEPTION("\t em_storage_open falied - %d", err); + goto FINISH_OFF; + } + + if (!em_core_get_empty_session(&session)) + EM_DEBUG_EXCEPTION("\t em_core_get_empty_session failed..."); + + /* get the list of mailbox name on which IDLE notifications are required. */ + /* currently all INBOXES of all accounts need to be notified */ + /* Dependent on GetMyIdentities for account names */ + + /* For testing - mailbox_num and mailbox_list are hardcoded here */ + mailbox_num = 1; + mailbox_list[0] = EM_SAFE_STRDUP("INBOX"); + + /* make a list of mailboxes IDLING */ + for (counter = 0; counter < mailbox_num; counter++){ + EM_DEBUG_EXCEPTION(">>>> em_core_imap_idle_run 4 "); + if (!em_storage_get_mailbox_by_name(accountID, 0, mailbox_list[counter], &local_mailbox, true, &err)) { + EM_DEBUG_EXCEPTION("em_storage_get_mailbox_by_name failed - %d", err); + } + + else { + curr_mailbox = em_core_malloc(sizeof(emf_mailbox_t)); + + curr_mailbox->account_id = local_mailbox->account_id; + curr_mailbox->name = EM_SAFE_STRDUP(local_mailbox->mailbox_name); + curr_mailbox->local = local_mailbox->local_yn; + if (!em_core_imap_idle_connect_and_idle_on_mailbox(curr_mailbox, &err)) { + EM_DEBUG_EXCEPTION("em_core_imap_idle_connect_and_idle_on_mailbox failed - %d", err); + em_core_mailbox_free(&curr_mailbox, 1, NULL); + } + else { + if (flag) { + mail_box_list = curr_mailbox; + prev_mailbox = curr_mailbox; + flag = false; + num++; + } + + else { + prev_mailbox->next = curr_mailbox; + prev_mailbox = curr_mailbox; + num++; + } + + } + + } + if (local_mailbox != NULL) + em_storage_free_mailbox(&local_mailbox, 1, NULL); + + } + + em_core_clear_session(session); + + em_core_imap_idle_loop_start(mail_box_list, num, NULL); + + EM_DEBUG_EXCEPTION("IMAP IDLE "); + + ret = true; +FINISH_OFF: + if (!em_storage_close(&err)) { + EM_DEBUG_EXCEPTION("\t em_storage_close falied - %d", err); + } + + return ret; + +} + +int em_core_imap_idle_loop_start(emf_mailbox_t *mailbox_list, int num, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN(); + fd_set readfds; + int maxfd = 0; + int err = EMF_ERROR_NONE; + int counter = 0; + int select_result = 0; + int ret = false; + emf_mailbox_t *temp = NULL; + struct timeval timeout; + + EM_DEBUG_EXCEPTION(">>>>>>> em_core_imap_idle_loop_start start "); + if (!mailbox_list || !num) { + EM_DEBUG_EXCEPTION("\t mailbox_list[%p], num[%d]", mailbox_list, num); + + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + /* set timeout value to 10min */ + timeout.tv_sec = 10 * 60; + timeout.tv_usec = 0; + + /* IMAP IDLE LOOP */ + while (1){ + EM_DEBUG_EXCEPTION(">>>>>>>>>>>IDLING>>>>>>>>>>>>"); + FD_ZERO(&readfds); + temp = mailbox_list; + for (counter = 0; counter < num; counter++) { + FD_SET(temp->hold_connection, &readfds); + if (temp->hold_connection > maxfd) + maxfd = temp->hold_connection; + temp = temp->next; + } + maxfd++; + temp = mailbox_list; + + select_result = select(maxfd, &readfds, NULL, NULL, &timeout); + + if (select_result > 0) /* Data coming on some socket */ { + EM_DEBUG_EXCEPTION(">>>> Data Coming from Socket "); + for (counter = 0; counter < num; counter++) { + if (temp && FD_ISSET(temp->hold_connection, &readfds)) { + if (!em_core_imap_idle_parse_response_stream(temp, &err)) { + EM_DEBUG_EXCEPTION(">>>> em_core_imap_idle_loop_start 6 "); + em_core_mailbox_close(temp->account_id, temp->mail_stream); + EM_DEBUG_EXCEPTION(">>>> em_core_imap_idle_loop_start 7 "); + goto FINISH_OFF; + } + break; /* break for now - check if it is possible to get data on two sockets - shasikala.p */ + } + temp = temp->next; + } + } + + else if (select_result == 0) /* Timeout occured */ { + EM_DEBUG_EXCEPTION(">>>> em_core_imap_idle_loop_start 8 "); + IMAPLOCAL *imap_local = NULL; + char cmd[128], tag[32]; + char *p = NULL; + /* send DONE Command */ + /* free all data here */ + for (counter = 0; counter < num; counter++) { + EM_DEBUG_LOG(">>>> em_core_imap_idle_loop_start 9 "); + if (temp && temp->mail_stream) { + imap_local = ((MAILSTREAM *)temp->mail_stream)->local; + + sprintf(tag, "%08lx", 0xffffffff & (((MAILSTREAM *)temp->mail_stream)->gensym++)); + sprintf(cmd, "%s DONE\015\012", tag); + + if (!imap_local->netstream || !net_sout(imap_local->netstream, cmd, (int)strlen(cmd))) + { + EM_DEBUG_EXCEPTION("network error - failed to DONE on Mailbox - %s ", temp->name); + } + else { + while (imap_local->netstream) { + p = net_getline(imap_local->netstream); + EM_DEBUG_EXCEPTION("p =[%s]", p); + em_core_mailbox_close(temp->account_id, temp->mail_stream); + break; + } + } + } + + temp = temp->next; + } + + + /* kill idle thread */ + em_core_imap_idle_thread_kill(&err); + break; + } + + else { + /* + might happen that a socket desciptor passed to select got closed + chack which got closed and make hold_connection 0 + */ + EM_DEBUG_EXCEPTION(">>>>>> socket desciptor error : No Data "); + break; + } + + select_result = 0; + } + + ret = true; + + EM_DEBUG_LOG(">>>> em_core_imap_idle_loop_start 17 "); +FINISH_OFF: + if (err_code) + *err_code = err; + EM_DEBUG_EXCEPTION(">>>>>>> em_core_imap_idle_loop_start End "); + return ret; +} + + +int em_core_imap_idle_insert_sync_event(emf_mailbox_t *mailbox, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN(); + + int ret = false; + int err = EMF_ERROR_NONE; + int handle; + + if (!mailbox || mailbox->account_id <= 0) { + EM_DEBUG_LOG("\t mailbox[%p]", mailbox); + + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + emf_event_t event_data; + memset(&event_data, 0x00, sizeof(emf_event_t)); + + event_data.type = EMF_EVENT_SYNC_HEADER; + event_data.event_param_data_1 = mailbox ? EM_SAFE_STRDUP(mailbox->name) : NULL; + event_data.event_param_data_3 = NULL; + event_data.account_id = mailbox->account_id; + + if (!em_core_insert_event(&event_data, &handle, &err)) { + EM_DEBUG_LOG("\t em_core_insert_event falied - %d", err); + + /* err = EMF_ERROR_DB_FAILURE; */ + goto FINISH_OFF; + } + + ret = true; +FINISH_OFF: + if (err_code) + *err_code = err; + + return ret; +} + +/* connects to given mailbox. send idle and returns socket id */ +int em_core_imap_idle_connect_and_idle_on_mailbox(emf_mailbox_t *mailbox, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN(); + void *mail_stream = NULL; + char cmd[128], tag[32], *p; + int socket_id = 0; + int ret = 0; + int err = EMF_ERROR_NONE; + emf_account_t *ref_account = NULL; + + /* NULL param check */ + if (!mailbox) { + EM_DEBUG_EXCEPTION("\t mailbox[%p]", mailbox); + if (err_code) + *err_code = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + ref_account = em_core_get_account_reference(mailbox->account_id); + if (!ref_account) { + EM_DEBUG_EXCEPTION("\t em_core_get_account_reference failed - %d", mailbox->account_id); + + err = EMF_ERROR_INVALID_ACCOUNT; + goto FINISH_OFF; + } + + /* Open connection to mailbox */ + if (!em_core_mailbox_open(mailbox->account_id, mailbox->name, (void **)&mail_stream, &err) || !mail_stream) { + EM_DEBUG_EXCEPTION("\t em_core_mailbox_open failed - %d", err); + if (err_code) + *err_code = err; + goto FINISH_OFF; + } + + IMAPLOCAL *imap_local = ((MAILSTREAM *)mail_stream)->local; + NETSTREAM *net_stream = imap_local->netstream; + + /* check if ssl option is enabled on this account - shasikala.p */ + TCPSTREAM *tcp_stream = NULL; + if (ref_account->use_security){ + SSLSTREAM *ssl_stream = net_stream->stream; + tcp_stream = ssl_stream->tcpstream; + } + else{ + tcp_stream = net_stream->stream; + } + + /* Get Socket ID */ + socket_id = ((TCPSTREAM *)tcp_stream)->tcpsi; + + sprintf(tag, "%08lx", 0xffffffff & (((MAILSTREAM *)mail_stream)->gensym++)); + sprintf(cmd, "%s IDLE\015\012", tag); + + /* Send IDLE command */ + if (!imap_local->netstream || !net_sout(imap_local->netstream, cmd, (int)strlen(cmd))) + { + EM_DEBUG_EXCEPTION("network error - failed to IDLE on Mailbox - %s ", mailbox->name); + if (err_code) + *err_code = EMF_ERROR_IMAP4_IDLE_FAILURE; + goto FINISH_OFF; + } + + /* Get the response for IDLE command */ + while (imap_local->netstream){ + p = net_getline(imap_local->netstream); + EM_DEBUG_LOG("p =[%s]", p); + if (!strncmp(p, "+", 1)) { + ret = 1; + break; + } + else if (!strncmp(p, "*", 1)) { + EM_SAFE_FREE(p); + continue; + } + else { + ret = 0; + break; + } + } + EM_SAFE_FREE(p); /* Prevent Defect - 18815 */ + +FINISH_OFF: + + if (ret) /* IMAP IDLE - SUCCESS */{ + mailbox->mail_stream = mail_stream; + mailbox->hold_connection = socket_id; /* holds connection continuosly on the given socket_id */ + } + else + if (mail_stream) em_core_mailbox_close(mailbox->account_id, mail_stream); + return ret; +} + + +int em_core_imap_idle_parse_response_stream(emf_mailbox_t *mailbox, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN(); + int err = EMF_ERROR_NONE; + char *p = NULL; + int ret = false; + + /* NULL PARAM CHECK */ + if (!mailbox) { + EM_DEBUG_EXCEPTION("\t mailbox[%p]", mailbox); + if (err_code) + *err_code = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + IMAPLOCAL *imap_local = NULL; + + if (!mailbox->mail_stream){ + EM_DEBUG_EXCEPTION("mail_stream is NULL"); + goto FINISH_OFF; + } + + imap_local = ((MAILSTREAM *)mailbox->mail_stream)->local; + + if (!imap_local){ + EM_DEBUG_EXCEPTION("imap_local is NULL"); + goto FINISH_OFF; + } + + + while (imap_local->netstream){ + p = net_getline(imap_local->netstream); + if (p && !strncmp(p, "*", 1)) { + EM_DEBUG_LOG("p is [%s]", p); + if (p+1 && p+2 && p+3 && p+4 && !strncmp(p+2, "BYE", 3)) { + EM_DEBUG_LOG("BYE connection from server"); + + EM_SAFE_FREE(p); + goto FINISH_OFF; + } + else { + if (!em_core_imap_idle_insert_sync_event(mailbox, &err)) + EM_DEBUG_EXCEPTION("Syncing mailbox %s failed with err_code - %d", mailbox->name, err); + EM_SAFE_FREE(p); + break; + } + + + } + else if (p && (!strncmp(p, "+", 1))) { + /* Bad response from server */ + EM_DEBUG_LOG("p is [%s]", p); + EM_SAFE_FREE(p); + break; + } + else { + EM_DEBUG_LOG("In else part"); + break; + } + } + + ret = true; +FINISH_OFF: + return ret; +} +#endif /* _FEATURE_IMAP_IDLE */ diff --git a/email-core/em-core-imap-mailbox.c b/email-core/em-core-imap-mailbox.c new file mode 100755 index 0000000..2cef70e --- /dev/null +++ b/email-core/em-core-imap-mailbox.c @@ -0,0 +1,1193 @@ +/* +* email-service +* +* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. +* +* Contact: Kyuho Jo <kyuho.jo@samsung.com>, Sunghyun Kwon <sh0701.kwon@samsung.com> +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + + + +/****************************************************************************** + * File : em-core-imap_folder.c + * Desc : Mail IMAP mailbox + * + * Auth : + * + * History : + * 2006.08.01 : created + *****************************************************************************/ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <vconf.h> +#include "em-core-global.h" +#include "em-core-utils.h" +#include "c-client.h" +#include "em-storage.h" +#include "em-core-event.h" +#include "em-core-mailbox.h" +#include "em-core-imap-mailbox.h" +#include "em-core-mailbox-sync.h" +#include "em-core-account.h" +#include "lnx_inc.h" + +#include "emf-dbglog.h" + +EXPORT_API int em_core_mailbox_get_default_mail_slot_count(int *output_count, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN(); + EM_DEBUG_LOG("output_count[%p], err_code[%p]", output_count, err_code); + + int err = EMF_ERROR_NONE; + int mail_slot_count; + int ret = false, ret2; + + if (output_count == NULL) { + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + ret2 = vconf_get_int(VCONF_KEY_DEFAULT_SLOT_SIZE, &mail_slot_count); + + if (ret2 < 0) { + EM_DEBUG_EXCEPTION("vconf_get_int() Failed(%d)", ret2); + mail_slot_count = 100; + } + + ret = true; + +FINISH_OFF: + + if (output_count) + *output_count = mail_slot_count; + + if (err_code) + *err_code = err; + + return ret; + +} + + +EXPORT_API int em_core_mailbox_remove_overflowed_mails(emf_mailbox_tbl_t *intput_mailbox_tbl, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("intput_mailbox_tbl[%p], err_code[%p]", intput_mailbox_tbl, err_code); + + int ret = false; + int *mail_id_list = NULL, mail_id_list_count = 0; + int err = EMF_ERROR_NONE; + emf_account_t *account_ref = NULL; + + if (!intput_mailbox_tbl || intput_mailbox_tbl->account_id < 1) { + if (intput_mailbox_tbl) + EM_DEBUG_EXCEPTION("Invalid Parameter. intput_mailbox_tbl->account_id [%d]", intput_mailbox_tbl->account_id); + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + account_ref = em_core_get_account_reference(intput_mailbox_tbl->account_id); + if (account_ref) { + if (account_ref->receiving_server_type == EMF_SERVER_TYPE_ACTIVE_SYNC) { + EM_DEBUG_LOG("ActiveSync Account didn't support mail slot"); + err = EMF_ERROR_NOT_SUPPORTED; + goto FINISH_OFF; + } + } + + if (!em_storage_get_overflowed_mail_id_list(intput_mailbox_tbl->account_id, intput_mailbox_tbl->mailbox_name, intput_mailbox_tbl->mail_slot_size, &mail_id_list, &mail_id_list_count, true, &err)) { + if (err == EM_STORAGE_ERROR_MAIL_NOT_FOUND) { + EM_DEBUG_LOG("There are enough slot in intput_mailbox_tbl [%s]", intput_mailbox_tbl->mailbox_name); + err = EMF_ERROR_NONE; + ret = true; + } + else + EM_DEBUG_EXCEPTION("em_storage_get_overflowed_mail_id_list failed [%d]", err); + goto FINISH_OFF; + } + + if (mail_id_list) { + if (!em_core_mail_delete(intput_mailbox_tbl->account_id, mail_id_list, mail_id_list_count, false, EMF_DELETED_BY_OVERFLOW, false, &err)) { + EM_DEBUG_EXCEPTION("em_core_mail_delete failed [%d]", err); + goto FINISH_OFF; + } + } + + ret = true; +FINISH_OFF: + EM_SAFE_FREE(mail_id_list); + + if (err_code) + *err_code = err; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + + +EXPORT_API int em_core_mailbox_set_mail_slot_size(int account_id, char *mailbox_name, int new_slot_size, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN(); + EM_DEBUG_LOG("account_id [%d], mailbox_name[%p], err_code[%p]", account_id, mailbox_name, err_code); + + int ret = false, err = EMF_ERROR_NONE; + int i, mailbox_count = 0; + emf_account_t *account_ref = NULL; + emf_mailbox_tbl_t *mailbox_tbl_list = NULL; + + if (account_id > ALL_ACCOUNT) { + account_ref = em_core_get_account_reference(account_id); + if (account_ref && account_ref->receiving_server_type == EMF_SERVER_TYPE_ACTIVE_SYNC) { + EM_DEBUG_LOG("ActiveSync account didn't support mail slot"); + ret = true; + goto FINISH_OFF; + } + else if (!account_ref) { + EM_DEBUG_EXCEPTION("em_core_get_account_reference failed"); + goto FINISH_OFF; + } + } + + if (!em_storage_set_mail_slot_size(account_id, mailbox_name, new_slot_size, true, &err)) { + EM_DEBUG_EXCEPTION("em_storage_set_mail_slot_size failed [%d]", err); + goto FINISH_OFF; + } + + if (mailbox_name) { + mailbox_count = 1; + if (new_slot_size > 0) { + mailbox_tbl_list = em_core_malloc(sizeof(emf_mailbox_tbl_t) * mailbox_count); + if(!mailbox_tbl_list) { + EM_DEBUG_EXCEPTION("em_core_malloc failed"); + goto FINISH_OFF; + } + mailbox_tbl_list->account_id = account_id; + mailbox_tbl_list->mailbox_name = EM_SAFE_STRDUP(mailbox_name); + mailbox_tbl_list->mail_slot_size = new_slot_size; + } + else { /* read information from DB */ + if (!em_storage_get_mailbox_by_name(account_id, EMF_MAILBOX_ALL, mailbox_name, &mailbox_tbl_list, true, &err)) { + EM_DEBUG_EXCEPTION("em_storage_get_mailbox failed [%d]", err); + goto FINISH_OFF; + } + + } + } + else { + if (!em_storage_get_mailbox(account_id, EMF_MAILBOX_ALL, EMAIL_MAILBOX_SORT_BY_NAME_ASC, &mailbox_count, &mailbox_tbl_list, true, &err)) { + EM_DEBUG_EXCEPTION("em_storage_get_mailbox failed [%d]", err); + goto FINISH_OFF; + } + } + + for (i = 0; i < mailbox_count; i++) { + if (!em_core_mailbox_remove_overflowed_mails(mailbox_tbl_list + i, &err)) { + if (err == EM_STORAGE_ERROR_MAIL_NOT_FOUND || err == EMF_ERROR_NOT_SUPPORTED) + err = EMF_ERROR_NONE; + else + EM_DEBUG_EXCEPTION("em_core_mailbox_remove_overflowed_mails failed [%d]", err); + } + } + + + + ret = true; +FINISH_OFF: + + if (mailbox_tbl_list) + em_storage_free_mailbox(&mailbox_tbl_list, mailbox_count, NULL); + + + if (err_code) + *err_code = err; + return ret; +} + + +static int em_core_get_mailbox_connection_path(int account_id, char *mailbox_name, char **path, int *err_code) +{ + emf_account_t *ref_account = NULL; + size_t path_len = 0; + + + ref_account = em_core_get_account_reference(account_id); + if (!ref_account) { + EM_DEBUG_EXCEPTION("em_core_get_account_reference failed"); + return 0; + } + + path_len = strlen(ref_account->receiving_server_addr) + + (mailbox_name ? strlen(mailbox_name) : 0) + 50; + + *path = em_core_malloc(path_len);/* strlen(ref_account->receiving_server_addr) + */ + /* (mailbox_name ? strlen(mailbox_name) : 0) + 20); */ + if (!*path) + return 0; + memset(*path, 0x00, path_len); + /* 1. server address / server type */ + + if (ref_account->receiving_server_type == EMF_SERVER_TYPE_POP3) { + SNPRINTF(*path + 1, path_len-1, "%s:%d/pop", ref_account->receiving_server_addr, ref_account->port_num); + } + else { + SNPRINTF(*path + 1, path_len-1, "%s:%d/imap", ref_account->receiving_server_addr, ref_account->port_num); + } + + /* 2. set tls option if security connection */ +/* if (ref_account->use_security) strncat(*path + 1, "/tls", path_len-(strlen(*path)-1)); */ + if (ref_account->use_security & 0x01) { + strncat(*path + 1, "/ssl", path_len-(strlen(*path)-1)); + } + if (ref_account->use_security & 0x02) + strncat(*path + 1, "/tls", path_len-(strlen(*path)-1)); + else + strncat(*path + 1, "/notls", path_len-(strlen(*path)-1)); + + /* 3. re-format mailbox name (ex:"{mai.test.com:143/imap} or {mai.test.com:143/imap/tls}"} */ + strncat(*path + 1, "}", path_len-strlen(*path)-1); + **path = '{'; + + if (mailbox_name) strncat(*path, mailbox_name, path_len-strlen(*path)-1); + + return 1; +} + +EXPORT_API int em_core_mailbox_sync_mailbox_list(int account_id, char *mailbox_name, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id[%d], mailbox_name[%p], err_code[%p]", account_id, mailbox_name, err_code); + + int ret = false; + int err = EMF_ERROR_NONE; + int status = EMF_DOWNLOAD_FAIL; + + MAILSTREAM *stream = NULL; + emf_mailbox_t *mailbox_list = NULL; + emf_account_t *ref_account = NULL; + void *tmp_stream = NULL; + char *mbox_path = NULL; + int i = 0, count = 0, counter = 0, mailbox_type_list[EMF_MAILBOX_TYPE_ALL_EMAILS + 1] = {-1, -1, -1, -1, -1, -1, -1, -1}; + char *mailbox_name_for_mailbox_type = NULL; + + + if (err_code) + *err_code = EMF_ERROR_NONE; + + if (!em_core_check_thread_status()) { + err = EMF_ERROR_CANCELLED; + goto FINISH_OFF; + } + + ref_account = em_core_get_account_reference(account_id); + if (!ref_account) { + EM_DEBUG_EXCEPTION("em_core_get_account_reference failed - %d", account_id); + err = EMF_ERROR_INVALID_ACCOUNT; + goto FINISH_OFF; + } + + /* if not imap4 mail, return */ + if (ref_account->account_bind_type != EMF_BIND_TYPE_EM_CORE || ref_account->receiving_server_type != EMF_SERVER_TYPE_IMAP4) { + EM_DEBUG_EXCEPTION("unsupported account..."); + err = EMF_ERROR_INVALID_ACCOUNT; + goto FINISH_OFF; + } + + /* get mail server path */ + /* mbox_path is not used. the below func might be unnecessary */ + if (!em_core_get_mailbox_connection_path(account_id, NULL, &mbox_path, &err) || !mbox_path) { + EM_DEBUG_EXCEPTION("em_core_get_mailbox_connection_path - %d", err); + goto FINISH_OFF; + } + + + if (!em_core_check_thread_status()) { + err = EMF_ERROR_CANCELLED; + goto FINISH_OFF; + } + + stream = NULL; + if (!em_core_mailbox_open(account_id, NULL, (void **)&tmp_stream, &err) || !tmp_stream) { + EM_DEBUG_EXCEPTION("em_core_mailbox_open failed - %d", err); + + if (err == EMF_ERROR_CONNECTION_BROKEN) + err = EMF_ERROR_CANCELLED; + else + err = EMF_ERROR_CONNECTION_FAILURE; + + status = EMF_DOWNLOAD_CONNECTION_FAIL; + goto FINISH_OFF; + } + + EM_SAFE_FREE(mbox_path); + + stream = (MAILSTREAM *)tmp_stream; + + if (!em_core_check_thread_status()) { + err = EMF_ERROR_CANCELLED; + goto FINISH_OFF; + } + + /* download mailbox list */ + if (!em_core_mailbox_download_mailbox_list(stream, mailbox_name, &mailbox_list, &count, &err)) { + EM_DEBUG_EXCEPTION("em_core_mailbox_download_mailbox_list failed - %d", err); + goto FINISH_OFF; + } + + if (!em_core_check_thread_status()) { + err = EMF_ERROR_CANCELLED; + goto FINISH_OFF; + } + + for (i = 0; i < count; i++) { + if (!em_core_check_thread_status()) { + EM_DEBUG_LOG("em_core_check_thread_status - cancelled"); + err = EMF_ERROR_CANCELLED; + goto FINISH_OFF; + } + if (mailbox_list[i].name) { + EM_DEBUG_LOG("mailbox name - %s", mailbox_list[i].name); + em_core_mailbox_get_default_mail_slot_count(&(mailbox_list[i].mail_slot_size), NULL); + em_core_bind_mailbox_type(mailbox_list + i); + + if (mailbox_list[i].mailbox_type <= EMF_MAILBOX_TYPE_ALL_EMAILS) { /* if result mailbox type is duplicated, */ + if (mailbox_type_list[mailbox_list[i].mailbox_type] != -1) { + EM_DEBUG_LOG("Mailbox type [%d] of [%s] is duplicated", mailbox_list[i].mailbox_type, mailbox_list[i].name); + mailbox_list[i].mailbox_type = EMF_MAILBOX_TYPE_USER_DEFINED; /* ignore latest one */ + } + else + mailbox_type_list[mailbox_list[i].mailbox_type] = i; + } + + EM_DEBUG_LOG("mailbox type [%d]", mailbox_list[i].mailbox_type); + if(!em_core_mailbox_set_sync_imap_mailbox(mailbox_list + i, 1, &err)) { + EM_DEBUG_EXCEPTION("em_core_mailbox_set_sync_imap_mailbox failed [%d]", err); + goto FINISH_OFF; + } + + } + } + + + for (counter = EMF_MAILBOX_TYPE_INBOX; counter <= EMF_MAILBOX_TYPE_OUTBOX; counter++) { + /* if (!em_storage_get_mailboxname_by_mailbox_type(account_id, counter, &mailbox_name_for_mailbox_type, false, &err)) */ + if (mailbox_type_list[counter] == -1) { + /* EM_DEBUG_EXCEPTION("em_storage_get_mailboxname_by_mailbox_type failed - %d", err); */ + /* if (EM_STORAGE_ERROR_MAILBOX_NOT_FOUND == err) */ + /* { */ + emf_mailbox_tbl_t mailbox_tbl; + + memset(&mailbox_tbl, 0x00, sizeof(mailbox_tbl)); + + mailbox_tbl.account_id = account_id; + mailbox_tbl.mailbox_id = 0; + mailbox_tbl.local_yn = 1; + mailbox_tbl.mailbox_type = counter; + mailbox_tbl.sync_with_server_yn = 1; + mailbox_tbl.modifiable_yn = 1; + mailbox_tbl.total_mail_count_on_server = 0; + em_core_mailbox_get_default_mail_slot_count(&mailbox_tbl.mail_slot_size, NULL); + + switch (counter) { + case EMF_MAILBOX_TYPE_SENTBOX: + mailbox_tbl.mailbox_name = EMF_SENTBOX_NAME; + mailbox_tbl.alias = EMF_SENTBOX_DISPLAY_NAME; + break; + + case EMF_MAILBOX_TYPE_TRASH: + mailbox_tbl.mailbox_name = EMF_TRASH_NAME; + mailbox_tbl.alias = EMF_TRASH_DISPLAY_NAME; + break; + + case EMF_MAILBOX_TYPE_DRAFT: + mailbox_tbl.mailbox_name = EMF_DRAFTBOX_NAME; + mailbox_tbl.alias = EMF_DRAFTBOX_DISPLAY_NAME; + break; + + case EMF_MAILBOX_TYPE_SPAMBOX: + mailbox_tbl.mailbox_name = EMF_SPAMBOX_NAME; + mailbox_tbl.alias = EMF_SPAMBOX_DISPLAY_NAME; + break; + + case EMF_MAILBOX_TYPE_OUTBOX: + mailbox_tbl.mailbox_name = EMF_OUTBOX_NAME; + mailbox_tbl.alias = EMF_OUTBOX_DISPLAY_NAME; + break; + + default: + mailbox_tbl.mailbox_name = EMF_INBOX_NAME; + mailbox_tbl.alias = EMF_INBOX_DISPLAY_NAME; + break; + } + + if (!em_storage_add_mailbox(&mailbox_tbl, true, &err)) { + EM_DEBUG_EXCEPTION("em_storage_add_mailbox failed - %d", err); + + if (err == EM_STORAGE_ERROR_DB_IS_FULL) + err = EMF_ERROR_MAIL_MEMORY_FULL; + else if (err == EM_STORAGE_ERROR_INVALID_PARAM) + err = EMF_ERROR_INVALID_PARAM; + else if (err == EM_STORAGE_ERROR_OUT_OF_MEMORY) + err = EMF_ERROR_OUT_OF_MEMORY; + else if (err == EM_STORAGE_ERROR_DB_FAILURE) + err = EMF_ERROR_DB_FAILURE; + else + err = EMF_ERROR_UNKNOWN; + goto FINISH_OFF; + } + + /* } */ + /* else */ + /* { */ + /* err = em_storage_get_emf_error_from_em_storage_error(err); */ + /* goto FINISH_OFF; */ + /* } */ + + } + EM_SAFE_FREE(mailbox_name_for_mailbox_type); + } + + emf_mailbox_tbl_t *local_mailbox_list = NULL; + int select_num = 0; + i = 0; + emf_mailbox_t mailbox; + + if (em_storage_get_mailbox_by_modifiable_yn(account_id, 0 /* modifiable_yn */, &select_num, &local_mailbox_list, true, &err)) { + if (select_num > 0) { + for (i = 0; i < select_num; i++) { + EM_DEBUG_LOG(">>> MailBox needs to be Deleted[ %s ] ", local_mailbox_list[i].mailbox_name); + mailbox.account_id = local_mailbox_list[i].account_id; + mailbox.name = local_mailbox_list[i].mailbox_name; + if (!em_core_mailbox_delete_all(&mailbox, &err)) { + EM_DEBUG_EXCEPTION(" em_core_mailbox_delete_all of Mailbox [%s] Failed ", mailbox.name); + em_storage_free_mailbox(&local_mailbox_list, select_num, NULL); + local_mailbox_list = NULL; + goto FINISH_OFF; + } + } + em_storage_free_mailbox(&local_mailbox_list, select_num, NULL); + local_mailbox_list = NULL; + } + } + + if (!em_storage_set_all_mailbox_modifiable_yn(account_id, 0, true, &err)) { + EM_DEBUG_EXCEPTION(" >>>> em_storage_set_all_mailbox_modifiable_yn Failed [ %d ]", err); + goto FINISH_OFF; + } + + if (!em_core_check_thread_status()) { + err = EMF_ERROR_CANCELLED; + goto FINISH_OFF; + } + + for (i = 0; i < count; i++) + mailbox_list[i].account_id = account_id; + + + ret = true; + +FINISH_OFF: + EM_SAFE_FREE(mailbox_name_for_mailbox_type); + EM_SAFE_FREE(mbox_path); + + if (stream) + em_core_mailbox_close(account_id, stream); + + if (mailbox_list) + em_core_mailbox_free(&mailbox_list, count, NULL); + + if (err_code != NULL) + *err_code = err; + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +int em_core_mailbox_download_mailbox_list(void *mail_stream, + char *mailbox, + emf_mailbox_t **mailbox_list, + int *count, + int *err_code) +{ + MAILSTREAM *stream = mail_stream; + emf_callback_holder_t holder; + char *pattern = NULL; + char *reference = NULL; + int err = EMF_ERROR_NONE; + int ret = false; + + EM_DEBUG_FUNC_BEGIN(); + + if (err_code) { + *err_code = EMF_ERROR_NONE; + } + + if (!stream || !mailbox_list || !count) { + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + memset(&holder, 0x00, sizeof(holder)); + + /* reference (ex : "{mail.test.com}", "{mail.test.com}inbox") */ + if (mailbox) { + char *s = NULL; + reference = em_core_malloc(strlen(stream->original_mailbox) + strlen(mailbox) + 1); + if (reference) { + strncpy(reference, stream->original_mailbox, (size_t)strlen(stream->original_mailbox)); + if ((s = strchr(reference, '}'))) + *(++s) = '\0'; + strcat(reference, mailbox); + } + } + else + reference = EM_SAFE_STRDUP(stream->original_mailbox); + + pattern = "*"; + stream->sparep = &holder; + + /* imap command : tag LIST reference * */ + mail_list(stream, reference, pattern); + + stream->sparep = NULL; + + EM_SAFE_FREE(reference); + + *count = holder.num; + *mailbox_list = (emf_mailbox_t *)holder.data; + + ret = true; + +FINISH_OFF: + if (err_code) *err_code = err; + + return ret; +} + +/* description + * check whether this imap mailbox is synchronous mailbox + * arguments + * mailbox : imap mailbox to be checked + * synchronous : boolean variable to be synchronous (1 : sync 0 : non-sync) + * return + * succeed : 1 + * fail : 0 + */ +int em_core_mailbox_check_sync_imap_mailbox(emf_mailbox_t *mailbox, int *synchronous, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN(); + + EM_DEBUG_LOG("\t mailbox[%p], synchronous[%p], err_code[%p]", mailbox, synchronous, err_code); + + if (err_code) { + *err_code = EMF_ERROR_NONE; + } + + if (!mailbox || !synchronous) { + EM_DEBUG_EXCEPTION("\t mailbox[%p], synchronous[%p]", mailbox, synchronous); + + if (err_code != NULL) + *err_code = EMF_ERROR_INVALID_PARAM; + return false; + } + + int ret = false; + int err = EMF_ERROR_NONE; + emf_mailbox_tbl_t *imap_mailbox_tbl = NULL; + + if (!em_storage_get_mailbox_by_name(mailbox->account_id, 0, mailbox->name, &imap_mailbox_tbl, true, &err)) { + EM_DEBUG_EXCEPTION("em_storage_get_mailbox_by_name failed - %d", err); + + if (err == EM_STORAGE_ERROR_MAILBOX_NOT_FOUND) + err = EMF_ERROR_MAILBOX_NOT_FOUND; + else if (err == EM_STORAGE_ERROR_INVALID_PARAM) + err = EMF_ERROR_INVALID_PARAM; + else if (err == EM_STORAGE_ERROR_OUT_OF_MEMORY) + err = EMF_ERROR_OUT_OF_MEMORY; + else if (err == EM_STORAGE_ERROR_DB_FAILURE) + err = EMF_ERROR_DB_FAILURE; + else + err = EMF_ERROR_UNKNOWN; + goto FINISH_OFF; + } + + *synchronous = imap_mailbox_tbl ? 1 : 0; + + ret = true; + +FINISH_OFF: + if (imap_mailbox_tbl != NULL) + em_storage_free_mailbox(&imap_mailbox_tbl, 1, NULL); + + if (err_code != NULL) + *err_code = err; + + return ret; +} + + +/* description + * set sync imap mailbox + * arguments + * mailbox_list : imap mailbox to be synced + * syncronous : 0-sync 1 : non-sync + * return + * succeed : 1 + * fail : 0 + */ + +int em_core_mailbox_set_sync_imap_mailbox(emf_mailbox_t *mailbox, int synchronous, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("mailbox[%p], synchronous[%d], err_code[%p]", mailbox, synchronous, err_code); + + if (!mailbox) { + EM_DEBUG_EXCEPTION("mailbox[%p], synchronous[%d]", mailbox, synchronous); + if (err_code != NULL) + *err_code = EMF_ERROR_INVALID_PARAM; + return false; + } + + int ret = false; + int err = EMF_ERROR_NONE; + emf_mailbox_tbl_t *imap_mailbox_tbl_item = NULL; + em_core_uid_list *uid_list = NULL; + emf_mail_read_mail_uid_tbl_t *downloaded_uids = NULL; + MAILSTREAM *stream = mailbox->mail_stream; + int mailbox_renamed = 0; + int j = 0; + int i = 0; + int temp = 0; + IMAPLOCAL *imap_local = NULL; + char cmd[128], tag[32], *p; + + if (synchronous) { + /* if synchcronous, insert imap mailbox to db */ + if (em_storage_get_mailbox_by_name(mailbox->account_id, 0, mailbox->name, &imap_mailbox_tbl_item, true, &err)) { + /* mailbox already exists */ + /* mailbox Found, Do set the modifiable_yn = 1 */ + EM_DEBUG_LOG("mailbox already exists and setting modifiable_yn to 1"); + if (!em_storage_update_mailbox_modifiable_yn(mailbox->account_id, 0, mailbox->name, 1, true, &err)) { + EM_DEBUG_EXCEPTION(" em_storage_update_mailbox_modifiable_yn Failed [ %d ] ", err); + if (err == EM_STORAGE_ERROR_INVALID_PARAM) + err = EMF_ERROR_INVALID_PARAM; + else if (err == EM_STORAGE_ERROR_OUT_OF_MEMORY) + err = EMF_ERROR_OUT_OF_MEMORY; + else if (err == EM_STORAGE_ERROR_DB_FAILURE) + err = EMF_ERROR_DB_FAILURE; + else + err = EMF_ERROR_UNKNOWN; + goto JOB_ERROR; + } + } + else { + if (err != EM_STORAGE_ERROR_MAILBOX_NOT_FOUND) { + EM_DEBUG_EXCEPTION(">>>>.>>>>>Getting mailbox failed>>>>>>>>>>>>>>"); + /* This is error scenario so finish the job */ + if (err == EM_STORAGE_ERROR_INVALID_PARAM) + err = EMF_ERROR_INVALID_PARAM; + else if (err == EM_STORAGE_ERROR_OUT_OF_MEMORY) + err = EMF_ERROR_OUT_OF_MEMORY; + else if (err == EM_STORAGE_ERROR_DB_FAILURE) + err = EMF_ERROR_DB_FAILURE; + else + err = EMF_ERROR_UNKNOWN; + goto JOB_ERROR; + } + else { + /* This is not error scenario - mailbox is either new/renamed mailbox and needs to be added/modfied in DB */ + /* Now check if mailbox is renamed */ + EM_DEBUG_LOG(">>>>>>>>>>>>>>>>>>>>>>>MAILBOX NEW OR RENAMED"); + if (stream) { + imap_local = ((MAILSTREAM *)stream)->local; + EM_DEBUG_LINE; + sprintf(tag, "%08lx", 0xffffffff & (((MAILSTREAM *)stream)->gensym++)); + EM_DEBUG_LINE; + sprintf(cmd, "%s SELECT %s\015\012", tag, mailbox->name); + EM_DEBUG_LINE; + + } + + /* select the mailbox and get its UID */ + if (!imap_local || !imap_local->netstream || !net_sout(imap_local->netstream, cmd, (int)strlen(cmd))) { + EM_DEBUG_EXCEPTION("network error - failed to IDLE on Mailbox [%s]", mailbox->name); + /* + err = EMF_ERROR_CONNECTION_BROKEN; + if(imap_local) + imap_local->netstream = NULL; + mailbox->mail_stream = NULL; + goto JOB_ERROR; + */ + } + else { + EM_DEBUG_LOG("Get response for select call"); + while (imap_local->netstream) { + p = net_getline(imap_local->netstream); + EM_DEBUG_LOG("p =[%s]", p); + if (!strncmp(p, "+", 1)) { + ret = 1; + break; + } + else if (!strncmp(p, "*", 1)) { + EM_SAFE_FREE(p); + continue; + } + else { + ret = 0; + break; + } + } + EM_SAFE_FREE(p); + EM_DEBUG_LINE; + /* check if OK or BAD response comes. */ + /* if response is OK the try getting UID list. */ + if (!strncmp((char *)imap_local->reply.key, "OK", strlen("OK"))) { + EM_DEBUG_LOG(">>>>>>>>>>Select success on %s mailbox", mailbox->name); + if (!imap4_mailbox_get_uids(stream, &uid_list, &err)) { + EM_DEBUG_EXCEPTION("imap4_mailbox_get_uids failed - %d", err); + EM_SAFE_FREE(uid_list); + } + else { + if (!em_storage_get_downloaded_list(mailbox->account_id, NULL, &downloaded_uids, &j, true, &err)) { + EM_DEBUG_EXCEPTION("em_storage_get_downloaded_list failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + downloaded_uids = NULL; + } + else /* Prevent Defect - 28497 */ { + em_core_uid_list *uid_elem = uid_list; + em_core_uid_list *next_uid_elem = NULL; + if (uid_elem) { + for (i = j; (i > 0 && !mailbox_renamed); i--) { + if (uid_elem) { + next_uid_elem = uid_elem->next; + if (uid_elem->uid && downloaded_uids[i - 1].s_uid && !strcmp(uid_elem->uid, downloaded_uids[i - 1].s_uid)) { + temp = i-1; + mailbox_renamed = 1; + break; + } + EM_SAFE_FREE(uid_elem->uid); + uid_elem = next_uid_elem; + } + } + } + } + } + } /* mailbox selected */ + } + + if (mailbox_renamed) /* renamed mailbox */ { + EM_DEBUG_LOG("downloaded_uids[temp].mailbox_name [%s]", downloaded_uids[temp].mailbox_name); + /* Do a mailbox rename in the DB */ + if (!em_storage_modify_mailbox_of_mails(downloaded_uids[temp].mailbox_name, mailbox->name, true, &err)) + EM_DEBUG_EXCEPTION(" em_storage_modify_mailbox_of_mails Failed [%d]", err); + + mailbox_renamed = 0; + + emf_mailbox_tbl_t mailbox_tbl; + mailbox_tbl.account_id = mailbox->account_id; + mailbox_tbl.local_yn = 0; + mailbox_tbl.mailbox_name = mailbox->name; + mailbox_tbl.mailbox_type = mailbox->mailbox_type; + + /* Get the Alias Name after parsing the Full mailbox Path */ + mailbox->alias = em_core_get_alias_of_mailbox((const char *)mailbox->name); + + if (mailbox->alias) + EM_DEBUG_LOG("mailbox->alias [%s] ", mailbox->alias); + + mailbox_tbl.alias = mailbox->alias; + mailbox_tbl.sync_with_server_yn = 0; + mailbox_tbl.modifiable_yn = 1; + mailbox_tbl.total_mail_count_on_server = 0; + + /* if non synchronous, delete imap mailbox from db */ + if (!em_storage_update_mailbox(mailbox->account_id, 0, downloaded_uids[temp].mailbox_name, &mailbox_tbl, true, &err)) { + EM_DEBUG_EXCEPTION(" em_storage_update_mailbox Failed [ %d ] ", err); + if (err == EM_STORAGE_ERROR_INVALID_PARAM) + err = EMF_ERROR_INVALID_PARAM; + else if (err == EM_STORAGE_ERROR_OUT_OF_MEMORY) + err = EMF_ERROR_OUT_OF_MEMORY; + else if (err == EM_STORAGE_ERROR_DB_FAILURE) + err = EMF_ERROR_DB_FAILURE; + else + err = EMF_ERROR_UNKNOWN; + goto JOB_ERROR; + } + + } + else /* Its a Fresh Mailbox */ { + emf_mailbox_tbl_t mailbox_tbl; + mailbox_tbl.mailbox_id = mailbox->mailbox_id; + mailbox_tbl.account_id = mailbox->account_id; + mailbox_tbl.local_yn = 0; + mailbox_tbl.mailbox_type = mailbox->mailbox_type; + mailbox_tbl.mailbox_name = mailbox->name; + mailbox_tbl.mail_slot_size = mailbox->mail_slot_size; + + /* Get the Alias Name after Parsing the Full mailbox Path */ + mailbox->alias = em_core_get_alias_of_mailbox((const char *)mailbox->name); + + if (mailbox->alias) { + EM_DEBUG_LOG("mailbox->alias [%s] ", mailbox->alias); + + mailbox_tbl.alias = mailbox->alias; + mailbox_tbl.sync_with_server_yn = 1; + mailbox_tbl.modifiable_yn = 1; + mailbox_tbl.total_mail_count_on_server = 0; + + EM_DEBUG_LOG("mailbox_tbl.mailbox_type - %d", mailbox_tbl.mailbox_type); + + if (!em_storage_add_mailbox(&mailbox_tbl, true, &err)) { + EM_DEBUG_EXCEPTION("em_storage_add_mailbox failed - %d", err); + + if (err == EM_STORAGE_ERROR_DB_IS_FULL) + err = EMF_ERROR_MAIL_MEMORY_FULL; + else if (err == EM_STORAGE_ERROR_INVALID_PARAM) + err = EMF_ERROR_INVALID_PARAM; + else if (err == EM_STORAGE_ERROR_OUT_OF_MEMORY) + err = EMF_ERROR_OUT_OF_MEMORY; + else if (err == EM_STORAGE_ERROR_DB_FAILURE) + err = EMF_ERROR_DB_FAILURE; + else + err = EMF_ERROR_UNKNOWN; + goto JOB_ERROR; + } + } + } + } + } + } + + /* set sync db mailbox */ + mailbox->synchronous = synchronous; + + ret = true; + +JOB_ERROR: + + if (downloaded_uids) + em_storage_free_read_mail_uid(&downloaded_uids, j, NULL); + + if (imap_mailbox_tbl_item) + em_storage_free_mailbox(&imap_mailbox_tbl_item, 1, NULL); + + if (err_code) + *err_code = err; + + return ret; +} + +/* description + * create a new imap mailbox + * arguments + * new_mailbox : imap mailbox to be created + * return + * succeed : 1 + * fail : 0 + */ +EXPORT_API int em_core_mailbox_create_imap_mailbox(emf_mailbox_t *mailbox, int *err_code) +{ + MAILSTREAM *stream = NULL; + char *long_enc_path = NULL; + void *tmp_stream = NULL; + int ret = false; + int err = EMF_ERROR_NONE; + + EM_DEBUG_FUNC_BEGIN(); + + if (err_code) { + *err_code = EMF_ERROR_NONE; + } + + if (!mailbox) + { + err = EMF_ERROR_INVALID_PARAM; + goto JOB_ERROR; + } + + /* connect mail server */ + stream = NULL; + if (!em_core_mailbox_open(mailbox->account_id, NULL, (void **)&tmp_stream, NULL)) + { + err = EMF_ERROR_CONNECTION_FAILURE; + goto JOB_ERROR; + } + + stream = (MAILSTREAM *)tmp_stream; + + /* encode mailbox name by UTF7, and rename to full path (ex : {mail.test.com}child_mailbox) */ + if (!em_core_get_long_encoded_path(mailbox->account_id, mailbox->name, '/', &long_enc_path, err_code)) + { + err = EMF_ERROR_UNKNOWN; + goto JOB_ERROR; + } + + /* create mailbox */ + if (!mail_create(stream, long_enc_path)) + { + err = EMF_ERROR_UNKNOWN; + goto JOB_ERROR; + } + + em_core_mailbox_close(0, stream); + stream = NULL; + + EM_SAFE_FREE(long_enc_path); + + ret = true; + +JOB_ERROR: + if (stream) + { + em_core_mailbox_close(0, stream); + stream = NULL; + } + + EM_SAFE_FREE(long_enc_path); + + if (err_code) + *err_code = err; + + return ret; +} + + +/* description + * delete a imap mailbox + * arguments + * mailbox : mailbox to be deleted + * return + * succeed : 1 + * fail : 0 + */ +EXPORT_API int em_core_mailbox_delete_imap_mailbox(emf_mailbox_t *mailbox, int *err_code) +{ + MAILSTREAM *stream = NULL; + char *long_enc_path = NULL; + emf_account_t *ref_account = NULL; + void *tmp_stream = NULL; + int ret = false; + int err = EMF_ERROR_NONE; + + EM_DEBUG_FUNC_BEGIN(); + + if (err_code) { + *err_code = EMF_ERROR_NONE; + } + + if (!mailbox) + { + err = EMF_ERROR_INVALID_PARAM; + goto JOB_ERROR; + } + + ref_account = em_core_get_account_reference(mailbox->account_id); + if (!ref_account) + { + err = EMF_ERROR_INVALID_PARAM; + goto JOB_ERROR; + } + + /* if not imap4 mail, return */ + if (ref_account->account_bind_type != EMF_BIND_TYPE_EM_CORE || + ref_account->receiving_server_type != EMF_SERVER_TYPE_IMAP4) + { + err = EMF_ERROR_INVALID_PARAM; + goto JOB_ERROR; + } + + /* connect mail server */ + stream = NULL; + if (!em_core_mailbox_open(ref_account->account_id, NULL, (void **)&tmp_stream, NULL)) + { + err = EMF_ERROR_CONNECTION_FAILURE; + goto JOB_ERROR; + } + + stream = (MAILSTREAM *)tmp_stream; + + /* encode mailbox name by UTF7, and rename to full path (ex : {mail.test.com}child_mailbox) */ + if (!em_core_get_long_encoded_path(mailbox->account_id, mailbox->name, '/', &long_enc_path, err_code)) + { + err = EMF_ERROR_UNKNOWN; + goto JOB_ERROR; + } + + /* delete mailbox */ + if (!mail_delete(stream, long_enc_path)) + { + err = EMF_ERROR_UNKNOWN; + goto JOB_ERROR; + } + + em_core_mailbox_close(0, stream); + stream = NULL; + + EM_SAFE_FREE(long_enc_path); + + /* if deleted imap mailbox is synchronous mailbox, delete db imap mailbox from db */ + if (!em_storage_delete_mailbox(ref_account->account_id, 0, mailbox->name, true, &err)) { + EM_DEBUG_EXCEPTION("\t em_storage_delete_mailbox failed - %d", err); + + if (err == EM_STORAGE_ERROR_MAILBOX_NOT_FOUND) + err = EMF_ERROR_MAILBOX_NOT_FOUND; + else if (err == EM_STORAGE_ERROR_INVALID_PARAM) + err = EMF_ERROR_INVALID_PARAM; + else if (err == EM_STORAGE_ERROR_OUT_OF_MEMORY) + err = EMF_ERROR_OUT_OF_MEMORY; + else if (err == EM_STORAGE_ERROR_DB_FAILURE) + err = EMF_ERROR_DB_FAILURE; + else + err = EMF_ERROR_UNKNOWN; + goto JOB_ERROR; + } + + ret = true; + +JOB_ERROR: + if (stream) + { + em_core_mailbox_close(0, stream); + stream = NULL; + } + + EM_SAFE_FREE(long_enc_path); + + if (err_code) + *err_code = err; + + return ret; +} + + +/* description + * change imap mailbox name + * arguments + * old_mailbox : previous mailbox + * new_mailbox : renamed mailbox + * return + * succeed : 1 + * fail : 0 + */ +EXPORT_API int em_core_mailbox_modify_imap_mailbox(emf_mailbox_t *old_mailbox, emf_mailbox_t *new_mailbox, int *err_code) +{ + MAILSTREAM *stream = NULL; + char *long_enc_path = NULL; + char *long_enc_path_new = NULL; + emf_mailbox_tbl_t imap_mailbox_tbl_item; + emf_account_t *ref_account = NULL; + void *tmp_stream = NULL; + int ret = false; + int err = EMF_ERROR_NONE; + + EM_DEBUG_FUNC_BEGIN(); + + if (err_code) { + *err_code = EMF_ERROR_NONE; + } + + if (!old_mailbox || !new_mailbox) + { + err = EMF_ERROR_INVALID_PARAM; + goto JOB_ERROR; + } + + ref_account = em_core_get_account_reference(old_mailbox->account_id); + if (!ref_account) + { + err = EMF_ERROR_INVALID_PARAM; + goto JOB_ERROR; + } + + if (!em_core_get_account_reference(new_mailbox->account_id)) + { + err = EMF_ERROR_INVALID_PARAM; + goto JOB_ERROR; + } + + /* if not imap4 mail, return */ + if (ref_account->account_bind_type != EMF_BIND_TYPE_EM_CORE || + ref_account->receiving_server_type != EMF_SERVER_TYPE_IMAP4) + { + err = EMF_ERROR_INVALID_PARAM; + goto JOB_ERROR; + } + + /* connect mail server */ + stream = NULL; + if (!em_core_mailbox_open(ref_account->account_id, NULL, (void **)&tmp_stream, NULL)) + { + err = EMF_ERROR_CONNECTION_FAILURE; + goto JOB_ERROR; + } + + stream = (MAILSTREAM *)tmp_stream; + + /* encode mailbox name by UTF7, and rename to full path (ex : {mail.test.com}child_mailbox) */ + if (!em_core_get_long_encoded_path(old_mailbox->account_id, old_mailbox->name, '/', &long_enc_path, err_code)) + { + err = EMF_ERROR_UNKNOWN; + goto JOB_ERROR; + } + + /* encode mailbox name by UTF7, and rename to full path (ex : {mail.test.com}child_mailbox) */ + if (!em_core_get_long_encoded_path(new_mailbox->account_id, new_mailbox->name, '/', &long_enc_path_new, err_code)) + { + err = EMF_ERROR_UNKNOWN; + goto JOB_ERROR; + } + + /* rename mailbox */ + if (!mail_rename(stream, long_enc_path, long_enc_path_new)) + { + err = EMF_ERROR_UNKNOWN; + goto JOB_ERROR; + } + + EM_SAFE_FREE(long_enc_path); + EM_SAFE_FREE(long_enc_path_new); + + em_core_mailbox_close(0, stream); + stream = NULL; + + imap_mailbox_tbl_item.alias = NULL; + imap_mailbox_tbl_item.mailbox_name = new_mailbox->name; + imap_mailbox_tbl_item.modifiable_yn = 1; + + /* if modified imap mailbox is synchronous mailbox, update mailbox name from imap mailbox table */ + if (!em_storage_update_mailbox(ref_account->account_id, 0, old_mailbox->name, &imap_mailbox_tbl_item, true, &err)) + { + EM_DEBUG_EXCEPTION("em_storage_update_mailbox failed - %d", err); + if (err == EM_STORAGE_ERROR_DB_IS_FULL) + err = EMF_ERROR_MAIL_MEMORY_FULL; + else + err = EMF_ERROR_DB_FAILURE; + goto JOB_ERROR; + } + + ret = true; + +JOB_ERROR: + EM_SAFE_FREE(long_enc_path); + EM_SAFE_FREE(long_enc_path_new); + + if (stream) + { + em_core_mailbox_close(0, stream); + stream = NULL; + } + + if (err_code) + *err_code = err; + + return ret; +} diff --git a/email-core/em-core-mailbox-sync.c b/email-core/em-core-mailbox-sync.c new file mode 100755 index 0000000..8918044 --- /dev/null +++ b/email-core/em-core-mailbox-sync.c @@ -0,0 +1,4007 @@ +/* +* email-service +* +* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. +* +* Contact: Kyuho Jo <kyuho.jo@samsung.com>, Sunghyun Kwon <sh0701.kwon@samsung.com> +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + + +/****************************************************************************** + * File : em-core-mailbox_sync.c + * Desc : Mail Header Sync + * + * Auth : + *****************************************************************************/ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> + +#include "em-core-types.h" + +#include "c-client.h" +#include "lnx_inc.h" + +#include "Msg_Convert.h" +#include "em-core-mailbox-sync.h" +#include "em-core-global.h" +#include "em-core-imap-mailbox.h" +#include "em-core-event.h" +#include "em-core-mailbox.h" +#include "em-core-mesg.h" +#include "em-core-mime.h" +#include "em-core-utils.h" +#include "em-core-smtp.h" +#include "em-core-account.h" +#include "em-storage.h" +#include "flstring.h" +#include "emf-dbglog.h" + +#define MAX_CHARSET_VALUE 256 + +static char g_append_uid_rsp[129]; /* added for getting server response */ + +extern void imap_parse_body_structure (MAILSTREAM *stream, BODY *body, unsigned char **txtptr, IMAPPARSEDREPLY *reply); + +#ifdef __FEATURE_PARTIAL_BODY_DOWNLOAD__ +static emf_partial_buffer *em_core_get_response_from_server (NETSTREAM *nstream, char *tag, IMAPPARSEDREPLY **reply); +static int em_core_initiate_pbd(MAILSTREAM *stream, int account_id, int mail_id, char *uid, char *mailbox, int *err_code); +#endif + +#ifdef __FEATURE_SYNC_CLIENT_TO_SERVER__ +static char g_append_uid_rsp[129]; /* added for getting server response */ +#endif + + +int pop3_mail_calc_rfc822_size(MAILSTREAM *stream, int msgno, int *size, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN(); + + int ret = false; + int err = EMF_ERROR_NONE; + + POP3LOCAL *pop3local = NULL; + char command[16]; + char *response = NULL; + + if (!stream || !size) { + EM_DEBUG_EXCEPTION(" stream[%p], msgno[%d], size[%p]\n", stream, msgno, size); + + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + if (!(pop3local = stream->local) || !pop3local->netstream) { + err = EMF_ERROR_INVALID_STREAM; + goto FINISH_OFF; + } + + memset(command, 0x00, sizeof(command)); + + SNPRINTF(command, sizeof(command), "LIST %d\015\012", msgno); + + /* EM_DEBUG_LOG(" [POP3] >>> %s", command); */ + + /* send command : get rfc822 size by msgno */ + if (!net_sout(pop3local->netstream, command, (int)strlen(command))) { + EM_DEBUG_EXCEPTION(" net_sout failed..."); + + err = EMF_ERROR_INVALID_RESPONSE; + goto FINISH_OFF; + } + + /* receive response */ + if (!(response = net_getline(pop3local->netstream))) { + err = EMF_ERROR_CONNECTION_BROKEN; /* EMF_ERROR_UNKNOWN; */ + goto FINISH_OFF; + } + + /* EM_DEBUG_LOG(" [POP3] <<< %s", response); */ + + if (*response == '+') { /* "+ OK" */ + char *p = NULL; + + if (!(p = strchr(response + strlen("+OK "), ' '))) { + err = EMF_ERROR_INVALID_RESPONSE; + goto FINISH_OFF; + } + + *size = atoi(p + 1); + } + else if (*response == '-') { /* "- ERR" */ + err = EMF_ERROR_POP3_LIST_FAILURE; + goto FINISH_OFF; + } + else { + err = EMF_ERROR_INVALID_RESPONSE; + goto FINISH_OFF; + } + + ret = true; + +FINISH_OFF: + EM_SAFE_FREE(response); + + if (err_code != NULL) + *err_code = err; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +int imap4_mail_calc_rfc822_size(MAILSTREAM *stream, int msgno, int *size, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN(); + + int ret = false; + int err = EMF_ERROR_NONE; + + IMAPLOCAL *imaplocal = NULL; + char tag[32], command[128]; + char *response = NULL; + + if (!stream || !size) { + EM_DEBUG_EXCEPTION("stream[%p], msgno[%d], size[%p]", stream, msgno, size); + + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + if (!(imaplocal = stream->local) || !imaplocal->netstream) { + err = EMF_ERROR_INVALID_STREAM; + goto FINISH_OFF; + } + + memset(tag, 0x00, sizeof(tag)); + memset(command, 0x00, sizeof(command)); + + SNPRINTF(tag, sizeof(tag), "%08lx", 0xffffffff & (stream->gensym++)); + SNPRINTF(command, sizeof(command), "%s FETCH %d RFC822.SIZE\015\012", tag, msgno); + + /* EM_DEBUG_LOG(" [IMAP4] >>> %s", command); */ + + /* send command : get rfc822 size by msgno */ + if (!net_sout(imaplocal->netstream, command, (int)strlen(command))) { + EM_DEBUG_EXCEPTION(" net_sout failed..."); + + err = EMF_ERROR_INVALID_RESPONSE; + goto FINISH_OFF; + } + + while (imaplocal->netstream) { + char *s = NULL; + char *t = NULL; + + /* receive response */ + if (!(response = net_getline(imaplocal->netstream))) + break; + + /* EM_DEBUG_LOG(" [IMAP4] <<< %s", response); */ + + if (!strncmp(response, tag, strlen(tag))) { + if (!strncmp(response + strlen(tag) + 1, "OK", 2)) { + EM_SAFE_FREE(response); + break; + } + else { /* 'NO' or 'BAD' */ + err = EMF_ERROR_IMAP4_FETCH_SIZE_FAILURE; /* EMF_ERROR_INVALID_RESPONSE; */ + goto FINISH_OFF; + } + } + else { /* untagged response */ + if (*response == '*') { + if (!(t = strstr(response, "FETCH (RFC822.SIZE "))) { + EM_SAFE_FREE(response); + continue; + } + + s = t + strlen("FETCH (RFC822.SIZE "); + + if (!(t = strchr(s, ' '))) { + err = EMF_ERROR_INVALID_RESPONSE; + goto FINISH_OFF; + } + + *t = '\0'; + + *size = atoi(s); + } + } + + EM_SAFE_FREE(response); + } + + ret = true; + +FINISH_OFF: + EM_SAFE_FREE(response); + + if (err_code != NULL) + *err_code = err; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +int pop3_mailbox_get_uids(MAILSTREAM *stream, em_core_uid_list** uid_list, int *err_code) +{ + EM_PROFILE_BEGIN(pop3MailboxGetuid); + EM_DEBUG_FUNC_BEGIN("stream[%p], uid_list[%p], err_code[%p]", stream, uid_list, err_code); + + int ret = false; + int err = EMF_ERROR_NONE; + + POP3LOCAL *pop3local = NULL; + char command[64]; + char *response = NULL; + em_core_uid_list *uid_elem = NULL; + + if (!stream || !uid_list) { + EM_DEBUG_EXCEPTION("stream[%p], uid_list[%p]n", stream, uid_list); + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + if (!(pop3local = stream->local) || !pop3local->netstream) { + EM_DEBUG_EXCEPTION("invalid POP3 stream detected..."); + err = EMF_ERROR_INVALID_STREAM; + goto FINISH_OFF; + } + + memset(command, 0x00, sizeof(command)); + + SNPRINTF(command, sizeof(command), "UIDL\015\012"); + +#ifdef FEATURE_CORE_DEBUG + EM_DEBUG_LOG(" [POP3] >>> [%s]", command); +#endif + + /* send command : get msgno/uid for all message */ + if (!net_sout(pop3local->netstream, command, (int)strlen(command))) { + EM_DEBUG_EXCEPTION("net_sout failed..."); + err = EMF_ERROR_CONNECTION_BROKEN; /* EMF_ERROR_UNKNOWN; */ + goto FINISH_OFF; + } + + *uid_list = NULL; + + while (pop3local->netstream) { + char *p = NULL; + + /* receive response */ + if (!(response = net_getline(pop3local->netstream))) { + EM_DEBUG_EXCEPTION("net_getline failed..."); + err = EMF_ERROR_INVALID_RESPONSE; + goto FINISH_OFF; + } + +#ifdef FEATURE_CORE_DEBUG + EM_DEBUG_LOG(" [POP3] <<< [%s]", response); +#endif + + if (*response == '-') { /* "-ERR" */ + err = EMF_ERROR_POP3_UIDL_FAILURE; /* EMF_ERROR_INVALID_RESPONSE; */ + goto FINISH_OFF; + } + + if (*response == '+') { /* "+OK" */ + free(response); response = NULL; + continue; + } + + if (*response == '.') { + free(response); response = NULL; + break; + } + + if ((p = strchr(response, ' '))) { + *p = '\0'; + + if (!(uid_elem = em_core_malloc(sizeof(em_core_uid_list)))) { + EM_DEBUG_EXCEPTION("malloc failed..."); + err = EMF_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + uid_elem->msgno = atoi(response); + uid_elem->uid = EM_SAFE_STRDUP(p + 1); + + if (*uid_list != NULL) + uid_elem->next = *uid_list; /* prepend new data to table */ + + *uid_list = uid_elem; + } + else { + err = EMF_ERROR_INVALID_RESPONSE; + goto FINISH_OFF; + } + + free(response); response = NULL; + } + + ret = true; + +FINISH_OFF: + if (response != NULL) + free(response); + + if (err_code != NULL) + *err_code = err; + + EM_PROFILE_END(pop3MailboxGetuid); + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +int imap4_mailbox_get_uids(MAILSTREAM *stream, em_core_uid_list** uid_list, int *err_code) +{ + EM_PROFILE_BEGIN(ImapMailboxGetUids); + EM_DEBUG_FUNC_BEGIN("stream[%p], uid_list[%p], err_code[%p]", stream, uid_list, err_code); + + int ret = false; + int err = EMF_ERROR_NONE; + + IMAPLOCAL *imaplocal = NULL; + char tag[16], command[64]; + char *response = NULL; + em_core_uid_list *uid_elem = NULL; + + if (!stream || !uid_list) { + EM_DEBUG_EXCEPTION("stream[%p], uid_list[%p]", stream, uid_list); + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + if (!(imaplocal = stream->local) || !imaplocal->netstream) { + EM_DEBUG_EXCEPTION("invalid IMAP4 stream detected..."); + err = EMF_ERROR_INVALID_PARAM; /* EMF_ERROR_UNKNOWN */ + goto FINISH_OFF; + } + + if (stream->nmsgs == 0){ + err = EMF_ERROR_MAIL_NOT_FOUND_ON_SERVER; + goto FINISH_OFF; + } + memset(tag, 0x00, sizeof(tag)); + memset(command, 0x00, sizeof(command)); + + SNPRINTF(tag, sizeof(tag), "%08lx", 0xffffffff & (stream->gensym++)); + SNPRINTF(command, sizeof(command), "%s FETCH 1:* (FLAGS UID)\015\012", tag); /* TODO : confirm me */ + EM_DEBUG_LOG("COMMAND [%s] \n", command); +#ifdef FEATURE_CORE_DEBUG + EM_DEBUG_LOG(" [IMAP4] >>> [%s]", command); +#endif + + /* send command : get msgno/uid for all message */ + if (!net_sout(imaplocal->netstream, command, (int)strlen(command))) { + EM_DEBUG_EXCEPTION(" net_sout failed...\n"); + err = EMF_ERROR_CONNECTION_BROKEN; + goto FINISH_OFF; + } + + *uid_list = NULL; + + while (imaplocal->netstream) { + char *p = NULL; + char *s = NULL; + int seen = 0; + int forwarded = 0; + int draft = 0; + /* receive response */ + if (!(response = net_getline(imaplocal->netstream))) { + EM_DEBUG_EXCEPTION("net_getline failed..."); + err = EMF_ERROR_INVALID_RESPONSE; + goto FINISH_OFF; + } + +#ifdef FEATURE_CORE_DEBUG + EM_DEBUG_LOG(" [IMAP4] <<< [%s]", response); +#endif + + if (!strncmp(response, tag, strlen(tag))) { + if (!strncmp(response + strlen(tag) + 1, "OK", 2)) { + free(response); response = NULL; + break; + } + else { /* 'NO' or 'BAD' */ + err = EMF_ERROR_IMAP4_FETCH_UID_FAILURE; /* EMF_ERROR_INVALID_RESPONSE; */ + goto FINISH_OFF; + } + } + + if ((p = strstr(response, " FETCH ("))) { + if (!strstr(p, "\\Deleted")) { /* undeleted only */ + *p = '\0'; p += strlen(" FETCH "); + + seen = strstr(p, "\\Seen") ? 1 : 0; + draft = strstr(p, "\\Draft") ? 1 : 0; + forwarded = strstr(p, "$Forwarded") ? 1 : 0; + + if ((p = strstr(p, "UID "))) { + s = p + strlen("UID "); + + while (isdigit(*s)) + s++; + + *s = '\0'; + + if (!(uid_elem = em_core_malloc(sizeof(em_core_uid_list)))) { + EM_DEBUG_EXCEPTION("em_core_malloc failed..."); + err = EMF_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + uid_elem->msgno = atoi(response + strlen("* ")); + uid_elem->uid = EM_SAFE_STRDUP(p + strlen("UID ")); + uid_elem->flag.seen = seen; + uid_elem->flag.draft = draft; + uid_elem->flag.forwarded = forwarded; + if (*uid_list != NULL) + uid_elem->next = *uid_list; /* prepend new data to list */ + + *uid_list = uid_elem; + } + else { + err = EMF_ERROR_INVALID_RESPONSE; + goto FINISH_OFF; + } + } + } + else { + err = EMF_ERROR_INVALID_RESPONSE; + goto FINISH_OFF; + } + + EM_SAFE_FREE(response);; + } + + ret = true; + +FINISH_OFF: + EM_SAFE_FREE(response); + + if (err_code != NULL) + *err_code = err; + + EM_PROFILE_END(ImapMailboxGetUids); + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +static char *__em_get_month_in_string(int month) +{ + EM_DEBUG_FUNC_BEGIN("month [%d]", month); + + char *mon = NULL; + + switch (month){ + case 0: + mon = EM_SAFE_STRDUP("jan"); + break; + case 1: + mon = EM_SAFE_STRDUP("feb"); + break; + case 2: + mon = EM_SAFE_STRDUP("mar"); + break; + case 3: + mon = EM_SAFE_STRDUP("apr"); + break; + case 4: + mon = EM_SAFE_STRDUP("may"); + break; + case 5: + mon = EM_SAFE_STRDUP("jun"); + break; + case 6: + mon = EM_SAFE_STRDUP("jul"); + break; + case 7: + mon = EM_SAFE_STRDUP("aug"); + break; + case 8: + mon = EM_SAFE_STRDUP("sep"); + break; + case 9: + mon = EM_SAFE_STRDUP("oct"); + break; + case 10: + mon = EM_SAFE_STRDUP("nov"); + break; + case 11: + mon = EM_SAFE_STRDUP("dec"); + break; + } + return mon; +} + +int imap4_mailbox_get_uids_by_timestamp(MAILSTREAM *stream, em_core_uid_list** uid_list, int *err_code) +{ + EM_PROFILE_BEGIN(emCoreMailboxuidsbystamp); + EM_DEBUG_FUNC_BEGIN("stream[%p], uid_list[%p], err_code[%p]", stream, uid_list, err_code); + + int ret = false; + int err = EMF_ERROR_NONE; + + IMAPLOCAL *imaplocal = NULL; + char tag[16], command[64]; + char *response = NULL; + em_core_uid_list *uid_elem = NULL; + char delims[] = " "; + char *result = NULL; + + struct tm *timeinfo = NULL; + time_t RawTime = 0; + time_t week_before_RawTime = 0; + char date_string[16]; + char *mon = NULL; + + if (!stream || !uid_list) { + EM_DEBUG_EXCEPTION(" stream[%p], uid_list[%p]", stream, uid_list); + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + if (!(imaplocal = stream->local) || !imaplocal->netstream) { + EM_DEBUG_EXCEPTION(" invalid IMAP4 stream detected..."); + err = EMF_ERROR_INVALID_PARAM; /* EMF_ERROR_UNKNOWN */ + goto FINISH_OFF; + } + + /* Fetch the System time and Retrieve the a Week before time */ + /* tzset(); */ + time(&RawTime); + + EM_DEBUG_LOG("RawTime Info [%lu]", RawTime); + + timeinfo = localtime (&RawTime); + + EM_DEBUG_LOG(">>>>>Current TIme %d %d %d %d %d %d", 1900+timeinfo->tm_year, timeinfo->tm_mon+1, timeinfo->tm_mday); + + week_before_RawTime = RawTime - 604800; + + /* Reading the current timeinfo */ + timeinfo = localtime (&week_before_RawTime); + + EM_DEBUG_LOG(">>>>>Mobile Date a Week before %d %d %d %d %d %d", 1900 + timeinfo->tm_year, timeinfo->tm_mon+1, timeinfo->tm_mday); + + memset(&date_string, 0x00, 16); + + mon = __em_get_month_in_string(timeinfo->tm_mon); + + if (mon){ + snprintf(date_string, 16, "%d-%s-%04d", timeinfo->tm_mday, mon, 1900 + timeinfo->tm_year); + EM_DEBUG_LOG("DATE IS [ %s ] ", date_string); + EM_SAFE_FREE(mon); + } + + memset(tag, 0x00, sizeof(tag)); + memset(command, 0x00, sizeof(command)); + + SNPRINTF(tag, sizeof(tag), "%08lx", 0xffffffff & (stream->gensym++)); + + /* SNPRINTF(command, sizeof(command), "%s UID SEARCH 1:* SINCE 17-Aug-2009\015\012", tag, date_string); */ /* TODO : confirm me */ + + SNPRINTF(command, sizeof(command), "%s UID SEARCH 1:* SINCE %s\015\012", tag, date_string); /* TODO : confirm me */ + + EM_DEBUG_LOG("COMMAND [%s] ", command); + + +#ifdef FEATURE_CORE_DEBUG + EM_DEBUG_LOG(" [IMAP4] >>> [%s]", command); +#endif + + /* send command : get msgno/uid for all message */ + if (!net_sout(imaplocal->netstream, command, (int)strlen(command))) { + EM_DEBUG_EXCEPTION(" net_sout failed..."); + err = EMF_ERROR_CONNECTION_BROKEN; /* EMF_ERROR_UNKNOWN */ + goto FINISH_OFF; + } + + *uid_list = NULL; + + while (imaplocal->netstream) { + char *p = NULL; + /* receive response */ + if (!(response = net_getline(imaplocal->netstream))) { + EM_DEBUG_EXCEPTION(" net_getline failed..."); + err = EMF_ERROR_INVALID_RESPONSE; /* EMF_ERROR_UNKNOWN; */ + goto FINISH_OFF; + } +#ifdef FEATURE_CORE_DEBUG + EM_DEBUG_LOG(" [IMAP4] <<< [%s]", response); +#endif + + if (!strncmp(response, tag, strlen(tag))) { + if (!strncmp(response + strlen(tag) + 1, "OK", 2)) { + free(response); response = NULL; + break; + } + else { /* 'NO' or 'BAD' */ + err = EMF_ERROR_IMAP4_FETCH_UID_FAILURE; /* EMF_ERROR_INVALID_RESPONSE; */ + goto FINISH_OFF; + } + } + + if ((p = strstr(response, " SEARCH "))){ + *p = '\0'; p += strlen(" SEARCH "); + + result = strtok(p, delims); + + while (result != NULL) + { + EM_DEBUG_LOG("UID VALUE DEEP is [%s]", result); + + if (!(uid_elem = em_core_malloc(sizeof(em_core_uid_list)))) { + EM_DEBUG_EXCEPTION(" malloc failed..."); + err = EMF_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + uid_elem->uid = EM_SAFE_STRDUP(result); + + if (*uid_list != NULL) + uid_elem->next = *uid_list; + *uid_list = uid_elem; + result = strtok(NULL, delims); + } + + EM_SAFE_FREE(response); + return 1; + } + else { + err = EMF_ERROR_INVALID_RESPONSE; + goto FINISH_OFF; + } + + free(response); response = NULL; + } + + ret = true; + +FINISH_OFF: + if (response != NULL) + free(response); + + if (err_code != NULL) + *err_code = err; + EM_PROFILE_END(emCoreMailboxuidsbystamp); + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +#define PARSE_BUFFER_LENGTH 4096 +static int em_core_mailbox_parse_header(char *rfc822_header, int *req_read_receipt, int *priority, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("rfc822_header[%p], req_read_receipt[%p], priority[%p], err_code[%p]", rfc822_header, req_read_receipt, priority, err_code); + + if (!rfc822_header || !priority) + return false; + + if (err_code) + *err_code = EMF_ERROR_NONE; + + EM_PROFILE_BEGIN(emCoreMailboxParseHeader); + + /* char *buf = NULL; */ + char buf[PARSE_BUFFER_LENGTH]; + int len, i, j; + /* int buf_length = strlen(rfc822_header)+1; */ + + EM_DEBUG_LOG("Buffer length [%d]", PARSE_BUFFER_LENGTH); + /* + buf = (char *) malloc(sizeof(char) * (buf_length)); + + if (!buf) { + EM_DEBUG_EXCEPTION("buf is NULL"); + return false; + } + */ + *priority = 3; + + memset(buf, 0x00, PARSE_BUFFER_LENGTH); + + for (len = strlen(rfc822_header), i = 0, j = 0; i < len; i++) { + if (rfc822_header[i] == CR && rfc822_header[i+1] == LF){ + if (j + 3 < PARSE_BUFFER_LENGTH) /* '3' include CR LF NULL */ + strncpy(buf + j, CRLF_STRING, PARSE_BUFFER_LENGTH - (j + 2)); /* '3' include CR LF */ + else + EM_DEBUG_EXCEPTION("buf is too small."); + + i++; + j = 0; + + /* parsing data */ + em_core_upper_string(buf); + + /* message-id */ +/* if (buf[0] == 'M' && buf[3] == 'S' && buf[6] == 'E' && buf[7] == '-' && buf[8] == 'I') { */ +/* buf[strlen(buf)-2] = '\0'; */ +/* if (buf[12]) *message_id = EM_SAFE_STRDUP(buf+12); */ +/* memset(buf, 0x00, sizeof(buf)); */ +/* continue; */ +/* } */ + + /* disposition_notification_to */ + if (buf[0] == 'D' && buf[11] == '-' && buf[12] == 'N' && buf[24] == '-' && buf[25] == 'T') { + if (req_read_receipt) + *req_read_receipt = 1; + memset(buf, 0x00, PARSE_BUFFER_LENGTH); + continue; + } + + /* x-priority */ + if (buf[0] == 'X' && buf[2] == 'P' && buf[9] == 'Y'){ + size_t len_2 = strlen(buf); + if (len_2 >= 12){ + buf[len_2 - 2] = '\0'; + *priority = atoi(buf + 11); + memset(buf, 0x00, PARSE_BUFFER_LENGTH); + continue; + } + } + + /* x-msmail-priority */ + if (buf[0] == 'X' && buf[2] == 'M' && buf[9] == 'P' && buf[16] == 'Y'){ + if (strstr(buf, "HIGH")) + *priority = 1; + if (strstr(buf, "NORMAL")) + *priority = 3; + if (strstr(buf, "LOW")) + *priority = 5; + memset(buf, 0x00, PARSE_BUFFER_LENGTH); + continue; + } + + memset(buf, 0x00, PARSE_BUFFER_LENGTH); + continue; + } + + if (j + 1 < PARSE_BUFFER_LENGTH) + buf[j++] = rfc822_header[i]; + else + EM_DEBUG_EXCEPTION("buf is too small."); + } + + /* + EM_SAFE_FREE(buf); + */ + EM_PROFILE_END(emCoreMailboxParseHeader); + + if (err_code) + *err_code = EMF_ERROR_NONE; + + return true; +} + + +static int em_core_mail_get_extra_info(MAILSTREAM *stream, int msgno, int *req_read_receipt, int *priority, int *err_code) +{ + EM_PROFILE_BEGIN(emCoreMailGetExtraInfo); + EM_DEBUG_FUNC_BEGIN("stream[%p], msgno[%d], req_read_receipt[%p], priority[%p], err_code[%p]", stream, msgno, req_read_receipt, priority, err_code); + + int ret = false; + int err = EMF_ERROR_NONE; + char *rfc822_header = NULL; + unsigned long len = 0; + + EM_PROFILE_BEGIN(MaiFetchHeader); +#ifdef __FEATURE_HEADER_OPTIMIZATION__ + /* Check if header already available in cache */ + if (stream && stream->cache && stream->cache[msgno-1]->private.msg.header.text.data){ + EM_DEBUG_LOG("I found the header in stream->cache!!"); + rfc822_header = (char *) stream->cache[msgno-1]->private.msg.header.text.data; + } + else{ + EM_DEBUG_LOG("I couldn't find the header. I'll fetch the header from server again."); + if (stream) + rfc822_header = mail_fetch_header(stream, msgno, NULL, NULL, &len, FT_PEEK); + } + +#else + rfc822_header = mail_fetch_header(stream, msgno, NULL, NULL, &len, FT_PEEK); +#endif + EM_PROFILE_END(MaiFetchHeader); + + if (!rfc822_header || !*rfc822_header) { + EM_DEBUG_EXCEPTION("mail_fetch_header failed..."); + err = EMF_ERROR_IMAP4_FETCH_UID_FAILURE; /* EMF_ERROR_UNKNOWN; */ + goto FINISH_OFF; + } + + if (!em_core_mailbox_parse_header(rfc822_header, req_read_receipt, priority, &err)) { + EM_DEBUG_EXCEPTION("em_core_mailbox_parse_header falied - %d", err); + goto FINISH_OFF; + } + ret = true; + +FINISH_OFF: + + if (err_code != NULL) + *err_code = err; + + EM_PROFILE_END(emCoreMailGetExtraInfo); + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +static int em_core_mailbox_get_uids_to_download(MAILSTREAM *stream, emf_account_t *account, emf_mailbox_tbl_t *input_mailbox_tbl, int limit_count, em_core_uid_list** uid_list, int *uids, int retrieve_mode , int *err_code) +{ + EM_PROFILE_BEGIN(emCoreGetUidsDownload); + EM_DEBUG_FUNC_BEGIN("account[%p], input_mailbox_tbl[%p], limit_count[%d], uid_list[%p], err_code[%p]", account, input_mailbox_tbl, limit_count, uid_list, err_code); + + int ret = false; + int err = EMF_ERROR_NONE; + + emf_mail_read_mail_uid_tbl_t *downloaded_uids = NULL; + emf_mail_info_t *mail_info = NULL; + int i = 0, j = 0, uid_count = 0, uid_to_be_downloaded_count = 0; + em_core_uid_list *uid_elem = NULL; + em_core_uid_list *head_uid_elem = NULL, *end = NULL; + em_core_uid_list *next_uid_elem = NULL; + emf_mail_tbl_t *mail = NULL; + + if (!account || !input_mailbox_tbl || !uid_list) { + EM_DEBUG_EXCEPTION("account[%p], input_mailbox_tbl[%p], uid_list[%p]", account, input_mailbox_tbl, uid_list); + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + *uid_list = NULL; + + if (account->receiving_server_type == EMF_SERVER_TYPE_POP3) { + if (!pop3_mailbox_get_uids(stream, uid_list, &err)) { + EM_DEBUG_EXCEPTION("pop3_mailbox_get_uids failed - %d", err); + goto FINISH_OFF; + } + } + else { /* EMF_SERVER_TYPE_IMAP4 */ + /* sowmya.kr commented , since imap4_mailbox_get_uids_by_timestamp will fetch mails since last week and not all mails */ + + EM_DEBUG_LOG("calling imap4_mailbox_get_uids"); + if (!imap4_mailbox_get_uids(stream, uid_list, &err)) { + EM_DEBUG_EXCEPTION("imap4_mailbox_get_uids failed [%d]", err); + if (err != EMF_ERROR_MAIL_NOT_FOUND_ON_SERVER) + goto FINISH_OFF; + } + } + + if (!em_storage_get_downloaded_list(input_mailbox_tbl->account_id, input_mailbox_tbl->mailbox_name, &downloaded_uids, &j, true, &err)) { + EM_DEBUG_EXCEPTION("em_storage_get_downloaded_list failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + EM_DEBUG_LOG("Number of Mails in Downloaded Table [%d]", j); + + uid_elem = *uid_list; + uid_count = 0; + + if(!uid_elem) { /* If there is no mail in the input_mailbox_tbl, remove all mails in the input_mailbox_tbl */ + for (i = 0; i < j; i++) { + downloaded_uids[i].reserved = 0; + } + } + + EM_PROFILE_BEGIN(emCoreGetUidsDownloadWhilwLoop); + + while (uid_elem) { + next_uid_elem = uid_elem->next; + + if ((account->retrieval_mode == EMF_IMAP4_RETRIEVAL_MODE_NEW) && (uid_elem->flag.seen != 0)){ /* already seen */ + if (uid_elem->uid) + free(uid_elem->uid); + + free(uid_elem); + } + else { + int to_be_downloaded = 1; + + if (limit_count > 0 && uid_count >= limit_count){ + /* EM_DEBUG_LOG("hit the limit[%d] for [%s]", limit_count, uid_elem->uid); */ + to_be_downloaded = 0; + } + else{ + for (i = j; i > 0; i--) { + if (downloaded_uids[i - 1].reserved == 0 && !strcmp(uid_elem->uid, downloaded_uids[i - 1].s_uid)) { + downloaded_uids[i - 1].reserved = uid_elem->flag.seen ? 2 : 1; + to_be_downloaded = 0; + break; + } + } + } + + /* EM_DEBUG_LOG("Is uid[%s] going to be downloded ? [%d]", uid_elem->uid, to_be_downloaded); */ + + if (to_be_downloaded) { + if (retrieve_mode == EMF_SYNC_OLDEST_MAILS_FIRST){ + uid_elem->next = head_uid_elem; + head_uid_elem = uid_elem; + } + else{ /* if retrieve_mode is EMF_SYNC_LATEST_MAILS_FIRST, add uid elem to end so that latest mails are in front of list */ + if (head_uid_elem == NULL){ + uid_elem->next = head_uid_elem; + head_uid_elem = uid_elem; + end = head_uid_elem; + } + else{ + end->next = uid_elem; + uid_elem->next = NULL; + end = uid_elem; + } + } + uid_to_be_downloaded_count++; + + } + else { + if (uid_elem->uid) + free(uid_elem->uid); + free(uid_elem); + } + + uid_count++; + } + + uid_elem = next_uid_elem; + } + + EM_PROFILE_END(emCoreGetUidsDownloadWhilwLoop); + EM_PROFILE_BEGIN(emCoreGetUidsDownloadForLoop); + + for (i = 0; i < j; i++) { + /* EM_DEBUG_LOG("input_mailbox_tbl[%s] reserved[%d]", input_mailbox_tbl->name, downloaded_uids[i].reserved); */ + if (downloaded_uids[i].reserved == 0) { /* deleted on server */ + if (!em_storage_get_maildata_by_servermailid(input_mailbox_tbl->account_id, downloaded_uids[i].s_uid, &mail, true, &err)){ + EM_DEBUG_EXCEPTION("em_storage_get_maildata_by_servermailid for uid[%s] Failed [%d] \n ", downloaded_uids[i].s_uid, err); + if (err == EM_STORAGE_ERROR_MAIL_NOT_FOUND){ + continue; + } + } + + if (account->receiving_server_type == EMF_SERVER_TYPE_IMAP4) { + if (!em_core_mail_delete_from_local(input_mailbox_tbl->account_id, &(mail->mail_id), 1, EMF_DELETED_FROM_SERVER, false, &err)) { + EM_DEBUG_EXCEPTION("em_core_mail_delete_from_local falied - %d", err); + goto FINISH_OFF; + } + /* em_core_delete_notification_for_read_mail(mail->mail_id); */ + em_core_check_unread_mail(); + } + + if (!em_storage_remove_downloaded_mail(input_mailbox_tbl->account_id, input_mailbox_tbl->mailbox_name, downloaded_uids[i].s_uid, true, &err)) { /* remove uid from uid list */ + EM_DEBUG_EXCEPTION("em_storage_remove_downloaded_mail failed - %d", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + /* goto FINISH_OFF; */ + } + + } + else if (account->receiving_server_type == EMF_SERVER_TYPE_IMAP4 && downloaded_uids[i].reserved == 1) { + /* unseen on server */ + if (!em_core_mail_get_info(downloaded_uids[i].local_uid, &mail_info, &err)){ + EM_DEBUG_EXCEPTION("em_core_mail_get_info failed for [%d] - [%d]", downloaded_uids[i].local_uid, err); + continue; + } + + if (mail_info) { + if (mail_info->body_downloaded && mail_info->flags.seen){ + EM_DEBUG_LOG("Set flag as seen on server"); + mail_setflag_full(stream, downloaded_uids[i].s_uid, "\\Seen", ST_UID); + } + em_core_mail_info_free(&mail_info, 1, NULL); + mail_info = NULL; + } + + } + } + EM_PROFILE_END(emCoreGetUidsDownloadForLoop); + + *uid_list = head_uid_elem; + *uids = uid_to_be_downloaded_count; + + ret = true; + +FINISH_OFF: + if (ret == false){ + if (head_uid_elem) + em_core_mailbox_free_uids(head_uid_elem, NULL); + } + + if (mail_info != NULL) + em_core_mail_info_free(&mail_info, 1, NULL); + + if (downloaded_uids != NULL) + em_storage_free_read_mail_uid(&downloaded_uids, j, NULL); + + if (mail != NULL) + em_storage_free_mail(&mail, 1, NULL); + + if (err_code != NULL) + *err_code = err; + + EM_PROFILE_END(emCoreGetUidsDownload); + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +/* insert received mail UID to read mail uid table */ +static int em_core_mailbox_add_read_mail_uid(emf_mailbox_tbl_t *input_maibox_data, char *server_mailbox_name, int mail_id, char *uid, int rfc822_size, int rule_id, int *err_code) +{ + EM_PROFILE_BEGIN(emCoreMailboxAddReadMailUid); + EM_DEBUG_FUNC_BEGIN("input_maibox_data[%p], server_mailbox_name[%s], uid[%s], rfc822_size[%d], rule_id[%d], err_code[%p]", input_maibox_data, server_mailbox_name, uid, rfc822_size, rule_id, err_code); + + int ret = false; + int err = EMF_ERROR_NONE; + + emf_mail_read_mail_uid_tbl_t read_mail_uid = { 0 }; + char *mailbox_name = NULL; + + if (!input_maibox_data || !uid) { + EM_DEBUG_EXCEPTION("EMF_ERROR_INVALID_PARAM"); + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + read_mail_uid.account_id = input_maibox_data->account_id; + + if (!(input_maibox_data->mailbox_name) || !(server_mailbox_name)){ + if (!em_storage_get_mailboxname_by_mailbox_type(input_maibox_data->account_id, EMF_MAILBOX_TYPE_INBOX, &mailbox_name, false, &err)) { + EM_DEBUG_EXCEPTION("em_storage_get_mailboxname_by_mailbox_type failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + } + + if (input_maibox_data->mailbox_name) + read_mail_uid.local_mbox = input_maibox_data->mailbox_name; + else + read_mail_uid.local_mbox = mailbox_name; + + read_mail_uid.local_uid = mail_id; + EM_DEBUG_LOG("MAIL ID [%d] LOCAL_UID [%d]", mail_id, read_mail_uid.local_uid); + + if (server_mailbox_name) + read_mail_uid.mailbox_name = server_mailbox_name; + else + read_mail_uid.mailbox_name = mailbox_name; + + read_mail_uid.s_uid = uid; + read_mail_uid.data1 = rfc822_size; + read_mail_uid.flag = rule_id; + + if (!em_storage_add_downloaded_mail(&read_mail_uid, false, &err)) { + EM_DEBUG_EXCEPTION("em_storage_add_downloaded_mail failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + + ret = true; + +FINISH_OFF: + EM_SAFE_FREE(mailbox_name); + + if (err_code) + *err_code = err; + + EM_PROFILE_END(emCoreMailboxAddReadMailUid); + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +static int em_core_mail_add_header(MAILSTREAM *mail_stream, emf_mailbox_tbl_t *input_maibox_data, emf_mail_head_t *head, int to_num, em_core_uid_list *uid_elem, int *mail_id, int *result_thread_id, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("mail_stream [%p], input_maibox_data[%p], head[%p], to_num[%d], uid_elem[%p], mail_id[%p], err_code[%p]", mail_stream, input_maibox_data, head, to_num, uid_elem, mail_id, err_code); + + int ret = false, err = EMF_ERROR_NONE; + int req_read_receipt = 0; + int priority = 0; + int thread_id = -1, thread_item_count = 0, latest_mail_id_in_thread = -1; + char datetime[16] = { 0, }; + MESSAGECACHE *elt = NULL; + emf_mail_tbl_t mail_table_data = {0}; + + if (!input_maibox_data || !mail_stream || !head || !uid_elem) { + EM_DEBUG_EXCEPTION("Invalid Parameter"); + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + if (!(elt = mail_elt(mail_stream, uid_elem->msgno))) { + EM_DEBUG_EXCEPTION("mail_elt failed..."); + err = EMF_ERROR_UNKNOWN; + goto FINISH_OFF; + } + + if (!em_core_mail_get_extra_info(mail_stream, uid_elem->msgno, &req_read_receipt, &priority, &err)) { + EM_DEBUG_EXCEPTION("em_core_mail_get_extra_info failed - %d", err); + goto FINISH_OFF; + } + + SNPRINTF(datetime, sizeof(datetime), "%04d%02d%02d%02d%02d%02d", BASEYEAR + elt->year, elt->month, elt->day, elt->hours, elt->minutes, elt->seconds); + + head->datetime.year = elt->year; + head->datetime.month = elt->month; + head->datetime.day = elt->day; + head->datetime.hour = elt->hours; + head->datetime.minute = elt->minutes; + head->datetime.second = elt->seconds; + + mail_table_data.account_id = input_maibox_data->account_id; + mail_table_data.mailbox_name = input_maibox_data->mailbox_name; + mail_table_data.mailbox_type = input_maibox_data->mailbox_type; + mail_table_data.subject = head->subject; + mail_table_data.datetime = EM_SAFE_STRDUP(datetime); + mail_table_data.server_mail_status = 1; + mail_table_data.server_mail_id = uid_elem->uid; + mail_table_data.message_id = head->mid; + mail_table_data.full_address_from = head->from; + mail_table_data.full_address_to = head->to; + mail_table_data.full_address_cc = head->cc; + mail_table_data.full_address_bcc = head->bcc; + mail_table_data.full_address_reply = head->reply_to; + mail_table_data.full_address_return = head->return_path; + mail_table_data.mail_size = elt->rfc822_size; + mail_table_data.flags_seen_field = uid_elem->flag.seen; + mail_table_data.flags_deleted_field = elt->deleted; + mail_table_data.flags_flagged_field = elt->flagged; + mail_table_data.flags_answered_field = elt->answered; + mail_table_data.flags_recent_field = elt->recent; + mail_table_data.flags_draft_field = elt->draft; + mail_table_data.flags_forwarded_field = uid_elem->flag.forwarded; + mail_table_data.priority = priority; + mail_table_data.report_status = (req_read_receipt ? 3 : 0); + mail_table_data.attachment_count = 0; + + em_core_fill_address_information_of_mail_tbl(&mail_table_data); + + em_storage_begin_transaction(NULL, NULL, NULL); + + /* Get the Mail_id */ + if (!em_storage_increase_mail_id(&(mail_table_data.mail_id), false, &err)) { + EM_DEBUG_EXCEPTION("em_storage_increase_mail_id failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + + if (em_storage_get_thread_id_of_thread_mails(&mail_table_data, &thread_id, &latest_mail_id_in_thread, &thread_item_count) != EMF_ERROR_NONE) + EM_DEBUG_LOG(" em_storage_get_thread_id_of_thread_mails is failed."); + + if (thread_id == -1){ + mail_table_data.thread_id = mail_table_data.mail_id; + mail_table_data.thread_item_count = thread_item_count = 1; + } + else { + mail_table_data.thread_id = thread_id; + thread_item_count++; + } + + if (result_thread_id) + *result_thread_id = mail_table_data.thread_id; + + EM_DEBUG_LOG("mail_table_data.mail_id [%d]", mail_table_data.mail_id); + EM_DEBUG_LOG("mail_table_data.thread_id [%d]", mail_table_data.thread_id); + + if (!em_storage_add_mail(&mail_table_data, 0, false, &err)) { + EM_DEBUG_EXCEPTION("em_storage_add_mail failed [%d]", err); + em_storage_rollback_transaction(NULL, NULL, NULL); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + + if (thread_item_count > 1){ + if (!em_storage_update_latest_thread_mail(mail_table_data.account_id, mail_table_data.thread_id, 0, 0, false, &err)) { + EM_DEBUG_EXCEPTION("em_storage_update_latest_thread_mail failed [%d]", err); + em_storage_rollback_transaction(NULL, NULL, NULL); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + } + + if (mail_id != NULL) + *mail_id = mail_table_data.mail_id; + + if (!em_core_mailbox_add_read_mail_uid(input_maibox_data, input_maibox_data->mailbox_name, mail_table_data.mail_id, uid_elem->uid, mail_table_data.mail_size, 0, &err)) { + EM_DEBUG_EXCEPTION("em_core_mailbox_add_read_mail_uid failed [%d]", err); + em_storage_rollback_transaction(NULL, NULL, NULL); + goto FINISH_OFF; + } + + em_storage_commit_transaction(NULL, NULL, NULL); + ret = true; + +FINISH_OFF: + + EM_SAFE_FREE(mail_table_data.datetime); + EM_SAFE_FREE(mail_table_data.email_address_sender); + EM_SAFE_FREE(mail_table_data.alias_sender); + EM_SAFE_FREE(mail_table_data.email_address_recipient); + EM_SAFE_FREE(mail_table_data.alias_recipient); + + if (err_code != NULL) + *err_code = err; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +int em_core_mail_check_rule(emf_mail_head_t *head, emf_mail_rule_tbl_t *rule, int rule_len, int *matched, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("head [%p], rule [%p], rule_len [%d], matched [%p], err_code [%p]", head, rule, rule_len, matched, err_code); + + int ret = false, err = EMF_ERROR_NONE, i; + size_t len = 0; + char *src = NULL; /* string which will be compared with rules */ + char *from_address = NULL; + ADDRESS *addr = NULL; + + if (!matched || !head || !head->from || !head->subject) { + EM_DEBUG_EXCEPTION("EMF_ERROR_INVALID_PARAM"); + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + *matched = -1; + + for (i = 0; i < rule_len; i++) { + if (!(rule + i)) { + EM_DEBUG_EXCEPTION("EMF_ERROR_INVALID_PARAM"); + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + EM_DEBUG_LOG("rule[%d].flag1(rule id[%d]) is %d", i, rule[i].rule_id, rule[i].flag1); + + if (rule[i].flag1){ + /* 'ON' */ + EM_DEBUG_LOG("rule[%d].flag2(rule id[%d]) is %d", i, rule[i].rule_id, rule[i].flag2); + switch (rule[i].type) { + case EMF_FILTER_FROM: + if (from_address == NULL) { + from_address = EM_SAFE_STRDUP(head->from); + rfc822_parse_adrlist(&addr, from_address, NULL); + if(addr) { + EM_DEBUG_LOG("rule : head->from[%s], addr->mailbox[%s], addr->host[%s]", head->from, addr->mailbox, addr->host); + EM_SAFE_FREE(from_address); + + if (addr->mailbox) + len = strlen(addr->mailbox); + if (addr->host) + len += strlen(addr->host); + len += 2; + + if (!(from_address = em_core_malloc(len))) { + EM_DEBUG_EXCEPTION("em_core_malloc failed..."); + err = EMF_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + SNPRINTF(from_address, len, "%s@%s", addr->mailbox, addr->host); + } + else { + EM_DEBUG_EXCEPTION("rfc822_parse_adrlist failed."); + err = EMF_ERROR_INVALID_ADDRESS; + goto FINISH_OFF; + } + } + + src = from_address; + break; + case EMF_FILTER_SUBJECT: + src = head->subject; + break; + case EMF_FILTER_BODY: + err = EMF_ERROR_NOT_SUPPORTED; + goto FINISH_OFF; + break; + } + EM_DEBUG_LOG("rule src[%s], value[%s]\n", src, rule[i].value); + + if (src && rule[i].value) { + if (RULE_TYPE_INCLUDES == rule[i].flag2) { + if (strstr(src, rule[i].value)) { + *matched = i; + break; + } + } + else if (RULE_TYPE_EXACTLY == rule[i].flag2) { + if (!strcmp(src, rule[i].value)) { + *matched = i; + break; + } + } + } + } + else + EM_DEBUG_LOG("Invald src or rule[i].value"); + } + ret = true; + + EM_DEBUG_LOG("i [%d], matched [%d]", i, *matched); +FINISH_OFF: + + EM_SAFE_FREE(from_address); + + if (addr != NULL) + mail_free_address(&addr); + + if (err_code != NULL) + *err_code = err; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +static int em_core_get_utf8_address(char **dest, ADDRESS *address, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("dest[%p], address[%p], err_code[%p]", dest, address, err_code); + + if (!dest || !address) { + EM_DEBUG_EXCEPTION("dest[%p], address[%p]", dest, address); + if (err_code != NULL) + *err_code = EMF_ERROR_INVALID_PARAM; + return false; + } + + int ret = false; + int err = EMF_ERROR_NONE; + + gchar *concatenated = NULL; + gchar *utf8_address = NULL; + gchar *temp = NULL; + char *nickname = NULL; + + while (address) { + EM_DEBUG_LOG("address->mailbox[%s], address->host[%s]", address->mailbox, address->host); + if (!address->mailbox || !address->host) { + address = address->next; + continue; + } + EM_DEBUG_LOG("address->mailbox[%p]", address->personal); + if (address->personal) { + if (!(nickname = em_core_decode_rfc2047_text(address->personal, &err))) { + EM_DEBUG_EXCEPTION("em_core_decode_rfc2047_text failed - %d", err); + goto FINISH_OFF; + } + EM_DEBUG_LOG("nickname[%s]", nickname); + if (*nickname != '\0') + utf8_address = g_strdup_printf("\"%s\" <%s@%s>", nickname, address->mailbox ? address->mailbox : "", address->host ? address->host : ""); + else + utf8_address = g_strdup_printf("<%s@%s>", address->mailbox ? address->mailbox : "", address->host ? address->host : ""); + + EM_SAFE_FREE(nickname); + } + else + utf8_address = g_strdup_printf("<%s@%s>", address->mailbox ? address->mailbox : "", address->host ? address->host : ""); + + EM_DEBUG_LOG("utf8_address[%s]", utf8_address); + + if (concatenated != NULL) { + temp = concatenated; + concatenated = g_strdup_printf("%s; %s", temp, utf8_address); + g_free(temp); + } + else + concatenated = g_strdup(utf8_address); + + g_free(utf8_address); + utf8_address = NULL; + + address = address->next; + } + + *dest = concatenated; + + ret = true; + +FINISH_OFF: + EM_SAFE_FREE(nickname); + EM_DEBUG_FUNC_END("ret[%d]", ret); + return ret; +} + + +static int em_core_mail_parse_envelope(ENVELOPE *envelope, emf_mail_head_t **head, int *to_num, int *err_code) +{ + EM_PROFILE_BEGIN(emCoreParseEnvelope); + EM_DEBUG_FUNC_BEGIN("envelope[%p], head[%p], to_num[%p], err_code[%p]", envelope, head, to_num, err_code); + + int ret = false; + int err = EMF_ERROR_NONE; + + emf_mail_head_t *p = NULL; + int i = 0; + + if (!head) { + EM_DEBUG_EXCEPTION("envelope[%p], head[%p], to_num[%p]", envelope, head, to_num); + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + if (!(p = em_core_malloc(sizeof(emf_mail_head_t)))) { + EM_DEBUG_EXCEPTION("em_core_malloc failed..."); + err = EMF_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + if (envelope->subject) { + p->subject = em_core_decode_rfc2047_text(envelope->subject, &err); + EM_DEBUG_LOG("subject[%s]", p->subject); + } + + if (envelope->from) { + if (!em_core_get_utf8_address(&p->from, envelope->from, &err)) { + EM_DEBUG_EXCEPTION("em_core_get_utf8_address failed [%d]", err); + goto FINISH_OFF; + } + + EM_DEBUG_LOG(" head->from[%s]", p->from); + } + + if (envelope->to) { + /* + ADDRESS *addr = NULL; + + for (addr = envelope->to, i = 0; addr != NULL; addr = addr->next, i++) + EM_DEBUG_LOG("envelope->personal[%s], mailbox[%s], host[%s]", addr->personal, addr->mailbox, addr->host); + */ + + EM_DEBUG_LOG("envelope->to"); + if (!em_core_get_utf8_address(&p->to, envelope->to, &err)) { + EM_DEBUG_EXCEPTION("em_core_get_utf8_address failed [%d]", err); + goto FINISH_OFF; + } + + EM_DEBUG_LOG("head->to[%s]", p->to); + } + + if (envelope->cc) { + EM_DEBUG_LOG("envelope->cc"); + if (!em_core_get_utf8_address(&p->cc, envelope->cc, &err)) { + EM_DEBUG_EXCEPTION("em_core_get_utf8_address failed [%d]", err); + goto FINISH_OFF; + } + + EM_DEBUG_LOG("head->cc[%s]", p->cc); + } + + if (envelope->bcc) { + if (!em_core_get_utf8_address(&p->bcc, envelope->bcc, &err)) { + EM_DEBUG_EXCEPTION("em_core_get_utf8_address failed [%d]", err); + goto FINISH_OFF; + } + + EM_DEBUG_LOG("head->bcc[%s]", p->bcc); + } + + if (envelope->reply_to) { + if (!em_core_get_utf8_address(&p->reply_to, envelope->reply_to, &err)) { + EM_DEBUG_EXCEPTION("em_core_get_utf8_address failed [%d]", err); + goto FINISH_OFF; + } + + EM_DEBUG_LOG(" head->reply_to[%s]\n", p->reply_to); + } + + if (envelope->return_path) { + if (!em_core_get_utf8_address(&p->return_path, envelope->return_path, &err)) { + EM_DEBUG_EXCEPTION("em_core_get_utf8_address failed [%d]", err); + goto FINISH_OFF; + } + EM_DEBUG_LOG("head->return_path[%s]", p->return_path); + } + + p->mid = EM_SAFE_STRDUP(envelope->message_id); + + *head = p; + p = NULL; + + if (to_num != NULL) + *to_num = i; + + ret = true; + +FINISH_OFF: + + if (ret != true) + EM_SAFE_FREE(p); + + if (err_code != NULL) + *err_code = err; + + EM_PROFILE_END(emCoreParseEnvelope); + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API int em_core_mailbox_sync_header(emf_mailbox_tbl_t *input_mailbox_tbl, emf_mailbox_tbl_t *input_mailbox_tbl_spam, void *stream_recycle, em_core_uid_list **input_uid_list, int *unread_mail, int *err_code) +{ + EM_PROFILE_BEGIN(emCoreSyncHeader); + EM_DEBUG_FUNC_BEGIN("input_mailbox_tbl[%p], input_mailbox_tbl_spam[%p], input_uid_list [%p], err_code[%p]", input_mailbox_tbl, input_mailbox_tbl_spam, input_uid_list, err_code); + + int ret = false; + int err = EMF_ERROR_NONE, err_2 = EMF_ERROR_NONE; + int status = EMF_LIST_FAIL; + int download_limit_count; + emf_account_t *account_ref = NULL; + emf_mail_rule_tbl_t *rule = NULL; + em_core_uid_list *uid_list = NULL; + em_core_uid_list *uid_elem = NULL; + emf_mail_head_t *head = NULL; + ENVELOPE *env = NULL; + int account_id = 0, mail_id = 0, rule_len = 1000, total = 0, unread = 0, i = 0, percentage = 0, thread_id = -1; + void *stream = NULL; + char *uid_range = NULL; + + if (!input_mailbox_tbl) { + EM_DEBUG_EXCEPTION("EMF_ERROR_INVALID_PARAM:input_mailbox_tbl[%p]", input_mailbox_tbl); + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + account_id = input_mailbox_tbl->account_id; + account_ref = em_core_get_account_reference(account_id); + if (!account_ref) { + EM_DEBUG_EXCEPTION("em_core_get_account_reference failed - %d", account_id); + err = EMF_ERROR_INVALID_ACCOUNT; + goto FINISH_OFF; + } + + FINISH_OFF_IF_CANCELED; + +#ifndef __FEATURE_KEEP_CONNECTION__ + /* h.gahlaut : Recycling of stream is taken care internally in em_core_mailbox_open so no need of this code here */ + if (stream_recycle) + stream = stream_recycle; /* set stream for recycling connection. */ +#endif + + if (!em_core_mailbox_open(account_id, input_mailbox_tbl->mailbox_name, (void **)&stream, &err) || !stream){ + EM_DEBUG_EXCEPTION("em_core_mailbox_open failed - %d", err); + status = EMF_LIST_CONNECTION_FAIL; + goto FINISH_OFF; + } + + FINISH_OFF_IF_CANCELED; + + /* save total mail count on server to DB */ + if (!em_storage_update_mailbox_total_count(account_id, input_mailbox_tbl->mailbox_name, ((MAILSTREAM *)stream)->nmsgs, 1, &err)){ + EM_DEBUG_EXCEPTION("em_storage_update_mailbox_total_count failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + + /* if (((MAILSTREAM *)stream)->nmsgs > 0) */ + { + emf_option_t *opt_ref = &account_ref->options; + EM_DEBUG_LOG("block_address = %d, block_subject = %d", opt_ref->block_address, opt_ref->block_subject); + + if (opt_ref->block_address || opt_ref->block_subject) { + int is_completed = false; + int type = 0; + + if (!opt_ref->block_address) + type = EMF_FILTER_SUBJECT; + else if (!opt_ref->block_subject) + type = EMF_FILTER_FROM; + + if (!em_storage_get_rule(ALL_ACCOUNT, type, 0, &rule_len, &is_completed, &rule, true, &err) || !rule) + EM_DEBUG_EXCEPTION("em_storage_get_rule failed - %d", err); + } + download_limit_count = input_mailbox_tbl->mail_slot_size; + if (!em_core_mailbox_get_uids_to_download(stream, account_ref, input_mailbox_tbl, download_limit_count, &uid_list, &total, EMF_SYNC_LATEST_MAILS_FIRST, &err)){ + EM_DEBUG_EXCEPTION("em_core_mailbox_get_uids_to_download failed [%d]", err); + uid_list = NULL; + goto FINISH_OFF; + } + + FINISH_OFF_IF_CANCELED; + + if (input_uid_list && *input_uid_list){ + em_core_mailbox_free_uids(*input_uid_list, NULL); + *input_uid_list = uid_list; + } + uid_elem = uid_list; + i = 0; + EM_PROFILE_BEGIN(emCoreSyncHeaderwhileloop); + +#ifdef __FEATURE_HEADER_OPTIMIZATION__ + /* g.shyamakshi@samsung.com : Bulk fetch of headers only if the recieving server type is IMAP */ + + EM_DEBUG_LOG("((MAILSTREAM *)stream)->nmsgs [%d]", ((MAILSTREAM *)stream)->nmsgs); + EM_DEBUG_LOG("uid_list [%p]", uid_list); + if (account_ref->receiving_server_type == EMF_SERVER_TYPE_IMAP4 && uid_list != NULL){ + em_core_uid_list *uid_list_prev = NULL; + em_core_uid_list *uid_list_fast = uid_list; + int index = 0; + int msg_count = total; + int uid_range_size = msg_count * 8 + 1000; + + EM_DEBUG_LOG("memory allocation for uid_range [%d, %d]", msg_count, uid_range_size); + uid_range = malloc(sizeof(char) * uid_range_size); + + if (uid_range == NULL){ + EM_DEBUG_EXCEPTION("memory allocation for uid_range failed"); + err = EMF_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + uid_list_prev = uid_list_fast; + + if (uid_list_fast->next == NULL){ + /* Single list entry */ + snprintf(uid_range, uid_range_size, "%d", atoi(uid_list_fast->uid)); + } + else{ + /* forming range of uids to be passed */ + while (uid_list_fast != NULL){ + /* uid_list_fast = uid_list_fast->next; */ + + if ((uid_list_fast->next != NULL) && (((atoi(uid_list_prev->uid)) - (atoi(uid_list_fast->next->uid))) == 1)){ + index += snprintf(uid_range+index, uid_range_size, "%d", atoi(uid_list_prev->uid)); + + uid_list_fast = uid_list_fast->next; + uid_list_prev = uid_list_fast; + + /* to make UID range string "abc, XX : YY" */ + while (uid_list_fast != NULL){ + if (uid_list_fast->next == NULL) + break; + if (((atoi(uid_list_prev->uid)) - (atoi(uid_list_fast->next->uid))) == 1){ + uid_list_fast = uid_list_fast->next; + uid_list_prev = uid_list_fast; + } + else + break; + } + if ((uid_list_fast != NULL) && (uid_list_fast->next != NULL)) + index += snprintf(uid_range+index, uid_range_size, ":%d,", atoi(uid_list_prev->uid)); + else + index += snprintf(uid_range+index, uid_range_size, ":%d", atoi(uid_list_prev->uid)); + + uid_list_fast = uid_list_fast->next; + uid_list_prev = uid_list_fast; + } + else{ + if (uid_list_fast->next != NULL) + index += snprintf(uid_range+index, uid_range_size, "%d,", atoi(uid_list_prev->uid)); + else + index += snprintf(uid_range+index, uid_range_size, "%d", atoi(uid_list_prev->uid)); + uid_list_fast = uid_list_fast->next; + uid_list_prev = uid_list_fast; + } + } + } + + /* h.gahlaut : [Start] */ + /* Adding this check here to check if application has called cancel job. */ + /* This checking should be done because fetching 50 headers will take time */ + FINISH_OFF_IF_CANCELED; + + EM_DEBUG_LOG("index [%d]", index); + + /* h.gahlaut : [End] */ + uid_elem = uid_list; + if (stream && uid_elem){ + EM_DEBUG_LOG("msgno : %d", uid_elem->msgno); + ((MAILSTREAM *)stream)->nmsgs = uid_elem->msgno; + } + else{ + EM_DEBUG_LOG("Uid List Null"); + } + EM_DEBUG_LOG("Calling ... mail_fetch_fast. uid_range [%s]", uid_range); + mail_fetch_fast(stream, uid_range, FT_UID | FT_PEEK | FT_NEEDENV); + EM_SAFE_FREE(uid_range); + } +#endif + + /* h.gahlaut@samsung.com : Clear the event queue of partial body download thread before starting fetching new headers */ +#ifndef __PARTIAL_BODY_FOR_POP3__ + if (account_ref->receiving_server_type == EMF_SERVER_TYPE_IMAP4){ +#endif /* __PARTIAL_BODY_FOR_POP3__ */ + /* Partial body download feature is only for IMAP accounts */ + if (false == em_core_clear_partial_body_thd_event_que(&err)) + EM_DEBUG_LOG("em_core_clear_partial_body_thd_event_que failed [%d]", err); +#ifndef __PARTIAL_BODY_FOR_POP3__ + } +#endif /* __PARTIAL_BODY_FOR_POP3__ */ + while (uid_elem) { + EM_PROFILE_BEGIN(emCoreSyncHeaderEachMail); + EM_DEBUG_LOG("mail_fetchstructure_full : uid_elem->msgno[%d]", uid_elem->msgno); + + env = NULL; + + if (uid_elem->msgno > ((MAILSTREAM *)stream)->nmsgs) + EM_DEBUG_EXCEPTION("Warnings! msgno[%d] can't be greater than nmsgs[%d]. It might cause crash.", uid_elem->msgno, ((MAILSTREAM *)stream)->nmsgs); + else{ + +#ifdef __FEATURE_HEADER_OPTIMIZATION__ + if (account_ref->receiving_server_type == EMF_SERVER_TYPE_IMAP4) /* Fetch env from cache in case of IMAP */ + env = mail_fetchstructure_full(stream, uid_elem->msgno, NULL, FT_PEEK, 0); + else /* Fetch header from network in case of POP */ + env = mail_fetchstructure_full(stream, uid_elem->msgno, NULL, FT_PEEK, 1); +#else + env = mail_fetchstructure_full(stream, uid_elem->msgno, NULL, FT_PEEK); +#endif + } + FINISH_OFF_IF_CANCELED; + + if (env != NULL){ + int to_num = 0; + int matched = -1; + + if (!em_core_mail_parse_envelope(env, &head, &to_num, &err) || !head) { + EM_DEBUG_EXCEPTION("em_core_mail_parse_envelope failed [%d]", err); + goto FINISH_OFF; + } + + if (rule && input_mailbox_tbl_spam && !em_core_mail_check_rule(head, rule, rule_len, &matched, &err)) { + EM_DEBUG_EXCEPTION("em_core_mail_check_rule failed [%d]", err); + goto FINISH_OFF; + } + + if (matched >= 0 && input_mailbox_tbl_spam){ /* add filtered mails to SPAMBOX */ + EM_DEBUG_LOG("mail[%d] added to spambox", mail_id); + + if (!em_core_mail_add_header(stream, input_mailbox_tbl_spam, head, to_num, uid_elem, &mail_id, &thread_id, &err)) { + EM_DEBUG_EXCEPTION("em_core_mail_add_header falied [%d]", err); + goto FINISH_OFF; + } + + if (account_ref->receiving_server_type == EMF_SERVER_TYPE_IMAP4){ + if (!em_core_mail_move_from_server(account_id, input_mailbox_tbl->mailbox_name, &mail_id, 1, input_mailbox_tbl_spam->mailbox_name, &err)){ + EM_DEBUG_EXCEPTION("em_core_mail_move_from_server falied [%d]", err); + goto FINISH_OFF; + } + } + } else { + /* add mails to specified mail box */ + EM_DEBUG_LOG("mail[%d] moved to input_mailbox_tbl [%s]", mail_id, input_mailbox_tbl->mailbox_name); + if (!em_core_mail_add_header(stream, input_mailbox_tbl, head, to_num, uid_elem, &mail_id, &thread_id, &err)) { + EM_DEBUG_EXCEPTION("em_core_mail_add_header falied [%d]", err); + goto FINISH_OFF; + } + + /*h.gahlaut : Start partial body dowload using partial body thread only for IMAP accounts*/ +#ifndef __PARTIAL_BODY_FOR_POP3__ + if (account_ref->receiving_server_type == EMF_SERVER_TYPE_IMAP4) { +#endif /* __PARTIAL_BODY_FOR_POP3__ */ + if (false == em_core_initiate_pbd(stream, account_id, mail_id, uid_elem->uid, input_mailbox_tbl->mailbox_name, &err)) + EM_DEBUG_LOG("Partial body download initiation failed [%d]", err); +#ifndef __PARTIAL_BODY_FOR_POP3__ + } +#endif /* __PARTIAL_BODY_FOR_POP3__ */ + + if (!uid_elem->flag.seen && input_mailbox_tbl->mailbox_type != EMF_MAILBOX_TYPE_SPAMBOX) + em_core_add_notification_for_unread_mail_by_mail_header(account_id, mail_id, head); + + FINISH_OFF_IF_CANCELED; + + if (!uid_elem->flag.seen) + unread++; + + percentage = ((i+1) * 100) / total ; + EM_DEBUG_LOG("Header Percentage Completed [%d] : [%d/%d] mail_id [%d]", percentage, i+1, total, mail_id); + + if (!em_storage_notify_storage_event(NOTI_MAIL_ADD, account_id, mail_id, input_mailbox_tbl->mailbox_name, thread_id)) + EM_DEBUG_EXCEPTION("em_storage_notify_storage_event [NOTI_MAIL_ADD] failed"); + } + + /* Release for envelope is not required and it may cause crash. Don't free the memory for envelope here. */ + /* Envelope data will be freed by garbage collector in mail_close_full */ + if (head){ + em_core_mail_head_free(&head, 1, NULL); + head = NULL; + } + + FINISH_OFF_IF_CANCELED; + } + + uid_elem = uid_elem->next; + i++; + EM_PROFILE_END(emCoreSyncHeaderEachMail); + } + EM_PROFILE_END(emCoreSyncHeaderwhileloop); + } + + *unread_mail = unread; + ret = true; +FINISH_OFF: + + if (!em_core_mailbox_remove_overflowed_mails(input_mailbox_tbl, &err_2)) + EM_DEBUG_EXCEPTION("em_core_mailbox_remove_overflowed_mails failed - %d", err_2); + + if (head != NULL) + em_core_mail_head_free(&head, 1, NULL); + + if (uid_list != NULL){ + em_core_mailbox_free_uids(uid_list, NULL); + /* uid_list point to the same memory with input_mailbox_tbl->user_data. */ + /* input_mailbox_tbl->user_data should be set NULL if uid_list is freed */ + *input_uid_list = NULL; + } + + EM_SAFE_FREE(uid_range); + + if (rule != NULL) + em_storage_free_rule(&rule, rule_len, NULL); + +#ifdef __FEATURE_KEEP_CONNECTION__ + if (stream != NULL) { +#else /* __FEATURE_KEEP_CONNECTION__ */ + if (stream != NULL && stream_recycle == NULL) { +#endif /* __FEATURE_KEEP_CONNECTION__ */ + em_core_mailbox_close(0, stream); + stream = NULL; + } + + if (err_code != NULL) + *err_code = err; + + EM_PROFILE_END(emCoreSyncHeader); + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + + +em_core_uid_list *__ReverseList(em_core_uid_list *uid_list) +{ + em_core_uid_list *temp, *current, *result; + + temp = NULL; + result = NULL; + current = uid_list; + + while (current != NULL){ + temp = current->next; + current->next = result; + result = current; + current = temp; + } + uid_list = result; + return uid_list; +} + + + +int em_core_mailbox_download_uid_all(emf_mailbox_t *mailbox, em_core_uid_list** uid_list, int *total, emf_mail_read_mail_uid_tbl_t *downloaded_uids, int count, em_core_get_uids_for_delete_t for_delete, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("mailbox[%p], uid_list[%p], total[%p], downloaded_uids[%p], count[%d], for_delete[%d], err_code[%p]", mailbox, uid_list, total, downloaded_uids, count, for_delete, err_code); + + int ret = false; + int err = EMF_ERROR_NONE; + + MAILSTREAM *stream = NULL; + emf_account_t *ref_account = NULL; + em_core_uid_list *uid_elem = NULL; + em_core_uid_list *fetch_data_p = NULL; + void *tmp_stream = NULL; + char cmd[64] = {0x00, }; + char *p = NULL; + + if (!mailbox || !uid_list) { + EM_DEBUG_EXCEPTION("mailbox[%p], uid_list[%p], total[%p], downloaded_uids[%p], count[%d], for_delete[%d]", mailbox, uid_list, total, downloaded_uids, count, for_delete); + + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + if (!(ref_account = em_core_get_account_reference(mailbox->account_id))) { + EM_DEBUG_EXCEPTION("em_core_get_account_reference failed - %d", mailbox->account_id); + + err = EMF_ERROR_INVALID_ACCOUNT; + goto FINISH_OFF; + } + + if (!mailbox->mail_stream) { + if (!em_core_mailbox_open(mailbox->account_id, mailbox->name, (void **)&tmp_stream, &err)){ + EM_DEBUG_EXCEPTION("em_core_mailbox_open failed..."); + + goto FINISH_OFF; + } + + stream = (MAILSTREAM *)tmp_stream; + } + else + stream = mailbox->mail_stream; + + if (ref_account->receiving_server_type == EMF_SERVER_TYPE_POP3) { /* POP3 */ + POP3LOCAL *pop3local = NULL; + + if (!stream || !(pop3local = stream->local) || !pop3local->netstream) { + err = EMF_ERROR_INVALID_PARAM; /* EMF_ERROR_UNKNOWN; */ + goto FINISH_OFF; + } + + /* send UIDL */ + memset(cmd, 0x00, sizeof(cmd)); + + SNPRINTF(cmd, sizeof(cmd), "UIDL\015\012"); + +#ifdef FEATURE_CORE_DEBUG + EM_DEBUG_LOG("[POP3] >>> [%s]", cmd); +#endif + + if (!net_sout(pop3local->netstream, cmd, (int)strlen(cmd))) { + EM_DEBUG_EXCEPTION("net_sout failed..."); + + err = EMF_ERROR_CONNECTION_BROKEN; + goto FINISH_OFF; + } + + /* get uid from replied data */ + while (pop3local->netstream) { + char *s = NULL; + + if (!(p = net_getline(pop3local->netstream))) + break; + +#ifdef FEATURE_CORE_DEBUG + EM_DEBUG_LOG(" [POP3] <<< [%s]", p); +#endif + + /* replied error "-ERR" */ + if (*p == '-') { + err = EMF_ERROR_MAIL_NOT_FOUND; + goto FINISH_OFF; + } + + /* replied success "+OK" */ + if (*p == '+') { + free(p); p = NULL; + continue; + } + + /* end of command */ + if (*p == '.') + break; + + /* EM_DEBUG_LOG("UID list [%s]", p); */ + + uid_elem = (em_core_uid_list *)malloc(sizeof(em_core_uid_list)); + if (!uid_elem) { + EM_DEBUG_EXCEPTION("malloc falied..."); + + err = EMF_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + memset(uid_elem, 0x00, sizeof(em_core_uid_list)); + + /* format : "1 AAA6FHEAAAQrB6c1ymXxty04yks7hcQ7" */ + + /* save uid */ + s = strstr(p, " "); + if (s) { + *s = '\0'; + uid_elem->msgno = atoi(p); + uid_elem->uid = EM_SAFE_STRDUP(s+1); + } + + /* check downloaded_uids */ + if (downloaded_uids) { + int i; + for (i = 0; i < count; ++i) { + if (!strcmp(uid_elem->uid, downloaded_uids[i].s_uid)) { + downloaded_uids[i].flag = 1; + break; + } + } + } + + if (*uid_list) { /* TODO : modify me */ + fetch_data_p = *uid_list; + + while (fetch_data_p->next) + fetch_data_p = fetch_data_p->next; + + fetch_data_p->next = uid_elem; + } + else + *uid_list = uid_elem; + + if (total) + ++(*total); + + free(p); p = NULL; + } + } + else { /* IMAP */ + IMAPLOCAL *imaplocal = NULL; + char tag[16]; + char *s = NULL; + char *t = NULL; + + if (!stream || !(imaplocal = stream->local) || !imaplocal->netstream) { + err = EMF_ERROR_INVALID_PARAM; /* EMF_ERROR_UNKNOWN; */ + goto FINISH_OFF; + } + + /* send FETCH UID */ + memset(tag, 0x00, sizeof(tag)); + memset(cmd, 0x00, sizeof(cmd)); + + SNPRINTF(tag, sizeof(tag), "%08lx", 0xffffffff & (stream->gensym++)); + SNPRINTF(cmd, sizeof(cmd), "%s UID FETCH %d:* (FLAGS)\015\012", tag, 1); +#ifdef FEATURE_CORE_DEBUG + EM_DEBUG_LOG("[IMAP] >>> %s", cmd); +#endif + if (!net_sout(imaplocal->netstream, cmd, (int)strlen(cmd))) { + EM_DEBUG_EXCEPTION("net_sout failed..."); + + err = EMF_ERROR_CONNECTION_BROKEN; + goto FINISH_OFF; + } + + /* get uid from replied data */ + while (imaplocal->netstream) { + if (!(p = net_getline(imaplocal->netstream))) + break; + + /* EM_DEBUG_LOG(" [IMAP] <<< %s", p); */ + + /* tagged line - end of command */ + if (!strncmp(p, tag, strlen(tag))) + break; + + /* check that reply is reply to our command */ + /* format : "* 9 FETCH (UID 68)" */ + if (!strstr(p, "FETCH (FLAGS")) { + free(p); p = NULL; + continue; + } + + if (for_delete == EM_CORE_GET_UIDS_FOR_NO_DELETE) { + if ((ref_account->retrieval_mode == EMF_IMAP4_RETRIEVAL_MODE_NEW) && (strstr(p, "\\Seen"))) { + free(p); p = NULL; + continue; + } + } + + uid_elem = (em_core_uid_list *)malloc(sizeof(em_core_uid_list)); + if (!uid_elem) { + EM_DEBUG_EXCEPTION("malloc failed..."); + + err = EMF_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + memset(uid_elem, 0x00, sizeof(em_core_uid_list)); + /* parse uid, sequence, flags from replied data */ + + /* parse uid from replied data */ + s = p+2; + t = strchr(s, ' '); + + if (!t) { + err = EMF_ERROR_INVALID_RESPONSE; + goto FINISH_OFF; + } + + *t = '\0'; + + /* save sequence */ + uid_elem->msgno = atoi(s); + + if (strstr(++t, "\\Deleted")) + uid_elem->flag.deleted = 1; + + /* parse uid */ + s = strstr(++t, "UID "); + if (s) { + s += strlen("UID "); + t = strchr(s, ')'); + + if (!t) { + err = EMF_ERROR_INVALID_RESPONSE; + goto FINISH_OFF; + } + + *t = '\0'; + } + else { + err = EMF_ERROR_INVALID_RESPONSE; + goto FINISH_OFF; + } + + /* save uid */ + uid_elem->uid = EM_SAFE_STRDUP(s); + + /* check downloaded_uids */ + if (downloaded_uids) { + int i; + for (i = 0; i < count; ++i) { + if (uid_elem->uid && !strcmp(uid_elem->uid, downloaded_uids[i].s_uid)) { /* 20080308 - prevent 25231 : Reverse Null. Pointer "(uid_elem)->uid" dereferenced before NULL check */ + downloaded_uids[i].flag = 1; + free(uid_elem->uid); + free(uid_elem); uid_elem = NULL; + break; + } + } + } + + if (uid_elem) { + if (*uid_list) { + fetch_data_p = *uid_list; + + while (fetch_data_p->next) + fetch_data_p = fetch_data_p->next; + + fetch_data_p->next = uid_elem; + } + else { + *uid_list = uid_elem; + } + + if (total) + ++(*total); + } + + free(p); p = NULL; + } + } + + ret = true; + +FINISH_OFF: + if (uid_elem && ret == false) + free(uid_elem); + + if (p) + free(p); + + if (mailbox && !mailbox->mail_stream) { + em_core_mailbox_close(0, stream); + stream = NULL; + } + + if (err_code) + *err_code = err; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +int em_core_mailbox_download_imap_msgno(emf_mailbox_t *mailbox, char *uid, int *msgno, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("mailbox[%p], uid[%p], msgno[%p], err_code[%p]", mailbox, uid, msgno, err_code); + + int ret = false; + int err = EMF_ERROR_NONE; + MAILSTREAM *stream = NULL; + IMAPLOCAL *imaplocal = NULL; + emf_account_t *ref_account = NULL; + void *tmp_stream = NULL; + char tag[32], cmd[64]; + char *p = NULL; + + if (!mailbox || !uid) { + EM_DEBUG_EXCEPTION("mailbox[%p], uid[%p], msgno[%p]", mailbox, uid, msgno); + + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + if (!(ref_account = em_core_get_account_reference(mailbox->account_id))) { + EM_DEBUG_EXCEPTION("em_core_get_account_reference failed [%d]", mailbox->account_id); + + err = EMF_ERROR_INVALID_ACCOUNT; + goto FINISH_OFF; + } + + if (ref_account->receiving_server_type != EMF_SERVER_TYPE_IMAP4) { + err = EMF_ERROR_INVALID_ACCOUNT; /* EMF_ERROR_INVALID_PARAM; */ + goto FINISH_OFF; + } + + if (!mailbox->mail_stream) { + if (!em_core_mailbox_open(mailbox->account_id, mailbox->name, (void **)&tmp_stream, &err)) { + EM_DEBUG_EXCEPTION("em_core_mailbox_open failed - %d", err); + + goto FINISH_OFF; + } + + stream = (MAILSTREAM *)tmp_stream; + } + else + stream = mailbox->mail_stream; + + if (!stream || !(imaplocal = stream->local) || !imaplocal->netstream) { + err = EMF_ERROR_INVALID_PARAM; /* EMF_ERROR_UNKNOWN; */ + goto FINISH_OFF; + } + + /* send SEARCH UID */ + memset(tag, 0x00, sizeof(tag)); + memset(cmd, 0x00, sizeof(cmd)); + + SNPRINTF(tag, sizeof(tag), "%08lx", 0xffffffff & (stream->gensym++)); + SNPRINTF(cmd, sizeof(cmd), "%s SEARCH UID %s\015\012", tag, uid); + + if (!net_sout(imaplocal->netstream, cmd, (int)strlen(cmd))) { + EM_DEBUG_EXCEPTION("net_sout failed..."); + + err = EMF_ERROR_CONNECTION_BROKEN; + goto FINISH_OFF; + } + + /* get message number from replied data */ + while (imaplocal->netstream) { + if (!(p = net_getline(imaplocal->netstream))) + break; + + /* tagged line - end of command */ + if (!strncmp(p, tag, strlen(tag))) + break; + + /* check that reply is reply to our command */ + /* format : "* SEARCH 68", if not found, "* SEARCH" */ + if (!strstr(p, "SEARCH ") || (p[9] < '0' || p[9] > '9')) { + free(p); p = NULL; + continue; + } + + if (msgno) + *msgno = atoi(p+9); + + free(p); p = NULL; + + ret = true; + } + + if (ret != true) + err = EMF_ERROR_MAIL_NOT_FOUND; + +FINISH_OFF: + if (p) + free(p); + + if (mailbox && !mailbox->mail_stream){ + em_core_mailbox_close(0, stream); + stream = NULL; + } + + if (err_code) + *err_code = err; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +int em_core_mailbox_get_msgno(em_core_uid_list *uid_list, char *uid, int *msgno, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("uid_list[%p], uid[%s], msgno[%p], err_code[%p]", uid_list, uid, msgno, err_code); + + int ret = false; + int err = EMF_ERROR_MAIL_NOT_FOUND; /* EMF_ERROR_NONE; */ + + if (!uid || !msgno || !uid_list) { + EM_DEBUG_EXCEPTION("uid_list[%p], uid[%p], msgno[%p]", uid_list, uid, msgno); + + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + EM_DEBUG_LOG(" >> uid[%s]", uid); + + while (uid_list) { + if (!strcmp(uid_list->uid, uid)) { + *msgno = uid_list->msgno; + + EM_DEBUG_LOG("*msgno[%d]", *msgno); + + err = EMF_ERROR_NONE; + + ret = true; + break; + } + + uid_list = uid_list->next; + } + +FINISH_OFF: + if (err_code != NULL) + *err_code = err; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +int em_core_mailbox_get_uid(em_core_uid_list *uid_list, int msgno, char **uid, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN(); + + int ret = false, err = EMF_ERROR_NONE; + + if (!uid || msgno <= 0 || !uid_list){ + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + while (uid_list) { + if (uid_list->msgno == msgno) { + if (uid) { + if (!(*uid = EM_SAFE_STRDUP(uid_list->uid))) { + EM_DEBUG_EXCEPTION("strdup failed..."); + err = EMF_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + ret = true; + break; + } + } + + uid_list = uid_list->next; + } + + if (ret != true) + err = EMF_ERROR_MAIL_NOT_FOUND; + +FINISH_OFF: + if (err_code) + *err_code = err; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +int em_core_mailbox_free_uids(em_core_uid_list *uid_list, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("uid_list[%p], err_code[%p]", uid_list, err_code); + + int ret = false; + int err = EMF_ERROR_NONE; + em_core_uid_list *p = NULL; + + if (!uid_list) { + EM_DEBUG_EXCEPTION(" uid_list[%p]\n", uid_list); + + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + while (uid_list) { + p = uid_list; uid_list = uid_list->next; + + EM_SAFE_FREE(p->uid); + + free(p); + p = NULL; + } + + ret = true; + +FINISH_OFF: + if (err_code) + *err_code = err; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + + +#ifdef __FEATURE_SYNC_CLIENT_TO_SERVER__ +/* callback for GET_APPENDUID - shasikala.p */ +void mail_appenduid(char *mailbox, unsigned long uidvalidity, SEARCHSET *set) +{ + EM_DEBUG_FUNC_BEGIN("mailbox - %s", mailbox); + EM_DEBUG_LOG("UID - %ld", set->first); + + memset(g_append_uid_rsp, 0x00, 129); + + sprintf(g_append_uid_rsp, "%ld", set->first); + EM_DEBUG_LOG("append uid - %s", g_append_uid_rsp); +} + +EXPORT_API int em_core_mail_sync_from_client_to_server(int account_id, int mail_id, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id [%d], mail_id [%d], mail_id [%p]", account_id, mail_id, *err_code); + + int err = EMF_ERROR_NONE; + int ret = false; + int len = 0; + int read_size = 0; + char *fname = NULL; + char *long_enc_path = NULL; + char *data = NULL; + char set_flags[100] = { 0, }; + ENVELOPE *envelope = NULL; + FILE *fp = NULL; + STRING str; + MAILSTREAM *stream = NULL; + emf_mail_t *mail = NULL; + emf_mail_tbl_t *mail_table_data = NULL; + emf_mailbox_tbl_t *mailbox_tbl = NULL; + + if (mail_id < 1){ + EM_DEBUG_EXCEPTION("EMF_ERROR_INVALID_PARAM"); + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + /* get a mail from mail table */ + if (!em_storage_get_mail_by_id(mail_id, &mail_table_data, true, &err)) { + EM_DEBUG_EXCEPTION("em_storage_get_mail_by_id failed [%d]", err); + goto FINISH_OFF; + } + + EM_DEBUG_LOG("mailbox_name [%s]", mail_table_data->mailbox_name); + if (!em_storage_get_mailbox_by_name(mail_table_data->account_id, 0, mail_table_data->mailbox_name, &mailbox_tbl, false, &err) || !mailbox_tbl){ + EM_DEBUG_EXCEPTION("em_storage_get_mailbox_by_name failed [%d]", err); + goto FINISH_OFF; + } + + if (mailbox_tbl->sync_with_server_yn == 0) { + EM_DEBUG_EXCEPTION("The mailbox [%s] is not on server.", mail_table_data->mailbox_name); + err = EMF_ERROR_INVALID_MAILBOX; + goto FINISH_OFF; + } + + /* get a mail to send */ + if (!em_core_mail_get_mail(mail_id, &mail, &err)){ + EM_DEBUG_EXCEPTION(" em_core_mail_get_mail failed [%d]", err); + goto FINISH_OFF; + } + + if (!em_core_get_long_encoded_path(mail_table_data->account_id, mail_table_data->mailbox_name, '/', &long_enc_path, &err)) { + EM_DEBUG_EXCEPTION(">>em_core_get_long_encoded_path : Failed [%d] ", err); + goto FINISH_OFF; + } + + if (!long_enc_path) { + EM_DEBUG_EXCEPTION(">>long_enc_path : NULL "); + goto FINISH_OFF; + } + + if (!em_core_mail_get_rfc822(mail, &envelope, &fname, NULL, &err)){ + EM_DEBUG_EXCEPTION(" em_core_mail_get_rfc822 failed [%d]", err); + goto FINISH_OFF; + } + + if (fname){ + if (!(fp = fopen(fname, "a+"))) + { + EM_DEBUG_EXCEPTION("fopen failed - %s", fname); + err = EMF_ERROR_SYSTEM_FAILURE; + goto FINISH_OFF; + } + } + + if (!fp) { + EM_DEBUG_EXCEPTION("fp is NULL..!"); + err = EMF_ERROR_SYSTEM_FAILURE; + goto FINISH_OFF; + } + + rewind(fp); + + ret = fseek(fp, 0, SEEK_END) == 0 && (len = ftell(fp)) != -1; + + if (fname) + EM_DEBUG_LOG("Composed file name [%s] and file size [%d]", fname, len); + + rewind(fp); + + ret = 0; + stream = NULL; + if (!em_core_mailbox_open(mail_table_data->account_id, NULL, (void **)&stream, &err)){ + EM_DEBUG_EXCEPTION("em_core_mail_move_from_server failed : Mailbox open[%d]", err); + goto FINISH_OFF; + } + + /* added for copying server UID to DB */ + mail_parameters(stream, SET_APPENDUID, mail_appenduid); + + data = (char *)malloc(len + 1); + /* copy data from file to data */ + read_size = fread(data, sizeof (char), len, fp); + if (read_size != len){ + /* read faiil. */ + EM_DEBUG_EXCEPTION("Read from file failed"); + } + + INIT(&str, mail_string, data, len); + + sprintf(set_flags, "\\Seen"); + + if ((mail->info->flags).seen){ + if (!mail_append_full(stream, long_enc_path, set_flags, NULL, &str)) { + EM_DEBUG_EXCEPTION("mail_append failed -"); + goto FINISH_OFF; + } + } + else{ + if (!mail_append_full(stream, long_enc_path, NULL, NULL, &str)) { + EM_DEBUG_EXCEPTION("mail_append failed -"); + goto FINISH_OFF; + } + } + + /* Update read_mail_uid tbl */ + if (!em_core_mailbox_add_read_mail_uid(mailbox_tbl, mail_table_data->mailbox_name, mail_table_data->mail_id, g_append_uid_rsp, mail_table_data->mail_size, 0, &err)) { + EM_DEBUG_EXCEPTION(" em_core_mailbox_add_read_mail_uid failed [%d]", err); + em_storage_rollback_transaction(NULL, NULL, NULL); + goto FINISH_OFF; + } + + ret = true; + +FINISH_OFF: + +#ifdef __LOCAL_ACTIVITY__ + if (ret){ + emf_activity_tbl_t new_activity; + memset(&new_activity, 0x00, sizeof(emf_activity_tbl_t)); + new_activity.activity_type = ACTIVITY_SAVEMAIL; + new_activity.account_id = account_id; + new_activity.mail_id = mail_id; + new_activity.dest_mbox = NULL; + new_activity.server_mailid = NULL; + new_activity.src_mbox = NULL; + + if (!em_core_activity_delete(&new_activity, &err)){ + EM_DEBUG_EXCEPTION(">>>>>>Local Activity [ACTIVITY_SAVEMAIL] [%d] ", err); + } + } +#endif /* __LOCAL_ACTIVITY__ */ + + EM_SAFE_FREE(data); + EM_SAFE_FREE(long_enc_path); + + if (fp) + fclose(fp); + + if (envelope) + mail_free_envelope(&envelope); + + if (mail) + em_core_mail_free(&mail, 1, NULL); + + if (mail_table_data) + em_storage_free_mail(&mail_table_data, 1, NULL); + + if (mailbox_tbl) + em_storage_free_mailbox(&mailbox_tbl, 1, NULL); + + if (fname) { + remove(fname); + EM_SAFE_FREE(fname); + } + + if (stream){ + em_core_mailbox_close(0, stream); + stream = NULL; + } + + if (err_code != NULL) + *err_code = err; + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +#endif + +#ifdef __FEATURE_PARTIAL_BODY_DOWNLOAD__ + +static int em_core_initiate_pbd(MAILSTREAM *stream, int account_id, int mail_id, char *uid, char *input_mailbox_name, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id [%d], mail_id[%d], uid[%p], input_mailbox_name[%p]", account_id, mail_id, uid, input_mailbox_name); + + int ret = false; + int err = EMF_ERROR_NONE; + emf_account_t *account_ref; + + if (account_id < FIRST_ACCOUNT_ID || mail_id < 0 || NULL == uid || NULL == input_mailbox_name){ + EM_DEBUG_EXCEPTION("EMF_ERROR_INVALID_PARAM"); + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + account_ref = em_core_get_account_reference(account_id); + + emf_event_partial_body_thd pbd_event; + + memset(&pbd_event, 0x00, sizeof(emf_event_partial_body_thd)); + + pbd_event.account_id = account_id; + if (account_ref && account_ref->receiving_server_type == EMF_SERVER_TYPE_POP3) + pbd_event.activity_type = ACTIVITY_PARTIAL_BODY_DOWNLOAD_POP3_WAIT; + else + pbd_event.activity_type = ACTIVITY_PARTIAL_BODY_DOWNLOAD_IMAP4; + + pbd_event.mailbox_name = EM_SAFE_STRDUP(input_mailbox_name); + pbd_event.mail_id = mail_id; + pbd_event.server_mail_id = strtoul(uid, NULL, 0); + + EM_DEBUG_LOG("input_mailbox_name name [%s]", pbd_event.mailbox_name); + EM_DEBUG_LOG("uid [%s]", uid); + EM_DEBUG_LOG("pbd_event.account_id[%d], pbd_event.mail_id[%d], pbd_event.server_mail_id [%d]", pbd_event.account_id, pbd_event.mail_id , pbd_event.server_mail_id); + + if (!em_core_insert_pbd_activity(&pbd_event, &pbd_event.activity_id, &err)){ + EM_DEBUG_EXCEPTION("Inserting Partial Body Download activity failed with error[%d]", err); + goto FINISH_OFF; + } + else{ + if (false == em_core_is_partial_body_thd_que_full()){ + /* h.gahaut : Before inserting the event into event queue activity_type should be made 0 + Because partial body thread differentiates events coming from DB and event queue + on the basis of activity_type and event_type fields */ + + pbd_event.activity_type = 0; + pbd_event.event_type = EMF_EVENT_BULK_PARTIAL_BODY_DOWNLOAD; + + if (!em_core_insert_partial_body_thread_event(&pbd_event, &err)){ + EM_DEBUG_EXCEPTION("Inserting Partial body thread event failed with error[%d]", err); + goto FINISH_OFF; + } + + /*h.gahlaut : Partial body thread has created a copy of event for itself so this local event should be freed here*/ + if (!em_core_free_partial_body_thd_event(&pbd_event, &err)) + EM_DEBUG_EXCEPTION("Freeing Partial body thread event failed with error[%d]", err); + } + else{ + EM_DEBUG_LOG(" Activity inserted only in DB .. Queue is Full"); + } + } + + ret = true; + + FINISH_OFF: + + if (NULL != err_code) + *err_code = err; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +#define UID_RANGE_STRING_LENGTH 3000 +#define TEMP_STRING_LENGTH 50 + +static int em_core_parse_html_part_for_partial_body(char *start_header, char *boundary_string, char *bufsendforparse, char *text_html, int body_size) +{ + EM_DEBUG_FUNC_BEGIN("start_header [%s], boundary_string [%s], bufsendforparse [%s], text_html [%s], body_size [%d]", start_header, boundary_string, bufsendforparse, text_html, body_size); + + int err = EMF_ERROR_NONE; + int html_uidno = 0; + int iEncodingHeader = 0; + int enc_type = ENCOTHER, dec_len = 0, html_length = 0; + char EncodingHeader[40] = {0}; + char Encoding[30] = {0}; + char *pEncodingHeaderEnd = NULL; + char *txt_html = NULL; + char *pHeaderStart = NULL; + char *start = NULL, *end = NULL; + char *temp_enc1 = NULL; + + EM_DEBUG_LOG("Content-Type : text/html or message/rfc822 or text/rfc822-headers"); + + pHeaderStart = start_header; + pHeaderStart = pHeaderStart-2; + do{ + pHeaderStart--; + } while (*pHeaderStart != LF && bufsendforparse < pHeaderStart); + + pHeaderStart++; + + memcpy(EncodingHeader, pHeaderStart, 25); + + if (strcasecmp(EncodingHeader, "Content-Transfer-Encoding") == 0){ + pEncodingHeaderEnd = strstr(pHeaderStart, CRLF_STRING); + memcpy(Encoding, pHeaderStart + 27, pEncodingHeaderEnd - (pHeaderStart+27)); + iEncodingHeader = 1; + } + + /* HTML Content found */ + + txt_html = start_header; + txt_html = strstr(txt_html, CRLF_STRING CRLF_STRING); + + if (txt_html != NULL){ + txt_html += 4; /* txt_html points at html content */ + start = txt_html; + char multipart_boundary[100] = {0}; + char *multipart_related_boundry = NULL; + char *multipart_related_boundry_end = NULL; + if (iEncodingHeader == 1) + multipart_related_boundry = pHeaderStart; + else + multipart_related_boundry = start_header; + + multipart_related_boundry = multipart_related_boundry - 3; + multipart_related_boundry_end = multipart_related_boundry; + + while (bufsendforparse < multipart_related_boundry && *multipart_related_boundry != LF && *multipart_related_boundry != NULL_CHAR) + multipart_related_boundry -= 1; + + multipart_related_boundry += 1; + memcpy(multipart_boundary, multipart_related_boundry, multipart_related_boundry_end - multipart_related_boundry); + + EM_DEBUG_LOG("multipart_boundary [%s], boundary_string [%s]", multipart_boundary, boundary_string); + + if (strcmp(multipart_boundary, boundary_string) == 0) + end = strstr(txt_html, boundary_string); + else + end = strstr(txt_html, multipart_boundary); + + memset(multipart_boundary, 0, strlen(multipart_boundary)); + + EM_DEBUG_LOG("end [%p], txt_html [%p]", end, txt_html); + + if (end == NULL) { + EM_DEBUG_LOG("HTML body contents exceeds %d Bytes", PARTIAL_BODY_SIZE_IN_BYTES); + + end = txt_html + body_size - (txt_html - bufsendforparse); + html_uidno = 1; + } + else if(end == txt_html) { /* empty multipart */ + EM_DEBUG_LOG("Emtpy HTML multipart"); + return false; + } + else { + if ((*(end-2) == CR) && (*(end-1) == LF)) + end -= 2; + else if ((*(end-2) == CR) && (*(end-1) == LF) + && (*(end-4) == CR) && (*(end-3) == LF)) + end -= 4; + else + EM_DEBUG_EXCEPTION(" Content not per as grammar."); + } + + EM_DEBUG_LOG("end [%p], txt_html [%p]", end, txt_html); + + EM_DEBUG_LOG("iEncodingHeader [%d]", iEncodingHeader); + + if (iEncodingHeader == 1){ + enc_type = ENCOTHER; + if (strncasecmp(Encoding, "base64", strlen("base64")) == 0) + enc_type = ENCBASE64; + else if (strncasecmp(Encoding, "quoted-printable", strlen("quoted-printable")) == 0) + enc_type = ENCQUOTEDPRINTABLE; + + EM_DEBUG_LOG("enc_type [%d]", enc_type); + + memcpy(text_html, start, end - txt_html); + + if (em_core_decode_body_text(text_html, end - txt_html, enc_type , &dec_len, &err) < 0) + EM_DEBUG_EXCEPTION("em_core_decode_body_text failed [%d]", err); + } + else if (start_header && ((temp_enc1 = (char *)strcasestr(start_header, "Content-transfer-encoding:")) != NULL) && !(temp_enc1 && temp_enc1 >= end)){ + if (temp_enc1) + start_header = temp_enc1; + + start_header += strlen("Content-Transfer-Encoding:"); + start_header = em_core_skip_whitespace_without_strdup(start_header); + + if (!start_header) + EM_DEBUG_EXCEPTION(" Invalid parsing "); + else{ + enc_type = ENCOTHER; + if (strncasecmp(start_header, "base64", strlen("base64")) == 0) + enc_type = ENCBASE64; + else if (strncasecmp(start_header, "quoted-printable", strlen("quoted-printable")) == 0) + enc_type = ENCQUOTEDPRINTABLE; + + EM_DEBUG_LOG("enc_type [%d]", enc_type); + + memcpy(text_html, start, end - txt_html); + + if (em_core_decode_body_text(text_html, end - txt_html, enc_type , &dec_len, &err) < 0) + EM_DEBUG_EXCEPTION("em_core_decode_body_text failed [%d]", err); + html_length = dec_len; + } + + EM_DEBUG_LOG("Decoded length = %d", dec_len); + EM_DEBUG_LOG("start - %s", start); + } + else{ + memcpy(text_html, start, end-txt_html); + html_length = (end-txt_html); + } + + /* EM_DEBUG_LOG(" Content-Type: text/html [%s]\n", text_html); */ + } + else + EM_DEBUG_EXCEPTION(" Invalid html body content "); + + EM_DEBUG_FUNC_END(); + return true; +} + + + +/*For the following scenario +*Content-Transfer-Encoding : base64 +*Content-Type : text/plain; charset = "windows-1252" +*MIME-Version : 1.0 +*Message-ID: <11512468.945901271910226702.JavaMail.weblogic@epml03> +*/ + +#define CONTENT_TRANSFER_ENCODING "Content-Transfer-Encoding" + +static int em_core_parse_plain_part_for_partial_body(char *header_start_string, char *start_header, char *boundary_string, char *bufsendforparse, char *text_plain, int body_size) +{ + EM_DEBUG_FUNC_BEGIN("header_start_string[%s], start_header[%s], boundary_string [%s], bufsendforparse [%s], text_plain [%s]", header_start_string, start_header, boundary_string, bufsendforparse, text_plain); + int err = EMF_ERROR_NONE, iEncodingHeader = 0, enc_type = ENCOTHER; + int dec_len = 0, strcmpret = -1; + char *pHeaderStart = NULL, *pEncodingHeaderEnd = NULL; + char EncodingHeader[40] = {0, }; + char Encoding[30] = {0, }; + char *temp_text_boundary = NULL; + char *start = NULL, *end = NULL, *txt_plain = NULL, *temp_enc1 = NULL; + + EM_DEBUG_LOG("Content-Type : text/plain"); + + pHeaderStart = header_start_string; + temp_text_boundary = start_header; + + memcpy(EncodingHeader, pHeaderStart, 25); + + if (strcasecmp(EncodingHeader, "Content-Transfer-Encoding") == 0){ + pEncodingHeaderEnd = strstr(pHeaderStart, CRLF_STRING); + memcpy(Encoding, pHeaderStart + 27, pEncodingHeaderEnd - (pHeaderStart + 27)); + iEncodingHeader = 1; + } + + /* Plain text content found */ + + txt_plain = start_header; + txt_plain = strstr(txt_plain, CRLF_STRING CRLF_STRING); + + if (txt_plain != NULL){ + txt_plain += strlen(CRLF_STRING CRLF_STRING); /* txt_plain points at plain text content */ + + /* Fix is done for mail having "Content-Type: text/plain" but there is no content but having only attachment. */ + + strcmpret = strncmp(txt_plain, boundary_string, strlen(boundary_string)); + if (strcmpret == 0){ + } + else{ + start = txt_plain; + end = strstr(txt_plain, boundary_string); + + if (end == NULL){ + EM_DEBUG_LOG("Text body contents exceeds %d Bytes", PARTIAL_BODY_SIZE_IN_BYTES); + end = txt_plain + body_size - (txt_plain - bufsendforparse); + } + else{ + /* EM_DEBUG_LOG("pbd_event[temp_count].partial_body_complete - %d", partial_body_complete); */ + + if ((*(end-2) == CR) && (*(end-1) == LF)) + end -= 2; + else if ((*(end-2) == CR) && (*(end-1) == LF) + && (*(end-4) == CR) && (*(end-3) == LF)) + end -= 4; + else + EM_DEBUG_EXCEPTION(" Content not per as grammar."); + } + + if (iEncodingHeader == 1){ + enc_type = ENCOTHER; + if (strncasecmp(Encoding, "base64", strlen("base64")) == 0) + enc_type = ENCBASE64; + else if (strncasecmp(Encoding, "quoted-printable", strlen("quoted-printable")) == 0) + enc_type = ENCQUOTEDPRINTABLE; + + EM_DEBUG_LOG("enc_type [%d]", enc_type); + + memcpy(text_plain, start, end - txt_plain); + + if (em_core_decode_body_text(text_plain, end - txt_plain, enc_type , &dec_len, &err) < 0) + EM_DEBUG_EXCEPTION("em_core_decode_body_text failed [%d]", err); + } + else if (start_header && ((temp_enc1 = (char *)strcasestr(start_header, "Content-transfer-encoding:")) != NULL) && !(temp_enc1 && temp_enc1 >= end)){ + if (temp_enc1) + start_header = temp_enc1; + + start_header += strlen("Content-Transfer-Encoding:"); + start_header = em_core_skip_whitespace_without_strdup(start_header); + + if (!start_header) + EM_DEBUG_EXCEPTION(" Invalid parsing "); + else{ + enc_type = ENCOTHER; + if (strncasecmp(start_header, "base64", strlen("base64")) == 0) + enc_type = ENCBASE64; + else if (strncasecmp(start_header, "quoted-printable", strlen("quoted-printable")) == 0) + enc_type = ENCQUOTEDPRINTABLE; + + EM_DEBUG_LOG("enc_type [%d]", enc_type); + memcpy(text_plain, start, end - txt_plain); + if (em_core_decode_body_text(text_plain, end - txt_plain, enc_type , &dec_len, &err) < 0) + EM_DEBUG_EXCEPTION("em_core_decode_body_text failed [%d]", err); + } + + EM_DEBUG_LOG("Decoded length = %d", dec_len); + /* EM_DEBUG_LOG("start - %s", start); */ /* print raw MIME content. */ + } + else + memcpy(text_plain, start, end-txt_plain); + + /* EM_DEBUG_LOG(" Content-type: text/plain [%s]\n", text_plain); */ + } + } + else + EM_DEBUG_EXCEPTION(" Invalid text body content "); + + EM_DEBUG_FUNC_END(); + return 1; +} + + + +/* Content-Type : IMAGE/octet-stream; name = Default.png */ +/* Content-Transfer-Encoding : BASE64 */ +/* Content-ID: <4b0d6810b17291f9438783a8eb9d5228@email-service> */ +/* Content-Disposition : inline; filename = Default.png */ + +static int em_core_parse_image_part_for_partial_body(char *header_start_string, char *start_header, char *boundary_string, char *bufsendforparse, emf_image_data *image_data, int body_size) +{ + EM_DEBUG_FUNC_BEGIN(); + + int err = EMF_ERROR_NONE; + char *multiple_image = NULL; + int donot_parse_next_image = 0; + char *image_boundary = NULL; + char *image_boundary_end = NULL; + char temp_image_boundary[256] = {0}; + int i = 0, ch_image = 0, cidno = 0; + int enc_type = ENCOTHER, dec_len = 0, image_length = 0; + char *p = header_start_string; + char *start = NULL, *end = NULL, *txt_image = NULL; + char *temp_image = NULL; + char *temp_cid1 = NULL; + char *cid_end = NULL; + char *temp_enc1 = NULL; + + + image_boundary = start_header; + image_boundary_end = image_boundary - 2; + image_boundary = image_boundary - 2; + + EM_DEBUG_LOG("Content-type: image"); + + while (*image_boundary != LF) + image_boundary--; + + image_boundary++; + + if (image_boundary != NULL && image_boundary_end != NULL) + memcpy(temp_image_boundary, image_boundary, image_boundary_end-image_boundary); + + if ((char *)strcasestr((const char *)temp_image_boundary, "Content-type:") == NULL) + boundary_string = temp_image_boundary; + do { + if (multiple_image != NULL){ + p = multiple_image; + start_header = multiple_image; + } + if ((strcasestr(p, "Content-Disposition: attachment")) || (!strcasestr(p, "Content-ID: <"))){ + EM_DEBUG_EXCEPTION(" Body has attachment no need to parse "); + end = NULL; + multiple_image = NULL; + } + else{ /* HTML Content found */ + ch_image = 0; + cidno = 0; + int boundarylen = -1; + char *cid = NULL; + char *temp_name = NULL; + + memset(image_data[i].image_file_name, 0, 100); + txt_image = start_header; + temp_image = start_header; + + temp_name = strstr(txt_image, "name="); + if (temp_name != NULL){ + temp_image = temp_name; + if (*(temp_image+5) == '"') + temp_image = temp_image+5; + + while (*temp_image != CR){ + temp_image++; + memcpy(image_data[i].image_file_name+ch_image, temp_image, 1); + ch_image++; + } + + if ((*(temp_name+4) == '=') && (*(temp_name+5) == '\"')) + image_data[i].image_file_name[ch_image-2] = '\0'; + + if ((*(temp_name+4) == '=') && (*(temp_name+5) != '\"')) + image_data[i].image_file_name[ch_image-1] = '\0'; + } + + if (((temp_cid1 = (char *)strcasestr((const char *)start_header, "Content-ID: <")) != NULL)){ + if (temp_cid1){ + cid = temp_cid1; + temp_image = temp_cid1; + } + + cid += 13; + cid_end = strstr(temp_image, "\076"); /* 076 == '>' */ + + image_data[i].content_id = (char *)em_core_malloc(cid_end-cid+5); + if (image_data[i].content_id != NULL){ + strcpy(image_data[i].content_id, "cid:"); + memcpy(image_data[i].content_id+4, cid, cid_end-cid); + } + else + EM_DEBUG_EXCEPTION("em_core_malloc() failed"); + + if (image_data[i].image_file_name[0] == '\0') + memcpy(image_data[i].image_file_name, cid, cid_end - cid); + } + + txt_image = strstr(txt_image, CRLF_STRING CRLF_STRING); + + if (txt_image != NULL){ + txt_image += 4; /* txt_image points at image content */ + start = txt_image; + end = strstr(txt_image, boundary_string); + + + if (end == NULL){ + EM_DEBUG_LOG("HTML body contents exceeds %d Bytes", PARTIAL_BODY_SIZE_IN_BYTES); + /* end points to end of partial body data */ + end = txt_image + body_size - (txt_image-bufsendforparse); + } + else{ + boundarylen = strlen(boundary_string); + end -= 2; + } + + if (start_header && ((temp_enc1 = (char *)strcasestr((const char *)start_header, "Content-transfer-encoding:")) != NULL)){ + if (temp_enc1) + start_header = temp_enc1; + + start_header += strlen("Content-Transfer-Encoding:"); + start_header = em_core_skip_whitespace_without_strdup(start_header); + + if (!start_header) + EM_DEBUG_EXCEPTION(" Invalid parsing "); + else{ + enc_type = ENCOTHER; + if (strncasecmp(start_header, "base64", strlen("base64")) == 0) + enc_type = ENCBASE64; + else if (strncasecmp(start_header, "quoted-printable", strlen("quoted-printable")) == 0) + enc_type = ENCQUOTEDPRINTABLE; + + EM_DEBUG_LOG("enc_type [%d]", enc_type); + + image_data[i].text_image = (char *)em_core_malloc((end-txt_image)+1); + if (image_data[i].text_image){ + memcpy(image_data[i].text_image, start, end-txt_image); + if (em_core_decode_body_text(image_data[i].text_image, end-txt_image, enc_type , &(image_data[i].dec_len), &err) < 0) + EM_DEBUG_EXCEPTION("em_core_decode_body_text failed [%d]", err); + else + image_length = image_data[i].dec_len; + } + else + EM_DEBUG_EXCEPTION("em_core_malloc() failed"); + } + + EM_DEBUG_LOG("Decoded length [%d]", dec_len); + } + else{ + image_data[i].text_image = (char *)em_core_malloc(end-txt_image); + if (image_data[i].text_image) + memcpy(image_data[i].text_image, start, end - txt_image); + else + EM_DEBUG_EXCEPTION("em_core_malloc() failed"); + } + } + else{ + donot_parse_next_image = 1; + EM_DEBUG_EXCEPTION(" Invalid html body content "); + } + } + + if (end != NULL) { + multiple_image = (char *)strcasestr((const char *)end, "Content-type: image"); + i++; + } + } while (multiple_image != NULL && donot_parse_next_image != 1 && (i < IMAGE_DISPLAY_PARTIAL_BODY_COUNT)); + + EM_DEBUG_FUNC_END(); + return 1; +} + +static int em_core_find_boundary_string_of_the_part(const char *whole_string, const char *first_line_of_part, char **result_boundary_string, int *error) +{ + EM_DEBUG_FUNC_BEGIN("whole_string[%p], first_line_of_part[%p], result_boundary_string[%p]", whole_string, first_line_of_part, result_boundary_string); + int ret = false, err = EMF_ERROR_NONE; + char *boundary_cur = NULL, *boundary_end = NULL, *boundary_string = NULL; + + if(!whole_string || !first_line_of_part || !result_boundary_string) { + EM_DEBUG_EXCEPTION("EMF_ERROR_INVALID_PARAM"); + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + if(first_line_of_part - 2 > whole_string) { + boundary_cur = (char*)first_line_of_part - 2; /* 2 means CRLF. */ + boundary_end = boundary_cur; + + do{ + boundary_cur--; + } while (whole_string < boundary_cur && *boundary_cur != LF && *boundary_cur != NULL_CHAR); + + boundary_cur++; + + if(boundary_end > boundary_cur && boundary_cur > whole_string) { + EM_DEBUG_LOG("boundary_end - boundary_cur + 15 [%d]", boundary_end - boundary_cur + 15); + boundary_string = em_core_malloc(boundary_end - boundary_cur + 15); + if(!boundary_string) { + EM_DEBUG_EXCEPTION("em_core_malloc failed"); + err = EMF_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + memcpy(boundary_string, boundary_cur, boundary_end - boundary_cur); + EM_DEBUG_LOG("boundary_string [%s]", boundary_string); + *result_boundary_string = boundary_string; + } + else { + EM_DEBUG_EXCEPTION("There is no string before the part"); + err = EMF_ERROR_ON_PARSING; + goto FINISH_OFF; + } + } + else { + EM_DEBUG_EXCEPTION("There is no string before the part"); + err = EMF_ERROR_ON_PARSING; + goto FINISH_OFF; + } + ret = true; +FINISH_OFF: + + if(error) + *error = err; + + EM_DEBUG_FUNC_END("ret[%d], err[%d]", ret, err); + return ret; +} + +#define TAG_LENGTH 16 +#define COMMAND_LENGTH 2000 +EXPORT_API int em_core_bulk_partial_mailbody_download_for_imap(MAILSTREAM *stream, emf_event_partial_body_thd *pbd_event, int item_count, int *error) +{ + EM_DEBUG_FUNC_BEGIN("stream [%p], pbd_event [%p], item_count [%d], error [%p]", stream, pbd_event, item_count, error); + + int ret = false, err = EMF_ERROR_NONE; + int encoding = 0; + int j = 0; + int i32_index = 0, temp_string_index = 0; + int no_alternative_part_flag = 0; + int dec_len = 0, response_buffer_length = 0, mailparselen = 0, image_length = 0, tempmailparselen = 0; + int temp_count = 0, total_mail_size = 0, attachment_num, body_size = 0, total_mail_size_except_attach = 0; + int total_parsed_len_per_uid = 0, total_parsed_len = 0; + unsigned long uidno = 0; + char buf[512] = {0, }; + char text_plain[PARTIAL_BODY_SIZE_IN_BYTES + 1] = {0, }; + char text_html[PARTIAL_BODY_SIZE_IN_BYTES + 1] = {0, }; + char temp_text_buf[PARTIAL_BODY_SIZE_IN_BYTES + 1] = {0, }; + char uid_range_string_to_be_downloaded[UID_RANGE_STRING_LENGTH] = {0, }; + char imap_tag[TAG_LENGTH] = {0, }; + char command[COMMAND_LENGTH] = {0, }; + char *p = NULL, *s = NULL, *decoded_text_buffer = NULL; + char *response_buffer = NULL; + char *bufsendforparse = NULL; + char *start_header = NULL; + char *boundary_string = NULL; + char *temp_content_type1 = NULL; + char *bodystructure_start = NULL, *bodystructure_end = NULL, *body_structure_string = NULL, *moified_body_structure_string = NULL; + char *plain_text_file_name_from_content_info = NULL, *html_text_file_name_from_content_info = NULL, *plain_charset_from_content_info = NULL; + char temp_string[TEMP_STRING_LENGTH] = {0, }; + IMAPLOCAL *imaplocal = NULL; + IMAPPARSEDREPLY *reply_from_server = NULL; + emf_mail_tbl_t *mail = NULL; + emf_partial_buffer *imap_response = NULL; + BODY *body = NULL; + struct _m_content_info *cnt_info = NULL; + struct attachment_info *attach_info = NULL; + emf_mail_attachment_tbl_t attachment_tbl; + emf_event_partial_body_thd *stSectionNo = NULL; + emf_image_data image_data[IMAGE_DISPLAY_PARTIAL_BODY_COUNT]; + + if (!(stream) || !(imaplocal = stream->local) || !imaplocal->netstream || !pbd_event) { + EM_DEBUG_EXCEPTION("invalid parameter"); + err = EMF_ERROR_INVALID_PARAM; + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; + } + + memset(image_data, 0x00 , sizeof(emf_image_data) * IMAGE_DISPLAY_PARTIAL_BODY_COUNT); + + EM_DEBUG_LOG("Start of em_core_get_section_for_partial_download, item_count = %d ", item_count); + + /* For constructing UID list which is having 10 UID or less at a time */ + for (j = 0, stSectionNo = pbd_event; (stSectionNo != NULL && j < item_count); j++) + { + EM_DEBUG_LOG("pbd_event[%d].account_id [%d], mail_id [%d], server_mail_id [%d], activity_id [%d]", \ + j, stSectionNo[j].account_id, stSectionNo[j].mail_id, stSectionNo[j].server_mail_id, stSectionNo[j].activity_id); + + if (i32_index >= UID_RANGE_STRING_LENGTH){ + EM_DEBUG_EXCEPTION("String length exceeded its limitation!"); + goto FINISH_OFF; + } + + if (j == item_count - 1) + i32_index += SNPRINTF(uid_range_string_to_be_downloaded + i32_index, UID_RANGE_STRING_LENGTH, "%lu", stSectionNo[j].server_mail_id); + else + i32_index += SNPRINTF(uid_range_string_to_be_downloaded + i32_index, UID_RANGE_STRING_LENGTH, "%lu,", stSectionNo[j].server_mail_id); + } + + SNPRINTF(imap_tag, TAG_LENGTH, "%08lx", 0xffffffff & (stream->gensym++)); + SNPRINTF(command, COMMAND_LENGTH, "%s UID FETCH %s (BODYSTRUCTURE BODY.PEEK[TEXT]<0.15360>)\015\012", imap_tag, uid_range_string_to_be_downloaded); + + mm_dlog(command); + + /* Sending out the IMAP request */ + if (!net_sout(imaplocal->netstream, command, (int)strlen(command))) { + EM_DEBUG_EXCEPTION("net_sout failed..."); + err = EMF_ERROR_CONNECTION_BROKEN; + goto FINISH_OFF; + } + + /* responce from the server */ + imap_response = em_core_get_response_from_server(imaplocal->netstream, imap_tag, &reply_from_server); + + if (!imap_response || !reply_from_server ){ + EM_DEBUG_EXCEPTION(" Invalid response from em_core_get_response_from_server"); + goto FINISH_OFF; + } + + if (!imap_response->buffer || imap_response->buflen == 0){ + EM_DEBUG_EXCEPTION(" NULL partial BODY Content "); + goto FINISH_OFF; + } + EM_DEBUG_LOG("imap_response->buffer [%s]",imap_response->buffer); + response_buffer = imap_response->buffer; + response_buffer_length = imap_response->buflen; + + while (response_buffer && (bodystructure_start = strstr(response_buffer, "BODYSTRUCTURE (")) != NULL){ + /* if it has BODYSTRUCTURE */ + EM_DEBUG_LOG("response_buffer [%s]",response_buffer); + bodystructure_start = bodystructure_start + strlen("BODYSTRUCTURE"); + bodystructure_end = strstr(bodystructure_start, "BODY["); + + if (bodystructure_end != NULL){ + int bodystructure_length = bodystructure_end - bodystructure_start; + + EM_DEBUG_LOG("bodystructure_length [%d]", bodystructure_length); + + if (bodystructure_length > response_buffer_length){ + EM_DEBUG_EXCEPTION("bodystructure_length[%d] is longer than response_buffer_length[%d]", bodystructure_length, response_buffer_length); + err = EMF_ERROR_INVALID_RESPONSE; + goto FINISH_OFF; + } + + body_structure_string = (char *)em_core_malloc(sizeof(char) * bodystructure_length + 1); + + if (NULL == body_structure_string){ + EM_DEBUG_EXCEPTION("em_core_malloc failed...!"); + err = EMF_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + memcpy(body_structure_string, bodystructure_start, bodystructure_length); + + body = mail_newbody(); + + if (NULL == body){ + EM_DEBUG_EXCEPTION("New body creation failed...!"); + EM_SAFE_FREE(body_structure_string); + goto FINISH_OFF; + } + + /* Parse body_structure_string to BODY */ + EM_DEBUG_LOG("body_structure_string [%s]", body_structure_string); + /* body_structure_string modified */ + moified_body_structure_string = em_core_replace_string(body_structure_string, "}\r\n", "} "); + if (moified_body_structure_string != NULL) { + EM_SAFE_STRNCPY(body_structure_string, moified_body_structure_string, strlen(moified_body_structure_string)); + EM_DEBUG_LOG("moified_body_structure_string [%s]", moified_body_structure_string); + } + imap_parse_body_structure (stream, body, (unsigned char **)&body_structure_string, reply_from_server); + + total_mail_size = 0; + + if (em_core_set_fetch_body_section(body, true, &total_mail_size, &err) < 0) { + EM_DEBUG_EXCEPTION("em_core_set_fetch_body_section failed - %d", err); + goto FINISH_OFF; + } + + if (!(cnt_info = em_core_malloc(sizeof(struct _m_content_info)))) { + EM_DEBUG_EXCEPTION("em_core_malloc failed..."); + err = EMF_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + memset(cnt_info, 0, sizeof(struct _m_content_info)); + + /* getting content info from body */ + + if (em_core_get_body(stream, 0, 0, 0, body, cnt_info, &err) < 0 || !cnt_info) { + EM_DEBUG_EXCEPTION("em_core_get_body falied [%d]", err); + err = EMF_ERROR_IMAP4_FETCH_UID_FAILURE; + goto FINISH_OFF; + } + + EM_DEBUG_LOG("Start parsing partial body..."); + + int no_html = 0; + char *temp_alternative_plain_header = NULL; + + p = (char *)strstr(response_buffer, " {"); + if (p != NULL){ + EM_DEBUG_LOG("Getting the body size"); + p += strlen(" {"); + s = p; + + temp_string_index = 0; + memset(temp_string, 0, TEMP_STRING_LENGTH); + + while (isdigit(*s) && temp_string_index < TEMP_STRING_LENGTH){ + memcpy(temp_string + temp_string_index, s, 1); /* ! */ + s++; + temp_string_index++; + } + + body_size = atoi(temp_string); + EM_DEBUG_LOG("body_size [%d]", body_size); + } + else{ + body_size = 0; + EM_DEBUG_EXCEPTION("Can't find body size from MIME header"); + /* err = EMF_ERROR_INVALID_RESPONSE; */ + /* goto FINISH_OFF; */ + } + + /* Find next line */ + tempmailparselen = 0; + while (tempmailparselen < response_buffer_length && response_buffer[tempmailparselen] != LF) + tempmailparselen++; + tempmailparselen++; + + if (imap_response->buflen < (total_parsed_len + body_size)){ + err = EMF_ERROR_CONNECTION_BROKEN; + EM_DEBUG_EXCEPTION("EMF_ERROR_CONNECTION_BROKEN : imap_response->buflen [%d], total_parsed_len [%d], body_size [%d]", imap_response->buflen, total_parsed_len, body_size); + goto FINISH_OFF; + } + else { + if ((p = strstr(response_buffer, "UID "))) { + EM_DEBUG_LOG("getting the UID number"); + p += strlen("UID "); + s = p; + + temp_string_index = 0; + memset(temp_string, 0, TEMP_STRING_LENGTH); + + while (isdigit(*s) && temp_string_index < TEMP_STRING_LENGTH){ + memcpy(temp_string + temp_string_index, s, 1); + s++; + temp_string_index++; + } + + uidno = strtoul(temp_string, NULL, 0); + EM_DEBUG_LOG("UID [%d]", uidno); + + for (temp_count = 0; temp_count < BULK_PARTIAL_BODY_DOWNLOAD_COUNT && + pbd_event[temp_count].server_mail_id != uidno && temp_count != item_count; temp_count++) + continue; + + if (temp_count >= BULK_PARTIAL_BODY_DOWNLOAD_COUNT){ + EM_DEBUG_EXCEPTION("Can't find proper server_mail_id"); + goto FINISH_OFF; + } + + EM_SAFE_FREE(plain_text_file_name_from_content_info); + EM_SAFE_FREE(html_text_file_name_from_content_info); + EM_SAFE_FREE(plain_charset_from_content_info); + + /* partial_body_complete = -1; */ /* Meaningless */ + /* encoding = -1; */ /* Meaningless */ + + plain_text_file_name_from_content_info = EM_SAFE_STRDUP(cnt_info->text.plain); + html_text_file_name_from_content_info = EM_SAFE_STRDUP(cnt_info->text.html); + plain_charset_from_content_info = EM_SAFE_STRDUP(cnt_info->text.plain_charset); + + EM_DEBUG_LOG("plain_text_file_name_from_content_info [%s]", plain_text_file_name_from_content_info); + EM_DEBUG_LOG("html_text_file_name_from_content_info [%s]", html_text_file_name_from_content_info); + EM_DEBUG_LOG("plain_charset_from_content_info [%s]", plain_charset_from_content_info); + + encoding = body->encoding; + + if (!em_storage_get_maildata_by_servermailid(pbd_event[temp_count].account_id, temp_string, &mail , true, &err) || !mail){ + EM_DEBUG_EXCEPTION("em_storage_get_maildata_by_servermailid failed [%d]", err); + if (err == EM_STORAGE_ERROR_MAIL_NOT_FOUND || !mail) + goto FINISH_OFF; + } + + /* Assign calculated mail size */ + mail->mail_size = total_mail_size; + total_mail_size_except_attach = total_mail_size; + + /* Update attachment details except inline content */ + if (cnt_info->file && cnt_info->file->name){ + memset(&attachment_tbl, 0x00, sizeof(emf_attachment_info_t)); + + attachment_tbl.account_id = pbd_event[temp_count].account_id; + attachment_tbl.mail_id = mail->mail_id; + attachment_tbl.mailbox_name = pbd_event[temp_count].mailbox_name; + attachment_tbl.file_yn = 0; + + for (attachment_num = 1, attach_info = cnt_info->file; attach_info; attach_info = attach_info->next, attachment_num++) { + total_mail_size_except_attach -= attach_info->size; + attachment_tbl.attachment_size = attach_info->size; + attachment_tbl.attachment_path = attach_info->save; + attachment_tbl.attachment_name = attach_info->name; + attachment_tbl.flag2 = attach_info->drm; + attachment_tbl.flag3 = (attach_info->type == 1) ? 1 : 0; +#ifdef __ATTACHMENT_OPTI__ + attachment_tbl.encoding = attach_info->encoding; + attachment_tbl.section = attach_info->section; +#endif + + if (attach_info->type == 1) { + EM_DEBUG_LOG("Breaking attachment_num [%d] attach_info->type [%d]", attachment_num, attach_info->type); + break; /* Inline images at end of list not to be added */ + } + + EM_DEBUG_LOG("attach_info->type != 1 [%d]", attachment_num); + + mail->attachment_count++; + if (!em_storage_add_attachment(&attachment_tbl, 0, false, &err)) { + EM_DEBUG_EXCEPTION("em_storage_add_attachment failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + + } + } + + em_core_mime_free_content_info(cnt_info); + cnt_info = NULL; + + mail_free_body(&body); + body = NULL; + + } + + /* Find next line. */ + mailparselen = 0; + + while (mailparselen < response_buffer_length && response_buffer[mailparselen] != LF) + mailparselen++; + + mailparselen++; + + /* Removed the response header and send the buffer for parsing */ + response_buffer = response_buffer + mailparselen; + response_buffer_length = response_buffer_length - mailparselen; + + bufsendforparse = em_core_malloc(body_size + 1); /* old */ + /* bufsendforparse = em_core_malloc(response_buffer_length + 1); */ /* new */ + + EM_DEBUG_LOG("body_size [%d], response_buffer_length [%d]", body_size, response_buffer_length); + + if (bufsendforparse == NULL){ + EM_DEBUG_EXCEPTION("Allocation for bufsendforparse failed."); + err = EMF_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + memcpy(bufsendforparse, response_buffer, body_size); /* old */ + bufsendforparse[body_size] = NULL_CHAR; /* old */ + /* EM_SAFE_STRNCPY(bufsendforparse, response_buffer, response_buffer_length);*/ /* new */ + /* bufsendforparse[response_buffer_length] = '\0'; */ /* new */ + + if (strlen(bufsendforparse) == 0) + EM_DEBUG_EXCEPTION(" NULL partial BODY Content "); + + EM_DEBUG_LOG("string bufendforparse :[%s]", bufsendforparse); + p = bufsendforparse; + EM_DEBUG_LOG("string p :[%s]", p); + if (mail && mail->body_download_status == EMF_BODY_DOWNLOAD_STATUS_FULLY_DOWNLOADED) /* No need to save */ + goto NEXTUIDPARSING; + + if (!strcasestr(p, "Content-Type: text/plain") && !strcasestr(p, "Content-Type: text/html") && !strcasestr(p, "Content-type: image/jpeg") + && !strcasestr(p, "Content-Type: image/gif") && !strcasestr(p, "Content-Type: image/bmp")&&(plain_text_file_name_from_content_info || html_text_file_name_from_content_info)){ + /* Encoded Content-Type: text/html or Content-Type: text/plain */ + /* No Partial body has No headers with Content-Type: text/html or Content-Type: text/plain */ + + EM_DEBUG_LOG("plain_text_file_name_from_content_info [%p] html_text_file_name_from_content_info[%p] ", plain_text_file_name_from_content_info, html_text_file_name_from_content_info); + EM_DEBUG_LOG("mbody->encoding [%d] ", encoding); + + if (em_core_decode_body_text(p, strlen(p), encoding , &dec_len, &err) < 0) { + EM_DEBUG_EXCEPTION("em_core_decode_body_text failed [%d]", err); + goto FINISH_OFF; + } + + decoded_text_buffer = p; + + EM_DEBUG_LOG("Decoded length [%d]", dec_len); + /* EM_DEBUG_LOG("p - %s", p); */ + + if (dec_len > 0){ + if (plain_text_file_name_from_content_info){ + EM_DEBUG_LOG(" plain_text_file_name_from_content_info [%s]", plain_text_file_name_from_content_info); + memcpy(text_plain, decoded_text_buffer, dec_len); + /* EM_DEBUG_LOG(" Content-Type : text/plain [%s]", text_plain); */ + } + + if (html_text_file_name_from_content_info){ + EM_DEBUG_LOG("html_text_file_name_from_content_info [%s]", html_text_file_name_from_content_info); + memcpy(text_html, decoded_text_buffer, dec_len); + /* EM_DEBUG_LOG(" Content-Type: text/html [%s]", text_html); */ + } + } + } + else{ /* Partial body has headers with Content-Type: text/html or Content-Type: text/plain */ + no_alternative_part_flag = 0; + + if (((temp_alternative_plain_header = (char *)strcasestr(p, "Content-type: multipart/alternative")) != NULL)){ /* Found 'alternative' */ + if (((temp_content_type1 = (char *)strcasestr(p, "Content-type: text/plain")) != NULL)){ + if (temp_content_type1 < temp_alternative_plain_header) /* This part is text/plain not alternative. */ + no_html = 1; + no_alternative_part_flag = 1; + } + else{ + EM_DEBUG_LOG(" Content-type: multipart/alternative "); + p = strstr(bufsendforparse, CRLF_STRING CRLF_STRING); + + if (p == NULL) + EM_DEBUG_EXCEPTION(" Incorrect parsing "); + else{ + p += strlen(CRLF_STRING CRLF_STRING); + boundary_string = p; + if (boundary_string[0] == CR){ + EM_DEBUG_EXCEPTION(" Incorrect Body structure "); + goto NEXTUIDPARSING; + } + + p = strstr(p, CRLF_STRING); + + if (p == NULL) + EM_DEBUG_EXCEPTION(" Invalid parsing "); + } + } + } + else + no_alternative_part_flag = 1; + + if (no_alternative_part_flag){ + p = strstr(bufsendforparse, "--"); + + boundary_string = p; + if (boundary_string == NULL){ + EM_DEBUG_EXCEPTION("Should not have come here "); + goto NEXTUIDPARSING; + } + + if (boundary_string[0] == CR){ + EM_DEBUG_EXCEPTION(" Incorrect Body structure "); + goto NEXTUIDPARSING; + } + + p = strstr(p, CRLF_STRING); + if (p == NULL) + EM_DEBUG_EXCEPTION(" Invalid parsing "); + } + + /* EM_DEBUG_LOG("p[%s]", p); */ + + if (p != NULL){ + *p = NULL_CHAR; /* Boundary value set */ + EM_DEBUG_LOG("Boundary value [%s]", boundary_string); + p += 2; /* p points to content after boundary_string */ + + if (((start_header = (char *)strcasestr(p, "Content-Type: text/html")) != NULL) && (no_html != 1) &&(((char *)strcasestr(p, "Content-Type: message/rfc822")) == NULL) && + (((char *)strcasestr(p, "Content-Type: text/rfc822-headers")) == NULL)) + em_core_parse_html_part_for_partial_body(start_header, boundary_string, bufsendforparse, text_html, body_size); + + if (((start_header = (char *)strcasestr(p, "Content-Type: text/plain")) != NULL)) { + char *internal_boundary_string = NULL; + if(!em_core_find_boundary_string_of_the_part(bufsendforparse, start_header, &internal_boundary_string, &err)) { + EM_DEBUG_EXCEPTION("internal_boundary_string failed [%d]", err); + } + + if(!internal_boundary_string) + internal_boundary_string = EM_SAFE_STRDUP(boundary_string); + + em_core_parse_plain_part_for_partial_body(p, start_header, internal_boundary_string, bufsendforparse, text_plain, body_size); + EM_SAFE_FREE(internal_boundary_string); + } + + if (((start_header = (char *)strcasestr((const char *)p, "Content-type: image/jpeg")) != (char *)NULL) || + ((start_header = (char *)strcasestr((const char *)p, "Content-Type: image/gif")) != (char *)NULL) || + ((start_header = (char *)strcasestr((const char *)p, "Content-Type: image/bmp")) != (char *)NULL)) + em_core_parse_image_part_for_partial_body(p, start_header, boundary_string, bufsendforparse, image_data, body_size); + } + } + + /* Updating mail information */ + memset(buf, 0x00, sizeof(buf)); + + if (!em_storage_create_dir(pbd_event[temp_count].account_id, mail->mail_id, 0, &err)) + EM_DEBUG_EXCEPTION("em_storage_create_dir failed [%d]", err); + + if (!em_storage_get_save_name(pbd_event[temp_count].account_id, mail->mail_id, 0, + plain_charset_from_content_info ? plain_charset_from_content_info : "UTF-8", buf, &err)) + EM_DEBUG_EXCEPTION("em_storage_get_save_name failed [%d]", err); + + if (!em_storage_create_file(text_plain, strlen(text_plain), buf, &err)) + EM_DEBUG_EXCEPTION("em_storage_create_file failed [%d]", err); + + mail->file_path_plain = EM_SAFE_STRDUP(buf); + EM_DEBUG_LOG("mail->file_path_plain [%s]", mail->file_path_plain); + + if (image_data[0].text_image != NULL && image_data[0].text_image[0] != NULL_CHAR){ + char *result_string_of_replcaing = NULL; + char temp_data_html[PARTIAL_BODY_SIZE_IN_BYTES + 1] = {0}; + int store_file = 0; + int content_index = 0; + + memset(buf, 0x00, sizeof(buf)); + if (text_html[0] != NULL_CHAR) + memcpy(temp_data_html, text_html, strlen(text_html)); + /* EM_SAFE_STRNCPY(temp_data_html, text_html, text_html); */ + + do { + if (!em_storage_create_dir(pbd_event[temp_count].account_id, mail->mail_id, 0, &err)) + EM_DEBUG_EXCEPTION("em_storage_create_dir failed [%d]", err); + + if (!em_storage_get_save_name(pbd_event[temp_count].account_id, mail->mail_id, 0, image_data[store_file].image_file_name, buf, &err)) + EM_DEBUG_EXCEPTION("em_storage_get_save_name failed [%d]", err); + + if (!em_storage_create_file(image_data[store_file].text_image, image_data[store_file].dec_len, buf, &err)) + EM_DEBUG_EXCEPTION("em_storage_create_file failed [%d]", err); + + if (mail->body_download_status != EMF_BODY_DOWNLOAD_STATUS_PARTIALLY_DOWNLOADED){ + memset(&attachment_tbl, 0x00, sizeof(emf_mail_attachment_tbl_t)); + attachment_tbl.mail_id = mail->mail_id; + attachment_tbl.account_id = pbd_event[temp_count].account_id; + attachment_tbl.mailbox_name = stream->mailbox; + attachment_tbl.attachment_name = image_data[store_file].image_file_name; + attachment_tbl.attachment_size = image_data[store_file].dec_len; + attachment_tbl.attachment_path = buf; + attachment_tbl.file_yn = 1; + attachment_tbl.flag3 = 1; /* set to 1 for inline image */ + mail->attachment_count++; + mail->inline_content_count++; + if (!em_storage_add_attachment (&attachment_tbl, false, false, &err)) + EM_DEBUG_EXCEPTION("em_storage_add_attachment failed - %d", err); + } + + store_file++; + } while (image_data[store_file].text_image != NULL && image_data[store_file].text_image[0] != NULL_CHAR && (store_file < IMAGE_DISPLAY_PARTIAL_BODY_COUNT)); + + while (image_data[content_index].text_image != NULL && image_data[content_index].text_image[0] != NULL_CHAR && + image_data[content_index].content_id && image_data[content_index].content_id[0] != NULL_CHAR && (content_index < IMAGE_DISPLAY_PARTIAL_BODY_COUNT)){ /* Finding CID in HTML and replacing with image name. */ + result_string_of_replcaing = em_core_replace_string((char *)temp_data_html, (char *)image_data[content_index].content_id, (char *)image_data[content_index].image_file_name); + + EM_SAFE_STRNCPY(temp_data_html, result_string_of_replcaing, PARTIAL_BODY_SIZE_IN_BYTES); + EM_SAFE_FREE(result_string_of_replcaing); + + if (strstr(temp_data_html, image_data[content_index].content_id) != NULL) + continue; /* Replace content id on HTML with same file name one more time. */ + + EM_SAFE_FREE(image_data[content_index].content_id); + EM_SAFE_FREE(image_data[content_index].text_image); + memset(image_data[content_index].image_file_name, 0x00, 100); + image_data[content_index].dec_len = 0; + content_index++; + } + + image_length = 0; + memset(text_html, 0, PARTIAL_BODY_SIZE_IN_BYTES+1); + + if (temp_data_html[0] != NULL_CHAR) + memcpy(text_html, temp_data_html, strlen(temp_data_html)); + memset(temp_data_html, 0x00, PARTIAL_BODY_SIZE_IN_BYTES+1); + } + + if (strlen(text_html) > 0){ + memset(buf, 0x00, sizeof(buf)); + char html_body[MAX_CHARSET_VALUE] = {0x00, }; + if (plain_charset_from_content_info != NULL){ + if (strlen(plain_charset_from_content_info) < MAX_CHARSET_VALUE) + memcpy(html_body, plain_charset_from_content_info, strlen(plain_charset_from_content_info)); + else + memcpy(html_body, "UTF-8", strlen("UTF-8")); + } + if (html_body[0] != NULL_CHAR) + strcat(html_body, HTML_EXTENSION_STRING); + else + memcpy(html_body, "UTF-8.htm", strlen("UTF-8.htm")); + + if (!em_storage_create_dir(pbd_event[temp_count].account_id, mail->mail_id, 0, &err)) + EM_DEBUG_EXCEPTION("em_storage_create_dir failed [%d]", err); + + if (!em_storage_get_save_name(pbd_event[temp_count].account_id, mail->mail_id, 0, html_body, buf, &err)) + EM_DEBUG_EXCEPTION("em_storage_get_save_name failed [%d]", err); + + if (!em_storage_create_file(text_html, strlen(text_html), buf, &err)) + EM_DEBUG_EXCEPTION("em_storage_create_file failed [%d]", err); + + mail->file_path_html = EM_SAFE_STRDUP(buf); + + } + + mail->body_download_status = (total_mail_size_except_attach < PARTIAL_BODY_SIZE_IN_BYTES) ? 1 : 2; + EM_DEBUG_LOG("total_mail_size_except_attach [%d], mail->body_download_status [%d]", total_mail_size_except_attach, mail->body_download_status); + + /* Get preview text */ + if ( (err = em_core_get_preview_text_from_file(mail->file_path_plain, mail->file_path_html, MAX_PREVIEW_TEXT_LENGTH, &(mail->preview_text))) != EMF_ERROR_NONE) + EM_DEBUG_EXCEPTION("em_core_get_preview_text_from_file() failed[%d]", err); + + /* Update body contents */ + if (!em_storage_change_mail_field(mail->mail_id, UPDATE_PARTIAL_BODY_DOWNLOAD, mail, true, &err)) + EM_DEBUG_EXCEPTION("em_storage_change_mail_field failed - %d", err); + +NEXTUIDPARSING: + + response_buffer = response_buffer + body_size; /* Set pointer for next mail body. */ + + /* Find end of body */ + if ((response_buffer[0] == CR) && (response_buffer[1] == LF)&& (response_buffer[2] == ')') + && (response_buffer[3] == CR) && (response_buffer[4] == LF)){ + response_buffer = response_buffer + 5; + total_parsed_len_per_uid = body_size+tempmailparselen + 5; + } + else if ((response_buffer[0] == ')') && (response_buffer[1] == CR) && (response_buffer[2] == LF)){ + response_buffer = response_buffer + 3; + total_parsed_len_per_uid = body_size+tempmailparselen + 3; + } + else + EM_DEBUG_EXCEPTION("Mail response end could not found, - %c : %c : %c", response_buffer[0], response_buffer[1], response_buffer[2]); + + EM_SAFE_FREE(bufsendforparse); + + memset(text_html, 0, PARTIAL_BODY_SIZE_IN_BYTES+1); + memset(text_plain, 0, PARTIAL_BODY_SIZE_IN_BYTES+1); + memset(temp_text_buf, 0, PARTIAL_BODY_SIZE_IN_BYTES+1); + + if (mail) + em_storage_free_mail(&mail, 1, NULL); + + /* Free the activity for mail id in partial body activity table */ + if (false == em_core_delete_pbd_activity(pbd_event[temp_count].account_id, pbd_event[temp_count].mail_id, pbd_event[temp_count].activity_id, &err)){ + EM_DEBUG_EXCEPTION("em_core_delete_pbd_activity failed [%d]", err); + goto FINISH_OFF; + } + } + + total_parsed_len += total_parsed_len_per_uid; + } + } + + EM_DEBUG_LOG("imap_response buflen is [%d]", imap_response->buflen); + ret = true; + +FINISH_OFF: + + if (error) + *error = err; + + if (true != ret) + EM_DEBUG_EXCEPTION("Failed download for the uid list %s", command); + + if(reply_from_server) { + EM_SAFE_FREE(reply_from_server->key); + EM_SAFE_FREE(reply_from_server->line); + EM_SAFE_FREE(reply_from_server->tag); + EM_SAFE_FREE(reply_from_server->text); + EM_SAFE_FREE(reply_from_server); + } + + EM_SAFE_FREE(bufsendforparse); + EM_SAFE_FREE(plain_text_file_name_from_content_info); + EM_SAFE_FREE(html_text_file_name_from_content_info); + EM_SAFE_FREE(plain_charset_from_content_info); + + if (cnt_info) + em_core_mime_free_content_info(cnt_info); + + if (body) + mail_free_body(&body); + + if (imap_response) + EM_SAFE_FREE(imap_response->buffer); + EM_SAFE_FREE(imap_response); + + if (mail) + em_storage_free_mail(&mail, 1, NULL); + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API int em_core_bulk_partial_mailbody_download_for_pop3(MAILSTREAM *stream, emf_event_partial_body_thd *pbd_event, int item_count, int *error) +{ + EM_DEBUG_FUNC_BEGIN("stream [%p], pbd_event [%p], item_count [%d], error [%p]", stream, pbd_event, item_count, error); + int ret = false, err = EMF_ERROR_NONE; + int i; + + if (!stream || !pbd_event) { + EM_DEBUG_EXCEPTION("EMF_ERROR_INVALID_PARAM"); + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + for (i = 0; i < item_count; i++) { + EM_DEBUG_LOG("pbd_event[%d].account_id [%d], mail_id [%d], server_mail_id [%d], activity_id [%d]", \ + i, pbd_event[i].account_id, pbd_event[i].mail_id, pbd_event[i].server_mail_id, pbd_event[i].activity_id); + + if (!em_core_mail_download_body_multi_sections_bulk(stream, pbd_event[i].account_id, pbd_event[i].mail_id, false, false, PARTIAL_BODY_SIZE_IN_BYTES, 0 , &err)){ + EM_DEBUG_EXCEPTION("em_core_mail_download_body_multi_sections_bulk failed"); + goto FINISH_OFF; + } + + if (false == em_core_delete_pbd_activity(pbd_event[i].account_id, pbd_event[i].mail_id, pbd_event[i].activity_id, &err)){ + EM_DEBUG_EXCEPTION("em_core_delete_pbd_activity failed [%d]", err); + goto FINISH_OFF; + } + } + + ret = true; + +FINISH_OFF: + if (error) + *error = err; + + EM_DEBUG_FUNC_END("ret [%d] err [%d]", ret, err); + return ret; +} + + + +EXPORT_API int em_core_bulk_partial_mailbody_download(MAILSTREAM *stream, emf_event_partial_body_thd *pbd_event, int item_count, int *error) +{ + EM_DEBUG_FUNC_BEGIN("stream [%p], pbd_event [%p], item_count [%d], error [%p]", stream, pbd_event, item_count, error); + int ret = false, err = EMF_ERROR_NONE; + emf_account_t *pbd_account = NULL; + + if (!stream || !pbd_event) { + EM_DEBUG_EXCEPTION("EMF_ERROR_INVALID_PARAM"); + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + pbd_account = em_core_get_account_reference(pbd_event[0].account_id); + + if (pbd_account == NULL){ + EM_DEBUG_EXCEPTION("EMF_ERROR_INVALID_ACCOUNT"); + err = EMF_ERROR_INVALID_ACCOUNT; + goto FINISH_OFF; + } + + switch (pbd_account->receiving_server_type){ + case EMF_SERVER_TYPE_IMAP4: + ret = em_core_bulk_partial_mailbody_download_for_imap(stream, pbd_event, item_count, &err); + break; + case EMF_SERVER_TYPE_POP3: + ret = em_core_bulk_partial_mailbody_download_for_pop3(stream, pbd_event, item_count, &err); + break; + default: + err = EMF_ERROR_NOT_SUPPORTED; + ret = false; + break; + } + + ret = true; +FINISH_OFF: + if (error) + *error = err; + + EM_DEBUG_FUNC_END("ret [%d] err [%d]", ret, err); + return ret; +} + + +static emf_partial_buffer *em_core_get_response_from_server (NETSTREAM *nstream, char *tag, IMAPPARSEDREPLY **reply) +{ + EM_DEBUG_FUNC_BEGIN(); + + if (!nstream || !tag || !reply){ + EM_DEBUG_EXCEPTION("EMF_ERROR_INVALID_PARAM"); + return NIL; + } + + emf_partial_buffer *retPartialBuffer = NULL; + IMAPPARSEDREPLY *ret_reply = NULL; + char *pline = NULL; + int linelen = 0; + int bytes_copied = 0; + int allocated_buffer_size = (BULK_PARTIAL_BODY_DOWNLOAD_COUNT + 1) * PARTIAL_BODY_SIZE_IN_BYTES ; + + retPartialBuffer = (emf_partial_buffer *)em_core_malloc(sizeof(emf_partial_buffer)); + + if (NULL == retPartialBuffer){ + EM_DEBUG_EXCEPTION("em_core_malloc failed"); + return NIL; + } + + retPartialBuffer->buffer = (char *)em_core_malloc(allocated_buffer_size); + + if (NULL == retPartialBuffer->buffer){ + EM_DEBUG_EXCEPTION("em_core_malloc failed"); + EM_SAFE_FREE(retPartialBuffer); + return NIL; + } + + while (nstream){ + if (!(pline = net_getline(nstream))) { + EM_DEBUG_EXCEPTION("net_getline failed..."); + EM_SAFE_FREE(retPartialBuffer->buffer); + EM_SAFE_FREE(retPartialBuffer); + + return NIL; + } + + linelen = strlen(pline); + memcpy(retPartialBuffer->buffer + bytes_copied, pline, linelen); + bytes_copied += linelen; + memcpy(retPartialBuffer->buffer + bytes_copied, CRLF_STRING, 2); + bytes_copied += 2; + + if (0 == strncmp(pline, tag, strlen(tag))) { + + ret_reply = em_core_malloc(sizeof(IMAPPARSEDREPLY)); + + if (!ret_reply){ + EM_DEBUG_EXCEPTION("em_core_malloc failed"); + return NIL; + } + + if(reply) + *reply = ret_reply; + + if (0 == strncmp(pline + strlen(tag) + 1, "OK", 2)) { + ret_reply->line = (unsigned char*)EM_SAFE_STRDUP(tag); + ret_reply->tag = (unsigned char*)EM_SAFE_STRDUP(tag); + ret_reply->key = (unsigned char*)EM_SAFE_STRDUP("OK"); + ret_reply->text = (unsigned char*)EM_SAFE_STRDUP("Success"); + EM_SAFE_FREE(pline); + break; + } + else { + EM_DEBUG_EXCEPTION("Tagged Response not OK. IMAP4 Response -> [%s]", pline); + ret_reply->line = (unsigned char*)EM_SAFE_STRDUP(tag); + ret_reply->tag = (unsigned char*)EM_SAFE_STRDUP(tag); + ret_reply->key = (unsigned char*)EM_SAFE_STRDUP("NO"); + ret_reply->text = (unsigned char*)EM_SAFE_STRDUP("Fail"); + + EM_SAFE_FREE(pline); + EM_SAFE_FREE(retPartialBuffer->buffer); + EM_SAFE_FREE(retPartialBuffer); + + return NIL; + } + + EM_DEBUG_LOG("ret_reply->line [%s]", ret_reply->line); + EM_DEBUG_LOG("ret_reply->tag [%s]", ret_reply->tag); + EM_DEBUG_LOG("ret_reply->key [%s]", ret_reply->key); + EM_DEBUG_LOG("ret_reply->text [%s]", ret_reply->text); + + } + EM_SAFE_FREE(pline); + } + + retPartialBuffer->buflen = strlen(retPartialBuffer->buffer); + + EM_DEBUG_FUNC_END("retPartialBuffer [%p]", retPartialBuffer); + return retPartialBuffer; +} + +#endif /* __FEATURE_PARTIAL_BODY_DOWNLOAD__ */ +/* EOF */ diff --git a/email-core/em-core-mailbox.c b/email-core/em-core-mailbox.c new file mode 100755 index 0000000..712b3be --- /dev/null +++ b/email-core/em-core-mailbox.c @@ -0,0 +1,1168 @@ +/* +* email-service +* +* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. +* +* Contact: Kyuho Jo <kyuho.jo@samsung.com>, Sunghyun Kwon <sh0701.kwon@samsung.com> +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + + +/****************************************************************************** + * File : em-core-mailbox.c + * Desc : Local Mailbox Management + * + * Auth : + * + *****************************************************************************/ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include <sys/types.h> +#include "emf-types.h" +#include "emf-dbglog.h" +#include "em-core-global.h" +#include "em-core-utils.h" +#include "em-core-mailbox.h" +#include "em-core-event.h" +#include "em-core-mesg.h" +#include "em-core-imap-mailbox.h" +#include "em-storage.h" +#include "em-core-account.h" + +#ifdef __FEATURE_KEEP_CONNECTION__ +static void *g_receiving_thd_stream = NULL; /* Stores the recv thd stream for next time reuse */ +static int prev_acc_id_recv_thd = 0; /* Stores the account id for which recv thd stream is open */ +extern int recv_thread_run; + +static void *g_partial_body_thd_stream = NULL; /* Stores the pb thd stream for next time reuse */ +static int prev_acc_id_pb_thd = 0; /* Stores the account id for which pb thd stream is open */ + +__thread emf_connection_info_t *g_connection_info_list = NULL; + +#ifdef __FEATURE_USE_PTHREAD__ +static pthread_mutex_t _close_stream_lock = PTHREAD_MUTEX_INITIALIZER; /* Mutex to protect closing stream */ +#else /* __FEATURE_USE_PTHREAD__ */ +static GMutex *_close_stream_lock = NULL; /* Mutex to protect closing stream */ +#endif /* __FEATURE_USE_PTHREAD__ */ + +#endif /* __FEATURE_KEEP_CONNECTION__ */ + + +/* Binding IMAP mailbox with its function */ +static emf_mailbox_type_item_t g_mailbox_type[MAX_MAILBOX_TYPE] = { + {EMF_MAILBOX_TYPE_INBOX, "INBOX" }, + /* Naver */ + {EMF_MAILBOX_TYPE_INBOX, "Inbox" }, + {EMF_MAILBOX_TYPE_SENTBOX, "Sent Messages"} , + {EMF_MAILBOX_TYPE_SPAMBOX, "&wqTTOLpUx3zVaA-"} , + {EMF_MAILBOX_TYPE_DRAFT, "Drafts"} , + {EMF_MAILBOX_TYPE_TRASH, "Deleted Messages" } , + /* Google English */ + {EMF_MAILBOX_TYPE_SENTBOX, "[Gmail]/Sent Mail"} , + {EMF_MAILBOX_TYPE_SPAMBOX, "[Gmail]/Spam"} , + {EMF_MAILBOX_TYPE_DRAFT, "[Gmail]/Drafts"} , + {EMF_MAILBOX_TYPE_TRASH, "[Gmail]/Trash" } , + {EMF_MAILBOX_TYPE_ALL_EMAILS, "[Gmail]/All Mail" } , + /* Google Korean */ + {EMF_MAILBOX_TYPE_SENTBOX, "[Gmail]/&vPSwuNO4ycDVaA-"} , + {EMF_MAILBOX_TYPE_SPAMBOX, "[Gmail]/&wqTTONVo-" }, + {EMF_MAILBOX_TYPE_DRAFT, "[Gmail]/&x4TC3Lz0rQDVaA-"} , + {EMF_MAILBOX_TYPE_TRASH, "[Gmail]/&1zTJwNG1-"} , + {EMF_MAILBOX_TYPE_ALL_EMAILS, "[Gmail]/&yATMtLz0rQDVaA-" } , + /* AOL */ + {EMF_MAILBOX_TYPE_SENTBOX, "Sent"} , + {EMF_MAILBOX_TYPE_SPAMBOX, "Spam" }, + {EMF_MAILBOX_TYPE_DRAFT, "Drafts"} , + {EMF_MAILBOX_TYPE_TRASH, "Trash"}, + /* DAUM */ + {EMF_MAILBOX_TYPE_SPAMBOX, "&wqTTONO4ycDVaA-"}, + /* ETC */ + {EMF_MAILBOX_TYPE_SENTBOX, "mail/sent-mail"}, + {EMF_MAILBOX_TYPE_SPAMBOX, "mail/spam-mail" }, + {EMF_MAILBOX_TYPE_DRAFT, "mail/saved-drafts"} , + {EMF_MAILBOX_TYPE_TRASH, "mail/mail-trash"}, +}; + +#ifdef __FEATURE_KEEP_CONNECTION__ +emf_connection_info_t* em_core_get_connection_info_by_account_id(int account_id) +{ + EM_DEBUG_FUNC_BEGIN("account_id [%d]", account_id); + emf_connection_info_t *connection_info = g_connection_info_list; + + while(connection_info) { + if(connection_info->account_id == account_id) + break; + connection_info = connection_info->next; + } + + EM_DEBUG_FUNC_END("connection_info [%p]", connection_info); + return connection_info; +} + +int em_core_append_connection_info(emf_connection_info_t *new_connection_info) +{ + EM_DEBUG_FUNC_BEGIN("new_connection_info [%p]", new_connection_info); + emf_connection_info_t *connection_info = g_connection_info_list; + + if(!new_connection_info) { + EM_DEBUG_EXCEPTION("EMF_ERROR_INVALID_PARAM"); + return EMF_ERROR_INVALID_PARAM; + } + + if(em_core_get_connection_info_by_account_id(new_connection_info->account_id)) { + EM_DEBUG_EXCEPTION("EMF_ERROR_ALREADY_EXISTS"); + return EMF_ERROR_ALREADY_EXISTS; + } + + if(connection_info) { + while(connection_info) { + if(connection_info->next == NULL) { + connection_info->next = new_connection_info; + new_connection_info->next = NULL; + } + connection_info = connection_info->next; + } + } + else { + new_connection_info->next = NULL; + g_connection_info_list = new_connection_info; + } + + EM_DEBUG_FUNC_END("EMF_ERROR_NONE"); + return EMF_ERROR_NONE; +} + +EXPORT_API int em_core_remove_connection_info(int account_id) +{ + EM_DEBUG_FUNC_BEGIN("account_id [%d]", account_id); + emf_connection_info_t *connection_info = g_connection_info_list, *prev_connection_info = NULL; + + while(connection_info) { + if(connection_info->account_id == account_id) { + if(prev_connection_info) { + prev_connection_info->next = connection_info->next; + } + else { + g_connection_info_list = connection_info->next; + } + EM_SAFE_FREE(connection_info); + break; + } + prev_connection_info = connection_info; + connection_info = connection_info->next; + } + + EM_DEBUG_FUNC_END(""); + return EMF_ERROR_NONE; +} + +#endif /* __FEATURE_KEEP_CONNECTION__ */ + + +/* description + * get local mailbox list + */ +EXPORT_API int em_core_mailbox_get_list(int account_id, emf_mailbox_t **mailbox_list, int *p_count, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id[%d], mailbox_list[%p], p_count[%p], err_code[%p]", account_id, mailbox_list, p_count, err_code); + + if (account_id <= 0 || !mailbox_list || !p_count) { + EM_DEBUG_EXCEPTION("PARAM Failed account_id[%d], mailbox_list[%p], p_count[%p]", account_id, mailbox_list, p_count); + if (err_code != NULL) + *err_code = EMF_ERROR_INVALID_PARAM; + return false; + } + + int ret = false; + int error = EMF_ERROR_NONE; + emf_mailbox_tbl_t *local_mailbox_list = NULL; + emf_account_t *ref_account = NULL; + int i, count = 512; + + /* get mailbox list from mailbox table */ + + if (!(ref_account = em_core_get_account_reference(account_id))) { + EM_DEBUG_EXCEPTION(" em_core_get_account_reference failed - %d", account_id); + error = EMF_ERROR_INVALID_ACCOUNT; + goto FINISH_OFF; + } + + if (!em_storage_get_mailbox(ref_account->account_id, EMF_MAILBOX_ALL, EMAIL_MAILBOX_SORT_BY_NAME_ASC, &count, &local_mailbox_list, true, &error)) { + EM_DEBUG_EXCEPTION(" em_storage_get_mailbox failed - %d", error); + error = em_storage_get_emf_error_from_em_storage_error(error); + goto FINISH_OFF; + } + + if (count > 0) { + if (!(*mailbox_list = em_core_malloc(sizeof(emf_mailbox_t) * count))) { + EM_DEBUG_EXCEPTION(" mailloc failed..."); + error = EMF_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + memset(*mailbox_list, 0x00, (sizeof(emf_mailbox_t) * count)); + + for (i = 0; i < count; i++) { + (*mailbox_list)[i].mailbox_id = local_mailbox_list[i].mailbox_id; + (*mailbox_list)[i].account_id = account_id; + (*mailbox_list)[i].name = local_mailbox_list[i].mailbox_name; local_mailbox_list[i].mailbox_name = NULL; + (*mailbox_list)[i].alias = local_mailbox_list[i].alias; local_mailbox_list[i].alias = NULL; + (*mailbox_list)[i].local = local_mailbox_list[i].local_yn; + (*mailbox_list)[i].mailbox_type = local_mailbox_list[i].mailbox_type; + (*mailbox_list)[i].synchronous = local_mailbox_list[i].sync_with_server_yn; + (*mailbox_list)[i].unread_count = local_mailbox_list[i].unread_count; + (*mailbox_list)[i].total_mail_count_on_local = local_mailbox_list[i].total_mail_count_on_local; + (*mailbox_list)[i].total_mail_count_on_server = local_mailbox_list[i].total_mail_count_on_server; + (*mailbox_list)[i].has_archived_mails = local_mailbox_list[i].has_archived_mails; + (*mailbox_list)[i].mail_slot_size = local_mailbox_list[i].mail_slot_size; + } + } + else + mailbox_list = NULL; + + * p_count = count; + + ret = true; + +FINISH_OFF: + if (local_mailbox_list != NULL) + em_storage_free_mailbox(&local_mailbox_list, count, NULL); + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END(); + return ret; +} + +/* description + * get imap sync mailbox list + */ +int em_core_mailbox_get_list_to_be_sync(int account_id, emf_mailbox_t **mailbox_list, int *p_count, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id[%d], mailbox_list[%p], p_count[%p], err_code[%p]", account_id, mailbox_list, p_count, err_code); + + if (account_id <= 0 || !mailbox_list || !p_count) { + EM_DEBUG_EXCEPTION(" account_id[%d], mailbox_list[%p], p_count[%p]", account_id, mailbox_list, p_count); + if (err_code != NULL) + *err_code = EMF_ERROR_INVALID_PARAM; + return false; + } + + int ret = false; + int error = EMF_ERROR_NONE; + emf_mailbox_t *tmp_mailbox_list = NULL; + emf_mailbox_tbl_t *mailbox_tbl_list = NULL; + emf_account_t *ref_account = NULL; + int i, count = 512; + + /* get mailbox list from mailbox table */ + if (!(ref_account = em_core_get_account_reference(account_id))) { + EM_DEBUG_EXCEPTION("em_core_get_account_reference failed - %d", account_id); + error = EMF_ERROR_INVALID_ACCOUNT; + goto FINISH_OFF; + } + + if (!em_storage_get_mailbox(ref_account->account_id, 0, EMAIL_MAILBOX_SORT_BY_TYPE_ASC, &count, &mailbox_tbl_list, true, &error)) { + EM_DEBUG_EXCEPTION("em_storage_get_mailbox failed - %d", error); + error = em_storage_get_emf_error_from_em_storage_error(error); + goto FINISH_OFF; + } + + if (count > 0) { + if (!(tmp_mailbox_list = em_core_malloc(sizeof(emf_mailbox_t) * count))) { + EM_DEBUG_EXCEPTION("malloc failed..."); + error = EMF_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + memset(tmp_mailbox_list, 0x00, (sizeof(emf_mailbox_t) * count)); + + for (i = 0; i < count; i++) { + tmp_mailbox_list[i].mailbox_id = mailbox_tbl_list[i].mailbox_id; + tmp_mailbox_list[i].account_id = account_id; + tmp_mailbox_list[i].name = mailbox_tbl_list[i].mailbox_name; mailbox_tbl_list[i].mailbox_name = NULL; + tmp_mailbox_list[i].mailbox_type = mailbox_tbl_list[i].mailbox_type; + tmp_mailbox_list[i].alias = mailbox_tbl_list[i].alias; mailbox_tbl_list[i].alias = NULL; + tmp_mailbox_list[i].local = mailbox_tbl_list[i].local_yn; + tmp_mailbox_list[i].synchronous = mailbox_tbl_list[i].sync_with_server_yn; + tmp_mailbox_list[i].unread_count = mailbox_tbl_list[i].unread_count; + tmp_mailbox_list[i].total_mail_count_on_local = mailbox_tbl_list[i].total_mail_count_on_local; + tmp_mailbox_list[i].total_mail_count_on_server = mailbox_tbl_list[i].total_mail_count_on_server; + tmp_mailbox_list[i].mail_slot_size = mailbox_tbl_list[i].mail_slot_size; + } + } + else + tmp_mailbox_list = NULL; + *p_count = count; + ret = true; + +FINISH_OFF: + + *mailbox_list = tmp_mailbox_list; + + + if (mailbox_tbl_list != NULL) + em_storage_free_mailbox(&mailbox_tbl_list, count, NULL); + + if (err_code != NULL) + *err_code = error; + EM_DEBUG_FUNC_END("error [%d]", error); + return ret; +} + +EXPORT_API int em_core_mailbox_get_mail_count(emf_mailbox_t *mailbox, int *total, int *unseen, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("mailbox[%p], total[%p], unseen[%p], err_code[%p]", mailbox, total, unseen, err_code); + + int ret = false; + int err = EMF_ERROR_NONE; + + if (!mailbox) { + EM_DEBUG_EXCEPTION(" mailbox[%p], total[%p], unseen[%p]", mailbox, total, unseen); + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + if (!em_storage_get_mail_count(mailbox->account_id, mailbox->name, total, unseen, true, &err)) { + EM_DEBUG_EXCEPTION(" em_storage_get_mail_count failed - %d", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + + + ret = true; + +FINISH_OFF: + if (err_code != NULL) + *err_code = err; + + return ret; +} + +EXPORT_API int em_core_mailbox_create(emf_mailbox_t *new_mailbox, int on_server, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("new_mailbox[%p], err_code[%p]", new_mailbox, err_code); + int ret = false; + int err = EMF_ERROR_NONE; + emf_mailbox_tbl_t local_mailbox; + + if (new_mailbox == NULL || new_mailbox->name == NULL) { + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + if (on_server) { + /* Create a mailbox from Sever */ + if (!em_core_mailbox_create_imap_mailbox(new_mailbox, &err)) { + EM_DEBUG_EXCEPTION(">>>>> mailbox Creation in Server FAILED >>> "); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + else + EM_DEBUG_LOG(">>>>> mailbox Creation in Server SUCCESS >>> "); + } + + memset(&local_mailbox, 0x00, sizeof(emf_mailbox_tbl_t)); + EM_DEBUG_LOG("box name[%s] local yn[%d] mailbox_type[%d]", new_mailbox->name, local_mailbox.local_yn, new_mailbox->mailbox_type); + + /* add local mailbox into local mailbox table */ + local_mailbox.mailbox_id = new_mailbox->mailbox_id; + local_mailbox.account_id = new_mailbox->account_id; + local_mailbox.local_yn = new_mailbox->local; + local_mailbox.mailbox_name = new_mailbox->name; + local_mailbox.alias = new_mailbox->alias; + local_mailbox.sync_with_server_yn = new_mailbox->synchronous; + local_mailbox.mailbox_type = new_mailbox->mailbox_type; + local_mailbox.unread_count = 0; + local_mailbox.total_mail_count_on_local = 0; + local_mailbox.total_mail_count_on_server = 0; + em_core_mailbox_get_default_mail_slot_count(&local_mailbox.mail_slot_size, NULL); + + if (strncmp(new_mailbox->name, EMF_INBOX_NAME, strlen(EMF_INBOX_NAME)) == 0 || + strncmp(new_mailbox->name, EMF_DRAFTBOX_NAME, strlen(EMF_DRAFTBOX_NAME)) == 0 || + strncmp(new_mailbox->name, EMF_OUTBOX_NAME, strlen(EMF_OUTBOX_NAME)) == 0 || + strncmp(new_mailbox->name, EMF_SENTBOX_NAME, strlen(EMF_SENTBOX_NAME)) == 0) + local_mailbox.modifiable_yn = 0; /* can be deleted/modified */ + else + local_mailbox.modifiable_yn = 1; + + + if (!em_storage_add_mailbox(&local_mailbox, true, &err)) { + EM_DEBUG_EXCEPTION(" em_storage_add_mailbox failed - %d", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + ret = true; + +FINISH_OFF: + if (err_code) + *err_code = err; + + return ret; +} + +EXPORT_API int em_core_mailbox_delete(emf_mailbox_t *mailbox, int on_server, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("mailbox[%p], err_code[%p]", mailbox, err_code); + + int ret = false; + int err = EMF_ERROR_NONE; + + if (mailbox == NULL) { + EM_DEBUG_EXCEPTION(" mailbox[%p]", mailbox); + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + if (!em_core_mail_delete_all(mailbox, on_server, &err)) { + EM_DEBUG_EXCEPTION(" em_core_mail_delete_all failed - %d", err); + goto FINISH_OFF; + } + + if (on_server) { + EM_DEBUG_LOG(">> Delete the mailbox in Sever >>> "); + if (!em_core_mailbox_delete_imap_mailbox(mailbox, &err)) + EM_DEBUG_EXCEPTION(">>> Delete the mailbox in Server : FAILED >>> "); + else + EM_DEBUG_LOG(">>> Delete the mailbox in Server : SUCCESS >>> "); + } + + if (!em_storage_delete_mailbox(mailbox->account_id, -1, mailbox->name, true, &err)) { + EM_DEBUG_EXCEPTION(" em_storage_delete_mailbox failed - %d", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + + ret = true; + +FINISH_OFF: + if (err_code != NULL) + *err_code = err; + + return ret; +} + +EXPORT_API int em_core_mailbox_delete_all(emf_mailbox_t *mailbox, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN(); + + EM_DEBUG_LOG(" mailbox[%p], err_code[%p]", mailbox, err_code); + + int ret = false; + int err = EMF_ERROR_NONE; + + if (mailbox == NULL) { + EM_DEBUG_EXCEPTION(" mailbox[%p]", mailbox); + + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + if (!em_core_mail_delete_all(mailbox, 0, /*NULL, */ &err)) { + EM_DEBUG_EXCEPTION(" em_core_mail_delete_all failed - %d", err); + + goto FINISH_OFF; + } + + if (!em_storage_delete_mailbox(mailbox->account_id, -1, mailbox->name, true, &err)) { + EM_DEBUG_EXCEPTION(" em_storage_delete_mailbox failed - %d", err); + + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + + ret = true; + +FINISH_OFF: + if (err_code != NULL) + *err_code = err; + + return ret; +} + +EXPORT_API int em_core_mailbox_update(emf_mailbox_t *old_mailbox, emf_mailbox_t *new_mailbox, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("old_mailbox[%p], new_mailbox[%p], err_code[%p]", old_mailbox, new_mailbox, err_code); + + int ret = false; + int err = EMF_ERROR_NONE; + + if (old_mailbox == NULL || new_mailbox == NULL) { + EM_DEBUG_EXCEPTION("old_mailbox[%p], new_mailbox[%p]", old_mailbox, new_mailbox); + + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + emf_mailbox_tbl_t new_mailbox_tbl; + memset(&new_mailbox_tbl, 0x00, sizeof(emf_mailbox_tbl_t)); + + /* Support only updating mailbox_type */ + new_mailbox_tbl.mailbox_type = new_mailbox->mailbox_type; + + if (old_mailbox->mailbox_type != new_mailbox_tbl.mailbox_type) { + if (!em_storage_update_mailbox_type(old_mailbox->account_id, -1, old_mailbox->name, &new_mailbox_tbl, true, &err)) { + EM_DEBUG_EXCEPTION("em_storage_update_mailbox failed - %d", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + } + + new_mailbox_tbl.mailbox_id = old_mailbox->mailbox_id; + new_mailbox_tbl.account_id = old_mailbox->account_id; + new_mailbox_tbl.mailbox_name = new_mailbox->name; + new_mailbox_tbl.mailbox_type = new_mailbox->mailbox_type; + new_mailbox_tbl.alias = new_mailbox->alias; + new_mailbox_tbl.sync_with_server_yn = new_mailbox->synchronous; + new_mailbox_tbl.mail_slot_size = new_mailbox->mail_slot_size; + new_mailbox_tbl.total_mail_count_on_server = new_mailbox->total_mail_count_on_server; + + if (!em_storage_update_mailbox(old_mailbox->account_id, -1, old_mailbox->name, &new_mailbox_tbl, true, &err)) { + EM_DEBUG_EXCEPTION("em_storage_update_mailbox failed - %d", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + + if (EM_SAFE_STRCMP(old_mailbox->name, new_mailbox_tbl.mailbox_name) != 0) { + if (!em_storage_rename_mailbox(old_mailbox->account_id, old_mailbox->name, new_mailbox_tbl.mailbox_name, true, &err)) { + EM_DEBUG_EXCEPTION("em_storage_rename_mailbox failed - %d", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + } + + ret = true; + +FINISH_OFF: + if (err_code) + *err_code = err; + + return ret; +} + +extern int try_auth; +extern int try_auth_smtp; + +extern long smtp_send(SENDSTREAM *stream, char *command, char *args); +extern long smtp_rcpt(SENDSTREAM *stream, ADDRESS *adr, long* error); + + +EXPORT_API int em_core_mailbox_open_with_account_info(emf_account_t *account, char *mailbox, void **result_stream, int *err_code) +{ + EM_PROFILE_BEGIN(emCoreMailboxOpen); + EM_DEBUG_FUNC_BEGIN("account[%p], mailbox[%p], mail_stream[%p], err_code[%p]", account, mailbox, result_stream, err_code); + + int ret = false; + int error = EMF_ERROR_NONE; + emf_session_t *session = NULL; + char *mbox_path = NULL; + void *reusable_stream = NULL; + int is_connection_for = _SERVICE_THREAD_TYPE_NONE; + + if (account == NULL) { + EM_DEBUG_EXCEPTION("Invalid Parameter."); + error = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + if (!em_core_get_current_session(&session)) { + EM_DEBUG_EXCEPTION("em_core_get_current_session failed..."); + error = EMF_ERROR_SESSION_NOT_FOUND; + goto FINISH_OFF; + } + + if (mailbox == NULL || (mailbox && strcmp(mailbox, ENCODED_PATH_SMTP) != 0)) + is_connection_for = _SERVICE_THREAD_TYPE_RECEIVING; + else + is_connection_for = _SERVICE_THREAD_TYPE_SENDING; + +#ifdef __FEATURE_KEEP_CONNECTION__ + emf_connection_info_t *connection_info = em_core_get_connection_info_by_account_id(account->account_id); + + if(connection_info) { + if (is_connection_for == _SERVICE_THREAD_TYPE_RECEIVING) { + if(connection_info->receiving_server_stream_status == EMF_STREAM_STATUS_CONNECTED) + reusable_stream = connection_info->receiving_server_stream; + } + else { + if(connection_info->sending_server_stream_status == EMF_STREAM_STATUS_CONNECTED) + reusable_stream = connection_info->sending_server_stream; + } + } + + if (reusable_stream != NULL) + EM_DEBUG_LOG("Stream reuse desired"); +#else + reusable_stream = *result_stream; +#endif + + session->error = EMF_ERROR_NONE; + em_core_set_network_error(EMF_ERROR_NONE); /* set current network error as EMF_ERROR_NONE before network operation */ + + if (is_connection_for == _SERVICE_THREAD_TYPE_RECEIVING) { + /* open pop3/imap server */ + MAILSTREAM *mail_stream = NULL; + + if (!em_core_get_long_encoded_path_with_account_info(account, mailbox, '/', &mbox_path, &error)) { + EM_DEBUG_EXCEPTION("em_core_get_long_encoded_path failed - %d", error); + session->error = error; + goto FINISH_OFF; + } + + EM_DEBUG_LOG("open mail connection to mbox_path [%s]", mbox_path); + + try_auth = 0; /* ref_account->receiving_auth ? 1 : 0 */ + session->auth = 0; /* ref_account->receiving_auth ? 1 : 0 */ + + if (!(mail_stream = mail_open(reusable_stream, mbox_path, IMAP_2004_LOG))) { + EM_DEBUG_EXCEPTION("mail_open failed. session->error[%d], session->network[%d]", session->error, session->network); + + if (session->network != EMF_ERROR_NONE) + session->error = session->network; + if ((session->error == EMF_ERROR_UNKNOWN) || (session->error == EMF_ERROR_NONE)) + session->error = EMF_ERROR_CONNECTION_FAILURE; + + error = session->error; + +#ifdef __FEATURE_KEEP_CONNECTION__ + /* Since mail_open failed Reset the global stream pointer as it is a dangling pointer now */ +#endif /* __FEATURE_KEEP_CONNECTION__ */ + goto FINISH_OFF; + } + *result_stream = mail_stream; + } + else { + /* open smtp server */ + SENDSTREAM *send_stream = NULL; + char *host_list[2] = {NULL, NULL}; + +#ifdef __FEATURE_KEEP_CONNECTION__ + if (reusable_stream != NULL) { + int send_ret = 0; + /* Check whether connection is avaiable */ + send_stream = reusable_stream; + /* + send_ret = smtp_send(send_stream, "RSET", 0); + + if (send_ret != SMTP_RESPONSE_OK) { + EM_DEBUG_EXCEPTION("[SMTP] RSET --> [%s]", send_stream->reply); + send_stream = NULL; + } + */ + } +#endif + if(!send_stream) { + if (!em_core_get_long_encoded_path_with_account_info(account, mailbox, 0, &mbox_path, &error)) { + EM_DEBUG_EXCEPTION(" em_core_get_long_encoded_path failed - %d", error); + session->error = error; + goto FINISH_OFF; + } + + EM_DEBUG_LOG("open SMTP connection to mbox_path [%s]", mbox_path); + + try_auth_smtp = account->sending_auth ? 1 : 0; + session->auth = account->sending_auth ? 1 : 0; + + host_list[0] = mbox_path; + + if (!(send_stream = smtp_open(host_list, 1))) { + EM_DEBUG_EXCEPTION("smtp_open failed... : current sending_security[%d] session->error[%d] session->network[%d]", account->sending_security, session->error, session->network); + if (session->network != EMF_ERROR_NONE) + session->error = session->network; + if ((session->error == EMF_ERROR_UNKNOWN) || (session->error == EMF_ERROR_NONE)) + session->error = EMF_ERROR_CONNECTION_FAILURE; + + error = session->error; + goto FINISH_OFF; + } + } + *result_stream = send_stream; + } + + ret = true; + +FINISH_OFF: + +#ifdef __FEATURE_KEEP_CONNECTION__ + if (ret == true) { + if(!connection_info) { + connection_info = em_core_malloc(sizeof(emf_connection_info_t)); + connection_info->account_id = account->account_id; + if(!connection_info) + EM_DEBUG_EXCEPTION("em_core_malloc for connection_info failed."); + else + em_core_append_connection_info(connection_info); + } + + if(connection_info) { + /* connection_info->account_id = account->account_id; */ + if (is_connection_for == _SERVICE_THREAD_TYPE_RECEIVING) { + connection_info->receiving_server_stream = *result_stream; + connection_info->receiving_server_stream_status = EMF_STREAM_STATUS_CONNECTED; + } + else { + connection_info->sending_server_stream = *result_stream; + connection_info->sending_server_stream_status = EMF_STREAM_STATUS_CONNECTED; + } + } + } +#endif + + EM_SAFE_FREE(mbox_path); + if (err_code != NULL) + *err_code = error; + EM_PROFILE_END(emCoreMailboxOpen); + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +#ifdef __FEATURE_KEEP_CONNECTION__ + +/*h.gahlaut@samsung.com : 20-oct-2010*/ +/*Precaution : When Reuse Stream feature is enabled then stream should only be closed using em_core_mailbox_close from email-service code. +mail_close should not be used directly from anywhere in code. +em_core_mailbox_close uses mail_close inside it. + +mail_close is only used in em_core_mailbox_open and em_core_reset_streams as an exception to above rule*/ + +EXPORT_API int em_core_mailbox_open(int account_id, char *mailbox, void **mail_stream, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id[%d], mailbox[%p], mail_stream[%p], err_code[%p]", account_id, mailbox, mail_stream, err_code); + + int ret = false; + int error = EMF_ERROR_NONE; + emf_account_t *ref_account = em_core_get_account_reference(account_id); + + if (!ref_account) { + EM_DEBUG_EXCEPTION("em_core_get_account_reference failed - account id[%d]", account_id); + error = EMF_ERROR_INVALID_ACCOUNT; + goto FINISH_OFF; + } + + ret = em_core_mailbox_open_with_account_info(ref_account, mailbox, mail_stream, &error); + +FINISH_OFF: + if (err_code) + *err_code = error; + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API +void em_core_close_receiving_stream() +{ + EM_DEBUG_FUNC_BEGIN("recv_thread_run [%d]", recv_thread_run); + if (!recv_thread_run) { + ENTER_CRITICAL_SECTION(_close_stream_lock); + mail_close(g_receiving_thd_stream); + g_receiving_thd_stream = NULL; + prev_acc_id_recv_thd = 0; + LEAVE_CRITICAL_SECTION(_close_stream_lock); + } + EM_DEBUG_FUNC_END(); +} + +EXPORT_API +void em_core_close_partial_body_stream() +{ + EM_DEBUG_FUNC_BEGIN(); + if (false == em_core_get_pbd_thd_state()) { + EM_DEBUG_LOG("em_core_get_pbd_thd_state returned false"); + mail_close(g_partial_body_thd_stream); + g_partial_body_thd_stream = NULL; + prev_acc_id_pb_thd = 0; + } + EM_DEBUG_FUNC_END(); +} + +/* h.gahlaut@samsung.com : 21-10-2010 - +em_core_reset_stream() function is used to reset globally stored partial body thread and receiving thread streams +on account deletion and pdp deactivation */ + +EXPORT_API +void em_core_reset_streams() +{ + EM_DEBUG_FUNC_BEGIN(); + + em_core_close_receiving_stream(); + em_core_close_partial_body_stream(); + + EM_DEBUG_FUNC_END(); + return; +} + +#else /* __FEATURE_KEEP_CONNECTION__ */ + +EXPORT_API int em_core_mailbox_open(int account_id, char *mailbox, void **mail_stream, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id[%d], mailbox[%p], mail_stream[%p], err_code[%p]", account_id, mailbox, mail_stream, err_code); + + int ret = false; + int error = EMF_ERROR_NONE; + emf_account_t *ref_account = em_core_get_account_reference(account_id); + + if (!ref_account) { + EM_DEBUG_EXCEPTION("em_core_get_account_reference failed - account id[%d]", account_id); + error = EMF_ERROR_INVALID_ACCOUNT; + goto FINISH_OFF; + } + + ret = em_core_mailbox_open_with_account_info(ref_account, mailbox, mail_stream, &error); + +FINISH_OFF: + if (err_code) + *err_code = error; + + return ret; +} +#endif /* __FEATURE_KEEP_CONNECTION__ */ + +EXPORT_API int em_core_mailbox_close(int account_id, void *mail_stream) +{ + EM_DEBUG_FUNC_BEGIN("account_id[%d], mail_stream[%p]", account_id, mail_stream); + + if (!mail_stream) { + EM_DEBUG_EXCEPTION("Invalid parameter"); + return false; /* TODO : confirm me */ + } + +#ifdef __FEATURE_KEEP_CONNECTION__ + thread_t thread_id = THREAD_SELF(); + + if (thread_id == (thread_t)em_core_get_receiving_thd_id()) { + /* Receiving thread - Dont' Free Reuse feature enabled */ + } + else if (thread_id == (thread_t)em_core_get_partial_body_thd_id()) { + /* Partial Body Download thread - Dont' Free Reuse feature enabled */ + } + else { + /* Some other thread so free stream */ + if (g_receiving_thd_stream != mail_stream && g_partial_body_thd_stream != mail_stream) + mail_close((MAILSTREAM *)mail_stream); + } +#else + mail_close((MAILSTREAM *)mail_stream); +#endif /* __FEATURE_KEEP_CONNECTION__ */ + EM_DEBUG_FUNC_END(); + return true; +} + +EXPORT_API int em_core_mailbox_free(emf_mailbox_t **mailbox_list, int count, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("mailbox_list[%p], count[%d], err_code[%p]", mailbox_list, count, err_code); + + /* default variable */ + int ret = false; + int err = EMF_ERROR_NONE; + + if (count > 0) { + if (!mailbox_list || !*mailbox_list) { + EM_DEBUG_EXCEPTION(" mailbox_list[%p], count[%d]", mailbox_list, count); + + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + emf_mailbox_t *p = *mailbox_list; + int i; + + /* EM_DEBUG_LOG("before loop"); */ + for (i = 0; i < count; i++) { + /* EM_DEBUG_LOG("p[%d].name [%p]", i, p[i].name); */ + /* EM_DEBUG_LOG("p[%d].alias [%p]", i, p[i].alias); */ + EM_SAFE_FREE(p[i].name); + EM_SAFE_FREE(p[i].alias); + } + /* EM_DEBUG_LOG("p [%p]", p); */ + free(p); + *mailbox_list = NULL; + } + + ret = true; + +FINISH_OFF: + if (err_code) + *err_code = err; + EM_DEBUG_FUNC_END(); + return ret; +} + +EXPORT_API void +em_core_bind_mailbox_type(emf_mailbox_t *mailbox_list) +{ + EM_DEBUG_FUNC_BEGIN("mailbox_list[%p]", mailbox_list); + + int i = 0; + int bIsNotUserMailbox = false; + emf_mailbox_type_item_t *pMailboxType1 = NULL ; + + for (i = 0 ; i < MAX_MAILBOX_TYPE ; i++) { + pMailboxType1 = g_mailbox_type + i; + + if (pMailboxType1->mailbox_name) { + if (0 == strcmp(pMailboxType1->mailbox_name, mailbox_list->name)) { + mailbox_list->mailbox_type = pMailboxType1->mailbox_type; + EM_DEBUG_LOG("mailbox_list->mailbox_type[%d]", mailbox_list->mailbox_type); + bIsNotUserMailbox = true; + break; + } + } + } + + if (false == bIsNotUserMailbox) + mailbox_list->mailbox_type = EMF_MAILBOX_TYPE_USER_DEFINED; + + EM_DEBUG_FUNC_END(); +} + +EXPORT_API int em_core_send_mail_event(emf_mailbox_t *mailbox, int mail_id , int *err_code) +{ + EM_DEBUG_FUNC_BEGIN(); + + int ret = false; + int err = EMF_ERROR_NONE; + int handle; + emf_event_t event_data; + + if (!mailbox || mailbox->account_id <= 0) { + EM_DEBUG_LOG(" mailbox[%p]", mailbox); + + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + memset(&event_data, 0x00, sizeof(emf_event_t)); + + event_data.type = EMF_EVENT_SEND_MAIL; + event_data.account_id = mailbox->account_id; + event_data.event_param_data_3 = EM_SAFE_STRDUP(mailbox->name); + event_data.event_param_data_4 = mail_id; + event_data.event_param_data_1 = NULL; + + if (!em_core_insert_send_event(&event_data, &handle, &err)) { + EM_DEBUG_LOG(" em_core_insert_event failed - %d", err); + goto FINISH_OFF; + } + em_core_add_transaction_info(mail_id , handle , &err); + + ret = true; +FINISH_OFF: + if (err_code) + *err_code = err; + + return ret; +} + +EXPORT_API +int em_core_partial_body_thd_local_activity_sync(int *is_event_inserted, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN(); + int activity_count = 0; + int ret = false; + int error = EMF_ERROR_NONE; + + if (false == em_storage_get_pbd_activity_count(&activity_count, false, &error)) { + EM_DEBUG_LOG("em_storage_get_pbd_activity_count failed [%d]", error); + goto FINISH_OFF; + } + + if (activity_count > 0) { + + emf_event_partial_body_thd pbd_event; + + /* Carefully initialise the event */ + memset(&pbd_event, 0x00, sizeof(emf_event_partial_body_thd)); + + pbd_event.event_type = EMF_EVENT_LOCAL_ACTIVITY_SYNC_BULK_PBD; + pbd_event.activity_type = EMF_EVENT_LOCAL_ACTIVITY_SYNC_BULK_PBD; + + if (false == em_core_insert_partial_body_thread_event(&pbd_event, &error)) { + EM_DEBUG_LOG(" em_core_insert_partial_body_thread_event failed [%d]", error); + goto FINISH_OFF; + } + else { + /*Not checking for NULL here because is_event_inserted is never NULL. */ + *is_event_inserted = true; + } + + } + else { + *is_event_inserted = false; + } + + ret = true; + + FINISH_OFF: + + if (NULL != err_code) { + *err_code = error; + } + + return ret; +} + +EXPORT_API +int em_core_get_mailbox_by_type(int account_id, emf_mailbox_type_e mailbox_type, emf_mailbox_t *result_mailbox, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id [%d], result_mailbox [%p], err_code [%p]", account_id, result_mailbox, err_code); + int ret = false, err = EMF_ERROR_NONE; + emf_mailbox_tbl_t *mail_box_tbl_spam = NULL; + + if (result_mailbox == NULL) { + EM_DEBUG_EXCEPTION("EMF_ERROR_INVALID_PARAM"); + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + if (!em_storage_get_mailbox_by_mailbox_type(account_id, mailbox_type, &mail_box_tbl_spam, false, &err)) { + err = em_storage_get_emf_error_from_em_storage_error(err); + EM_DEBUG_LOG("em_storage_get_mailbox_by_mailbox_type failed - %d", err); + } + else { + if (mail_box_tbl_spam) { + result_mailbox->mailbox_type = mail_box_tbl_spam->mailbox_type; + result_mailbox->name = EM_SAFE_STRDUP(mail_box_tbl_spam->mailbox_name); + result_mailbox->account_id = mail_box_tbl_spam->account_id; + result_mailbox->mail_slot_size = mail_box_tbl_spam->mail_slot_size; + if (!em_storage_free_mailbox(&mail_box_tbl_spam, 1, &err)) + EM_DEBUG_EXCEPTION(" em_storage_free_mailbox Failed [%d]", err); + ret = true; + } + } + +FINISH_OFF: + if (err_code) + *err_code = err; + EM_DEBUG_FUNC_END(); + return ret; +} + +#ifdef __LOCAL_ACTIVITY__ +EXPORT_API int em_core_local_activity_sync(int account_id, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN(); + + EM_DEBUG_LOG(">> account_id [%d], err_code [%p] ", account_id, err_code); + + int *activity_id_list = NULL; + int activity_count = 0; + int err = 0; + int handle = 0; + int ret = false; + emf_event_t event_data; + + + memset(&event_data, 0x00, sizeof(emf_event_t)); + + + EM_IF_NULL_RETURN_VALUE(err_code, false); + + if (account_id <= 0) { + EM_DEBUG_EXCEPTION(" Invalid Account ID [%d] ", account_id); + return false; + } + EM_DEBUG_LOG(">>> emf_local_activity_sync 3 "); + + if (!em_storage_get_activity_id_list(account_id, &activity_id_list, &activity_count, ACTIVITY_DELETEMAIL, ACTIVITY_COPYMAIL, true, &err)) { + EM_DEBUG_LOG(">>> emf_local_activity_sync 4 "); + EM_DEBUG_EXCEPTION(" em_storage_get_activity_id_list failed [ %d] ", err); + goto FINISH_OFF; + } + EM_DEBUG_LOG(">>> emf_local_activity_sync 5 "); + + if (activity_count > 0) { + event_data.type = EMF_EVENT_LOCAL_ACTIVITY; + event_data.account_id = account_id; + if (!em_core_insert_event(&event_data, &handle, &err)) { + EM_DEBUG_LOG(" em_core_insert_event failed - %d", err); + goto FINISH_OFF; + } + + ret = true; + } + + FINISH_OFF: + + if (activity_id_list) + em_storage_free_activity_id_list(activity_id_list, &err); + + if (err_code != NULL) + *err_code = err; + + return ret; + +} + +EXPORT_API int em_core_save_local_activity_sync(int account_id, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN(); + + EM_DEBUG_LOG(">> account_id [%d], err_code [%p] ", account_id, err_code); + + emf_activity_tbl_t *local_activity = NULL; + int *activity_id_list = NULL; + int activity_count = 0; + int err = 0; + int ret = false; + int handle = 0; + emf_event_t event_data; + + memset(&event_data, 0x00, sizeof(emf_event_t)); + + EM_IF_NULL_RETURN_VALUE(err_code, false); + + if (account_id <= 0) { + EM_DEBUG_EXCEPTION(" Invalid Account ID [%d] ", account_id); + return false; + } + EM_DEBUG_LOG(">>> emf_local_activity_sync 3 "); + + if (!em_storage_get_activity_id_list(account_id, &activity_id_list, &activity_count, ACTIVITY_SAVEMAIL, ACTIVITY_DELETEMAIL_SEND, true, &err)) { + EM_DEBUG_EXCEPTION(" em_storage_get_activity_id_list [ %d] ", err); + goto FINISH_OFF; + } + + + if (activity_count > 0) { + event_data.type = EMF_EVENT_LOCAL_ACTIVITY; + event_data.account_id = account_id; + if (!em_core_insert_send_event(&event_data, &handle, &err)) { + EM_DEBUG_LOG(" em_core_insert_event failed - %d", err); + goto FINISH_OFF; + } + + ret = true; + } + + + FINISH_OFF: + + if (local_activity) + em_storage_free_local_activity(&local_activity, activity_count, NULL); + + if (activity_id_list) + em_storage_free_activity_id_list(activity_id_list, &err); + + if (err_code != NULL) + *err_code = err; + + return ret; + +} + +#endif + diff --git a/email-core/em-core-mesg.c b/email-core/em-core-mesg.c new file mode 100755 index 0000000..968b16d --- /dev/null +++ b/email-core/em-core-mesg.c @@ -0,0 +1,7057 @@ +/* +* email-service +* +* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. +* +* Contact: Kyuho Jo <kyuho.jo@samsung.com>, Sunghyun Kwon <sh0701.kwon@samsung.com> +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + + + +/****************************************************************************** + * File : em-core-mesg.c + * Desc : Mail Operation + * + * Auth : + * + * History : + * 2006.08.16 : created + *****************************************************************************/ +#undef close +#include <time.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> +#include <fcntl.h> + +#include <sys/time.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> + +#include <vconf.h> +#include <contacts-svc.h> + +#include "em-core-types.h" +#include "c-client.h" +#include "lnx_inc.h" +#include "em-core-global.h" +#include "em-core-utils.h" +#include "em-core-mesg.h" +#include "em-core-mime.h" +#include "em-core-mailbox.h" +#include "em-storage.h" +#include "em-core-mailbox-sync.h" +#include "em-core-event.h" +#include "em-core-account.h" + +#include "Msg_Convert.h" +#include "emf-dbglog.h" + +#ifdef __FEATURE_DRM__ +#include <drm-service.h> +#endif /* __FEATURE_DRM__ */ + +#define ST_SILENT (long) 0x2 /* don't return results */ +#define ST_SET (long) 0x4 /* set vs. clear */ + +static char g_new_server_uid[129]; + +bool only_body_download = false; + +int multi_part_body_size = 0; +int is_multi_part_body_download_all = 0; +int _pop3_receiving_mail_id = 0; +int _pop3_received_body_size = 0; +int _pop3_last_notified_body_size = 0; +int _pop3_total_body_size = 0; + +int _imap4_received_body_size = 0; +int _imap4_last_notified_body_size = 0; +int _imap4_total_body_size = 0; +int _imap4_download_noti_interval_value = 0; + +BODY **g_inline_list = NULL ; +int g_inline_count = 0; + +static int em_core_mail_delete_from_server(emf_account_t *account, emf_mailbox_t *mailbox, int msgno, int *err_code); +static int em_core_mail_cmd_read_mail_pop3(void *stream, int msgno, int limited_size, int *downloded_size, int *total_body_size, int *err_code); +static void em_core_mail_fill_attachment(emf_attachment_info_t *atch , emf_mail_attachment_tbl_t *attachment_tbl); + +extern long pop3_send (MAILSTREAM *stream, char *command, char *args); + + +#ifdef FEATURE_CORE_DEBUG +static char *_getType(int type) +{ + switch (type) { + case 0: return "TYPETEXT"; + case 1: return "TYPEMULTIPART"; + case 2: return "TYPEMESSAGE"; + case 3: return "TYPEAPPLICATION"; + case 4: return "TYPEAUDIO"; + case 5: return "TYPEVIDEO"; + case 6: return "TYPEMODEL"; + case 7: return "TYPEOTHER"; + } + return g_strdup_printf("%d", type); +} + +static char *_getEncoding(int encoding) +{ + switch (encoding) { + case 0: return "ENC7BIT"; + case 1: return "ENC8BIT"; + case 2: return "ENCBINARY"; + case 3: return "ENCBASE64"; + case 4: return "ENCQUOTEDPRINTABLE"; + case 5: return "ENCOTHER"; + } + return g_strdup_printf("%d", encoding); +} + +static void _print_parameter(PARAMETER *param) +{ + while (param != NULL) { + EM_DEBUG_EXCEPTION("param->attribute[%s]", param->attribute); + EM_DEBUG_EXCEPTION("param->value[%s]", param->value); + + param = param->next; + } +} + +static void _print_stringlist(STRINGLIST *stringlist) +{ + while (stringlist != NULL) { + EM_DEBUG_LOG("stringlist->text.data[%s]", stringlist->text.data); + EM_DEBUG_LOG("stringlist->text.size[%ld]", stringlist->text.size); + + stringlist = stringlist->next; + } +} + +static void _print_body(BODY *body, int recursive) +{ + EM_DEBUG_LOG(" ========================================================== "); + + if (body != NULL) { + EM_DEBUG_LOG("body->type[%s]", _getType(body->type)); + EM_DEBUG_LOG("body->encoding[%s]", _getEncoding(body->encoding)); + EM_DEBUG_LOG("body->subtype[%s]", body->subtype); + + EM_DEBUG_LOG("body->parameter[%p]", body->parameter); + + _print_parameter(body->parameter); + + EM_DEBUG_LOG("body->id[%s]", body->id); + EM_DEBUG_LOG("body->description[%s]", body->description); + + EM_DEBUG_LOG("body->disposition.type[%s]", body->disposition.type); + EM_DEBUG_LOG("body->disposition.parameter[%p]", body->disposition.parameter); + + _print_parameter(body->disposition.parameter); + + EM_DEBUG_LOG("body->language[%p]", body->language); + + _print_stringlist(body->language); + + EM_DEBUG_LOG("body->location[%s]", body->location); + + EM_DEBUG_LOG("body->mime.offset[%ld]", body->mime.offset); + EM_DEBUG_LOG("body->mime.text.data[%s]", body->mime.text.data); + EM_DEBUG_LOG("body->mime.text.size[%ld]", body->mime.text.size); + + EM_DEBUG_LOG("body->contents.offset[%ld]", body->contents.offset); + EM_DEBUG_LOG("body->contents.text.data[%p]", body->contents.text.data); + EM_DEBUG_LOG("body->contents.text.size[%ld]", body->contents.text.size); + + EM_DEBUG_LOG("body->nested.part[%p]", body->nested.part); + + EM_DEBUG_LOG("body->size.lines[%ld]", body->size.lines); + EM_DEBUG_LOG("body->size.bytes[%ld]", body->size.bytes); + + EM_DEBUG_LOG("body->md5[%s]", body->md5); + EM_DEBUG_LOG("body->sparep[%p]", body->sparep); + + if (recursive) { + PART *part = body->nested.part; + + while (part != NULL) { + _print_body(&(part->body), recursive); + part = part->next; + } + } + } + + EM_DEBUG_LOG(" ========================================================== "); +} +#endif /* FEATURE_CORE_DEBUG */ + + +static int pop3_mail_delete(MAILSTREAM *stream, int msgno, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("stream[%p], msgno[%d], err_code[%p]", stream, msgno, err_code); + + int ret = false; + int err = EMF_ERROR_NONE; + + POP3LOCAL *pop3local = NULL; + char cmd[64]; + char *p = NULL; + + if (!stream) { + EM_DEBUG_EXCEPTION("stream[%p]", stream); + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + if (!(pop3local = stream->local) || !pop3local->netstream) { + EM_DEBUG_EXCEPTION("invalid POP3 stream detected..."); + err = EMF_ERROR_UNKNOWN; + goto FINISH_OFF; + } + + memset(cmd, 0x00, sizeof(cmd)); + + SNPRINTF(cmd, sizeof(cmd), "DELE %d\015\012", msgno); + +#ifdef FEATURE_CORE_DEBUG + EM_DEBUG_LOG("[POP3] >>> %s", cmd); +#endif + + /* send command : delete specified mail */ + if (!net_sout(pop3local->netstream, cmd, (int)strlen(cmd))) { + EM_DEBUG_EXCEPTION("net_sout failed..."); + err = EMF_ERROR_CONNECTION_BROKEN; /* EMF_ERROR_UNKNOWN; */ + goto FINISH_OFF; + } + + /* receive response */ + if (!(p = net_getline(pop3local->netstream))) { + EM_DEBUG_EXCEPTION("net_getline failed..."); + err = EMF_ERROR_INVALID_RESPONSE; + goto FINISH_OFF; + } + +#ifdef FEATURE_CORE_DEBUG + EM_DEBUG_LOG("[POP3] <<< %s", p); +#endif + + if (*p == '-') { /* '-ERR' */ + err = EMF_ERROR_POP3_DELE_FAILURE; /* EMF_ERROR_MAIL_NOT_FOUND_ON_SERVER; */ + goto FINISH_OFF; + } + + if (*p != '+') { /* '+OK' ... */ + err = EMF_ERROR_INVALID_RESPONSE; + goto FINISH_OFF; + } + + ret = true; + +FINISH_OFF: + if (p) + free(p); + + if (err_code) + *err_code = err; + + return ret; +} + +#ifdef __FEATURE_BULK_DELETE_MOVE_UPDATE_REQUEST_OPTI__ + +static void em_core_mail_copyuid_ex(MAILSTREAM *stream, char *mailbox, unsigned long uidvalidity, SEARCHSET *sourceset, SEARCHSET *destset) +{ + + EM_DEBUG_FUNC_BEGIN(); + + int index = -1; + int i = 0; + int err = EMF_ERROR_NONE; + + unsigned long first_uid = 0; + unsigned long last_uid = 0; + + unsigned long *old_server_uid = NULL; + unsigned long *new_server_uid = NULL; + int count = 0; + SEARCHSET *temp = sourceset; + + char old_server_uid_char[129]; + char new_server_uid_char[129]; + + if (NULL == sourceset || NULL == destset) { + /* + sourceset will be NULL when the sequence of UIDs sent to server for mail move operation has all invalid old server uids + if sourceset is NULL then corresponding dest set will be NULL + */ + + EM_DEBUG_LOG("em_core_mail_copyuid_ex failed : Invalid Parameters--> sourceset[%p] , destset[%p]", sourceset, destset); + return; + } + + /* To get count of mails actually moved */ + + while (temp) { + if (temp->first > 0) { + first_uid = temp->first; + + count++; + + if (temp->last > 0) { + last_uid = temp->last; + + while (first_uid < last_uid) { + first_uid++; + count++; + } + } + } + + temp = temp->next; + } + + + + + EM_DEBUG_LOG("Count of mails copied [%d]", count); + old_server_uid = em_core_malloc(count * sizeof(unsigned long)); + new_server_uid = em_core_malloc(count * sizeof(unsigned long)); + + /* While loop below will collect all old server uid from sourceset into old_server_uid array */ + + while (sourceset) { + if (sourceset->first > 0) { + first_uid = sourceset->first; + + index++; + old_server_uid[index] = first_uid; + + if (sourceset->last > 0) { + last_uid = sourceset->last; + + while (first_uid < last_uid) { + first_uid++; + index++; + + old_server_uid[index] = first_uid; + } + } + } + + sourceset = sourceset->next; + } + + /* While loop below will collect all new server uid from destset into new_server_uid array */ + + index = -1; + first_uid = last_uid = 0; + + while (destset) { + if (destset->first > 0) { + first_uid = destset->first; + + index++; + new_server_uid[index] = first_uid; + + if (destset->last > 0) { + last_uid = destset->last; + + while (first_uid < last_uid) { + first_uid++; + index++; + + new_server_uid[index] = first_uid; + } + } + } + + destset = destset->next; + } + + /* For loop below updates mail_tbl and mail_read_mail_uid_tbl with new server uids*/ + + for (i = 0; i <= index; ++i) { + + memset(old_server_uid_char, 0x00, sizeof(old_server_uid_char)); + sprintf(old_server_uid_char, "%ld", old_server_uid[i]); + + EM_DEBUG_LOG("Old Server Uid Char[%s]", old_server_uid_char); + + memset(new_server_uid_char, 0x00, sizeof(new_server_uid_char)); + sprintf(new_server_uid_char, "%ld", new_server_uid[i]); + + EM_DEBUG_LOG("New Server Uid Char[%s]", new_server_uid_char); + + if (!em_storage_update_server_uid(old_server_uid_char, new_server_uid_char, &err)) { + EM_DEBUG_EXCEPTION("em_storage_update_server_uid failed...[%d]", err); + } + + if (!em_storage_update_read_mail_uid_by_server_uid(old_server_uid_char, new_server_uid_char, mailbox, &err)) { + EM_DEBUG_EXCEPTION("em_storage_update_read_mail_uid_by_server_uid failed... [%d]", err); + } + +#ifdef __FEATURE_PARTIAL_BODY_DOWNLOAD__ + + if (false == em_storage_update_pbd_activity(old_server_uid_char, new_server_uid_char, mailbox, &err)) { + EM_DEBUG_EXCEPTION("em_storage_update_pbd_activity failed... [%d]", err); + } + +#endif + } + + EM_SAFE_FREE(old_server_uid); + EM_SAFE_FREE(new_server_uid); + +} + + +EXPORT_API int em_core_mail_move_from_server_ex(int account_id, char *src_mailbox, int mail_ids[], int num, char *dest_mailbox, int *error_code) +{ + EM_DEBUG_FUNC_BEGIN(); + MAILSTREAM *stream = NULL; + int err_code = EMF_ERROR_NONE; + emf_account_t *ref_account = NULL; + int ret = false; + int i = 0; + emf_id_set_t *id_set = NULL; + int id_set_count = 0; + + emf_uid_range_set *uid_range_set = NULL; + int len_of_each_range = 0; + + emf_uid_range_set *uid_range_node = NULL; + + char **string_list = NULL; + int string_count = 0; + + if (num <= 0 || account_id <= 0 || NULL == src_mailbox || NULL == dest_mailbox || NULL == mail_ids) { + if (error_code != NULL) { + *error_code = EMF_ERROR_INVALID_PARAM; + } + EM_DEBUG_LOG("Invalid Parameters- num[%d], account_id[%d], src_mailbox[%p], dest_mailbox[%p], mail_ids[%p]", num, account_id, src_mailbox, dest_mailbox, mail_ids); + return false; + } + + ref_account = em_core_get_account_reference(account_id); + + if (NULL == ref_account) { + EM_DEBUG_EXCEPTION(" em_core_get_account_reference failed[%d]", account_id); + + *error_code = EMF_ERROR_INVALID_ACCOUNT; + goto FINISH_OFF; + } + + + if (ref_account->receiving_server_type != EMF_SERVER_TYPE_IMAP4) { + *error_code = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + + if (!em_core_mailbox_open(account_id, src_mailbox, (void **)&stream, &err_code)) { + EM_DEBUG_EXCEPTION("em_core_mailbox_open failed[%d]", err_code); + + goto FINISH_OFF; + } + + if (NULL != stream) { + mail_parameters(stream, SET_COPYUID, em_core_mail_copyuid_ex); + EM_DEBUG_LOG("calling mail_copy_full FODLER MAIL COPY "); + /* [h.gahlaut] Break the set of mail_ids into comma separated strings of given length */ + /* Length is decided on the basis of remaining keywords in the Query to be formed later on in em_storage_get_id_set_from_mail_ids */ + /* Here about 90 bytes are required for fixed keywords in the query-> SELECT local_uid, s_uid from mail_read_mail_uid_tbl where local_uid in (....) ORDER by s_uid */ + /* So length of comma separated strings which will be filled in (.....) in above query can be maximum QUERY_SIZE - 90 */ + + if (false == em_core_form_comma_separated_strings(mail_ids, num, QUERY_SIZE - 90, &string_list, &string_count, &err_code)) { + EM_DEBUG_EXCEPTION("em_core_form_comma_separated_strings failed [%d]", err_code); + goto FINISH_OFF; + } + + /* Now execute one by one each comma separated string of mail_ids */ + + for (i = 0; i < string_count; ++i) { + /* Get the set of mail_ds and corresponding server_mail_ids sorted by server mail ids in ascending order */ + + if (false == em_storage_get_id_set_from_mail_ids(string_list[i], &id_set, &id_set_count, &err_code)) { + EM_DEBUG_EXCEPTION("em_storage_get_id_set_from_mail_ids failed [%d]", err_code); + goto FINISH_OFF; + } + + /* Convert the sorted sequence of server mail ids to range sequences of given length. A range sequence will be like A : B, C, D: E, H */ + + len_of_each_range = MAX_IMAP_COMMAND_LENGTH - 40; /* 1000 is the maximum length allowed RFC 2683. 40 is left for keywords and tag. */ + + if (false == em_core_convert_to_uid_range_set(id_set, id_set_count, &uid_range_set, len_of_each_range, &err_code)) { + EM_DEBUG_EXCEPTION("em_core_convert_to_uid_range_set failed [%d]", err_code); + goto FINISH_OFF; + } + + uid_range_node = uid_range_set; + + while (uid_range_node != NULL) { + /* Remove comma from end of uid_range */ + uid_range_node->uid_range[strlen(uid_range_node->uid_range) - 1] = '\0'; + EM_DEBUG_LOG("uid_range_node->uid_range - %s", uid_range_node->uid_range); + if (!mail_copy_full(stream, uid_range_node->uid_range, dest_mailbox, CP_UID | CP_MOVE)) { + EM_DEBUG_EXCEPTION("em_core_mail_move_from_server_ex : Mail cannot be moved failed"); + EM_DEBUG_EXCEPTION("Mail MOVE failed "); + goto FINISH_OFF; + } + else if (!mail_expunge_full(stream, uid_range_node->uid_range, EX_UID)) { + EM_DEBUG_EXCEPTION("em_core_mail_move_from_server_ex : Mail cannot be expunged after move. failed!"); + EM_DEBUG_EXCEPTION("Mail Expunge after move failed "); + goto FINISH_OFF; + } + else { + EM_DEBUG_LOG("Mail MOVE SUCCESS "); + } + + uid_range_node = uid_range_node->next; + } + + em_core_free_uid_range_set(&uid_range_set); + + EM_SAFE_FREE(id_set); + + id_set_count = 0; + } + + } + else { + EM_DEBUG_EXCEPTION(">>>> STREAM DATA IS NULL >>> "); + goto FINISH_OFF; + } + + + ret = true; + +FINISH_OFF: + em_core_mailbox_close(0, stream); + stream = NULL; + +#ifdef __LOCAL_ACTIVITY__ + if (ret || ref_account->receiving_server_type != EMF_SERVER_TYPE_IMAP4) /* Delete local activity for POP3 mails and successful move operation in IMAP */ { + emf_activity_tbl_t new_activity; + for (i = 0; i<num ; i++) { + memset(&new_activity, 0x00, sizeof(emf_activity_tbl_t)); + new_activity.activity_type = ACTIVITY_MOVEMAIL; + new_activity.account_id = account_id; + new_activity.mail_id = mail_ids[i]; + new_activity.src_mbox = src_mailbox; + new_activity.dest_mbox = dest_mailbox; + + if (!em_core_activity_delete(&new_activity, &err_code)) { + EM_DEBUG_EXCEPTION(">>>>>>Local Activity ACTIVITY_MOVEMAIL [%d] ", err_code); + } + } + + } +#endif + + if (error_code != NULL) { + *error_code = err_code; + } + + return ret; +} + +#ifdef __LOCAL_ACTIVITY__ +int imap4_mail_delete_ex(emf_mailbox_t *mailbox, int mail_ids[], int num, int from_server, int *err_code) +#else +int imap4_mail_delete_ex(emf_mailbox_t *mailbox, int mail_ids[], int num, int *err_code) +#endif +{ + EM_DEBUG_FUNC_BEGIN(); + + int ret = false; + int err = EMF_ERROR_NONE; + + IMAPLOCAL *imaplocal = NULL; + char *p = NULL; + MAILSTREAM *stream = NULL; + char tag[MAX_TAG_SIZE]; + char cmd[MAX_IMAP_COMMAND_LENGTH]; + emf_id_set_t *id_set = NULL; + int id_set_count = 0; + int i = 0; + emf_uid_range_set *uid_range_set = NULL; + int len_of_each_range = 0; + emf_uid_range_set *uid_range_node = NULL; + char **string_list = NULL; + int string_count = 0; + int delete_success = false; + + if (num <= 0 || !mail_ids || !mailbox) { + EM_DEBUG_EXCEPTION(" Invalid parameter "); + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + stream = mailbox->mail_stream; + if (!stream) { + EM_DEBUG_EXCEPTION(" Stream is NULL "); + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + + } + + /* [h.gahlaut] Break the set of mail_ids into comma separated strings of given length */ + /* Length is decided on the basis of remaining keywords in the Query to be formed later on in em_storage_get_id_set_from_mail_ids */ + /* Here about 90 bytes are required for fixed keywords in the query-> SELECT local_uid, s_uid from mail_read_mail_uid_tbl where local_uid in (....) ORDER by s_uid */ + /* So length of comma separated strings which will be filled in (.....) in above query can be maximum QUERY_SIZE - 90 */ + + if (false == em_core_form_comma_separated_strings(mail_ids, num, QUERY_SIZE - 90, &string_list, &string_count, &err)) { + EM_DEBUG_EXCEPTION("em_core_form_comma_separated_strings failed [%d]", err); + goto FINISH_OFF; + } + + /* Now execute one by one each comma separated string of mail_ids */ + + for (i = 0; i < string_count; ++i) { + /* Get the set of mail_ds and corresponding server_mail_ids sorted by server mail ids in ascending order */ + + if (false == em_storage_get_id_set_from_mail_ids(string_list[i], &id_set, &id_set_count, &err)) { + EM_DEBUG_EXCEPTION("em_storage_get_id_set_from_mail_ids failed [%d]", err); + goto FINISH_OFF; + } + + /* Convert the sorted sequence of server mail ids to range sequences of given length. A range sequence will be like A : B, C, D: E, H */ + + len_of_each_range = MAX_IMAP_COMMAND_LENGTH - 40; /* 1000 is the maximum length allowed RFC 2683. 40 is left for keywords and tag. */ + + if (false == em_core_convert_to_uid_range_set(id_set, id_set_count, &uid_range_set, len_of_each_range, &err)) { + EM_DEBUG_EXCEPTION("em_core_convert_to_uid_range_set failed [%d]", err); + goto FINISH_OFF; + } + + uid_range_node = uid_range_set; + + while (uid_range_node != NULL) { + /* Remove comma from end of uid_range */ + + uid_range_node->uid_range[strlen(uid_range_node->uid_range) - 1] = '\0'; + + if (!(imaplocal = stream->local) || !imaplocal->netstream) { + EM_DEBUG_EXCEPTION("invalid IMAP4 stream detected..."); + + err = EMF_ERROR_CONNECTION_BROKEN; + goto FINISH_OFF; + } + + memset(tag, 0x00, sizeof(tag)); + memset(cmd, 0x00, sizeof(cmd)); + + SNPRINTF(tag, sizeof(tag), "%08lx", 0xffffffff & (stream->gensym++)); + SNPRINTF(cmd, sizeof(cmd), "%s UID STORE %s +FLAGS (\\Deleted)\015\012", tag, uid_range_node->uid_range); + + EM_DEBUG_LOG("[IMAP4] >>> %s", cmd); + + + /* send command : set deleted flag */ + if (!net_sout(imaplocal->netstream, cmd, (int)strlen(cmd))) { + EM_DEBUG_EXCEPTION("net_sout failed..."); + + err = EMF_ERROR_CONNECTION_BROKEN; /* EMF_ERROR_UNKNOWN */ + goto FINISH_OFF; + } + + + while (imaplocal->netstream) { + /* receive response */ + if (!(p = net_getline(imaplocal->netstream))) { + EM_DEBUG_EXCEPTION("net_getline failed..."); + + err = EMF_ERROR_INVALID_RESPONSE; /* EMF_ERROR_UNKNOWN; */ + goto FINISH_OFF; + } + + + EM_DEBUG_LOG("[IMAP4] <<< %s", p); + + /* To confirm - Commented out as FETCH response does not contain the tag - may be a problem for common stream in email-service*/ + /* Success case - delete all local activity and entry from mail_read_mail_uid_tbl + if (strstr(p, "FETCH") != NULL) { + EM_DEBUG_LOG(" FETCH Response recieved "); + delete_success = true; + EM_SAFE_FREE(p); + break; + } + */ + + + if (!strncmp(p, tag, strlen(tag))) { + if (!strncmp(p + strlen(tag) + 1, "OK", 2)) { + /*Error scenario delete all local activity and entry from mail_read_mail_uid_tbl */ + EM_DEBUG_LOG(" OK Response recieved "); + delete_success = true; + EM_SAFE_FREE(p); + break; + } + else { + /* 'NO' or 'BAD' */ + delete_success = false; + err = EMF_ERROR_IMAP4_STORE_FAILURE; /* EMF_ERROR_INVALID_RESPONSE; */ + goto FINISH_OFF; + } + } + + EM_SAFE_FREE(p); + } + + memset(tag, 0x00, sizeof(tag)); + memset(cmd, 0x00, sizeof(cmd)); + + EM_DEBUG_LOG("Calling Expunge"); + + SNPRINTF(tag, sizeof(tag), "%08lx", 0xffffffff & (stream->gensym++)); + SNPRINTF(cmd, sizeof(cmd), "%s EXPUNGE\015\012", tag); + + EM_DEBUG_LOG("[IMAP4] >>> %s", cmd); + + /* send command : EXPUNGE */ + if (!net_sout(imaplocal->netstream, cmd, (int)strlen(cmd))) { + EM_DEBUG_EXCEPTION("net_sout failed..."); + + err = EMF_ERROR_CONNECTION_BROKEN; + goto FINISH_OFF; + } + + while (imaplocal->netstream) { + /* receive response */ + if (!(p = net_getline(imaplocal->netstream))) { + EM_DEBUG_EXCEPTION("net_getline failed..."); + + err = EMF_ERROR_INVALID_RESPONSE; /* EMF_ERROR_UNKNOWN; */ + goto FINISH_OFF; + } + + EM_DEBUG_LOG("[IMAP4] <<< %s", p); + + if (!strncmp(p, tag, strlen(tag))) { + if (!strncmp(p + strlen(tag) + 1, "OK", 2)) { +#ifdef __LOCAL_ACTIVITY__ + int index = 0; + emf_mail_tbl_t **mail = NULL; + + mail = (emf_mail_tbl_t **) em_core_malloc(num * sizeof(emf_mail_tbl_t *)); + if (!mail) { + EM_DEBUG_EXCEPTION("em_core_malloc failed"); + err = EMF_ERROR_UNKNOWN; + goto FINISH_OFF; + } + + if (delete_success) { + for (index = 0 ; index < num; index++) { + if (!em_storage_get_downloaded_mail(mail_ids[index], &mail[index], false, &err)) { + EM_DEBUG_LOG("em_storage_get_uid_by_mail_id failed [%d]", err); + + if (err == EM_STORAGE_ERROR_MAIL_NOT_FOUND) { + EM_DEBUG_LOG("EMF_ERROR_MAIL_NOT_FOUND_ON_SERVER : "); + continue; + } + } + + if (mail[index]) { + /* Clear entry from mail_read_mail_uid_tbl */ + if (mail[index]->server_mail_id != NULL) { + if (!em_storage_remove_downloaded_mail(mailbox->account_id, mailbox->name, mail[index]->server_mail_id, true, &err)) { + EM_DEBUG_LOG("em_storage_remove_downloaded_mail falied [%d]", err); + } + } + + /* Delete local activity */ + emf_activity_tbl_t new_activity; + memset(&new_activity, 0x00, sizeof(emf_activity_tbl_t)); + if (from_server == EMF_DELETE_FOR_SEND_THREAD) { + new_activity.activity_type = ACTIVITY_DELETEMAIL_SEND; + EM_DEBUG_LOG("from_server == EMF_DELETE_FOR_SEND_THREAD "); + } + else { + new_activity.activity_type = ACTIVITY_DELETEMAIL; + } + + new_activity.mail_id = mail[index]->mail_id; + new_activity.server_mailid = NULL; + new_activity.src_mbox = NULL; + new_activity.dest_mbox = NULL; + + if (!em_core_activity_delete(&new_activity, &err)) { + EM_DEBUG_EXCEPTION(" em_core_activity_delete failed - %d ", err); + } + } + else { + /* Fix for crash seen while deleting Outbox mails which are moved to Trash. Outbox mails do not have server mail id and are not updated in mail_read_mail_uid_tbl. + * So there is no need of deleting entry in mail_read_mail_uid_tbl. However local activity has to be deleted. + */ + /* Delete local activity */ + emf_activity_tbl_t new_activity; + memset(&new_activity, 0x00, sizeof(emf_activity_tbl_t)); + new_activity.activity_type = ACTIVITY_DELETEMAIL; + new_activity.mail_id = mail_ids[index]; /* valid mail id passed for outbox mails*/ + new_activity.server_mailid = NULL; + new_activity.src_mbox = NULL; + new_activity.dest_mbox = NULL; + + if (!em_core_activity_delete(&new_activity, &err)) { + EM_DEBUG_EXCEPTION(" em_core_activity_delete failed - %d ", err); + } + } + } + + for (index = 0; index < num; index++) { + if (!em_storage_free_mail(&mail[index], 1, &err)) { + EM_DEBUG_EXCEPTION(" em_storage_free_mail [%d]", err); + } + } + + EM_SAFE_FREE(mail); + } + +#endif + EM_SAFE_FREE(p); + break; + } + else { /* 'NO' or 'BAD' */ + err = EMF_ERROR_IMAP4_EXPUNGE_FAILURE; /* EMF_ERROR_INVALID_RESPONSE; */ + goto FINISH_OFF; + } + } + + EM_SAFE_FREE(p); + } + uid_range_node = uid_range_node->next; + } + + em_core_free_uid_range_set(&uid_range_set); + + EM_SAFE_FREE(id_set); + + id_set_count = 0; + } + + ret = true; + +FINISH_OFF: + EM_SAFE_FREE(p); + + em_core_free_comma_separated_strings(&string_list, &string_count); + + if (false == ret) { + em_core_free_uid_range_set(&uid_range_set); + } + + if (err_code) { + *err_code = err; + } + + return ret; + +} + +#endif + +static int imap4_mail_delete(MAILSTREAM *stream, int msgno, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("stream[%p], msgno[%d], err_code[%p]", stream, msgno, err_code); + + int ret = false; + int err = EMF_ERROR_NONE; + + IMAPLOCAL *imaplocal = NULL; + char tag[16], cmd[64]; + char *p = NULL; + + if (!(imaplocal = stream->local) || !imaplocal->netstream) { + EM_DEBUG_EXCEPTION("invalid IMAP4 stream detected..."); + + err = EMF_ERROR_INVALID_PARAM; /* EMF_ERROR_UNKNOWN */ + goto FINISH_OFF; + } + + memset(tag, 0x00, sizeof(tag)); + memset(cmd, 0x00, sizeof(cmd)); + + SNPRINTF(tag, sizeof(tag), "%08lx", 0xffffffff & (stream->gensym++)); + SNPRINTF(cmd, sizeof(cmd), "%s STORE %d +FLAGS.SILENT (\\Deleted)\015\012", tag, msgno); + +#ifdef FEATURE_CORE_DEBUG + EM_DEBUG_LOG("[IMAP4] >>> %s", cmd); +#endif + + /* send command : set deleted flag */ + if (!net_sout(imaplocal->netstream, cmd, (int)strlen(cmd))) { + EM_DEBUG_EXCEPTION("net_sout failed..."); + + err = EMF_ERROR_CONNECTION_BROKEN; /* EMF_ERROR_UNKNOWN */ + goto FINISH_OFF; + } + + while (imaplocal->netstream) { + /* receive response */ + if (!(p = net_getline(imaplocal->netstream))) { + EM_DEBUG_EXCEPTION("net_getline failed..."); + + err = EMF_ERROR_INVALID_RESPONSE; /* EMF_ERROR_UNKNOWN; */ + goto FINISH_OFF; + } + +#ifdef FEATURE_CORE_DEBUG + EM_DEBUG_LOG("[IMAP4] <<< %s", p); +#endif + if (!strncmp(p, tag, strlen(tag))) { + if (!strncmp(p + strlen(tag) + 1, "OK", 2)) { + EM_SAFE_FREE(p); + break; + } + else { /* 'NO' or 'BAD' */ + err = EMF_ERROR_IMAP4_STORE_FAILURE; /* EMF_ERROR_INVALID_RESPONSE; */ + goto FINISH_OFF; + } + } + + EM_SAFE_FREE(p); + } + + memset(tag, 0x00, sizeof(tag)); + memset(cmd, 0x00, sizeof(cmd)); + + SNPRINTF(tag, sizeof(tag), "%08lx", 0xffffffff & (stream->gensym++)); + SNPRINTF(cmd, sizeof(cmd), "%s EXPUNGE\015\012", tag); + +#ifdef FEATURE_CORE_DEBUG + EM_DEBUG_LOG("[IMAP4] >>> %s", cmd); +#endif + + /* send command : delete flaged mail */ + if (!net_sout(imaplocal->netstream, cmd, (int)strlen(cmd))) { + EM_DEBUG_EXCEPTION("net_sout failed..."); + + err = EMF_ERROR_CONNECTION_BROKEN; + goto FINISH_OFF; + } + + while (imaplocal->netstream) { + /* receive response */ + if (!(p = net_getline(imaplocal->netstream))) { + EM_DEBUG_EXCEPTION("net_getline failed..."); + + err = EMF_ERROR_INVALID_RESPONSE; /* EMF_ERROR_UNKNOWN; */ + goto FINISH_OFF; + } + +#ifdef FEATURE_CORE_DEBUG + EM_DEBUG_LOG("[IMAP4] <<< %s", p); +#endif + + if (!strncmp(p, tag, strlen(tag))) { + if (!strncmp(p + strlen(tag) + 1, "OK", 2)) { + EM_SAFE_FREE(p); + break; + } + else { /* 'NO' or 'BAD' */ + err = EMF_ERROR_IMAP4_EXPUNGE_FAILURE; /* EMF_ERROR_INVALID_RESPONSE; */ + goto FINISH_OFF; + } + } + + EM_SAFE_FREE(p); + } + + ret = true; + +FINISH_OFF: + EM_SAFE_FREE(p); + + if (err_code) + *err_code = err; + + return ret; +} + +typedef enum { + IMAP4_CMD_EXPUNGE +} imap4_cmd_t; + +static int imap4_send_command(MAILSTREAM *stream, imap4_cmd_t cmd_type, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("stream[%p], cmd_type[%d], err_code[%p]", stream, cmd_type, err_code); + + int ret = false; + int err = EMF_ERROR_NONE; + + IMAPLOCAL *imaplocal = NULL; + char tag[16], cmd[64]; + char *p = NULL; + + if (!(imaplocal = stream->local) || !imaplocal->netstream) { + EM_DEBUG_EXCEPTION("invalid IMAP4 stream detected..."); + + err = EMF_ERROR_INVALID_PARAM; /* EMF_ERROR_UNKNOWN */ + goto FINISH_OFF; + } + + memset(tag, 0x00, sizeof(tag)); + memset(cmd, 0x00, sizeof(cmd)); + + SNPRINTF(tag, sizeof(tag), "%08lx", 0xffffffff & (stream->gensym++)); + SNPRINTF(cmd, sizeof(cmd), "%s EXPUNGE\015\012", tag); + +#ifdef FEATURE_CORE_DEBUG + EM_DEBUG_LOG("[IMAP4] >>> %s", cmd); +#endif + + /* send command : delete flaged mail */ + if (!net_sout(imaplocal->netstream, cmd, (int)strlen(cmd))) { + EM_DEBUG_EXCEPTION("net_sout failed..."); + + err = EMF_ERROR_CONNECTION_BROKEN; + goto FINISH_OFF; + } + + while (imaplocal->netstream) { + /* receive response */ + if (!(p = net_getline(imaplocal->netstream))) { + EM_DEBUG_EXCEPTION("net_getline failed..."); + + err = EMF_ERROR_INVALID_RESPONSE; /* EMF_ERROR_UNKNOWN; */ + goto FINISH_OFF; + } + +#ifdef FEATURE_CORE_DEBUG + EM_DEBUG_LOG("[IMAP4] <<< %s", p); +#endif + + if (!strncmp(p, tag, strlen(tag))) { + if (!strncmp(p + strlen(tag) + 1, "OK", 2)) { + EM_SAFE_FREE(p); + break; + } + else { /* 'NO' or 'BAD' */ + err = EMF_ERROR_IMAP4_EXPUNGE_FAILURE; /* EMF_ERROR_INVALID_RESPONSE; */ + goto FINISH_OFF; + } + } + + EM_SAFE_FREE(p); + } + + ret = true; + +FINISH_OFF: + EM_SAFE_FREE(p); + + if (err_code) + *err_code = err; + + return ret; +} + + + +/* description + * get mail header from local mailbox + * arguments + * mailbox : message no + * header : buffer to hold header information + * return + * succeed : 1 + * fail : 0 + */ +int em_core_mail_get_header(/*emf_mailbox_t *mailbox, */ int mail_id, emf_mail_head_t **header, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("mail_id[%d], header[%p], err_code[%p]", mail_id, header, err_code); + + if (!mail_id || !header) { + EM_DEBUG_EXCEPTION("mail_id[%d], header[%p]", mail_id, header); + if (err_code != NULL) + *err_code = EMF_ERROR_INVALID_PARAM; + return false; + } + + int ret = false; + int err = EMF_ERROR_NONE; + + emf_mail_head_t *p = NULL; + emf_mail_tbl_t *mail = NULL; + + *header = NULL; + + /* get mail from mail table */ + if (!em_storage_get_mail_by_id(mail_id, &mail, true, &err) || !mail) { + EM_DEBUG_EXCEPTION("em_storage_get_mail_by_id failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + + if (!em_core_mail_get_header_from_mail_tbl(&p, mail, &err)) { + EM_DEBUG_EXCEPTION("em_core_mail_get_header_from_mail_tbl failed [%d]", err); + goto FINISH_OFF; + } + + *header = p; + + ret = true; + +FINISH_OFF: + if (ret == false && p != NULL) + em_core_mail_head_free(&p, 1, NULL); + + if (mail != NULL) + em_storage_free_mail(&mail, 1, NULL); + + if (err_code != NULL) + *err_code = err; + + return ret; +} +EXPORT_API int em_core_mail_get_header_from_mail_tbl(emf_mail_head_t **header, emf_mail_tbl_t *mail , int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("mail[%p], header[%p], err_code[%p]", mail, header, err_code); + + if (!mail || !header) { + EM_DEBUG_EXCEPTION("mail[%p], header[%p]", mail, header); + if (err_code != NULL) + *err_code = EMF_ERROR_INVALID_PARAM; + return false; + } + + int ret = false; + int err = EMF_ERROR_NONE; + + emf_mail_head_t *p = NULL; + + if (!(p = em_core_malloc(sizeof(emf_mail_head_t)))) { + EM_DEBUG_EXCEPTION("malloc failed..."); + err = EMF_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + memset(p, 0x00, sizeof(emf_mail_head_t)); + + p->subject = mail->subject; mail->subject = NULL; + p->mid = mail->message_id; mail->message_id = NULL; + p->to_contact_name = NULL; + p->from_contact_name = NULL; + p->cc_contact_name = NULL; + p->bcc_contact_name = NULL; + + EM_DEBUG_LOG("to_contact_name [%s]", p->to_contact_name); + EM_DEBUG_LOG("from_contact_name [%s]", p->from_contact_name); + + p->from = mail->full_address_from; mail->full_address_from = NULL; + p->to = mail->full_address_to; mail->full_address_to = NULL; + p->cc = mail->full_address_cc; mail->full_address_cc = NULL; + p->bcc = mail->full_address_bcc; mail->full_address_bcc = NULL; + p->reply_to = mail->full_address_reply; mail->full_address_reply = NULL; + p->return_path = mail->full_address_return; mail->full_address_return = NULL; + p->previewBodyText = mail->preview_text; mail->preview_text = NULL; + + /* mail received time */ + if (!em_convert_string_to_datetime(mail->datetime, &p->datetime, &err)) { + EM_DEBUG_EXCEPTION("em_convert_string_to_datetime failed [%d]", err); + /* goto FINISH_OFF; */ + } + ret = true; + +FINISH_OFF: + if (ret == true) + *header = p; + else if (p != NULL) + em_core_mail_head_free(&p, 1, NULL); + + if (err_code != NULL) + *err_code = err; + + return ret; +} + +int em_core_mail_get_contact_info(emf_mail_contact_info_t *contact_info, char *full_address, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("contact_info[%p], full_address[%s], err_code[%p]", contact_info, full_address, err_code); + + int ret = false; + int err = EMF_ERROR_NONE; + + if (!em_core_mail_get_contact_info_with_update(contact_info, full_address, 0, &err)) + EM_DEBUG_EXCEPTION("em_core_mail_get_contact_info_with_update failed [%d]", err); + else + ret = true; + + if (err_code != NULL) + *err_code = err; + + return ret; +} + +EXPORT_API int em_core_mail_get_display_name(CTSvalue *contact_name_value, char **contact_display_name) +{ + EM_DEBUG_FUNC_BEGIN("contact_name_value[%p], contact_display_name[%p]", contact_name_value, contact_display_name); + char *display = NULL; + const char *first = contacts_svc_value_get_str(contact_name_value, CTS_NAME_VAL_FIRST_STR); + const char *last = contacts_svc_value_get_str(contact_name_value, CTS_NAME_VAL_LAST_STR); + + EM_DEBUG_LOG(">>>>>> first[%s] last[%s]", first, last); + if (first != NULL && last != NULL) { + /* if (CTS_ORDER_NAME_FIRSTLAST == contacts_svc_get_name_order()) */ + if (CTS_ORDER_NAME_FIRSTLAST == contacts_svc_get_order(CTS_ORDER_OF_DISPLAY)) + display = g_strconcat(first, " ", last, NULL); + else + display = g_strconcat(last, " ", first, NULL); + + } + else if (first != NULL || last != NULL) { + if (first != NULL) + display = (char *)EM_SAFE_STRDUP(first); + else + display = (char *)EM_SAFE_STRDUP(last); + } + else + display = g_strdup(contacts_svc_value_get_str(contact_name_value, CTS_NAME_VAL_DISPLAY_STR)); + + if (contact_display_name != NULL) + *contact_display_name = display; + + return true; +} + +int em_core_mail_get_contact_info_with_update(emf_mail_contact_info_t *contact_info, char *full_address, int mail_id, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("contact_info[%p], full_address[%s], mail_id[%d], err_code[%p]", contact_info, full_address, mail_id, err_code); + + int ret = false; + int err = EMF_ERROR_NONE; + + ADDRESS *addr = NULL; + char *address = NULL; + char *temp_emailaddr = NULL; + int start_text_ascii = 2; + int end_text_ascii = 3; + + char *alias = NULL; + int is_searched = false; + int address_length = 0; + + if (!contact_info) { + EM_DEBUG_EXCEPTION("contact_info[%p]", contact_info); + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + if (!full_address) { + full_address = ""; + address_length = 0; + temp_emailaddr = NULL; + } + else { + address_length = 2 * strlen(full_address); + temp_emailaddr = (char *)calloc(1, address_length); + } + + em_core_skip_whitespace(full_address , &address); + EM_DEBUG_LOG("address[address][%s]", address); + + + /* ',' -> "%2C" */ + gchar **tokens = g_strsplit(address, ", ", -1); + char *p = g_strjoinv("%2C", tokens); + int i = 0; + + g_strfreev(tokens); + + /* ';' -> ',' */ + while (p && p[i] != '\0') + { + if (p[i] == ';') + p[i] = ','; + i++; + } + EM_DEBUG_LOG(" 2 converted address %s ", p); + + rfc822_parse_adrlist(&addr, p, NULL); + + EM_SAFE_FREE(p); + EM_DEBUG_LOG(" 3 full_address %s ", full_address); + + if (!addr) { + EM_DEBUG_EXCEPTION("rfc822_parse_adrlist failed..."); + + err = EMF_ERROR_INVALID_ADDRESS; + goto FINISH_OFF; + } + + CTSstruct *contact = NULL; + CTSvalue *contact_name_value = NULL; + int contact_index = -1; + char *contact_display_name = NULL; + char *contact_display_name_from_contact_info = NULL; + int contact_display_name_len = 0; + + /* char **/ + char *email_address = NULL; + int contact_name_buffer_size = address_length; + int contact_name_len = 0; + char *contact_name = (char *)calloc(1, contact_name_buffer_size); + char temp_string[1024]; + + int is_saved = 0; + + if (!contact_name) { + EM_DEBUG_EXCEPTION("Memory allocation error!"); + err = EMF_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + memset(contact_name, 0x00, contact_name_buffer_size); + + while (addr != NULL) { + if (addr->mailbox && addr->host) { + if (!strncmp(addr->mailbox , "UNEXPECTED_DATA_AFTER_ADDRESS", strlen("UNEXPECTED_DATA_AFTER_ADDRESS")) || !strncmp(addr->mailbox , "INVALID_ADDRESS", strlen("INVALID_ADDRESS")) || !strncmp(addr->host , ".SYNTAX-ERROR.", strlen(".SYNTAX-ERROR."))) + { + EM_DEBUG_LOG("Invalid address "); + addr = addr->next; + continue; + } + } + else { + EM_DEBUG_LOG("Error in parsing..! "); + addr = addr->next; + continue; + } + + EM_SAFE_FREE(email_address); + email_address = g_strdup_printf("%s@%s", addr->mailbox ? addr->mailbox : "", addr->host ? addr->host : ""); + + EM_DEBUG_LOG(" addr->personal[%s]", addr->personal); + EM_DEBUG_LOG(" email_address[%s]", email_address); + + is_searched = false; + EM_DEBUG_LOG(" >>>>> em_core_mail_get_contact_info - 10"); + + err = contacts_svc_find_contact_by(CTS_FIND_BY_EMAIL, email_address); + if (err > CTS_SUCCESS) { + contact_index = err; + if ((err = contacts_svc_get_contact(contact_index, &contact)) == CTS_SUCCESS) { + /* get contact name */ + if (contacts_svc_struct_get_value(contact, CTS_CF_NAME_VALUE, &contact_name_value) == CTS_SUCCESS) { /* set contact display name name */ + contact_info->contact_id = contact_index; /* NOTE : This is valid only if there is only one address. */ + em_core_mail_get_display_name(contact_name_value, &contact_display_name_from_contact_info); + + contact_display_name = contact_display_name_from_contact_info; + + + EM_DEBUG_LOG(">>> contact_index[%d]", contact_index); + EM_DEBUG_LOG(">>> contact_name[%s]", contact_display_name); + + /* Make display name string */ + if (contact_display_name != NULL) { + is_searched = true; + + if (mail_id == 0 || (contact_name_len == 0)) { /* save only the first address information - 09-SEP-2010 */ + contact_display_name_len = strlen(contact_display_name); + if (contact_name_len + contact_display_name_len >= contact_name_buffer_size) { /* re-alloc memory */ + char *temp = contact_name; + contact_name_buffer_size += contact_name_buffer_size; + contact_name = (char *)calloc(1, contact_name_buffer_size); + if (contact_name == NULL) { + EM_DEBUG_EXCEPTION("Memory allocation failed."); + EM_SAFE_FREE(temp); + goto FINISH_OFF; + } + snprintf(contact_name, contact_name_buffer_size, "%s", temp); + EM_SAFE_FREE(temp); + } + + /* snprintf(temp_string, sizeof(temp_string), "%c%d%c%s <%s>%c", start_text_ascii, contact_index, start_text_ascii, contact_display_name, email_address, end_text_ascii); */ + if (addr->next == NULL) { + snprintf(temp_string, sizeof(temp_string), "\"%s\" <%s>", contact_display_name, email_address); + } + else { + snprintf(temp_string, sizeof(temp_string), "\"%s\" <%s>, ", contact_display_name, email_address); + } + + contact_display_name_len = strlen(temp_string); + if (contact_name_len + contact_display_name_len >= contact_name_buffer_size) { /* re-alloc memory */ + char *temp = contact_name; + contact_name_buffer_size += contact_name_buffer_size; + contact_name = (char *)calloc(1, contact_name_buffer_size); + if (contact_name == NULL) { + EM_DEBUG_EXCEPTION("Memory allocation failed."); + EM_SAFE_FREE(temp); + err = EMF_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + snprintf(contact_name, contact_name_buffer_size, "%s", temp); + EM_SAFE_FREE(temp); + } + snprintf(contact_name + contact_name_len, contact_name_buffer_size - contact_name_len, "%s", temp_string); + contact_name_len += contact_display_name_len; + EM_DEBUG_LOG("new contact_name >>>>> %s ", contact_name); + } + } + } + else { + EM_DEBUG_LOG("contacts_svc_struct_get_value error[%d]", err); + } + } + else { + EM_DEBUG_LOG("contacts_svc_get_contact error [%d]", err); + } + } + else { + EM_DEBUG_LOG("contacts_svc_find_contact_by - Not found contact record(if err is 203) or error [%d]", err); + } + + /* if contact doesn't exist, use alias or email address as display name */ + if (addr->personal != NULL) { + /* "%2C" -> ',' */ + tokens = g_strsplit(addr->personal, "%2C", -1); + + EM_SAFE_FREE(addr->personal); + + addr->personal = g_strjoinv(", ", tokens); + + g_strfreev(tokens); + /* contact_info->contact_name = EM_SAFE_STRDUP(addr->personal); */ + alias = addr->personal; + } + else { + /* alias = addr->mailbox ? addr->mailbox : ""; */ + alias = email_address; + } + contact_info->alias = EM_SAFE_STRDUP(alias); + + if (!is_searched) { + contact_display_name = alias; + contact_info->contact_id = -1; /* NOTE : This is valid only if there is only one address. */ + contact_info->storage_type = -1; + + /* Make display name string */ + EM_DEBUG_LOG("contact_display_name : [%s]", contact_display_name); + EM_DEBUG_LOG("email_address : [%s]", email_address); + + /* if mail_id is 0, return only contact info without saving contact info to DB */ + if (mail_id == 0 || (contact_name_len == 0)) { /* save only the first address information - 09-SEP-2010 */ + /* snprintf(temp_string, sizeof(temp_string), "%c%d%c%s <%s>%c", start_text_ascii, contact_index, start_text_ascii, contact_display_name, email_address, end_text_ascii); */ + if (addr->next == NULL) { + snprintf(temp_string, sizeof(temp_string), "\"%s\" <%s>", contact_display_name, email_address); + } + else { + snprintf(temp_string, sizeof(temp_string), "\"%s\" <%s>, ", contact_display_name, email_address); + } + EM_DEBUG_LOG("temp_string[%s]", temp_string); + + contact_display_name_len = strlen(temp_string); + if (contact_name_len + contact_display_name_len >= contact_name_buffer_size) { /* re-alloc memory */ + char *temp = contact_name; + contact_name_buffer_size += contact_name_buffer_size; + contact_name = (char *)calloc(1, contact_name_buffer_size); + if (contact_name == NULL) { + EM_DEBUG_EXCEPTION("Memory allocation failed."); + EM_SAFE_FREE(temp); + err = EMF_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + snprintf(contact_name, contact_name_buffer_size, "%s", temp); + EM_SAFE_FREE(temp); + } + + snprintf(contact_name + contact_name_len, contact_name_buffer_size - contact_name_len, "%s", temp_string); + contact_name_len += contact_display_name_len; + EM_DEBUG_LOG("new contact_name >>>>> %s ", contact_name); + } + } + + if (temp_emailaddr && email_address) { + if (mail_id == 0) { /* if mail_id is 0, return only contact info without saving contact info to DB */ + /* snprintf(temp_emailaddr, 400, "%s", contact_info->email_address); */ + EM_SAFE_STRCAT(temp_emailaddr, email_address); + if (addr->next != NULL) + EM_SAFE_STRCAT(temp_emailaddr, ", "); + EM_DEBUG_LOG(">>>> TEMP EMail Address [ %s ] ", temp_emailaddr); + } + else { /* save only the first address information - 09-SEP-2010 */ + if (is_saved == 0) { + is_saved = 1; + /* snprintf(temp_emailaddr, 400, "%s", contact_info->email_address); */ + EM_SAFE_STRCAT(temp_emailaddr, email_address); + /* + if (addr->next != NULL) + EM_SAFE_STRCAT(temp_emailaddr, ", "); + */ + EM_DEBUG_LOG(">>>> TEMP EMail Address [ %s ] ", temp_emailaddr); + } + } + } + + if (contact != NULL) { + contacts_svc_struct_free(contact); + contact = NULL; + } + EM_SAFE_FREE(contact_display_name_from_contact_info); + /* next address */ + addr = addr->next; + } /* while (addr != NULL) */ + + if (temp_emailaddr) { + EM_DEBUG_LOG(">>>> TEMPEMAIL ADDR [ %s ] ", temp_emailaddr); + contact_info->email_address = temp_emailaddr; + temp_emailaddr = NULL; + } + + if (contact_name != NULL) { + contact_info->contact_name = g_strdup(contact_name); + } + else { + contact_info->contact_name = g_strdup_printf("%c%d%c%s%c", start_text_ascii, 0, start_text_ascii, full_address, end_text_ascii); + contact_info->contact_id = -1; + } + + ret = true; + +FINISH_OFF: + + if (contact != NULL) + contacts_svc_struct_free(contact); + EM_SAFE_FREE(email_address); + EM_SAFE_FREE(address); + EM_SAFE_FREE(temp_emailaddr); + EM_SAFE_FREE(contact_name); + EM_SAFE_FREE(contact_display_name_from_contact_info); + + if (err_code != NULL) + *err_code = err; + + return ret; +} + +int em_core_mail_free_contact_info(emf_mail_contact_info_t *contact_info, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("contact_info[%p], err_code[%p]", contact_info, err_code); + + int ret = false; + int err = EMF_ERROR_NONE; + + if (!contact_info) { + EM_DEBUG_EXCEPTION("contact_info[%p]", contact_info); + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + EM_SAFE_FREE(contact_info->contact_name); + EM_SAFE_FREE(contact_info->email_address); + EM_SAFE_FREE(contact_info->alias); + + contact_info->storage_type = -1; + contact_info->contact_id = -1; + + ret = true; + +FINISH_OFF: + if (err_code != NULL) + *err_code = err; + EM_DEBUG_FUNC_END(); + return ret; +} + +int em_core_mail_contact_sync(int mail_id, int *err_code) +{ + EM_PROFILE_BEGIN(emCoreMailContactSync); + EM_DEBUG_FUNC_BEGIN(); + + int ret = false; + int err = EMF_ERROR_NONE; + + emf_mail_tbl_t *mail = NULL; + + emf_mail_contact_info_t contact_info_from; + emf_mail_contact_info_t contact_info_to; + emf_mail_contact_info_t contact_info_cc; + emf_mail_contact_info_t contact_info_bcc; + + EM_DEBUG_LOG("mail_id[%d], err_code[%p]", mail_id, err_code); + + memset(&contact_info_from, 0x00, sizeof(emf_mail_contact_info_t)); + memset(&contact_info_to, 0x00, sizeof(emf_mail_contact_info_t)); + memset(&contact_info_cc, 0x00, sizeof(emf_mail_contact_info_t)); + memset(&contact_info_bcc, 0x00, sizeof(emf_mail_contact_info_t)); + + if (!em_storage_get_mail_by_id(mail_id, &mail, true, &err) || !mail) { + EM_DEBUG_EXCEPTION("em_storage_get_mail_by_id failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + + if (mail->full_address_from != NULL) { + if (!em_core_mail_get_contact_info_with_update(&contact_info_from, mail->full_address_from, mail_id, &err)) { + EM_DEBUG_EXCEPTION("em_core_mail_get_contact_info failed [%d]", err); + } + } + + if (mail->full_address_to != NULL) { + if (!em_core_mail_get_contact_info_with_update(&contact_info_to, mail->full_address_to, mail_id, &err)) { + EM_DEBUG_EXCEPTION("em_core_mail_get_contact_info failed [%d]", err); + } + } + + if (mail->full_address_cc != NULL) { + if (!em_core_mail_get_contact_info_with_update(&contact_info_cc, mail->full_address_cc, mail_id, &err)) { + EM_DEBUG_EXCEPTION("em_core_mail_get_contact_info failed [%d]", err); + } + } + + if (mail->full_address_bcc != NULL) { + if (!em_core_mail_get_contact_info_with_update(&contact_info_bcc, mail->full_address_bcc, mail_id, &err)) { + EM_DEBUG_EXCEPTION("em_core_mail_get_contact_info failed [%d]", err); + } + } + + EM_SAFE_FREE(mail->email_address_sender); + mail->email_address_sender = contact_info_from.email_address; + contact_info_from.contact_name = NULL; + contact_info_from.email_address = NULL; + EM_SAFE_FREE(mail->email_address_recipient); + if (mail->full_address_to != NULL) { + mail->email_address_recipient = contact_info_to.email_address; + contact_info_to.contact_name = NULL; + contact_info_to.email_address = NULL; + } + else if (mail->full_address_cc != NULL) { + mail->email_address_recipient = contact_info_cc.email_address; + contact_info_cc.contact_name = NULL; + contact_info_cc.email_address = NULL; + } + else if (mail->full_address_bcc != NULL) { + mail->email_address_recipient = contact_info_bcc.email_address; + contact_info_bcc.contact_name = NULL; + contact_info_bcc.email_address = NULL; + } + + /* Update DB */ + if (!em_storage_change_mail_field(mail_id, UPDATE_ALL_CONTACT_INFO, mail, false, &err)) { + EM_DEBUG_EXCEPTION("em_storage_change_mail_field failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + + ret = true; + +FINISH_OFF: + if (mail != NULL) + em_storage_free_mail(&mail, 1, NULL); + + em_core_mail_free_contact_info(&contact_info_from, NULL); + em_core_mail_free_contact_info(&contact_info_to, NULL); + em_core_mail_free_contact_info(&contact_info_cc, NULL); + em_core_mail_free_contact_info(&contact_info_bcc, NULL); + + if (err_code != NULL) + *err_code = err; + + EM_PROFILE_END(emCoreMailContactSync); + return ret; +} + +/* 1. parsing : alias and address */ +/* 2. sync with contact */ +/* 3. make glist of address info */ +static int em_core_sync_address_info(emf_address_type_t address_type, char *full_address, GList **address_info_list, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("address type[%d], address_info_list[%p], full_address[%p]", address_type, address_info_list, full_address); + + int ret = false; + int error = EMF_ERROR_NONE; + int contact_index = -1; + int is_search = false; + char *alias = NULL; + char *address = NULL; + char *contact_display_name_from_contact_info = NULL; + char email_address[MAX_EMAIL_ADDRESS_LENGTH]; + emf_address_info_t *p_address_info = NULL; + ADDRESS *addr = NULL; + CTSstruct *contact = NULL; + CTSvalue *contact_name_value = NULL; + + if (full_address == NULL || address_info_list == NULL) { + EM_DEBUG_EXCEPTION("Invalid param : full_address or address_info_list is NULL"); + error = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + /* Parsing */ + address = EM_SAFE_STRDUP(full_address); + + /* ',' -> "%2C" */ + gchar **tokens = g_strsplit(address, ", ", -1); + char *p = g_strjoinv("%2C", tokens); + int i = 0; + + g_strfreev(tokens); + + /* ';' -> ',' */ + while (p && p[i] != '\0') { + if (p[i] == ';') + p[i] = ','; + i++; + } + + rfc822_parse_adrlist(&addr, p, NULL); + + EM_SAFE_FREE(p); + + if (!addr) { + EM_DEBUG_EXCEPTION("rfc822_parse_adrlist failed..."); + error = EM_STORAGE_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + /* Get a contact name */ + while (addr != NULL) { + if (addr->mailbox && addr->host) { + if (!strcmp(addr->mailbox , "UNEXPECTED_DATA_AFTER_ADDRESS") || !strcmp(addr->mailbox , "INVALID_ADDRESS") || !strcmp(addr->host , ".SYNTAX-ERROR.")) + { + EM_DEBUG_LOG("Invalid address "); + addr = addr->next; + continue; + } + } + else { + EM_DEBUG_LOG("Error in parsing..! "); + addr = addr->next; + continue; + } + + /* set display name */ + /* 1) contact name */ + /* 2) alias (if a alias in an original mail doesn't exist, this field is set with email address */ + /* 3) email address */ + + if (!(p_address_info = (emf_address_info_t *)malloc(sizeof(emf_address_info_t)))) { + EM_DEBUG_EXCEPTION("malloc failed..."); + error = EM_STORAGE_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + memset(p_address_info, 0x00, sizeof(emf_address_info_t)); + + SNPRINTF(email_address, MAX_EMAIL_ADDRESS_LENGTH, "%s@%s", addr->mailbox ? addr->mailbox : "", addr->host ? addr->host : ""); + + EM_DEBUG_LOG("Search a contact : address[%s]", email_address); + + is_search = false; + + error = contacts_svc_find_contact_by(CTS_FIND_BY_EMAIL, email_address); + if (error > CTS_SUCCESS) { + contact_index = error; + if ((error = contacts_svc_get_contact(contact_index, &contact)) == CTS_SUCCESS) { + /* get contact name */ + if (contacts_svc_struct_get_value(contact, CTS_CF_NAME_VALUE, &contact_name_value) == CTS_SUCCESS) { /* set contact display name name */ + em_core_mail_get_display_name(contact_name_value, &contact_display_name_from_contact_info); + EM_DEBUG_LOG(">>> contact index[%d]", contact_index); + EM_DEBUG_LOG(">>> contact display name[%s]", contact_display_name_from_contact_info); + + is_search = true; + } + else + EM_DEBUG_EXCEPTION("contacts_svc_struct_get_value error[%d]", error); + } + else + EM_DEBUG_EXCEPTION("contacts_svc_get_contact error [%d]", error); + } + else + EM_DEBUG_EXCEPTION("contacts_svc_find_contact_by - Not found contact record(if err is -203) or error [%d]", error); + + if (is_search == true) { + p_address_info->contact_id = contact_index; + p_address_info->storage_type = -1; + p_address_info->display_name = contact_display_name_from_contact_info; + EM_DEBUG_LOG("display_name from contact[%s]", p_address_info->display_name); + } + else { + /* if contact doesn't exist, use alias or email address as display name */ + if (addr->personal != NULL) { + /* "%2C" -> ',' */ + tokens = g_strsplit(addr->personal, "%2C", -1); + + EM_SAFE_FREE(addr->personal); + + addr->personal = g_strjoinv(", ", tokens); + + g_strfreev(tokens); + alias = addr->personal; + } + else { + alias = NULL; + } + p_address_info->contact_id = -1; + p_address_info->storage_type = -1; + /* Use an alias or an email address as a display name */ + if (alias == NULL) + p_address_info->display_name = EM_SAFE_STRDUP(email_address); + else + p_address_info->display_name = EM_SAFE_STRDUP(alias); + + EM_DEBUG_LOG("display_name from email [%s]", p_address_info->display_name); + } + + p_address_info->address = EM_SAFE_STRDUP(email_address); + p_address_info->address_type = address_type; + + EM_DEBUG_LOG("email address[%s]", p_address_info->address); + + *address_info_list = g_list_append(*address_info_list, p_address_info); + p_address_info = NULL; + + EM_DEBUG_LOG("after append"); + + alias = NULL; + if (contact != NULL) { + contacts_svc_struct_free(contact); + contact = NULL; + } + + EM_DEBUG_LOG("next address[%p]", addr->next); + + /* next address */ + addr = addr->next; + } + + ret = true; + +FINISH_OFF: + if (contact != NULL) + contacts_svc_struct_free(contact); + + EM_SAFE_FREE(address); + + if (err_code != NULL) + *err_code = error; + EM_DEBUG_FUNC_END(); + return ret; +} + +static gint address_compare(gconstpointer a, gconstpointer b) +{ + EM_DEBUG_FUNC_BEGIN(); + emf_sender_list_t *recipients_list1 = (emf_sender_list_t *)a; + emf_sender_list_t *recipients_list2 = (emf_sender_list_t *)b; + + EM_DEBUG_FUNC_END(); + return strcmp(recipients_list1->address, recipients_list2->address); +} + +EXPORT_API GList *em_core_get_recipients_list(GList *old_recipients_list, char *full_address, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN(); + + int i = 0, err; + int contact_index = -1; + int is_search = false; + + char *address = NULL; + char email_address[MAX_EMAIL_ADDRESS_LENGTH]; + char *display_name = NULL; + char *alias = NULL; + ADDRESS *addr = NULL; + CTSstruct *contact = NULL; + CTSvalue *contact_name_value = NULL; + GList *new_recipients_list = old_recipients_list; + GList *recipients_list; + + emf_sender_list_t *temp_recipients_list = NULL; + emf_sender_list_t *old_recipients_list_t = NULL; + + if (full_address == NULL || strlen(full_address) == 0) { + EM_DEBUG_EXCEPTION("Invalid param : full_address NULL or empty"); + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + address = EM_SAFE_STRDUP(full_address); + + gchar **tokens = g_strsplit(address, ", ", -1); + char *p = g_strjoinv("%2C", tokens); + + g_strfreev(tokens); + + while (p && p[i] != '\0') { + if (p[i] == ';') + p[i] = ','; + i++; + } + + rfc822_parse_adrlist(&addr, p, NULL); + + EM_SAFE_FREE(p); + + if (!addr) { + EM_DEBUG_EXCEPTION("rfc822_parse_adrlist failed..."); + err = EM_STORAGE_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + while (addr != NULL) { + if (addr->mailbox && addr->host) { + if (!strcmp(addr->mailbox , "UNEXPECTED_DATA_AFTER_ADDRESS") || !strcmp(addr->mailbox , "INVALID_ADDRESS") || !strcmp(addr->host , ".SYNTAX-ERROR.")) { + EM_DEBUG_LOG("Invalid address "); + addr = addr->next; + continue; + } + } else { + EM_DEBUG_LOG("Error in parsing..! "); + addr = addr->next; + continue; + } + + temp_recipients_list = g_new0(emf_sender_list_t, 1); + + SNPRINTF(email_address, MAX_EMAIL_ADDRESS_LENGTH, "%s@%s", addr->mailbox ? addr->mailbox : "", addr->host ? addr->host : ""); + + EM_DEBUG_LOG("Search a contact : address[%s]", email_address); + + err = contacts_svc_find_contact_by(CTS_FIND_BY_EMAIL, email_address); + if (err > CTS_SUCCESS) { + contact_index = err; + if ((err = contacts_svc_get_contact(contact_index, &contact)) == CTS_SUCCESS) { + if (contacts_svc_struct_get_value(contact, CTS_CF_NAME_VALUE, &contact_name_value) == CTS_SUCCESS) { + em_core_mail_get_display_name(contact_name_value, &display_name); + EM_DEBUG_LOG(">>> contact index[%d]", contact_index); + EM_DEBUG_LOG(">>> contact display name[%s]", display_name); + + is_search = true; + } else { + EM_DEBUG_LOG("contacts_svc_struct_get_value error[%d]", err); + } + } else { + EM_DEBUG_LOG("contacts_svc_get_contact error [%d]", err); + } + } else { + EM_DEBUG_LOG("contacts_svc_find_contact_by - Not found contact record(if err is -203) or error [%d]", err); + } + + if (is_search) { + temp_recipients_list->display_name = display_name; + EM_DEBUG_LOG("display_name from contact[%s]", temp_recipients_list->display_name); + } else { + if (addr->personal != NULL) { + tokens = g_strsplit(addr->personal, "%2C", -1); + EM_SAFE_FREE(addr->personal); + addr->personal = g_strjoinv(", ", tokens); + g_strfreev(tokens); + alias = addr->personal; + } else { + alias = NULL; + } + + if (alias == NULL) + temp_recipients_list->display_name = EM_SAFE_STRDUP(email_address); + else + temp_recipients_list->display_name = EM_SAFE_STRDUP(alias); + + EM_DEBUG_LOG("display_name from contact[%s]", temp_recipients_list->display_name); + } + + temp_recipients_list->address = EM_SAFE_STRDUP(email_address); + EM_DEBUG_LOG("email address[%s]", temp_recipients_list->address); + + EM_SAFE_FREE(display_name); + if (contact != NULL) { + contacts_svc_struct_free(contact); + contact = NULL; + } + EM_DEBUG_LOG("next address[%p]", addr->next); + + recipients_list = g_list_first(new_recipients_list); + while (recipients_list != NULL) { + old_recipients_list_t = (emf_sender_list_t *)recipients_list->data; + if (!strcmp(old_recipients_list_t->address, temp_recipients_list->address)) { + old_recipients_list_t->total_count = old_recipients_list_t->total_count + 1; + if (temp_recipients_list != NULL) + g_free(temp_recipients_list); + + goto FINISH_OFF; + } + recipients_list = g_list_next(recipients_list); + } + + new_recipients_list = g_list_insert_sorted(new_recipients_list, temp_recipients_list, address_compare); + + temp_recipients_list = NULL; + + alias = NULL; + if (contact != NULL) { + contacts_svc_struct_free(contact); + contact = NULL; + } + addr = addr->next; + } + +FINISH_OFF: + + if (contact != NULL) + contacts_svc_struct_free(contact); + + EM_SAFE_FREE(address); + + if (err_code != NULL) + *err_code = err; + + EM_DEBUG_FUNC_END(); + return new_recipients_list; +} + +EXPORT_API int em_core_mail_get_address_info_list(int mail_id, emf_address_info_list_t **address_info_list, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("mail_id[%d], address_info_list[%p]", mail_id, address_info_list); + + int ret = false, err = EMF_ERROR_NONE; + int failed = true; + int contact_error; + + emf_mail_tbl_t *mail = NULL; + emf_address_info_list_t *p_address_info_list = NULL; + + if (mail_id <= 0 || !address_info_list) { + EM_DEBUG_EXCEPTION("mail_id[%d], address_info_list[%p]", mail_id, address_info_list); + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + /* get mail from mail table */ + if (!em_storage_get_mail_by_id(mail_id, &mail, true, &err) || !mail) { + EM_DEBUG_EXCEPTION("em_storage_get_mail_by_id failed [%d]", err); + + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + + if (!(p_address_info_list = (emf_address_info_list_t *)malloc(sizeof(emf_address_info_list_t)))) { + EM_DEBUG_EXCEPTION("malloc failed..."); + err = EMF_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + memset(p_address_info_list, 0x00, sizeof(emf_address_info_list_t)); + + if ((contact_error = contacts_svc_connect()) == CTS_SUCCESS) { + EM_DEBUG_LOG("Open Contact Service Success"); + } + else { + EM_DEBUG_EXCEPTION("contact_db_service_connect failed [%d]", contact_error); + err = EMF_ERROR_DB_FAILURE; + goto FINISH_OFF; + } + + if (em_core_sync_address_info(EMF_ADDRESS_TYPE_FROM, mail->full_address_from, &p_address_info_list->from, &err)) + failed = false; + if (em_core_sync_address_info(EMF_ADDRESS_TYPE_TO, mail->full_address_to, &p_address_info_list->to, &err)) + failed = false; + if (em_core_sync_address_info(EMF_ADDRESS_TYPE_CC, mail->full_address_cc, &p_address_info_list->cc, &err)) + failed = false; + if (em_core_sync_address_info(EMF_ADDRESS_TYPE_BCC, mail->full_address_bcc, &p_address_info_list->bcc, &err)) + failed = false; + + if ((contact_error = contacts_svc_disconnect()) == CTS_SUCCESS) + EM_DEBUG_LOG("Close Contact Service Success"); + else + EM_DEBUG_EXCEPTION("Close Contact Service Fail [%d]", contact_error); + + if (failed == false) + ret = true; + +FINISH_OFF: + if (ret == true) + *address_info_list = p_address_info_list; + else if (p_address_info_list != NULL) + em_storage_free_address_info_list(&p_address_info_list); + + if (!mail) + em_storage_free_mail(&mail, 1, NULL); + + if (err_code != NULL) + *err_code = err; + + EM_DEBUG_FUNC_END(); + return ret; +} + + + +/* description + * get mail header from local mailbox + * arguments + * mailbox : message no + * header : buffer to hold header information + * return + * succeed : 1 + * fail : 0 + */ +int em_core_mail_get_info(int mail_id, emf_mail_info_t **info, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("mail_id[%d], info[%p], err_code[%p]", mail_id, info, err_code); + + int ret = false; + int error = EMF_ERROR_NONE; + + emf_mail_info_t *temp_mail_info = NULL; + emf_mail_tbl_t *mail = NULL; + + if (!mail_id || !info) { + EM_DEBUG_EXCEPTION("mail_id[%d], info[%p]", mail_id, info); + error = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + /* get mail from mail table */ + if (!em_storage_get_mail_by_id(mail_id, &mail, true, &error) || !mail) { + EM_DEBUG_EXCEPTION("em_storage_get_mail_by_id failed [%d]", error); + error = em_storage_get_emf_error_from_em_storage_error(error); + goto FINISH_OFF; + } + + if (!em_core_mail_get_info_from_mail_tbl(&temp_mail_info, mail, &error)) { + EM_DEBUG_EXCEPTION("em_core_mail_get_info_from_mail_tbl failed [%d]", error); + goto FINISH_OFF; + } + + ret = true; + +FINISH_OFF: + if (ret == true) + *info = temp_mail_info; + else if (temp_mail_info != NULL) + em_core_mail_info_free(&temp_mail_info, 1, NULL); + + if (mail != NULL) + em_storage_free_mail(&mail, 1, NULL); + + if (err_code != NULL) + *err_code = error; + EM_DEBUG_FUNC_END(); + return ret; +} + +EXPORT_API int em_core_mail_get_info_from_mail_tbl(emf_mail_info_t **pp_mail_info, emf_mail_tbl_t *mail_tbl_data , int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("pp_mail_info[%p], mail_tbl_data[%p], err_code[%p]", pp_mail_info, mail_tbl_data, err_code); + + int ret = false; + int error = EMF_ERROR_NONE; + emf_mail_info_t *p = NULL; + + if (!pp_mail_info || !mail_tbl_data) { + EM_DEBUG_EXCEPTION("pp_mail_info[%p], mail_tbl_data[%p]", pp_mail_info, mail_tbl_data); + error = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + /* memory allocate */ + if (!(p = em_core_malloc(sizeof(emf_mail_info_t)))) { + EM_DEBUG_EXCEPTION("em_core_malloc failed..."); + error = EMF_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + p->account_id = mail_tbl_data->account_id; + p->uid = mail_tbl_data->mail_id; + p->sid = EM_SAFE_STRDUP(mail_tbl_data->server_mail_id); + + /* mail_tbl_data download status */ + if (mail_tbl_data->server_mail_status == 0 || mail_tbl_data->body_download_status == EMF_BODY_DOWNLOAD_STATUS_FULLY_DOWNLOADED) { + p->body_downloaded = EMF_BODY_DOWNLOAD_STATUS_FULLY_DOWNLOADED; + p->extra_flags.text_download_yn = EMF_BODY_DOWNLOAD_STATUS_FULLY_DOWNLOADED; + } +#ifdef __FEATURE_PARTIAL_BODY_DOWNLOAD__ + else if (mail_tbl_data->body_download_status == EMF_BODY_DOWNLOAD_STATUS_PARTIALLY_DOWNLOADED) { + p->body_downloaded = EMF_BODY_DOWNLOAD_STATUS_PARTIALLY_DOWNLOADED; + p->extra_flags.text_download_yn = EMF_BODY_DOWNLOAD_STATUS_PARTIALLY_DOWNLOADED; + } +#endif + else { + p->body_downloaded = EMF_BODY_DOWNLOAD_STATUS_NONE; + p->extra_flags.text_download_yn = EMF_BODY_DOWNLOAD_STATUS_NONE; + } + + /* mail_tbl_data rfc822.size */ + p->rfc822_size = mail_tbl_data->mail_size; + + /* mail_tbl_data flags */ + if (!em_convert_mail_tbl_to_mail_flag(mail_tbl_data, &p->flags, &error)) { + EM_DEBUG_EXCEPTION("em_convert_mail_tbl_to_mail_flag failed [%d]", error); + goto FINISH_OFF; + } + + /* mail_tbl_data extra flag */ + p->extra_flags.lock = mail_tbl_data->lock_status; + p->extra_flags.priority = mail_tbl_data->priority; + p->extra_flags.report = mail_tbl_data->report_status; + p->extra_flags.status = mail_tbl_data->save_status; + p->flags.sticky = mail_tbl_data->lock_status; + p->extra_flags.drm = mail_tbl_data->DRM_status; + p->is_meeting_request = mail_tbl_data->meeting_request_status; + ret = true; + +FINISH_OFF: + if (ret == true) + *pp_mail_info = p; + else if (p != NULL) + em_core_mail_info_free(&p, 1, NULL); + + if (err_code != NULL) + *err_code = error; + EM_DEBUG_FUNC_END(); + return ret; +} + +/* description + * get a mail body from local mailbox + * mail body contain body text and attachment list. + * arguments + * mailbox : mail box + * msgno : mail no + * mail : [out] double pointer to hold mail data. (mail info, mail header, mail body text and attachment list) + * return + * succeed : 1 + * fail : 0 + */ +EXPORT_API int em_core_mail_get_mail(int mail_id, emf_mail_t **mail, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("mail_id[%d], mail[%p], err_code[%p]", mail_id, mail, err_code); + + int ret = false; + int error = EMF_ERROR_NONE; + + emf_mail_t *p = NULL; + + if (!mail_id || !mail) { + EM_DEBUG_EXCEPTION("mail_id[%d], mail[%p]", mail_id, mail); + error = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + /* memory allocate */ + if (!(p = em_core_malloc(sizeof(emf_mail_t)))) { + EM_DEBUG_EXCEPTION("malloc falied..."); + error = EMF_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + memset(p, 0x00, sizeof(emf_mail_t)); + + /* get mail info */ + if (!em_core_mail_get_info(mail_id, &p->info, &error)) { + EM_DEBUG_EXCEPTION("em_core_mail_get_info failed [%d]", error); + goto FINISH_OFF; + } + + /* get mail header */ + if (!em_core_mail_get_header(mail_id, &p->head, &error)) { + EM_DEBUG_EXCEPTION("em_core_mail_get_header failed [%d]", error); + goto FINISH_OFF; + } + + /* if body downloaded, get mail body */ + EM_DEBUG_LOG("p->info->body_downloaded [%d]", p->info->body_downloaded); + + /* if (p->info->body_downloaded) { */ + if (!em_core_mail_get_body(mail_id, &p->body, &error)) { + EM_DEBUG_EXCEPTION("em_core_mail_get_body failed [%d]", error); + goto FINISH_OFF; + } + /* } */ + + ret = true; + +FINISH_OFF: + if (ret == true) + *mail = p; + else if (p != NULL) + em_core_mail_free(&p, 1, NULL); + + if (err_code != NULL) + *err_code = error; + EM_DEBUG_FUNC_END(); + return ret; +} + +/* description + * get a mail data + * arguments + * input_mail_id : [in] mail id + * output_mail_data : [out] double pointer to hold mail data. + * return + * succeed : EMF_ERROR_NONE + * fail : error code + */ +EXPORT_API int em_core_get_mail_data(int input_mail_id, emf_mail_data_t **output_mail_data) +{ + EM_DEBUG_FUNC_BEGIN("input_mail_id[%d], output_mail_data[%p]", input_mail_id, output_mail_data); + + int error = EMF_ERROR_NONE; + int result_mail_count = 0; + char conditional_clause_string[QUERY_SIZE] = { 0, }; + emf_mail_tbl_t *result_mail_tbl = NULL; + + if (input_mail_id == 0 || !output_mail_data) { + EM_DEBUG_EXCEPTION("EMF_ERROR_INVALID_PARAM"); + error = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + SNPRINTF(conditional_clause_string, QUERY_SIZE, "WHERE mail_id = %d", input_mail_id); + + if(!em_storage_query_mail_tbl(conditional_clause_string, true, &result_mail_tbl, &result_mail_count, &error)) { + EM_DEBUG_EXCEPTION("em_storage_query_mail_tbl falied [%d]", error); + goto FINISH_OFF; + } + + if(!em_convert_mail_tbl_to_mail_data(result_mail_tbl, 1, output_mail_data, &error)) { + EM_DEBUG_EXCEPTION("em_convert_mail_tbl_to_mail_data falied [%d]", error); + goto FINISH_OFF; + } + +FINISH_OFF: + if (result_mail_tbl) + em_storage_free_mail(&result_mail_tbl, result_mail_count, NULL); + + EM_DEBUG_FUNC_END("error [%d]", error); + return error; +} + + +/* internal function */ +void +em_core_free_body_sharep(void **p) +{ + EM_DEBUG_FUNC_BEGIN(); + EM_SAFE_FREE(*p); + EM_DEBUG_FUNC_END(); +} + +/* description + * get mail rfc822 size + * arguments + * mailbox : mailbox name + * msgno : mail sequence + * size : out body size + * return + * succeed : 1 + * fail : 0 + */ +EXPORT_API int em_core_mail_get_size(/*emf_mailbox_t *mailbox, */ int mail_id, int *mail_size, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("mail_id[%d], mail_size[%p], err_code[%p]", mail_id, mail_size, err_code); + + int ret = false; + int err = EMF_ERROR_NONE; + emf_mail_tbl_t *mail = NULL; + + if (mail_size == NULL) { + EM_DEBUG_EXCEPTION("mail_id[%d], mail_size[%p]", mail_id, mail_size); + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + /* get mail from mail table */ + if (!em_storage_get_mail_by_id(mail_id, &mail, true, &err) || !mail) { + EM_DEBUG_EXCEPTION("em_storage_get_mail failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + + *mail_size = mail->mail_size; + + ret = true; + +FINISH_OFF: + if (mail != NULL) + em_storage_free_mail(&mail, 1, NULL); + + if (err_code != NULL) + *err_code = err; + EM_DEBUG_FUNC_END(); + return ret; +} + +/** + * description + * get mail body from local mailbox. + * if no body in local mailbox, return error. + * arguments + * mailbox : server mailbox + * mail_id : mai id to be downloaded + * callback : function callback. if NULL, ignored. + * return + * succeed : 1 + * fail : 0 + */ +EXPORT_API int em_core_mail_get_body(int mail_id, emf_mail_body_t **body, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("mail_id[%d], body[%p], err_code[%p]", mail_id, body, err_code); + + int ret = false; + int err = EMF_ERROR_NONE; + int count = EMF_ATTACHMENT_MAX_COUNT; + emf_mail_body_t *p_body = NULL; + emf_mail_tbl_t *mail = NULL; + emf_mail_attachment_tbl_t *attachment_tbl_list = NULL; + + /* get mail from mail table */ + if (!em_storage_get_mail_by_id(mail_id, &mail, true, &err) || !mail) { + EM_DEBUG_EXCEPTION("em_storage_get_mail_by_id failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + + EM_DEBUG_LOG("file_path_plain [%s]", mail->file_path_plain); + + /* + if (!mail->body_download_status) { + EM_DEBUG_EXCEPTION("This mail body is not received."); + *body = NULL; + em_storage_free_mail(&mail, 1, NULL); + return true; + } + */ + + em_core_mail_get_body_from_mail_tbl(&p_body, mail, NULL); + + /* retrieve attachment info */ + if ( (err = em_storage_get_attachment_list(mail_id, true, &attachment_tbl_list, &count)) != EM_STORAGE_ERROR_NONE ){ + EM_DEBUG_EXCEPTION("em_storage_get_attachment_list failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + else if (count) { + emf_attachment_info_t **atch = &p_body->attachment; + int i; + + EM_DEBUG_LOG("attchment count %d", count); + for (i = 0; i < count; i++) { + *atch = em_core_malloc(sizeof(emf_attachment_info_t)); + if (!(*atch)) { + EM_DEBUG_EXCEPTION("malloc failed..."); + err = EMF_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + em_core_mail_fill_attachment(*atch, &attachment_tbl_list[i]); + atch = &(*atch)->next; + } + } + + p_body->attachment_num = count; + + ret = true; + +FINISH_OFF: + if (ret == true) + *body = p_body; + else if (p_body != NULL) + em_core_mail_body_free(&p_body, 1, NULL); + + if (attachment_tbl_list != NULL) + em_storage_free_attachment(&attachment_tbl_list, count, NULL); + + if (mail != NULL) + em_storage_free_mail(&mail, 1, NULL); + + if (err_code != NULL) + *err_code = err; + EM_DEBUG_FUNC_END(); + return ret; +} + +EXPORT_API int em_core_mail_get_body_from_mail_tbl(emf_mail_body_t **p_body, emf_mail_tbl_t *mail, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN(); + int ret = 0, err = EMF_ERROR_NONE; + emf_mail_body_t *temp_body = NULL; + + if (!p_body || !mail) { + EM_DEBUG_EXCEPTION("Invalid parameter"); + err = EMF_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + temp_body = em_core_malloc(sizeof(emf_mail_body_t)); + + if (!temp_body) { + EM_DEBUG_EXCEPTION("em_core_malloc failed..."); + err = EMF_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + temp_body->plain = EM_SAFE_STRDUP(mail->file_path_plain); + temp_body->html = EM_SAFE_STRDUP(mail->file_path_html); + + if (mail->file_path_plain && mail->file_path_plain[0] != NULL_CHAR) + temp_body->plain_charset = g_path_get_basename(mail->file_path_plain); + else + temp_body->plain_charset = NULL; + + EM_DEBUG_LOG("temp_body->plain_charset [%s]", temp_body->plain_charset); + + *p_body = temp_body; + + ret = 1; +FINISH_OFF: + + if (err_code) + *err_code = err; + + EM_DEBUG_FUNC_END(); + return ret; +} + +static void +em_core_mail_fill_attachment(emf_attachment_info_t *atch , emf_mail_attachment_tbl_t *attachment_tbl) +{ + EM_DEBUG_FUNC_BEGIN(); + if (!atch || !attachment_tbl) + return; + + atch->attachment_id = attachment_tbl->attachment_id; + atch->size = attachment_tbl->attachment_size; + atch->name = EM_SAFE_STRDUP(attachment_tbl->attachment_name); + atch->downloaded = attachment_tbl->file_yn ? 1 : 0; + atch->savename = EM_SAFE_STRDUP(attachment_tbl->attachment_path); + atch->drm = attachment_tbl->flag2; + atch->inline_content = attachment_tbl->flag3; + + EM_DEBUG_FUNC_END(); +} + +int em_core_check_drm(emf_mail_attachment_tbl_t *attachment) +{ + EM_DEBUG_FUNC_BEGIN(); + int ret = 0; +#ifdef __FEATURE_DRM__ + drm_dcf_info_t fileInfo; + + if (attachment == NULL) + return ret; + + if (drm_svc_is_drm_file (attachment->attachment_path)) { + if (drm_svc_get_dcf_file_info (attachment->attachment_path, &fileInfo) == DRM_RESULT_SUCCESS) { + attachment->flag2 = 0; + EM_DEBUG_LOG ("fileInfo is [%d]", fileInfo.method); + if (fileInfo.method != DRM_METHOD_UNDEFINED) { + attachment->flag2 = fileInfo.method; + ret = 1; + } + } + } + else { + EM_DEBUG_LOG("not DRM file %s", attachment->attachment_path); + attachment->flag2 = 0; + ret = 0; + } +#endif + EM_DEBUG_FUNC_END(); + return ret; +} + + +/* description + * get mail attachment from local mailbox + * arguments + * mailbox : server mailbox + * mail_id : mai id to own attachment + * attachment : the number string to be downloaded + * callback : function callback. if NULL, ignored. + * return + * succeed : 1 + * fail : 0 + */ +EXPORT_API int em_core_mail_get_attachment(int mail_id, char *attachment_id_string, emf_attachment_info_t **attachment, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("mail_id[%d], attachment_id_string[%p], attachment[%p], err_code[%p]", mail_id, attachment_id_string, attachment, err_code); + + if (attachment == NULL || attachment_id_string == NULL) { + EM_DEBUG_EXCEPTION("mail_id[%d], attachment_id_string[%p], attachment[%p]", mail_id, attachment_id_string, attachment); + if (err_code != NULL) + *err_code = EMF_ERROR_INVALID_PARAM; + return false; + } + + int ret = false; + int err = EMF_ERROR_NONE; + emf_mail_attachment_tbl_t *attachment_tbl = NULL; + int attachment_id = atoi(attachment_id_string); + + /* get attachment from attachment tbl */ + if (!em_storage_get_attachment(mail_id, attachment_id, &attachment_tbl, true, &err) || !attachment_tbl) { + EM_DEBUG_EXCEPTION("em_storage_get_attachment failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + + *attachment = em_core_malloc(sizeof(emf_attachment_info_t)); + if (!*attachment) { + EM_DEBUG_EXCEPTION("malloc failed..."); + err = EMF_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + (*attachment)->attachment_id = attachment_id; + (*attachment)->name = attachment_tbl->attachment_name; attachment_tbl->attachment_name = NULL; + (*attachment)->size = attachment_tbl->attachment_size; + (*attachment)->downloaded = attachment_tbl->file_yn; + (*attachment)->savename = attachment_tbl->attachment_path; attachment_tbl->attachment_path = NULL; + (*attachment)->drm = attachment_tbl->flag2; + (*attachment)->inline_content = attachment_tbl->flag3; + (*attachment)->next = NULL; + + ret = true; + +FINISH_OFF: + if (attachment_tbl) + em_storage_free_attachment(&attachment_tbl, 1, NULL); + + if (err_code) + *err_code = err; + + return ret; +} + +/* description + * get mail attachment + * arguments + * input_mail_id : mail id to own attachment + * output_attachment_data : result attahchment data + * output_attachment_count : result attahchment count + * return + * succeed : EMF_ERROR_NONE + * fail : error code + */ +EXPORT_API int em_core_get_attachment_data_list(int input_mail_id, emf_attachment_data_t **output_attachment_data, int *output_attachment_count) +{ + EM_DEBUG_FUNC_BEGIN("input_mail_id[%d], output_attachment_data[%p], output_attachment_count[%p]", input_mail_id, output_attachment_data, output_attachment_count); + + if (input_mail_id == 0|| output_attachment_data == NULL || output_attachment_count == NULL) { + EM_DEBUG_EXCEPTION("EMF_ERROR_INVALID_PARAM"); + return EMF_ERROR_INVALID_PARAM; + } + + int i = 0; + int err = EMF_ERROR_NONE; + int attachment_tbl_count = 0; + emf_mail_attachment_tbl_t *attachment_tbl_list = NULL; + emf_attachment_data_t *temp_attachment_data = NULL; + + /* get attachment from attachment tbl */ + if ( (err = em_storage_get_attachment_list(input_mail_id, true, &attachment_tbl_list, &attachment_tbl_count)) != EM_STORAGE_ERROR_NONE ){ + EM_DEBUG_EXCEPTION("em_storage_get_attachment_list failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + + if (attachment_tbl_count) { + EM_DEBUG_LOG("attchment count %d", attachment_tbl_count); + + *output_attachment_data = em_core_malloc(sizeof(emf_attachment_data_t) * attachment_tbl_count); + + if(*output_attachment_data == NULL) { + EM_DEBUG_EXCEPTION("em_core_malloc failed"); + err = EMF_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + for (i = 0; i < attachment_tbl_count; i++) { + temp_attachment_data = (*output_attachment_data) + i; + + temp_attachment_data->attachment_id = attachment_tbl_list[i].attachment_id; + temp_attachment_data->attachment_name = attachment_tbl_list[i].attachment_name; attachment_tbl_list[i].attachment_name = NULL; + temp_attachment_data->attachment_path = attachment_tbl_list[i].attachment_path; attachment_tbl_list[i].attachment_path = NULL; + temp_attachment_data->attachment_size = attachment_tbl_list[i].attachment_size; + temp_attachment_data->mail_id = attachment_tbl_list[i].mail_id; + temp_attachment_data->account_id = attachment_tbl_list[i].account_id; + temp_attachment_data->mailbox_name = attachment_tbl_list[i].mailbox_name; attachment_tbl_list[i].mailbox_name = NULL; + temp_attachment_data->save_status = attachment_tbl_list[i].file_yn; + temp_attachment_data->drm_status = attachment_tbl_list[i].flag2; + temp_attachment_data->inline_content_status = attachment_tbl_list[i].flag3; + } + } + +FINISH_OFF: + + *output_attachment_count = attachment_tbl_count; + + if (attachment_tbl_list) + em_storage_free_attachment(&attachment_tbl_list, attachment_tbl_count, NULL); + + return err; +} + + +EXPORT_API int em_core_mail_download_attachment(int account_id, int mail_id, char *nth, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id[%d], mail_id[%d], nth[%p], err_code[%p]", account_id, mail_id, nth, err_code); + + int attachment_no = 0; + int err = EMF_ERROR_NONE; + + if (mail_id < 1 || !nth) { + EM_DEBUG_EXCEPTION("mail_id[%d], nth[%p]", mail_id, nth); + err = EMF_ERROR_INVALID_PARAM; + + if (err_code != NULL) + *err_code = err; + + if (nth) + attachment_no = atoi(nth); + + em_storage_notify_network_event(NOTI_DOWNLOAD_ATTACH_FAIL, mail_id, 0, attachment_no, err); + return false; + } + + int ret = false; + int status = EMF_DOWNLOAD_FAIL; + MAILSTREAM *stream = NULL; + BODY *mbody = NULL; + emf_mail_tbl_t *mail = NULL; + emf_mail_attachment_tbl_t *attachment = NULL; + struct attachment_info *ai = NULL; + struct _m_content_info *cnt_info = NULL; + void *tmp_stream = NULL; + char *s_uid = NULL, *server_mbox = NULL, buf[1024]; + int msg_no = 0; + emf_mail_attachment_tbl_t *attachment_list = NULL; + int current_attachment_no = 0; + int attachment_count_to_be_downloaded = 0; /* how many attachments should be downloaded */ + int i = 0; + + if (!em_core_check_thread_status()) { + err = EMF_ERROR_CANCELLED; + goto FINISH_OFF; + } + + only_body_download = false; + + /* get mail from mail table. */ + if (!em_storage_get_mail_by_id(mail_id, &mail, true, &err) || !mail) { + EM_DEBUG_EXCEPTION("em_storage_get_mail_by_id failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + + if (!mail->server_mail_status) { + EM_DEBUG_EXCEPTION("not synchronous mail..."); + err = EMF_ERROR_INVALID_MAIL; + goto FINISH_OFF; + } + + attachment_no = atoi(nth); + if (attachment_no == 0) { /* download all attachments, nth starts from 1, not zero */ + /* get attachment list from db */ + attachment_count_to_be_downloaded = EMF_ATTACHMENT_MAX_COUNT; + if ( (err = em_storage_get_attachment_list(mail_id, true, &attachment_list, &attachment_count_to_be_downloaded)) != EM_STORAGE_ERROR_NONE ){ + EM_DEBUG_EXCEPTION("em_storage_get_attachment_list failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + } + else { /* download only nth attachment */ + attachment_count_to_be_downloaded = 1; + if (!em_storage_get_attachment_nth(mail_id, attachment_no, &attachment_list, true, &err) || !attachment_list) { + EM_DEBUG_EXCEPTION("em_storage_get_attachment_nth failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + } + + if (!em_core_check_thread_status()) { + err = EMF_ERROR_CANCELLED; + goto FINISH_OFF; + } + + account_id = mail->account_id; + s_uid = EM_SAFE_STRDUP(mail->server_mail_id); + server_mbox = EM_SAFE_STRDUP(mail->mailbox_name); + + /* open mail server. */ + if (!em_core_mailbox_open(account_id, server_mbox, (void **)&tmp_stream, &err) || !tmp_stream) { + EM_DEBUG_EXCEPTION("em_core_mailbox_open failed [%d]", err); + status = EMF_DOWNLOAD_CONNECTION_FAIL; + goto FINISH_OFF; + } + + stream = (MAILSTREAM *)tmp_stream; + + for (i = 0; i < attachment_count_to_be_downloaded; i++) { + EM_DEBUG_LOG(" >>>>>> Attachment Downloading [%d / %d] start", i + 1, attachment_count_to_be_downloaded); + + attachment = attachment_list + i; + if (attachment_no == 0) /* download all attachments, nth starts from 1, not zero */ + current_attachment_no = i + 1; /* attachment no */ + else /* download only nth attachment */ + current_attachment_no = attachment_no; /* attachment no */ + + if (!em_core_check_thread_status()) { + err = EMF_ERROR_CANCELLED; + goto FINISH_OFF; + } + + if (!(cnt_info = em_core_malloc(sizeof(struct _m_content_info)))) { + EM_DEBUG_EXCEPTION("malloc failed..."); + err = EMF_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + cnt_info->grab_type = GRAB_TYPE_ATTACHMENT; /* attachment */ + cnt_info->file_no = current_attachment_no; /* attachment no */ + +#ifdef CHANGE_HTML_BODY_TO_ATTACHMENT + /* text/html be changed to attachment, this isn't real attachment in RFC822. */ + if (html_changed) cnt_info->file_no--; +#endif + + /* set sparep(member of BODY) memory free function. */ + mail_parameters(stream, SET_FREEBODYSPAREP, em_core_free_body_sharep); + + if (!em_core_check_thread_status()) { + err = EMF_ERROR_CANCELLED; + goto FINISH_OFF; + } + + msg_no = atoi(s_uid); + + /* get body structure. */ + /* don't free mbody because mbody is freed in closing mail_stream. */ + if ((!stream) || em_core_get_body_structure(stream, msg_no, &mbody, &err) < 0) { + EM_DEBUG_EXCEPTION("em_core_get_body_structure failed [%d]", err); + goto FINISH_OFF; + } + + if (!em_core_check_thread_status()) { + err = EMF_ERROR_CANCELLED; + goto FINISH_OFF; + } + + /* set body fetch section. */ + if (em_core_set_fetch_body_section(mbody, false, NULL, &err) < 0) { + EM_DEBUG_EXCEPTION("em_core_set_fetch_body_section failed [%d]", err); + goto FINISH_OFF; + } + + /* download attachment. */ + _imap4_received_body_size = 0; + _imap4_last_notified_body_size = 0; + _imap4_total_body_size = 0; /* This will be assigned in imap_mail_write_body_to_file() */ + _imap4_download_noti_interval_value = 0; /* This will be assigned in imap_mail_write_body_to_file() */ + + EM_DEBUG_LOG("cnt_info->file_no[%d], current_attachment_no[%d]", cnt_info->file_no, current_attachment_no); + if (em_core_get_body(stream, account_id, mail_id, msg_no, mbody, cnt_info, &err) < 0) { + EM_DEBUG_EXCEPTION("em_core_get_body failed [%d]", err); + goto FINISH_OFF; + } + + if (!em_core_check_thread_status()) { + err = EMF_ERROR_CANCELLED; + goto FINISH_OFF; + } + + /* select target attachment information. */ + for (ai = cnt_info->file ; ai; ai = ai->next) { + if (ai->name) + EM_DEBUG_LOG("[in loop] %s, %d", ai->name, cnt_info->file_no); + + if (--cnt_info->file_no == 0) + break; + } + + EM_DEBUG_LOG("cnt_info->file_no = %d, ai = %p", cnt_info->file_no, ai); + + if (cnt_info->file_no == 0 && ai) { + /* rename temporary file to real file. */ + if (!em_storage_create_dir(account_id, mail_id, current_attachment_no, &err)) { + EM_DEBUG_EXCEPTION("em_storage_create_dir failed [%d]", err); + goto FINISH_OFF; + } + + if (!em_storage_get_save_name(account_id, mail_id, current_attachment_no, ai->name, buf, &err)) { + EM_DEBUG_EXCEPTION("em_storage_get_save_name failed [%d]", err); + goto FINISH_OFF; + } + + if (!em_storage_move_file(ai->save, buf, false, &err)) { + EM_DEBUG_EXCEPTION("em_storage_move_file failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + + EM_SAFE_FREE(ai->save); + + EM_DEBUG_LOG("ai->size [%d]", ai->size); + attachment->attachment_size = ai->size; + attachment->attachment_path = EM_SAFE_STRDUP(buf); + + /* update attachment information. */ + if (!em_storage_change_attachment_field(mail_id, UPDATE_SAVENAME, attachment, true, &err)) { + EM_DEBUG_EXCEPTION("em_storage_change_attachment_field failed [%d]", err); + /* delete created file. */ + remove(buf); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + +#ifdef __FEATURE_DRM__ + if (em_core_check_drm(attachment)) { /* has drm attachment ? */ + if (drm_svc_register_file(attachment->attachment_path) == DRM_RESULT_SUCCESS) + EM_DEBUG_LOG("drm_svc_register_file success"); + else + EM_DEBUG_EXCEPTION("drm_svc_register_file fail"); + mail->DRM_status = attachment->flag2; + } +#endif /* __FEATURE_DRM__ */ + } + else { + EM_DEBUG_EXCEPTION("invalid attachment sequence..."); + err = EMF_ERROR_INVALID_ATTACHMENT; + goto FINISH_OFF; + } + + if (cnt_info) { + em_core_mime_free_content_info(cnt_info); + cnt_info = NULL; + } + EM_DEBUG_LOG(" >>>>>> Attachment Downloading [%d / %d] completed", i+1, attachment_count_to_be_downloaded); + } + + if (stream) { + em_core_mailbox_close(0, stream); + stream = NULL; + } + + ret = true; + +FINISH_OFF: + if (stream) + em_core_mailbox_close(account_id, stream); + if (attachment_list) + em_storage_free_attachment(&attachment_list, attachment_count_to_be_downloaded, NULL); + if (cnt_info) + em_core_mime_free_content_info(cnt_info); + if (mail) + em_storage_free_mail(&mail, 1, NULL); + + EM_SAFE_FREE(s_uid); + EM_SAFE_FREE(server_mbox); + + if (ret == true) + em_storage_notify_network_event(NOTI_DOWNLOAD_ATTACH_FINISH, mail_id, NULL, attachment_no, 0); + else + em_storage_notify_network_event(NOTI_DOWNLOAD_ATTACH_FAIL, mail_id, NULL, attachment_no, err); + + if (err_code != NULL) + *err_code = err; + + EM_DEBUG_FUNC_END(); + return ret; +} + +#ifdef __ATTACHMENT_OPTI__ +EXPORT_API int em_core_mail_download_attachment_bulk(int account_id, int mail_id, char *nth, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id[%d], mail_id[%d], nth[%p], err_code[%p]", account_id, mail_id, nth, err_code); + + int attachment_no = 0; + int err = EMF_ERROR_NONE; /* Prevent Defect - 25093 */ + int ret = false; + int status = EMF_DOWNLOAD_FAIL; + MAILSTREAM *stream = NULL; + emf_mail_tbl_t *mail = NULL; + emf_mail_attachment_tbl_t *attachment = NULL; + void *tmp_stream = NULL; + char *s_uid = NULL, *server_mbox = NULL, buf[512]; + emf_mail_attachment_tbl_t *attachment_list = NULL; + int current_attachment_no = 0; + int attachment_count_to_be_downloaded = 0; /* how many attachments should be downloaded */ + int i = 0; + char *savefile = NULL; + int dec_len = 0; + int uid = 0; +#ifdef SUPPORT_EXTERNAL_MEMORY + int iActualSize = 0; + int is_add = 0; + char dirName[512]; + int bIs_empty = 0; + int bIs_full = 0; + int bIsAdd_to_mmc = false; + int is_on_mmc = false; + emf_file_list *pFileListMMc = NULL; + emf_file_list *pFileList = NULL; +#endif /* SUPPORT_EXTERNAL_MEMORY */ + + + memset(buf, 0x00, 512); + /* CID FIX 31230 */ + if (mail_id < 1 || !nth) { + EM_DEBUG_EXCEPTION("account_id[%d], mail_id[%d], nth[%p]", account_id, mail_id, nth); + + err = EMF_ERROR_INVALID_PARAM; + + if (err_code != NULL) + *err_code = err; + + if (nth) + attachment_no = atoi(nth); + + em_storage_notify_network_event(NOTI_DOWNLOAD_ATTACH_FAIL, mail_id, 0, attachment_no, err); /* 090525, kwangryul.baek */ + + return false; + } + + if (!em_core_check_thread_status()) { + err = EMF_ERROR_CANCELLED; + goto FINISH_OFF; + } + only_body_download = false; + + attachment_no = atoi(nth); + + if (attachment_no == 0) { + /* download all attachments, nth starts from 1, not zero */ + /* get attachment list from db */ + attachment_count_to_be_downloaded = EMF_ATTACHMENT_MAX_COUNT; + if ( (err = em_storage_get_attachment_list(mail_id, true, &attachment_list, &attachment_count_to_be_downloaded)) != EM_STORAGE_ERROR_NONE || !attachment_list){ + EM_DEBUG_EXCEPTION("em_storage_get_attachment_list failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + } + else { /* download only nth attachment */ + attachment_count_to_be_downloaded = 1; + if (!em_storage_get_attachment_nth(mail_id, attachment_no, &attachment_list, true, &err) || !attachment_list) { + EM_DEBUG_EXCEPTION("em_storage_get_attachment_nth failed [%d]", err); + + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + } + + + if (!em_core_check_thread_status()) { + err = EMF_ERROR_CANCELLED; + goto FINISH_OFF; + } + + + /* get mail from mail table. */ + if (!em_storage_get_mail_by_id(mail_id, &mail, true, &err) || !mail) { + EM_DEBUG_EXCEPTION("em_storage_get_mail_by_id failed [%d]", err); + + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + + /* if (!mail->server_mail_yn || !mail->text_download_yn) {*/ /* faizan.h@samsung.com */ + + if (!em_core_check_thread_status()) { + err = EMF_ERROR_CANCELLED; + goto FINISH_OFF; + } + + account_id = mail->account_id; + s_uid = EM_SAFE_STRDUP(mail->server_mail_id); mail->server_mail_id = NULL; + server_mbox = EM_SAFE_STRDUP(mail->mailbox); mail->server_mailbox_name = NULL; + + + + /* open mail server. */ + if (!em_core_mailbox_open(account_id, server_mbox, (void **)&tmp_stream, &err) || !tmp_stream) { + EM_DEBUG_EXCEPTION("em_core_mailbox_open failed [%d]", err); + + status = EMF_DOWNLOAD_CONNECTION_FAIL; + goto FINISH_OFF; + } + + stream = (MAILSTREAM *)tmp_stream; + + + if (!em_core_check_thread_status()) { + err = EMF_ERROR_CANCELLED; + goto FINISH_OFF; + } + + + for (i = 0; i < attachment_count_to_be_downloaded; i++) { + EM_DEBUG_LOG(" >>>>>> Attachment Downloading [%d / %d] start", i+1, attachment_count_to_be_downloaded); + + attachment = attachment_list + i; + if (attachment_no == 0) { + /* download all attachments, nth starts from 1, not zero */ + current_attachment_no = i + 1; /* attachment no */ + } + else { + /* download only nth attachment */ + current_attachment_no = attachment_no; /* attachment no */ + } + + if (!em_core_check_thread_status()) { + err = EMF_ERROR_CANCELLED; + goto FINISH_OFF; + } + + _imap4_received_body_size = 0; + _imap4_last_notified_body_size = 0; + _imap4_total_body_size = 0; /* This will be assigned in imap_mail_write_body_to_file() */ + _imap4_download_noti_interval_value = 0; /* This will be assigned in imap_mail_write_body_to_file() */ + + + EM_SAFE_FREE(savefile); + if (!em_core_get_temp_file_name(&savefile, &err)) { + EM_DEBUG_EXCEPTION("em_core_get_temp_file_name failed [%d]", err); + + if (err_code != NULL) + *err_code = err; + goto FINISH_OFF; + } + + if (s_uid) + uid = atoi(s_uid); + + EM_DEBUG_LOG("uid [%d]", uid); + + if (!imap_mail_write_body_to_file(stream, account_id, mail_id, attachment_no, savefile, uid , attachment->section, attachment->encoding, &dec_len, NULL, &err)) { + EM_DEBUG_EXCEPTION("imap_mail_write_body_to_file failed [%d]", err); + if (err_code != NULL) + *err_code = err; + goto FINISH_OFF; + } + +#ifdef SUPPORT_EXTERNAL_MEMORY + iActualSize = em_core_get_actual_mail_size (cnt_info->text.plain , cnt_info->text.html, cnt_info->file , &err); + if (!em_storage_mail_check_free_space(iActualSize, &bIs_full, &err)) { + EM_DEBUG_EXCEPTION("em_storage_mail_check_free_space failed [%d]", err); + goto FINISH_OFF; + } + + if (bIs_full) { + /* If external memory not present, return error */ + if (PS_MMC_REMOVED == em_storage_get_mmc_status()) { + err = EMF_ERROR_MAIL_MEMORY_FULL; + goto FINISH_OFF; + } + bIsAdd_to_mmc = true; + } +#endif /* SUPPORT_EXTERNAL_MEMORY */ + + if (!em_storage_create_dir(account_id, mail_id, attachment_no, &err)) { + EM_DEBUG_EXCEPTION("em_storage_create_dir failed [%d]", err); + goto FINISH_OFF; + } + + if (!em_storage_get_save_name(account_id, mail_id, attachment_no, attachment->name, buf, &err)) { + EM_DEBUG_EXCEPTION("em_storage_get_save_name failed [%d]", err); + goto FINISH_OFF; + } + + if (!em_storage_move_file(savefile, buf, false, &err)) { + EM_DEBUG_EXCEPTION("em_storage_move_file failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + + attachment->attachment = EM_SAFE_STRDUP(buf); + /* update attachment information. */ + if (!em_storage_change_attachment_field(mail_id, UPDATE_SAVENAME, attachment, true, &err)) { + EM_DEBUG_EXCEPTION("em_storage_change_attachment_field failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + +#ifdef __FEATURE_DRM__ + if (em_core_check_drm(attachment)) { + /* is drm */ + if (drm_svc_register_file(attachment->attachment) == DRM_RESULT_SUCCESS) + EM_DEBUG_LOG("drm_svc_register_file success"); + else + EM_DEBUG_EXCEPTION("drm_svc_register_file fail"); + mail->flag3 = attachment->flag2; + } +#endif /* __FEATURE_DRM__ */ + + if (!em_core_check_thread_status()) { + err = EMF_ERROR_CANCELLED; + goto FINISH_OFF; + } + + EM_DEBUG_LOG(" >>>>>> Attachment Downloading [%d / %d] completed", i+1, attachment_count_to_be_downloaded); + } + + ret = true; + + FINISH_OFF: + + EM_SAFE_FREE(savefile); + + em_core_mailbox_close(0, stream); + stream = NULL; + + if (attachment_list) + em_storage_free_attachment(&attachment_list, attachment_count_to_be_downloaded, NULL); + + if (mail) + em_storage_free_mail(&mail, 1, NULL); + + if (s_uid) + free(s_uid); + + if (server_mbox) + free(server_mbox);server_mbox = NULL; + + if (ret == true) + em_storage_notify_network_event(NOTI_DOWNLOAD_ATTACH_FINISH, mail_id, NULL, attachment_no, 0); + else if (err != EMF_ERROR_CANCELLED) + em_storage_notify_network_event(NOTI_DOWNLOAD_ATTACH_FAIL, mail_id, NULL, attachment_no, err); + + if (err_code != NULL) + *err_code = err; + + return ret; +} +#endif + + +EXPORT_API int em_core_mail_download_body_multi_sections_bulk(void *mail_stream, int account_id, int mail_id, int verbose, int with_attach, int limited_size, int event_handle , int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("mail_stream[%p], account_id[%d], mail_id[%d], verbose[%d], with_attach[%d], event_handle [ %d ] ", mail_stream, account_id, mail_id, verbose, with_attach, event_handle); + + int ret = false; + int err = EMF_ERROR_NONE; + int status = EMF_DOWNLOAD_FAIL; + int pop3_body_size = 0; + int pop3_downloaded_size = 0; + MAILSTREAM *stream = NULL; + BODY *mbody = NULL; + PARTLIST *section_list = NULL; + emf_mailbox_t mbox = { 0 }; + emf_mail_tbl_t *mail = NULL; + emf_mail_attachment_tbl_t attachment = {0, 0, NULL, }; + emf_account_t *ref_account = NULL; + struct attachment_info *ai = NULL; + struct _m_content_info *cnt_info = NULL; + void *tmp_stream = NULL; + char *s_uid = NULL, *server_mbox = NULL, buf[512]; + int msgno = 0, attachment_num = 1, local_attachment_count = 0, local_inline_content_count = 0; + int iActualSize = 0; + char html_body[MAX_PATH] = {0, }; + em_core_uid_list *uid_list = NULL; + char *mailbox_name = NULL; +#ifdef CHANGE_HTML_BODY_TO_ATTACHMENT + int html_changed = 0; +#endif + + if (mail_id < 1) { + EM_DEBUG_EXCEPTION("mail_stream[%p], account_id[%d], mail_id[%d], verbose[%d], with_attach[%d]", mail_stream, account_id, mail_id, verbose, with_attach); + err = EMF_ERROR_INVALID_PARAM; + + if (err_code != NULL) + *err_code = err; + + em_storage_notify_network_event(NOTI_DOWNLOAD_BODY_FAIL, mail_id, NULL, event_handle, err); + return false; + } + + FINISH_OFF_IF_CANCELED; + + only_body_download = true; + + if (!em_storage_get_mail_by_id(mail_id, &mail, true, &err) || !mail) { + EM_DEBUG_EXCEPTION("em_storage_get_mail_by_id failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + + if (mail->mailbox_name) + mailbox_name = EM_SAFE_STRDUP(mail->mailbox_name); + + if (1 == mail->body_download_status) { + EM_DEBUG_EXCEPTION("not synchronous mail..."); + err = EMF_ERROR_INVALID_MAIL; + goto FINISH_OFF; + } + + account_id = mail->account_id; + s_uid = mail->server_mail_id; + server_mbox = mail->server_mailbox_name; + mail->server_mail_id = NULL; + mail->server_mailbox_name = NULL; + + attachment.account_id = mail->account_id; + attachment.mail_id = mail->mail_id; + attachment.mailbox_name = mail->mailbox_name; mail->mailbox_name = NULL; + attachment.file_yn = 0; + + em_storage_free_mail(&mail, 1, NULL); + mail = NULL; + + if (!(ref_account = em_core_get_account_reference(account_id))) { + EM_DEBUG_EXCEPTION("em_core_get_account_reference failed [%d]", account_id); + err = EMF_ERROR_INVALID_ACCOUNT; + goto FINISH_OFF; + } + + FINISH_OFF_IF_CANCELED; + + /* open mail server. */ + if (!mail_stream) { + if (!em_core_mailbox_open(account_id, mailbox_name, (void **)&tmp_stream, &err) || !tmp_stream) { + EM_DEBUG_EXCEPTION("em_core_mailbox_open failed [%d]", err); + status = EMF_DOWNLOAD_CONNECTION_FAIL; + goto FINISH_OFF; + } + stream = (MAILSTREAM *)tmp_stream; + } + else + stream = (MAILSTREAM *)mail_stream; + + free(server_mbox); server_mbox = NULL; + + + FINISH_OFF_IF_CANCELED; + + if (!(cnt_info = em_core_malloc(sizeof(struct _m_content_info)))) { + EM_DEBUG_EXCEPTION("em_core_malloc failed..."); + err = EMF_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + if (ref_account->receiving_server_type == EMF_SERVER_TYPE_POP3) { /* POP3 */ + /* in POP3 case, both text and attachment are downloaded in this call. */ + cnt_info->grab_type = GRAB_TYPE_TEXT | GRAB_TYPE_ATTACHMENT; + attachment.file_yn = 1; /* all attachments should be downloaded in the case of POP3 */ + + mbox.account_id = account_id; + mbox.mail_stream = stream; + + /* download all uids from server. */ + if (!em_core_mailbox_download_uid_all(&mbox, &uid_list, NULL, NULL, 0, EM_CORE_GET_UIDS_FOR_NO_DELETE, &err)) { + EM_DEBUG_EXCEPTION("em_core_mailbox_download_uid_all failed [%d]", err); + goto FINISH_OFF; + } + + /* get mesg number to be related to last download mail from uid list file */ + if (!em_core_mailbox_get_msgno(uid_list, s_uid, &msgno, &err)) { + EM_DEBUG_EXCEPTION("em_core_mailbox_get_msgno failed [%d]", err); + err = EMF_ERROR_MAIL_NOT_FOUND_ON_SERVER; + goto FINISH_OFF; + } + + free(s_uid); s_uid = NULL; + + if (!em_core_check_thread_status()) { + err = EMF_ERROR_CANCELLED; + goto FINISH_OFF; + } + + _pop3_received_body_size = 0; + _pop3_total_body_size = 0; + _pop3_last_notified_body_size = 0; + _pop3_receiving_mail_id = mail_id; + + /* send read mail commnad. */ + if (!em_core_mail_cmd_read_mail_pop3(stream, msgno, limited_size, &pop3_downloaded_size, &pop3_body_size, &err)) + /* if (!em_core_mail_cmd_read_mail_pop3(stream, msgno, PARTIAL_BODY_SIZE_IN_BYTES, &pop3_downloaded_size, &pop3_body_size, &err)) */ { + EM_DEBUG_EXCEPTION("em_core_mail_cmd_read_mail_pop3 failed [%d]", err); + goto FINISH_OFF; + } + + _pop3_total_body_size = pop3_body_size; + + if (!em_storage_notify_network_event(NOTI_DOWNLOAD_BODY_START, mail_id, "dummy-file", _pop3_total_body_size, 0)) + EM_DEBUG_EXCEPTION(" em_storage_notify_network_event [ NOTI_DOWNLOAD_BODY_START] failed >>>> "); + else + EM_DEBUG_LOG("NOTI_DOWNLOAD_BODY_START notified (%d / %d)", 0, _pop3_total_body_size); + + FINISH_OFF_IF_CANCELED; + + /* save message into tempfile */ + /* parsing mime from stream. */ + + if (!em_core_mime_parse_mime(stream, 0, cnt_info, &err)) { + EM_DEBUG_EXCEPTION("em_core_mime_parse_mime failed [%d]", err); + goto FINISH_OFF; + } + + FINISH_OFF_IF_CANCELED; + } + else { /* in IMAP case, both text and attachment list are downloaded in this call. */ + /* if (ref_account->flag1 == 2) *//* This flag is just for downloading mailbox.(sync header), don't be used when retrieve body. */ + if (with_attach > 0) + cnt_info->grab_type = GRAB_TYPE_TEXT | GRAB_TYPE_ATTACHMENT; + else + cnt_info->grab_type = GRAB_TYPE_TEXT; + + int uid = atoi(s_uid); + + free(s_uid); s_uid = NULL; + + /* set sparep(member of BODY) memory free function */ + mail_parameters(stream, SET_FREEBODYSPAREP, em_core_free_body_sharep); + + /* get body strucutre. */ + /* don't free mbody because mbody is freed in closing mail_stream. */ + if (em_core_get_body_structure(stream, uid, &mbody, &err) < 0 || (mbody == NULL)) { + EM_DEBUG_EXCEPTION("em_core_get_body_structure failed [%d]", err); + err = EMF_ERROR_MAIL_NOT_FOUND_ON_SERVER; + goto FINISH_OFF; + } + + FINISH_OFF_IF_CANCELED; + + if (mbody->type == TYPEMULTIPART) { + EM_DEBUG_LOG(">>> check multipart body size to download : only_body_download[%d]", only_body_download); + PART *part_child = mbody->nested.part; + int counter = 0; + + char filename[MAX_PATH+1] = {0, }; + int is_attachment = 0; + while (part_child) { + BODY *body = &(part_child->body); + if (only_body_download == true) { + if (((body->id) && strlen(body->id) > 1) || (body->location)) + is_attachment = 0; + else if (body->disposition.type) { /* "attachment" or "inline" or etc... */ + PARAMETER *param = body->disposition.parameter; + + while (param) { + EM_DEBUG_LOG("param->attribute [%s], param->value [%s]", param->attribute, param->value); + + if (!strcasecmp(param->attribute, "filename")) { /* attribute is "filename" */ + strncpy(filename, param->value, MAX_PATH); + EM_DEBUG_LOG(">>>>> FILENAME [%s] ", filename); + break; + } + param = param->next; + } + + is_attachment = 1; + + if (!*filename) { /* it may be report msg */ + if (body->disposition.type[0] == 'i' || body->disposition.type[0] == 'I') + is_attachment = 0; + } + } + + if (is_attachment == 0) { + EM_DEBUG_LOG("%d : body->size.bytes[%ld]", counter+1, body->size.bytes); + multi_part_body_size = multi_part_body_size + body->size.bytes; + } + } + else { /* download all */ + EM_DEBUG_LOG("%d : body->size.bytes[%ld]", counter+1, body->size.bytes); + multi_part_body_size = multi_part_body_size + body->size.bytes; + } + part_child = part_child->next; + counter++; + } + } + + /* set body fetch section. */ + if (em_core_set_fetch_body_section(mbody, true, &iActualSize, &err) < 0) { + EM_DEBUG_EXCEPTION("em_core_set_fetch_body_section failed [%d]", err); + goto FINISH_OFF; + } + + EM_DEBUG_LOG("iActualSize [%d]", iActualSize); + multi_part_body_size = iActualSize; + + _imap4_received_body_size = 0; + _imap4_last_notified_body_size = 0; + if (multi_part_body_size > 0) { /* download multiparts */ + _imap4_total_body_size = multi_part_body_size; + _imap4_download_noti_interval_value = DOWNLOAD_NOTI_INTERVAL_PERCENT * multi_part_body_size / 100; + } + else { /* download only one body part */ + _imap4_total_body_size = 0; /* This will be assigned in imap_mail_write_body_to_file() */ + _imap4_download_noti_interval_value = 0; /* This will be assigned in imap_mail_write_body_to_file() */ + } + + /* save message into tempfile */ + /* download body text and get attachment list. */ + if (em_core_get_body_part_list_full(stream, uid, account_id, mail_id, mbody, cnt_info, &err, section_list, event_handle) < 0) { + EM_DEBUG_EXCEPTION("em_core_get_body falied [%d]", err); + goto FINISH_OFF; + } + FINISH_OFF_IF_CANCELED; + } + + + if (false == em_storage_get_mail_by_id(mail_id, &mail, true, &err)) { + EM_DEBUG_EXCEPTION(" em_storage_get_mail_by_id failed [%d]", err); + goto FINISH_OFF; + } + + if (cnt_info->text.plain) { + EM_DEBUG_LOG("cnt_info->text.plain [%s]", cnt_info->text.plain); + + if (!em_storage_create_dir(account_id, mail_id, 0, &err)) { + EM_DEBUG_EXCEPTION("em_storage_create_dir failed [%d]", err); + goto FINISH_OFF; + } + + + if (!em_storage_get_save_name(account_id, mail_id, 0, cnt_info->text.plain_charset ? cnt_info->text.plain_charset : "UTF-8", buf, &err)) { + EM_DEBUG_EXCEPTION("em_storage_get_save_name failed [%d]", err); + goto FINISH_OFF; + } + + if (!em_storage_move_file(cnt_info->text.plain, buf, false, &err)) { + EM_DEBUG_EXCEPTION("em_storage_move_file failed [%d]", err); + goto FINISH_OFF; + } + + mail->file_path_plain = EM_SAFE_STRDUP(buf); + EM_DEBUG_LOG("> mail->file_path_plain [%s]", mail->file_path_plain); + } + + if (cnt_info->text.html) { + if (!em_storage_create_dir(account_id, mail_id, 0, &err)) { + EM_DEBUG_EXCEPTION("em_storage_create_dir failed [%d]", err); + goto FINISH_OFF; + } + + if (cnt_info->text.plain_charset != NULL) { + memcpy(html_body, cnt_info->text.plain_charset, strlen(cnt_info->text.plain_charset)); + strcat(html_body, HTML_EXTENSION_STRING); + } + else { + memcpy(html_body, "UTF-8.htm", strlen("UTF-8.htm")); + } + if (!em_storage_get_save_name(account_id, mail_id, 0, html_body, buf, &err)) { + EM_DEBUG_EXCEPTION("em_storage_get_save_name failed [%d]", err); + goto FINISH_OFF; + } + + if (!em_storage_move_file(cnt_info->text.html, buf, false, &err)) { + EM_DEBUG_EXCEPTION("em_storage_move_file failed [%d]", err); + goto FINISH_OFF; + } + mail->file_path_html = EM_SAFE_STRDUP(buf); + } + + if (ref_account->receiving_server_type == EMF_SERVER_TYPE_POP3 && limited_size != NO_LIMITATION && limited_size < pop3_body_size) + mail->body_download_status = EMF_BODY_DOWNLOAD_STATUS_PARTIALLY_DOWNLOADED; + else + mail->body_download_status = EMF_BODY_DOWNLOAD_STATUS_FULLY_DOWNLOADED; + +#ifdef CHANGE_HTML_BODY_TO_ATTACHMENT + if (html_changed) mail->flag2 = 1; +#endif + + FINISH_OFF_IF_CANCELED; + + for (ai = cnt_info->file; ai; ai = ai->next, attachment_num++) { + attachment.attachment_id = attachment_num; + attachment.attachment_size = ai->size; + attachment.attachment_path = ai->save; + attachment.attachment_name = ai->name; + attachment.flag1 = ai->drm; + attachment.flag3 = ai->type == 1; + attachment.file_yn = 0; + + EM_DEBUG_LOG("attachment.attachment_id[%d]", attachment.attachment_id); + EM_DEBUG_LOG("attachment.attachment_size[%d]", attachment.attachment_size); + EM_DEBUG_LOG("attachment.attachment_path[%s]", attachment.attachment_path); + EM_DEBUG_LOG("attachment.attachment_name[%s]", attachment.attachment_name); + EM_DEBUG_LOG("attachment.flag1[%d]", attachment.flag1); + EM_DEBUG_LOG("attachment.flag3[%d]", attachment.flag3); + EM_DEBUG_LOG("ai->save [%d]", ai->save); +#ifdef __ATTACHMENT_OPTI__ + attachment.encoding = ai->encoding; + attachment.section = ai->section; +#endif + + if (ai->type == 1) + local_inline_content_count++; + local_attachment_count++; + + if (ai->save) { + /* in POP3 case, rename temporary file to real file. */ + attachment.file_yn = 1; + if (ai->type == 1) { /* it is inline content */ + if (!em_storage_create_dir(account_id, mail_id, 0, &err)) { + EM_DEBUG_EXCEPTION("em_storage_create_dir failed [%d]", err); + goto FINISH_OFF; + } + if (!em_storage_get_save_name(account_id, mail_id, 0, attachment.attachment_name, buf, &err)) { + EM_DEBUG_EXCEPTION("em_storage_get_save_name failed [%d]", err); + goto FINISH_OFF; + } + } + else { + if (!em_storage_create_dir(account_id, mail_id, attachment_num, &err)) { + EM_DEBUG_EXCEPTION("em_storage_create_dir failed [%d]", err); + goto FINISH_OFF; + } + + if (!em_storage_get_save_name(account_id, mail_id, attachment_num, attachment.attachment_name, buf, &err)) { + EM_DEBUG_EXCEPTION("em_storage_get_save_name failed [%d]", err); + goto FINISH_OFF; + } + } + + if (!em_storage_move_file(ai->save, buf, false, &err)) { + EM_DEBUG_EXCEPTION("em_storage_move_file failed [%d]", err); + + /* delete all created files. */ + if (!em_storage_get_save_name(account_id, mail_id, 0, NULL, buf, NULL)) { + EM_DEBUG_EXCEPTION("em_storage_get_save_name failed..."); + /* goto FINISH_OFF; */ + } + + if (!em_storage_delete_dir(buf, NULL)) { + EM_DEBUG_EXCEPTION("em_storage_delete_dir failed..."); + /* goto FINISH_OFF; */ + } + + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + + free(ai->save); ai->save = EM_SAFE_STRDUP(buf); + + attachment.attachment_path = ai->save; + +#ifdef __FEATURE_DRM__ + if (em_core_check_drm(&attachment)) { /* is drm */ + if (!drm_svc_register_file(attachment.attachment_path)) + EM_DEBUG_EXCEPTION("drm_svc_register_file fail"); + mail->DRM_status = attachment.flag2; + } +#endif/* __FEATURE_DRM__ */ + } + +#ifdef __FEATURE_PARTIAL_BODY_DOWNLOAD__ + /* Information : Attachment info already saved if partial body is dowloaded. */ + if (ai->type) { /* Get attachment details */ + emf_mail_attachment_tbl_t *attch_info = NULL; + + if (!em_storage_get_attachment_nth(mail_id, attachment.attachment_id, &attch_info, true, &err) || !attch_info) { + EM_DEBUG_EXCEPTION("em_storage_get_attachment_nth failed [%d]", err); + if (err == EM_STORAGE_ERROR_ATTACHMENT_NOT_FOUND) { /* save only attachment file. */ + if (!em_storage_add_attachment(&attachment, 0, false, &err)) { + EM_DEBUG_EXCEPTION("em_storage_add_attachment failed [%d]", err); + if (attch_info) + em_storage_free_attachment(&attch_info, 1, NULL); + /* delete all created files. */ + if (!em_storage_get_save_name(account_id, mail_id, 0, NULL, buf, &err)) { + EM_DEBUG_EXCEPTION("em_storage_get_save_name failed [%d]", err); + goto FINISH_OFF; + } + + if (!em_storage_delete_dir(buf, &err)) { + EM_DEBUG_EXCEPTION("em_storage_delete_dir failed [%d]", err); + goto FINISH_OFF; + } + + /* ROLLBACK TRANSACTION; */ + em_storage_rollback_transaction(NULL, NULL, NULL); + + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + } + } + else { + EM_DEBUG_LOG("Attachment info already exists...!"); + /* Update attachment size */ + EM_DEBUG_LOG("attachment_size [%d], ai->size [%d]", attch_info->attachment_size, ai->size); + attch_info->attachment_size = ai->size; + if (!em_storage_update_attachment(attch_info, true, &err)) { + EM_DEBUG_EXCEPTION("em_storage_update_attachment failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + } + + if (attch_info) + em_storage_free_attachment(&attch_info, 1, NULL); + } + +#else + + if (ai->type) { + mail->attachment_yn = 1; + /* save only attachment file. */ + if (!em_storage_add_attachment(&attachment, 0, false, &err)) { + EM_DEBUG_EXCEPTION("em_storage_add_attachment failed [%d]", err); + if (bIsAdd_to_mmc) { + if (attachment.attachment) { + } + } + else { + /* delete all created files. */ + if (!em_storage_get_save_name(account_id, mail_id, 0, NULL, buf, &err)) { + EM_DEBUG_EXCEPTION("em_storage_get_save_name failed [%d]", err); + goto FINISH_OFF; + } + + if (!em_storage_delete_dir(buf, &err)) { + EM_DEBUG_EXCEPTION("em_storage_delete_dir failed [%d]", err); + goto FINISH_OFF; + } + + /* ROLLBACK TRANSACTION; */ + em_storage_rollback_transaction(NULL, NULL, NULL); + + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + } + } +#endif /* End of #ifdef __FEATURE_PARTIAL_BODY_DOWNLOAD__ */ + + } + + EM_DEBUG_LOG("Check #1"); + + mail->attachment_count = local_attachment_count; + mail->inline_content_count = local_inline_content_count; + + EM_DEBUG_LOG("Check #2"); + + EM_DEBUG_LOG("Mailbox Name [%s]", mailbox_name); + mail->mailbox_name = EM_SAFE_STRDUP(mailbox_name); /* fix for mailboox sync fail */ + + EM_DEBUG_LOG("Check #3"); + + /* change mail's information. */ + if (!em_storage_change_mail_field(mail_id, APPEND_BODY, mail, false, &err)) { + EM_DEBUG_EXCEPTION("em_storage_change_mail_field failed [%d]", err); + em_storage_rollback_transaction(NULL, NULL, NULL); /* ROLLBACK TRANSACTION; */ + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + + EM_DEBUG_LOG("cnt_info->text.plain [%s], cnt_info->text.html [%s]", cnt_info->text.plain, cnt_info->text.html); + + /* in pop3 mail case, the mail is deleted from server after being downloaded. */ + if (ref_account->receiving_server_type == EMF_SERVER_TYPE_POP3) { +#ifdef DELETE_AFTER_DOWNLOADING + char delmsg[24]; + + SNPRINTF(delmsg, sizeof(delmsg), "%d", msg_no); + + if (!ref_account->keep_on_server) { + if (!em_core_mail_delete_from_server(&mbox, delmsg, &err)) + EM_DEBUG_EXCEPTION("em_core_mail_delete_from_server failed [%d]", err); + } +#endif + + if (!mail_stream) { + if (stream != NULL) { + em_core_mailbox_close(0, stream); + stream = NULL; + } + } + } + + FINISH_OFF_IF_CANCELED; + + ret = true; + +FINISH_OFF: + + if (g_inline_count) { + g_inline_count = 0; + EM_SAFE_FREE(g_inline_list); + } + + multi_part_body_size = 0; + _pop3_received_body_size = 0; + _pop3_last_notified_body_size = 0; + _pop3_total_body_size = 0; + _pop3_receiving_mail_id = 0; + + _imap4_received_body_size = 0; + _imap4_last_notified_body_size = 0; + _imap4_total_body_size = 0; + _imap4_download_noti_interval_value = 0; + + if (cnt_info) + em_core_mime_free_content_info(cnt_info); + if (mail) + em_storage_free_mail(&mail, 1, NULL); + if (attachment.mailbox_name) + free(attachment.mailbox_name); + if (server_mbox) + free(server_mbox); + if (s_uid) + free(s_uid); + + multi_part_body_size = 0; + + if (ret == true) + em_storage_notify_network_event(NOTI_DOWNLOAD_BODY_FINISH, mail_id, NULL, event_handle, 0); + else + em_storage_notify_network_event(NOTI_DOWNLOAD_BODY_FAIL, mail_id, NULL, event_handle, err); + + if (mailbox_name) + free (mailbox_name); + + if (err_code != NULL) + *err_code = err; + + return ret; +} + + + +void em_core_mail_copyuid(MAILSTREAM *stream, char *mailbox, + unsigned long uidvalidity, SEARCHSET *sourceset, + SEARCHSET *destset) +{ + EM_DEBUG_FUNC_BEGIN(); + char old_server_uid[129]; + + EM_DEBUG_LOG("mailbox name - %s", mailbox); + EM_DEBUG_LOG("first sequence number source- %ld", sourceset->first); + EM_DEBUG_LOG("last sequence number last- %ld", sourceset->last); + EM_DEBUG_LOG("first sequence number dest - %ld", destset->first); + EM_DEBUG_LOG("last sequence number dest- %ld", sourceset->last); + + /* search for server _mail_id with value sourceset->first and update it with destset->first */ + /* faizan.h@samsung.com */ + memset(old_server_uid, 0x00, 129); + sprintf(old_server_uid, "%ld", sourceset->first); + EM_DEBUG_LOG(">>>>> old_server_uid = %s", old_server_uid); + + memset(g_new_server_uid, 0x00, 129); + sprintf(g_new_server_uid, "%ld", destset->first); + EM_DEBUG_LOG(">>>>> new_server_uid =%s", g_new_server_uid); + + if (!em_storage_update_server_uid(old_server_uid, g_new_server_uid, NULL)) { + EM_DEBUG_EXCEPTION("em_storage_update_server_uid falied..."); + } +} + +int em_core_mail_delete(int account_id, int mail_ids[], int num, int from_server, int noti_param_1, int noti_param_2, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id[%d], mail_ids[%p], num[%d], from_server[%d], noti_param_1 [%d], noti_param_2 [%d], err_code[%p]", account_id, mail_ids, num, from_server, noti_param_1, noti_param_2, err_code); + + int ret = false; + int err = EMF_ERROR_NONE; + int status = EMF_DELETE_FAIL; + + emf_account_t *account = NULL; + emf_mailbox_t mailbox; + emf_mail_tbl_t *mail = NULL; + void *stream = NULL; + int mail_id = 0; + int i = 0; + int msgno = 0, parameter_string_length = 0; + char *parameter_string = NULL, mail_id_string[10]; + #ifdef __FEATURE_BULK_DELETE_MOVE_UPDATE_REQUEST_OPTI__ + int bulk_flag = false; + #endif + + memset(&mailbox, 0x00, sizeof(emf_mailbox_t)); + + if (!account_id || !mail_ids || !num) { + EM_DEBUG_EXCEPTION("account_id[%d], mail_ids[%p], num[%d], from_server[%d]", account_id, mail_ids, num, from_server); + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + mail_id = mail_ids[0]; + + if (!(account = em_core_get_account_reference(account_id))) { + EM_DEBUG_EXCEPTION("em_core_get_account_reference failed [%d]", account_id); + err = EMF_ERROR_INVALID_ACCOUNT; + goto FINISH_OFF; + } + + if (account->receiving_server_type == EMF_SERVER_TYPE_ACTIVE_SYNC) + from_server = EMF_DELETE_LOCALLY; + + FINISH_OFF_IF_CANCELED; + + parameter_string_length = sizeof(char) * (num * 8 + 128 /* MAILBOX_LEN_IN_MAIL_TBL */ * 2); + parameter_string = malloc(parameter_string_length); + + if (parameter_string == NULL) { + EM_DEBUG_EXCEPTION("Memory allocation for mail_id_list_string failed"); + err = EMF_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + memset(parameter_string, 0, parameter_string_length); + + if (from_server == EMF_DELETE_LOCAL_AND_SERVER || from_server == EMF_DELETE_FOR_SEND_THREAD) { /* server delete */ + for (i = 0; i < num; i++) { + mail_id = mail_ids[i]; + + if (!em_storage_get_downloaded_mail(mail_id, &mail, false, &err) || !mail) { + EM_DEBUG_EXCEPTION("em_storage_get_uid_by_mail_id failed [%d]", err); + + if (err == EM_STORAGE_ERROR_MAIL_NOT_FOUND) { /* not server mail */ + /* err = EMF_ERROR_MAIL_NOT_FOUND_ON_SERVER; */ + continue; + } + else + err = em_storage_get_emf_error_from_em_storage_error(err); + + goto FINISH_OFF; + } + + EM_SAFE_FREE(mailbox.user_data); + + if (stream == NULL) { + if (!em_core_mailbox_open(account_id, mail->server_mailbox_name , (void **)&stream, &err)) { + EM_DEBUG_EXCEPTION("em_core_mailbox_open failed [%d]", err); + status = EMF_DELETE_CONNECTION_FAIL; + goto FINISH_OFF; + } + + mailbox.account_id = account_id; + mailbox.name = mail->server_mailbox_name; + mailbox.mail_stream = stream; + + FINISH_OFF_IF_CANCELED; + } + +#ifdef __FEATURE_BULK_DELETE_MOVE_UPDATE_REQUEST_OPTI__ + if (account->receiving_server_type == EMF_SERVER_TYPE_IMAP4) { +#ifdef __LOCAL_ACTIVITY__ + if (!bulk_flag && !imap4_mail_delete_ex(&mailbox, mail_ids, num, from_server, &err)) { +#else /* __LOCAL_ACTIVITY__ */ + if (!bulk_flag && !imap4_mail_delete_ex(&mailbox, mail_ids, num, &err)) { +#endif /* __LOCAL_ACTIVITY__ */ + EM_DEBUG_EXCEPTION("imap4_mail_delete_ex failed [%d]", err); + if (err == EMF_ERROR_IMAP4_STORE_FAILURE) + err = EMF_ERROR_MAIL_NOT_FOUND_ON_SERVER; + goto FINISH_OFF; + } + else + bulk_flag = true; + + } + else if (account->receiving_server_type == EMF_SERVER_TYPE_POP3) { + if (!em_core_mail_get_msgno_by_uid(account, &mailbox, mail->server_mail_id, &msgno, &err)) { + EM_DEBUG_EXCEPTION("em_core_mail_get_msgno_by_uid faild [%d]", err); + if (err == EMF_ERROR_MAIL_NOT_FOUND_ON_SERVER) + goto NOT_FOUND_ON_SERVER; + else + goto FINISH_OFF; + } + + FINISH_OFF_IF_CANCELED; + + if (!em_core_mail_delete_from_server(account, &mailbox, msgno, &err)) { + EM_DEBUG_EXCEPTION("em_core_mail_delete_from_server falied [%d]", err); + goto FINISH_OFF; + } +#ifdef __LOCAL_ACTIVITY__ + else { + /* Remove local activity */ + emf_activity_tbl_t new_activity; + memset(&new_activity, 0x00, sizeof(emf_activity_tbl_t)); + if (from_server == EMF_DELETE_FOR_SEND_THREAD) { + new_activity.activity_type = ACTIVITY_DELETEMAIL_SEND; + EM_DEBUG_LOG("from_server == EMF_DELETE_FOR_SEND_THREAD "); + } + else { + new_activity.activity_type = ACTIVITY_DELETEMAIL; + } + + new_activity.mail_id = mail->mail_id; + new_activity.server_mailid = mail->server_mail_id; + new_activity.src_mbox = NULL; + new_activity.dest_mbox = NULL; + + if (!em_core_activity_delete(&new_activity, &err)) { + EM_DEBUG_EXCEPTION(" em_core_activity_delete failed - %d ", err); + } + + /* Fix for issue - Sometimes mail move and immediately followed by mail delete is not reflected on server */ + if (!em_storage_remove_downloaded_mail(account_id, mail->server_mailbox_name, mail->server_mail_id, true, &err)) { + EM_DEBUG_LOG("em_storage_remove_downloaded_mail falied [%d]", err); + } + } + +#endif /* __LOCAL_ACTIVITY__ */ + } +#else /* __FEATURE_BULK_DELETE_MOVE_UPDATE_REQUEST_OPTI__ */ + if (!em_core_mail_get_msgno_by_uid(account, &mailbox, mail->server_mail_id, &msgno, &err)) { + EM_DEBUG_LOG("em_core_mail_get_msgno_by_uid faild [%d]", err); + + if (err == EMF_ERROR_MAIL_NOT_FOUND_ON_SERVER) /* Prevent Defect - 9561 */ + goto NOT_FOUND_ON_SERVER; + else + goto FINISH_OFF; + } + + FINISH_OFF_IF_CANCELED; + + if (!em_core_mail_delete_from_server(account, &mailbox, msgno, &err)) { + EM_DEBUG_LOG("em_core_mail_delete_from_server falied [%d]", err); + + goto FINISH_OFF; + } +#endif /* __FEATURE_BULK_DELETE_MOVE_UPDATE_REQUEST_OPTI__ */ + + if (!em_storage_remove_downloaded_mail(account_id, mail->server_mailbox_name, mail->server_mail_id, true, &err)) + EM_DEBUG_LOG("em_storage_remove_downloaded_mail falied [%d]", err); + + /* em_core_delete_notification_for_read_mail(mail_id); */ + +NOT_FOUND_ON_SERVER: + memset(mail_id_string, 0, 10); + SNPRINTF(mail_id_string, 10, "%d,", mail_id); + strcat(parameter_string, mail_id_string); + + FINISH_OFF_IF_CANCELED; + + em_storage_free_mail(&mail, 1, NULL); + } + } + else if (from_server == EMF_DELETE_LOCALLY) /* Local Delete */ { + em_core_mail_delete_from_local(account_id, mail_ids, num, noti_param_1, noti_param_2, err_code); + for (i = 0; i < num; i++) { + /* em_core_delete_notification_for_read_mail(mail_id); */ + SNPRINTF(mail_id_string, 10, "%d,", mail_id); + strcat(parameter_string, mail_id_string); + } + + em_core_check_unread_mail(); + } + + ret = true; + +FINISH_OFF: + + if (stream) { + em_core_mailbox_close(0, stream); + stream = NULL; + } + + if (mailbox.user_data != NULL) { + em_core_mailbox_free_uids(mailbox.user_data, NULL); + mailbox.user_data = NULL; + } + + EM_SAFE_FREE(parameter_string); + + if (mail != NULL) + em_storage_free_mail(&mail, 1, NULL); + + + if (from_server) + em_core_show_popup(account_id, EMF_ACTION_DELETE_MAIL, ret == true ? 0 : err); + + if (err_code != NULL) + *err_code = err; + + return ret; +} + + +int em_core_mail_delete_all(emf_mailbox_t *mailbox, int with_server, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("mailbox [%p], with_server [%d], err_code [%p]", mailbox, with_server, err_code); + + int ret = false; + int err = EMF_ERROR_NONE; + int search_handle = 0; + int *mail_ids = NULL; + int i = 0; + int total = 0; + char buf[512] = { 0, }; + + if (!mailbox || mailbox->account_id < FIRST_ACCOUNT_ID) { + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + if (mailbox->name != NULL) { + /* Delete all mails in specific mailbox */ + if (!em_storage_mail_search_start(NULL, mailbox->account_id, mailbox->name, 0, &search_handle, &total, true, &err)) { + EM_DEBUG_EXCEPTION("em_storage_mail_search_start failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + + EM_DEBUG_LOG("em_storage_mail_search_start returns [%d]", total); + + if (total > 0) { + mail_ids = em_core_malloc(sizeof(int) * total); + if (mail_ids == NULL) { + EM_DEBUG_EXCEPTION("em_core_malloc failed..."); + err = EMF_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + for (i = 0; i < total; i++) { + if (!em_storage_mail_search_result(search_handle, RETRIEVE_ID, (void**)&mail_ids[i], true, &err)) { + EM_DEBUG_EXCEPTION("em_storage_mail_search_result failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + } + + if (!em_core_mail_delete(mailbox->account_id, mail_ids, total, with_server, EMF_DELETED_BY_COMMAND, false, &err)) { + EM_DEBUG_EXCEPTION("em_core_mail_delete failed [%d]", err); + goto FINISH_OFF; + } + } + } + else if (with_server == EMF_DELETE_LOCALLY){ + /* em_storage_delete_mail_by_account is available only locally */ + if (!em_storage_delete_mail_by_account(mailbox->account_id, false, &err)) { + EM_DEBUG_EXCEPTION("em_storage_delete_mail_by_account failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + + if (!em_storage_delete_attachment_all_on_db(mailbox->account_id, NULL, false, &err)) { + EM_DEBUG_EXCEPTION("em_storage_delete_attachment_all_on_db failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + + /* delete mail contents from filesystem */ + if (!em_storage_get_save_name(mailbox->account_id, 0, 0, NULL, buf, &err)) { + EM_DEBUG_EXCEPTION("em_storage_get_save_name failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + + if (!em_storage_delete_dir(buf, &err)) { + EM_DEBUG_EXCEPTION("em_storage_delete_dir failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + } + + /* delete meeting request */ + if (!em_storage_delete_meeting_request(mailbox->account_id, 0, NULL, false, &err)) { + EM_DEBUG_EXCEPTION("em_storage_delete_attachment_all_on_db failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + + em_core_check_unread_mail(); + } + + ret = true; + +FINISH_OFF: + if (search_handle >= 0) { + if (!em_storage_mail_search_end(search_handle, true, &err)) + EM_DEBUG_EXCEPTION("em_storage_mail_search_end failed [%d]", err); + } + + EM_SAFE_FREE(mail_ids); + if (err_code != NULL) + *err_code = err; + EM_DEBUG_FUNC_END("ret [%d], err [%d]", ret, err); + return ret; +} + +EXPORT_API int em_core_mail_delete_from_local(int account_id, int *mail_ids, int num, int noti_param_1, int noti_param_2, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id[%d], mail_ids[%p], num [%d], noti_param_1 [%d], noti_param_2 [%d], err_code[%p]", account_id, mail_ids, num, noti_param_1, noti_param_2, num, err_code); + int ret = false, err = EMF_ERROR_NONE, i; + emf_mail_tbl_t *result_mail_list; + char mail_id_string[10], *noti_param_string = NULL, buf[512] = {0, }; + + /* Getting mail list by using select mail_id [in] */ + + if(!em_storage_get_mail_field_by_multiple_mail_id(mail_ids, num, RETRIEVE_SUMMARY, &result_mail_list, true, &err) || !result_mail_list) { + EM_DEBUG_EXCEPTION("em_storage_get_mail_field_by_multiple_mail_id failed [%d]", err); + goto FINISH_OFF; + } + + /* Deleting mails by using select mail_id [in] */ + if(!em_storage_delete_multiple_mails(mail_ids, num, true, &err)) { + EM_DEBUG_EXCEPTION("em_storage_delete_multiple_mails failed [%d]", err); + goto FINISH_OFF; + } + + /* Sending Notification */ + noti_param_string = em_core_malloc(sizeof(char) * 10 * num); + + if(!noti_param_string) { + EM_DEBUG_EXCEPTION("em_core_malloc failed"); + err = EMF_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + for(i = 0; i < num; i++) { + memset(mail_id_string, 0, 10); + SNPRINTF(mail_id_string, 10, "%d,", mail_ids[i]); + strcat(noti_param_string, mail_id_string); + /* can be optimized by appending sub string with directly pointing on string array kyuho.jo 2011-10-07 */ + } + + if (!em_storage_notify_storage_event(NOTI_MAIL_DELETE, account_id, noti_param_1, noti_param_string, noti_param_2)) + EM_DEBUG_EXCEPTION(" em_storage_notify_storage_event failed [ NOTI_MAIL_DELETE_FINISH ] >>>> "); + + /* Updating Thread informations */ + /* Thread information should be updated as soon as possible. */ + for(i = 0; i < num; i++) { + if (result_mail_list[i].thread_item_count > 1) { + if (!em_storage_update_latest_thread_mail(account_id, result_mail_list[i].thread_id, 0, 0, false, &err)) { + EM_DEBUG_EXCEPTION("em_storage_update_latest_thread_mail failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + } + } + if (!em_storage_notify_storage_event(NOTI_MAIL_DELETE_FINISH, account_id, noti_param_1, noti_param_string, noti_param_2)) + EM_DEBUG_EXCEPTION(" em_storage_notify_storage_event failed [ NOTI_MAIL_DELETE_FINISH ] >>>> "); + + for(i = 0; i < num; i++) { + /* Deleting attachments */ + if (!em_storage_delete_attachment_on_db(result_mail_list[i].mail_id, 0, false, &err)) { + EM_DEBUG_EXCEPTION("em_storage_delete_attachment_on_db failed [%d]", err); + + if (err == EM_STORAGE_ERROR_ATTACHMENT_NOT_FOUND) + err = EMF_ERROR_NONE; + else + err = em_storage_get_emf_error_from_em_storage_error(err); + } + + /* Deleting Directories */ + /* delete mail contents from filesystem */ + if (!em_storage_get_save_name(account_id, result_mail_list[i].mail_id, 0, NULL, buf, &err)) { + EM_DEBUG_EXCEPTION("em_storage_get_save_name failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + + if (!em_storage_delete_dir(buf, &err)) { + EM_DEBUG_EXCEPTION("em_storage_delete_dir failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + } + + /* Deleting Meeting Request */ + if (!em_storage_delete_meeting_request(account_id, result_mail_list[i].mail_id, NULL, false, &err)) { + EM_DEBUG_EXCEPTION("em_storage_delete_meeting_request failed [%d]", err); + if (err != EM_STORAGE_ERROR_CONTACT_NOT_FOUND) { + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + } + } + + ret = true; + +FINISH_OFF: + EM_SAFE_FREE(noti_param_string); + + if (err_code != NULL) + *err_code = err; + + EM_DEBUG_FUNC_END(); + return ret; +} + +int em_core_mail_delete_from_server(emf_account_t *account, emf_mailbox_t *mailbox, int msgno, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account[%p], mailbox[%p], msgno[%d], err_code[%p]", account, mailbox, msgno, err_code); + + int ret = false; + int err = EMF_ERROR_NONE; + + if (!account || !mailbox) { + EM_DEBUG_EXCEPTION("account[%p], mailbox[%p], msgno[%d]", account, mailbox, msgno); + + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + if (account->receiving_server_type == EMF_SERVER_TYPE_POP3) { + if (!pop3_mail_delete(mailbox->mail_stream, msgno, &err)) { + EM_DEBUG_EXCEPTION("pop3_mail_delete failed [%d]", err); + + if (err == EMF_ERROR_POP3_DELE_FAILURE) + err = EMF_ERROR_MAIL_NOT_FOUND_ON_SERVER; + goto FINISH_OFF; + } + } + else { /* EMF_SERVER_TYPE_IMAP4 */ + if (!imap4_mail_delete(mailbox->mail_stream, msgno, &err)) { + EM_DEBUG_EXCEPTION("imap4_mail_delete failed [%d]", err); + + if (err == EMF_ERROR_IMAP4_STORE_FAILURE) + err = EMF_ERROR_MAIL_NOT_FOUND_ON_SERVER; + goto FINISH_OFF; + } + } + + ret = true; + +FINISH_OFF: + if (err_code) + *err_code = err; + EM_DEBUG_FUNC_END(); + return ret; +} + +EXPORT_API int em_core_mail_get_msgno_by_uid(emf_account_t *account, emf_mailbox_t *mailbox, char *uid, int *msgno, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account[%p], mailbox[%p], uid[%s], msgno[%p], err_code[%p]", account, mailbox, uid, msgno, err_code); + + int ret = false; + int err = EMF_ERROR_NONE; + + em_core_uid_list *uid_list = NULL; + em_core_uid_list *pTemp_uid_list = NULL; + + if (!account || !mailbox || !uid || !msgno) { + EM_DEBUG_EXCEPTION("account[%p], mailbox[%p], uid[%s], msgno[%p]", account, mailbox, uid, msgno); + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + uid_list = mailbox->user_data; + + if (uid_list == NULL) { + if (account->receiving_server_type == EMF_SERVER_TYPE_POP3) { + if (!pop3_mailbox_get_uids(mailbox->mail_stream, &uid_list, &err)) { + EM_DEBUG_EXCEPTION("pop3_mailbox_get_uids failed [%d]", err); + goto FINISH_OFF; + } + } + else { /* EMF_SERVER_TYPE_IMAP4 */ + if (!imap4_mailbox_get_uids(mailbox->mail_stream, &uid_list, &err)) { + EM_DEBUG_EXCEPTION("imap4_mailbox_get_uids failed [%d]", err); + goto FINISH_OFF; + } + } + mailbox->user_data = uid_list; + } + pTemp_uid_list = uid_list; + while (uid_list) { + if (!strcmp(uid_list->uid, uid)) { + *msgno = uid_list->msgno; + EM_DEBUG_LOG("uid_list->msgno[%d]", uid_list->msgno); + ret = true; + goto FINISH_OFF; + } + EM_DEBUG_LOG("other uid_list->msgno[%d]", uid_list->msgno); + uid_list = uid_list->next; + } + + err = EMF_ERROR_MAIL_NOT_FOUND_ON_SERVER; + +FINISH_OFF: + if (err_code != NULL) + *err_code = err; + uid_list = pTemp_uid_list ; + if (uid_list != NULL) + em_core_mailbox_free_uids(uid_list, NULL); + /* mailbox->user_data and uid_list both point to same memory address, So when uid_list is freed then just set */ + /* mailbox->user_data to NULL and dont use EM_SAFE_FREE, it will crash : ) */ + if (mailbox) + mailbox->user_data = NULL; + EM_DEBUG_FUNC_END(); + return ret; +} + +/* description + * add a attachment to mail. + * arguments + * mailbox : mail box + * mail_id : mail id + * attachment : attachment to be added + * return + * succeed : 1 + * fail : 0 + */ +EXPORT_API int em_core_mail_add_attachment(int mail_id, emf_attachment_info_t *attachment, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("mail_id[%d], attachment[%p], err_code[%p]", mail_id, attachment, err_code); + + if (attachment == NULL) { + EM_DEBUG_EXCEPTION("mail_id[%d], attachment[%p]", mail_id, attachment); + if (err_code) + *err_code = EMF_ERROR_INVALID_PARAM; + return false; + } + + int ret = false, err = EMF_ERROR_NONE; + emf_mail_tbl_t *mail_table_data = NULL; + int attachment_id = 0; + + + + if (!em_storage_get_mail_field_by_id(mail_id, RETRIEVE_SUMMARY, &mail_table_data, true, &err) || !mail_table_data) { + EM_DEBUG_EXCEPTION("em_storage_get_mail_field_by_id failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF2; + } + + int account_id = mail_table_data->account_id; + emf_mail_attachment_tbl_t attachment_tbl; + + memset(&attachment_tbl, 0x00, sizeof(emf_mail_attachment_tbl_t)); + + mail_table_data->attachment_count = mail_table_data->attachment_count + 1; + attachment_tbl.account_id = mail_table_data->account_id; + attachment_tbl.mailbox_name = mail_table_data->mailbox_name; + attachment_tbl.mail_id = mail_id; + attachment_tbl.attachment_name = attachment->name; + attachment_tbl.attachment_size = attachment->size; + attachment_tbl.file_yn = attachment->downloaded; + attachment_tbl.flag1 = attachment->drm; + attachment_tbl.flag3 = attachment->inline_content; + + /* BEGIN TRANSACTION; */ + em_storage_begin_transaction(NULL, NULL, NULL); + + if (!em_storage_add_attachment(&attachment_tbl, 0, false, &err)) { + EM_DEBUG_EXCEPTION("em_storage_add_attachment failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + + attachment->attachment_id = attachment_tbl.attachment_id; + + if (attachment->savename) { + char buf[512]; + + if (!attachment->inline_content) { + if (!em_storage_create_dir(account_id, mail_id, attachment_tbl.attachment_id, &err)) { + EM_DEBUG_EXCEPTION("em_storage_create_dir failed [%d]", err); + goto FINISH_OFF; + } + attachment_id = attachment_tbl.attachment_id; + } + + if (!em_storage_get_save_name(account_id, mail_id, attachment_id, attachment->name, buf, &err)) { + EM_DEBUG_EXCEPTION("em_storage_get_save_name failed [%d]", err); + goto FINISH_OFF; + } + attachment_tbl.attachment_path = buf; + + if (!em_storage_change_attachment_field(mail_id, UPDATE_SAVENAME, &attachment_tbl, false, &err)) { + EM_DEBUG_EXCEPTION("em_storage_change_attachment_field failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + + if (!em_storage_change_mail_field(mail_id, APPEND_BODY, mail_table_data, false, &err)) { + EM_DEBUG_EXCEPTION("em_storage_change_mail_field failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + + if (attachment->downloaded) { + if (!em_storage_move_file(attachment->savename, buf, false, &err)) { + EM_DEBUG_EXCEPTION("em_storage_move_file failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + } + + /* Here only filename is being updated. Since first add is being done there will not be any old files. + So no need to check for old files in this update case */ + if (!em_storage_change_attachment_field(mail_id, UPDATE_SAVENAME, &attachment_tbl, false, &err)) { + EM_DEBUG_EXCEPTION("em_storage_change_attachment_field failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + + EM_SAFE_FREE(attachment->savename); + attachment->savename = EM_SAFE_STRDUP(buf); + } + + ret = true; + +FINISH_OFF: + if (ret == true) { /* COMMIT TRANSACTION; */ + if (em_storage_commit_transaction(NULL, NULL, NULL) == false) { + err = em_storage_get_emf_error_from_em_storage_error(EM_STORAGE_ERROR_DB_FAILURE); + ret = false; + } + } + else { /* ROLLBACK TRANSACTION; */ + if (em_storage_rollback_transaction(NULL, NULL, NULL) == false) + err = em_storage_get_emf_error_from_em_storage_error(EM_STORAGE_ERROR_DB_FAILURE); + } + +FINISH_OFF2: + if (mail_table_data != NULL) + em_storage_free_mail(&mail_table_data, 1, NULL); + + if (err_code) + *err_code = err; + EM_DEBUG_FUNC_END("err [%d]", err); + return ret; +} + + +EXPORT_API int em_core_mail_add_attachment_data(int input_mail_id, emf_attachment_data_t *input_attachment_data) +{ + EM_DEBUG_FUNC_BEGIN("input_mail_id[%d], input_attachment_data[%p]", input_mail_id, input_attachment_data); + + int err = EMF_ERROR_NONE; + int attachment_id = 0; + char buf[512] = { 0, }; + emf_mail_tbl_t *mail_table_data = NULL; + emf_mail_attachment_tbl_t attachment_tbl = { 0 }; + + if (input_attachment_data == NULL) { + EM_DEBUG_EXCEPTION("EMF_ERROR_INVALID_PARAM"); + return EMF_ERROR_INVALID_PARAM; + } + + if (!em_storage_get_mail_field_by_id(input_mail_id, RETRIEVE_SUMMARY, &mail_table_data, true, &err) || !mail_table_data) { + EM_DEBUG_EXCEPTION("em_storage_get_mail_field_by_id failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF2; + } + + mail_table_data->attachment_count = mail_table_data->attachment_count + 1; + + attachment_tbl.account_id = mail_table_data->account_id; + attachment_tbl.mailbox_name = mail_table_data->mailbox_name; + attachment_tbl.mail_id = input_mail_id; + attachment_tbl.attachment_name = input_attachment_data->attachment_name; + attachment_tbl.attachment_size = input_attachment_data->attachment_size; + attachment_tbl.file_yn = input_attachment_data->save_status; + attachment_tbl.flag1 = input_attachment_data->drm_status; + attachment_tbl.flag3 = input_attachment_data->inline_content_status; + + /* BEGIN TRANSACTION; */ + em_storage_begin_transaction(NULL, NULL, NULL); + + if (!em_storage_add_attachment(&attachment_tbl, 0, false, &err)) { + EM_DEBUG_EXCEPTION("em_storage_add_attachment failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + + input_attachment_data->attachment_id = attachment_tbl.attachment_id; + + if (input_attachment_data->attachment_path) { + if (!input_attachment_data->inline_content_status) { + if (!em_storage_create_dir(mail_table_data->account_id, input_mail_id, attachment_tbl.attachment_id, &err)) { + EM_DEBUG_EXCEPTION("em_storage_create_dir failed [%d]", err); + goto FINISH_OFF; + } + attachment_id = attachment_tbl.attachment_id; + } + + if (!em_storage_get_save_name(mail_table_data->account_id, input_mail_id, attachment_id, input_attachment_data->attachment_name, buf, &err)) { + EM_DEBUG_EXCEPTION("em_storage_get_save_name failed [%d]", err); + goto FINISH_OFF; + } + attachment_tbl.attachment_path = buf; + + if (!em_storage_change_attachment_field(input_mail_id, UPDATE_SAVENAME, &attachment_tbl, false, &err)) { + EM_DEBUG_EXCEPTION("em_storage_change_attachment_field failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + + if (!em_storage_change_mail_field(input_mail_id, APPEND_BODY, mail_table_data, false, &err)) { + EM_DEBUG_EXCEPTION("em_storage_change_mail_field failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + + if (input_attachment_data->save_status) { + if (!em_storage_move_file(input_attachment_data->attachment_path, buf, false, &err)) { + EM_DEBUG_EXCEPTION("em_storage_move_file failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + } + + /* Here only filename is being updated. Since first add is being done there will not be any old files. + So no need to check for old files in this update case */ + if (!em_storage_change_attachment_field(input_mail_id, UPDATE_SAVENAME, &attachment_tbl, false, &err)) { + EM_DEBUG_EXCEPTION("em_storage_change_attachment_field failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + + EM_SAFE_FREE(input_attachment_data->attachment_path); + input_attachment_data->attachment_path = EM_SAFE_STRDUP(buf); + } + +FINISH_OFF: + if (err == EMF_ERROR_NONE) { /* COMMIT TRANSACTION; */ + if (em_storage_commit_transaction(NULL, NULL, NULL) == false) { + err = em_storage_get_emf_error_from_em_storage_error(EM_STORAGE_ERROR_DB_FAILURE); + } + } + else { /* ROLLBACK TRANSACTION; */ + if (em_storage_rollback_transaction(NULL, NULL, NULL) == false) + err = em_storage_get_emf_error_from_em_storage_error(EM_STORAGE_ERROR_DB_FAILURE); + } + +FINISH_OFF2: + if (mail_table_data != NULL) + em_storage_free_mail(&mail_table_data, 1, NULL); + + EM_DEBUG_FUNC_END("err [%d]", err); + return err; +} + + +/* description + * delete a attachment from mail. + * arguments + * mailbox : mail box + * mail_id : mail id + * attachment_id : number string of attachment-id to be deleted + * (ex : if attachment id is 2, number stirng will be "2") + * return + * succeed : 1 + * fail : 0 + */ +int em_core_mail_delete_attachment(int mail_id, char *attachment_id_string, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("mail_id[%d], attachment_id_string[%s], err_code[%p]", mail_id, attachment_id_string, err_code); + + if (attachment_id_string == NULL) { + EM_DEBUG_EXCEPTION("mail_id[%d], attachment_id[%p]", mail_id, attachment_id_string); + if (err_code != NULL) + *err_code = EMF_ERROR_INVALID_PARAM; + return false; + } + + int ret = false; + int error = EMF_ERROR_NONE; + int attachment_id = atoi(attachment_id_string); + + /* BEGIN TRANSACTION; */ + em_storage_begin_transaction(NULL, NULL, NULL); + + if (!em_storage_delete_attachment_on_db(mail_id, attachment_id, false, &error)) { + EM_DEBUG_EXCEPTION("em_storage_delete_attachment_on_db failed [%d]", error); + goto FINISH_OFF; + } + + ret = true; + +FINISH_OFF: + if (ret == true) { /* COMMIT TRANSACTION; */ + if (em_storage_commit_transaction(NULL, NULL, NULL) == false) { + error = em_storage_get_emf_error_from_em_storage_error(EM_STORAGE_ERROR_DB_FAILURE); + ret = false; + } + } + else { /* ROLLBACK TRANSACTION; */ + if (em_storage_rollback_transaction(NULL, NULL, NULL) == false) + error = em_storage_get_emf_error_from_em_storage_error(EM_STORAGE_ERROR_DB_FAILURE); + } + + if (err_code != NULL) + *err_code = error; + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +/* description + * update a attachment to mail. + * arguments + * mailbox : mail box + * mail_id : mail id + * attachment : attachment to be added + * return + * succeed : 1 + * fail : 0 + */ +static int em_core_mail_update_attachment(int mail_id, emf_attachment_info_t *updated_attachment, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("mail_id[%d], attachment[%p], err_code[%p]", mail_id, updated_attachment, err_code); + + int ret = false, err = EMF_ERROR_NONE; + emf_mail_attachment_tbl_t *existing_attachment_info = NULL; + emf_mail_attachment_tbl_t attachment_tbl; + + if (updated_attachment == NULL) { + EM_DEBUG_EXCEPTION("Invalid Parameter"); + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF2; + } + + if (!em_storage_get_attachment(mail_id, updated_attachment->attachment_id, &existing_attachment_info, 1, &err)) { + EM_DEBUG_EXCEPTION("em_storage_get_attachment failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF2; + } + + memset(&attachment_tbl, 0x00, sizeof(emf_mail_attachment_tbl_t)); + + attachment_tbl.mail_id = mail_id; + attachment_tbl.account_id = existing_attachment_info->account_id; + attachment_tbl.mailbox_name = existing_attachment_info->mailbox_name; + attachment_tbl.attachment_name = updated_attachment->name; + attachment_tbl.attachment_size = updated_attachment->size; + attachment_tbl.attachment_path = updated_attachment->savename; + attachment_tbl.file_yn = updated_attachment->downloaded; + attachment_tbl.flag1 = updated_attachment->drm; + attachment_tbl.flag3 = updated_attachment->inline_content; + attachment_tbl.attachment_id = updated_attachment->attachment_id; + + char buf[512]; + int attachment_id = 0; + + /* EM_DEBUG_LOG("file is downloaded and different from old one. it should be moved"); */ + + if (!updated_attachment->inline_content) { + if (!em_storage_create_dir(attachment_tbl.account_id, mail_id, attachment_tbl.attachment_id, &err)) { + EM_DEBUG_EXCEPTION("em_storage_create_dir failed [%d]", err); + goto FINISH_OFF; + } + attachment_id = attachment_tbl.attachment_id; + } + + if (!em_storage_get_save_name(attachment_tbl.account_id, mail_id, attachment_id, updated_attachment->name, buf, &err)) { + EM_DEBUG_EXCEPTION("em_storage_get_save_name failed [%d]", err); + goto FINISH_OFF2; + } + attachment_tbl.attachment_path = buf; + + EM_DEBUG_LOG("downloaded [%d], savename [%s], attachment_path [%s]", updated_attachment->downloaded, updated_attachment->savename, existing_attachment_info->attachment_path); + if (updated_attachment->downloaded && EM_SAFE_STRCMP(updated_attachment->savename, existing_attachment_info->attachment_path) != 0) { + if (!em_storage_move_file(updated_attachment->savename, buf, false ,&err)) { + EM_DEBUG_EXCEPTION("em_storage_move_file failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF2; + } + } + else + EM_DEBUG_LOG("no need to move"); + + EM_SAFE_FREE(updated_attachment->savename); + updated_attachment->savename = EM_SAFE_STRDUP(buf); + + em_storage_begin_transaction(NULL, NULL, NULL); + + if (!em_storage_update_attachment(&attachment_tbl, false, &err)) { + EM_DEBUG_EXCEPTION("em_storage_update_attachment failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + + ret = true; + +FINISH_OFF: + if (ret == true) { /* COMMIT TRANSACTION; */ + if (em_storage_commit_transaction(NULL, NULL, NULL) == false) { + err = em_storage_get_emf_error_from_em_storage_error(EM_STORAGE_ERROR_DB_FAILURE); + ret = false; + } + } + else { /* ROLLBACK TRANSACTION; */ + if (em_storage_rollback_transaction(NULL, NULL, NULL) == false) + err = em_storage_get_emf_error_from_em_storage_error(EM_STORAGE_ERROR_DB_FAILURE); + } + +FINISH_OFF2: + if (existing_attachment_info) + em_storage_free_attachment(&existing_attachment_info, 1, NULL); + + if (err_code) + *err_code = err; + EM_DEBUG_FUNC_END("err [%d]", err); + return ret; +} + +static int em_core_mail_update_attachment_data(int input_mail_id, emf_attachment_data_t *input_attachment_data) +{ + EM_DEBUG_FUNC_BEGIN("input_mail_id[%d], input_attachment_data[%p]", input_mail_id, input_attachment_data); + + int err = EMF_ERROR_NONE; + int attachment_id = 0; + char buf[512] = { 0 , }; + emf_mail_attachment_tbl_t *existing_attachment_info = NULL; + emf_mail_attachment_tbl_t attachment_tbl = { 0 }; + + if (input_attachment_data == NULL) { + EM_DEBUG_EXCEPTION("Invalid Parameter"); + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF2; + } + + if (!em_storage_get_attachment(input_mail_id, input_attachment_data->attachment_id, &existing_attachment_info, 1, &err)) { + EM_DEBUG_EXCEPTION("em_storage_get_attachment failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF2; + } + + attachment_tbl.mail_id = input_mail_id; + attachment_tbl.account_id = existing_attachment_info->account_id; + attachment_tbl.mailbox_name = existing_attachment_info->mailbox_name; + attachment_tbl.attachment_name = input_attachment_data->attachment_name; + attachment_tbl.attachment_size = input_attachment_data->attachment_size; + attachment_tbl.attachment_path = input_attachment_data->attachment_path; + attachment_tbl.file_yn = input_attachment_data->save_status; + attachment_tbl.flag1 = input_attachment_data->drm_status; + attachment_tbl.flag3 = input_attachment_data->inline_content_status; + attachment_tbl.attachment_id = input_attachment_data->attachment_id; + + if (!input_attachment_data->inline_content_status) { + if (!em_storage_create_dir(attachment_tbl.account_id, input_mail_id, attachment_tbl.attachment_id, &err)) { + EM_DEBUG_EXCEPTION("em_storage_create_dir failed [%d]", err); + goto FINISH_OFF; + } + attachment_id = attachment_tbl.attachment_id; + } + + if (!em_storage_get_save_name(attachment_tbl.account_id, input_mail_id, attachment_id, input_attachment_data->attachment_name, buf, &err)) { + EM_DEBUG_EXCEPTION("em_storage_get_save_name failed [%d]", err); + goto FINISH_OFF2; + } + attachment_tbl.attachment_path = buf; + + EM_DEBUG_LOG("downloaded [%d], savename [%s], attachment_path [%s]", input_attachment_data->save_status, input_attachment_data->attachment_path, existing_attachment_info->attachment_path); + if (input_attachment_data->save_status && EM_SAFE_STRCMP(input_attachment_data->attachment_path, existing_attachment_info->attachment_path) != 0) { + if (!em_storage_move_file(input_attachment_data->attachment_path, buf, false ,&err)) { + EM_DEBUG_EXCEPTION("em_storage_move_file failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF2; + } + } + else + EM_DEBUG_LOG("no need to move"); + + EM_SAFE_FREE(input_attachment_data->attachment_path); + input_attachment_data->attachment_path = EM_SAFE_STRDUP(buf); + + em_storage_begin_transaction(NULL, NULL, NULL); + + if (!em_storage_update_attachment(&attachment_tbl, false, &err)) { + EM_DEBUG_EXCEPTION("em_storage_update_attachment failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + +FINISH_OFF: + if (err == EMF_ERROR_NONE) { /* COMMIT TRANSACTION; */ + if (em_storage_commit_transaction(NULL, NULL, NULL) == false) { + err = em_storage_get_emf_error_from_em_storage_error(EM_STORAGE_ERROR_DB_FAILURE); + } + } + else { /* ROLLBACK TRANSACTION; */ + if (em_storage_rollback_transaction(NULL, NULL, NULL) == false) + err = em_storage_get_emf_error_from_em_storage_error(EM_STORAGE_ERROR_DB_FAILURE); + } + +FINISH_OFF2: + if (existing_attachment_info) + em_storage_free_attachment(&existing_attachment_info, 1, NULL); + + EM_DEBUG_FUNC_END("err [%d]", err); + return err; +} + + +static int em_core_mail_compare_filename_of_attachment(int mail_id, int attachment_a_id, emf_attachment_info_t *attachment_b_info, int *result, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("mail_id[%d], attachment_a_id[%d], attachment_b_info[%p], result[%p], err_code[%p]", mail_id, attachment_a_id, attachment_b_info, result, err_code); + + EM_IF_NULL_RETURN_VALUE(attachment_b_info, false); + EM_IF_NULL_RETURN_VALUE(result, false); + + int err, err_2, ret = false; + emf_mail_attachment_tbl_t *attachment_a_tbl = NULL; + + if (!em_storage_get_attachment(mail_id, attachment_a_id, &attachment_a_tbl, 1, &err)) { + EM_DEBUG_EXCEPTION("em_storage_get_attachment failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + + if (attachment_a_tbl->attachment_name && attachment_b_info->savename) { + EM_DEBUG_LOG("attachment_a_tbl->attachment_name [%s], ttachment_b_info->name [%s]", attachment_a_tbl->attachment_name, attachment_b_info->name); + *result = strcmp(attachment_a_tbl->attachment_name, attachment_b_info->name); + } + + ret = true; + +FINISH_OFF: + + if (attachment_a_tbl) + em_storage_free_attachment(&attachment_a_tbl, 1, &err_2); + EM_DEBUG_FUNC_END("*result [%d]", *result); + return ret; +} + +static int em_core_mail_compare_filename_of_attachment_data(int input_mail_id, int input_attachment_a_id, emf_attachment_data_t *input_attachment_b_data, int *result) +{ + EM_DEBUG_FUNC_BEGIN("input_mail_id[%d], input_attachment_a_id[%d], input_attachment_b_data[%p], result[%p]", input_mail_id, input_attachment_a_id, input_attachment_b_data, result); + + EM_IF_NULL_RETURN_VALUE(input_attachment_b_data, false); + EM_IF_NULL_RETURN_VALUE(result, false); + + int err, err_2, ret = EMF_ERROR_NONE; + emf_mail_attachment_tbl_t *attachment_a_tbl = NULL; + + if (!em_storage_get_attachment(input_mail_id, input_attachment_a_id, &attachment_a_tbl, 1, &err)) { + EM_DEBUG_EXCEPTION("em_storage_get_attachment failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + + if (attachment_a_tbl->attachment_name && input_attachment_b_data->attachment_name) { + EM_DEBUG_LOG("attachment_a_tbl->attachment_name [%s], input_attachment_b_data->name [%s]", attachment_a_tbl->attachment_name, input_attachment_b_data->attachment_name); + *result = strcmp(attachment_a_tbl->attachment_name, input_attachment_b_data->attachment_name); + } + + ret = true; + +FINISH_OFF: + + if (attachment_a_tbl) + em_storage_free_attachment(&attachment_a_tbl, 1, &err_2); + EM_DEBUG_FUNC_END("*result [%d]", *result); + return ret; +} + + +/* description + * copy a mail to mail box + * arguments + * src_mailbox : source mail box + * msgno : mail sequence + * dst_mailbox : target mail box + * return + * succeed : 1 + * fail : 0 + */ +EXPORT_API int em_core_mail_copy(int mail_id, emf_mailbox_t *dst_mailbox, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("mail_id[%d], dst_mailbox[%p], err_code[%p]", mail_id, dst_mailbox, err_code); + + int ret = false; + int err = EMF_ERROR_NONE; + int i; + emf_mail_tbl_t *mail = NULL; + emf_mail_attachment_tbl_t *atch_list = NULL; + char buf[512]; + int count = EMF_ATTACHMENT_MAX_COUNT; + char *mailbox_name = NULL; + + if (!em_storage_get_mail_by_id(mail_id, &mail, true, &err) || !mail) { + EM_DEBUG_EXCEPTION("em_storage_get_mail_by_id failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + + if ( (err = em_storage_get_attachment_list(mail_id, true, &atch_list, &count)) != EM_STORAGE_ERROR_NONE ){ + EM_DEBUG_EXCEPTION("em_storage_get_attachment_list failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + + /* get increased uid. */ + if (!em_storage_increase_mail_id(&mail->mail_id, true, &err)) { + EM_DEBUG_EXCEPTION("em_storage_increase_mail_id failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + + /* copy mail body(text) file */ + if (mail->file_path_plain) { + if (!em_storage_create_dir(dst_mailbox->account_id, mail->mail_id, 0, &err)) { + EM_DEBUG_EXCEPTION("em_storage_create_dir failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + + gchar *filename = g_path_get_basename(mail->file_path_plain); + + if (!em_storage_get_save_name(dst_mailbox->account_id, mail->mail_id, 0, filename, buf, &err)) { + EM_DEBUG_EXCEPTION("em_storage_get_save_name failed [%d]", err); + g_free(filename); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + + g_free(filename); + + if (!em_storage_copy_file(mail->file_path_plain, buf, false, &err)) { + EM_DEBUG_EXCEPTION("em_storage_copy_file failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + + mail->file_path_plain = EM_SAFE_STRDUP(buf); + } + + /* copy mail body(html) file */ + if (mail->file_path_html) { + if (!em_storage_create_dir(dst_mailbox->account_id, mail->mail_id, 0, &err)) { + EM_DEBUG_EXCEPTION("em_storage_create_dir failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + + gchar *filename = g_path_get_basename(mail->file_path_html); + + if (!em_storage_get_save_name(dst_mailbox->account_id, mail->mail_id, 0, filename, buf, &err)) { + EM_DEBUG_EXCEPTION("em_storage_get_save_name failed [%d]", err); + g_free(filename); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + + g_free(filename); + + if (!em_storage_copy_file(mail->file_path_html, buf, false, &err)) { + EM_DEBUG_EXCEPTION("em_storage_copy_file failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + + mail->file_path_html = EM_SAFE_STRDUP(buf); + } + + /* BEGIN TRANSACTION; */ + em_storage_begin_transaction(NULL, NULL, NULL); + + /* insert mail data */ + EM_SAFE_FREE(mail->mailbox_name); + + mail->account_id = dst_mailbox->account_id; /* MUST BE */ + mail->mailbox_name = EM_SAFE_STRDUP(dst_mailbox->name); + mail->mailbox_type = dst_mailbox->mailbox_type; + + if (!em_storage_add_mail(mail, 0, false, &err)) { + EM_DEBUG_EXCEPTION("em_storage_add_mail failed [%d]", err); + + if (mail->file_path_plain) { + if (!em_storage_delete_file(mail->file_path_plain, &err)) { + EM_DEBUG_EXCEPTION("em_storage_delete_file failed [%d]", err); + em_storage_rollback_transaction(NULL, NULL, NULL); + goto FINISH_OFF; + } + } + if (mail->file_path_html) { + if (!em_storage_delete_file(mail->file_path_html, &err)) { + EM_DEBUG_EXCEPTION("em_storage_delete_file failed [%d]", err); + em_storage_rollback_transaction(NULL, NULL, NULL); + goto FINISH_OFF; + } + } + + /* ROLLBACK TRANSACTION; */ + em_storage_rollback_transaction(NULL, NULL, NULL); + + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + + /* copy attachment file */ + for (i = 0; i<count; i++) { + if (atch_list[i].attachment_path) { + if (!em_storage_create_dir(dst_mailbox->account_id, mail->mail_id, i+1, &err)) { + EM_DEBUG_EXCEPTION("em_storage_create_dir failed [%d]", err); + break; + } + + if (!em_storage_get_save_name(dst_mailbox->account_id, mail->mail_id, i+1, atch_list[i].attachment_name, buf, &err)) { + EM_DEBUG_EXCEPTION("em_storage_get_save_name failed [%d]", err); + break; + } + + if (!em_storage_copy_file(atch_list[i].attachment_path, buf, false, &err)) { + EM_DEBUG_EXCEPTION("em_storage_copy_file failed [%d]", err); + break; + } + + EM_SAFE_FREE(atch_list[i].attachment_path); + + atch_list[i].attachment_path = EM_SAFE_STRDUP(buf); + } + + atch_list[i].account_id = dst_mailbox->account_id; + atch_list[i].mail_id = mail->mail_id; + + EM_SAFE_FREE(atch_list[i].mailbox_name); + + atch_list[i].mailbox_name = EM_SAFE_STRDUP(mail->mailbox_name); + + if (!em_storage_add_attachment(&atch_list[i], 0, false, &err)) { + EM_DEBUG_EXCEPTION("em_storage_add_attachment failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + break; + } + } + + /* in case error happened, delete copied file. */ + if (i && i != count) { + for (;i >= 0; i--) { + if (atch_list[i].attachment_path) { + + if (!em_storage_delete_file(atch_list[i].attachment_path, &err)) { + EM_DEBUG_EXCEPTION("em_storage_delete_file failed [%d]", err); + em_storage_rollback_transaction(NULL, NULL, NULL); + goto FINISH_OFF; + } + } + } + + if (mail->file_path_plain) { + if (!em_storage_delete_file(mail->file_path_plain, &err)) { + EM_DEBUG_EXCEPTION("em_storage_delete_file failed [%d]", err); + em_storage_rollback_transaction(NULL, NULL, NULL); + goto FINISH_OFF; + } + } + if (mail->file_path_html) { + if (!em_storage_delete_file(mail->file_path_html, &err)) { + EM_DEBUG_EXCEPTION("em_storage_delete_file failed [%d]", err); + em_storage_rollback_transaction(NULL, NULL, NULL); + goto FINISH_OFF; + } + } + + /* ROLLBACK TRANSACTION; */ + em_storage_rollback_transaction(NULL, NULL, NULL); + goto FINISH_OFF; + } + + if (em_storage_commit_transaction(NULL, NULL, NULL) == false) { + err = em_storage_get_emf_error_from_em_storage_error(EM_STORAGE_ERROR_DB_FAILURE); + if (em_storage_rollback_transaction(NULL, NULL, NULL) == false) + err = em_storage_get_emf_error_from_em_storage_error(EM_STORAGE_ERROR_DB_FAILURE); + goto FINISH_OFF; + } + + if (!em_storage_get_mailboxname_by_mailbox_type(dst_mailbox->account_id, EMF_MAILBOX_TYPE_INBOX, &mailbox_name, false, &err)) { + EM_DEBUG_EXCEPTION("em_storage_get_mailboxname_by_mailbox_type failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + + if (!strcmp(dst_mailbox->name, mailbox_name) && !(mail->flags_seen_field)) + em_core_check_unread_mail(); + + ret = true; + +FINISH_OFF: + if (atch_list != NULL) + em_storage_free_attachment(&atch_list, count, NULL); + + if (mail != NULL) + em_storage_free_mail(&mail, 1, NULL); + + EM_SAFE_FREE(mailbox_name); + + if (err_code != NULL) + *err_code = err; + EM_DEBUG_FUNC_END("err [%d]", err); + return ret; +} + +/* description + * move a mail to mail box + * arguments + * old_mailbox : previous mail box + * msgno : msgno + * new_mailbox : target mail box + * return + * succeed : 1 + * fail : 0 + */ +EXPORT_API int em_core_mail_move(int mail_ids[], int mail_ids_count, char *dst_mailbox_name, int noti_param_1, int noti_param_2 ,int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("mail_ids[%p], mail_ids_count[%d], dst_mailbox_name[%s], noti_param [%d], err_code[%p]", mail_ids, mail_ids_count, dst_mailbox_name, noti_param_1, err_code); + + int ret = false; + int err = EMF_ERROR_NONE; + emf_mail_tbl_t *mail_list = NULL; + int account_id = 0; + int i = 0, parameter_string_length = 0; + char *parameter_string = NULL, mail_id_string[10]; + emf_mail_attachment_tbl_t attachment; + + if (!dst_mailbox_name && mail_ids_count < 1) { + EM_DEBUG_EXCEPTION("EMF_ERROR_INVALID_PARAM"); + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + if (!em_storage_get_mail_field_by_multiple_mail_id(mail_ids, mail_ids_count, RETRIEVE_FLAG, &mail_list, true, &err) || !mail_list) { + EM_DEBUG_EXCEPTION("em_storage_get_mail_field_by_multiple_mail_id failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + + account_id = mail_list[0].account_id; + + if(!em_storage_move_multiple_mails(account_id, dst_mailbox_name, mail_ids, mail_ids_count, true, &err)) { + EM_DEBUG_EXCEPTION("em_storage_move_multiple_mails failed [%d]", err); + goto FINISH_OFF; + } + + /* Sending a notification */ + parameter_string_length = sizeof(char) * (mail_ids_count * 10 + 128/*MAILBOX_LEN_IN_MAIL_TBL*/ * 2); + parameter_string = em_core_malloc(parameter_string_length); + + if (mail_list[0].mailbox_name) + SNPRINTF(parameter_string, parameter_string_length, "%s%c%s%c", mail_list[0].mailbox_name, 0x01, dst_mailbox_name , 0x01); + + if (parameter_string == NULL) { + EM_DEBUG_EXCEPTION("Memory allocation for mail_id_list_string failed"); + err = EMF_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + for (i = 0; i < mail_ids_count; i++) { + memset(mail_id_string, 0, 10); + SNPRINTF(mail_id_string, 10, "%d,", mail_ids[i]); + strcat(parameter_string, mail_id_string); + } + + EM_DEBUG_LOG("num : [%d], param string : [%s]", mail_ids_count , parameter_string); + + if (!em_storage_notify_storage_event(NOTI_MAIL_MOVE, account_id, noti_param_1, parameter_string, noti_param_2)) + EM_DEBUG_EXCEPTION(" em_storage_notify_storage_event failed [NOTI_MAIL_MOVE] >>>> "); + + /* Upating thread mail info should be done as soon as possible */ + attachment.mailbox_name = dst_mailbox_name; + + for (i = 0; i < mail_ids_count; i++) { + if (!em_storage_update_latest_thread_mail(account_id, mail_list[i].thread_id, 0, 0, true, &err)) + EM_DEBUG_EXCEPTION("em_storage_update_latest_thread_mail failed [%d]", err); + } + + if (!em_storage_notify_storage_event(NOTI_MAIL_MOVE_FINISH, account_id, noti_param_1, parameter_string, noti_param_2)) + EM_DEBUG_EXCEPTION(" em_storage_notify_storage_event failed [NOTI_MAIL_MOVE_FINISH] >>>> "); + + em_core_check_unread_mail(); + + ret = true; + +FINISH_OFF: + em_storage_free_mail(&mail_list, mail_ids_count, NULL); + EM_SAFE_FREE(parameter_string); + if (err_code != NULL) + *err_code = err; + EM_DEBUG_FUNC_END("err [%d]", err); + return ret; +} + + +EXPORT_API int em_core_mail_move_from_server(int account_id, char *src_mailbox, int mail_ids[], int num, char *dest_mailbox, int *error_code) +{ + EM_DEBUG_FUNC_BEGIN(); + MAILSTREAM *stream = NULL; + int err_code = 0; + emf_account_t *ref_account = NULL; + emf_mail_tbl_t *mail = NULL; + int ret = 1; + int mail_id = 0; + int i = 0; + + mail_id = mail_ids[0]; + + ref_account = em_core_get_account_reference(account_id); + if (!ref_account) { + EM_DEBUG_EXCEPTION("em_core_mail_move_from_server failed : get account reference[%d]", account_id); + *error_code = EMF_ERROR_INVALID_ACCOUNT; + ret = 0; + goto FINISH_OFF; + } + + /* if not imap4 mail, return */ + if (ref_account->account_bind_type != EMF_BIND_TYPE_EM_CORE || + ref_account->receiving_server_type != EMF_SERVER_TYPE_IMAP4) { + *error_code = EMF_ERROR_INVALID_PARAM; + ret = 0; + goto FINISH_OFF; + } + + for (i = 0; i < num; i++) { + mail_id = mail_ids[i]; + + if (!em_storage_get_mail_by_id(mail_id, &mail, false, &err_code) || !mail) { + EM_DEBUG_EXCEPTION("em_storage_get_uid_by_mail_id : em_storage_get_downloaded_mail failed [%d]", err_code); + mail = NULL; + if (err_code == EM_STORAGE_ERROR_MAIL_NOT_FOUND) { /* not server mail */ + /* err = EMF_ERROR_MAIL_NOT_FOUND_ON_SERVER; */ + /* continue; */ + } + else { + *error_code = em_storage_get_emf_error_from_em_storage_error(err_code); + } + + ret = 0; + goto FINISH_OFF; + } + + if (!em_core_mailbox_open(account_id, src_mailbox, (void **)&stream, &err_code)) /* faizan.h@samsung.com mail_move_fix_07042009 */ { + EM_DEBUG_EXCEPTION("em_core_mail_move_from_server failed : Mailbox open[%d]", err_code); + + ret = 0; + goto FINISH_OFF; + } + + if (stream) { + /* set callback for COPY_UID */ + mail_parameters(stream, SET_COPYUID, em_core_mail_copyuid); + + EM_DEBUG_LOG("calling mail_copy_full FODLER MAIL COPY "); + + if (mail->server_mail_id) { + if (!mail_copy_full(stream, mail->server_mail_id, dest_mailbox, CP_UID | CP_MOVE)) { + EM_DEBUG_EXCEPTION("em_core_mail_move_from_server : Mail cannot be moved failed"); + ret = 0; + } + else { + /* send EXPUNGE command */ + if (!imap4_send_command(stream, IMAP4_CMD_EXPUNGE, &err_code)) { + EM_DEBUG_EXCEPTION("imap4_send_command failed [%d]", err_code); + + if (err_code == EMF_ERROR_IMAP4_STORE_FAILURE) + err_code = EMF_ERROR_MAIL_NOT_FOUND_ON_SERVER; + goto FINISH_OFF; + } + + /* faizan.h@samsung.com duplicate copy while sync mailbox issue fixed */ + EM_DEBUG_LOG(">>>mailbox_name[%s]>>>>>>", mail->mailbox_name); + EM_DEBUG_LOG(">>>g_new_server_uid[%s]>>>>>>", g_new_server_uid); + EM_DEBUG_LOG(">>>mail_id[%d]>>>>>>", mail_id); + + if (!em_storage_update_read_mail_uid(mail_id, g_new_server_uid, mail->mailbox_name, &err_code)) { + EM_DEBUG_EXCEPTION("em_storage_update_read_mail_uid failed [%d]", err_code); + goto FINISH_OFF; + } + + EM_DEBUG_LOG("Mail MOVE SUCCESS "); + } + } + else + EM_DEBUG_EXCEPTION(">>>> Server MAIL ID IS NULL >>>> "); + } + else { + EM_DEBUG_EXCEPTION(">>>> STREAM DATA IS NULL >>> "); + ret = 0; + goto FINISH_OFF; + } + } + + /* ret = true; */ + +FINISH_OFF: + if (stream) em_core_mailbox_close(account_id, stream); + + if (mail != NULL) + em_storage_free_mail(&mail, 1, NULL); + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +static int em_core_mail_save_file(int account_id, int mail_id, int attachment_id, char *src_file_path, char *file_name, char *full_path, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id[%d], mail_id[%d], attachment_id[%d] , file_name[%p] , full_path[%p] , err_code[%p]", account_id, mail_id, attachment_id, file_name, full_path, err_code); + + int ret = false, err = EMF_ERROR_NONE; + + if (!file_name || !full_path || !src_file_path) { + EM_DEBUG_EXCEPTION("Invalid paramter"); + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + if (!em_storage_create_dir(account_id, mail_id, attachment_id, &err)) { + EM_DEBUG_EXCEPTION("em_storage_create_dir failed [%d]", err); + goto FINISH_OFF; + } + + if (!em_storage_get_save_name(account_id, mail_id, attachment_id, file_name, full_path, &err)) { + EM_DEBUG_EXCEPTION("em_storage_get_save_name failed [%d]", err); + goto FINISH_OFF; + } + + if (strcmp(src_file_path, full_path) != 0) { + if (!em_storage_copy_file(src_file_path, full_path, false, &err)) { + EM_DEBUG_EXCEPTION("em_storage_copy_file failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + } + + ret = true; + +FINISH_OFF: + if (err_code) + *err_code = err; + return 1; +} + +/* description + * update mail information + * arguments + * mailbox : mail box + * mail_id : mail id to be updated + * mail : updating mail header, body, flags, extra_flags + * return + * succeed : 1 + * fail : 0 + */ +EXPORT_API int em_core_mail_update_old(int mail_id, emf_mail_t *src_mail, emf_meeting_request_t *src_meeting_req, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("mail_id[%d], mail[%p], err_code[%p]", mail_id, src_mail, err_code); + + int ret = false, err = EMF_ERROR_NONE; + int local_attachment_count = 0, local_inline_content_count = 0; + emf_mail_tbl_t mail_table_data = {0}; + emf_attachment_info_t *attachment_info = NULL; + char filename_buf[1024] = {0, }, buf_date[512] = {0, }; + char html_body[MAX_PATH] = {0, }; + + if (!mail_id || !src_mail || !src_mail->info || !src_mail->head) { + EM_DEBUG_EXCEPTION("Invalid parameter"); + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF2; + } + + mail_table_data.full_address_from = src_mail->head->from; + mail_table_data.full_address_reply = src_mail->head->reply_to; + mail_table_data.full_address_to = src_mail->head->to; + mail_table_data.full_address_cc = src_mail->head->cc; + mail_table_data.full_address_bcc = src_mail->head->bcc; + mail_table_data.full_address_return = src_mail->head->return_path; + mail_table_data.subject = src_mail->head->subject; + mail_table_data.preview_text = src_mail->head->previewBodyText ; + mail_table_data.body_download_status = src_mail->info->body_downloaded; + mail_table_data.mailbox_name = NULL; /* UPDATE_MAIL type couldn't change mailbox. */ + mail_table_data.priority = src_mail->info->extra_flags.priority; + mail_table_data.report_status = src_mail->info->extra_flags.report; + mail_table_data.save_status = src_mail->info->extra_flags.status; + mail_table_data.lock_status = src_mail->info->extra_flags.lock; + mail_table_data.DRM_status = src_mail->info->extra_flags.drm; + mail_table_data.mail_size = src_mail->info->rfc822_size; + + if(mail_table_data.mail_size == 0) + mail_table_data.mail_size = em_core_get_mail_size(src_mail, &err); + + if (!mail_table_data.full_address_from) { + emf_account_t *ref_account = NULL; + if (!(ref_account = em_core_get_account_reference(src_mail->info->account_id))) { + EM_DEBUG_EXCEPTION("em_core_get_account_reference failed [%d]", src_mail->info->account_id); + err = EMF_ERROR_INVALID_ACCOUNT; + goto FINISH_OFF2; + } + mail_table_data.full_address_from = ref_account->email_addr; + } + + if(!em_convert_mail_flag_to_mail_tbl(&(src_mail->info->flags), &mail_table_data, &err)) { + EM_DEBUG_EXCEPTION("em_convert_mail_flag_to_mail_tbl failed [%d]", err); + goto FINISH_OFF2; + } + + if (src_mail->body && src_mail->body->plain) { /* Save plain text body. */ + if (!em_core_mail_save_file(src_mail->info->account_id, mail_id, 0, src_mail->body->plain, src_mail->body->plain_charset ? src_mail->body->plain_charset : "UTF-8", filename_buf, &err)) { + EM_DEBUG_EXCEPTION("em_core_mail_save_file failed [%d]", err); + goto FINISH_OFF2; + } + mail_table_data.file_path_plain = EM_SAFE_STRDUP(filename_buf); + } + else + mail_table_data.file_path_plain = NULL; + + if (src_mail->body && src_mail->body->html) { /* Save HTML text body. */ + if (src_mail->body->plain_charset != NULL && src_mail->body->plain_charset[0] != '\0') { + memcpy(html_body, src_mail->body->plain_charset, strlen(src_mail->body->plain_charset)); + strcat(html_body, ".htm"); + } + else + memcpy(html_body, "UTF-8.htm", strlen("UTF-8.htm")); + if (!em_core_mail_save_file(src_mail->info->account_id, mail_id, 0, src_mail->body->html, html_body, filename_buf, &err)) { + EM_DEBUG_EXCEPTION("em_core_mail_save_file failed [%d]", err); + goto FINISH_OFF2; + } + mail_table_data.file_path_html = EM_SAFE_STRDUP(filename_buf); + } + else + mail_table_data.file_path_html = NULL; + + if (src_mail->body && src_mail->body->attachment) { + int compare_result = 1; + char attachment_id[20]; + + attachment_info = src_mail->body->attachment; + do { + if (!em_core_mail_compare_filename_of_attachment(mail_id, attachment_info->attachment_id, attachment_info, &compare_result, &err)) { + EM_DEBUG_EXCEPTION("em_core_mail_compare_filename_of_attachment failed [%d]", err); + compare_result = 1; + } + + if (compare_result == 0) { + EM_DEBUG_LOG("file name and attachment id are same, update exising attachment"); + if (!em_core_mail_update_attachment(mail_id, attachment_info, &err)) { + EM_DEBUG_EXCEPTION("em_core_mail_update_attachment failed [%d]", err); + goto FINISH_OFF2; + } + } + else { + EM_DEBUG_LOG("save names are different"); + SNPRINTF(attachment_id, sizeof(attachment_id), "%d", attachment_info->attachment_id); + + if(attachment_info->attachment_id > 0) { + if (!em_core_mail_delete_attachment(mail_id, attachment_id, &err)) { + EM_DEBUG_EXCEPTION("em_core_mail_delete_attachment failed [%d]", err); + goto FINISH_OFF2; + } + } + + if (!em_core_mail_add_attachment(mail_id, attachment_info, &err)) { + EM_DEBUG_EXCEPTION("em_core_mail_add_attachment failed [%d]", err); + goto FINISH_OFF2; + } + } + + if (attachment_info->inline_content) + local_inline_content_count++; + local_attachment_count++; + attachment_info = attachment_info->next; + } + while (attachment_info != NULL); + } + + mail_table_data.attachment_count = local_attachment_count; + mail_table_data.inline_content_count = local_inline_content_count; + + if (!src_mail->head->datetime.year && !src_mail->head->datetime.month && !src_mail->head->datetime.day) { + time_t t = time(NULL); + struct tm *p_tm = localtime(&t); + + if (!p_tm) { + EM_DEBUG_EXCEPTION("localtime failed..."); + err = EM_STORAGE_ERROR_SYSTEM_FAILURE; + goto FINISH_OFF2; + } + + SNPRINTF(buf_date, sizeof(buf_date), "%04d%02d%02d%02d%02d%02d", + p_tm->tm_year + 1900, + p_tm->tm_mon + 1, + p_tm->tm_mday, + p_tm->tm_hour, + p_tm->tm_min, + p_tm->tm_sec); + } + else { + SNPRINTF(buf_date, sizeof(buf_date), "%04d%02d%02d%02d%02d%02d", + src_mail->head->datetime.year, + src_mail->head->datetime.month, + src_mail->head->datetime.day, + src_mail->head->datetime.hour, + src_mail->head->datetime.minute, + src_mail->head->datetime.second); + } + + mail_table_data.datetime = buf_date; + + EM_DEBUG_LOG("preview_text[%p]", mail_table_data.preview_text); + if (mail_table_data.preview_text == NULL) { + if ( (err = em_core_get_preview_text_from_file(mail_table_data.file_path_plain, mail_table_data.file_path_html, MAX_PREVIEW_TEXT_LENGTH, &(mail_table_data.preview_text))) != EMF_ERROR_NONE) { + EM_DEBUG_EXCEPTION("em_core_get_preview_text_from_file failed[%d]", err); + goto FINISH_OFF2; + } + } + + mail_table_data.meeting_request_status = src_mail->info->is_meeting_request; + + /* BEGIN TRANSACTION; */ + em_storage_begin_transaction(NULL, NULL, NULL); + + if (!em_storage_change_mail_field(mail_id, UPDATE_MAIL, &mail_table_data, false, &err)) { + EM_DEBUG_EXCEPTION("em_storage_change_mail_field failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + + if (src_mail->info->is_meeting_request == EMF_MAIL_TYPE_MEETING_REQUEST + || src_mail->info->is_meeting_request == EMF_MAIL_TYPE_MEETING_RESPONSE + || src_mail->info->is_meeting_request == EMF_MAIL_TYPE_MEETING_ORIGINATINGREQUEST) { + emf_meeting_request_t *meeting_req = NULL; + /* check where there is a meeting request in DB */ + if (!em_storage_get_meeting_request(mail_id, &meeting_req, false, &err) && err != EM_STORAGE_ERROR_DATA_NOT_FOUND) { + EM_DEBUG_EXCEPTION("em_storage_get_meeting_request failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + EM_SAFE_FREE(meeting_req); + if (err == EM_STORAGE_ERROR_DATA_NOT_FOUND) { /* insert */ + emf_mail_tbl_t *original_mail = NULL; + + if (!em_storage_get_mail_by_id(mail_id, &original_mail, false, &err)) { + EM_DEBUG_EXCEPTION("em_storage_get_mail_by_id failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + + if (original_mail) { + if (!em_storage_add_meeting_request(src_mail->info->account_id, original_mail->mailbox_name, src_meeting_req, false, &err)) { + EM_DEBUG_EXCEPTION("em_storage_add_meeting_request failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + em_storage_free_mail(&original_mail, 1, NULL); + } + } + else { /* update */ + if (!em_storage_update_meeting_request(src_meeting_req, false, &err)) { + EM_DEBUG_EXCEPTION("em_storage_update_meeting_request failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + } + } + + ret = true; + +FINISH_OFF: + if (ret == true) { /* COMMIT TRANSACTION; */ + if (em_storage_commit_transaction(NULL, NULL, NULL) == false) { + err = em_storage_get_emf_error_from_em_storage_error(EM_STORAGE_ERROR_DB_FAILURE); + ret = false; + } + /* publish a notification : to Active Sync Engine */ + if (!em_storage_notify_storage_event(NOTI_MAIL_UPDATE, src_mail->info->account_id, mail_id, NULL, UPDATE_MEETING)) + EM_DEBUG_EXCEPTION(" em_storage_notify_storage_event failed [ NOTI_MAIL_UPDATE : UPDATE_MEETING_RESPONSE ] >>>> "); + } + else { /* ROLLBACK TRANSACTION; */ + if (em_storage_rollback_transaction(NULL, NULL, NULL) == false) + err = em_storage_get_emf_error_from_em_storage_error(EM_STORAGE_ERROR_DB_FAILURE); + } + +FINISH_OFF2: + + EM_SAFE_FREE(mail_table_data.file_path_plain); + EM_SAFE_FREE(mail_table_data.file_path_html); + + if (err_code != NULL) + *err_code = err; + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + + +/* description + * update mail information + * 'em_core_mail_update_old' will be replaced with this function. + */ +EXPORT_API int em_core_update_mail(emf_mail_data_t *input_mail_data, emf_attachment_data_t *input_attachment_data_list, int input_attachment_count, emf_meeting_request_t* input_meeting_request, int input_sync_server) +{ + EM_DEBUG_FUNC_BEGIN("input_mail_data[%p], input_attachment_data_list[%p], input_attachment_count[%d], input_meeting_request[%p], input_sync_server[%d]", input_mail_data, input_attachment_data_list, input_attachment_count, input_meeting_request, input_sync_server); + + char filename_buf[1024] = {0, }; + int i = 0; + int err = EMF_ERROR_NONE; + int local_inline_content_count = 0; + emf_mail_tbl_t *converted_mail_tbl_data = NULL; + struct stat st_buf; + + + if (!input_mail_data || (input_attachment_count && !input_attachment_data_list) || (!input_attachment_count &&input_attachment_data_list)) { + EM_DEBUG_EXCEPTION("EMF_ERROR_INVALID_PARAM"); + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF2; + } + + if(input_sync_server) { + if (input_mail_data->file_path_plain) { + if (stat(input_mail_data->file_path_plain, &st_buf) < 0) { + EM_DEBUG_EXCEPTION("input_mail_data->file_path_plain, stat(\"%s\") failed...", input_mail_data->file_path_plain); + err = EMF_ERROR_INVALID_MAIL; + goto FINISH_OFF; + } + } + + if (input_mail_data->file_path_html) { + if (stat(input_mail_data->file_path_html, &st_buf) < 0) { + EM_DEBUG_EXCEPTION("input_mail_data->file_path_html, stat(\"%s\") failed...", input_mail_data->file_path_html); + err = EMF_ERROR_INVALID_MAIL; + goto FINISH_OFF; + } + } + + if (input_attachment_count && input_attachment_data_list) { + for (i = 0; i < input_attachment_count; i++) { + if (input_attachment_data_list[i].save_status) { + if (!input_attachment_data_list[i].attachment_path || stat(input_attachment_data_list[i].attachment_path, &st_buf) < 0) { + EM_DEBUG_EXCEPTION("stat(\"%s\") failed...", input_attachment_data_list[i].attachment_path); + err = EMF_ERROR_INVALID_ATTACHMENT; + goto FINISH_OFF; + } + } + } + } + } + + if(input_mail_data->mail_size == 0) { + em_core_calc_mail_size(input_mail_data, input_attachment_data_list, input_attachment_count, &(input_mail_data->mail_size)); + } + + if (!input_mail_data->full_address_from) { + emf_account_t *ref_account = NULL; + if (!(ref_account = em_core_get_account_reference(input_mail_data->account_id))) { + EM_DEBUG_EXCEPTION("em_core_get_account_reference failed [%d]", input_mail_data->account_id); + err = EMF_ERROR_INVALID_ACCOUNT; + goto FINISH_OFF2; + } + input_mail_data->full_address_from = ref_account->email_addr; + } + + if (input_mail_data->file_path_plain) { /* Save plain text body. */ + if (!em_core_mail_save_file(input_mail_data->account_id, input_mail_data->mail_id, 0, input_mail_data->file_path_plain, "UTF-8", filename_buf, &err)) { + EM_DEBUG_EXCEPTION("em_core_mail_save_file failed [%d]", err); + goto FINISH_OFF2; + } + EM_SAFE_FREE(input_mail_data->file_path_plain); + input_mail_data->file_path_plain = EM_SAFE_STRDUP(filename_buf); + } + + if (input_mail_data->file_path_html) { /* Save HTML text body. */ + if (!em_core_mail_save_file(input_mail_data->account_id, input_mail_data->mail_id, 0, input_mail_data->file_path_html, "UTF-8.htm", filename_buf, &err)) { + EM_DEBUG_EXCEPTION("em_core_mail_save_file failed [%d]", err); + goto FINISH_OFF2; + } + EM_SAFE_FREE(input_mail_data->file_path_html); + input_mail_data->file_path_html = EM_SAFE_STRDUP(filename_buf); + } + + if (input_attachment_data_list && input_attachment_count) { + int i = 0; + int compare_result = 1; + char attachment_id[20]; + emf_attachment_data_t *temp_attachment_data = NULL; + + for(i = 0; i < input_attachment_count; i++) { + temp_attachment_data = input_attachment_data_list + i; + if ( (err = em_core_mail_compare_filename_of_attachment_data(input_mail_data->mail_id, temp_attachment_data->attachment_id, temp_attachment_data, &compare_result)) != EMF_ERROR_NONE) { + EM_DEBUG_EXCEPTION("em_core_mail_compare_filename_of_attachment failed [%d]", err); + compare_result = 1; + } + + if (compare_result == 0) { + EM_DEBUG_LOG("file name and attachment id are same, update exising attachment"); + if (!em_core_mail_update_attachment_data(input_mail_data->mail_id, temp_attachment_data)) { + EM_DEBUG_EXCEPTION("em_core_mail_update_attachment failed [%d]", err); + goto FINISH_OFF2; + } + } + else { + EM_DEBUG_LOG("save names are different"); + SNPRINTF(attachment_id, sizeof(attachment_id), "%d", temp_attachment_data->attachment_id); + + if(temp_attachment_data->attachment_id > 0) { + if (!em_core_mail_delete_attachment(input_mail_data->mail_id, attachment_id, &err)) { + EM_DEBUG_EXCEPTION("em_core_mail_delete_attachment failed [%d]", err); + goto FINISH_OFF2; + } + } + + if ( (err = em_core_mail_add_attachment_data(input_mail_data->mail_id, temp_attachment_data)) != EMF_ERROR_NONE) { + EM_DEBUG_EXCEPTION("em_core_mail_add_attachment failed [%d]", err); + goto FINISH_OFF2; + } + } + + if (temp_attachment_data->inline_content_status) + local_inline_content_count++; + } + } + + input_mail_data->attachment_count = input_attachment_count; + input_mail_data->inline_content_count = local_inline_content_count; + + if (!input_mail_data->datetime) { + /* time isn't set */ + input_mail_data->datetime = em_core_get_current_time_string(&err); + if(!input_mail_data->datetime) { + EM_DEBUG_EXCEPTION("em_core_get_current_time_string failed [%d]", err); + goto FINISH_OFF; + } + } + + EM_DEBUG_LOG("preview_text[%p]", input_mail_data->preview_text); + if (input_mail_data->preview_text == NULL) { + if ( (err =em_core_get_preview_text_from_file(input_mail_data->file_path_plain, input_mail_data->file_path_html, MAX_PREVIEW_TEXT_LENGTH, &(input_mail_data->preview_text))) != EMF_ERROR_NONE) { + EM_DEBUG_EXCEPTION("em_core_get_preview_text_from_file failed[%d]", err); + goto FINISH_OFF2; + } + } + + if(!em_convert_mail_data_to_mail_tbl(input_mail_data, 1, &converted_mail_tbl_data, &err)) { + EM_DEBUG_EXCEPTION("em_convert_mail_data_to_mail_tbl failed[%d]", err); + goto FINISH_OFF2; + } + + /* BEGIN TRANSACTION; */ + em_storage_begin_transaction(NULL, NULL, NULL); + + if (!em_storage_change_mail_field(input_mail_data->mail_id, UPDATE_MAIL, converted_mail_tbl_data, false, &err)) { + EM_DEBUG_EXCEPTION("em_storage_change_mail_field failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + + if (input_mail_data->meeting_request_status == EMF_MAIL_TYPE_MEETING_REQUEST + || input_mail_data->meeting_request_status == EMF_MAIL_TYPE_MEETING_RESPONSE + || input_mail_data->meeting_request_status == EMF_MAIL_TYPE_MEETING_ORIGINATINGREQUEST) { + emf_meeting_request_t *meeting_req = NULL; + /* check where there is a meeting request in DB */ + if (!em_storage_get_meeting_request(input_mail_data->mail_id, &meeting_req, false, &err) && err != EM_STORAGE_ERROR_DATA_NOT_FOUND) { + EM_DEBUG_EXCEPTION("em_storage_get_meeting_request failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + EM_SAFE_FREE(meeting_req); + if (err == EM_STORAGE_ERROR_DATA_NOT_FOUND) { /* insert */ + emf_mail_tbl_t *original_mail = NULL; + + if (!em_storage_get_mail_by_id(input_mail_data->mail_id, &original_mail, false, &err)) { + EM_DEBUG_EXCEPTION("em_storage_get_mail_by_id failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + + if (original_mail) { + if (!em_storage_add_meeting_request(input_mail_data->account_id, original_mail->mailbox_name, input_meeting_request, false, &err)) { + EM_DEBUG_EXCEPTION("em_storage_add_meeting_request failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + em_storage_free_mail(&original_mail, 1, NULL); + } + } + else { /* update */ + if (!em_storage_update_meeting_request(input_meeting_request, false, &err)) { + EM_DEBUG_EXCEPTION("em_storage_update_meeting_request failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + } + } + +FINISH_OFF: + if (err == EMF_ERROR_NONE) { + /* COMMIT TRANSACTION; */ + if (em_storage_commit_transaction(NULL, NULL, NULL) == false) { + err = em_storage_get_emf_error_from_em_storage_error(EM_STORAGE_ERROR_DB_FAILURE); + } + + if (input_meeting_request && !em_storage_notify_storage_event(NOTI_MAIL_UPDATE, input_mail_data->account_id, input_mail_data->mail_id, NULL, UPDATE_MEETING)) + EM_DEBUG_EXCEPTION(" em_storage_notify_storage_event failed [ NOTI_MAIL_UPDATE : UPDATE_MEETING_RESPONSE ] >>>> "); + } + else { + /* ROLLBACK TRANSACTION; */ + if (em_storage_rollback_transaction(NULL, NULL, NULL) == false) + err = em_storage_get_emf_error_from_em_storage_error(EM_STORAGE_ERROR_DB_FAILURE); + } + +FINISH_OFF2: + if(converted_mail_tbl_data) + em_storage_free_mail(&converted_mail_tbl_data, 1, NULL); + + EM_DEBUG_FUNC_END("err [%d]", err); + return err; +} + +EXPORT_API int em_core_fetch_flags(int account_id, int mail_id, emf_mail_flag_t *mail_flag, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN(); + + int ret = false; + int err = 0; + emf_mail_tbl_t *mail = NULL; + + EM_IF_NULL_RETURN_VALUE(mail_flag, false); + if (account_id < FIRST_ACCOUNT_ID || mail_id < 1) { + EM_DEBUG_EXCEPTION("em_core_fetch_flags : Invalid Param "); + goto FINISH_OFF; + } + + if (!em_storage_get_mail_field_by_id(mail_id, RETRIEVE_FLAG, &mail, true, &err) || !mail) { + EM_DEBUG_EXCEPTION("em_storage_get_mail_field_by_id failed - %d ", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + + if (!em_convert_mail_tbl_to_mail_flag(mail, mail_flag, &err)) { + EM_DEBUG_EXCEPTION("em_convert_mail_flag_to_int failed - %d ", err); + goto FINISH_OFF; + } + + ret = true; + +FINISH_OFF: + if(mail) + em_storage_free_mail(&mail, 1, &err); + + if (err_code != NULL) + *err_code = err; + + EM_DEBUG_FUNC_END("err [%d]", err); + return ret; +} +/* description : modify flag of msgno. + return 1(success), 0(failure) + */ +EXPORT_API int em_core_mail_modify_flag(int mail_id, emf_mail_flag_t new_flag, int sticky_flag, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("mail_id[%d], err_code[%p]", mail_id, err_code); + + int ret = false; + int err = EMF_ERROR_NONE; + int old_seen, new_seen; + + emf_mail_tbl_t *mail = NULL; + emf_mail_flag_t old_flag; + + if (!em_storage_get_mail_field_by_id(mail_id, RETRIEVE_FLAG, &mail, true, &err) || !mail) { + EM_DEBUG_EXCEPTION("em_storage_get_mail_field_by_id failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + + if (!em_convert_mail_tbl_to_mail_flag(mail, &old_flag, &err)) { + EM_DEBUG_EXCEPTION("em_convert_mail_tbl_to_mail_flag failed [%d]", err); + goto FINISH_OFF; + } + + old_seen = mail->flags_seen_field; + new_seen = new_flag.seen; + + if (!em_convert_mail_flag_to_mail_tbl(&new_flag, mail, &err)) { + EM_DEBUG_EXCEPTION("em_convert_mail_flag_to_mail_tbl failed [%d]", err); + goto FINISH_OFF; + } + + mail->lock_status = sticky_flag; + + if (!em_storage_change_mail_field(mail_id, UPDATE_FLAG, mail, true, &err)) { + EM_DEBUG_EXCEPTION("em_storage_change_mail_field failed [%d]", err); + + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + + if (old_seen != new_seen && new_seen == 0) + em_core_delete_notification_for_read_mail(mail_id); + + em_core_check_unread_mail(); + + ret = true; + +FINISH_OFF: + if (mail) + em_storage_free_mail(&mail, 1, NULL); + + if (err_code) + *err_code = err; + EM_DEBUG_FUNC_END("err [%d]", err); + return ret; +} + +EXPORT_API int em_core_mail_set_flags_field(int account_id, int mail_ids[], int num, emf_flags_field_type field_type, int value, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id [%d], mail_ids[%p], num [%d], field_type [%d], value[%d], err_code[%p]", account_id, mail_ids, num, field_type, value, err_code); + + int ret = false; + int err = EMF_ERROR_NONE; + char *field_type_name[EMF_FLAGS_FIELD_COUNT] = { "flags_seen_field" + , "flags_deleted_field", "flags_flagged_field", "flags_answered_field" + , "flags_recent_field", "flags_draft_field", "flags_forwarded_field" }; + + if(field_type < 0 || field_type >= EMF_FLAGS_FIELD_COUNT || mail_ids == NULL || num <= 0 || account_id == 0) { + EM_DEBUG_EXCEPTION("EMF_ERROR_INVALID_PARAM"); + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + if (!em_storage_set_field_of_mails_with_integer_value(account_id, mail_ids, num, field_type_name[field_type], value, true, &err)) { + EM_DEBUG_EXCEPTION("em_storage_set_field_of_mails_with_integer_value failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + + em_core_check_unread_mail(); + + ret = true; + +FINISH_OFF: + + if (err_code) + *err_code = err; + EM_DEBUG_FUNC_END("err [%d]", err); + return ret; +} + + +/* description : modify extra flag of msgno. + return 0(success), -1(failure) + */ +EXPORT_API int em_core_mail_modify_extra_flag(int mail_id, emf_extra_flag_t new_flag, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("mail_id[%d], err_code[%p]", mail_id, err_code); + + int ret = false; + int err = EMF_ERROR_NONE; + emf_mail_tbl_t mail; + + memset(&mail, 0x00, sizeof(emf_mail_tbl_t)); + + mail.mail_id = mail_id; + mail.save_status = new_flag.status; + mail.lock_status = new_flag.report; + mail.lock_status = new_flag.lock; + mail.priority = new_flag.priority; + mail.DRM_status = new_flag.drm; + + if (!em_storage_change_mail_field(mail_id, UPDATE_EXTRA_FLAG, &mail, false, &err)) { + EM_DEBUG_EXCEPTION("em_storage_change_mail_field failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + + ret = true; + +FINISH_OFF: + if (err_code != NULL) + *err_code = err; + EM_DEBUG_FUNC_END("err [%d]", err); + return ret; +} + + +int em_core_mail_cmd_read_mail_pop3(void *stream, int msgno, int limited_size, int *downloded_size, int *result_total_body_size, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("stream[%p], msgno[%d], limited_size[%d], err_code[%p]", stream, msgno, limited_size, err_code); + + int ret = false; + int err = EMF_ERROR_NONE; + int total_body_size = 0; + char command[32]; + char *response = NULL; + POP3LOCAL *pop3local; + + if (!stream || !result_total_body_size) { + EM_DEBUG_EXCEPTION("stream[%p], total_body_size[%p]", stream, msgno, result_total_body_size); + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + pop3local = (POP3LOCAL *)(((MAILSTREAM *)stream)->local); + + if (!pop3local || !pop3local->netstream) { + err = EMF_ERROR_INVALID_STREAM; + goto FINISH_OFF; + } + memset(command, 0x00, sizeof(command)); + + SNPRINTF(command, sizeof(command), "LIST %d\015\012", msgno); + +#ifdef FEATURE_CORE_DEBUG + EM_DEBUG_LOG("[POP3] >>> [%s]", command); +#endif + + + /* send command : LIST [msgno] - to get the size of the mail */ + if (!net_sout(pop3local->netstream, command, (int)strlen(command))) { + EM_DEBUG_EXCEPTION("net_sout failed..."); + + err = EMF_ERROR_INVALID_RESPONSE; + goto FINISH_OFF; + } + + EM_DEBUG_LOG("Sending command success"); + + while (pop3local->netstream) { + /* receive response */ + if (!(response = net_getline(pop3local->netstream))) + break; + + if (response) + EM_DEBUG_LOG("[POP3] <<< %s", response); + + if (*response == '.') { + EM_SAFE_FREE(response); + break; + } + + if (*response == '+') { /* "+ OK" */ + char *p = NULL; + + if (!(p = strchr(response + strlen("+OK "), ' '))) { + err = EMF_ERROR_INVALID_RESPONSE; + goto FINISH_OFF; + } + + total_body_size = atoi(p + 1); + EM_DEBUG_LOG("Body size [%d]", total_body_size); + + if (result_total_body_size) { + *result_total_body_size = total_body_size; + break; + } + } + else if (*response == '-') { /* "- ERR" */ + err = EMF_ERROR_INVALID_RESPONSE; + goto FINISH_OFF; + } + else { + err = EMF_ERROR_INVALID_RESPONSE; + goto FINISH_OFF; + } + + EM_SAFE_FREE(response); + } + + memset(command, 0x00, sizeof(command)); + + if (limited_size && total_body_size > limited_size) { + int count_of_line = limited_size / 80; + SNPRINTF(command, sizeof(command), "TOP %d %d", msgno, count_of_line); + } + else + SNPRINTF(command, sizeof(command), "RETR %d", msgno); + + EM_DEBUG_LOG("[POP3] >>> %s", command); + + em_core_set_network_error(EMF_ERROR_NONE); /* set current network error as EMF_ERROR_NONE before network operation */ + /* get mail from mail server */ + if (!pop3_send((MAILSTREAM *)stream, command, NULL)) { + EM_DEBUG_EXCEPTION("pop3_send failed..."); + + emf_session_t *session = NULL; + + if (!em_core_get_current_session(&session)) { + EM_DEBUG_EXCEPTION("em_core_get_current_session failed..."); + err = EMF_ERROR_SESSION_NOT_FOUND; + goto FINISH_OFF; + } + + if (session->network == EMF_ERROR_NONE) + err = EMF_ERROR_UNKNOWN; + else + err = session->network; + + goto FINISH_OFF; + } + + ret = true; + +FINISH_OFF: + EM_SAFE_FREE(response); + + if (err_code != NULL) + *err_code = err; + EM_DEBUG_FUNC_END("err [%d]", err); + return ret; +} + + +EXPORT_API int em_core_mail_sync_flag_with_server(int mail_id, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("mail_id[%p], err_code[%p]", mail_id, err_code); + + if (mail_id < 1) { + if (err_code != NULL) + *err_code = EMF_ERROR_INVALID_PARAM; + return false; + } + + int ret = false; + int err = EMF_ERROR_NONE; + int status = EMF_DOWNLOAD_FAIL; + MAILSTREAM *stream = NULL; + emf_mailbox_t mbox = {0}; + emf_mail_tbl_t *mail = NULL; + emf_account_t *ref_account = NULL; + int account_id = 0; + int msgno = 0; + emf_mail_flag_t new_flag = {0}; + char set_flags[100] = { 0, }; + char clear_flags[100] = { 0, }; + char tmp[100] = { 0, }; + + if (!em_core_check_thread_status()) { + err = EMF_ERROR_CANCELLED; + goto FINISH_OFF; + } + + if (!em_storage_get_mail_by_id(mail_id, &mail, true, &err) || !mail) { + EM_DEBUG_EXCEPTION("em_storage_get_mail_by_id failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + + account_id = mail->account_id; + em_convert_mail_tbl_to_mail_flag(mail, &new_flag, NULL); + + if (!(ref_account = em_core_get_account_reference(account_id))) { + EM_DEBUG_EXCEPTION("em_core_get_account_reference failed [%d]", account_id); + err = EMF_ERROR_INVALID_ACCOUNT; + goto FINISH_OFF; + } + + if (!em_core_check_thread_status()) { + err = EMF_ERROR_CANCELLED; + goto FINISH_OFF; + } + + /* open mail server. */ + if (!em_core_mailbox_open(account_id, mail->mailbox_name, (void **)&stream, &err) || !stream) { + EM_DEBUG_EXCEPTION("em_core_mailbox_open failed [%d]", err); + status = EMF_LIST_CONNECTION_FAIL; + goto FINISH_OFF; + } + + + if (!em_core_check_thread_status()) { + err = EMF_ERROR_CANCELLED; + goto FINISH_OFF; + } + + mbox.name = mail->mailbox_name; + mbox.account_id = account_id; + mbox.mail_stream = stream; + + /* download all uids from server. */ + if (!em_core_mail_get_msgno_by_uid(ref_account, &mbox, mail->server_mail_id, &msgno, &err)) { + EM_DEBUG_EXCEPTION("em_core_mail_get_msgno_by_uid failed message_no : %d ", err); + goto FINISH_OFF; + } + + sprintf (tmp, "%d", msgno); + + if (new_flag.seen) + sprintf(set_flags, "\\Seen"); + else + sprintf(clear_flags, "\\Seen"); + + if (new_flag.answered) + sprintf(set_flags, "%s \\Answered", set_flags); + else + sprintf(clear_flags, "%s \\Answered", clear_flags); + + if (new_flag.flagged) + sprintf(set_flags, "%s \\Flagged", set_flags); + else + sprintf(clear_flags, "%s \\Flagged", clear_flags); + + if (new_flag.forwarded) + sprintf(set_flags, "%s $Forwarded", set_flags); + else + sprintf(clear_flags, "%s $Forwarded", clear_flags); + + if (strlen(set_flags) > 0) { + EM_DEBUG_LOG(">>>> Calling mail_setflag [%s] ", set_flags); + mail_flag(stream, tmp, set_flags, ST_SET | ST_SILENT); + EM_DEBUG_LOG(">>>> End mail_setflag "); + } + + if (strlen(clear_flags) > 0) { + EM_DEBUG_LOG(">>>> Calling mail_clearflag [%s]", clear_flags); + mail_clearflag(stream, tmp, clear_flags); + EM_DEBUG_LOG(">>>> End mail_clearflag "); + } + + if (mail->lock_status) { + memset(set_flags, 0x00, 100); + sprintf(set_flags, "Sticky"); + if (strlen(set_flags) > 0) { + EM_DEBUG_LOG(">>>> Calling mail_setflag [%s]", set_flags); + mail_flag(stream, tmp, set_flags, ST_SET | ST_SILENT); + EM_DEBUG_LOG(">>>> End mail_setflag "); + } + } + + EM_DEBUG_LOG(">>>> Returning from em_core_mail_sync_flag_with_server "); + + if (!em_core_check_thread_status()) { + err = EMF_ERROR_CANCELLED; + goto FINISH_OFF; + } + + ret = true; + +FINISH_OFF: + + if (stream) em_core_mailbox_close(account_id, stream); + if (mail) em_storage_free_mail(&mail, 1, NULL); + + if (err_code != NULL) + *err_code = err; + EM_DEBUG_FUNC_END("err [%d]", err); + return ret; +} + +EXPORT_API int em_core_mail_sync_seen_flag_with_server(int mail_ids[], int num, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("mail_ids[%p], err_code[%p]", mail_ids[0], err_code); + + if (mail_ids[0] < 1) { + if (err_code != NULL) + *err_code = EMF_ERROR_INVALID_PARAM; + return false; + } + + int ret = false; + int err = EMF_ERROR_NONE; + int status = EMF_DOWNLOAD_FAIL; + MAILSTREAM *stream = NULL; + emf_mailbox_t mbox; + emf_mail_tbl_t *mail = NULL; + emf_account_t *ref_account = NULL; + int account_id = 0; + int msgno = 0; + emf_mail_flag_t new_flag; + char set_flags[100]; + char clear_flags[100]; + char tmp[100]; + int mail_id = 0; + int i = 0; + + memset(&mbox, 0x00, sizeof(emf_mailbox_t)); + + mail_id = mail_ids[0]; + + if (!em_storage_get_mail_by_id(mail_id, &mail, true, &err) || !mail) { + EM_DEBUG_EXCEPTION("em_storage_get_mail_by_id failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + + account_id = mail->account_id; + + if (!(ref_account = em_core_get_account_reference(account_id))) { + EM_DEBUG_EXCEPTION("em_core_get_account_reference failed [%d]", account_id); + err = EMF_ERROR_INVALID_ACCOUNT; + goto FINISH_OFF; + } + + /* open mail server. */ + if (!em_core_mailbox_open(account_id, mail->mailbox_name, (void **)&stream, &err) || !stream) { + EM_DEBUG_EXCEPTION("em_core_mailbox_open failed [%d]", err); + status = EMF_LIST_CONNECTION_FAIL; + goto FINISH_OFF; + } + + mbox.name = mail->mailbox_name; + mbox.account_id = account_id; + mbox.mail_stream = stream; + + for (i = 0; i < num; i++) { + mail_id = mail_ids[i]; + + if (!em_core_check_thread_status()) { + err = EMF_ERROR_CANCELLED; + goto FINISH_OFF; + } + + if (!em_storage_get_mail_by_id(mail_id, &mail, true, &err) || !mail) { + EM_DEBUG_EXCEPTION("em_storage_get_mail_by_id failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + + /* account_id = mail->account_id; */ + em_convert_mail_tbl_to_mail_flag(mail, &new_flag, NULL); + + if (!em_core_check_thread_status()) { + err = EMF_ERROR_CANCELLED; + goto FINISH_OFF; + } + + /* download message number from server. */ + if (!em_core_mail_get_msgno_by_uid(ref_account, &mbox, mail->server_mail_id, &msgno, &err)) { + EM_DEBUG_LOG("em_core_mail_get_msgno_by_uid failed message_no : %d ", err); + goto FINISH_OFF; + } + + memset(tmp, 0x00, 100); + sprintf (tmp, "%d", msgno); + + memset(set_flags, 0x00, 100); + memset(clear_flags, 0x00, 100); + + if (new_flag.seen) + sprintf(set_flags, "\\Seen"); + else + sprintf(clear_flags, "\\Seen"); + EM_DEBUG_LOG("new_flag.seen : %s ", set_flags); + + if (strlen(set_flags) > 0) { + EM_DEBUG_LOG(">>>> Calling mail_setflag "); + mail_flag(stream, tmp, set_flags, ST_SET | ST_SILENT); + EM_DEBUG_LOG(">>>> End mail_setflag "); + } + else { + EM_DEBUG_LOG(">>>> Calling mail_clearflag "); + mail_clearflag(stream, tmp, clear_flags); + EM_DEBUG_LOG(">>>> End mail_clearflag "); + } + + EM_DEBUG_LOG(">>>> Returning from em_core_mail_sync_flag_with_server "); + + if (!em_core_check_thread_status()) { + err = EMF_ERROR_CANCELLED; + goto FINISH_OFF; + } + } + ret = true; + +FINISH_OFF: + + if (stream) em_core_mailbox_close(account_id, stream); + if (mail) em_storage_free_mail(&mail, 1, NULL); + + if (err_code != NULL) + *err_code = err; + EM_DEBUG_FUNC_END("err [%d]", err); + return ret; +} + + + +EXPORT_API int em_core_mail_info_free(emf_mail_info_t **mail_info_list, int count, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("mail_info_list[%p], count[%d], err_code[%p]", mail_info_list, count, err_code); + + if (count > 0) { + if (!mail_info_list || !*mail_info_list) { + EM_DEBUG_EXCEPTION("mail_info_list[%p]", mail_info_list); + if (err_code != NULL) + *err_code = EMF_ERROR_INVALID_PARAM; + return false; + } + + emf_mail_info_t *p = *mail_info_list; + int i = 0; + + for (; i < count; i++) + EM_SAFE_FREE(p[i].sid); + + free(p); + *mail_info_list = NULL; + } + + if (err_code != NULL) + *err_code = EMF_ERROR_NONE; + EM_DEBUG_FUNC_END(); + return true; +} + +EXPORT_API int em_core_mail_head_free(emf_mail_head_t **mail_head_list, int count, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("mail_head_list[%p], count[%d], err_code[%p]", mail_head_list, count, err_code); + EM_PROFILE_BEGIN(emCoreMailHeadeFree); + + if (count > 0) { + if (!mail_head_list || !*mail_head_list) { + EM_DEBUG_EXCEPTION("mail_head_list[%p], count[%d]", mail_head_list, count); + + if (err_code != NULL) + *err_code = EMF_ERROR_INVALID_PARAM; + return false; + } + + int i; + emf_mail_head_t *p = *mail_head_list; + + for (i = 0; i < count; i++) { + EM_SAFE_FREE(p[i].mid); + EM_SAFE_FREE(p[i].subject); + EM_SAFE_FREE(p[i].to); + EM_SAFE_FREE(p[i].from); + EM_SAFE_FREE(p[i].cc); + EM_SAFE_FREE(p[i].bcc); + EM_SAFE_FREE(p[i].reply_to); + EM_SAFE_FREE(p[i].return_path); + EM_SAFE_FREE(p[i].previewBodyText); + } + + free(p); *mail_head_list = NULL; + } + + if (err_code != NULL) + *err_code = EMF_ERROR_NONE; + + EM_PROFILE_END(emCoreMailHeadeFree); + EM_DEBUG_FUNC_END(); + return true; +} + +EXPORT_API int em_core_mail_body_free(emf_mail_body_t **mail_body_list, int count, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("mail_body_list[%p], count[%d], err_code[%p]", mail_body_list, count, err_code); + + if (count > 0) { + if (!mail_body_list || !*mail_body_list) { + EM_DEBUG_EXCEPTION("mail_body_list[%p]", mail_body_list); + if (err_code != NULL) + *err_code = EMF_ERROR_INVALID_PARAM; + return false; + } + + emf_mail_body_t *p = *mail_body_list; + int i = 0; + + for (; i < count; i++) { + EM_SAFE_FREE(p[i].plain); + EM_SAFE_FREE(p[i].plain_charset); + EM_SAFE_FREE(p[i].html); + if (p[i].attachment) em_core_mail_attachment_info_free(&p[i].attachment, NULL); + } + + free(p); *mail_body_list = NULL; + } + + if (err_code != NULL) + *err_code = EMF_ERROR_NONE; + EM_DEBUG_FUNC_END(); + return true; +} + +EXPORT_API int em_core_mail_free(emf_mail_t **mail_list, int count, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("mail_list[%p], count[%d], err_code[%p]", mail_list, count, err_code); + + if (count > 0) { + if (!mail_list || !*mail_list) { + EM_DEBUG_EXCEPTION("mail_list[%p], count[%d]", mail_list, count); + if (err_code != NULL) + *err_code = EMF_ERROR_INVALID_PARAM; + return false; + } + + emf_mail_t *p = *mail_list; + int i = 0; + + for (; i < count; i++) { + if (p[i].info) + em_core_mail_info_free(&p[i].info, 1, NULL); + + if (p[i].head) + em_core_mail_head_free(&p[i].head, 1, NULL); + + if (p[i].body) + em_core_mail_body_free(&p[i].body, 1, NULL); + } + + free(p); *mail_list = NULL; + } + + if (err_code != NULL) + *err_code = EMF_ERROR_NONE; + EM_DEBUG_FUNC_END(); + return true; +} + +EXPORT_API int em_core_free_mail_data(emf_mail_data_t **mail_list, int count, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("mail_list[%p], count[%d]", mail_list, count); + + if (count <= 0 || !mail_list || !*mail_list) { + EM_DEBUG_EXCEPTION("EMF_ERROR_INVALID_PARAM"); + if(err_code) + *err_code = EMF_ERROR_INVALID_PARAM; + return false; + } + + emf_mail_data_t* p = *mail_list; + int i; + + for (i = 0; i < count; i++) { + EM_SAFE_FREE(p[i].mailbox_name); + EM_SAFE_FREE(p[i].subject); + EM_SAFE_FREE(p[i].datetime); + EM_SAFE_FREE(p[i].server_mailbox_name); + EM_SAFE_FREE(p[i].server_mail_id); + EM_SAFE_FREE(p[i].message_id); + EM_SAFE_FREE(p[i].full_address_from); + EM_SAFE_FREE(p[i].full_address_reply); + EM_SAFE_FREE(p[i].full_address_to); + EM_SAFE_FREE(p[i].full_address_cc); + EM_SAFE_FREE(p[i].full_address_bcc); + EM_SAFE_FREE(p[i].full_address_return); + EM_SAFE_FREE(p[i].email_address_sender); + EM_SAFE_FREE(p[i].email_address_recipient); + EM_SAFE_FREE(p[i].alias_sender); + EM_SAFE_FREE(p[i].alias_recipient); + EM_SAFE_FREE(p[i].file_path_plain); + EM_SAFE_FREE(p[i].file_path_html); + EM_SAFE_FREE(p[i].preview_text); + } + + EM_SAFE_FREE(p); *mail_list = NULL; + + if(err_code) + *err_code = EMF_ERROR_NONE; + + EM_DEBUG_FUNC_END(); + return true; +} + + +EXPORT_API int em_core_mail_attachment_info_free(emf_attachment_info_t **atch_info, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("atch_info[%p], err_code[%p]", atch_info, err_code); + + if (!atch_info || !*atch_info) { + if (err_code != NULL) + *err_code = EMF_ERROR_INVALID_PARAM; + return false; + } + + emf_attachment_info_t *p = *atch_info; + emf_attachment_info_t *t; + + while (p) { + EM_SAFE_FREE(p->name); + EM_SAFE_FREE(p->savename); + t = p->next; + free(p); p = NULL; + p = t; + } + + if (err_code != NULL) + *err_code = EMF_ERROR_NONE; + EM_DEBUG_FUNC_END(); + return true; +} + + +EXPORT_API int em_core_free_attachment_data(emf_attachment_data_t **attachment_data_list, int attachment_data_count, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("attachment_data_list[%p], attachment_data_count [%d], err_code[%p]", attachment_data_list, attachment_data_count, err_code); + + if (!attachment_data_list || !*attachment_data_list) { + if (err_code != NULL) + *err_code = EMF_ERROR_INVALID_PARAM; + return false; + } + + emf_attachment_data_t* p = *attachment_data_list; + int i = 0; + + for (i = 0; i < attachment_data_count; i++) { + EM_SAFE_FREE(p[i].mailbox_name); + EM_SAFE_FREE(p[i].attachment_name); + EM_SAFE_FREE(p[i].attachment_path); + } + + EM_SAFE_FREE(p); *attachment_data_list = NULL; + + if(err_code) + *err_code = EMF_ERROR_NONE; + + EM_DEBUG_FUNC_END(); + return true; +} + + + +#ifdef __FEATURE_PARTIAL_BODY_DOWNLOAD__ + +EXPORT_API int em_core_delete_pbd_activity(int account_id, int mail_id, int activity_id, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id[%d], mail_id[%d], err_code[%p]", account_id, mail_id, err_code); + + if (account_id < FIRST_ACCOUNT_ID || mail_id < 0) { + EM_DEBUG_EXCEPTION("account_id[%d], mail_id[%d], err_code[%p]", account_id, mail_id, err_code); + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + int ret = false; + int err = EMF_ERROR_NONE; + + em_storage_begin_transaction(NULL, NULL, NULL); + + if (!em_storage_delete_pbd_activity(account_id, mail_id, activity_id, false, &err)) { + EM_DEBUG_EXCEPTION("em_storage_delete_pbd_activity failed [%d]", err); + + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + + ret = true; + +FINISH_OFF: + if (ret == true) { /* COMMIT TRANSACTION; */ + if (em_storage_commit_transaction(NULL, NULL, NULL) == false) { + err = em_storage_get_emf_error_from_em_storage_error(EM_STORAGE_ERROR_DB_FAILURE); + ret = false; + } + } + else { /* ROLLBACK TRANSACTION; */ + if (em_storage_rollback_transaction(NULL, NULL, NULL) == false) + err = em_storage_get_emf_error_from_em_storage_error(EM_STORAGE_ERROR_DB_FAILURE); + } + + if (err_code != NULL) + *err_code = err; + EM_DEBUG_FUNC_END(); + return ret; +} + +EXPORT_API int em_core_insert_pbd_activity(emf_event_partial_body_thd *local_activity, int *activity_id, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("local_activity[%p], activity_id[%p], err_code[%p]", local_activity, activity_id, err_code); + + if (!local_activity || !activity_id) { + EM_DEBUG_EXCEPTION("local_activity[%p], activity_id[%p] err_code[%p]", local_activity, activity_id, err_code); + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + int ret = false; + int err = EMF_ERROR_NONE; + + em_storage_begin_transaction(NULL, NULL, NULL); + + if (!em_storage_add_pbd_activity(local_activity, activity_id, false, &err)) { + EM_DEBUG_EXCEPTION("em_storage_add_pbd_activity failed [%d]", err); + + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + + ret = true; + +FINISH_OFF: + if (ret == true) { /* COMMIT TRANSACTION; */ + if (em_storage_commit_transaction(NULL, NULL, NULL) == false) { + err = em_storage_get_emf_error_from_em_storage_error(EM_STORAGE_ERROR_DB_FAILURE); + ret = false; + } + } + else { /* ROLLBACK TRANSACTION; */ + if (em_storage_rollback_transaction(NULL, NULL, NULL) == false) + err = em_storage_get_emf_error_from_em_storage_error(EM_STORAGE_ERROR_DB_FAILURE); + } + + if (err_code != NULL) + *err_code = err; + EM_DEBUG_FUNC_END(); + return ret; +} + +#endif + +#ifdef __FEATURE_BULK_DELETE_MOVE_UPDATE_REQUEST_OPTI__ + +/* API to set or unset a field of flags on server in single IMAP request to server */ + +EXPORT_API int em_core_mail_sync_flags_field_with_server(int mail_ids[], int num, emf_flags_field_type field_type, int value, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("mail_ids [%p], num [%d], field_type [%d], value [%d], err_code [%p]", mail_ids, num, field_type, value, err_code); + + if (NULL == mail_ids || num <= 0 || field_type < 0 || field_type >= EMF_FLAGS_FIELD_COUNT) { + EM_DEBUG_EXCEPTION("EMF_ERROR_INVALID_PARAM"); + if (err_code != NULL) { + *err_code = EMF_ERROR_INVALID_PARAM; + } + return false; + } + + MAILSTREAM *stream = NULL; + IMAPLOCAL *imaplocal = NULL; + char tag[MAX_TAG_SIZE] = {0, }; + char cmd[MAX_IMAP_COMMAND_LENGTH] = {0, }; + char *p = NULL; + char **string_list = NULL; + int ret = false; + int err = EMF_ERROR_NONE; + int command_success = false; + int account_id = 0; + int mail_id = 0; + int i = 0; + int id_set_count = 0; + int len_of_each_range = 0; + int string_count = 0; + emf_account_t *temp_account; + emf_id_set_t *id_set = NULL; + emf_mail_tbl_t *mail = NULL; + emf_uid_range_set *uid_range_set = NULL; + emf_uid_range_set *uid_range_node = NULL; + char *field_type_name[EMF_FLAGS_FIELD_COUNT] = { "\\Seen" + , "\\Deleted", "\\Flagged", "\\Answered" + , "\\Recent", "\\Draft", "$Forwarded" }; + + mail_id = mail_ids[0]; + + if (!em_storage_get_mail_field_by_id(mail_id, RETRIEVE_FLAG, &mail, true, &err) || !mail) /*To DO : This is a existing bug. on mail deletion before this call it will fail always */ { + EM_DEBUG_LOG("em_storage_get_mail_by_id failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + + account_id = mail[0].account_id; + + temp_account = em_core_get_account_reference(account_id); + + if (!temp_account) { + EM_DEBUG_EXCEPTION("em_core_get_account_reference failed [%d]", account_id); + err = EMF_ERROR_INVALID_ACCOUNT; + goto FINISH_OFF; + } + + if (temp_account->receiving_server_type != EMF_SERVER_TYPE_IMAP4) { + EM_DEBUG_EXCEPTION("Syncing seen flag is available only for IMAP4 server. The server type [%d]", temp_account->receiving_server_type); + err = EMF_ERROR_NOT_SUPPORTED; + goto FINISH_OFF; + } + + if (!em_core_mailbox_open(account_id, mail->mailbox_name, (void **)&stream, &err) || !stream) { + EM_DEBUG_EXCEPTION("em_core_mailbox_open failed [%d]", err); + goto FINISH_OFF; + } + + if (false == em_storage_free_mail(&mail, 1, &err)) { + EM_DEBUG_EXCEPTION("em_storage_free_mail failed - %d ", err); + goto FINISH_OFF; + } + + /* [h.gahlaut] Break the set of mail_ids into comma separated strings of given length */ + /* Length is decided on the basis of remaining keywords in the Query to be formed later on in em_storage_get_id_set_from_mail_ids */ + /* Here about 90 bytes are required for fixed keywords in the query-> SELECT local_uid, s_uid from mail_read_mail_uid_tbl where local_uid in (....) ORDER by s_uid */ + /* So length of comma separated strings which will be filled in (.....) in above query can be maximum QUERY_SIZE - 90 */ + + if (false == em_core_form_comma_separated_strings(mail_ids, num, QUERY_SIZE - 90, &string_list, &string_count, &err)) { + EM_DEBUG_EXCEPTION("em_core_form_comma_separated_strings failed [%d]", err); + goto FINISH_OFF; + } + + /* Now execute one by one each comma separated string of mail_ids */ + + for (i = 0; i < string_count; ++i) { + /* Get the set of mail_ds and corresponding server_mail_ids sorted by server mail ids in ascending order */ + + if (false == em_storage_get_id_set_from_mail_ids(string_list[i], &id_set, &id_set_count, &err)) { + EM_DEBUG_EXCEPTION("em_storage_get_id_set_from_mail_ids failed [%d]", err); + goto FINISH_OFF; + } + + /* Convert the sorted sequence of server mail ids to range sequences of given length. A range sequence will be like A : B, C, D: E, H */ + + len_of_each_range = MAX_IMAP_COMMAND_LENGTH - 40; /* 1000 is the maximum length allowed RFC 2683. 40 is left for keywords and tag. */ + + if (false == em_core_convert_to_uid_range_set(id_set, id_set_count, &uid_range_set, len_of_each_range, &err)) { + EM_DEBUG_EXCEPTION("em_core_convert_to_uid_range_set failed [%d]", err); + goto FINISH_OFF; + } + + uid_range_node = uid_range_set; + + while (uid_range_node != NULL) { + /* Remove comma from end of uid_range */ + + uid_range_node->uid_range[strlen(uid_range_node->uid_range) - 1] = '\0'; + + /* Form the IMAP command */ + + SNPRINTF(tag, MAX_TAG_SIZE, "%08lx", 0xffffffff & (stream->gensym++)); + + if (value) + SNPRINTF(cmd, MAX_IMAP_COMMAND_LENGTH, "%s UID STORE %s +FLAGS (%s)\015\012", tag, uid_range_node->uid_range, field_type_name[field_type]); + else + SNPRINTF(cmd, MAX_IMAP_COMMAND_LENGTH, "%s UID STORE %s -FLAGS (%s)\015\012", tag, uid_range_node->uid_range, field_type_name[field_type]); + + EM_DEBUG_LOG("[IMAP4] command %s", cmd); + + /* send command */ + + if (!(imaplocal = stream->local) || !imaplocal->netstream) { + EM_DEBUG_EXCEPTION("invalid IMAP4 stream detected..."); + + err = EMF_ERROR_UNKNOWN; + goto FINISH_OFF; + } + + if (!net_sout(imaplocal->netstream, cmd, (int)strlen(cmd))) { + EM_DEBUG_EXCEPTION("net_sout failed..."); + err = EMF_ERROR_CONNECTION_BROKEN; + goto FINISH_OFF; + } + + /* Receive Response */ + + command_success = false; + + while (imaplocal->netstream) { + if (!(p = net_getline(imaplocal->netstream))) { + EM_DEBUG_EXCEPTION("net_getline failed..."); + + err = EMF_ERROR_INVALID_RESPONSE; + goto FINISH_OFF; + } + + EM_DEBUG_LOG("[IMAP4 Response ] %s", p); + + if (!strncmp(p, tag, strlen(tag))) { + if (!strncmp(p + strlen(tag) + 1, "OK", 2)) { + /*Delete all local activities */ + command_success = true; + + EM_SAFE_FREE(p); + break; + } + else { + /* 'NO' or 'BAD' */ + command_success = false; + err = EMF_ERROR_IMAP4_STORE_FAILURE; + EM_SAFE_FREE(p); + goto FINISH_OFF; + } + } + + EM_SAFE_FREE(p); + } + + uid_range_node = uid_range_node->next; + } + + em_core_free_uid_range_set(&uid_range_set); + + EM_SAFE_FREE(id_set); + + id_set_count = 0; + } + + ret = true; + +FINISH_OFF: + +#ifdef __LOCAL_ACTIVITY__ + if (ret) { + emf_activity_tbl_t new_activity; + for (i = 0; i<num ; i++) { + memset(&new_activity, 0x00, sizeof(emf_activity_tbl_t)); + new_activity.activity_type = ACTIVITY_MODIFYSEENFLAG; + new_activity.account_id = account_id; + new_activity.mail_id = mail_ids[i]; + + if (!em_core_activity_delete(&new_activity, &err)) + EM_DEBUG_EXCEPTION("Local Activity ACTIVITY_MOVEMAIL [%d] ", err); + } + + } +#endif + + if (NULL != mail) { + if (false == em_storage_free_mail(&mail, 1, &err)) + EM_DEBUG_EXCEPTION("em_storage_free_mail failed - %d ", err); + } + + em_core_free_comma_separated_strings(&string_list, &string_count); + + if (false == ret) + em_core_free_uid_range_set(&uid_range_set); + + em_core_mailbox_close(0, stream); + stream = NULL; + + if (err_code != NULL) + *err_code = err; + EM_DEBUG_FUNC_END(); + return ret; + +} +#endif + +EXPORT_API int em_core_mail_filter_by_rule(emf_rule_t *filter_info, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("filter_info[%p], err_code[%p]", filter_info, err_code); + + int ret = false, err = EMF_ERROR_NONE; + int account_index, account_count, mail_id_index = 0; + emf_account_t *account_ref = NULL, *account_list_ref = NULL; + int filtered_mail_id_count = 0, *filtered_mail_id_list = NULL, parameter_string_length = 0; + char *parameter_string = NULL, mail_id_string[10] = { 0x00, }; + emf_mailbox_tbl_t *spam_mailbox = NULL; + + if (!filter_info) { + EM_DEBUG_EXCEPTION("filter_info[%p]", filter_info); + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + if (!em_core_account_get_list_refer(&account_list_ref, &account_count, &err)) { + EM_DEBUG_EXCEPTION("em_core_account_get_list_refer failed [%d]", err); + goto FINISH_OFF; + } + + for (account_index = 0; account_index < account_count; account_index++) { + account_ref = account_list_ref + account_index; + + if (!em_storage_get_mailbox_by_mailbox_type(account_ref->account_id, EMF_MAILBOX_TYPE_SPAMBOX, &spam_mailbox, false, &err)) + EM_DEBUG_EXCEPTION("em_storage_get_mailbox_by_mailbox_type for account_id[%d] failed [%d]", account_ref->account_id, err); + else if (spam_mailbox && spam_mailbox->mailbox_name) { + if (!em_storage_filter_mails_by_rule(account_ref->account_id, spam_mailbox->mailbox_name, (emf_mail_rule_tbl_t *)filter_info, &filtered_mail_id_list, &filtered_mail_id_count, &err)) + EM_DEBUG_EXCEPTION("em_storage_filter_mails_by_rule failed [%d]", err); + else { + if (filtered_mail_id_count) { + parameter_string_length = strlen(spam_mailbox->mailbox_name) + 7 + (10 * filtered_mail_id_count); + parameter_string = em_core_malloc(sizeof(char) * parameter_string_length); + + if (parameter_string == NULL) { + err = EMF_ERROR_OUT_OF_MEMORY; + EM_DEBUG_EXCEPTION("em_core_malloc failed for parameter_string"); + goto FINISH_OFF; + } + + SNPRINTF(parameter_string, parameter_string_length, "[NA]%c%s%c", 0x01, spam_mailbox->mailbox_name, 0x01); + + for (mail_id_index = 0; mail_id_index < filtered_mail_id_count; mail_id_index++) { + memset(mail_id_string, 0, 10); + SNPRINTF(mail_id_string, 10, "%d", filtered_mail_id_list[mail_id_index]); + strcat(parameter_string, mail_id_string); + strcat(parameter_string, ","); + } + + EM_DEBUG_LOG("filtered_mail_id_count [%d]", filtered_mail_id_count); + EM_DEBUG_LOG("param string [%s]", parameter_string); + + if (!em_storage_notify_storage_event(NOTI_MAIL_MOVE, account_ref->account_id, 0, parameter_string, 0)) + EM_DEBUG_EXCEPTION("em_storage_notify_storage_event failed [ NOTI_MAIL_MOVE ] >>>> "); + + EM_SAFE_FREE(filtered_mail_id_list); + EM_SAFE_FREE(parameter_string); + } + } + em_storage_free_mailbox(&spam_mailbox, 1, &err); + spam_mailbox = NULL; + } + } + + em_core_check_unread_mail(); + + ret = true; + +FINISH_OFF: + EM_SAFE_FREE(account_list_ref); + EM_SAFE_FREE(filtered_mail_id_list); + EM_SAFE_FREE(parameter_string); + + + if (spam_mailbox) + em_storage_free_mailbox(&spam_mailbox, 1, &err); + + if (err_code) + *err_code = err; + EM_DEBUG_FUNC_END(); + return ret; +} diff --git a/email-core/em-core-mime.c b/email-core/em-core-mime.c new file mode 100755 index 0000000..8e17098 --- /dev/null +++ b/email-core/em-core-mime.c @@ -0,0 +1,4719 @@ +/* +* email-service +* +* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. +* +* Contact: Kyuho Jo <kyuho.jo@samsung.com>, Sunghyun Kwon <sh0701.kwon@samsung.com> +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + + + +/* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** *** + *File : em-core-mime.c + *Desc : MIME Operation + * + *Auth : + * + *History : + * 2011.04.14 : created + ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ***/ +#undef close + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <vconf.h> +#include <ctype.h> +#include <sys/stat.h> +#include <sys/time.h> +#include "em-core-types.h" +#include "lnx_inc.h" +#include "em-core-global.h" +#include "em-core-utils.h" +#include "em-core-mesg.h" +#include "em-core-mime.h" +#include "em-storage.h" +#include "em-core-event.h" +#include "em-core-account.h" +#include "emf-dbglog.h" + + +#define MIME_MESG_IS_SOCKET + +#define MIME_LINE_LEN 1024 +#define BOUNDARY_LEN 256 + +#define TYPE_TEXT 1 +#define TYPE_IMAGE 2 +#define TYPE_AUDIO 3 +#define TYPE_VIDEO 4 +#define TYPE_APPLICATION 5 +#define TYPE_MULTIPART 6 +#define TYPE_MESSAGE 7 +#define TYPE_UNKNOWN 8 + +#define TEXT_STR "TEXT" +#define IMAGE_STR "IMAGE" +#define AUDIO_STR "AUDIO" +#define VIDEO_STR "VIDEO" +#define APPLICATION_STR "APPLICATION" +#define MULTIPART_STR "MULTIPART" +#define MESSAGE_STR "MESSAGE" + +#define CONTENT_TYPE 1 +#define CONTENT_SUBTYPE 2 +#define CONTENT_ENCODING 3 +#define CONTENT_CHARSET 4 +#define CONTENT_DISPOSITION 5 +#define CONTENT_NAME 6 +#define CONTENT_FILENAME 7 +#define CONTENT_BOUNDARY 8 +#define CONTENT_REPORT_TYPE 9 +#define CONTENT_ID 10 +#define CONTENT_LOCATION 11 + +#define GRAB_TYPE_TEXT 1 /* retrieve text and attachment name */ +#define GRAB_TYPE_ATTACHMENT 2 /* retrieve only attachmen */ + +#define SAVE_TYPE_SIZE 1 /* only get content siz */ +#define SAVE_TYPE_BUFFER 2 /* save content to buffe */ +#define SAVE_TYPE_FILE 3 /* save content to temporary fil */ + +/* + MIME Structure Example + + (part 0) multipart/mixed + (part 1) multipart/alternative + (part 1.1) text/plain <- text message + (part 1.2) text/html <- html message + (part 2) text/plain <- text attachment + + + (part 0) multipart/related + (part 1) multipart/alternative + (part 1.1) text/plain <- text message + (part 1.2) text/html <- html message + (part 2) image/png <- inline image + (part 2) image/png <- inline image + + + (part 0) multipart/mixed + (part 1.1) multipart/related + (part 2.1) multipart/alternative + (part 3.1) text/plain(body) <- text message + (part 3.2) text/html(body) <- html message + (part 2.2) image/png(related) <- inline image + (part 1.2) image/png(attachment) <- image attachment +*/ + +/* Text and Attachment Holde */ +/* struct _m_content_info */ +/* int grab_type; */ /* 1 : text and attachment list */ + /* 2 : attachmen */ +/* int file_no; */ /* attachment sequence to be downloaded (min : 1 */ +/* struct text_data */ +/* char *plain; */ /* body plain tex */ +/* char *plain_charset */ /* charset of plai */ +/* char *html; */ /* body html tex */ +/* } text */ + +/* struct attachment_info */ +/* int type; */ /* 1 : inline 2 : attachmen */ +/* char *name; */ /* attachment filenam */ +/* int size; */ /* attachment siz */ +/* char *save; */ /* content saving filenam */ +/* struct attachment_info *next */ +/* } *file */ +/* } */ + +/* --------------------- MIME Structure --------------------------------- */ +/* MIME Header Parameter (Content-Type, Content-Disposition, ... */ +struct _parameter { + char *name; /* parameter name */ + char *value; /* parameter valu */ + struct _parameter *next; /* next paramete */ +}; + +/* Content-Dispositio */ +struct _disposition { + char *type; /* "inline" "attachment */ + struct _parameter *parameter; /* "filename", .. */ +}; + +/* RFC822 Heade */ +struct _rfc822header { + char *return_path; /* error return pat */ + char *received; + char *date; + char *from; + char *subject; + char *sender; + char *to; + char *cc; + char *bcc; + char *reply_to; + char *priority; + char *ms_priority; + char *dsp_noti_to; + char *others; +}; +/* MIME Part Header */ +struct _m_part_header { + char *type; /* text, image, audio, video, application, multipart, messag */ + char *subtype; /* plain, html, jpeg, .. */ + char *encoding; /* encoding typ */ + struct _parameter *parameter; /* content-type parameter : "boundary" "charset" .. */ + char *desc; /* descriptio */ + char *disp_type; /* disposition type : "inline" "attachment", */ + struct _parameter *disp_parameter; /* disposition parameter : "filename", .. */ + char *content_id; /* content id : it is inline */ + char *content_location; /* content location : "inline" location */ +}; + +/* MIME Message Header */ +struct _m_mesg_header { + char *version; /* MIME Versio */ + struct _m_part_header *part_header; /* MIME Part Heade */ +}; + +/* MIME Multipart Body linked list */ +typedef struct _m_body _m_body_t; +struct _m_part{ + _m_body_t *body; /* part bod */ + struct _m_part *next; /* the next found par */ +}; + +/* MIME Multipart Body */ +struct _m_body { + struct _m_part_header *part_header; /* MIME Part Heade */ + struct _m_part nested; /* nested structure if contain multipar */ + char *text; /* text if not contain multipar */ + int size; /* text size if not contain multipar */ + char *holdingfile; +}; + +/* MIME Message */ +struct _m_mesg { + struct _rfc822header *rfc822header; /* RFC822 Heade */ + struct _m_mesg_header *header; /* MIME Message Heade */ + struct _m_part nested; /* nested structure if contain multipar */ + char *text; /* text if not contain multipar */ + int size; /* text size if not contain multipar */ +}; +/* ---------------------------------------------------------------------- */ +/* Global variable */ +static bool next_decode_string = false; + + +/* ---------------------------------------------------------------------- */ +/* External variable */ +extern int _pop3_receiving_mail_id; +extern int _pop3_received_body_size; +extern int _pop3_last_notified_body_size; +extern int _pop3_total_body_size; + +extern int _imap4_received_body_size; +extern int _imap4_last_notified_body_size; +extern int _imap4_total_body_size; +extern int _imap4_download_noti_interval_value; + +extern int multi_part_body_size; +extern bool only_body_download; + +extern BODY **g_inline_list; +extern int g_inline_count; + +/* ---------------------------------------------------------------------- */ +/* Function Declaration */ + +/* parsing the first header (RFC822 Header and Message Header and Etc... */ +static int em_core_mime_parse_header(void *stream, int is_file, struct _rfc822header **rfcheader, struct _m_mesg_header **header, int *err_code); + +/* parsing the first bod */ +static int em_core_mime_parse_body(void *stream, int is_file, struct _m_mesg *mmsg, struct _m_content_info *cnt_info, void *callback, int *err_code); + +/* parsing the message part header (CONTENT-... header */ +static int em_core_mime_parse_part_header(void *stream, int is_file, struct _m_part_header **header, int *err_code); + +/* parsing the message part by boundar */ +static int em_core_mime_parse_part(void *stream, int is_file, struct _m_part_header *parent_header, struct _m_part *nested, struct _m_content_info *cnt_info, int *end_of_parsing, int *err_code); + +/* set RFC822 Header valu */ +static int em_core_mime_set_rfc822_header_value(struct _rfc822header **rfc822header, char *name, char *value, int *err_code); + +/* set Message Part Header (Content-... Header */ +static int em_core_mime_set_part_header_value(struct _m_part_header **header, char *name, char *value, int *err_code); + +char *em_core_mime_get_content_param(struct _m_body *mbody, char *name, int *err_code); + +static int em_core_mime_get_param_from_str(char *str, struct _parameter **param, int *err_code); + +static int em_core_mime_add_param_to_list(struct _parameter **param_list, struct _parameter *param, int *err_code); + +char *em_core_mime_get_header_value(struct _m_part_header *header, int type, int *err_code); + +void em_core_mime_free_param(struct _parameter *param); +void em_core_mime_free_part_header(struct _m_part_header *header); +void em_core_mime_free_message_header(struct _m_mesg_header *header); +void em_core_mime_free_rfc822_header(struct _rfc822header *rfc822header); +void em_core_mime_free_part(struct _m_part *part); +void em_core_mime_free_part_body(struct _m_body *body); +void em_core_mime_free_mime(struct _m_mesg *mmsg); +char *em_core_mime_get_line_from_sock(void *stream, char *buf, int size, int *err_code); +char *em_core_mime_trim_left(char *str); +char *em_core_mime_trim_right(char *str); +char *em_core_mime_upper_str(char *str); +char *em_core_mime_get_save_file_name(int *err_code); + +/* get content data and save buffer or fil */ +/* mode - 1 : get the only siz */ +/* 2 : save content to buffer (holder is buffer */ +/* 3 : save content to file (holder is file name */ +static int em_core_mime_get_content_data(void *stream, + int is_file, + int is_text, + char *boundary_str, + char *content_encoding, + int *end_of_parsing, + int mode, + char **holder, + int *size, + void *callback, + int *err_code); +/* skip content data to boundary_str or end of fil */ +int em_core_mime_skip_content_data(void *stream, + int is_file, + char *boundary_str, + int *end_of_parsing, + int *size, + void *callback, + int *err_code); + +static int em_core_get_file_pointer(BODY *body, char *buf, struct _m_content_info *cnt_info , int *err); +static PARTLIST *em_core_get_body_full(MAILSTREAM *stream, int msg_uid, BODY *body, struct _m_content_info *cnt_info, int *err_code, PARTLIST *section_list); +static int em_core_get_body_part_imap_full(MAILSTREAM *stream, int msg_uid, int account_id, int mail_id, PARTLIST *section_list, struct _m_content_info *cnt_info, int *err_code, int event_handle); +static PARTLIST *em_core_add_node(PARTLIST *section_list, BODY *body); +static void em_core_free_section_list(PARTLIST *section_list); +static int em_core_get_section_body_size(char *response, char *section, int *body_size); +static void parse_file_path_to_filename(char *src_string, char **out_string); +extern long pop3_reply (MAILSTREAM *stream); +/* ------------------------------------------------------------------------------------------------- */ + + +/* Fix for issue junk characters in mail body */ +char *em_split_file_path(char *str) +{ + EM_DEBUG_FUNC_BEGIN("str [%s]", str); + + EM_IF_NULL_RETURN_VALUE(str, NULL); + + char *buf = NULL; + char delims[] = "@"; + char *result = NULL; + char *temp_str = NULL; + char *content_id = NULL; + int buf_length = 0; + char *temp_cid_data = NULL; + char *temp_cid = NULL; + temp_str = EM_SAFE_STRDUP(str); + buf_length = strlen(str) + 1024; + buf = em_core_malloc(buf_length); + content_id = temp_str; + temp_cid = strstr(temp_str, "\""); + + if (temp_cid == NULL) { + EM_DEBUG_EXCEPTION(">>>> File Path Doesnot contain end line for CID "); + next_decode_string = true; + EM_SAFE_FREE(buf); + return temp_str; + } + temp_cid_data = em_core_malloc((temp_cid-temp_str)+1); + memcpy(temp_cid_data, temp_str, (temp_cid-temp_str)); + + if (!strstr(temp_cid_data, delims)) { + EM_DEBUG_EXCEPTION(">>>> File Path Doesnot contain @ "); + next_decode_string = true; + EM_SAFE_FREE(buf); + EM_SAFE_FREE(temp_cid_data); + return temp_str; + } + else { + result = strstr(temp_str, delims); + if (result != NULL) { + next_decode_string = false; + *result = '\0'; + result++; + EM_DEBUG_LOG("content_id is [ %s ]", content_id); + + if (strcasestr(content_id, ".bmp") || strcasestr(content_id, ".jpeg") || strcasestr(content_id, ".png") || + strcasestr(content_id, ".jpg") || strcasestr(content_id, ".gif")) + snprintf(buf+strlen(buf), buf_length - strlen(buf), "%s\"", content_id); + else + snprintf(buf+strlen(buf), buf_length - strlen(buf), "%s%s", content_id, ".jpeg\""); + } + else { + EM_DEBUG_EXCEPTION(">>>> File Path Doesnot contain end line for CID "); + next_decode_string = true; + EM_SAFE_FREE(buf); + EM_SAFE_FREE(temp_cid_data); + return temp_str; + } + result = strstr(result, "\""); + if (result != NULL) { + result++; + snprintf(buf+strlen(buf), buf_length - strlen(buf), "%s", result); + } + } + EM_SAFE_FREE(temp_str); + EM_SAFE_FREE(temp_cid_data); + return buf; +} + + +static char *em_replace_string_with_split_file_path(char *source_string, char *old_string, char *new_string) +{ + EM_DEBUG_FUNC_BEGIN(); + char *buffer = NULL; + char *split_str = NULL; + char *p = NULL; + char *q = NULL; + int buf_len = 0; + + EM_IF_NULL_RETURN_VALUE(source_string, NULL); + EM_IF_NULL_RETURN_VALUE(old_string, NULL); + EM_IF_NULL_RETURN_VALUE(new_string, NULL); + + EM_DEBUG_LOG("source_string [%s] ", source_string); + EM_DEBUG_LOG("old_string [%s] ", old_string); + EM_DEBUG_LOG("new_string [%s] ", new_string); + + p = strstr(source_string, old_string); + + if (!p) { + EM_DEBUG_EXCEPTION("Orig not found in source_string"); + return NULL; + } + + buf_len = strlen(source_string) + 1024; + buffer = (char *)em_core_malloc(buf_len); + + if(p - source_string < strlen(source_string) + 1024 + 1) { + strncpy(buffer, source_string, p - source_string); + + EM_DEBUG_LOG("BUFFER [%s]", buffer); + + split_str = em_split_file_path(p); + + if (!split_str) { + EM_DEBUG_EXCEPTION(">> SPLIT STRING IS NULL "); + goto FINISH_OFF; + } + + q = strstr(split_str, old_string); + if (q) { + EM_DEBUG_LOG("Split string [%s]", split_str); + snprintf(buffer + strlen(buffer), buf_len - strlen(buffer), "%s%s", new_string, q+strlen(old_string)); + EM_DEBUG_LOG("BUFFER 1 [%s]", buffer); + EM_SAFE_FREE(split_str); + EM_DEBUG_FUNC_END("Suceeded"); + return buffer; + } + } + else { + EM_DEBUG_EXCEPTION("Buffer is too small."); + EM_SAFE_FREE(buffer); + return NULL; + } + +FINISH_OFF: + EM_SAFE_FREE(split_str); + EM_SAFE_FREE(buffer); + + EM_DEBUG_FUNC_END("Failed"); + return NULL; + +} + + +int +em_core_mime_flush_receiving_buffer(void *stream, int is_file, char *boundary_string, char *boundary_end_string, int *end_of_parsing, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("stream[%p], is_file[%d], boundary_string[%s], boundary_end_string[%s], end_of_parsing[%p], err_code[%p]", stream, is_file, boundary_string, boundary_end_string, end_of_parsing, err_code); + char buf[MIME_LINE_LEN] = {0, }; + int local_end_of_parsing = 0; + + if (!stream) { + if (err_code) + *err_code = EMF_ERROR_INVALID_PARAM; + EM_DEBUG_EXCEPTION("EMF_ERROR_INVALID_PARAM"); + return false; + } + + while (TRUE) { + if (!em_core_check_thread_status()) { + if (err_code != NULL) + *err_code = EMF_ERROR_CANCELLED; + EM_DEBUG_FUNC_END("EMF_ERROR_CANCELLED"); + return false; + } + + if ((is_file == 0 && !em_core_mime_get_line_from_sock(stream, buf, MIME_LINE_LEN, err_code)) || + (is_file == 1 && !em_core_mime_get_line_from_file(stream, buf, MIME_LINE_LEN, err_code))) { + EM_DEBUG_EXCEPTION("em_core_mime_get_line_from_sock failed"); + local_end_of_parsing = 0; + break; + } + + if (boundary_string && boundary_end_string) { + if (!strcmp(buf, boundary_string)) { + EM_DEBUG_LOG("found boundary"); + local_end_of_parsing = 0; + break; + } + else if (!strcmp(buf, boundary_end_string)) { + EM_DEBUG_LOG("found boundary_end"); + local_end_of_parsing = 1; + break; + } + } + } + + if (end_of_parsing) + *end_of_parsing = local_end_of_parsing; + + EM_DEBUG_FUNC_END(); + return true; +} + +int em_core_mime_parse_mime(void *stream, int is_file, struct _m_content_info *cnt_info, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("stream[%p], is_file[%d], cnt_info[%p], err_code[%p]", stream, is_file, cnt_info, err_code); + + struct _m_mesg *mmsg = em_core_malloc(sizeof(struct _m_mesg)); + + if (!mmsg) return false; + + memset(mmsg, 0x00, sizeof(struct _m_mesg)); + + /* 1. parse the first found heade */ + EM_DEBUG_LOG(">>>>>> 1. parse the first found header"); + if (!em_core_mime_parse_header(stream, is_file, &mmsg->rfc822header, &mmsg->header, err_code)) { + EM_SAFE_FREE(mmsg); + return false; + } + + if (!em_core_check_thread_status()) { + if (err_code != NULL) + *err_code = EMF_ERROR_CANCELLED; + return false; + } + + /* 2. parse bod */ + EM_DEBUG_LOG(">>>>>> 2. parse body"); + if (mmsg && mmsg->header && mmsg->header->part_header && mmsg->header->part_header->parameter) { + EM_DEBUG_LOG("name[%s]", mmsg->header->part_header->parameter->name); + EM_DEBUG_LOG("value[%s]", mmsg->header->part_header->parameter->value); + EM_DEBUG_LOG("next : %p", mmsg->header->part_header->parameter->next); + } + + if (em_core_mime_parse_body(stream, is_file, mmsg, cnt_info, NULL, err_code)<0) { + EM_SAFE_FREE(mmsg); + return false; + } + + /* 3. free memor */ + EM_DEBUG_LOG(">>>>>> 3. free memory"); + if (mmsg && mmsg->header && mmsg->header->part_header && mmsg->header->part_header->parameter) { + EM_DEBUG_LOG("name[%s]", mmsg->header->part_header->parameter->name); + EM_DEBUG_LOG("value[%s]", mmsg->header->part_header->parameter->value); + EM_DEBUG_LOG("next : %p", mmsg->header->part_header->parameter->next); + } + em_core_mime_free_mime(mmsg); + EM_DEBUG_FUNC_END(); + return true; +} + +int em_core_mime_parse_header(void *stream, int is_file, struct _rfc822header **rfc822header, struct _m_mesg_header **header, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("stream[%p], is_file[%d], rfc822header[%p], header[%p], err_code[%p]", stream, is_file, rfc822header, header, err_code); + + struct _m_mesg_header *tmp_header = NULL; + struct _rfc822header *tmp_rfc822header = NULL; + char buf[MIME_LINE_LEN] = {0, }; + char *name = NULL; + char *value = NULL; + char *pTemp = NULL; + int is_longheader; + + if (!em_core_check_thread_status()) { + if (err_code != NULL) + *err_code = EMF_ERROR_CANCELLED; + return false; + } + + + if ((is_file == 0 && !em_core_mime_get_line_from_sock(stream, buf, MIME_LINE_LEN, err_code)) || + (is_file == 1 && !em_core_mime_get_line_from_file(stream, buf, MIME_LINE_LEN, err_code))) { + return false; + } + + if (!(tmp_header = em_core_malloc(sizeof(struct _m_mesg_header)))) { + EM_DEBUG_EXCEPTION("malloc failed..."); + if (err_code != NULL) + *err_code = EMF_ERROR_OUT_OF_MEMORY; + return false; + } + + if (!em_core_check_thread_status()) { + if (err_code != NULL) + *err_code = EMF_ERROR_CANCELLED; + return false; + } + + while (TRUE) { + EM_DEBUG_LOG("buf[%s]", buf); + + if (!strncmp(buf, CRLF_STRING, 2)) + break; + + is_longheader = (buf[0] == ' ' || buf[0] == '\t') ? TRUE : FALSE; + + + if (!is_longheader) { /* Normal header (format : "Name : Value" or "Name : Value; Parameters" */ + if (name) { + EM_SAFE_FREE(name); + } + + /* EM_DEBUG_FUNC_BEGIN() */ + if ((pTemp = strtok(buf, ":")) == NULL) + break; + + name = EM_SAFE_STRDUP(pTemp); + + value = strtok(NULL, CRLF_STRING); + + /* --> 2007-05-16, cy */ + if (value) + if (!*++value) + break; + + em_core_mime_upper_str(name); + } + else { /* Long header */ + value = strtok(buf, CRLF_STRING); + em_core_mime_trim_left(value); + } + + /* --> 2007-05-08 by cy */ + if (!name) + break; + + EM_DEBUG_LOG("> name[%s]", name); + EM_DEBUG_LOG("> value[%s]", value); + + /* MIME Part Heade */ + if (memcmp(name, "CONTENT-", 8) == 0 && value) { + EM_DEBUG_LINE; + em_core_mime_set_part_header_value(&tmp_header->part_header, name, value, err_code); + + if (tmp_header->part_header && tmp_header->part_header->parameter) { + EM_DEBUG_LOG("name[%s]", tmp_header->part_header->parameter->name); + EM_DEBUG_LOG("value[%s]", tmp_header->part_header->parameter->value); + EM_DEBUG_LOG("next : %p", tmp_header->part_header->parameter->next); + } + + /* MIME Version Heade */ + } + else if (memcmp(name, "MIME-VERSION", 12) == 0) { + /* EM_DEBUG_FUNC_BEGIN() */ + /* ignored because we need only contents informatio */ + /* tmp_header->version = EM_SAFE_STRDUP(value) */ + + /* RFC822 Heade */ + } + else { + /* in socket stream case, ignored because we need only contents informatio */ + if (is_file == 1) + em_core_mime_set_rfc822_header_value(&tmp_rfc822header, name, value, err_code); + } + + if (!em_core_check_thread_status()) { + if (err_code != NULL) + *err_code = EMF_ERROR_CANCELLED; + return false; + } + if ((is_file == 0 && !em_core_mime_get_line_from_sock(stream, buf, MIME_LINE_LEN, err_code)) || + (is_file == 1 && !em_core_mime_get_line_from_file(stream, buf, MIME_LINE_LEN, err_code))) { + + if (tmp_rfc822header) + em_core_mime_free_rfc822_header(tmp_rfc822header); + + + if (tmp_header) { + em_core_mime_free_part_header(tmp_header->part_header); + + EM_SAFE_FREE(tmp_header->version); + EM_SAFE_FREE(tmp_header); + } + return false; + } + } + + *header = tmp_header; + *rfc822header = tmp_rfc822header; + + EM_SAFE_FREE(name); + EM_DEBUG_FUNC_END(); + return true; +} + +int em_core_mime_parse_part_header(void *stream, int is_file, struct _m_part_header **header, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("stream[%p], is_file[%d], header[%p], err_code[%p]", stream, is_file, header, err_code); + + struct _m_part_header *tmp_header = NULL; + char buf[MIME_LINE_LEN] = {0x00}; + char *name = NULL; + char *value = NULL; + char *p = NULL; + int is_longheader = false; + + if (!em_core_check_thread_status()) { + if (err_code != NULL) + *err_code = EMF_ERROR_CANCELLED; + return false; + } + + if ((is_file == 0 && !em_core_mime_get_line_from_sock(stream, buf, MIME_LINE_LEN, err_code)) || + (is_file == 1 && !em_core_mime_get_line_from_file(stream, buf, MIME_LINE_LEN, err_code))) + return false; + + tmp_header = em_core_malloc(sizeof(struct _m_part_header)); + + if (!tmp_header) { + EM_DEBUG_EXCEPTION("em_core_malloc failed"); + return false; + } + + memset(tmp_header, 0, sizeof(struct _m_part_header)); + + while (true) { + if (!strncmp(buf, CRLF_STRING, strlen(CRLF_STRING))) break; + + is_longheader = (buf[0] == ' ' || buf[0] == TAB); + + if (!is_longheader) { /* Normal header (format : "Name : Value" or "Name : Value; Parameters" */ + EM_SAFE_FREE(name); + p = strtok(buf , ":"); + + if (p) { + name = EM_SAFE_STRDUP(p); + value = strtok(NULL, CRLF_STRING); + em_core_mime_upper_str(name); + } + } + else /* Long header */ + value = strtok(buf, CRLF_STRING); + + if (!name) + break; + + em_core_mime_set_part_header_value(&tmp_header, name, value, err_code); + + if (!em_core_check_thread_status()) { + if (err_code != NULL) + *err_code = EMF_ERROR_CANCELLED; + return false; + } + + if ((is_file == 0 && !em_core_mime_get_line_from_sock(stream, buf, MIME_LINE_LEN, err_code)) || + (is_file == 1 && !em_core_mime_get_line_from_file(stream, buf, MIME_LINE_LEN, err_code))) { + EM_SAFE_FREE(name); + EM_SAFE_FREE(tmp_header); + + return false; + } + } + + *header = tmp_header; + + EM_SAFE_FREE(name); + EM_DEBUG_FUNC_END(); + return true; +} + + +int em_core_mime_parse_body(void *stream, int is_file, struct _m_mesg *mmsg, struct _m_content_info *cnt_info, void *callback, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("stream[%p], is_file[%d], mmsg[%p], cnt_info[%p], callback[%p], err_code[%p]", stream, is_file, mmsg, cnt_info, callback, err_code); + + char *content_type = NULL, *content_encoding = NULL, *holder = NULL, *attachment_name, *t = NULL; + int type = 0, end_of_parsing = 0, size, local_err_code = EMF_ERROR_NONE; + + if (!em_core_check_thread_status()) { + if (err_code != NULL) + *err_code = EMF_ERROR_CANCELLED; + return false; + } + + if (mmsg->header) + content_type = em_core_mime_get_header_value(mmsg->header->part_header, CONTENT_TYPE, err_code); + if (!content_type) + content_type = "TEXT/PLAIN"; + + if (mmsg->header) + content_encoding = em_core_mime_get_header_value(mmsg->header->part_header, CONTENT_ENCODING, err_code); + if (!content_encoding) + content_encoding = "7BIT"; + + if (strstr(content_type, TEXT_STR)) type = TYPE_TEXT; + else if (strstr(content_type, IMAGE_STR)) type = TYPE_IMAGE; + else if (strstr(content_type, AUDIO_STR)) type = TYPE_AUDIO; + else if (strstr(content_type, VIDEO_STR)) type = TYPE_VIDEO; + else if (strstr(content_type, APPLICATION_STR)) type = TYPE_APPLICATION; + else if (strstr(content_type, MULTIPART_STR)) type = TYPE_MULTIPART; + else if (strstr(content_type, MESSAGE_STR)) type = TYPE_MESSAGE; + else type = TYPE_UNKNOWN; + + switch (type) { + case TYPE_MULTIPART: + if (mmsg->header && !em_core_mime_get_header_value(mmsg->header->part_header, CONTENT_BOUNDARY, err_code)) { + EM_DEBUG_FUNC_END("false"); + return false; + } + + if (mmsg->header && !em_core_mime_parse_part(stream, is_file, mmsg->header->part_header, &mmsg->nested, cnt_info, &end_of_parsing, &local_err_code)) { + EM_DEBUG_FUNC_END("false"); + return false; + } + + /* after finishing body parsing, make stream empty to get next mail. (get line from sock or file until '.' is read */ + if (end_of_parsing == true && local_err_code != EMF_ERROR_NO_MORE_DATA) + em_core_mime_flush_receiving_buffer(stream, is_file, NULL, NULL, NULL, err_code); + + if (err_code) + *err_code = local_err_code; + + break; + + default: + attachment_name = NULL; + + if (mmsg->header && em_core_mime_get_header_value(mmsg->header->part_header, CONTENT_DISPOSITION, err_code)) { + attachment_name = em_core_mime_get_header_value(mmsg->header->part_header, CONTENT_FILENAME, err_code); + /* if (!attachment_name) attachment_name = "unknown" */ + if (attachment_name) EM_DEBUG_LOG(" attachment = [%s]", attachment_name); + } + + if (cnt_info->grab_type & GRAB_TYPE_TEXT) { + /* EM_DEBUG_LINE */ + /* get content data. content data is saved in file */ + em_core_mime_get_content_data(stream, is_file, true, NULL, content_encoding, &end_of_parsing, SAVE_TYPE_FILE, &holder, &size, NULL, err_code); + + EM_DEBUG_LOG("After em_core_mime_get_content_data"); + + if (mmsg->header && mmsg->header->part_header && strstr((t = em_core_mime_get_header_value(mmsg->header->part_header, CONTENT_TYPE, err_code)) ? t : "", "HTML")) + cnt_info->text.html = holder; + else if (mmsg->header) { + char *charset = em_core_mime_get_header_value(mmsg->header->part_header, CONTENT_CHARSET, err_code); + + EM_DEBUG_LOG(">>>> charset [%s]", charset); + + if (!charset || !strncmp(charset, "X-UNKNOWN", strlen("X-UNKNOWN"))) + cnt_info->text.plain_charset = EM_SAFE_STRDUP("UTF-8"); + else + cnt_info->text.plain_charset = EM_SAFE_STRDUP(charset); + + EM_DEBUG_LOG(">>>> cnt_info->text.plain_charset [%s]", cnt_info->text.plain_charset); + + cnt_info->text.plain = holder; + + EM_DEBUG_LOG(">>>> cnt_info->text.plain [%s]", cnt_info->text.plain); + } + } + + break; + } + EM_DEBUG_FUNC_END(); + return true; +} + +int em_core_mime_parse_part(void *stream, int is_file, struct _m_part_header *parent_header, struct _m_part *nested, struct _m_content_info *cnt_info, int *eop, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("stream[%p], is_file[%d], parent_header[%p], nested[%p], cnt_info[%p], eop[%p], err_code[%p]", stream, is_file, parent_header, nested, cnt_info, eop, err_code); + + struct _m_body *tmp_body = NULL; + struct _m_part **p = NULL; + char buf[MIME_LINE_LEN] = {0x00, }; + char boundary[BOUNDARY_LEN] = {0x00, }; + char boundary_end[BOUNDARY_LEN] = {0x00, }; + char *boundary_str = NULL; + char *content_type = NULL; + char *content_encoding = NULL; + char *holder = NULL; + char *attachment_name = NULL; + char *t = NULL; + int type = 0; + int end_of_parsing = 0; + int size = 0, local_err_code = EMF_ERROR_NONE; + int is_skip = false; + char *pTemp = NULL; + + boundary_str = em_core_mime_get_header_value(parent_header, CONTENT_BOUNDARY, err_code); + + SNPRINTF(boundary, BOUNDARY_LEN, "--%s%s", boundary_str, CRLF_STRING); + SNPRINTF(boundary_end, BOUNDARY_LEN, "--%s%s", boundary_str, "--\r\n"); + + nested->body = NULL; + nested->next = NULL; + + /* goto the first found useful mime dat */ + EM_DEBUG_LOG("Before first loop"); + while (true) { + if (!em_core_check_thread_status()) { + if (err_code != NULL) + *err_code = EMF_ERROR_CANCELLED; + return false; + } + if ((is_file == 0 && !em_core_mime_get_line_from_sock(stream, buf, MIME_LINE_LEN, err_code)) || + (is_file == 1 && !em_core_mime_get_line_from_file(stream, buf, MIME_LINE_LEN, err_code))) { + EM_DEBUG_EXCEPTION("em_core_mime_get_line_from_sock failed."); + if (eop) + *eop = true; + EM_DEBUG_FUNC_END("false"); + return false; + } + + if (!strcmp(buf, boundary)) + break; + } + + EM_DEBUG_LOG("Before second loop"); + while (true) { + if (!(tmp_body = em_core_malloc(sizeof(struct _m_body)))) { + EM_DEBUG_EXCEPTION("em_core_malloc failed."); + if (nested->body) + em_core_mime_free_part_body(nested->body); + if (nested->next) + em_core_mime_free_part(nested->next); + EM_DEBUG_FUNC_END("false"); + return false; + } + + memset(tmp_body, 0, sizeof(struct _m_body)); + + /* parsing MIME Header */ + if (!em_core_mime_parse_part_header(stream, is_file, &tmp_body->part_header, err_code)) { + EM_DEBUG_EXCEPTION("em_core_mime_parse_part_header failed."); + if (nested->body) + em_core_mime_free_part_body(nested->body); + if (nested->next) + em_core_mime_free_part(nested->next); + + em_core_mime_free_part_body(tmp_body); + return false; + } + + content_type = em_core_mime_get_header_value(tmp_body->part_header, CONTENT_TYPE, err_code); + if (!content_type) + content_type = "TEXT/PLAIN"; + + content_encoding = em_core_mime_get_header_value(tmp_body->part_header, CONTENT_ENCODING, err_code); + if (!content_encoding) + content_encoding = "7BIT"; + + if (strstr(content_type, TEXT_STR)) type = TYPE_TEXT; + else if (strstr(content_type, IMAGE_STR)) type = TYPE_IMAGE; + else if (strstr(content_type, AUDIO_STR)) type = TYPE_AUDIO; + else if (strstr(content_type, VIDEO_STR)) type = TYPE_VIDEO; + else if (strstr(content_type, APPLICATION_STR)) type = TYPE_APPLICATION; + else if (strstr(content_type, MULTIPART_STR)) type = TYPE_MULTIPART; + else if (strstr(content_type, MESSAGE_STR)) type = TYPE_MESSAGE; + else type = TYPE_UNKNOWN; + + switch (type) { + case TYPE_MULTIPART: + EM_DEBUG_LOG("TYPE_MULTIPART"); + if (!em_core_mime_get_header_value(tmp_body->part_header, CONTENT_BOUNDARY, err_code)) { + EM_DEBUG_EXCEPTION("em_core_mime_get_header_value failed."); + em_core_mime_free_part_body(tmp_body); + EM_DEBUG_FUNC_END("false"); + return false; + } + + em_core_mime_parse_part(stream, is_file, tmp_body->part_header, &tmp_body->nested, cnt_info, &end_of_parsing, &local_err_code); + + if (!nested->body) + nested->body = tmp_body; + else { + p = &nested->next; + + while (*p && (*p)->next) + *p = (*p)->next; + + if (*p) + p = &(*p)->next; + + if (!(*p = em_core_malloc(sizeof(struct _m_part)))) { + EM_DEBUG_EXCEPTION("em_core_malloc failed"); + if (nested->body) em_core_mime_free_part_body(nested->body); + if (nested->next) em_core_mime_free_part(nested->next); + em_core_mime_free_part_body(tmp_body); + EM_DEBUG_FUNC_END("false"); + return false; + } + + (*p)->body = tmp_body; + (*p)->next = NULL; + } + + if (err_code) + *err_code = local_err_code; + + if (end_of_parsing && local_err_code != EMF_ERROR_NO_MORE_DATA) /* working with imap */ + /* if (!end_of_parsing) */ /* working with pop */ { + EM_DEBUG_LOG("Enter flushing socket buffer."); + em_core_mime_flush_receiving_buffer(stream, is_file, boundary, boundary_end, &end_of_parsing, err_code); + } + + break; + + default: + EM_DEBUG_LOG("default"); + attachment_name = NULL; + + if (type == TYPE_MESSAGE) + is_skip = true; + + if (is_skip == true) { + if (!em_core_mime_skip_content_data(stream, is_file, boundary_str, &end_of_parsing, &size, NULL, err_code)) + EM_DEBUG_EXCEPTION("em_core_mime_skip_content_data failed..."); + + em_core_mime_free_part_body(tmp_body); + EM_DEBUG_LOG_MIME("break"); + break; + } + + /* first check inline content */ + /* if the content id or content location exis */ + attachment_name = em_core_mime_get_header_value(tmp_body->part_header, CONTENT_ID, err_code); + if (!attachment_name) + attachment_name = em_core_mime_get_header_value(tmp_body->part_header, CONTENT_LOCATION, err_code); + + if (!attachment_name) { + /* check if the content is attachment */ + /* if Content-Disposition Header exists, the content is attachment */ + if (em_core_mime_get_header_value(tmp_body->part_header, CONTENT_DISPOSITION, err_code)) { + attachment_name = em_core_mime_get_header_value(tmp_body->part_header, CONTENT_FILENAME, err_code); + EM_DEBUG_LOG_MIME(">> attachment = [%s]", attachment_name ? attachment_name : NIL); + } + } + + if (!em_core_check_thread_status()) { + if (err_code != NULL) + *err_code = EMF_ERROR_CANCELLED; + EM_DEBUG_EXCEPTION("EMF_ERROR_CANCELLED"); + EM_DEBUG_FUNC_END("false"); + return false; + } + /* get content and content informatio */ + if (!attachment_name) { /* text */ + /* get content by buffe */ + EM_DEBUG_LOG_MIME("attachment_name is NULL. It's a text message"); + em_core_mime_get_content_data(stream, is_file, true, boundary_str, content_encoding, &end_of_parsing, SAVE_TYPE_FILE, &holder, &size, NULL, err_code); + + EM_DEBUG_LOG("After em_core_mime_get_content_data"); + + if (cnt_info->grab_type & GRAB_TYPE_TEXT) { + if (tmp_body->part_header && strstr((t = em_core_mime_get_header_value(tmp_body->part_header, CONTENT_TYPE, err_code)) ? t : "", "HTML")) { + cnt_info->text.html = holder; + + EM_DEBUG_LOG(" cnt_info->text.html [%s]", cnt_info->text.html); + } + else { + char *charset = em_core_mime_get_header_value(tmp_body->part_header, CONTENT_CHARSET, err_code); + EM_DEBUG_LOG(" charset [%s]", charset); + + if (!charset || !strncmp(charset, "X-UNKNOWN", strlen("X-UNKNOWN"))) + cnt_info->text.plain_charset = EM_SAFE_STRDUP("UTF-8"); + else + cnt_info->text.plain_charset = EM_SAFE_STRDUP(charset); + + EM_DEBUG_LOG(" cnt_info->text.plain_charset [%s]", cnt_info->text.plain_charset); + + cnt_info->text.plain = holder; + + EM_DEBUG_LOG(" cnt_info->text.plain [%s]", cnt_info->text.plain); + } + } + else { + if (holder) { + free(holder); + holder = NULL; + } + } + } + else { /* attachmen */ + EM_DEBUG_LOG_MIME("attachment_name is not NULL. It's a attachment"); + struct attachment_info **file = &cnt_info->file; + int i = 1; + + while (*file && (*file)->next) { + file = &(*file)->next; + i++; + } + + if (*file) { + file = &(*file)->next; + i++; + } + + *file = em_core_malloc(sizeof(struct attachment_info)); + if (*file) { + if ((em_core_mime_get_header_value(tmp_body->part_header, CONTENT_ID, err_code)) || + (em_core_mime_get_header_value(tmp_body->part_header, CONTENT_LOCATION, err_code))) { /* this is inline conten */ + (*file)->type = 1; + } + else { /* this is attachment conten */ + (*file)->type = 2; + } + EM_DEBUG_LOG_MIME("file->type : %d", (*file)->type); + + (*file)->name = cpystr(attachment_name); + + /* check if the current file is target file */ + if (cnt_info->grab_type & GRAB_TYPE_ATTACHMENT || (*file)->type == 1) { + /* get content by fil */ + EM_DEBUG_LOG_MIME("Trying to get content"); + em_core_mime_get_content_data(stream, is_file, false, boundary_str, content_encoding, &end_of_parsing, SAVE_TYPE_FILE, &holder, &size, NULL, err_code); + (*file)->save = holder; + } + else { + /* only get content siz */ + EM_DEBUG_LOG_MIME("Pass downloading"); + em_core_mime_get_content_data(stream, is_file, false, boundary_str, content_encoding, &end_of_parsing, SAVE_TYPE_SIZE, NULL, &size, NULL, err_code); + (*file)->save = NULL; + } + + if (err_code) + EM_DEBUG_LOG("end_of_parsing [%d], err_code [%d]", end_of_parsing, *err_code); + + (*file)->size = size; + + if (strstr(content_type, APPLICATION_STR)) { + pTemp = content_type + strlen(APPLICATION_STR); + + if (strcasecmp(pTemp, MIME_SUBTYPE_DRM_OBJECT) == 0) + (*file)->drm = EMF_ATTACHMENT_DRM_OBJECT; + else if (strcasecmp(pTemp, MIME_SUBTYPE_DRM_RIGHTS) == 0) + (*file)->drm = EMF_ATTACHMENT_DRM_RIGHTS; + else if (strcasecmp(pTemp, MIME_SUBTYPE_DRM_DCF) == 0) + (*file)->drm = EMF_ATTACHMENT_DRM_DCF; + } + } + else { + EM_DEBUG_EXCEPTION("em_core_malloc failed..."); + em_core_mime_free_part_body(tmp_body); + EM_DEBUG_FUNC_END("false"); + return false; + } + } + + if (!em_core_check_thread_status()) { + if (err_code != NULL) + *err_code = EMF_ERROR_CANCELLED; + EM_DEBUG_EXCEPTION("EMF_ERROR_CANCELLED"); + EM_DEBUG_FUNC_END("false"); + return false; + } + + if (!nested->body) + nested->body = tmp_body; + else { + p = &nested->next; + + while (*p && (*p)->next) + p = &(*p)->next; + + if (*p) + p = &(*p)->next; + + if (!(*p = em_core_malloc(sizeof(struct _m_part)))) { + EM_DEBUG_EXCEPTION("em_core_malloc failed"); + if (nested->body) em_core_mime_free_part_body(nested->body); + if (nested->next) em_core_mime_free_part(nested->next); + + em_core_mime_free_part_body(tmp_body); + EM_DEBUG_FUNC_END("false"); + return false; + } + + (*p)->body = tmp_body; + (*p)->next = NULL; + } + + break; + } + + /* End of parsin */ + if (end_of_parsing) + break; + } + + if (eop != NULL) + *eop = end_of_parsing; + + EM_DEBUG_FUNC_END("end_of_parsing [%d]", end_of_parsing); + return true; +} + +/* set RFC822 Heade */ +int em_core_mime_set_rfc822_header_value(struct _rfc822header **header, char *name, char *value, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("header[%p], name[%s], value[%s], err_code[%p]", header, name, value, err_code); + + char **p = NULL; + char *t = NULL; + + /* ? ? ? why return value is 1 */ + if (!value || !*value) return true; + + if (!*header) { + *header = em_core_malloc(sizeof(struct _rfc822header)); + if (!*header) { + EM_DEBUG_EXCEPTION("em_core_malloc failed"); + return false; + } + } + + if (name) { + em_core_mime_upper_str(name); + + if (strncmp(name, "RETURN-PATH", strlen("RETURN-PATH")) == 0) + p = &(*header)->return_path;/* Return-Rat */ + else if (strncmp(name, "RECEIVED", strlen("RECEIVED")) == 0) + p = &(*header)->received; /* Receive */ + else if (strncmp(name, "REPLY-TO", strlen("REPLY-TO")) == 0) + p = &(*header)->reply_to; /* Reply-T */ + else if (strncmp(name, "DATE", strlen("DATE")) == 0) + p = &(*header)->date; /* Dat */ + else if (strncmp(name, "FROM", strlen("FROM")) == 0) + p = &(*header)->from; /* Fro */ + else if (strncmp(name, "SUBJECT", strlen("SUBJECT")) == 0) + p = &(*header)->subject; /* Subjec */ + else if (strncmp(name, "SENDER", strlen("SENDER")) == 0) + p = &(*header)->sender; /* Sende */ + else if (strncmp(name, "TO", strlen("TO")) == 0) + p = &(*header)->to; /* T */ + else if (strncmp(name, "CC", strlen("CC")) == 0) + p = &(*header)->cc; /* C */ + else if (strncmp(name, "BCC", strlen("BCC")) == 0) + p = &(*header)->bcc; /* Bc */ + else if (strncmp(name, "X-PRIORITY", strlen("X-PRIORITY")) == 0) + p = &(*header)->priority; /* Prorit */ + else if (strncmp(name, "X-MSMAIL-PRIORITY", strlen("X-MSMAIL-PRIORITY")) == 0) + p = &(*header)->ms_priority;/* Prorit */ + else if (strncmp(name, "DISPOSITION-NOTIFICATION-TO", strlen("DISPOSITION-NOTIFICATION-TO")) == 0) + p = &(*header)->dsp_noti_to;/* Disposition-Notification-T */ + else { + return false; + } + } + + if (p) { + if (!*p) + *p = EM_SAFE_STRDUP(value); + else { /* Long Heade */ + if (!(t = realloc(*p, strlen(*p) + strlen(value)+1))) + return false; + + strncat(t, value, strlen(value)); + *p = t; + } + } + + return true; +} + +/* set MIME Part Heade */ +int em_core_mime_set_part_header_value(struct _m_part_header **header, char *name, char *value, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("header[%p], name[%s], value[%s], err_code[%p]", header, name, value, err_code); + + if (!name || !value) { + EM_DEBUG_EXCEPTION("Invalid parameter"); + if (err_code != NULL) + *err_code = EMF_ERROR_INVALID_PARAM; + return false; + } + + struct _parameter *p = NULL; + char *p_val = NULL; + + if (!*header) { + *header = em_core_malloc(sizeof(struct _m_part_header)); + if (!(*header)) { + EM_DEBUG_EXCEPTION("em_core_malloc failed..."); + return false; + } + } + + em_core_mime_upper_str(name); + em_core_mime_trim_left(value); + em_core_mime_trim_right(value); + + if (!em_core_check_thread_status()) { + if (err_code != NULL) + *err_code = EMF_ERROR_CANCELLED; + return false; + } + + if (name) { + if (strncmp(name, "CONTENT-TYPE", strlen("CONTENT-TYPE")) == 0) { + p_val = strtok(value, ";"); + + if (p_val) { + if (!(*header)->type) { /* Content-Type */ + em_core_mime_upper_str(p_val); + (*header)->type = EM_SAFE_STRDUP(p_val); + } + else { /* Content-Type Parameter (format : "name =value" */ + if (em_core_mime_get_param_from_str(p_val, &p, err_code)) + em_core_mime_add_param_to_list(&((*header)->parameter), p, err_code); + } + + /* repeatedly get paramete */ + while ((p_val = strtok(NULL, ";"))) { + if (em_core_mime_get_param_from_str(p_val, &p, err_code)) + em_core_mime_add_param_to_list(&((*header)->parameter), p, err_code); + } + } + } + else if (strncmp(name, "CONTENT-TRANSFER-ENCODING", strlen("CONTENT-TRANSFER-ENCODING")) == 0) { + em_core_mime_upper_str(value); + (*header)->encoding = EM_SAFE_STRDUP(value); + } + else if (strncmp(name, "CONTENT-DESCRPTION", strlen("CONTENT-DESCRPTION")) == 0) { + em_core_mime_upper_str(value); + (*header)->desc = EM_SAFE_STRDUP(value); + } + else if (strncmp(name, "CONTENT-DISPOSITION", strlen("CONTENT-DISPOSITION")) == 0) { + p_val = strtok(value, ";"); + + if (p_val) { + if (!(*header)->disp_type) { /* Content-Dispositio */ + em_core_mime_upper_str(p_val); + (*header)->disp_type = EM_SAFE_STRDUP(p_val); + } + else { /* Content-Disposition parameter (format : "name =value" */ + if (em_core_mime_get_param_from_str(p_val, &p, err_code)) + em_core_mime_add_param_to_list(&((*header)->disp_parameter), p, err_code); + } + + /* repeatedly get paramete */ + while ((p_val = strtok(NULL, ";"))) { + if (em_core_mime_get_param_from_str(p_val, &p, err_code)) + em_core_mime_add_param_to_list(&((*header)->disp_parameter), p, err_code); + } + } + } + else if (strncmp(name, "CONTENT-ID", strlen("CONTENT-ID")) == 0) { + size_t len = 0; + len = strlen(value); + /* em_core_mime_upper_str(value) */ + + if ((len) && (value[0] == '<')) { + ++value; + --len; + } + + if ((len > 1) && (value[len-1] == '>')) + value[len-1] = '\0'; + + (*header)->content_id = EM_SAFE_STRDUP(value); + } + else if (strncmp(name, "CONTENT-LOCATION", strlen("CONTENT-LOCATION")) == 0) + (*header)->content_location = EM_SAFE_STRDUP(value); + } + EM_DEBUG_FUNC_END(); + return true; +} + +/* get header parameter from strin */ +int em_core_mime_get_param_from_str(char *str, struct _parameter **param, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("str[%s], param[%p], err_code[%p]", str, param, err_code); + + char *p_name, *p_val, *p; + + *param = NULL; + + /* Parameter Chec */ + if (!(p = strchr(str, '='))) return false; + + *p = '\0'; + + p_name = str; + p_val = p+1; + + em_core_mime_trim_left(p_name); + em_core_mime_trim_right(p_name); + + if (!*p_name) return false; + + em_core_mime_trim_left(p_val); + em_core_mime_trim_right(p_val); + + if (!*p_val) return false; + + if (!(*param = em_core_malloc(sizeof(struct _parameter)))) return false; + + (*param)->next = NULL; + + /* Name se */ + /* check string lengt */ + if (strlen(p_name) > 0) { + em_core_mime_upper_str(p_name); + (*param)->name = EM_SAFE_STRDUP(p_name); + } + + if (strlen(p_val) > 0) { + if ((p = strchr(p_val, '\"'))) { + p_val = p + 1; + if (!*p_val) return false; + } + if ((p = strchr(p_val, '\"'))) + *p = '\0'; + + if (strncmp(p_name, "BOUNDARY", strlen("BOUNDARY")) != 0 && !strstr(p_name, "NAME")) + em_core_mime_upper_str(p_val); + + /* = ? ENCODING_TYPE ? B(Q) ? ENCODED_STRING ? */ + int err = EMF_ERROR_NONE; + char *utf8_text = NULL; + + if (!(utf8_text = em_core_decode_rfc2047_text(p_val, &err))) + EM_DEBUG_EXCEPTION("em_core_decode_rfc2047_text failed [%d]", err); + (*param)->value = utf8_text; + } + EM_DEBUG_FUNC_END(); + return true; +} + +/* add a parameter to parameter lis */ +int em_core_mime_add_param_to_list(struct _parameter **param_list, struct _parameter *param, int *err_code) +{ + struct _parameter **t = param_list; + + while (*t && (*t)->next) + *t = (*t)->next; + + if (*t) + (*t)->next = param; + else + *t = param; + + return true; +} + +/* get header value from MIME Part Heade */ +char *em_core_mime_get_header_value(struct _m_part_header *header, int type, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("header[%p], type[%d], err_code[%p]", header, type, err_code); + + struct _parameter *p = NULL; + char *name = NULL; + + if (!header) { + EM_DEBUG_EXCEPTION("header[%p], type[%d]", header, type); + + if (err_code != NULL) + *err_code = EMF_ERROR_INVALID_PARAM; + return NULL; + } + + switch (type) { + case CONTENT_TYPE: + return header->type; + + case CONTENT_SUBTYPE: + return header->subtype; + + case CONTENT_ENCODING: + return header->encoding; + + case CONTENT_CHARSET: + name = "CHARSET"; + p = header->parameter; + break; + + case CONTENT_DISPOSITION: + return header->disp_type; + + case CONTENT_NAME: + name = "NAME"; + p = header->parameter; + break; + + case CONTENT_FILENAME: + name = "FILENAME"; + p = header->disp_parameter; + break; + + case CONTENT_BOUNDARY: + name = "BOUNDARY"; + p = header->parameter; + break; + + case CONTENT_REPORT_TYPE: + name = "REPORT-TYPE"; + p = header->parameter; + break; + + case CONTENT_ID: + return header->content_id; + + case CONTENT_LOCATION: + return header->content_location; + + default: + return NULL; + } + + for (; p; p = p->next) { + if (strcmp(p->name, name) == 0) + break; + } + + if (!p) + return NULL; + EM_DEBUG_FUNC_END(); + return p->value; +} + +/* + * decode body text (quoted-printable, base64) + * enc_type : encoding type (base64/quotedprintable) + */ +EXPORT_API int em_core_decode_body_text(char *enc_buf, int enc_len, int enc_type, int *dec_len, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("enc_buf[%p], enc_len[%d], enc_type[%d], dec_len[%p]", enc_buf, enc_len, enc_type, dec_len); + unsigned char *content = NULL; + + /* too many called */ + *dec_len = enc_len; + + switch (enc_type) { + case ENCQUOTEDPRINTABLE: + EM_DEBUG_LOG("ENCQUOTEDPRINTABLE"); + content = rfc822_qprint((unsigned char *)enc_buf, (unsigned long)enc_len, (unsigned long *)dec_len); + break; + + case ENCBASE64: + EM_DEBUG_LOG("ENCBASE64"); + content = rfc822_base64((unsigned char *)enc_buf, (unsigned long)enc_len, (unsigned long *)dec_len); + break; + + case ENC7BIT: + case ENC8BIT: + case ENCBINARY: + case ENCOTHER: + default: + break; + } + + if (content) { + if (enc_len < *dec_len) { + EM_DEBUG_EXCEPTION("Decoded length is too big to store it"); + return -1; + } + memcpy(enc_buf, content, *dec_len); + enc_buf[*dec_len] = '\0'; + EM_SAFE_FREE(content); + } + EM_DEBUG_FUNC_END(); + return 0; +} + +/* 1. if boundary is NULL, contnent has not multipart */ +/* 2. if boundary isn't NULL, content is from current line to the next found boundary */ +/* if next found boundary is the other part boundary ("--boundary"), return and set end_of_parsing to 1 */ +/* if next found boundary is the multipart ending boundary ("--boundary--"), return and set end_of_parsing to 0 */ +/* mode - SAVE_TYPE_SIZE : no saving (only hold content size */ +/* SAVE_TYPE_BUFFER : content is saved to buffer (holder is buffer */ +/* SAVE_TYPE_FILE : content is saved to temporary file (holder is file name */ +int em_core_mime_get_content_data(void *stream, int is_file, int is_text, char *boundary_str, char *content_encoding, int *end_of_parsing, int mode, char **holder, int *size, void *callback, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("stream[%p], is_file[%d], boundary_str[%s], content_encoding[%s], end_of_parsing[%p], mode[%d], holder[%p], size[%p], callback[%p], err_code[%p]", stream, is_file, boundary_str, content_encoding, end_of_parsing, mode, holder, size, callback, err_code); + + char buf[MIME_LINE_LEN] = {0x00, }; + char boundary[BOUNDARY_LEN] = {0x00, }; + char boundary_end[BOUNDARY_LEN] = {0x00, }; + char *result_buffer = NULL; + int sz = 0, fd = 0, result_buffer_size = 0;; + int encoding = ENC7BIT; + int dec_len = 0; + int error = EMF_ERROR_NONE, ret = false; + char *pTemp = NULL; + + if ((mode == SAVE_TYPE_FILE || mode == SAVE_TYPE_BUFFER) && !holder) + return false; + + if (holder) + *holder = NULL; + + if (size) + *size = 0; + + EM_DEBUG_LOG("get content"); + + if (content_encoding) { + switch (content_encoding[0]) { + case 'Q': + encoding = ENCQUOTEDPRINTABLE; + break; /* qutoed-printabl */ + case 'B': + if (content_encoding[1] == 'A') { + encoding = ENCBASE64; + break; /* base6 */ + } + if (content_encoding[1] == 'I') { + encoding = ENCBINARY; + break; /* binar */ + } + case '7': + encoding = ENC7BIT; + break; /* 7bi */ + case '8': + encoding = ENC8BIT; + break; /* 8bi */ + default: + encoding = ENCOTHER; + break; /* unknow */ + } + } + + /* saving type is file */ + if (mode == SAVE_TYPE_FILE) { + *holder = em_core_mime_get_save_file_name(err_code); + + EM_DEBUG_LOG("holder[%s]", *holder); + + fd = open(*holder, O_WRONLY|O_CREAT, 0644); + if (fd <= 0) { + EM_DEBUG_EXCEPTION("holder open failed : holder is a filename that will be saved."); + goto FINISH_OFF; + } + } + + if (boundary_str) { + /* if there boundary, this content is from current line to ending boundary */ + memset(boundary, 0x00, BOUNDARY_LEN); + memset(boundary_end, 0x00, BOUNDARY_LEN); + + SNPRINTF(boundary, BOUNDARY_LEN, "--%s%s", boundary_str, CRLF_STRING); + SNPRINTF(boundary_end, BOUNDARY_LEN, "--%s%s", boundary_str, "--\r\n"); + } + + while (TRUE) { + if (!em_core_check_thread_status()) { + EM_DEBUG_EXCEPTION("EMF_ERROR_CANCELLED"); + error = EMF_ERROR_CANCELLED; + goto FINISH_OFF; + } + + if ((is_file == 0 && !em_core_mime_get_line_from_sock(stream, buf, MIME_LINE_LEN, &error)) || + (is_file == 1 && !em_core_mime_get_line_from_file(stream, buf, MIME_LINE_LEN, &error))) { + if (error == EMF_ERROR_NO_MORE_DATA) + EM_DEBUG_EXCEPTION("End of data"); + else + EM_DEBUG_EXCEPTION("em_core_mime_get_line_from_sock failed"); + *end_of_parsing = 1; + + ret = true; + goto FINISH_OFF; + } + + if (boundary_str) { + if (!strcmp(buf, boundary)) { /* the other part started. the parsing of other part will be started */ + *end_of_parsing = 0; + ret = true; + goto FINISH_OFF; + } + else if (!strcmp(buf, boundary_end)) { /* if ending boundary, the parsing of other multipart will be started */ + *end_of_parsing = 1; + ret = true; + goto FINISH_OFF; + } + } + + /* parsing string started by '.' in POP3 */ + if ((buf[0] == '.' && buf[1] == '.') && (encoding == ENCQUOTEDPRINTABLE || encoding == ENC7BIT)) { + strncpy(buf, buf+1, MIME_LINE_LEN-1); + buf[strlen(buf)] = NULL_CHAR; + } + + if (encoding == ENCBASE64) { + if (strlen(buf) >= 2) + buf[strlen(buf)-2] = NULL_CHAR; + } + else if (encoding == ENCQUOTEDPRINTABLE) { +/* if (strcmp(buf, CRLF_STRING) == 0 */ +/* continue */ + } + + dec_len = strlen(buf); + + if (mode > SAVE_TYPE_SIZE) { /* decode conten */ + em_core_decode_body_text(buf, dec_len, encoding, &dec_len, err_code); + + if (is_text) { + result_buffer = em_core_replace_string(buf, "cid:", ""); + if (result_buffer) + result_buffer_size = strlen(result_buffer); + } + + if (result_buffer == NULL) { + result_buffer = buf; + result_buffer_size = dec_len; + } + + if (result_buffer) { + if (mode == SAVE_TYPE_BUFFER) { /* save content to buffe */ + pTemp = realloc(*holder, sz + result_buffer_size + 2); + if (!pTemp) { + EM_DEBUG_EXCEPTION("realloc failed..."); + error = EMF_ERROR_OUT_OF_MEMORY; + + EM_SAFE_FREE(*holder); + EM_SAFE_FREE(result_buffer); + goto FINISH_OFF; + } + else + *holder = pTemp; + + memcpy(*holder + sz, result_buffer, result_buffer_size); + (*holder)[sz + strlen(result_buffer) + 1] = NULL_CHAR; + } + else if (mode == SAVE_TYPE_FILE) { /* save content to fil */ + if (write(fd, result_buffer, result_buffer_size) != result_buffer_size) { + if (is_text && (result_buffer != buf)) + EM_SAFE_FREE(result_buffer); + EM_DEBUG_EXCEPTION("write failed"); + error = EMF_ERROR_SYSTEM_FAILURE; + goto FINISH_OFF; + } + } + if (is_text && (result_buffer != buf)) + EM_SAFE_FREE(result_buffer); + result_buffer = NULL; + } + } + sz += dec_len; + } + + ret = true; +FINISH_OFF: + if (err_code != NULL) + *err_code = error; + + if (fd > 0) + close(fd); + + if (ret) { + if (size) + *size = sz; + } + + EM_DEBUG_FUNC_END("ret [%d], sz [%d]", ret, sz); + return ret; +} + +int em_core_mime_skip_content_data(void *stream, + int is_file, + char *boundary_str, + int *end_of_parsing, + int *size, + void *callback, + int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("stream[%p], is_file[%d], boundary_str[%s], end_of_parsing[%p], size[%p], callback[%p], err_code[%p]", stream, is_file, boundary_str, end_of_parsing, size, callback, err_code); + + char buf[MIME_LINE_LEN] = {0x00}, boundary[BOUNDARY_LEN], boundary_end[BOUNDARY_LEN]; + int sz = 0; + + if (size) + *size = 0; + + EM_DEBUG_LOG(">>> skip content <<<<<<<<<<<<<"); + + if (!boundary_str) { /* if no boundary, this content is from current line to end of all multipart */ + while (TRUE) { + + if (!em_core_check_thread_status()) { + if (err_code != NULL) + *err_code = EMF_ERROR_CANCELLED; + return false; + } + if ((is_file == 0 && !em_core_mime_get_line_from_sock(stream, buf, MIME_LINE_LEN, err_code)) || + (is_file == 1 && !em_core_mime_get_line_from_file(stream, buf, MIME_LINE_LEN, err_code))) { + *end_of_parsing = 1; + if (size) + *size = sz; + return false; + } + sz += strlen(buf); + } + } + else { /* if there boundary, this content is from current line to ending boundary */ + memset(boundary, 0x00, BOUNDARY_LEN); + memset(boundary_end, 0x00, BOUNDARY_LEN); + + SNPRINTF(boundary, BOUNDARY_LEN, "--%s%s", boundary_str, CRLF_STRING); + SNPRINTF(boundary_end, BOUNDARY_LEN, "--%s%s", boundary_str, "--\r\n"); + + while (TRUE) { + + if (!em_core_check_thread_status()) { + if (err_code != NULL) + *err_code = EMF_ERROR_CANCELLED; + return false; + } + if ((is_file == 0 && !em_core_mime_get_line_from_sock(stream, buf, MIME_LINE_LEN, err_code)) || + (is_file == 1 && !em_core_mime_get_line_from_file(stream, buf, MIME_LINE_LEN, err_code))) { + /* end of fil */ + *end_of_parsing = 1; + if (size) + *size = sz; + return true; + } + + if (!strcmp(buf, boundary)) { /* the other part started. the parsing of other part will be started */ + *end_of_parsing = 0; + if (size) + *size = sz; + return true; + } + else if (!strcmp(buf, boundary_end)) { /* if ending boundary, the parsing of other multipart will be started */ + *end_of_parsing = 1; + if (size) + *size = sz; + return true; + } + + sz += strlen(buf); + } + } + + if (size) + *size = sz; + EM_DEBUG_FUNC_END(); + return true; +} + +/* get temporary file nam */ +char *em_core_mime_get_save_file_name(int *err_code) +{ + EM_DEBUG_FUNC_BEGIN(); + char tempname[512]; + struct timeval tv; + + gettimeofday(&tv, NULL); + srand(tv.tv_usec); + + memset(tempname, 0x00, sizeof(tempname)); + + SNPRINTF(tempname, sizeof(tempname), "%s%s%s%s%d", MAILHOME, DIR_SEPERATOR, MAILTEMP, DIR_SEPERATOR, rand()); + EM_DEBUG_FUNC_END(); + return EM_SAFE_STRDUP(tempname); +} + +/* get a line from file pointer */ +char *em_core_mime_get_line_from_file(void *stream, char *buf, int size, int *err_code) +{ + if (!fgets(buf, size, (FILE *)stream)) { + if (feof((FILE *)stream)) + return NULL; + else + return NULL; + } + return buf; +} + +/* get a line from POP3 mail stream */ +/* em_core_mail_cmd_read_mail_pop3 must be called before this function */ +char *em_core_mime_get_line_from_sock(void *stream, char *buf, int size, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("stream[%p], buf[%p]", stream, buf); + POP3LOCAL *p_pop3local = NULL; + + if (!stream || !buf) { + EM_DEBUG_EXCEPTION("EMF_ERROR_INVALID_PARAM"); + if (err_code != NULL) + *err_code = EMF_ERROR_INVALID_PARAM; + return NULL; + } + + memset(buf, 0x00, size); + + p_pop3local = (POP3LOCAL *)(((MAILSTREAM *)stream)->local); + if (!p_pop3local) { + EM_DEBUG_EXCEPTION("stream->local[%p]", p_pop3local); + if (err_code != NULL) + *err_code = EMF_ERROR_INVALID_PARAM; + return NULL; + } + + if (!pop3_reply((MAILSTREAM *)stream)) { /* if TRUE, check respons */ + EM_DEBUG_LOG("p_pop3local->response 1[%s]", p_pop3local->response); + if (p_pop3local->response) { + if (*p_pop3local->response == '.' && strlen(p_pop3local->response) == 1) { + free(p_pop3local->response); + p_pop3local->response = NULL; + if (err_code != NULL) + *err_code = EMF_ERROR_NO_MORE_DATA; + EM_DEBUG_FUNC_END("end of response"); + return NULL; + } + EM_DEBUG_LOG("Not end of response"); + strncpy(buf, p_pop3local->response, size-1); + strncat(buf, CRLF_STRING, size-(strlen(buf) + 1)); + + free(p_pop3local->response); + p_pop3local->response = NULL; + + goto FINISH_OFF; + } + } + + EM_DEBUG_LOG("p_pop3local->response 2[%s]", p_pop3local->response); + if (p_pop3local->response) + { + /* if response isn't NULL, check whether this response start with '+' */ + /* if the first character is '+', return error because this response is normal data */ + strncpy(buf, p_pop3local->response, size-1); + strncat(buf, CRLF_STRING, size-(strlen(buf)+1)); + free(p_pop3local->response); p_pop3local->response = NULL; + goto FINISH_OFF; + } + else { + EM_DEBUG_EXCEPTION("p_pop3local->response is null. network error... "); + if (err_code != NULL) + *err_code = EMF_ERROR_INVALID_RESPONSE; + EM_DEBUG_FUNC_END(); + return NULL; + } + +FINISH_OFF: + if (buf) { + int received_percentage, last_notified_percentage; + _pop3_received_body_size += strlen(buf); + + last_notified_percentage = (double)_pop3_last_notified_body_size / (double)_pop3_total_body_size *100.0; + received_percentage = (double)_pop3_received_body_size / (double)_pop3_total_body_size *100.0; + + EM_DEBUG_LOG("_pop3_received_body_size = %d, _pop3_total_body_size = %d", _pop3_received_body_size, _pop3_total_body_size); + EM_DEBUG_LOG("received_percentage = %d, last_notified_percentage = %d", received_percentage, last_notified_percentage); + + if (received_percentage > last_notified_percentage + 5) { + if (!em_storage_notify_network_event(NOTI_DOWNLOAD_BODY_START, _pop3_receiving_mail_id, "dummy-file", _pop3_total_body_size, _pop3_received_body_size)) + EM_DEBUG_EXCEPTION(" em_storage_notify_network_event [NOTI_DOWNLOAD_BODY_START] Failed >>>> "); + else + EM_DEBUG_LOG("NOTI_DOWNLOAD_BODY_START notified (%d / %d)", _pop3_received_body_size, _pop3_total_body_size); + _pop3_last_notified_body_size = _pop3_received_body_size; + } + } + EM_DEBUG_FUNC_END(); + return buf; +} + +void em_core_mime_free_param(struct _parameter *param) +{ + struct _parameter *t, *p = param; + EM_DEBUG_FUNC_BEGIN(); + while (p) { + t = p->next; + EM_SAFE_FREE(p->name); + EM_SAFE_FREE(p->value); + free(p);p = NULL; + p = t; + } + EM_DEBUG_FUNC_END(); +} + +void em_core_mime_free_part_header(struct _m_part_header *header) +{ + EM_DEBUG_FUNC_BEGIN(); + if (!header) return ; + EM_SAFE_FREE(header->type); + if (header->parameter) em_core_mime_free_param(header->parameter); + EM_SAFE_FREE(header->subtype); + EM_SAFE_FREE(header->encoding); + EM_SAFE_FREE(header->desc); + EM_SAFE_FREE(header->disp_type); + if (header->disp_parameter) em_core_mime_free_param(header->disp_parameter); + free(header); header = NULL; + EM_DEBUG_FUNC_END(); +} + +void em_core_mime_free_message_header(struct _m_mesg_header *header) +{ + EM_DEBUG_FUNC_BEGIN(); + if (!header) return ; + EM_SAFE_FREE(header->version); + if (header->part_header) em_core_mime_free_part_header(header->part_header); + free(header); header = NULL; + EM_DEBUG_FUNC_END(); +} + +void em_core_mime_free_rfc822_header(struct _rfc822header *header) +{ + EM_DEBUG_FUNC_BEGIN(); + if (!header) return ; + EM_SAFE_FREE(header->return_path); + EM_SAFE_FREE(header->received); + EM_SAFE_FREE(header->reply_to); + EM_SAFE_FREE(header->date); + EM_SAFE_FREE(header->from); + EM_SAFE_FREE(header->subject); + EM_SAFE_FREE(header->sender); + EM_SAFE_FREE(header->to); + EM_SAFE_FREE(header->cc); + EM_SAFE_FREE(header->bcc); + free(header); header = NULL; + EM_DEBUG_FUNC_END(); +} + +void em_core_mime_free_part_body(struct _m_body *body) +{ + EM_DEBUG_FUNC_BEGIN(); + if (!body) return ; + if (body->part_header) em_core_mime_free_part_header(body->part_header); + EM_SAFE_FREE(body->text); + if (body->nested.body) em_core_mime_free_part_body(body->nested.body); + if (body->nested.next) em_core_mime_free_part(body->nested.next); + free(body); body = NULL; + EM_DEBUG_FUNC_END(); +} + +void em_core_mime_free_part(struct _m_part *part) +{ + EM_DEBUG_FUNC_BEGIN(); + if (!part) return ; + if (part->body) em_core_mime_free_part_body(part->body); + if (part->next) em_core_mime_free_part(part->next); + free(part);part = NULL; + EM_DEBUG_FUNC_END(); +} + +void em_core_mime_free_mime(struct _m_mesg *mmsg) +{ + EM_DEBUG_FUNC_BEGIN(); + + if (!mmsg) return ; + if (mmsg->header) em_core_mime_free_message_header(mmsg->header); + if (mmsg->rfc822header) em_core_mime_free_rfc822_header(mmsg->rfc822header); + if (mmsg->nested.body) em_core_mime_free_part_body(mmsg->nested.body); + if (mmsg->nested.next) em_core_mime_free_part(mmsg->nested.next); + EM_SAFE_FREE(mmsg->text); + free(mmsg); mmsg = NULL; + EM_DEBUG_FUNC_END(); +} + +void em_core_mime_free_content_info(struct _m_content_info *cnt_info) +{ + EM_DEBUG_FUNC_BEGIN(); + struct attachment_info *p; + + if (!cnt_info) return ; + EM_SAFE_FREE(cnt_info->text.plain); + EM_SAFE_FREE(cnt_info->text.plain_charset); + EM_SAFE_FREE(cnt_info->text.html); + while (cnt_info->file) { + p = cnt_info->file->next; + EM_SAFE_FREE(cnt_info->file->name); + EM_SAFE_FREE(cnt_info->file->save); + free(cnt_info->file); cnt_info->file = NULL; + cnt_info->file = p; + } + free(cnt_info);cnt_info = NULL; + EM_DEBUG_FUNC_END(); +} + +/* remove left space, tab, CR, L */ +char *em_core_mime_trim_left(char *str) +{ + char *p, *temp_buffer = NULL; + + /* EM_DEBUG_FUNC_BEGIN() */ + if (!str) return NULL; + + p = str; + while (*p && (*p == ' ' || *p == '\t' || *p == LF || *p == CR)) p++; + + if (!*p) return NULL; + + temp_buffer = EM_SAFE_STRDUP(p); + + strncpy(str, temp_buffer, strlen(str)); + str[strlen(temp_buffer)] = NULL_CHAR; + + EM_SAFE_FREE(temp_buffer); + + return str; +} + +/* remove right space, tab, CR, L */ +char *em_core_mime_trim_right(char *str) +{ + char *p; + + /* EM_DEBUG_FUNC_BEGIN() */ + if (!str) return NULL; + + p = str+strlen(str)-1; + while (((int)p >= (int)str) && (*p == ' ' || *p == '\t' || *p == LF || *p == CR)) + *p --= '\0'; + + if ((int) p < (int)str) + return NULL; + + return str; +} + +char *em_core_mime_upper_str(char *str) +{ + char *p = str; + while (*p) { + *p = toupper(*p); + p++; + } + return str; +} + + +/* get body-part in nested part */ +static PARTLIST *em_core_get_allnested_part_full(MAILSTREAM *stream, int msg_uid, BODY *body, struct _m_content_info *cnt_info, int *err_code, PARTLIST *section_list) +{ + EM_DEBUG_FUNC_BEGIN("stream[%p], msg_uid[%d], body[%p], cnt_info[%p], err_code[%p]", stream, msg_uid, body, cnt_info, err_code); + + PART *part_child = body->nested.part; + + while (part_child) { + section_list = em_core_get_body_full(stream, msg_uid, &part_child->body, cnt_info, err_code, section_list); + part_child = part_child->next; + } + + return section_list; +} + +/* get body-part in alternative multiple part */ +static PARTLIST *em_core_get_alternative_multi_part_full(MAILSTREAM *stream, int msg_uid, BODY *body, struct _m_content_info *cnt_info, int *err_code, PARTLIST *section_list) +{ + EM_DEBUG_FUNC_BEGIN("stream[%p], msg_uid[%d], body[%p], cnt_info[%p], err_code[%p]", stream, msg_uid, body, cnt_info, err_code); + + PART *part_child = body->nested.part; + + /* find the best sub part we can show */ + while (part_child) { + section_list = em_core_get_body_full(stream, msg_uid, &part_child->body, cnt_info, err_code, section_list); + part_child = part_child->next; + } + + return section_list; +} + +/* get body part in signed multiple part */ +static PARTLIST *em_core_get_signed_multi_part_full(MAILSTREAM *stream, int msg_uid, BODY *body, struct _m_content_info *cnt_info, int *err_code, PARTLIST *section_list) +{ + EM_DEBUG_FUNC_BEGIN(); + + EM_DEBUG_LOG("stream[%p], msg_uid[%d], body[%p], cnt_info[%p], err_code[%p]", stream, msg_uid, body, cnt_info, err_code); + + /* "protocol"= "application/pgp-signature */ + return section_list; +} + +/* get body part in encrypted multiple part */ +static PARTLIST *em_core_get_encrypted_multi_part_full(MAILSTREAM *stream, int msg_uid, BODY *body, struct _m_content_info *cnt_info, int *err_code, PARTLIST *section_list) +{ + EM_DEBUG_FUNC_BEGIN("stream[%p], msg_uid[%d], body[%p], cnt_info[%p], err_code[%p]", stream, msg_uid, body, cnt_info, err_code); + + /* "protocol" = "application/pgp-encrypted */ + return section_list; +} + +/* get body part in multiple part */ +static PARTLIST *em_core_get_multi_part_full(MAILSTREAM *stream, int msg_uid, BODY *body, struct _m_content_info *cnt_info, int *err_code, PARTLIST *section_list) +{ + EM_DEBUG_FUNC_BEGIN("stream[%p], msg_uid[%d], body[%p], cnt_info[%p], err_code[%p]", stream, msg_uid, body, cnt_info, err_code); + + switch (body->subtype[0]) { + case 'A': /* ALTERNATIV */ + return section_list = em_core_get_alternative_multi_part_full(stream, msg_uid, body, cnt_info, err_code, section_list); + + case 'S': /* SIGNE */ + return section_list = em_core_get_signed_multi_part_full(stream, msg_uid, body, cnt_info, err_code, section_list); + + case 'E': /* ENCRYPTE */ + return section_list = em_core_get_encrypted_multi_part_full(stream, msg_uid, body, cnt_info, err_code, section_list); + + default: /* process all unknown as MIXED (according to the RFC 2047 */ + return section_list = em_core_get_allnested_part_full(stream, msg_uid, body, cnt_info, err_code, section_list); + } +} + + +PARTLIST * +em_core_get_body_full(MAILSTREAM *stream, int msg_uid, BODY *body, struct _m_content_info *cnt_info, int *err_code, PARTLIST *section_list) +{ + EM_DEBUG_FUNC_BEGIN("stream[%p], msg_uid[%d], body[%p], cnt_info[%p], err_code[%p]", stream, msg_uid, body, cnt_info, err_code); + + if (!stream || !body || !cnt_info) { + EM_DEBUG_EXCEPTION("stream[%p], msg_uid[%d], body[%p], cnt_info[%p]", stream, msg_uid, body, cnt_info); + + if (err_code != NULL) + *err_code = EMF_ERROR_INVALID_PARAM; + return NULL; + } + + switch (body->type) { + case TYPEMULTIPART: + return section_list = em_core_get_multi_part_full(stream, msg_uid, body, cnt_info, err_code, section_list); + + case TYPEMESSAGE: + break; + + case TYPETEXT: + case TYPEAPPLICATION: + case TYPEAUDIO: + case TYPEIMAGE: + case TYPEVIDEO: + case TYPEMODEL: + case TYPEOTHER: + + /* Form list of attachment followed by list of inline images */ + if (body->id || body->location || body->disposition.type) { + + char filename[512] = {0, }; + struct attachment_info **ai = NULL; + struct attachment_info *prev_ai = NULL; + struct attachment_info *next_ai = NULL; + int i = 0; + + if (em_core_get_file_pointer(body, filename, cnt_info , (int *)NULL) < 0) + EM_DEBUG_EXCEPTION("em_core_get_file_pointer failed"); + else { + /* To form list of attachment info - Attachment list followed by inline attachment list */ + prev_ai = NULL; + next_ai = NULL; + ai = &cnt_info->file; + + EM_DEBUG_LOG(" ai - %p ", (*ai)); + + if (ai != NULL) { + /* if ((body->id) || (body->location) */ + if ((body->id) || (body->location) || ((body->disposition.type != NULL) && ((body->disposition.type[0] == 'i') || (body->disposition.type[0] == 'I')))) { + /* For Inline content append to the end */ + for (i = 1; *ai; ai = &(*ai)->next) + i++; + } + else { + /* For attachment - search till Inline content found and insert before inline */ + for (i = 1; *ai; ai = &(*ai)->next) { + if ((*ai)->type == 1) { + /* Means inline image */ + EM_DEBUG_LOG(" Found Inline Content "); + next_ai = (*ai); + break; + } + i++; + prev_ai = (*ai); + } + } + } + if (!(*ai = em_core_malloc(sizeof(struct attachment_info)))) { + EM_DEBUG_EXCEPTION("em_core_malloc failed..."); + } + else { + if (ai == NULL) { + cnt_info->file = (*ai); + } + + memset((*ai), 0x00, sizeof(struct attachment_info)); + if ((body->id) || (body->location) || ((body->disposition.type != NULL) && ((body->disposition.type[0] == 'i') || (body->disposition.type[0] == 'I')))) + (*ai)->type = 1; + else + (*ai)->type = 2; + + (*ai)->name = EM_SAFE_STRDUP(filename); + (*ai)->size = body->size.bytes; + +#ifdef __ATTACHMENT_OPTI__ + (*ai)->encoding = body->encoding; + if (body->sparep) + (*ai)->section = EM_SAFE_STRDUP(body->sparep); + + EM_DEBUG_LOG(" Encoding - %d Section No - %s ", (*ai)->encoding, (*ai)->section); +#endif + + EM_DEBUG_LOG("Type[%d], Name[%s], Path[%s] ", (*ai)->type, (*ai)->name, (*ai)->save); + if (body->type == TYPEAPPLICATION) { + if (!strcasecmp(body->subtype, MIME_SUBTYPE_DRM_OBJECT)) + (*ai)->drm = EMF_ATTACHMENT_DRM_OBJECT; + else if (!strcasecmp(body->subtype, MIME_SUBTYPE_DRM_RIGHTS)) + (*ai)->drm = EMF_ATTACHMENT_DRM_RIGHTS; + else if (!strcasecmp(body->subtype, MIME_SUBTYPE_DRM_DCF)) + (*ai)->drm = EMF_ATTACHMENT_DRM_DCF; + else if (!strcasecmp(body->subtype, "pkcs7-mime")) + cnt_info->grab_type = cnt_info->grab_type | GRAB_TYPE_ATTACHMENT; + } + + if ((*ai)->type != 1 && next_ai != NULL) { + /* Means next_ai points to the inline attachment info structure */ + if (prev_ai == NULL) { + /* First node is inline attachment */ + (*ai)->next = next_ai; + cnt_info->file = (*ai); + } + else { + prev_ai->next = (*ai); + (*ai)->next = next_ai; + } + } + } + } + + } + + + /* if (cnt_info->grab_type == GRAB_TYPE_ATTACHMENT */ + if (cnt_info->grab_type & GRAB_TYPE_ATTACHMENT) { + if (((body->disposition.type != NULL) && ((body->disposition.type[0] == 'a') || (body->disposition.type[0] == 'A'))) && (cnt_info->file != NULL)) { + PARAMETER *param = NULL; + char *fn = NULL; + + param = body->parameter; + + while (param) { + if (!strcasecmp(param->attribute, "NAME")) { + fn = EM_SAFE_STRDUP(param->value); + break; + } + if (!strcasecmp(param->attribute, "FILENAME")) { + fn = EM_SAFE_STRDUP(param->value); + break; + } + param = param->next; + } + if ((fn != NULL)&& (!strcmp(fn, cnt_info->file->name)) && (body->size.bytes == cnt_info->file->size)) /* checks to zero in on particular attachmen */ { + section_list = em_core_add_node(section_list, body); + if (section_list == NULL) { + EM_DEBUG_EXCEPTION("adding node to section list failed"); + EM_SAFE_FREE(fn); + return NULL; + } + else { + EM_SAFE_FREE(fn); + return section_list; /* single attachment download, so if a match found break the recursio */ + } + } + EM_SAFE_FREE(fn); + } + } + else { + /* get a section list which has only plain, html and inline */ + if (!((body->disposition.type != NULL) && ((body->disposition.type[0] == 'a') || (body->disposition.type[0] == 'A'))))/* if the body not an attachmen */ { + section_list = em_core_add_node(section_list, body); + if (section_list == NULL) { + EM_DEBUG_EXCEPTION("adding node to section list failed"); + return NULL; + } + } + } + + break; + + default: + break; + } + + return section_list; +} + +EXPORT_API int em_core_get_body_part_list_full(MAILSTREAM *stream, int msg_uid, int account_id, int mail_id, BODY *body, struct _m_content_info *cnt_info, int *err_code, PARTLIST *section_list, int event_handle) +{ + EM_DEBUG_FUNC_BEGIN("stream[%p], msg_uid[%d], body[%p], cnt_info[%p], err_code[%p]", stream, msg_uid, body, cnt_info, err_code); + + if (!stream || !body || !cnt_info) { + EM_DEBUG_EXCEPTION("stream[%p], msg_uid[%d], body[%p], cnt_info[%p]", stream, msg_uid, body, cnt_info); + + if (err_code != NULL) + *err_code = EMF_ERROR_INVALID_PARAM; + return FAILURE; + } + section_list = em_core_get_body_full(stream, msg_uid, body, cnt_info, err_code, section_list); + if (section_list == NULL) /* assumed at least one body part exist */ { + EM_DEBUG_EXCEPTION("em_core_get_body_full failed"); + return FAILURE; + } + if (em_core_get_body_part_imap_full(stream, msg_uid, account_id, mail_id, section_list, cnt_info, err_code, event_handle)<0) { + EM_DEBUG_EXCEPTION("em_core_get_body_part_imap_full failed"); + em_core_free_section_list(section_list); + return FAILURE; + } + em_core_free_section_list(section_list); + return SUCCESS; +} + +static int em_core_write_response_into_file(char *filename, char *write_mode, char *encoded, int encoding_type, char *subtype, int account_id, int mail_id, int *err) +{ + EM_DEBUG_FUNC_BEGIN(); + int not_found = true; + FILE *fp = NULL; + char *decoded = NULL; + unsigned long decoded_len = 0; + int encoded_len = 0; + char *decoded_temp = NULL; + PARAMETER *param = NULL; + PARAMETER *param1 = NULL; + char save_file_name[MAX_PATH+1] = {0, }; + char html_cid_path[MAX_PATH+1] = {0, }; + int temp_decoded_len = 0; + int inline_support = 0; + int error = EMF_ERROR_NONE; + + if (!encoded || !filename || !write_mode) { + EM_DEBUG_EXCEPTION("Invalid Param "); + error = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + + EM_DEBUG_LOG("Encoded buffer length [%d]", strlen(encoded)); + encoded_len = strlen(encoded); + + EM_DEBUG_LOG("encoding_type [%d]", encoding_type); + switch (encoding_type) { + case ENCQUOTEDPRINTABLE: { + unsigned char *orignal = (unsigned char *)g_strdup_printf("%s\r\n", encoded); + decoded = (char *)rfc822_qprint(orignal, encoded_len + 2, &decoded_len); + g_free(orignal); + break; + } + + case ENCBASE64: + decoded = (char *)rfc822_base64((unsigned char *)encoded, encoded_len, &decoded_len); + break; + + default: { + unsigned char *orignal = (unsigned char *)g_strdup_printf("%s\r\n", encoded); + memcpy(decoded = malloc(encoded_len + 3), orignal, encoded_len + 3); + decoded_len = encoded_len + 2; + g_free(orignal); + } + break; + } + + if (decoded != NULL) { + EM_DEBUG_LOG("Decoded Length [%d] " , decoded_len); + + if (!(fp = fopen(filename, write_mode))) { + EM_DEBUG_EXCEPTION("fopen failed - %s", filename); + error = EMF_ERROR_SYSTEM_FAILURE; + return false; + } + + if (subtype && subtype[0] == 'H') { + char body_inline_id[512] = {0}; + + while (strstr(decoded, "cid:")) { + EM_DEBUG_LOG("Found cid:"); + not_found = true; + if (g_inline_count) { + BODY *body_inline = NULL; + int inline_count = 0; + char *decoded_content_id = NULL; + while (inline_count < g_inline_count && g_inline_list[inline_count]) { + EM_DEBUG_LOG("inline_count [%d], g_inline_count [%d]", inline_count, g_inline_count); + body_inline = g_inline_list[inline_count]; + param = body_inline->disposition.parameter; + param1 = body_inline->parameter; + + memset(body_inline_id, 0x00, 512); + + if (body_inline && body_inline->id && strlen(body_inline->id) > 0) { + EM_DEBUG_LOG("body_inline->id - %s", body_inline->id); + EM_DEBUG_LOG("param - %p param1 - %p", param, param1); + decoded_content_id = strstr(decoded, "cid:"); + + if (body_inline->id[0] == '<') + memcpy(body_inline_id, body_inline->id + 1, strlen(body_inline->id) - 2); + else + memcpy(body_inline_id, body_inline->id , strlen(body_inline->id)); + + EM_DEBUG_LOG("Inline body_inline_id [%s] ", body_inline_id); + + if ((param || param1) && 0 == strncmp(body_inline_id , decoded_content_id + strlen("cid:"), strlen(body_inline_id))) { + EM_DEBUG_LOG(" Inline CID Found "); + + memset(save_file_name, 0x00, MAX_PATH); + memset(html_cid_path, 0x00, MAX_PATH); + + /* Finding 'filename' attribute from content inf */ + em_core_get_file_pointer(body_inline, save_file_name, NULL, &error); + + if (strlen(save_file_name) > 0) { + /* Content ID will be replaced with its file name in html */ + memcpy(html_cid_path, decoded_content_id , strlen("cid:") + strlen(body_inline_id)); + + EM_DEBUG_LOG("Replacing %s with %s ", html_cid_path, save_file_name); + if ((decoded_temp = em_core_replace_string(decoded, html_cid_path, save_file_name))) { + EM_SAFE_FREE(decoded); + decoded = decoded_temp; + decoded_len = strlen(decoded); + EM_DEBUG_LOG("Decoded Length [%d] ", decoded_len); + inline_support = 1; + not_found = false; + /* only_body_download = false */ + break; + } + } + } + } + inline_count++; + } + + } + + + if (not_found) { + EM_DEBUG_LOG("not_found is true"); + memset(body_inline_id, 0x00, sizeof(body_inline_id)); + decoded_temp = em_replace_string_with_split_file_path(decoded, "cid:", body_inline_id); + if (decoded_temp) { + /* only_body_download = false */ + /* EM_DEBUG_LOG(">>>> decoded_temp 2 [ %s ] ", decoded_temp) */ + EM_SAFE_FREE(decoded); + decoded = decoded_temp; + temp_decoded_len = strlen(body_inline_id); + decoded_len = strlen(decoded); + EM_DEBUG_LOG("Decoded Length [%d] ", decoded_len); + inline_support = 1; + } + } + } + } + + EM_DEBUG_LOG("Before fwrite"); + + if (decoded_len > 0 && fwrite(decoded, decoded_len, 1, fp) < 0) { + EM_DEBUG_EXCEPTION("fwrite(\"%s\") failed...", decoded); + EM_DEBUG_EXCEPTION(" Error Occured while writing "); + error = EMF_ERROR_SYSTEM_FAILURE; + goto FINISH_OFF; + } + + } + else { + EM_DEBUG_EXCEPTION(" Error Occured while decoding "); + goto FINISH_OFF; + } + +FINISH_OFF: + if (err) + *err = error; + + EM_SAFE_FREE(decoded); + + if (fp != NULL) + fclose(fp); + + EM_DEBUG_FUNC_END(); + + return true; +} + + +static BODY *em_core_select_body_structure_from_section_list(PARTLIST *section_list, char *section) +{ + PARTLIST *temp = section_list; + BODY *body = NULL; + + while (temp != NULL) { + body = temp->body; + if (!strcmp(section, body->sparep)) + return body; + temp = (PARTLIST *)temp->next; + } + return body; +} + + + + +static int imap_mail_write_body_to_file(MAILSTREAM *stream, int account_id, int mail_id, int is_attachment, char *filepath, int uid, char *section, int encoding, int *decoded_total, char *section_subtype, int *err_code) +{ + EM_PROFILE_BEGIN(imapMailWriteBodyToFile); + EM_DEBUG_FUNC_BEGIN("stream[%p], filepath[%s], uid[%d], section[%s], encoding[%d], decoded_total[%p], err_code[%p]", stream, filepath, uid, section, encoding, decoded_total, err_code); + + int ret = false; + int err = EMF_ERROR_NONE; + + FILE *fp = NULL; + IMAPLOCAL *imaplocal = NULL; + char tag[16], command[64]; + char *response = NULL; + char *decoded = NULL; + int body_size = 0, total = 0; + char *file_id = NULL; + char server_uid[129]; + char *filename = NULL; + int server_response_yn = 0; + int write_flag = false; + char *write_buffer = NULL; + unsigned char encoded[DOWNLOAD_MAX_BUFFER_SIZE] = {0, }; + unsigned char test_buffer[LOCAL_MAX_BUFFER_SIZE] = {0}; + int flag_first_write = true; + + if (!stream || !filepath || !section) { + EM_DEBUG_EXCEPTION("stream[%p], filepath[%s], uid[%d], section[%s], encoding[%d], decoded_total[%p]", stream, filepath, uid, section, encoding, decoded_total); + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + int max_write_buffer_size = 0; + if (vconf_get_int("db/email/write_buffer_mode", &max_write_buffer_size) != 0) { + EM_DEBUG_EXCEPTION("vconf_get_int failed. So set direct file writing"); + /* set as default profile typ */ + max_write_buffer_size = 0; + } + + EM_DEBUG_LOG(">>> WRITE BUFFER SIZE : %d KB", max_write_buffer_size); + if (max_write_buffer_size > 0) { + max_write_buffer_size *= 1024; /* KB -> byte */ + if (!(write_buffer = em_core_malloc(sizeof(char) *max_write_buffer_size))) { + EM_DEBUG_EXCEPTION("em_core_malloc failed..."); + err = EMF_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + } + + FINISH_OFF_IF_CANCELED; + + if (!(fp = fopen(filepath, "wb+"))) { + EM_DEBUG_EXCEPTION("fopen failed - %s", filepath); + err = EMF_ERROR_SYSTEM_FAILURE; /* EMF_ERROR_UNKNOWN */ + goto FINISH_OFF; + } + + imaplocal = stream->local; + + if (!imaplocal->netstream) { + EM_DEBUG_EXCEPTION("invalid IMAP4 stream detected... %p", imaplocal->netstream); + + err = EMF_ERROR_INVALID_STREAM; + goto FINISH_OFF; + } + + EM_DEBUG_LOG(" next_decode_string = false "); + next_decode_string = false; + + memset(tag, 0x00, sizeof(tag)); + memset(command, 0x00, sizeof(command)); + + SNPRINTF(tag, sizeof(tag), "%08lx", 0xffffffff & (stream->gensym++)); + SNPRINTF(command, sizeof(command), "%s UID FETCH %d BODY.PEEK[%s]\015\012", tag, uid, section); + + EM_DEBUG_LOG("[IMAP4] >>> [%s]", command); + + /* send command : get msgno/uid for all messag */ + if (!net_sout(imaplocal->netstream, command, (int)strlen(command))) { + EM_DEBUG_EXCEPTION("net_sout failed..."); + err = EMF_ERROR_CONNECTION_BROKEN; + goto FINISH_OFF; + } + + while (imaplocal->netstream) { + char *p = NULL; + char *s = NULL; + + if (!em_core_check_thread_status()) { + EM_DEBUG_LOG("Canceled..."); + /* Is it realy required ? It might cause crashes. + if (imaplocal->netstream) + net_close (imaplocal->netstream); + */ + imaplocal->netstream = NULL; + err = EMF_ERROR_CANCELLED; + goto FINISH_OFF; + } + + /* receive respons */ + if (!(response = net_getline(imaplocal->netstream))) { + EM_DEBUG_EXCEPTION("net_getline failed..."); + err = EMF_ERROR_INVALID_RESPONSE; + goto FINISH_OFF; + } +#ifdef FEATURE_CORE_DEBUG + EM_DEBUG_LOG("recv[%s]", response); +#endif + + write_flag = false; + if (response[0] == '*' && !server_response_yn) { /* start of respons */ + + if ((p = strstr(response, "BODY[")) /* || (p = strstr(s + 1, "BODY["))*/) { + server_response_yn = 1; + p += strlen("BODY["); + s = p; + + while (*s != ']') + s++; + + *s = '\0'; + + if (strcmp(section, p)) { + err = EMF_ERROR_INVALID_RESPONSE; + goto FINISH_OFF; + } + + if ((p = strstr(s+1, " {"))) { + p += strlen(" {"); + s = p; + + while (isdigit(*s)) + s++; + + *s = '\0'; + + body_size = atoi(p); + } + else { /* no body length is replied */ + if ((p = strstr(s+1, " \""))) { /* seek the termination of double quot */ + char *t = NULL; + p += strlen(" \""); + if ((t = strstr(p, "\""))) { + body_size = t - p; + *t = '\0'; + EM_DEBUG_LOG("Body : start[%p] end[%p] : body[%s]", p, t, p); + /* need to decod */ + EM_SAFE_FREE(response); + response = EM_SAFE_STRDUP(p); + write_flag = true; + } + else { + err = EMF_ERROR_INVALID_RESPONSE; + goto FINISH_OFF; + } + } + else { + err = EMF_ERROR_INVALID_RESPONSE; + goto FINISH_OFF; + } + } + + /* sending progress noti to application. + 1. mail_id + 2. file_id + 3. bodysize + */ + parse_file_path_to_filename(filepath, &file_id); + + filename = file_id; + sprintf(server_uid, "%d", uid); + + EM_DEBUG_LOG("file_id [%s]", file_id); + EM_DEBUG_LOG("filename [%p]-[%s]", filename, filename); + EM_DEBUG_LOG("body_size [%d]", body_size); + EM_DEBUG_LOG("server_uid [%s]", server_uid); + EM_DEBUG_LOG("mail_id [%d]", mail_id); + + if (is_attachment) { + EM_DEBUG_LOG("Attachment number [%d]", is_attachment); + if (!em_storage_notify_network_event(NOTI_DOWNLOAD_ATTACH_START, mail_id, filename, is_attachment, 0)) + EM_DEBUG_EXCEPTION(" em_storage_notify_network_event [ NOTI_DOWNLOAD_ATTACH_START] Failed >>>> "); + _imap4_download_noti_interval_value = body_size *DOWNLOAD_NOTI_INTERVAL_PERCENT / 100; + _imap4_total_body_size = body_size; + } + else { + if (multi_part_body_size) { + EM_DEBUG_LOG("Multipart body size is [%d]", multi_part_body_size); + if (!em_storage_notify_network_event(NOTI_DOWNLOAD_MULTIPART_BODY, mail_id, filename, multi_part_body_size, 0)) + EM_DEBUG_EXCEPTION(" em_storage_notify_network_event [ NOTI_DOWNLOAD_BODY_START] Failed >>>> "); + _imap4_download_noti_interval_value = multi_part_body_size *DOWNLOAD_NOTI_INTERVAL_PERCENT / 100; + /* _imap4_total_body_size should be set before calling this functio */ + /* _imap4_total_body_size */ + } + else { + if (!em_storage_notify_network_event(NOTI_DOWNLOAD_BODY_START, mail_id, filename, body_size, 0)) + EM_DEBUG_EXCEPTION(" em_storage_notify_network_event [ NOTI_DOWNLOAD_BODY_START] Failed >>>>"); + _imap4_download_noti_interval_value = body_size *DOWNLOAD_NOTI_INTERVAL_PERCENT / 100; + _imap4_total_body_size = body_size; + } + } + if (_imap4_download_noti_interval_value > DOWNLOAD_NOTI_INTERVAL_SIZE) { + _imap4_download_noti_interval_value = DOWNLOAD_NOTI_INTERVAL_SIZE; + } + if (body_size < DOWNLOAD_MAX_BUFFER_SIZE) { + if (net_getbuffer (imaplocal->netstream, (long)body_size, (char *)encoded) <= 0) { + EM_DEBUG_EXCEPTION("net_getbuffer failed..."); + err = EMF_ERROR_NO_RESPONSE; + goto FINISH_OFF; + } + + if (!em_core_write_response_into_file(filepath, "wb+", (char *)encoded, encoding, section_subtype, account_id, mail_id, &err)) { + EM_DEBUG_EXCEPTION("write_response_into_file failed [%d]", err); + goto FINISH_OFF; + } + + total = strlen((char *)encoded); + EM_DEBUG_LOG("total = %d", total); + EM_DEBUG_LOG("write_response_into_file successful %s.....", filename); + + if (((_imap4_last_notified_body_size + _imap4_download_noti_interval_value) <= _imap4_received_body_size) + || (_imap4_received_body_size >= _imap4_total_body_size)) /* 100 */ { + /* In some situation, total_encoded_len includes the length of dummy bytes. So it might be greater than body_size */ + int gap = 0; + if (total > body_size) + gap = total - body_size; + _imap4_received_body_size -= gap; + _imap4_last_notified_body_size = _imap4_received_body_size; + + EM_DEBUG_LOG("DOWNLOADING STATUS NOTIFY : Encoded[%d] / [%d] = %d %% Completed. -- Total Decoded[%d]", total, body_size, 100*total/body_size, total); + EM_DEBUG_LOG("DOWNLOADING STATUS NOTIFY : Total[%d] / [%d] = %d %% Completed.", _imap4_received_body_size, _imap4_total_body_size, 100*_imap4_received_body_size/_imap4_total_body_size); + + if (is_attachment) { + if (!em_storage_notify_network_event(NOTI_DOWNLOAD_ATTACH_START, mail_id, filename, is_attachment, 100 *_imap4_received_body_size / _imap4_total_body_size)) + EM_DEBUG_EXCEPTION(" em_storage_notify_network_event [ NOTI_DOWNLOAD_ATTACH_START] Failed >>>> "); + } + else { + if (multi_part_body_size) { + if (!em_storage_notify_network_event(NOTI_DOWNLOAD_MULTIPART_BODY, mail_id, filename, _imap4_total_body_size, _imap4_received_body_size)) + EM_DEBUG_EXCEPTION(" em_storage_notify_network_event [ NOTI_DOWNLOAD_BODY_START] Failed >>>> "); + } + else { + if (!em_storage_notify_network_event(NOTI_DOWNLOAD_BODY_START, mail_id, filename, _imap4_total_body_size, _imap4_received_body_size)) + EM_DEBUG_EXCEPTION(" em_storage_notify_network_event [ NOTI_DOWNLOAD_BODY_START] Failed >>>>"); + } + } /* if (is_attachment) .. else .. */ + } + } + else { + int temp_body_size = body_size; + int x = 0; + + if (encoding == ENCBASE64) + x = (sizeof(encoded)/78) *78; /* to solve base64 decoding pro */ + else + x = sizeof(encoded)-1; + + memset(test_buffer, 0x00, sizeof(test_buffer)); + while (temp_body_size && (total <body_size)) { + + memset(test_buffer, 0x00, sizeof(test_buffer)); + while ((total != body_size) && temp_body_size && ((strlen((char *)test_buffer) + x) < sizeof(test_buffer))) { + memset(encoded, 0x00, sizeof(encoded)); + + if (net_getbuffer (imaplocal->netstream, (long)x, (char *)encoded) <= 0) { + EM_DEBUG_EXCEPTION("net_getbuffer failed..."); + err = EMF_ERROR_NO_RESPONSE; + goto FINISH_OFF; + } + + temp_body_size = temp_body_size - x; + strncat((char *)test_buffer, (char *)encoded, strlen((char *)encoded)); + total = total + x; + _imap4_received_body_size += strlen((char *)encoded); + + if (temp_body_size/x) + x = x; + else if (temp_body_size%x) + x = temp_body_size%x; + + if (((_imap4_last_notified_body_size + _imap4_download_noti_interval_value) <= _imap4_received_body_size) + || (_imap4_received_body_size >= _imap4_total_body_size)) /* 100 */ { + /* In some situation, total_encoded_len includes the length of dummy bytes. So it might be greater than body_size */ + int gap = 0; + if (total > body_size) + gap = total - body_size; + _imap4_received_body_size -= gap; + _imap4_last_notified_body_size = _imap4_received_body_size; + + /* EM_DEBUG_LOG("DOWNLOADING STATUS NOTIFY : Encoded[%d] / [%d] = %d %% Completed. -- Total Decoded[%d]", total, body_size, 100*total/body_size, total) */ + EM_DEBUG_LOG("DOWNLOADING STATUS NOTIFY : Total[%d] / [%d] = %d %% Completed.", _imap4_received_body_size, _imap4_total_body_size, 100*_imap4_received_body_size/_imap4_total_body_size); + + if (is_attachment) { + if (!em_storage_notify_network_event(NOTI_DOWNLOAD_ATTACH_START, mail_id, filename, is_attachment, 100 *_imap4_received_body_size / _imap4_total_body_size)) + EM_DEBUG_EXCEPTION(" em_storage_notify_network_event [ NOTI_DOWNLOAD_ATTACH_START] Failed >>>> "); + } + else { + if (multi_part_body_size) { + /* EM_DEBUG_LOG("DOWNLOADING.......... : Multipart body size is [%d]", multi_part_body_size) */ + if (!em_storage_notify_network_event(NOTI_DOWNLOAD_MULTIPART_BODY, mail_id, filename, _imap4_total_body_size, _imap4_received_body_size)) + EM_DEBUG_EXCEPTION(" em_storage_notify_network_event [ NOTI_DOWNLOAD_BODY_START] Failed >>>> "); + } + else { + if (!em_storage_notify_network_event(NOTI_DOWNLOAD_BODY_START, mail_id, filename, _imap4_total_body_size, _imap4_received_body_size)) + EM_DEBUG_EXCEPTION(" em_storage_notify_network_event [ NOTI_DOWNLOAD_BODY_START] Failed >>>>"); + } + } /* if (is_attachment) .. else .. */ + } + + + } + + if (flag_first_write == true) { + if (!em_core_write_response_into_file(filepath, "wb+", (char *)test_buffer, encoding, section_subtype, account_id, mail_id, &err)) { + EM_DEBUG_EXCEPTION("write_response_into_file %s failed [%d]", filepath, err); + goto FINISH_OFF; + } + flag_first_write = false; + } + else { + if (!em_core_write_response_into_file(filepath, "ab+", (char *)test_buffer, encoding, section_subtype, account_id, mail_id, &err)) /* append */ { + EM_DEBUG_EXCEPTION("write_response_into_file %s failed [%d]", filepath, err); + goto FINISH_OFF; + } + } + EM_DEBUG_LOG("%d has been written", strlen((char *)test_buffer)); + /* notif */ + } + } + + } + else { + err = EMF_ERROR_INVALID_RESPONSE; + goto FINISH_OFF; + } + + } + else if (!strncmp(response, tag, strlen(tag))) { /* end of respons */ + if (!strncmp(response + strlen(tag) + 1, "OK", 2)) { + EM_SAFE_FREE(response); + } + else { /* 'NO' or 'BAD */ + err = EMF_ERROR_IMAP4_FETCH_UID_FAILURE; + goto FINISH_OFF; + } + + break; + } + else if (!strcmp(response, ")")) { + /* The end of response which contains body informatio */ + write_flag = false; + } + + } /* while (imaplocal->netstream) */ + + if (decoded_total != NULL) + *decoded_total = total; + + ret = true; + +FINISH_OFF: + EM_SAFE_FREE(decoded); + EM_SAFE_FREE(response); + + if (fp != NULL) + fclose(fp); + + EM_SAFE_FREE(write_buffer); + + if (ret == false) { /* delete temp fil */ + struct stat temp_file_stat; + if (filepath && stat(filepath, &temp_file_stat) == 0) + remove(filepath); + } + + if (err_code != NULL) + *err_code = err; + + EM_PROFILE_END(imapMailWriteBodyToFile); + + return ret; +} + +static int em_core_get_body_part_imap_full(MAILSTREAM *stream, int msg_uid, int account_id, int mail_id, PARTLIST *section_list, struct _m_content_info *cnt_info, int *err_code, int event_handle) +{ + EM_DEBUG_FUNC_BEGIN("stream[%p], msg_uid[%d], body[%p], cnt_info[%p], err_code[%p]", stream, msg_uid, section_list, cnt_info, err_code); + + int err = EMF_ERROR_NONE; + char sections[IMAP_MAX_COMMAND_LENGTH] = {0}; + IMAPLOCAL *imaplocal = NULL; + char tag[16] = {0}, command[IMAP_MAX_COMMAND_LENGTH] = {0}; + char section[16] = {0}; + char *response = NULL; + BODY *body = NULL; + int server_response_yn = 0; + int body_size = 0; + char *buf = NULL; + char filename[512] = {0, }; + int return_value = 0 ; + int encoding = 0; + unsigned char encoded[DOWNLOAD_MAX_BUFFER_SIZE] = {0}; + unsigned char test_buffer[LOCAL_MAX_BUFFER_SIZE] = {0}; + struct attachment_info *ai = NULL; + int i = 0; + int total = 0; + int flag_first_write = 1; + int imap4_total_body_download_progress = 0, progress = 0; + + if (!(imaplocal = stream->local) || !imaplocal->netstream || !section_list || !cnt_info) { + EM_DEBUG_EXCEPTION("invalid IMAP4 stream detected..."); + err = EMF_ERROR_INVALID_PARAM; + return_value = -1; + goto FINISH_OFF; + } + memset(sections, 0x00, sizeof(sections)); + + if (section_list != NULL) { + PARTLIST *temp = section_list; + + if (cnt_info->grab_type == GRAB_TYPE_ATTACHMENT) /* to download attachmen */ { + body = temp->body; + if (body->sparep != NULL) { + snprintf(sections, sizeof(sections), "BODY.PEEK[%s]", (char *)body->sparep); + } + else { + EM_DEBUG_EXCEPTION("body->sparep can not be null. "); + return_value = -1; + goto FINISH_OFF; + + } + } + else { + while (temp != NULL) { + char t[64] = {0}; + body = temp->body; + + if ((body->type == TYPETEXT) || (body->id != NULL) || ((body->disposition.type != NULL) && ((body->disposition.type[0] == 'i') || (body->disposition.type[0] == 'I')))) { + snprintf(t, sizeof(t), "BODY.PEEK[%s] ", (char *)body->sparep); /* body parts seperated by period */ + strcat(sections, t); + } + temp = (PARTLIST *)temp->next; + } + } + } + + if ((strlen(sections) == (sizeof(sections)-1)) || (strlen(sections) == 0)) { + EM_DEBUG_EXCEPTION(" Too many body parts or nil. IMAP command may cross 1000bytes."); + return_value = -1; + goto FINISH_OFF; + } + + if (sections[strlen(sections)-1] == ' ') { + sections[strlen(sections)-1] = '\0'; + } + + EM_DEBUG_LOG("sections <%s>", sections); + + memset(tag, 0x00, sizeof(tag)); + memset(command, 0x00, sizeof(command)); + + SNPRINTF(tag, sizeof(tag), "%08lx", 0xffffffff & (stream->gensym++)); + SNPRINTF(command, sizeof(command), "%s UID FETCH %d (%s)\015\012", tag, msg_uid, sections); + EM_DEBUG_LOG("command %s", command); + + if (strlen(command) == (sizeof(command)-1)) { + EM_DEBUG_EXCEPTION(" Too many body parts. IMAP command will fail."); + return_value = -1; + goto FINISH_OFF; + } + + /* send command : get msgno/uid for all messag */ + if (!net_sout(imaplocal->netstream, command, (int)strlen(command))) { + EM_DEBUG_EXCEPTION("net_sout failed..."); + err = EMF_ERROR_CONNECTION_BROKEN; + return_value = -1; + goto FINISH_OFF; + } + while (imaplocal->netstream) { + + /* receive respons */ + if (!(response = net_getline(imaplocal->netstream))) { + EM_DEBUG_EXCEPTION("net_getline failed..."); + err = EMF_ERROR_INVALID_RESPONSE; + return_value = -1; + goto FINISH_OFF; + } + + if (strstr(response, "BODY[")) { + + if (!server_response_yn) /* start of respons */ { + if (response[0] != '*') { + err = EMF_ERROR_INVALID_RESPONSE; + EM_DEBUG_EXCEPTION("Start of response doesn contain *"); + return_value = -1; + goto FINISH_OFF; + } + server_response_yn = 1; + } + + flag_first_write = 1; + total = 0; + memset(encoded, 0x00, sizeof(encoded)); + + if (em_core_get_section_body_size(response, section, &body_size)<0) { + EM_DEBUG_EXCEPTION("em_core_get_section_body_size failed [%d]", err); + err = EMF_ERROR_INVALID_RESPONSE; + return_value = -1; + goto FINISH_OFF; + } + EM_DEBUG_LOG("body_size-%d", body_size); + + if ((body = em_core_select_body_structure_from_section_list(section_list, section)) == NULL)/* get body from seciton_lis */ { + EM_DEBUG_EXCEPTION("em_core_select_body_structure_from_section_list failed [%d]", err); + err = EMF_ERROR_INVALID_RESPONSE; + return_value = -1; + goto FINISH_OFF; + } + encoding = body->encoding; + + /* if (em_core_get_file_pointer(account_id, mail_id, body, buf, cnt_info , err)<0) { + EM_DEBUG_EXCEPTION("em_core_get_file_pointer failed [%d]", err); + goto FINISH_OFF; + }*/ + + if (!em_core_get_temp_file_name(&buf, &err)) { + EM_DEBUG_EXCEPTION("em_core_get_temp_file_name failed [%d]", err); + goto FINISH_OFF; + } + + EM_DEBUG_LOG("buf : %s", buf); + + /* notifying UI start */ + /* parse_file_path_to_filename(buf, &file_id); */ + + /* EM_DEBUG_LOG(">>>> filename - %p >>>>>>", file_id) */ + + + if (body->type == TYPETEXT && body->subtype && (!body->disposition.type || (body->disposition.type && (body->disposition.type[0] == 'i' || body->disposition.type[0] == 'I')))) { + if (body->subtype[0] == 'H') { + cnt_info->text.html = buf; + } + else { + cnt_info->text.plain = buf; + } + PARAMETER *param = NULL; + + param = body->parameter; + + while (param) { + if (!strcasecmp(param->attribute, "CHARSET")) { + cnt_info->text.plain_charset = EM_SAFE_STRDUP(param->value); + break; + } + + param = param->next; + } + + } + else if (body->id || body->location || body->disposition.type) { + + if (em_core_get_file_pointer(body, filename, cnt_info , &err)<0) { + EM_DEBUG_EXCEPTION("em_core_get_file_pointer failed [%d]", err); + goto FINISH_OFF; + } + + /* Search info from attachment list followed by inline attachment list */ + + ai = cnt_info->file; + EM_DEBUG_LOG(" ai - %p ", (ai)); + + /* For Inline content append to the end */ + for (i = 1; ai; ai = ai->next, i++) { + if (ai->save == NULL && (ai->name != NULL && !strcmp(ai->name, filename))) { + EM_DEBUG_LOG("Found matching details "); + ai->save = buf; + } + + } + + } + + FINISH_OFF_IF_CANCELED; + + if (cnt_info->grab_type == GRAB_TYPE_ATTACHMENT) { + if (!em_storage_notify_network_event(NOTI_DOWNLOAD_ATTACH_START, mail_id, buf, cnt_info->file_no, 0)) + EM_DEBUG_EXCEPTION(" em_storage_notify_network_event [ NOTI_DOWNLOAD_ATTACH_START] Failed >>>> "); + + _imap4_download_noti_interval_value = body_size *DOWNLOAD_NOTI_INTERVAL_PERCENT / 100; + _imap4_total_body_size = body_size; + } + else { + if (multi_part_body_size) { + EM_DEBUG_LOG("Multipart body size is [%d]", multi_part_body_size); + if (!em_storage_notify_network_event(NOTI_DOWNLOAD_MULTIPART_BODY, mail_id, buf, multi_part_body_size, 0)) + EM_DEBUG_EXCEPTION(" em_storage_notify_network_event [ NOTI_DOWNLOAD_BODY_START] Failed >>>> "); + + _imap4_download_noti_interval_value = multi_part_body_size *DOWNLOAD_NOTI_INTERVAL_PERCENT / 100; + } + else { + if (!em_storage_notify_network_event(NOTI_DOWNLOAD_BODY_START, mail_id, buf, body_size, 0)) + EM_DEBUG_EXCEPTION(" em_storage_notify_network_event [ NOTI_DOWNLOAD_BODY_START] Failed >>>> "); + + _imap4_download_noti_interval_value = body_size *DOWNLOAD_NOTI_INTERVAL_PERCENT / 100; + _imap4_total_body_size = body_size; + } + + } + + if (_imap4_download_noti_interval_value > DOWNLOAD_NOTI_INTERVAL_SIZE) { + _imap4_download_noti_interval_value = DOWNLOAD_NOTI_INTERVAL_SIZE; + } + + /* EM_SAFE_FREE(file_id) */ + /* notifying UI end */ + + if (body_size < DOWNLOAD_MAX_BUFFER_SIZE) { + if (net_getbuffer (imaplocal->netstream, (long)body_size, (char *)encoded) <= 0) { + EM_DEBUG_EXCEPTION("net_getbuffer failed..."); + err = EMF_ERROR_NO_RESPONSE; + return_value = -1; + goto FINISH_OFF; + } + if (!em_core_write_response_into_file(buf, "wb+", (char *)encoded, encoding, body->subtype, account_id, mail_id, &err)) { + EM_DEBUG_EXCEPTION("write_response_into_file failed [%d]", err); + return_value = -1; + goto FINISH_OFF; + } + + EM_DEBUG_LOG("total = %d", total); + EM_DEBUG_LOG("write_response_into_file successful %s.....", buf); + + total = _imap4_received_body_size = strlen((char *)encoded); + + EM_DEBUG_LOG(" _imap4_last_notified_body_size - %d ", _imap4_last_notified_body_size); + EM_DEBUG_LOG(" _imap4_download_noti_interval_value - %d ", _imap4_download_noti_interval_value); + EM_DEBUG_LOG(" _imap4_received_body_size - %d ", _imap4_received_body_size); + EM_DEBUG_LOG(" _imap4_total_body_size - %d ", _imap4_total_body_size); + + if (((_imap4_last_notified_body_size + _imap4_download_noti_interval_value) <= _imap4_received_body_size) + || (_imap4_received_body_size >= _imap4_total_body_size)) /* 100 */ { + /* In some situation, total_encoded_len includes the length of dummy bytes. So it might be greater than body_size */ + int gap = 0; + + if (total > body_size) + gap = total - body_size; + _imap4_received_body_size -= gap; + _imap4_last_notified_body_size = _imap4_received_body_size; + if (_imap4_total_body_size) + imap4_total_body_download_progress = 100*_imap4_received_body_size/_imap4_total_body_size; + else + imap4_total_body_download_progress = _imap4_received_body_size; + + EM_DEBUG_LOG("3 : body_size %d", body_size); + + if (body_size) + progress = 100*total/body_size; + else + progress = body_size; + + EM_DEBUG_LOG("DOWNLOADING STATUS NOTIFY : Encoded[%d] / [%d] = %d %% Completed. -- Total Decoded[%d]", total, body_size, progress, total); + EM_DEBUG_LOG("DOWNLOADING STATUS NOTIFY : Total[%d] / [%d] = %d %% Completed.", _imap4_received_body_size, _imap4_total_body_size, imap4_total_body_download_progress); + + if (cnt_info->grab_type == GRAB_TYPE_ATTACHMENT) { + if (!em_storage_notify_network_event(NOTI_DOWNLOAD_ATTACH_START, mail_id, buf, cnt_info->file_no, imap4_total_body_download_progress)) + EM_DEBUG_EXCEPTION(" em_storage_notify_network_event [ NOTI_DOWNLOAD_ATTACH_START] Failed >>>> "); + } + else { + if (multi_part_body_size) { + /* EM_DEBUG_LOG("DOWNLOADING.......... : Multipart body size is [%d]", multi_part_body_size) */ + if (!em_storage_notify_network_event(NOTI_DOWNLOAD_MULTIPART_BODY, mail_id, buf, _imap4_total_body_size, _imap4_received_body_size)) + EM_DEBUG_EXCEPTION(" em_storage_notify_network_event [ NOTI_DOWNLOAD_BODY_START] Failed >>>> "); + } + else { + if (!em_storage_notify_network_event(NOTI_DOWNLOAD_BODY_START, mail_id, buf, _imap4_total_body_size, _imap4_received_body_size)) + EM_DEBUG_EXCEPTION(" em_storage_notify_network_event [ NOTI_DOWNLOAD_BODY_START] Failed >>>>"); + } + } /* if (is_attachment) .. else .. */ + } + + EM_DEBUG_LOG("4"); + + } + else { + int temp_body_size = body_size; + int x = 0; + + if (encoding == ENCBASE64) + x = (sizeof(encoded)/78) *78; /* to solve base64 decoding pro */ + else + x = sizeof(encoded)-1; + + memset(test_buffer, 0x00, sizeof(test_buffer)); + while (temp_body_size && (total <body_size)) { + + memset(test_buffer, 0x00, sizeof(test_buffer)); + while ((total != body_size) && temp_body_size && ((strlen((char *)test_buffer) + x) < sizeof(test_buffer))) { + memset(encoded, 0x00, sizeof(encoded)); + + if (net_getbuffer (imaplocal->netstream, (long)x, (char *)encoded) <= 0) { + EM_DEBUG_EXCEPTION("net_getbuffer failed..."); + err = EMF_ERROR_NO_RESPONSE; + return_value = -1; + goto FINISH_OFF; + } + + temp_body_size = temp_body_size - x; + strncat((char *)test_buffer, (char *)encoded, strlen((char *)encoded)); + total = total + x; + _imap4_received_body_size += strlen((char *)encoded); + + EM_DEBUG_LOG("total = %d", total); + + if (temp_body_size/x) + x = x; + else if (temp_body_size%x) + x = temp_body_size%x; + + EM_DEBUG_LOG(" _imap4_last_notified_body_size - %d ", _imap4_last_notified_body_size); + EM_DEBUG_LOG(" _imap4_download_noti_interval_value - %d ", _imap4_download_noti_interval_value); + EM_DEBUG_LOG(" _imap4_received_body_size - %d ", _imap4_received_body_size); + EM_DEBUG_LOG(" _imap4_received_body_size - %d ", _imap4_received_body_size); + EM_DEBUG_LOG(" _imap4_total_body_size - %d ", _imap4_total_body_size); + + if (_imap4_total_body_size) + imap4_total_body_download_progress = 100*_imap4_received_body_size/_imap4_total_body_size; + else + imap4_total_body_download_progress = _imap4_received_body_size; + + if (((_imap4_last_notified_body_size + _imap4_download_noti_interval_value) <= _imap4_received_body_size) + || (_imap4_received_body_size >= _imap4_total_body_size)) /* 100 */ { + /* In some situation, total_encoded_len includes the length of dummy bytes. So it might be greater than body_size */ + int gap = 0; + if (total > body_size) + gap = total - body_size; + _imap4_received_body_size -= gap; + _imap4_last_notified_body_size = _imap4_received_body_size; + + if (body_size) + progress = 100*total/body_size; + else + progress = body_size; + + EM_DEBUG_LOG("DOWNLOADING STATUS NOTIFY : Encoded[%d] / [%d] = %d %% Completed. -- Total Decoded[%d]", total, body_size, progress, total); + EM_DEBUG_LOG("DOWNLOADING STATUS NOTIFY : Total[%d] / [%d] = %d %% Completed.", _imap4_received_body_size, _imap4_total_body_size, imap4_total_body_download_progress); + + if (cnt_info->grab_type == GRAB_TYPE_ATTACHMENT) { + if (!em_storage_notify_network_event(NOTI_DOWNLOAD_ATTACH_START, mail_id, buf, cnt_info->file_no, imap4_total_body_download_progress)) + EM_DEBUG_EXCEPTION(" em_storage_notify_network_event [ NOTI_DOWNLOAD_ATTACH_START] Failed >>>> "); + } + else { + if (multi_part_body_size) { + /* EM_DEBUG_LOG("DOWNLOADING.......... : Multipart body size is [%d]", multi_part_body_size) */ + if (!em_storage_notify_network_event(NOTI_DOWNLOAD_MULTIPART_BODY, mail_id, buf, _imap4_total_body_size, _imap4_received_body_size)) + EM_DEBUG_EXCEPTION(" em_storage_notify_network_event [ NOTI_DOWNLOAD_BODY_START] Failed >>>> "); + } + else { + if (!em_storage_notify_network_event(NOTI_DOWNLOAD_BODY_START, mail_id, buf, _imap4_total_body_size, _imap4_received_body_size)) + EM_DEBUG_EXCEPTION(" em_storage_notify_network_event [ NOTI_DOWNLOAD_BODY_START] Failed >>>>"); + } + } /* if (is_attachment) .. else .. */ + } + } + + if (flag_first_write == 1) { + if (!em_core_write_response_into_file(buf, "wb+", (char *)test_buffer, encoding, body->subtype, account_id, mail_id, &err)) { + EM_DEBUG_EXCEPTION("write_response_into_file %s failed [%d]", buf, err); + return_value = -1; + goto FINISH_OFF; + } + flag_first_write = 0; + } + else { + if (!em_core_write_response_into_file(buf, "ab+", (char *)test_buffer, encoding, body->subtype, account_id, mail_id, &err)) /* append */ { + EM_DEBUG_EXCEPTION("write_response_into_file %s failed [%d]", buf, err); + return_value = -1; + goto FINISH_OFF; + } + } + + EM_DEBUG_LOG("%d has been written", strlen((char *)test_buffer)); + + + + } + } + EM_DEBUG_LOG("5"); + } + else if (!strncmp(response, tag, strlen(tag))) /* end of respons */ { + if (!strncmp(response + strlen(tag) + 1, "OK", 2)) + EM_SAFE_FREE(response); + else /* 'NO' or 'BAD */ { + err = EMF_ERROR_IMAP4_FETCH_UID_FAILURE; + return_value = -1; + goto FINISH_OFF; + } + + break; + } + else if (!strcmp(response, ")")) { + + } + + free(response); + response = NULL; + } + + return_value = 0; + + FINISH_OFF: + + if (err_code) + *err_code = err; + + EM_SAFE_FREE(response); + + return return_value; +} + +static int em_core_get_file_pointer(BODY *body, char *buf, struct _m_content_info *cnt_info , int *err) +{ + EM_DEBUG_FUNC_BEGIN(); + + char *decoded_filename = NULL; + char attachment_file_name[MAX_PATH] = { 0, }; + char attachment_file_name_source[MAX_PATH] = {0, }; + int error = EMF_ERROR_NONE; + + if ((body->type == TYPETEXT) && (body->disposition.type == NULL)) { + EM_DEBUG_LOG("body->type == TYPETEXT"); + if (!cnt_info) { + EM_DEBUG_EXCEPTION("But, cnt_info is null"); + error = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + if (body->subtype[0] == 'H') { + if (cnt_info->text.plain_charset != NULL) { + memcpy(buf, cnt_info->text.plain_charset, strlen(cnt_info->text.plain_charset)); + strcat(buf, HTML_EXTENSION_STRING); + } + else { + memcpy(buf, "UTF-8.htm", strlen("UTF-8.htm")); + } + cnt_info->text.html = EM_SAFE_STRDUP(buf); + } + else { + PARAMETER *param = body->parameter; + char charset_string[512]; + + if (em_core_get_attribute_value_of_body_part(param, "CHARSET", charset_string, 512, false, &error)) { + cnt_info->text.plain_charset = EM_SAFE_STRDUP(charset_string); + memcpy(buf, cnt_info->text.plain_charset, strlen(cnt_info->text.plain_charset)); + } + else + memcpy(buf, "UTF-8", strlen("UTF-8")); + + cnt_info->text.plain = EM_SAFE_STRDUP(buf); + } + + } + else if ((body->id != NULL) || ((body->disposition.type != NULL) && ((body->disposition.type[0] == 'i') || (body->disposition.type[0] == 'I')))) { /* body id is exising or disposition type is Inlin */ + size_t len = 0; + if (body->parameter) /* Get actual name of file */ { + PARAMETER *param_body = body->parameter; + if (!em_core_get_attribute_value_of_body_part(param_body, "NAME", attachment_file_name_source, MAX_PATH, true, &error)) + em_core_get_attribute_value_of_body_part(param_body, "CHARSET", attachment_file_name_source, MAX_PATH, true, &error); + if (!em_core_make_attachment_file_name_with_extension(attachment_file_name_source, body->subtype, attachment_file_name, MAX_PATH, &error)) { + EM_DEBUG_EXCEPTION("em_core_make_attachment_file_name_with_extension failed [%d]", error); + goto FINISH_OFF; + } + } + else if (body->disposition.type) { + PARAMETER *param_disposition = body->disposition.parameter; + EM_DEBUG_LOG("body->disposition.type exist"); + em_core_get_attribute_value_of_body_part(param_disposition, "filename", attachment_file_name_source, MAX_PATH, true, &error); + if (!em_core_make_attachment_file_name_with_extension(attachment_file_name_source, body->subtype, attachment_file_name, MAX_PATH, &error)) { + EM_DEBUG_EXCEPTION("em_core_make_attachment_file_name_with_extension failed [%d]", error); + goto FINISH_OFF; + } + } + else { /* body id is not null but disposition type is null */ + if ((body->id[0] == '<')) + SNPRINTF(attachment_file_name, MAX_PATH, body->id+1); /* fname = em_parse_filename(body->id + 1 */ + else + SNPRINTF(attachment_file_name, MAX_PATH, body->id); /* fname = em_parse_filename(body->id */ + + len = strlen(attachment_file_name); + + if ((len > 1) && (attachment_file_name[len-1] == '>')) + attachment_file_name[len - 1] = '\0'; + decoded_filename = em_core_decode_rfc2047_text(attachment_file_name, &error); + } + EM_DEBUG_LOG("attachment_file_name [%s]", attachment_file_name); + if (decoded_filename != NULL) + memcpy(buf, decoded_filename, strlen(decoded_filename)); + else + memcpy(buf, attachment_file_name, strlen(attachment_file_name)); + + } + else if (body->disposition.type != NULL) { /* disposition type is existing and not inline and body_id is nul */ + PARAMETER *param = body->parameter; + if (!em_core_get_attribute_value_of_body_part(param, "NAME", attachment_file_name, MAX_PATH, true, &error)) + em_core_get_attribute_value_of_body_part(param, "FILENAME", attachment_file_name, MAX_PATH, true, &error); + memcpy(buf, attachment_file_name, strlen(attachment_file_name)); + } + +FINISH_OFF: + if (err) + *err = error; + + EM_SAFE_FREE(decoded_filename); + EM_DEBUG_FUNC_END("buf[%s]", buf); + return SUCCESS; +} + + +static PARTLIST *em_core_add_node(PARTLIST *section_list, BODY *body) +{ + PARTLIST *temp = (PARTLIST *)malloc(sizeof(PARTLIST)); + + if (temp == NULL) { + EM_DEBUG_EXCEPTION("PARTLIST node creation failed"); + return NULL; + } + temp->body = body; + temp->next = NULL; + + if (section_list == NULL)/* first node in lis */ { + section_list = temp; + } + else/* has min 1 nod */ { + PARTLIST *t = section_list; + while (t->next != NULL) /* go to last nod */ { + t = (PARTLIST *) t->next; + } + t->next = (PART *)temp;/* I think this should be PARTLIST, but why this is PART */ +/* +in imap-2007e/c-client/mail.h +PARTLIST{ + BODY *body; + PART *next; +}; +*/ + } + return section_list; +} + + +static void em_core_free_section_list(PARTLIST *section_list) +{ + PARTLIST *temp = NULL; + + while (section_list != NULL) { + temp = (PARTLIST *)section_list->next; + EM_SAFE_FREE(section_list); + section_list = temp; + } +} + +static int em_core_get_section_body_size(char *response, char *section, int *body_size) +{ + char *p = NULL; + char *s = NULL; + int size = 0; + if ((p = strstr(response, "BODY[")) /* || (p = strstr(s + 1, "BODY["))*/) { + + p += strlen("BODY["); + s = p; + + while (*s != ']') + s++; + + *s = '\0'; + + strcpy(section, p); + + /* if (strcmp(section, p)) { + err = EMF_ERROR_INVALID_RESPONSE; + goto FINISH_OFF; + }*/ + p = strstr(s+1, " {"); + if (p) { + p += strlen(" {"); + s = p; + + while (isdigit(*s)) + s++; + + *s = '\0'; + + size = atoi(p); + *body_size = size; + + /* sending progress noti to application. + 1. mail_id + 2. file_id + 3. bodysize + */ + + } + else { + return FAILURE; + } + } + else { + return FAILURE; + } + return SUCCESS; +} + + +static char *em_parse_filename(char *filename) +{ + EM_DEBUG_FUNC_BEGIN("filename [%p] ", filename); + if (!filename) { + EM_DEBUG_EXCEPTION("filename is NULL "); + return NULL; + } + + char delims[] = "@"; + char *result = NULL; + static char parsed_filename[512] = {0, }; + + memset(parsed_filename, 0x00, 512); + + if (!strstr(filename, delims)) { + EM_DEBUG_EXCEPTION("FileName doesnot contain @ "); + return NULL; + } + + result = strtok(filename, delims); + + if (strcasestr(result, ".bmp") || strcasestr(result, ".jpeg") || strcasestr(result, ".png") || strcasestr(result, ".jpg")) + sprintf(parsed_filename + strlen(parsed_filename), "%s", result); + else + sprintf(parsed_filename + strlen(parsed_filename), "%s%s", result, ".jpeg"); + + EM_DEBUG_LOG(">>> FileName [ %s ] ", result); + + EM_DEBUG_FUNC_END("parsed_filename [%s] ", parsed_filename); + return parsed_filename; + } + + +EXPORT_API int em_core_get_attribute_value_of_body_part(PARAMETER *input_param, char *atribute_name, char *output_value, int output_buffer_length, int with_rfc2047_text, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("input_param [%p], atribute_name [%s], output_buffer_length [%d], with_rfc2047_text [%d]", input_param, atribute_name, output_buffer_length, with_rfc2047_text); + PARAMETER *temp_param = input_param; + char *decoded_value = NULL, *result_value = NULL; + int ret = false, err = EMF_ERROR_NONE; + + if(!output_value) { + EM_DEBUG_EXCEPTION("EMF_ERROR_INVALID_PARAM"); + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + memset(output_value, 0, output_buffer_length); + + while (temp_param) { + if (!strcasecmp(temp_param->attribute, atribute_name)) { + EM_DEBUG_LOG("temp_param->value [%s]", temp_param->value); + if (temp_param->value) { + if (with_rfc2047_text) { + decoded_value = em_core_decode_rfc2047_text(temp_param->value, &err); + if (decoded_value) + result_value = decoded_value; + else + result_value = decoded_value; + } + else + result_value = temp_param->value; + } + else { + EM_DEBUG_EXCEPTION("EMF_ERROR_DATA_NOT_FOUND"); + err = EMF_ERROR_DATA_NOT_FOUND; + goto FINISH_OFF; + } + EM_DEBUG_LOG("result_value [%s]", result_value); + if(result_value) { + if(output_buffer_length > strlen(result_value)) { + strncpy(output_value, result_value, output_buffer_length); + output_value[strlen(result_value)] = NULL_CHAR; + ret = true; + } + else { + EM_DEBUG_EXCEPTION("buffer is too short"); + err = EMF_ERROR_DATA_TOO_LONG; + goto FINISH_OFF; + } + } + + break; + } + temp_param = temp_param->next; + } + +FINISH_OFF: + EM_SAFE_FREE(decoded_value); + + if(err_code) + *err_code = err; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + + +/* + *download body part of imap mail (body-text and attachment) + */ +static int em_core_get_body_part_imap(MAILSTREAM *stream, int account_id, int mail_id, int msg_uid, BODY *body, struct _m_content_info *cnt_info, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("stream[%p], msg_uid[%d], body[%p], cnt_info[%p], err_code[%p]", stream, msg_uid, body, cnt_info, err_code); + + int err = EMF_ERROR_NONE, ret = -1; + struct attachment_info **ai; + struct attachment_info *prev_ai = NULL; + struct attachment_info *next_ai = NULL; + char *savefile = NULL; + char *o_data = NULL; + char filename[MAX_PATH + 1] = { 0, }; + char *decoded_filename = NULL; + int is_attachment = 0; + int o_data_len = 0; + char *filename_temp = NULL; + char charset_value_buffer[512] = { 0, }; +/* { is_pb */ + PART *part = NULL; + int dec_len; + int i = 0; + char *sparep = NULL; + unsigned short encode = 0; + int section_plain = 0; + int section_html = 0; + int is_pbd = (account_id == 0 && mail_id == 0) ? true : false; +/* } is_pb */ + + EM_DEBUG_LOG("Grab Type [ %d ] ", cnt_info->grab_type); + + /* unknown type */ + if (body->type > TYPEOTHER) { /* unknown type */ + EM_DEBUG_EXCEPTION("Unknown type."); + err = EMF_ERROR_NOT_SUPPORTED; + goto FINISH_OFF; + } + + if (NULL == body->subtype) { + EM_DEBUG_LOG("body->subtype is null. "); /* not exceptional case */ + if (err_code != NULL) + *err_code = EMF_ERROR_INVALID_PARAM; + return FAILURE; + } + + if (is_pbd) { + if (!em_core_get_temp_file_name(&o_data, &err) || !o_data) { + EM_DEBUG_EXCEPTION("em_core_get_temp_file_name failed [%d]", err); + if (err_code != NULL) + *err_code = err; + return FAILURE; + } + + + if (body->subtype[0] == 'P') { /* Sub type is PLAIN_TEX */ + if (cnt_info->text.plain != NULL) + EM_SAFE_FREE(o_data); + } + + if (body->type == TYPETEXT && body->subtype && + (!body->disposition.type || (body->disposition.type && (body->disposition.type[0] == 'i' || body->disposition.type[0] == 'I')))) { + if (body->subtype[0] == 'H') /* HTM */ + cnt_info->text.html = o_data; + else + cnt_info->text.plain = o_data; + + memset(charset_value_buffer, 0, 512); + + if (em_core_get_attribute_value_of_body_part(body->parameter, "CHARSET", charset_value_buffer, 512, true, &err)) { + cnt_info->text.plain_charset = EM_SAFE_STRDUP(charset_value_buffer); + EM_DEBUG_LOG(">>>>> CHARSET [%s] ", filename); + } + } + } /* is_pbd */ + + if ((body->id) && strlen(body->id) > 1) { /* if Content-ID or Content-Location exists, it is inline contents */ + EM_DEBUG_LOG("body->id exist"); + size_t len = 0; + /* Get actual name of file - fix for inline images to be stored with actual names and not .jpeg */ + if (body->parameter) { + PARAMETER *param1 = body->parameter; + while (param1) { + EM_DEBUG_LOG("param1->attribute - %s ", param1->attribute); + if (!strcasecmp(param1->attribute, "NAME")) { /* attribute is "NAME" */ + char *extcheck = NULL; + + if (param1->value) { + decoded_filename = em_core_decode_rfc2047_text(param1->value, &err); + strncpy(filename, decoded_filename, MAX_PATH); + EM_SAFE_FREE(decoded_filename); + } + EM_DEBUG_LOG(">>>>> FILENAME [%s] ", filename); + extcheck = strchr(filename, '.'); + + if (extcheck) + EM_DEBUG_LOG(">>>> Extension Exist in the Attachment [ %s ] ", extcheck); + else /* No extension attached , So add the Extension based on the subtyp */ { + if (body->subtype) { + strcat(filename, "."); + strcat(filename, body->subtype); + EM_DEBUG_LOG(">>>>> FILENAME Identified the Extension [%s] ", filename); + } + else + EM_DEBUG_EXCEPTION("UnKnown Extesnsion : _ ("); + + } + + break; + } + param1 = param1->next; + } + + } + else if (body->disposition.type) { + PARAMETER *param = body->disposition.parameter; + + while (param) { + EM_DEBUG_LOG(">>>>> body->disposition.parameter->attribute [ %s ] ", param->attribute); + EM_DEBUG_LOG(">>>>> body->disposition.parameter->value [ %s ] ", param->value); + + /* attribute is "filename" */ + if (!strcasecmp(param->attribute, "filename")) { + decoded_filename = em_core_decode_rfc2047_text(param->value, &err); + strncpy(filename, decoded_filename, MAX_PATH); + EM_SAFE_FREE(decoded_filename); + EM_DEBUG_LOG(">>>>> FILENAME [%s] ", filename); + break; + } + + param = param->next; + } + } + else { + if ((body->id[0] == '<')) + SNPRINTF(filename, MAX_PATH, body->id+1); + else + SNPRINTF(filename, MAX_PATH, body->id); + + len = strlen(filename); + + if ((len > 1) && (filename[len-1] == '>')) + filename[len-1] = '\0'; + } + /* is_attachment = 1; */ + is_attachment = 0; + } + else if (body->location) { + EM_DEBUG_LOG("body->location exist"); + is_attachment = 1; + decoded_filename = em_core_decode_rfc2047_text(body->location, &err); + strncpy(filename, decoded_filename, MAX_PATH); + EM_SAFE_FREE(decoded_filename); + EM_DEBUG_LOG("body->location [%s]", body->location); + } + else if (is_pbd && (strncmp(body->subtype, "RFC822", strlen("RFC822")) == 0) && (cnt_info->grab_type == 0 || cnt_info->grab_type & GRAB_TYPE_ATTACHMENT)) { + EM_DEBUG_LOG("Beause subtype is RFC822. This is ttachment"); + is_attachment = 1; + + if (cnt_info->grab_type == 0) { + if ((body->nested.msg != NULL) && (body->nested.msg->env != NULL) && (body->nested.msg->env->subject != NULL)) { + decoded_filename = em_core_decode_rfc2047_text(body->nested.msg->env->subject, &err); + strncpy(filename, decoded_filename, MAX_PATH); + EM_SAFE_FREE(decoded_filename); + } + else + strncpy(filename, "Unknown <message/rfc822>", MAX_PATH); + } + else if (cnt_info->grab_type & GRAB_TYPE_ATTACHMENT) { + BODY *temp_body = NULL; + if (body->nested.msg->env->subject != NULL) { + int i = 0; + int subject_count = 0; + if (g_str_has_prefix(body->nested.msg->env->subject, "= ? ") && g_str_has_suffix(body->nested.msg->env->subject, " ? = ")) + strncpy(filename, "unknown", MAX_PATH); + else { + for (subject_count = 0; body->nested.msg->env->subject[subject_count] != '\0' ; subject_count++) { + if (body->nested.msg->env->subject[subject_count] != ':' && + body->nested.msg->env->subject[subject_count] != ';' && + body->nested.msg->env->subject[subject_count] != '*' && + body->nested.msg->env->subject[subject_count] != '?' && + body->nested.msg->env->subject[subject_count] != '\"' && + body->nested.msg->env->subject[subject_count] != '<' && + body->nested.msg->env->subject[subject_count] != '>' && + body->nested.msg->env->subject[subject_count] != '|' && + body->nested.msg->env->subject[subject_count] != '/') { + filename[i] = body->nested.msg->env->subject[subject_count]; + i++; + } + else + continue; + } + } + } + else + strncpy(filename, "Unknown", MAX_PATH); + + body = ((MESSAGE *)body->nested.msg)->body; + part = body->nested.part; + + if ((body->subtype[0] == 'P') || (body->subtype[0] == 'H')) + temp_body = body; + else if (part != NULL) { + temp_body = &(part->body); + if ((temp_body->subtype[0] == 'P' || temp_body->subtype[0] == 'H') && part->next != NULL) { + part = part->next; + temp_body = &(part->body); + } + } + + if (temp_body) { + if (temp_body->subtype[0] == 'P') + section_plain = 1; + else if (temp_body->subtype[0] == 'H') + section_html = 1; + + sparep = temp_body->sparep; + encode = temp_body->encoding; + } + + } + } + else if (body->disposition.type) /* if disposition exists, get filename from disposition parameter */ { /* "attachment" or "inline" or etc.. */ + EM_DEBUG_LOG("body->disposition.type exist"); + is_attachment = 1; + + if (em_core_get_attribute_value_of_body_part(body->disposition.parameter, "filename", filename, MAX_PATH, true, &err)) + EM_DEBUG_LOG(">>>>> FILENAME [%s] ", filename); + + if (!*filename) { /* If the part has no filename, it may be report ms */ + if ((body->disposition.type[0] == 'i' || body->disposition.type[0] == 'I') && body->parameter && body->parameter->attribute && strcasecmp(body->parameter->attribute, "NAME")) + is_attachment = 0; + else if (body->parameter) /* Fix for the MMS attachment File name as unknown */ { + char *extcheck = NULL; + + if (em_core_get_attribute_value_of_body_part(body->parameter, "NAME", filename, MAX_PATH, true, &err)) + EM_DEBUG_LOG("NAME [%s] ", filename); + + extcheck = strchr(filename, '.'); + + if (extcheck) + EM_DEBUG_LOG(">>>> Extension Exist in the Attachment [ %s ] ", extcheck); + else { /* No extension attached , So add the Extension based on the subtype */ + if (body->subtype) { + if (strlen(filename) + strlen(body->subtype) + 1 < MAX_PATH) { + strcat(filename, "."); + strcat(filename, body->subtype); + } + EM_DEBUG_LOG(">>>>> FILENAME Identified the Extension [%s] ", filename); + } + else + EM_DEBUG_EXCEPTION("UnKnown Extesnsion : _ ("); + } + + } + else + strncpy(filename, "unknown", MAX_PATH); + } + else { + if ((body->disposition.type[0] == 'i' || body->disposition.type[0] == 'I')) + is_attachment = 0; + } + } + + /* if (!is_pbd) */ { + EM_DEBUG_LOG("filename [%s]", filename); + if (*filename) { + decoded_filename = em_core_decode_rfc2047_text(filename, &err); + strncpy(filename, decoded_filename, MAX_PATH); + EM_SAFE_FREE(decoded_filename); + filename_temp = em_parse_filename(filename); + if (filename_temp) { + strncpy(filename, filename_temp, MAX_PATH); + EM_DEBUG_LOG("filename [%s]", filename); + } + } + } + EM_DEBUG_LOG("is_attachment [%d]", is_attachment); + + if (!is_attachment) { /* Text or RFC822 Message */ + EM_DEBUG_LOG("Multipart is not attachment, body->type = %d", body->type); + if ((cnt_info->grab_type & GRAB_TYPE_TEXT) && (body->type == TYPEMESSAGE || body->type == TYPETEXT || body->type == TYPEIMAGE)) { + if (is_pbd) + return SUCCESS; + else { /* fetch body */ + if (!em_core_get_temp_file_name(&o_data, &err)) { + EM_DEBUG_EXCEPTION("em_core_get_temp_file_name failed [%d]", err); + goto FINISH_OFF; + } + + if (!imap_mail_write_body_to_file(stream, account_id, mail_id, 0, o_data, msg_uid, body->sparep, body->encoding, &o_data_len, body->subtype, &err)) { + EM_DEBUG_EXCEPTION("imap_mail_write_body_to_file failed [%d]", err); + goto FINISH_OFF; + } + } + } + + switch (body->type) { + case TYPETEXT: + EM_DEBUG_LOG("TYPETEXT"); + if (body->subtype[0] == 'H') + cnt_info->text.html = o_data; + else { + cnt_info->text.plain = o_data; + memset(charset_value_buffer, 0, 512); + if (em_core_get_attribute_value_of_body_part(body->parameter, "CHARSET", charset_value_buffer, 512, true, &err)) + cnt_info->text.plain_charset = EM_SAFE_STRDUP(charset_value_buffer); + } + break; + case TYPEIMAGE: + case TYPEAPPLICATION: + /* Inline Content - suspect of crash on partial body download */ + if (!is_pbd) { + EM_DEBUG_LOG("TYPEIMAGE or TYPEAPPLICATION : inline content"); + ai = &(cnt_info->file); + + dec_len = body->size.bytes; + if ((cnt_info->grab_type & GRAB_TYPE_ATTACHMENT) && + (cnt_info->grab_type & GRAB_TYPE_TEXT)) { /* it is 'download all */ + only_body_download = false; + cnt_info->file_no = 1; + } + + /* add attachment info to content info */ + if (!(*ai = em_core_malloc(sizeof(struct attachment_info)))) { + EM_DEBUG_EXCEPTION("em_core_malloc failed..."); + if (err_code != NULL) + *err_code = EMF_ERROR_OUT_OF_MEMORY; + return FAILURE; + } + + memset(*ai, 0, sizeof(struct attachment_info)); + + if (((body->id) || (body->location)) && body->type == TYPEIMAGE) + (*ai)->type = 1; /* inline */ + else + (*ai)->type = 2; /* attachment */ + + (*ai)->name = EM_SAFE_STRDUP(filename); + (*ai)->size = body->size.bytes; + (*ai)->save = o_data; + EM_DEBUG_LOG("file->name[%s], file->size[%d], file->save[%s], file->content_id[%s]", cnt_info->file->name, cnt_info->file->size, cnt_info->file->save); +#ifdef __ATTACHMENT_OPTI__ + (*ai)->encoding = body->encoding; + if (body->sparep) + (*ai)->section = EM_SAFE_STRDUP(body->sparep); + + EM_DEBUG_LOG(" Encoding - %d Section No - %s ", (*ai)->encoding, (*ai)->section); +#endif + /* + if (prev_ai == NULL) { + (*ai)->next = NULL; + cnt_info->file = (*ai); + } + else { + prev_ai->next = (*ai); + (*ai)->next = NULL; + } + */ + } + break; + + case TYPEMESSAGE: /* RFC822 Message */ + EM_DEBUG_EXCEPTION("MESSAGE/RFC822"); + err = EMF_ERROR_NOT_SUPPORTED; + goto FINISH_OFF; + + default: + EM_DEBUG_EXCEPTION("Unknown type. body->type [%d]", body->type); + err = EMF_ERROR_NOT_SUPPORTED; + goto FINISH_OFF; + } + + stream->text.data = NULL; /* ? ? ? ? ? ? ? ? */ + } + else { /* Attachment */ + prev_ai = NULL; + next_ai = NULL; + ai = &cnt_info->file; + EM_DEBUG_LOG(" ai - %p ", (*ai)); + + if ((body->id) || (body->location)) { + /* For Inline content append to the end */ + for (i = 1; *ai; ai = &(*ai)->next) + i++; + } + else { /* For attachment - search till Inline content found and insert before inline */ + for (i = 1; *ai; ai = &(*ai)->next) { + if ((*ai)->type == 1) { + /* Means inline image */ + EM_DEBUG_LOG("Found Inline Content "); + next_ai = (*ai); + break; + } + i++; + prev_ai = (*ai); + } + } + + EM_DEBUG_LOG("i - %d next_ai - %p prev_ai - %p", i, next_ai, prev_ai); + + if ((cnt_info->grab_type & GRAB_TYPE_ATTACHMENT) && + (cnt_info->grab_type & GRAB_TYPE_TEXT)) { /* it is 'download all */ + EM_DEBUG_LOG("Download All"); + only_body_download = false; + cnt_info->file_no = 1; + i = 1; + } + /* meaningless code */ + dec_len = body->size.bytes; + + if (body->id) + EM_DEBUG_LOG("BODY ID [ %s ]", body->id); + else + EM_DEBUG_LOG("BODY ID IS NULL"); + + EM_DEBUG_LOG("i : %d, cnt_info->file_no : %d", i, cnt_info->file_no); + + if ( + ((cnt_info->grab_type & GRAB_TYPE_ATTACHMENT) && i == cnt_info->file_no) || /* Is it correct attachment */ + (((body->id) || (body->location)) && (cnt_info->grab_type & GRAB_TYPE_TEXT)) /* Is it inline contents */ + ) { + /* fetch attachment */ + EM_DEBUG_LOG("attachment (enc) : %s %ld bytes", filename, body->size.bytes); + EM_DEBUG_LOG(">>>>> ONLY BODY DOWNLOAD [ %d ] ", only_body_download); + + if (only_body_download == false) { + if (!em_core_get_temp_file_name(&savefile, &err)) { + EM_DEBUG_EXCEPTION("em_core_get_temp_file_name failed [%d]", err); + goto FINISH_OFF; + } + + if (!is_pbd) { + if (!imap_mail_write_body_to_file(stream, account_id, mail_id, cnt_info->file_no, savefile, msg_uid, body->sparep, body->encoding, &dec_len, body->subtype, &err)) { + EM_DEBUG_EXCEPTION("imap_mail_write_body_to_file failed [%d]", err); + goto FINISH_OFF; + } + } + } + } + + EM_DEBUG_LOG("attachment (dec) : %s %d bytes", filename, dec_len); + + /* add attachment info to content inf */ + if (!(*ai = em_core_malloc(sizeof(struct attachment_info)))) { + EM_DEBUG_EXCEPTION("em_core_malloc failed..."); + err = EMF_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + memset((*ai), 0x00, sizeof(struct attachment_info)); + if ((body->id) || (body->location)) + (*ai)->type = 1; + else + (*ai)->type = 2; + + if (is_pbd) { + if (savefile != NULL) { + if (section_plain == 1) + strcat(filename, ".txt"); + if (section_html == 1) + strcat(filename, ".html"); + section_plain = 0; + section_html = 0; + } + } /* is_pbd */ + (*ai)->name = EM_SAFE_STRDUP(filename); + (*ai)->size = dec_len; + (*ai)->save = savefile; + + #ifdef __ATTACHMENT_OPTI__ + (*ai)->encoding = body->encoding; + if (body->sparep) + (*ai)->section = EM_SAFE_STRDUP(body->sparep); + + EM_DEBUG_LOG(" Encoding - %d Section No - %s ", (*ai)->encoding, (*ai)->section); + #endif + if (body->type == TYPEAPPLICATION) { + if (!strcasecmp(body->subtype, MIME_SUBTYPE_DRM_OBJECT)) + (*ai)->drm = EMF_ATTACHMENT_DRM_OBJECT; + else if (!strcasecmp(body->subtype, MIME_SUBTYPE_DRM_RIGHTS)) + (*ai)->drm = EMF_ATTACHMENT_DRM_RIGHTS; + else if (!strcasecmp(body->subtype, MIME_SUBTYPE_DRM_DCF)) + (*ai)->drm = EMF_ATTACHMENT_DRM_DCF; + } + + /* All inline images information are stored at the end of list */ + if ((*ai)->type != 1 && next_ai != NULL) { + /* Means next_ai points to the inline attachment info structure */ + if (prev_ai == NULL) { + /* First node is inline attachment */ + (*ai)->next = next_ai; + cnt_info->file = (*ai); + } + else { + prev_ai->next = (*ai); + (*ai)->next = next_ai; + } + } + } + + ret = 0; +FINISH_OFF: + if (err_code) + *err_code = err; + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} +/* get body-part in nested part */ + +static int em_core_get_allnested_part(MAILSTREAM *stream, int account_id, int mail_id, int msg_uid, BODY *body, struct _m_content_info *cnt_info, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("stream[%p], msg_uid[%d], body[%p], cnt_info[%p], err_code[%p]", stream, msg_uid, body, cnt_info, err_code); + PART *part_child = body->nested.part; + + while (part_child) { + if (em_core_get_body(stream, account_id, mail_id, msg_uid, &part_child->body, cnt_info, err_code) < 0) + return FAILURE; + + part_child = part_child->next; + } + + EM_DEBUG_FUNC_END(); + return SUCCESS; +} + +/* get body-part in alternative multiple part */ +static int em_core_get_alternative_multi_part(MAILSTREAM *stream, int account_id, int mail_id, int msg_uid, BODY *body, struct _m_content_info *cnt_info, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("stream[%p], msg_uid[%d], body[%p], cnt_info[%p], err_code[%p]", stream, msg_uid, body, cnt_info, err_code); + + PART *part_child = body->nested.part; + + /* find the best sub part we can show */ + while (part_child) { + if (em_core_get_body(stream, account_id, mail_id, msg_uid, &part_child->body, cnt_info, err_code) < 0) + return FAILURE; + + part_child = part_child->next; + } + EM_DEBUG_FUNC_END(); + return SUCCESS; +} + +/* get body part in signed multiple part */ +static int em_core_get_signed_multi_part(MAILSTREAM *stream, int account_id, int mail_id, int msg_uid, BODY *body, struct _m_content_info *cnt_info, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("stream[%p], msg_uid[%d], body[%p], cnt_info[%p], err_code[%p]", stream, msg_uid, body, cnt_info, err_code); + EM_DEBUG_FUNC_END(); + return SUCCESS; +} + +/* get body part in encrypted multiple part */ +static int em_core_get_encrypted_multi_part(MAILSTREAM *stream, int account_id, int mail_id, int msg_uid, BODY *body, struct _m_content_info *cnt_info, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("stream[%p], msg_uid[%d], body[%p], cnt_info[%p], err_code[%p]", stream, msg_uid, body, cnt_info, err_code); + EM_DEBUG_FUNC_END(); + return SUCCESS; +} + +/* get body part in multiple part */ +static int em_core_get_multi_part(MAILSTREAM *stream, int account_id, int mail_id, int msg_uid, BODY *body, struct _m_content_info *cnt_info, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("stream[%p], msg_uid[%d], body[%p], cnt_info[%p], err_code[%p]", stream, msg_uid, body, cnt_info, err_code); + + if (!body) { + EM_DEBUG_EXCEPTION("Invalid Parameter."); + if (err_code) + *err_code = EMF_ERROR_INVALID_PARAM; + return FAILURE; + } + + switch (body->subtype[0]) { + case 'A': /* ALTERNATIVE */ + EM_DEBUG_LOG("body->subtype[0] = ALTERNATIVE"); + return em_core_get_alternative_multi_part(stream, account_id, mail_id, msg_uid, body, cnt_info, err_code); + + case 'S': /* SIGNED */ + EM_DEBUG_LOG("body->subtype[0] = SIGNED"); + return em_core_get_signed_multi_part(stream, account_id, mail_id, msg_uid, body, cnt_info, err_code); + + case 'E': /* ENCRYPTED */ + EM_DEBUG_LOG("body->subtype[0] = ENCRYPTED"); + return em_core_get_encrypted_multi_part(stream, account_id, mail_id, msg_uid, body, cnt_info, err_code); + + default: /* process all unknown as MIXED (according to the RFC 2047) */ + EM_DEBUG_LOG("body->subtype[0] = [%c].", body->subtype[0]); + return em_core_get_allnested_part(stream, account_id, mail_id, msg_uid, body, cnt_info, err_code); + } + + if (body->id) + EM_DEBUG_LOG("em_core_get_multi_part BODY ID [%s].", body->id); + else + EM_DEBUG_LOG("em_core_get_multi_part BODY ID NULL."); + EM_DEBUG_FUNC_END(); + return SUCCESS; +} + +/* get body data by body structure */ +/* if POP3, ignored */ +EXPORT_API int em_core_get_body(MAILSTREAM *stream, int account_id, int mail_id, int msg_uid, BODY *body, struct _m_content_info *cnt_info, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("stream[%p], msg_uid[%d], body[%p], cnt_info[%p], err_code[%p]", stream, msg_uid, body, cnt_info, err_code); + + if (!stream || !body || !cnt_info) { + EM_DEBUG_EXCEPTION("Invalid parameter"); + + if (err_code != NULL) + *err_code = EMF_ERROR_INVALID_PARAM; + return FAILURE; + } + + EM_DEBUG_LOG("body->type [%d]", body->type); + + switch (body->type) { + case TYPEMULTIPART: + return em_core_get_multi_part(stream, account_id, mail_id, msg_uid, body, cnt_info, err_code); + + case TYPEMESSAGE: /* not support */ + if (strcasecmp(body->subtype, "RFC822") == 0) + return em_core_get_body_part_imap(stream, account_id, mail_id, msg_uid, body, cnt_info, err_code); + break; + + case TYPETEXT: + case TYPEAPPLICATION: + case TYPEAUDIO: + case TYPEIMAGE: + case TYPEVIDEO: + case TYPEMODEL: + case TYPEOTHER: + /* exactly, get a pure body part (text and attachment */ + return em_core_get_body_part_imap(stream, account_id, mail_id, msg_uid, body, cnt_info, err_code); + + default: + break; + } + EM_DEBUG_FUNC_END(); + return SUCCESS; +} + +/* get body structure */ +EXPORT_API int em_core_get_body_structure(MAILSTREAM *stream, int msg_uid, BODY **body, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("stream[%p], msg_uid[%d], body[%p], err_code[%p]", stream, msg_uid, body, err_code); + + EM_IF_NULL_RETURN_VALUE(stream, false); + EM_IF_NULL_RETURN_VALUE(body, false); + +#ifdef __FEATURE_HEADER_OPTIMIZATION__ + ENVELOPE *env = mail_fetch_structure(stream, msg_uid, body, FT_UID | FT_PEEK | FT_NOLOOKAHEAD, 1); +#else + ENVELOPE *env = mail_fetch_structure(stream, msg_uid, body, FT_UID | FT_PEEK | FT_NOLOOKAHEAD); +#endif + if (!env) { + if (err_code) + *err_code = EMF_ERROR_MAIL_NOT_FOUND_ON_SERVER; + EM_DEBUG_EXCEPTION("mail_fetch_structure failed"); + return FAILURE; + } + +#ifdef FEATURE_CORE_DEBUG + _print_body(*body, true); /* shasikala.p@partner.samsung.co */ +#endif + EM_DEBUG_FUNC_END(); + return SUCCESS; +} + +int em_core_set_fetch_part_section(BODY *body, char *section_pfx, int section_subno, int enable_inline_list, int *total_mail_size, int *err_code); + +/* set body section to be fetched */ +EXPORT_API int em_core_set_fetch_body_section(BODY *body, int enable_inline_list, int *total_mail_size, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("body[%p], err_code[%p]", body, err_code); + + if (!body) { + EM_DEBUG_EXCEPTION("body [%p]", body); + if (err_code != NULL) + *err_code = EMF_ERROR_INVALID_PARAM; + return FAILURE; + } + + body->id = cpystr("1"); /* top level bod */ + + g_inline_count = 0; + EM_SAFE_FREE(g_inline_list); + em_core_set_fetch_part_section(body, (char *)NULL, 0, enable_inline_list, total_mail_size, err_code); + + if (body->id && body) + EM_DEBUG_LOG(">>>>> FILE NAME [ %s ] ", body->id); + else + EM_DEBUG_LOG(">>>>> BODY NULL ", body->id); + + EM_DEBUG_FUNC_END(); + return SUCCESS; +} + +/* set part section of body to be fetched */ +int em_core_set_fetch_part_section(BODY *body, char *section_pfx, int section_subno, int enable_inline_list, int *total_mail_size, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("body[%p], section_pfx[%s], section_subno[%d], err_code[%p]", body, section_pfx, section_subno, err_code); + + PART *part = NULL; + char section[64] = {0x00, }; + + /* multipart doesn't have a row to itself */ + if (body->type == TYPEMULTIPART) { + /* if not first time, extend prefix */ + if (section_pfx) { + SNPRINTF(section, sizeof(section), "%s%d.", section_pfx, ++section_subno); + } + else { + section[0] = '\0'; + } + + for (section_subno = 0, part = body->nested.part; part; part = part->next) + em_core_set_fetch_part_section(&part->body, section, section_subno++, enable_inline_list, total_mail_size, err_code); + } + else { + if (!section_pfx) /* dummy prefix if top level */ + section_pfx = ""; + + SNPRINTF(section, sizeof(section), "%s%d", section_pfx, ++section_subno); + + if (enable_inline_list && ((body->disposition.type && (body->disposition.type[0] == 'i' || body->disposition.type[0] == 'I')) || + (!body->disposition.type && body->id))) { + BODY **temp = NULL; + temp = realloc(g_inline_list, sizeof(BODY *) *(g_inline_count + 1)); + if (NULL != temp) { + memset(temp+g_inline_count, 0x00, sizeof(BODY *)); + g_inline_list = temp; + g_inline_list[g_inline_count] = body; + g_inline_count++; + temp = NULL; + } + else { + EM_DEBUG_EXCEPTION("realloc fails"); + } + + EM_DEBUG_LOG("Update g_inline_list with inline count [%d]", g_inline_count); + } + + /* if ((total_mail_size != NULL) && !(body->disposition.type && (body->disposition.type[0] == 'a' || body->disposition.type[0] == 'A')) */ + if (total_mail_size != NULL) { + *total_mail_size = *total_mail_size + (int)body->size.bytes; + EM_DEBUG_LOG("body->size.bytes [%d]", body->size.bytes); + } + + /* encapsulated message ? */ + if ((body->type == TYPEMESSAGE) && !strcasecmp(body->subtype, "RFC822") && (body = ((MESSAGE *)body->nested.msg)->body)) { + if (body->type == TYPEMULTIPART) { + section[0] = '\0'; + em_core_set_fetch_part_section(body, section, section_subno-1, enable_inline_list, total_mail_size, err_code); + } + else { /* build encapsulation prefi */ + SNPRINTF(section, sizeof(section), "%s%d.", section_pfx, section_subno); + em_core_set_fetch_part_section(body, section, 0, enable_inline_list, total_mail_size, err_code); + } + } + else { + /* set body section */ + if (body) + body->sparep = cpystr(section); + } + } + EM_DEBUG_FUNC_END(); + return SUCCESS; +} + + +static void parse_file_path_to_filename(char *src_string, char **out_string) +{ + char *token = NULL; + char *filepath = NULL; + char *str = NULL; + char *prev1 = NULL; + char *prev2 = NULL; + + filepath = EM_SAFE_STRDUP(src_string); + token = strtok_r(filepath, "/", &str); + + do { + prev2 = prev1; + prev1 = token; + } while ((token = strtok_r(NULL , "/", &str))); + + *out_string = EM_SAFE_STRDUP(prev1); + EM_SAFE_FREE(filepath); +} + +static char *em_core_decode_rfc2047_word(char *encoded_word, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("encoded_word[%s], err_code[%p]", encoded_word, err_code); + + int err = EMF_ERROR_NONE; + int base64_encoded = false, length = 0; + SIZEDTEXT src = { NULL, 0 }; + SIZEDTEXT dst = { NULL, 0 }; + gchar *charset = NULL, *encoded_text = NULL; + char *decoded_text = NULL, *decoded_word = NULL; + char *current = NULL, *start = NULL, *end = NULL; + char *buffer = (char*) em_core_malloc(strlen(encoded_word) * 2 + 1); + + if (buffer == NULL) { + EM_DEBUG_EXCEPTION("Memory allocation fail"); + err = EMF_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + strcpy(buffer, ""); + + /* encoding format : =?charset?encoding?encoded-text ?= */ + /* charset : UTF-8, EUC-KR, ... */ + /* encoding : b/B (BASE64), q/Q (QUOTED-PRINTABLE) */ + current = encoded_word; + + while (*current != NULL_CHAR) { + /* search next */ + start = strstr(current, "=?"); /* start of encoding */ + end = strstr(current, "?="); /* end of encoding */ + +#ifdef FEATURE_CORE_DEBUG + EM_DEBUG_LOG("current[%p][%s], start[%p][%s], end[%p][%s]", current, current, start, start, end, end); +#endif + if (start != NULL) { + if (current != start) { /* copy the string between current and start to buffer */ + strncat(buffer, current, start - current); + current = start; +#ifdef FEATURE_CORE_DEBUG + EM_DEBUG_LOG("1 - Buffer[%s]", buffer); +#endif + } + + if (end) { /* decode text between start and end */ + char *p = strstr(start, "?b?"); + + if (p || (p = strstr(start, "?B?"))) /* BASE64 */ + base64_encoded = true; + else { + p = strstr(start, "?q?"); + + if (p || (p = strstr(start, "?Q?"))) /* QUOTED-PRINTABLE */ + base64_encoded = false; + else { + EM_DEBUG_EXCEPTION("unknown encoding found..."); + + err = EMF_ERROR_UNKNOWN; + goto FINISH_OFF; + } + } + + if (base64_encoded) { /* BASE64 */ + charset = g_strndup(start + 2, p - (start + 2)); + encoded_text = g_strndup(p + 3, end - (p + 3)); + } + else { /* QUOTED-PRINTABLE */ + charset = g_strndup(start + 2, p - (start + 2)); + if (*(p+3) == '=') { /* encoded text might start with '='. ex) '?Q?=E0' */ + end = strstr(p+3, "?="); /* find new end flag */ + if (end) { + encoded_text = g_strndup(p + 3, end - (p + 3)); + } + else { /* end flag is not found */ + EM_DEBUG_EXCEPTION("em_core_decode_rfc2047_word decoding error : '?=' is not found..."); + + err = EMF_ERROR_UNKNOWN; + goto FINISH_OFF; + } + } + else { + encoded_text = g_strndup(p + 3, end - (p + 3)); + } + } + +#ifdef FEATURE_CORE_DEBUG + EM_DEBUG_LOG("\t >>>>>>>>>>>>>>> CHARSET[%s]", charset); + EM_DEBUG_LOG("\t >>>>>>>>>>>>>>> ENCODED_TEXT[%s]", encoded_text); +#endif + + unsigned long len = 0; + if (encoded_text != NULL) { + if (base64_encoded == true) { + if (!(decoded_text = (char *)rfc822_base64((unsigned char *)encoded_text, strlen(encoded_text), &len))) { + EM_DEBUG_EXCEPTION("rfc822_base64 falied..."); + goto FINISH_OFF; + } + } + else { + g_strdelimit(encoded_text, "_", ' '); + + if (!(decoded_text = (char *)rfc822_qprint((unsigned char *)encoded_text, strlen(encoded_text), &len))) { + EM_DEBUG_EXCEPTION("rfc822_base64 falied..."); + goto FINISH_OFF; + } + } + + src.data = (unsigned char *)decoded_text; + src.size = strlen(decoded_text); + + if (!utf8_text(&src, charset, &dst, 0)) { + EM_DEBUG_EXCEPTION("utf8_text falied..."); + strncat(buffer, (char *)src.data, src.size); /* Eventhough failed to decode, downloading should go on. Kyuho Jo */ + } + else + strncat(buffer, (char *)dst.data, dst.size); +#ifdef FEATURE_CORE_DEBUG + EM_DEBUG_LOG("2 - Buffer[%s]", buffer); +#endif + + /* free all of the temp variables */ + if (dst.data != NULL && dst.data != src.data) + EM_SAFE_FREE(dst.data); + + EM_SAFE_FREE(decoded_text); + + g_free(encoded_text); + encoded_text = NULL; + } + if (charset != NULL) { + g_free(charset); + charset = NULL; + } + + current = end + 2; /* skip '?=' */ + } + else { + /* unencoded text */ + length = strlen(start); + strncat(buffer, start, length); + current = start + length; +#ifdef FEATURE_CORE_DEBUG + EM_DEBUG_LOG("3 - Buffer[%s]", buffer); +#endif + } + } + else { + /* unencoded text */ + length = strlen(current); + strncat(buffer, current, length); + current = current + length; +#ifdef FEATURE_CORE_DEBUG + EM_DEBUG_LOG("4 - Buffer[%s]", buffer); +#endif + } + } + + decoded_word = EM_SAFE_STRDUP(buffer); + +#ifdef FEATURE_CORE_DEBUG + EM_DEBUG_LOG(">>>>>>>>>>>>>>> DECODED_WORD[%s]", decoded_word); +#endif + +FINISH_OFF: + if (dst.data != NULL && dst.data != src.data) + EM_SAFE_FREE(dst.data); + EM_SAFE_FREE(decoded_text); + EM_SAFE_FREE(buffer); + + if (encoded_text != NULL) + g_free(encoded_text); + if (charset != NULL) + g_free(charset); + + if (err_code != NULL) + *err_code = err; + + EM_DEBUG_FUNC_END(); + return decoded_word; +} + +EXPORT_API char *em_core_decode_rfc2047_text(char *rfc2047_text, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("rfc2047_text[%s], err_code[%p]", rfc2047_text, err_code); + + int ret = false; + int err = EMF_ERROR_NONE; + + if (!rfc2047_text) { + EM_DEBUG_EXCEPTION("rfc2047_text[%p]", rfc2047_text); + if (err_code != NULL) + *err_code = EMF_ERROR_INVALID_PARAM; + return NULL; + } + + char *text = NULL; + + gchar **encoded_words = g_strsplit_set(rfc2047_text, " \t\r\n", -1); + gchar **decoded_words = g_new0(char *, g_strv_length(encoded_words) + 1); + + /* EM_DEBUG_LOG("g_strv_length(encoded_words) [%d]", g_strv_length(encoded_words)); */ + + if (encoded_words != NULL) { + int i = 0; + + while (encoded_words[i] != NULL) { + if (!(decoded_words[i] = em_core_decode_rfc2047_word(encoded_words[i], &err))) { + EM_DEBUG_EXCEPTION("em_core_decode_rfc2047_word falied [%d]", err); + goto FINISH_OFF; + } + + i++; + } + text = g_strjoinv(" ", decoded_words); + } + else + text = EM_SAFE_STRDUP(rfc2047_text); + + /* Exceptional ... EUC-KR handling */ { + gsize bytes_read, bytes_written; + GError *glib_error = NULL; + int i = 0, has_special_character = 0; + char *utf8_encoded_string = NULL; + + while(text[i]) { + if(text[i++] & 0x80) { + has_special_character = 1; + break; + } + } + EM_DEBUG_LOG("has_special_character [%d]", has_special_character); + + if(has_special_character) /* It might be euc-kr. It should be encoded as UTF-8 */ { + utf8_encoded_string = (char*)g_convert (text, -1, "UTF-8", "EUC-KR", &bytes_read, &bytes_written, &glib_error); + if(utf8_encoded_string) { + EM_DEBUG_LOG("utf8_encoded_string [%s]", utf8_encoded_string); + EM_SAFE_FREE(text); + text = EM_SAFE_STRDUP(utf8_encoded_string); + } + else + EM_DEBUG_EXCEPTION("g_convert failed"); + } + } + +#ifdef FEATURE_CORE_DEBUG + EM_DEBUG_LOG(">>>>>>>>>>>>>>>>> TEXT[%s]", text); +#endif /* FEATURE_CORE_DEBUG */ + + ret = true; + +FINISH_OFF: + g_strfreev(decoded_words); + g_strfreev(encoded_words); + + if (err_code != NULL) + *err_code = err; + EM_DEBUG_FUNC_END(); + return text; +} diff --git a/email-core/em-core-mm-callbacks.c b/email-core/em-core-mm-callbacks.c new file mode 100755 index 0000000..ec3a7e4 --- /dev/null +++ b/email-core/em-core-mm-callbacks.c @@ -0,0 +1,412 @@ +/* +* email-service +* +* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. +* +* Contact: Kyuho Jo <kyuho.jo@samsung.com>, Sunghyun Kwon <sh0701.kwon@samsung.com> +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + + +/****************************************************************************** + * File : em-core-mm_callbacks.c + * Desc : mm_callbacks for IMAP-2004g + * + * Auth : + * + * History : + * 2006.08.22 : created + *****************************************************************************/ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "em-core-types.h" +#include "c-client.h" +#include "em-core-global.h" +#include "em-core-utils.h" +#include "emf-dbglog.h" +#include "em-core-mailbox.h" +#include "em-core-account.h" + +static void mm_get_error(char *string, int *err_code); + +/* + * callback mm_lsub + * get subscribed mailbox list + */ +EXPORT_API void mm_lsub(MAILSTREAM *stream, int delimiter, char *mailbox, long attributes) +{ + EM_DEBUG_FUNC_BEGIN(); + emf_callback_holder_t *p_holder = (emf_callback_holder_t *)stream->sparep; + emf_mailbox_t *p, *p_old = p_holder->data; + int count = p_holder->num; + char *s, *enc_path; + + /* memory allocation */ + p = realloc(p_old, sizeof(emf_mailbox_t) * (count + 1)); + if (!p) return ; + + /* uw-imap mailbox name format (ex : "{mail.test.com...}inbox" or "{mail.test.com...}anybox/anysubbox") */ + enc_path = strchr(mailbox, '}'); + if (enc_path) + enc_path += 1; + else { + em_core_mailbox_free(&p, count+1, NULL); + return ; + } + + /* Convert UTF7 mailbox name to UTF8 mailbox name */ + + /* convert directory delimiter to '/' */ + for (s = enc_path; *s; s++) { + if (*s == (char)delimiter) { + *s = '/'; + } + } + + /* coyp string */ + p[count].name = cpystr(enc_path); + p[count].alias = cpystr(enc_path); + p[count].local = 0; + p[count].account_id = stream->spare8; + + + p_holder->data = p; + p_holder->num++; + + /* ignore attributes */ +/* if (attributes & latt_noinferiors) fputs (", no inferiors", fp_log); */ +/* if (attributes & latt_noselect) fputs (", no select", fp_log); */ +/* if (attributes & latt_marked) fputs (", marked", fp_log); */ +/* if (attributes & latt_unmarked) fputs (", unmarked", fp_log); */ + EM_DEBUG_FUNC_END(); +} + + +/* + * callback mm_lsub + * get mailbox list + */ +EXPORT_API void mm_list(MAILSTREAM *stream, int delimiter, char *mailbox, long attributes) +{ + EM_DEBUG_FUNC_BEGIN(); + emf_callback_holder_t *p_holder = (emf_callback_holder_t *)stream->sparep; + emf_mailbox_t *p, *p_old = p_holder->data; + int count = p_holder->num; + char *s, *enc_path; + + /* memory allocation */ + p = realloc(p_old, sizeof(emf_mailbox_t) * (count + 1)); + if (!p) return ; + + /* uw-imap mailbox name format (ex : "{mail.test.com...}inbox" or "{mail.test.com...}anybox/anysubbox") */ + enc_path = strchr(mailbox, '}'); + if (enc_path) + enc_path += 1; + else { + em_core_mailbox_free(&p, count+1, NULL); + return ; + } + + /* convert directory delimiter to '/' */ + for (s = enc_path;*s;s++) + if (*s == (char)delimiter) + *s = '/'; + + /* coyp string */ + memset(p + count, 0x00, sizeof(emf_mailbox_t)); + p[count].name = cpystr(enc_path); + p[count].alias = cpystr(enc_path); + p[count].local = 0; + EM_DEBUG_LOG("mm_list account_id %d", stream->spare8); + + char *tmp = NULL; + /* in mailbox name parse n get user = %d - which is account_id */ + tmp = strstr(mailbox, "user="); + if (tmp) { + tmp = tmp+5; + for (s = tmp; *s != '/'; s++); + *s = '\0'; + p[count].account_id = atoi(tmp); + } + EM_DEBUG_LOG("mm_list account_id1 %d ", p[count].account_id); + EM_DEBUG_LOG("mm_list mailbox name r %s ", p[count].name); + p_holder->data = p; + p_holder->num++; + + /* ignore attributes */ + EM_DEBUG_FUNC_END(); +} + + +/* + * callback mm_status + * get mailbox status + */ +EXPORT_API void mm_status(MAILSTREAM *stream, char *mailbox, MAILSTATUS* status) +{ + EM_DEBUG_FUNC_BEGIN(); + emf_callback_holder_t *p = stream->sparep; + + EM_DEBUG_FUNC_BEGIN(); + if (status->flags & SA_MESSAGES) + p->num = status->messages; + if (status->flags & SA_UNSEEN) + p->data = (void *)status->unseen; + EM_DEBUG_FUNC_END(); +} + +/* callback mm_login + * get user_name and password + */ + +EXPORT_API void mm_login(NETMBX *mb, char *user, char *pwd, long trial) +{ + EM_DEBUG_FUNC_BEGIN(); + int account_id; + emf_account_t *ref_account; + char *username = NULL; + char *password = NULL; + + if (!mb->user[0]) { + EM_DEBUG_EXCEPTION("invalid account_id..."); + return; + } + + account_id = atoi(mb->user); + + ref_account = em_core_get_account_reference(account_id); + + if (!ref_account) { + EM_DEBUG_EXCEPTION("em_core_get_account_reference failed"); + return; + } + + if (ref_account->user_name == NULL) { + EM_DEBUG_EXCEPTION("invalid user_name..."); + return; + } + username = EM_SAFE_STRDUP(ref_account->user_name); + + if (ref_account->password == NULL) { + EM_SAFE_FREE(username); + EM_DEBUG_EXCEPTION("invalid password..."); + return; + } + + password = EM_SAFE_STRDUP(ref_account->password); + + if (username && password && strlen(username) > 0 && strlen(password) > 0) { + strcpy(user, username); + strcpy(pwd, password); + } + else + EM_DEBUG_EXCEPTION("User Information is NULL || strlen is 0 "); + + EM_SAFE_FREE(username); + EM_SAFE_FREE(password); + + EM_DEBUG_FUNC_END(); +} + + +EXPORT_API void mm_dlog(char *string) +{ +#ifdef FEATURE_CORE_DEBUG + EM_DEBUG_LOG("IMAP_TOOLKIT_DLOG [%s]", string); + /* Write into debug file + FILE *fp_dlog = NULL; + fp_dlog = fopen("/opt/data/email/.emfdata/core_debug", "a"); + if(fp_dlog) { + fprintf(fp_dlog, "%s\n", string); + fclose(fp_dlog); + } + */ +#endif +} + +EXPORT_API void mm_log(char *string, long errflg) +{ + /* EM_DEBUG_FUNC_BEGIN(); */ + + switch ((short)errflg) { + case NIL: + EM_DEBUG_LOG("IMAP_TOOLKIT_LOG NIL [%s]", string); + break; + + case WARN: + EM_DEBUG_LOG("IMAP_TOOLKIT_LOG WARN [%s]", string); + break; + + case PARSE: + EM_DEBUG_LOG("IMAP_TOOLKIT_LOG PARSE [%s]", string); + break; + + case BYE: + EM_DEBUG_LOG("IMAP_TOOLKIT_LOG BYE [%s]", string); + break; + + case TCPDEBUG: + EM_DEBUG_LOG("IMAP_TOOLKIT_LOG TCPDEBUG [%s]", string); + break; + + case ERROR: { + emf_session_t *session = NULL; + + EM_DEBUG_EXCEPTION("IMAP_TOOLKIT_LOG ERROR [%s]", string); + + em_core_get_current_session(&session); + + if (session) { + mm_get_error(string, &session->error); + EM_DEBUG_EXCEPTION("IMAP_TOOLKIT_LOG ERROR [%d]", session->error); + } + + /* Handling exceptional case of connection failures. */ + /* + if (string) { + if (strstr(string, "15 minute") != 0) { + if (session) + session->error = EMF_ERROR_LOGIN_ALLOWED_EVERY_15_MINS; + } + else if (strstr(string, "Too many login failures") == 0) { + if (session) + session->error = EMF_ERROR_TOO_MANY_LOGIN_FAILURE; + } + } + */ + + break; + } + } +} + +EXPORT_API void mm_searched(MAILSTREAM *stream, unsigned long number) +{ + EM_DEBUG_FUNC_BEGIN("stream [%p], number [%d]", stream, number); + EM_DEBUG_FUNC_END(); +} + +EXPORT_API void mm_exists(MAILSTREAM *stream, unsigned long number) +{ + EM_DEBUG_FUNC_BEGIN("stream [%p], number [%d]", stream, number); + EM_DEBUG_FUNC_END(); +} + +EXPORT_API void mm_expunged(MAILSTREAM *stream, unsigned long number) +{ + EM_DEBUG_FUNC_BEGIN("stream [%p], number [%d]", stream, number); + EM_DEBUG_FUNC_END(); +} + +EXPORT_API void mm_flags(MAILSTREAM *stream, unsigned long number) +{ + EM_DEBUG_FUNC_BEGIN("stream [%p], number [%d]", stream, number); + EM_DEBUG_FUNC_END(); +} + +EXPORT_API void mm_notify(MAILSTREAM *stream, char *string, long errflg) +{ + EM_DEBUG_FUNC_BEGIN(); + mm_log(string, errflg); + EM_DEBUG_FUNC_END(); +} + +EXPORT_API void mm_critical(MAILSTREAM *stream) +{ + EM_DEBUG_FUNC_BEGIN("stream [%p]", stream); + EM_DEBUG_FUNC_END(); +} + +EXPORT_API void mm_nocritical(MAILSTREAM *stream) +{ + EM_DEBUG_FUNC_BEGIN("stream [%p]", stream); + EM_DEBUG_FUNC_END(); +} + +EXPORT_API long mm_diskerror(MAILSTREAM *stream, long errcode, long serious) +{ + EM_DEBUG_FUNC_BEGIN("stream [%p] errcode[%d] serious[%d]", stream, errcode, serious); +#if UNIXLIKE + kill(getpid(), SIGSTOP); +#else + abort(); +#endif + EM_DEBUG_FUNC_END(); + return NIL; +} + +EXPORT_API void mm_fatal(char *string) +{ + EM_DEBUG_EXCEPTION("%s", string); +} + +EXPORT_API void mm_get_error(char *string, int *err_code) +{ + if (!string || !err_code) + return ; + + EM_DEBUG_LOG("string [%s]", string); + + if (strstr(string, "login failure") || strstr(string, "Login aborted") || strstr(string, "Can't login")) + *err_code = EMF_ERROR_LOGIN_FAILURE; + else if (strstr(string, "Scan not valid")) + *err_code = EMF_ERROR_MAILBOX_FAILURE; + else if (strstr(string, "Authentication cancelled")) + *err_code = EMF_ERROR_AUTHENTICATE; + else if (strstr(string, "authuser")) + *err_code = EMF_ERROR_AUTH_NOT_SUPPORTED; + else if (strstr(string, "negotiate TLS")) + *err_code = EMF_ERROR_CANNOT_NEGOTIATE_TLS; + else if (strstr(string, "TLS/SSL failure")) + *err_code = EMF_ERROR_TLS_SSL_FAILURE; + else if (strstr(string, "STARTLS")) + *err_code = EMF_ERROR_STARTLS; + else if (strstr(string, "TLS unavailable")) + *err_code = EMF_ERROR_TLS_NOT_SUPPORTED; + else if (strstr(string, "Can't access")) + *err_code = EMF_ERROR_APPEND_FAILURE; + else if (strstr(string, "Can not authenticate")) + *err_code = EMF_ERROR_AUTHENTICATE; + else if (strstr(string, "Unexpected IMAP response") || strstr(string, "hello")) + *err_code = EMF_ERROR_INVALID_RESPONSE; + else if (strstr(string, "NOTIMAP4REV1")) + *err_code = EMF_ERROR_COMMAND_NOT_SUPPORTED; + else if (strstr(string, "Anonymous")) + *err_code = EMF_ERROR_ANNONYM_NOT_SUPPORTED; + else if (strstr(string, "connection broken")) + *err_code = EMF_ERROR_CONNECTION_BROKEN; + else if (strstr(string, "SMTP greeting")) + *err_code = EMF_ERROR_NO_RESPONSE; + else if (strstr(string, "ESMTP failure")) + *err_code = EMF_ERROR_SMTP_SEND_FAILURE; + else if (strstr(string, "socket") || strstr(string, "Socket")) + *err_code = EMF_ERROR_SOCKET_FAILURE; + else if (strstr(string, "connect to") || strstr(string, "Connection failed")) + *err_code = EMF_ERROR_CONNECTION_FAILURE; + else if (strstr(string, "Certificate failure")) + *err_code = EMF_ERROR_CERTIFICATE_FAILURE; + else if (strstr(string, "ESMTP failure")) + *err_code = EMF_ERROR_INVALID_PARAM; + else if (strstr(string, "No such host")) + *err_code = EMF_ERROR_NO_SUCH_HOST; + else if (strstr(string, "host") || strstr(string, "Host")) + *err_code = EMF_ERROR_INVALID_SERVER; + else if (strstr(string, "SELECT failed")) + *err_code = EMF_ERROR_MAILBOX_NOT_FOUND; + else + *err_code = EMF_ERROR_UNKNOWN; +} +/* EOF */ diff --git a/email-core/em-core-smtp.c b/email-core/em-core-smtp.c new file mode 100755 index 0000000..de370ef --- /dev/null +++ b/email-core/em-core-smtp.c @@ -0,0 +1,3646 @@ +/* +* email-service +* +* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. +* +* Contact: Kyuho Jo <kyuho.jo@samsung.com>, Sunghyun Kwon <sh0701.kwon@samsung.com> +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <fcntl.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <time.h> +#include "em-core-types.h" +#include "c-client.h" +#include "em-core-global.h" +#include "em-core-utils.h" +#include "em-storage.h" +#include "em-core-api.h" +#include "em-core-smtp.h" +#include "em-core-event.h" +#include "em-core-mailbox.h" +#include "em-core-mesg.h" +#include "em-core-mime.h" +#include "em-core-account.h" +#include "em-core-imap-mailbox.h" +#include "em-core-mailbox-sync.h" +#include "Msg_Convert.h" + + +#include <unistd.h> +#include "emf-dbglog.h" + + +/* Functions from uw-imap-toolkit */ +/* extern void *fs_get(size_t size); */ +extern void rfc822_date(char *date); +extern long smtp_soutr(void *stream, char *s); +extern long smtp_send(SENDSTREAM *stream, char *command, char *args); +extern long smtp_rcpt(SENDSTREAM *stream, ADDRESS *adr, long* error); + +#ifdef __FEATURE_SEND_OPTMIZATION__ +extern long smtp_soutr_test(void *stream, char *s); +#endif + + +static int em_core_mail_get_report_body(ENVELOPE *envelope, BODY **multipart_body, int *err_code); +static int em_core_mail_send_smtp(SENDSTREAM *stream, ENVELOPE *env, char *data_file, int account_id, int mail_id, int *err_code); + +void mail_send_notify(emf_send_status_t status, int total, int sent, int account_id, int mail_id, int err_code) +{ + EM_DEBUG_FUNC_BEGIN("status[%d], total[%d], sent[%d], account_id[%d], mail_id[%d], err_code[%d]", status, total, sent, account_id, mail_id, err_code); + + switch (status) { + case EMF_SEND_CONNECTION_FAIL: + case EMF_SEND_FINISH: + case EMF_SEND_FAIL: + break; + + case EMF_SEND_PROGRESS: + default: + break; + } + em_core_execute_event_callback(EMF_ACTION_SEND_MAIL, total, sent, status, account_id, mail_id, -1, err_code); + EM_DEBUG_FUNC_END(); +} + +/* ------ rfc822 handle ---------------------------------------------------*/ +long buf_flush(void *stream, char *string) +{ + EM_DEBUG_FUNC_BEGIN("stream[%p], string[%s]", stream, string); + EM_DEBUG_FUNC_END(); + return 1; +} + + +#define RFC822_READ_BLOCK_SIZE 1024 +#define RFC822_STRING_BUFFER_SIZE 1536 + +static char *em_core_find_img_tag(char *source_string) +{ + EM_DEBUG_FUNC_BEGIN("source_string[%p]", source_string); + + int cur = 0, string_length; + if (!source_string) + return false; + + string_length = strlen(source_string); + + for (cur = 0; cur < string_length; cur++) { + if (source_string[cur] == 'I' || source_string[cur] == 'i') { + cur++; + if (source_string[cur] == 'M' || source_string[cur] == 'm') { + cur++; + if (source_string[cur] == 'G' || source_string[cur] == 'g') { + EM_DEBUG_FUNC_END("%s", source_string + cur - 2); + return source_string + cur - 2; + } + } + } + } + EM_DEBUG_FUNC_END("Can't find"); + return NULL; +} + +#define CONTENT_ID_BUFFER_SIZE 512 +static char *em_core_replace_inline_image_path_with_content_id(char *source_string, BODY *html_body, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("source_string[%p], html_body[%p], err_code[%p]", source_string, html_body, err_code); + + int err = EMF_ERROR_NONE; + char content_id_buffer[CONTENT_ID_BUFFER_SIZE], file_name_buffer[512], new_string[512], *result_string = NULL, *input_string = NULL; + BODY *cur_body = NULL; + PART *cur_part = NULL; + + if (!source_string || !html_body) { + EM_DEBUG_EXCEPTION("EMF_ERROR_INVALID_PARAM"); + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + input_string = EM_SAFE_STRDUP(source_string); + + cur_part = html_body->nested.part; + + while (cur_part) { + cur_body = &(cur_part->body); + if (cur_body) { + EM_DEBUG_LOG("Has body. id[%s]", cur_body->disposition.type); + if (cur_body->disposition.type && cur_body->disposition.type[0] == 'i') { /* Is inline content? */ + EM_DEBUG_LOG("Has inline content"); + memset(content_id_buffer, 0, CONTENT_ID_BUFFER_SIZE); + if (cur_body->id) { + EM_SAFE_STRNCPY(content_id_buffer, cur_body->id + 1, CONTENT_ID_BUFFER_SIZE - 1); /* Removing <, > */ + content_id_buffer[strlen(content_id_buffer) - 1] = NULL_CHAR; + /* if (em_core_get_attribute_value_of_body_part(cur_body->parameter, "name", file_name_buffer, CONTENT_ID_BUFFER_SIZE, false, &err)) { */ + if (em_core_get_attribute_value_of_body_part(cur_body->parameter, "name", file_name_buffer, CONTENT_ID_BUFFER_SIZE, true, &err)) { + EM_DEBUG_LOG("Content-ID[%s], filename[%s]", content_id_buffer, file_name_buffer); + SNPRINTF(new_string, CONTENT_ID_BUFFER_SIZE, "cid:%s", content_id_buffer); + result_string = em_core_replace_string(input_string, file_name_buffer, new_string); + if (input_string) + EM_SAFE_FREE(input_string); + } + } + } + } + if (result_string) + input_string = result_string; + cur_part = cur_part->next; + } + + if (input_string) + result_string = EM_SAFE_STRDUP(input_string); +FINISH_OFF: + + EM_SAFE_FREE(input_string); + if (err_code) + *err_code = err; + + EM_DEBUG_FUNC_END("ret[%s]", result_string); + return result_string; +} + +static int em_core_write_rfc822_body(BODY *body, BODY *html_body, FILE *fp, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("body[%p], html_body[%p], fp[%p], err_code[%p]", body, html_body, fp, err_code); + + PARAMETER *param = NULL; + PART *part = NULL; + char *p = NULL, *bndry = NULL, buf[1025], *replaced_string = NULL; + int fd, nread, nwrite, error = EMF_ERROR_NONE; + + switch (body->type) { + case TYPEMULTIPART: + EM_DEBUG_LOG("body->type = TYPEMULTIPART"); + part = body->nested.part; + + for (param = body->parameter; param; param = param->next) { + if (strcasecmp(param->attribute, "BOUNDARY") == 0) { + bndry = param->value; + break; + } + } + + do { + p = buf; p[0] = '\0'; + + rfc822_write_body_header(&p, &part->body); + + fprintf(fp, "--%s"CRLF_STRING, bndry); + fprintf(fp, "%s"CRLF_STRING, buf); + + em_core_write_rfc822_body(&part->body, html_body, fp, err_code); + } while ((part = part->next)); + + fprintf(fp, "--%s--"CRLF_STRING, bndry); + break; + + default: { + EM_DEBUG_LOG("body->type is not TYPEMULTIPART"); + + char *file_path = body->sparep; + char buf[RFC822_STRING_BUFFER_SIZE + 1] = { 0, }, *img_tag_pos = NULL; + unsigned long len; + + p = NULL; + + if (!file_path || strlen(file_path) == 0) { + EM_DEBUG_LOG("There is no file path"); + switch (body->encoding) { + case 0: + break; + default: + p = cpystr((const char *)body->contents.text.data); + len = body->contents.text.size; + break; + } + + if (p) { + EM_DEBUG_LOG("p[%s]", p); + fprintf(fp, "%s"CRLF_STRING CRLF_STRING, p); + EM_SAFE_FREE(p); + } + + EM_SAFE_FREE(body->sparep); + EM_DEBUG_FUNC_END(); + return true; + } + + EM_DEBUG_LOG("Opening a file[%s]", file_path); + fd = open(file_path, O_RDONLY); + + if (fd < 0) { + EM_DEBUG_EXCEPTION("open(\"%s\") failed...", file_path); + return false; + } + + while (1) { + nread = read(fd, buf, (body->encoding == ENCBASE64 ? 57 : RFC822_READ_BLOCK_SIZE - 2)); + + if (nread < 0) { + close(fd); + return false; + } + + if (nread == 0) { + close(fd); + break; + } + + p = NULL; + len = nread; + + /* EM_DEBUG_LOG("body->type[%d], body->subtype[%c]", body->type, body->subtype[0]); */ + if (body->type == TYPETEXT && (body->subtype && (body->subtype[0] == 'H' || body->subtype[0] == 'h'))) { + EM_DEBUG_LOG("HTML Part"); + img_tag_pos = em_core_find_img_tag(buf); + + if (img_tag_pos) { + replaced_string = em_core_replace_inline_image_path_with_content_id(buf, html_body, &error); + if (replaced_string) { + EM_DEBUG_LOG("em_core_replace_inline_image_path_with_content_id succeeded"); + strcpy(buf, replaced_string); + nread = len = strlen(buf); + EM_DEBUG_LOG("buf[%s], nread[%d], len[%d]", buf, nread, len); + } + else + EM_DEBUG_LOG("em_core_replace_inline_image_path_with_content_id failed[%d]", error); + } + } + + switch (body->encoding) { + case ENCQUOTEDPRINTABLE: + p = (char *)rfc822_8bit((unsigned char *)buf, (unsigned long)nread, (unsigned long *)&len); + break; + case ENCBASE64: + p = (char *)rfc822_binary((void *)buf, (unsigned long)nread, (unsigned long *)&len); + break; + default: + buf[len] = '\0'; + break; + } + + + nwrite = fprintf(fp, "%s", (p ? p : buf)); + + if (nwrite != len) { + fclose(fp); + close(fd); + EM_SAFE_FREE(p); + EM_DEBUG_EXCEPTION("fprintf failed nwrite[%d], len[%d]", nwrite, len); + return false; + } + EM_SAFE_FREE(p); + } + + if (body->encoding == ENCQUOTEDPRINTABLE || body->encoding == ENCBASE64) + fprintf(fp, CRLF_STRING); + + fprintf(fp, CRLF_STRING); + + if (body->sparep) { + free(body->sparep); + body->sparep = NULL; + } + + break; + } /* default: */ + } + EM_DEBUG_FUNC_END(); + return true; +} + +static int em_core_write_rfc822(ENVELOPE *env, BODY *body, BODY *html_body, emf_extra_flag_t flag, char **data, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("env[%p], body[%p], data[%p], err_code[%p]", env, body, data, err_code); + + int ret = false; + int error = EMF_ERROR_NONE; + + FILE *fp = NULL; + char *fname = NULL; + char *p = NULL; + size_t p_len = 0; + + if (!env || !data) { + EM_DEBUG_EXCEPTION("Invalid Parameters"); + error = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + srand(time(NULL)); + + rfc822_encode_body_7bit(env, body); /* if contents.text.data isn't NULL, the data will be encoded. */ + + /* FIXME : create memory map for this file */ + p_len = (env->subject ? strlen(env->subject) : 0) + 8192; + + if (!(p = em_core_malloc(p_len))) { /* (env->subject ? strlen(env->subject) : 0) + 8192))) */ + EM_DEBUG_EXCEPTION(" malloc failed..."); + error = EMF_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + + RFC822BUFFER buf; + + /* write at start of buffer */ + buf.end = (buf.beg = buf.cur = p) + p_len - 1; + /* buf.f = NIL; */ + buf.f = buf_flush; + buf.s = NIL; + + /* rfc822_output_header(&buf, env, body, NIL, T); */ /* including BCC */ + rfc822_output_header(&buf, env, body, NIL, NIL); /* Excluding BCC */ + + *buf.cur = '\0'; /* tie off buffer */ + { + gchar **tokens = g_strsplit(p, "CHARSET=X-UNKNOWN", 2); + + if (g_strv_length(tokens) > 1) { + gchar *charset; + + if (body->sparep) { + charset = g_path_get_basename(body->sparep); + char *pHtml = NULL; + if (charset != NULL) { + if ((pHtml = strstr(charset, ".htm")) != NULL) + charset[pHtml-charset] = '\0'; + } + + SNPRINTF(p, p_len, "%sCHARSET=%s%s", tokens[0], charset, tokens[1]); + g_free(charset); + } + else + EM_DEBUG_EXCEPTION("body->sparep is NULL"); + } + + g_strfreev(tokens); + } { + gchar **tokens = g_strsplit(p, "To: undisclosed recipients: ;\015\012", 2); + if (g_strv_length(tokens) > 1) + SNPRINTF(p, p_len, "%s%s", tokens[0], tokens[1]); + g_strfreev(tokens); + } + + + EM_DEBUG_LOG(" =============================================================================== " + LF_STRING"%s"LF_STRING + " =============================================================================== ", p); + + if (strlen(p) > 2) + *(p + strlen(p) - 2) = '\0'; + + + if (flag.report) { + char buf[512] = {0x00, }; + switch (flag.report) { + case EMF_MAIL_REPORT_DSN: /* DSN (delivery status) */ + /* change content-type */ + /* Content-Type: multipart/report; */ + /* report-type= delivery-status; */ + /* boundary="----=_NextPart_000_004F_01C76EFF.54275C50" */ + break; + + case EMF_MAIL_REPORT_MDN: /* MDN (read receipt) */ + /* Content-Type: multipart/report; */ + /* report-type= disposition-notification; */ + /* boundary="----=_NextPart_000_004F_01C76EFF.54275C50" */ + break; + + case EMF_MAIL_REPORT_REQUEST: /* require read status */ + rfc822_address(buf, env->from); + if (strlen(buf)) + SNPRINTF(p + strlen(p), p_len-(strlen(p)), "Disposition-Notification-To: %s"CRLF_STRING, buf); + break; + + default: + break; + } + } + + if (flag.priority) { /* priority (1:high 3:normal 5:low) */ + SNPRINTF(p + strlen(p), p_len-(strlen(p)), "X-Priority: %d"CRLF_STRING, flag.priority); + + switch (flag.priority) { + case EMF_MAIL_PRIORITY_HIGH: + SNPRINTF(p + strlen(p), p_len-(strlen(p)), "X-MSMail-Priority: HIgh"CRLF_STRING); + break; + case EMF_MAIL_PRIORITY_NORMAL: + SNPRINTF(p + strlen(p), p_len-(strlen(p)), "X-MSMail-Priority: Normal"CRLF_STRING); + break; + case EMF_MAIL_PRIORITY_LOW: + SNPRINTF(p + strlen(p), p_len-(strlen(p)), "X-MSMail-Priority: Low"CRLF_STRING); + break; + } + } + + SNPRINTF(p + strlen(p), p_len-(strlen(p)), CRLF_STRING); + + if (!em_core_get_temp_file_name(&fname, &error)) { + EM_DEBUG_EXCEPTION(" em_core_get_temp_file_name failed[%d]", error); + goto FINISH_OFF; + } + + if (!(fp = fopen(fname, "w+"))) { + EM_DEBUG_EXCEPTION("fopen failed[%s]", fname); + error = EMF_ERROR_SYSTEM_FAILURE; + goto FINISH_OFF; + } + + fprintf(fp, "%s", p); + + if (body) { + if (!em_core_write_rfc822_body(body, html_body, fp, &error)) { + EM_DEBUG_EXCEPTION("em_core_write_rfc822_body failed[%d]", error); + goto FINISH_OFF; + } + } + + ret = true; + + +FINISH_OFF: + if (fp != NULL) + fclose(fp); + +#ifdef USE_SYNC_LOG_FILE + em_storage_copy_file(fname, "/tmp/phone2pc.eml", false, NULL); +#endif + + if (ret == true) + *data = fname; + else if (fname != NULL) { + remove(fname); + EM_SAFE_FREE(fname); + } + + EM_SAFE_FREE(p); + + if (err_code != NULL) + *err_code = error; + EM_DEBUG_FUNC_END(); + return ret; +} + +static int em_core_set_current_time_to_mail_header(emf_mail_head_t *head, int *err) +{ + EM_DEBUG_FUNC_BEGIN("head[%p], err [%p]", head, err); + + int err_code = EMF_ERROR_NONE, ret = false; + time_t t = time(NULL); + struct tm *p_tm = NULL; + + if(!head) { + EM_DEBUG_EXCEPTION("EMF_ERROR_INVALID_PARAM"); + err_code = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + p_tm = gmtime(&t); + + if (!p_tm) { + EM_DEBUG_EXCEPTION("localtime failed..."); + err_code = EMF_ERROR_SYSTEM_FAILURE; + goto FINISH_OFF; + } + + head->datetime.year = p_tm->tm_year + 1900; + head->datetime.month = p_tm->tm_mon + 1; + head->datetime.day = p_tm->tm_mday; + head->datetime.hour = p_tm->tm_hour; + head->datetime.minute = p_tm->tm_min; + head->datetime.second = p_tm->tm_sec; + + ret = true; + +FINISH_OFF: + + if(err) + *err = err_code; + + EM_DEBUG_FUNC_END(); + return ret; +} + + + +EXPORT_API int em_core_mail_save(int account_id, char *mailbox_name, emf_mail_t *mail_src, emf_meeting_request_t *meeting_req, int from_composer, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id[%d], mailbox_name[%p], mail_src[%p], from_composer[%d], err_code[%p]", account_id, mailbox_name, mail_src, from_composer, err_code); + + int ret = false, err = EMF_ERROR_NONE; + int attachment_id = 0, mail_id = 0, thread_id = -1, thread_item_count = 0, latest_mail_id_in_thread = -1; + int rule_len, rule_matched = -1, local_attachment_count = 0, local_inline_content_count = 0; + char *ext = NULL, *mailbox_name_spam = NULL, *mailbox_name_target = NULL; + char name_buf[MAX_PATH] = {0x00, }, html_body[MAX_PATH] = {0x00, }; + char datetime[DATETIME_LENGTH] = { 0, }; + emf_mail_tbl_t *mail_table_data = NULL; + emf_mailbox_tbl_t *mailbox_tbl_data = NULL; + emf_attachment_info_t *atch = NULL; + emf_mail_account_tbl_t *account_tbl_item = NULL; + emf_mail_rule_tbl_t *rule = NULL; + emf_mail_attachment_tbl_t attachment_tbl = { 0 }; + struct stat st_buf = { 0 }; + + /* Validating parameters */ + + if (!account_id || !mailbox_name || !mail_src || !mail_src->info || !mail_src->head) { + EM_DEBUG_EXCEPTION("EMF_ERROR_INVALID_PARAM"); + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + if (!em_storage_get_account_by_id(account_id, EMF_ACC_GET_OPT_DEFAULT | EMF_ACC_GET_OPT_OPTIONS, &account_tbl_item, true, &err)) { + EM_DEBUG_EXCEPTION("em_storage_get_account_by_id failed. account_id[%d] err[%d]", account_id, err); + err = EMF_ERROR_INVALID_ACCOUNT; + goto FINISH_OFF; + } + + if (from_composer) { + if (!mail_src->head->from) + mail_src->head->from = EM_SAFE_STRDUP(account_tbl_item->email_addr); + + /* check for email_address validation */ + if (!em_core_verify_email_address_of_mail_header(mail_src->head, false, &err)) { + EM_DEBUG_EXCEPTION("em_core_verify_email_address_of_mail_header failed [%d]", err); + goto FINISH_OFF; + } + + if (mail_src->info->extra_flags.report == EMF_MAIL_REPORT_MDN) { + /* check read-report mail */ + if(!mail_src->head->to) { /* A report mail should have 'to' address */ + EM_DEBUG_EXCEPTION("EMF_ERROR_INVALID_PARAM"); + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + /* Create report mail body */ + if (!em_core_mail_get_rfc822(mail_src, NULL, NULL, NULL, &err)) { + EM_DEBUG_EXCEPTION("em_core_mail_get_rfc822 failed [%d]", err); + goto FINISH_OFF; + } + } + + mailbox_name_target = EM_SAFE_STRDUP(mailbox_name); + } + else { /* For Spam handling */ + emf_option_t *opt = &account_tbl_item->options; + EM_DEBUG_LOG("block_address [%d], block_subject [%d]", opt->block_address, opt->block_subject); + + if (opt->block_address || opt->block_subject) { + int is_completed = false; + int type = 0; + + if (!opt->block_address) + type = EMF_FILTER_SUBJECT; + else if (!opt->block_subject) + type = EMF_FILTER_FROM; + + if (!em_storage_get_rule(ALL_ACCOUNT, type, 0, &rule_len, &is_completed, &rule, true, &err) || !rule) + EM_DEBUG_LOG("No proper rules. em_storage_get_rule returnes [%d]", err); + } + + if (rule) { + if (!em_storage_get_mailboxname_by_mailbox_type(account_id, EMF_MAILBOX_TYPE_SPAMBOX, &mailbox_name_spam, false, &err)) { + EM_DEBUG_EXCEPTION("em_storage_get_mailboxname_by_mailbox_type failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + mailbox_name_spam = NULL; + } + + if (mailbox_name_spam && !em_core_mail_check_rule(mail_src->head, rule, rule_len, &rule_matched, &err)) { + EM_DEBUG_EXCEPTION("em_core_mail_check_rule failed [%d]", err); + goto FINISH_OFF; + } + } + + if (rule_matched >= 0 && mailbox_name_spam) + mailbox_name_target = EM_SAFE_STRDUP(mailbox_name_spam); + else + mailbox_name_target = EM_SAFE_STRDUP(mailbox_name); + } + + if (!em_storage_get_mailbox_by_name(account_id, -1, mailbox_name_target, (emf_mailbox_tbl_t **)&mailbox_tbl_data, false, &err)) { + EM_DEBUG_EXCEPTION("em_storage_get_mailboxname_by_mailbox_type failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + + if (!em_storage_increase_mail_id(&mail_id, true, &err)) { + EM_DEBUG_EXCEPTION("em_storage_increase_mail_id failed [%d]", err); + goto FINISH_OFF; + } + + mail_table_data = (emf_mail_tbl_t *)em_core_malloc(sizeof(emf_mail_tbl_t)); + + if(!mail_table_data) { + EM_DEBUG_EXCEPTION("em_core_malloc failed"); + err = EMF_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + mail_table_data->account_id = account_id; + mail_table_data->mail_id = mail_id; + mail_table_data->mailbox_name = EM_SAFE_STRDUP(mailbox_name_target); + mail_table_data->mail_size = mail_src->info->rfc822_size; + mail_table_data->server_mail_status = !from_composer; + mail_table_data->server_mail_id = EM_SAFE_STRDUP(mail_src->info->sid); + mail_table_data->full_address_from = EM_SAFE_STRDUP(mail_src->head->from); + mail_table_data->full_address_to = EM_SAFE_STRDUP(mail_src->head->to); + mail_table_data->full_address_cc = EM_SAFE_STRDUP(mail_src->head->cc); + mail_table_data->full_address_bcc = EM_SAFE_STRDUP(mail_src->head->bcc); + mail_table_data->full_address_reply = EM_SAFE_STRDUP(mail_src->head->reply_to); + mail_table_data->full_address_return = EM_SAFE_STRDUP(mail_src->head->return_path); + mail_table_data->subject = EM_SAFE_STRDUP(mail_src->head->subject); + mail_table_data->body_download_status = mail_src->info->extra_flags.text_download_yn; + mail_table_data->mailbox_type = mailbox_tbl_data->mailbox_type; + + em_core_fill_address_information_of_mail_tbl(mail_table_data); + + EM_DEBUG_LOG("mail_table_data->mail_size [%d]", mail_table_data->mail_size); + if(mail_table_data->mail_size == 0) + mail_table_data->mail_size = em_core_get_mail_size(mail_src, &err); /* Getting file size before file moved. */ + + if (mail_src->body) { + if (from_composer || mail_table_data->body_download_status) { + if (!em_storage_create_dir(account_id, mail_id, 0, &err)) { + EM_DEBUG_EXCEPTION("em_storage_create_dir failed [%d]", err); + goto FINISH_OFF; + } + + if (mail_src->body->plain) { + EM_DEBUG_LOG("mail_src->body->plain [%s]", mail_src->body->plain); + if (!em_storage_get_save_name(account_id, mail_id, 0, mail_src->body->plain_charset ? mail_src->body->plain_charset : "UTF-8", name_buf, &err)) { + EM_DEBUG_EXCEPTION("em_storage_get_save_name failed [%d]", err); + goto FINISH_OFF; + } + + if (!em_storage_move_file(mail_src->body->plain, name_buf, from_composer, &err)) { + EM_DEBUG_EXCEPTION("em_storage_move_file failed [%d]", err); + goto FINISH_OFF; + } + if (mail_table_data->body_download_status == 0) + mail_table_data->body_download_status = 1; + mail_table_data->file_path_plain = EM_SAFE_STRDUP(name_buf); + EM_SAFE_FREE(mail_src->body->plain); + mail_src->body->plain = EM_SAFE_STRDUP(name_buf); + } + + if (mail_src->body->html) { + EM_DEBUG_LOG("mail_src->body->html [%s]", mail_src->body->html); + if (mail_src->body->plain_charset != NULL && mail_src->body->plain_charset[0] != NULL_CHAR) { + memcpy(html_body, mail_src->body->plain_charset, strlen(mail_src->body->plain_charset)); + strcat(html_body, ".htm"); + } + else { + memcpy(html_body, "UTF-8.htm", strlen("UTF-8.htm")); + } + + if (!em_storage_get_save_name(account_id, mail_id, 0, html_body, name_buf, &err)) { + EM_DEBUG_EXCEPTION("em_storage_get_save_name failed [%d]", err); + goto FINISH_OFF; + } + + if (!em_storage_move_file(mail_src->body->html, name_buf, from_composer, &err)) { + EM_DEBUG_EXCEPTION("em_storage_move_file failed [%d]", err); + goto FINISH_OFF; + } + + if (mail_table_data->body_download_status == EMF_BODY_DOWNLOAD_STATUS_NONE) + mail_table_data->body_download_status = EMF_BODY_DOWNLOAD_STATUS_FULLY_DOWNLOADED; + + mail_table_data->file_path_html = EM_SAFE_STRDUP(name_buf); + EM_SAFE_FREE(mail_src->body->html); + mail_src->body->html = EM_SAFE_STRDUP(name_buf); + } + } + } + + + if (!mail_src->head->datetime.year && !mail_src->head->datetime.month && !mail_src->head->datetime.day) { + /* time isn't set */ + if(!em_core_set_current_time_to_mail_header(mail_src->head, &err)) { + EM_DEBUG_EXCEPTION("em_core_set_current_time_to_mail_header failed [%d]", err); + goto FINISH_OFF; + } + } + + SNPRINTF(datetime, sizeof(datetime), "%04d%02d%02d%02d%02d%02d", + mail_src->head->datetime.year, mail_src->head->datetime.month, mail_src->head->datetime.day, mail_src->head->datetime.hour, mail_src->head->datetime.minute, mail_src->head->datetime.second); + + mail_table_data->datetime = EM_SAFE_STRDUP(datetime); + mail_table_data->message_id = EM_SAFE_STRDUP(mail_src->head->mid); + + if (mail_src->info) { + mail_src->info->flags.draft = 1; + if(!em_convert_mail_flag_to_mail_tbl(&(mail_src->info->flags), mail_table_data, &err)) { + EM_DEBUG_EXCEPTION("em_convert_mail_flag_to_mail_tbl failed [%d]", err); + goto FINISH_OFF; + } + mail_table_data->priority = mail_src->info->extra_flags.priority; + mail_table_data->lock_status = mail_src->info->extra_flags.lock; + mail_table_data->report_status = mail_src->info->extra_flags.report; + } + mail_table_data->save_status = EMF_MAIL_STATUS_SAVED; + + mail_id = mail_table_data->mail_id; + mail_src->info->uid = mail_id; + + mail_table_data->meeting_request_status = mail_src->info->is_meeting_request; + + if(mail_src->info->thread_id == 0) { + if (em_storage_get_thread_id_of_thread_mails(mail_table_data, &thread_id, &latest_mail_id_in_thread, &thread_item_count) != EMF_ERROR_NONE) + EM_DEBUG_LOG(" em_storage_get_thread_id_of_thread_mails is failed"); + + if (thread_id == -1) { + mail_table_data->thread_id = mail_id; + mail_table_data->thread_item_count = thread_item_count = 1; + } + else { + mail_table_data->thread_id = thread_id; + thread_item_count++; + } + } + else { + mail_table_data->thread_id = mail_src->info->thread_id; + thread_item_count = 2; + } + + /* Getting attachment count */ + if (mail_src->body) + atch = mail_src->body->attachment; + while (atch) { + if (atch->inline_content) + local_inline_content_count++; + local_attachment_count++; + atch = atch->next; + } + + mail_table_data->inline_content_count = local_inline_content_count; + mail_table_data->attachment_count = local_attachment_count; + + EM_DEBUG_LOG("inline_content_count [%d]", local_inline_content_count); + EM_DEBUG_LOG("attachment_count [%d]", local_attachment_count); + + EM_DEBUG_LOG("preview_text[%p]", mail_table_data->preview_text); + if (mail_table_data->preview_text == NULL) { + if ( (err = em_core_get_preview_text_from_file(mail_table_data->file_path_plain, mail_table_data->file_path_html, MAX_PREVIEW_TEXT_LENGTH, &(mail_table_data->preview_text))) != EMF_ERROR_NONE) { + EM_DEBUG_EXCEPTION("em_core_get_preview_text_from_file failed[%d]", err); + goto FINISH_OFF; + } + } + + em_storage_begin_transaction(NULL, NULL, NULL); + + /* insert mail to mail table */ + if (!em_storage_add_mail(mail_table_data, 0, false, &err)) { + EM_DEBUG_EXCEPTION("em_storage_add_mail failed [%d]", err); + /* ROLLBACK TRANSACTION; */ + em_storage_rollback_transaction(NULL, NULL, NULL); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + + EM_DEBUG_LOG("thread_item_count [%d]", thread_item_count); + if (thread_item_count > 1) { + if (!em_storage_update_latest_thread_mail(mail_table_data->account_id, mail_table_data->thread_id, 0, 0, false, &err)) { + EM_DEBUG_EXCEPTION("em_storage_update_latest_thread_mail failed [%d]", err); + em_storage_rollback_transaction(NULL, NULL, NULL); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + } + + /* Insert attachment information to DB */ + if (mail_src->body) + atch = mail_src->body->attachment; + EM_DEBUG_LOG("atch [%p]", atch); + while (atch) { + if (from_composer && stat(atch->savename, &st_buf) < 0) { + atch = atch->next; + continue; + } + + if (!atch->inline_content) { + if (!em_storage_get_new_attachment_no(&attachment_id, &err)) { + EM_DEBUG_EXCEPTION("em_storage_get_new_attachment_no failed [%d]", err); + em_storage_rollback_transaction(NULL, NULL, NULL); + goto FINISH_OFF; + } + } + + if (!em_storage_create_dir(account_id, mail_id, atch->inline_content ? 0 : attachment_id, &err)) { + EM_DEBUG_EXCEPTION("em_storage_create_dir failed [%d]", err); + em_storage_rollback_transaction(NULL, NULL, NULL); + goto FINISH_OFF; + } + + if (!em_storage_get_save_name(account_id, mail_id, atch->inline_content ? 0 : attachment_id, atch->name, name_buf, &err)) { + EM_DEBUG_EXCEPTION("em_storage_get_save_name failed [%d]", err); + em_storage_rollback_transaction(NULL, NULL, NULL); + goto FINISH_OFF; + } + + if (from_composer || atch->downloaded) { + if (!em_storage_copy_file(atch->savename, name_buf, from_composer, &err)) { + EM_DEBUG_EXCEPTION("em_storage_copy_file failed [%d]", err); + em_storage_rollback_transaction(NULL, NULL, NULL); + goto FINISH_OFF; + } + + if ((ext = strrchr(atch->name, '.'))) { + if (!strncmp(ext, ".vcs", strlen(".vcs"))) + remove(atch->savename); + else if (!strncmp(ext, ".vcf", strlen(".vcf"))) + remove(atch->savename); + else if (!strncmp(ext, ".vnt", strlen(".vnt"))) + remove(atch->savename); + } + } + + memset(&attachment_tbl, 0x00, sizeof(emf_mail_attachment_tbl_t)); + + attachment_tbl.mail_id = mail_id; + attachment_tbl.account_id = account_id; + attachment_tbl.mailbox_name = mailbox_name_target; + attachment_tbl.file_yn = atch->downloaded; + attachment_tbl.flag2 = mail_src->body->attachment->drm; + attachment_tbl.attachment_name = atch->name; + attachment_tbl.attachment_path = name_buf; + attachment_tbl.flag3 = atch->inline_content; + if (from_composer) + attachment_tbl.attachment_size = st_buf.st_size; + else + attachment_tbl.attachment_size = atch->size; + + if (!em_storage_add_attachment(&attachment_tbl, 0, false, &err)) { + EM_DEBUG_EXCEPTION("em_storage_add_attachment failed [%d]", err); + em_storage_rollback_transaction(NULL, NULL, NULL); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + atch->attachment_id = attachment_tbl.attachment_id; + atch = atch->next; + } + + /* Insert Meeting request to DB */ + if (mail_src->info->is_meeting_request == EMF_MAIL_TYPE_MEETING_REQUEST + || mail_src->info->is_meeting_request == EMF_MAIL_TYPE_MEETING_RESPONSE + || mail_src->info->is_meeting_request == EMF_MAIL_TYPE_MEETING_ORIGINATINGREQUEST) { + EM_DEBUG_LOG("This mail has the meeting request"); + meeting_req->mail_id = mail_id; + if (!em_storage_add_meeting_request(account_id, mailbox_name_target, meeting_req, false, &err)) { + EM_DEBUG_EXCEPTION("em_storage_add_meeting_request failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + } + + em_storage_commit_transaction(NULL, NULL, NULL); + + if (!em_storage_notify_storage_event(NOTI_MAIL_ADD, account_id, mail_id, mailbox_name_target, mail_table_data->thread_id)) + EM_DEBUG_LOG("em_storage_notify_storage_event [NOTI_MAIL_ADD] failed."); + + if (account_tbl_item->receiving_server_type != EMF_SERVER_TYPE_ACTIVE_SYNC) { + if (!em_core_mailbox_remove_overflowed_mails(mailbox_tbl_data, &err)) { + if (err == EM_STORAGE_ERROR_MAIL_NOT_FOUND || err == EMF_ERROR_NOT_SUPPORTED) + err = EMF_ERROR_NONE; + else + EM_DEBUG_LOG("em_core_mailbox_remove_overflowed_mails failed [%d]", err); + } + } + + if ( !from_composer && (mail_src->info->flags.seen == 0) + && mail_table_data->mailbox_type != EMF_MAILBOX_TYPE_TRASH + && mail_table_data->mailbox_type != EMF_MAILBOX_TYPE_SPAMBOX) { /* 0x01 fSeen */ + if (!em_storage_update_sync_status_of_account(account_id, SET_TYPE_SET, SYNC_STATUS_SYNCING | SYNC_STATUS_HAVE_NEW_MAILS, true, &err)) + EM_DEBUG_LOG("em_storage_update_sync_status_of_account failed [%d]", err); + em_core_add_notification_for_unread_mail_by_mail_header(account_id, mail_id, mail_src->head); + em_core_check_unread_mail(); + } + + ret = true; + +FINISH_OFF: + if (mail_table_data) + em_storage_free_mail(&mail_table_data, 1, NULL); + + if (account_tbl_item) + em_storage_free_account(&account_tbl_item, 1, NULL); + + if (mailbox_tbl_data) + em_storage_free_mailbox(&mailbox_tbl_data, 1, NULL); + + EM_SAFE_FREE(mailbox_name_spam); + EM_SAFE_FREE(mailbox_name_target); + + if (err_code) + *err_code = err; + + EM_DEBUG_FUNC_END(); + return ret; +} + + +EXPORT_API int em_core_add_mail(emf_mail_data_t *input_mail_data, emf_attachment_data_t *input_attachment_data_list, int input_attachment_count, emf_meeting_request_t *input_meeting_request, int input_sync_server) +{ + EM_DEBUG_FUNC_BEGIN("input_mail_data[%p], input_attachment_data_list [%p], input_attachment_count [%d], input_meeting_request [%p], input_sync_server[%d]", input_mail_data, input_attachment_data_list, input_attachment_count, input_meeting_request, input_sync_server); + + int err = EMF_ERROR_NONE; + int attachment_id = 0, thread_id = -1, thread_item_count = 0, latest_mail_id_in_thread = -1; + int i = 0, rule_len, rule_matched = -1, local_attachment_count = 0, local_inline_content_count = 0; + char *ext = NULL, *mailbox_name_spam = NULL, *mailbox_name_target = NULL; + char name_buf[MAX_PATH] = {0x00, }, html_body[MAX_PATH] = {0x00, }; + emf_mail_tbl_t *converted_mail_tbl = NULL; + emf_mailbox_tbl_t *mailbox_tbl = NULL; + emf_mail_attachment_tbl_t attachment_tbl = { 0 }; + emf_mail_account_tbl_t *account_tbl_item = NULL; + emf_mail_rule_tbl_t *rule = NULL; + struct stat st_buf = { 0 }; + + /* Validating parameters */ + + if (!input_mail_data || !(input_mail_data->account_id) || !(input_mail_data->mailbox_name)) { + EM_DEBUG_EXCEPTION("EMF_ERROR_INVALID_PARAM"); + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + if (!em_storage_get_account_by_id(input_mail_data->account_id, EMF_ACC_GET_OPT_DEFAULT | EMF_ACC_GET_OPT_OPTIONS, &account_tbl_item, true, &err)) { + EM_DEBUG_EXCEPTION("em_storage_get_account_by_id failed. account_id[%d] err[%d]", input_mail_data->account_id, err); + err = EMF_ERROR_INVALID_ACCOUNT; + goto FINISH_OFF; + } + + if(input_sync_server) { + if (input_mail_data->file_path_plain) { + if (stat(input_mail_data->file_path_plain, &st_buf) < 0) { + EM_DEBUG_EXCEPTION("input_mail_data->file_path_plain, stat(\"%s\") failed...", input_mail_data->file_path_plain); + err = EMF_ERROR_INVALID_MAIL; + goto FINISH_OFF; + } + } + + if (input_mail_data->file_path_html) { + if (stat(input_mail_data->file_path_html, &st_buf) < 0) { + EM_DEBUG_EXCEPTION("input_mail_data->file_path_html, stat(\"%s\") failed...", input_mail_data->file_path_html); + err = EMF_ERROR_INVALID_MAIL; + goto FINISH_OFF; + } + } + + if (input_attachment_count && input_attachment_data_list) { + for (i = 0; i < input_attachment_count; i++) { + if (input_attachment_data_list[i].save_status) { + if (!input_attachment_data_list[i].attachment_path || stat(input_attachment_data_list[i].attachment_path, &st_buf) < 0) { + EM_DEBUG_EXCEPTION("stat(\"%s\") failed...", input_attachment_data_list[i].attachment_path); + err = EMF_ERROR_INVALID_ATTACHMENT; + goto FINISH_OFF; + } + } + } + } + } + + if (input_sync_server) { + if (!input_mail_data->full_address_from) + input_mail_data->full_address_from = EM_SAFE_STRDUP(account_tbl_item->email_addr); + + /* check for email_address validation */ + if (!em_core_verify_email_address_of_mail_data(input_mail_data, false, &err)) { + EM_DEBUG_EXCEPTION("em_core_verify_email_address_of_mail_data failed [%d]", err); + goto FINISH_OFF; + } + + if (input_mail_data->report_status == EMF_MAIL_REPORT_MDN) { + /* check read-report mail */ + if(!input_mail_data->full_address_to) { /* A report mail should have 'to' address */ + EM_DEBUG_EXCEPTION("EMF_ERROR_INVALID_PARAM"); + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + /* Create report mail body */ + /* + if (!em_core_mail_get_rfc822(mail_src, NULL, NULL, NULL, &err)) { + EM_DEBUG_EXCEPTION("em_core_mail_get_rfc822 failed [%d]", err); + goto FINISH_OFF; + } + */ + } + + mailbox_name_target = EM_SAFE_STRDUP(input_mail_data->mailbox_name); + } + else { /* For Spam handling */ + emf_option_t *opt = &account_tbl_item->options; + EM_DEBUG_LOG("block_address [%d], block_subject [%d]", opt->block_address, opt->block_subject); + + if (opt->block_address || opt->block_subject) { + int is_completed = false; + int type = 0; + + if (!opt->block_address) + type = EMF_FILTER_SUBJECT; + else if (!opt->block_subject) + type = EMF_FILTER_FROM; + + if (!em_storage_get_rule(ALL_ACCOUNT, type, 0, &rule_len, &is_completed, &rule, true, &err) || !rule) + EM_DEBUG_LOG("No proper rules. em_storage_get_rule returns [%d]", err); + } + + if (rule) { + if (!em_storage_get_mailboxname_by_mailbox_type(input_mail_data->account_id, EMF_MAILBOX_TYPE_SPAMBOX, &mailbox_name_spam, false, &err)) { + EM_DEBUG_EXCEPTION("em_storage_get_mailboxname_by_mailbox_type failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + mailbox_name_spam = NULL; + } + + /* + if (mailbox_name_spam && !em_core_mail_check_rule(mail_src->head, rule, rule_len, &rule_matched, &err)) { + EM_DEBUG_EXCEPTION("em_core_mail_check_rule failed [%d]", err); + goto FINISH_OFF; + } + */ + } + + if (rule_matched >= 0 && mailbox_name_spam) + mailbox_name_target = EM_SAFE_STRDUP(mailbox_name_spam); + else + mailbox_name_target = EM_SAFE_STRDUP(input_mail_data->mailbox_name); + } + + if (!em_storage_get_mailbox_by_name(input_mail_data->account_id, -1, mailbox_name_target, (emf_mailbox_tbl_t **)&mailbox_tbl, false, &err)) { + EM_DEBUG_EXCEPTION("em_storage_get_mailboxname_by_mailbox_type failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + + if (!em_storage_increase_mail_id(&input_mail_data->mail_id, true, &err)) { + EM_DEBUG_EXCEPTION("em_storage_increase_mail_id failed [%d]", err); + goto FINISH_OFF; + } + + EM_DEBUG_LOG("input_mail_data->mail_size [%d]", input_mail_data->mail_size); + + if(input_mail_data->mail_size == 0) + em_core_calc_mail_size(input_mail_data, input_attachment_data_list, input_attachment_count, &(input_mail_data->mail_size)); /* Getting file size before file moved. */ + + if (input_sync_server || input_mail_data->body_download_status) { + if (!em_storage_create_dir(input_mail_data->account_id, input_mail_data->mail_id, 0, &err)) { + EM_DEBUG_EXCEPTION("em_storage_create_dir failed [%d]", err); + goto FINISH_OFF; + } + + if (input_mail_data->file_path_plain) { + EM_DEBUG_LOG("input_mail_data->file_path_plain [%s]", input_mail_data->file_path_plain); + /* if (!em_storage_get_save_name(account_id, mail_id, 0, input_mail_data->body->plain_charset ? input_mail_data->body->plain_charset : "UTF-8", name_buf, &err)) {*/ + if (!em_storage_get_save_name(input_mail_data->account_id, input_mail_data->mail_id, 0, "UTF-8", name_buf, &err)) { + EM_DEBUG_EXCEPTION("em_storage_get_save_name failed [%d]", err); + goto FINISH_OFF; + } + + if (!em_storage_move_file(input_mail_data->file_path_plain, name_buf, input_sync_server, &err)) { + EM_DEBUG_EXCEPTION("em_storage_move_file failed [%d]", err); + goto FINISH_OFF; + } + if (input_mail_data->body_download_status == EMF_BODY_DOWNLOAD_STATUS_NONE) + input_mail_data->body_download_status = EMF_BODY_DOWNLOAD_STATUS_FULLY_DOWNLOADED; + + EM_SAFE_FREE(input_mail_data->file_path_plain); + input_mail_data->file_path_plain = EM_SAFE_STRDUP(name_buf); + } + + if (input_mail_data->file_path_html) { + EM_DEBUG_LOG("input_mail_data->file_path_html [%s]", input_mail_data->file_path_html); + memcpy(html_body, "UTF-8.htm", strlen("UTF-8.htm")); + + if (!em_storage_get_save_name(input_mail_data->account_id, input_mail_data->mail_id, 0, html_body, name_buf, &err)) { + EM_DEBUG_EXCEPTION("em_storage_get_save_name failed [%d]", err); + goto FINISH_OFF; + } + + if (!em_storage_move_file(input_mail_data->file_path_html, name_buf, input_sync_server, &err)) { + EM_DEBUG_EXCEPTION("em_storage_move_file failed [%d]", err); + goto FINISH_OFF; + } + + if (input_mail_data->body_download_status == EMF_BODY_DOWNLOAD_STATUS_NONE) + input_mail_data->body_download_status = EMF_BODY_DOWNLOAD_STATUS_FULLY_DOWNLOADED; + + EM_SAFE_FREE(input_mail_data->file_path_html); + input_mail_data->file_path_html = EM_SAFE_STRDUP(name_buf); + } + } + + + if (!input_mail_data->datetime) { + /* time isn't set */ + input_mail_data->datetime = em_core_get_current_time_string(&err); + if(!input_mail_data->datetime) { + EM_DEBUG_EXCEPTION("em_core_get_current_time_string failed [%d]", err); + goto FINISH_OFF; + } + } + + EM_SAFE_FREE(input_mail_data->mailbox_name); + + input_mail_data->mailbox_name = EM_SAFE_STRDUP(mailbox_name_target); + input_mail_data->mailbox_type = mailbox_tbl->mailbox_type; + input_mail_data->server_mail_status = !input_sync_server; + input_mail_data->save_status = EMF_MAIL_STATUS_SAVED; + + /* Getting attachment count */ + for (i = 0; i < input_attachment_count; i++) { + if (input_attachment_data_list[i].inline_content_status== 1) + local_inline_content_count++; + local_attachment_count++; + } + + input_mail_data->inline_content_count = local_inline_content_count; + input_mail_data->attachment_count = local_attachment_count; + + EM_DEBUG_LOG("inline_content_count [%d]", local_inline_content_count); + EM_DEBUG_LOG("input_attachment_count [%d]", local_attachment_count); + + EM_DEBUG_LOG("preview_text[%p]", input_mail_data->preview_text); + if (input_mail_data->preview_text == NULL) { + if ( (err = em_core_get_preview_text_from_file(input_mail_data->file_path_plain, input_mail_data->file_path_html, MAX_PREVIEW_TEXT_LENGTH, &(input_mail_data->preview_text))) != EMF_ERROR_NONE) { + EM_DEBUG_EXCEPTION("em_core_get_preview_text_from_file failed[%d]", err); + goto FINISH_OFF; + } + } + + if (!em_convert_mail_data_to_mail_tbl(input_mail_data, 1, &converted_mail_tbl, &err)) { + EM_DEBUG_EXCEPTION("em_convert_mail_data_to_mail_tbl failed [%d]", err); + goto FINISH_OFF; + } + + /* Fill address information */ + em_core_fill_address_information_of_mail_tbl(converted_mail_tbl); + + /* Fill thread id */ + if(input_mail_data->thread_id == 0) { + if (em_storage_get_thread_id_of_thread_mails(converted_mail_tbl, &thread_id, &latest_mail_id_in_thread, &thread_item_count) != EMF_ERROR_NONE) + EM_DEBUG_LOG(" em_storage_get_thread_id_of_thread_mails is failed"); + + if (thread_id == -1) { + converted_mail_tbl->thread_id = input_mail_data->mail_id; + converted_mail_tbl->thread_item_count = thread_item_count = 1; + } + else { + converted_mail_tbl->thread_id = thread_id; + thread_item_count++; + } + } + else { + thread_item_count = 2; + } + + em_storage_begin_transaction(NULL, NULL, NULL); + + /* insert mail to mail table */ + if (!em_storage_add_mail(converted_mail_tbl, 0, false, &err)) { + EM_DEBUG_EXCEPTION("em_storage_add_mail failed [%d]", err); + /* ROLLBACK TRANSACTION; */ + em_storage_rollback_transaction(NULL, NULL, NULL); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + + /* Update thread information */ + EM_DEBUG_LOG("thread_item_count [%d]", thread_item_count); + + if (thread_item_count > 1) { + if (!em_storage_update_latest_thread_mail(input_mail_data->account_id, converted_mail_tbl->thread_id, 0, 0, false, &err)) { + EM_DEBUG_EXCEPTION("em_storage_update_latest_thread_mail failed [%d]", err); + em_storage_rollback_transaction(NULL, NULL, NULL); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + } + + /* Insert attachment information to DB */ + + for (i = 0; i < input_attachment_count; i++) { + if (input_attachment_data_list[i].attachment_size == 0) { + /* set attachment size */ + if(input_attachment_data_list[i].attachment_path && stat(input_attachment_data_list[i].attachment_path, &st_buf) < 0) + input_attachment_data_list[i].attachment_size = st_buf.st_size; + } + + if (!input_attachment_data_list[i].inline_content_status) { + if (!em_storage_get_new_attachment_no(&attachment_id, &err)) { + EM_DEBUG_EXCEPTION("em_storage_get_new_attachment_no failed [%d]", err); + em_storage_rollback_transaction(NULL, NULL, NULL); + goto FINISH_OFF; + } + } + + if (!em_storage_create_dir(input_mail_data->account_id, input_mail_data->mail_id, input_attachment_data_list[i].inline_content_status ? 0 : attachment_id, &err)) { + EM_DEBUG_EXCEPTION("em_storage_create_dir failed [%d]", err); + em_storage_rollback_transaction(NULL, NULL, NULL); + goto FINISH_OFF; + } + + if (!em_storage_get_save_name(input_mail_data->account_id, input_mail_data->mail_id, input_attachment_data_list[i].inline_content_status ? 0 : attachment_id, input_attachment_data_list[i].attachment_name, name_buf, &err)) { + EM_DEBUG_EXCEPTION("em_storage_get_save_name failed [%d]", err); + em_storage_rollback_transaction(NULL, NULL, NULL); + goto FINISH_OFF; + } + + if (input_sync_server || input_attachment_data_list[i].save_status) { + if (!em_storage_copy_file(input_attachment_data_list[i].attachment_path, name_buf, input_sync_server, &err)) { + EM_DEBUG_EXCEPTION("em_storage_copy_file failed [%d]", err); + em_storage_rollback_transaction(NULL, NULL, NULL); + goto FINISH_OFF; + } + + if ((ext = strrchr(input_attachment_data_list[i].attachment_name, '.'))) { + if (!strncmp(ext, ".vcs", strlen(".vcs"))) + remove(input_attachment_data_list[i].attachment_path); + else if (!strncmp(ext, ".vcf", strlen(".vcf"))) + remove(input_attachment_data_list[i].attachment_path); + else if (!strncmp(ext, ".vnt", strlen(".vnt"))) + remove(input_attachment_data_list[i].attachment_path); + } + } + + memset(&attachment_tbl, 0, sizeof(emf_mail_attachment_tbl_t)); + attachment_tbl.attachment_name = input_attachment_data_list[i].attachment_name; + attachment_tbl.attachment_path = name_buf; + attachment_tbl.attachment_size = input_attachment_data_list[i].attachment_size; + attachment_tbl.mail_id = input_mail_data->mail_id; + attachment_tbl.account_id = input_mail_data->account_id; + attachment_tbl.mailbox_name = input_mail_data->mailbox_name; + attachment_tbl.file_yn = input_attachment_data_list[i].save_status; + attachment_tbl.flag2 = input_attachment_data_list[i].drm_status; + attachment_tbl.flag3 = input_attachment_data_list[i].inline_content_status; + + if (!em_storage_add_attachment(&attachment_tbl, 0, false, &err)) { + EM_DEBUG_EXCEPTION("em_storage_add_attachment failed [%d]", err); + em_storage_rollback_transaction(NULL, NULL, NULL); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + input_attachment_data_list[i].attachment_id = attachment_tbl.attachment_id; + } + + /* Insert Meeting request to DB */ + if (input_mail_data->meeting_request_status == EMF_MAIL_TYPE_MEETING_REQUEST + || input_mail_data->meeting_request_status == EMF_MAIL_TYPE_MEETING_RESPONSE + || input_mail_data->meeting_request_status == EMF_MAIL_TYPE_MEETING_ORIGINATINGREQUEST) { + EM_DEBUG_LOG("This mail has the meeting request"); + input_meeting_request->mail_id = input_mail_data->mail_id; + if (!em_storage_add_meeting_request(input_mail_data->account_id, mailbox_name_target, input_meeting_request, false, &err)) { + EM_DEBUG_EXCEPTION("em_storage_add_meeting_request failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + } + + em_storage_commit_transaction(NULL, NULL, NULL); + + if (!em_storage_notify_storage_event(NOTI_MAIL_ADD, converted_mail_tbl->account_id, converted_mail_tbl->mail_id, mailbox_name_target, converted_mail_tbl->thread_id)) + EM_DEBUG_LOG("em_storage_notify_storage_event [NOTI_MAIL_ADD] failed."); + + if (account_tbl_item->receiving_server_type != EMF_SERVER_TYPE_ACTIVE_SYNC) { + if (!em_core_mailbox_remove_overflowed_mails(mailbox_tbl, &err)) { + if (err == EM_STORAGE_ERROR_MAIL_NOT_FOUND || err == EMF_ERROR_NOT_SUPPORTED) + err = EMF_ERROR_NONE; + else + EM_DEBUG_LOG("em_core_mailbox_remove_overflowed_mails failed [%d]", err); + } + } + + if ( !input_sync_server && (input_mail_data->flags_seen_field == 0) + && input_mail_data->mailbox_type != EMF_MAILBOX_TYPE_TRASH + && input_mail_data->mailbox_type != EMF_MAILBOX_TYPE_SPAMBOX) { + if (!em_storage_update_sync_status_of_account(input_mail_data->account_id, SET_TYPE_SET, SYNC_STATUS_SYNCING | SYNC_STATUS_HAVE_NEW_MAILS, true, &err)) + EM_DEBUG_LOG("em_storage_update_sync_status_of_account failed [%d]", err); + em_core_add_notification_for_unread_mail(input_mail_data); + em_core_check_unread_mail(); + } + +FINISH_OFF: + if (account_tbl_item) + em_storage_free_account(&account_tbl_item, 1, NULL); + + if (mailbox_tbl) + em_storage_free_mailbox(&mailbox_tbl, 1, NULL); + + if (converted_mail_tbl) + em_storage_free_mail(&converted_mail_tbl, 1, NULL); + + EM_SAFE_FREE(mailbox_name_spam); + EM_SAFE_FREE(mailbox_name_target); + + EM_DEBUG_FUNC_END(); + return err; +} + +EXPORT_API int +em_core_mail_add_meeting_request(int account_id, char *mailbox_name, emf_meeting_request_t *meeting_req, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id[%d], mailbox_name[%s], meeting_req[%p], err_code[%p]", account_id, mailbox_name, meeting_req, err_code); + int ret = false; + int err = EMF_ERROR_NONE; + + if (!meeting_req || meeting_req->mail_id <= 0) { + if (meeting_req) + EM_DEBUG_EXCEPTION("mail_id[%d]", meeting_req->mail_id); + + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + if (!em_storage_add_meeting_request(account_id, mailbox_name, meeting_req, 1, &err)) { + EM_DEBUG_EXCEPTION(" em_storage_add_meeting_request failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + + ret = true; + +FINISH_OFF: + + if (err_code) + *err_code = err; + + EM_DEBUG_FUNC_END(); + return ret; +} + +/* send a message (not saved) */ +EXPORT_API int em_core_mail_send(int account_id, char *input_mailbox_name, int mail_id, emf_option_t *sending_option, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id[%d], input_mailbox_name[%s], mail_id[%d], sending_option[%p], err_code[%p]", account_id, input_mailbox_name, mail_id, sending_option, err_code); + EM_PROFILE_BEGIN(profile_em_core_mail_send); + int ret = false; + int err = EMF_ERROR_NONE, err2 = EMF_ERROR_NONE; + int status = EMF_SEND_FAIL; + + SENDSTREAM *stream = NULL; + ENVELOPE *envelope = NULL; + sslstart_t stls = NULL; + emf_mail_t *mail = NULL; + emf_account_t *ref_account = NULL; + emf_option_t *opt = NULL; + emf_mailbox_t dest_mbox = {0}; + void *tmp_stream = NULL; + char *fpath = NULL; + int sent_box = 0; + char *mailbox_name = NULL; + + if (!account_id || !mail_id) { + EM_DEBUG_EXCEPTION("EMF_ERROR_INVALID_PARAM"); + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + if (!(ref_account = em_core_get_account_reference(account_id))) { + EM_DEBUG_EXCEPTION("em_core_get_account_reference failed [%d]", account_id); + err = EMF_ERROR_INVALID_ACCOUNT; + goto FINISH_OFF; + } + + /* get mail to send */ + if (!em_core_mail_get_mail(mail_id, &mail, &err)) { + EM_DEBUG_EXCEPTION("em_core_mail_get_mail failed [%d]", err); + goto FINISH_OFF; + } + + if (!em_core_check_send_mail_thread_status()) { + EM_DEBUG_EXCEPTION("em_core_check_send_mail_thread_status failed..."); + err = EMF_ERROR_CANCELLED; + goto FINISH_OFF; + } + + if ((!mail->head->to) && (!mail->head->cc) && (!mail->head->bcc)) { + err = EMF_ERROR_NO_RECIPIENT; + EM_DEBUG_EXCEPTION("No Recipient information [%d]", err); + goto FINISH_OFF; + } + else { + if (!em_core_verify_email_address_of_mail_header(mail->head, false, &err)) { + err = EMF_ERROR_INVALID_ADDRESS; + EM_DEBUG_EXCEPTION("em_core_verify_email_address_of_mail_header failed [%d]", err); + goto FINISH_OFF; + } + } + + if (mail->info) + mail->info->account_id = account_id; + + if (!em_core_check_send_mail_thread_status()) { + EM_DEBUG_EXCEPTION("em_core_check_send_mail_thread_status failed..."); + err = EMF_ERROR_CANCELLED; + goto FINISH_OFF; + } + + if (sending_option != NULL) + opt = sending_option; + else + opt = em_core_get_option(&err); + + + /*Update status flag to DB*/ + + /* get rfc822 data */ + if (!em_core_mail_get_rfc822(mail, &envelope, &fpath, opt, &err)) { + EM_DEBUG_EXCEPTION("em_core_mail_get_rfc822 failed [%d]", err); + goto FINISH_OFF; + } + + if (!envelope || (!envelope->to && !envelope->cc && !envelope->bcc)) { + EM_DEBUG_EXCEPTION(" no recipients found..."); + + err = EMF_ERROR_NO_RECIPIENT; + goto FINISH_OFF; + } + + /* if there is no security option, unset security. */ + if (!ref_account->sending_security) { + stls = (sslstart_t)mail_parameters(NULL, GET_SSLSTART, NULL); + mail_parameters(NULL, SET_SSLSTART, NULL); + } + + if (!em_core_check_send_mail_thread_status()) { + EM_DEBUG_EXCEPTION("em_core_check_send_mail_thread_status failed..."); + err = EMF_ERROR_CANCELLED; + goto FINISH_OFF; + } + + if (ref_account->pop_before_smtp != FALSE) { + if (!em_core_mailbox_open(account_id, NULL, (void **)&tmp_stream, &err)) { + EM_DEBUG_EXCEPTION(" POP before SMTP Authentication failed [%d]", err); + status = EMF_LIST_CONNECTION_FAIL; + if (err == EMF_ERROR_CONNECTION_BROKEN) + err = EMF_ERROR_CANCELLED; + goto FINISH_OFF; + } + } + + + if (!em_storage_get_mailboxname_by_mailbox_type(account_id, EMF_MAILBOX_TYPE_DRAFT, &mailbox_name, false, &err)) { + EM_DEBUG_EXCEPTION(" em_storage_get_mailboxname_by_mailbox_type failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + + if (!em_core_mailbox_open(account_id, (char *)ENCODED_PATH_SMTP, (void **)&tmp_stream, &err)) { + EM_DEBUG_EXCEPTION(" em_core_mailbox_open failed [%d]", err); + + if (err == EMF_ERROR_CONNECTION_BROKEN) + err = EMF_ERROR_CANCELLED; + + status = EMF_SEND_CONNECTION_FAIL; + goto FINISH_OFF; + } + + stream = (SENDSTREAM *)tmp_stream; + + if (!em_core_check_send_mail_thread_status()) { + EM_DEBUG_EXCEPTION(" em_core_check_send_mail_thread_status failed..."); + err = EMF_ERROR_CANCELLED; + goto FINISH_OFF; + } + + /* set request of delivery status. */ + if (opt->req_delivery_receipt == EMF_OPTION_REQ_DELIVERY_RECEIPT_ON) { + stream->protocol.esmtp.dsn.want = 1; + stream->protocol.esmtp.dsn.full = 0; + stream->protocol.esmtp.dsn.notify.failure = 1; + stream->protocol.esmtp.dsn.notify.success = 1; + EM_DEBUG_LOG("opt->req_delivery_receipt == EMF_OPTION_REQ_DELIVERY_RECEIPT_ON"); + } + + mail->info->extra_flags.status = EMF_MAIL_STATUS_SENDING; + + /*Update status flag to DB*/ + if (!em_core_mail_modify_extra_flag(mail_id, mail->info->extra_flags, &err)) + EM_DEBUG_EXCEPTION("Failed to modify extra flag [%d]", err); + + /* send mail to server. */ + if (!em_core_mail_send_smtp(stream, envelope, fpath, account_id, mail_id, &err)) { + EM_DEBUG_EXCEPTION(" em_core_mail_send_smtp failed [%d]", err); + + +#ifndef __FEATURE_MOVE_TO_OUTBOX_FIRST__ + EM_SAFE_FREE(mailbox_name); + if (!em_storage_get_mailboxname_by_mailbox_type(account_id, EMF_MAILBOX_TYPE_OUTBOX, &mailbox_name, false, &err)) { + EM_DEBUG_EXCEPTION(" em_storage_get_mailboxname_by_mailbox_type failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + dest_mbox.name = mailbox_name; + dest_mbox.account_id = account_id; + + /* unsent mail is moved to 'OUTBOX'. */ + if (!em_core_mail_move(&mail_id, 1, dest_mbox.name, EMF_MOVED_BY_COMMAND, 0, NULL)) + EM_DEBUG_EXCEPTION(" em_core_mail_move falied..."); +#endif + + + goto FINISH_OFF; + } + + /* sent mail is moved to 'SENT' box or deleted. */ + if (opt->keep_local_copy) { + EM_SAFE_FREE(mailbox_name); + + if (!em_storage_get_mailboxname_by_mailbox_type(account_id, EMF_MAILBOX_TYPE_SENTBOX, &mailbox_name, false, &err)) { + EM_DEBUG_EXCEPTION(" em_storage_get_mailboxname_by_mailbox_type failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + dest_mbox.name = mailbox_name; + dest_mbox.account_id = account_id; + + if (!em_core_mail_move(&mail_id, 1, dest_mbox.name, EMF_MOVED_AFTER_SENDING, 0, &err)) + EM_DEBUG_EXCEPTION(" em_core_mail_move falied [%d]", err); +#ifdef __FEATURE_SYNC_CLIENT_TO_SERVER__ +#ifdef __LOCAL_ACTIVITY__ + else if (ref_account->receiving_server_type == EMF_SERVER_TYPE_IMAP4) /* To be synced to Sent box only IMAP not for POP */ { + + emf_activity_tbl_t new_activity; + int activityid = 0; + + if (false == em_core_get_next_activity_id(&activityid, &err)) { + EM_DEBUG_EXCEPTION(" em_core_get_next_activity_id Failed [%d] ", err); + } + + memset(&new_activity, 0x00, sizeof(emf_activity_tbl_t)); + new_activity.activity_id = activityid; + new_activity.server_mailid = NULL; + new_activity.account_id = account_id; + new_activity.mail_id = mail_id; + new_activity.activity_type = ACTIVITY_SAVEMAIL; + new_activity.dest_mbox = NULL; + new_activity.src_mbox = NULL; + + if (!em_core_activity_add(&new_activity, &err)) { + EM_DEBUG_EXCEPTION(" em_core_activity_add Failed [%d] ", err); + } + + if (!em_core_mail_move_from_server(dest_mbox.account_id, mailbox_name, &mail_id, 1, dest_mbox.name, &err)) { + EM_DEBUG_EXCEPTION(" em_core_mail_move_from_server falied [%d]", err); + } + else { + /* Remove ACTIVITY_SAVEMAIL activity */ + new_activity.activity_id = activityid; + new_activity.activity_type = ACTIVITY_SAVEMAIL; + new_activity.account_id = account_id; + new_activity.mail_id = mail_id; + new_activity.dest_mbox = NULL; + new_activity.server_mailid = NULL; + new_activity.src_mbox = NULL; + + if (!em_core_activity_delete(&new_activity, &err)) { + EM_DEBUG_EXCEPTION(">>>>>>Local Activity [ACTIVITY_SAVEMAIL] [%d] ", err); + } + } + sent_box = 1; + } +#endif +#endif + + /* On Successful Mail sent remove the Draft flag */ + emf_mail_flag_t update_flag; + if (mail->info) + memcpy(&update_flag, &(mail->info->flags), sizeof(emf_mail_flag_t)); + else + memset(&update_flag, 0x00, sizeof(emf_mail_flag_t)); + update_flag.draft = 0; + int sticky_flag = 1; + if (!em_core_mail_modify_flag(mail_id, update_flag, sticky_flag, &err)) + EM_DEBUG_EXCEPTION(" Flag Modification Failed [ %d] ", err); + sent_box = 1; + } + else { + if (!em_core_mail_delete(account_id, &mail_id, 1, 0, EMF_DELETED_AFTER_SENDING, false, &err)) + EM_DEBUG_EXCEPTION(" em_core_mail_delete failed [%d]", err); + } + + /*Update status flag to DB*/ + mail->info->extra_flags.status = EMF_MAIL_STATUS_SENT; + if (!em_core_mail_modify_extra_flag(mail_id, mail->info->extra_flags, &err)) + EM_DEBUG_EXCEPTION("Failed to modify extra flag [%d]", err); + /*Update status flag to DB*/ + if (!em_core_delete_transaction_info_by_mailId(mail_id)) + EM_DEBUG_EXCEPTION(" em_core_delete_transaction_info_by_mailId failed for mail_id[%d]", mail_id); + + ret = true; + +FINISH_OFF: + if (ret == false && err != EMF_ERROR_INVALID_PARAM && mail) { + if (err != EMF_ERROR_CANCELLED) { + mail->info->extra_flags.status = EMF_MAIL_STATUS_SEND_FAILURE; + if (!em_core_mail_modify_extra_flag(mail_id, mail->info->extra_flags, &err2)) + EM_DEBUG_EXCEPTION("Failed to modify extra flag [%d]", err2); + } + else { + if (EMF_MAIL_STATUS_SEND_CANCELED == mail->info->extra_flags.status) + EM_DEBUG_LOG("EMF_MAIL_STATUS_SEND_CANCELED Already set for "); + else { + mail->info->extra_flags.status = EMF_MAIL_STATUS_SEND_CANCELED; + if (!em_core_mail_modify_extra_flag(mail_id, mail->info->extra_flags, &err2)) + EM_DEBUG_EXCEPTION("Failed to modify extra flag [%d]", err2); + } + } + } + +#ifndef __FEATURE_KEEP_CONNECTION__ + if (stream) + smtp_close(stream); +#endif /* __FEATURE_KEEP_CONNECTION__ */ + if (stls) + mail_parameters(NULL, SET_SSLSTART, (void *)stls); + if (mail) + em_core_mail_free(&mail, 1, NULL); + if (envelope) + mail_free_envelope(&envelope); + + if (fpath) { + EM_DEBUG_LOG("REMOVE TEMP FILE : %s", fpath); + remove(fpath); + free(fpath); + } + + if (ret == true) { + if (!em_storage_notify_network_event(NOTI_SEND_FINISH, account_id, NULL, mail_id, 0)) + EM_DEBUG_EXCEPTION("em_storage_notify_network_event [NOTI_SEND_FINISH] Failed"); + } + else { + if (!em_storage_notify_network_event(NOTI_SEND_FAIL, account_id, NULL, mail_id, err)) + EM_DEBUG_EXCEPTION("em_storage_notify_network_event [NOTI_SEND_FAIL] Failed"); + em_core_show_popup(mail_id, EMF_ACTION_SEND_MAIL, err); + } + + EM_SAFE_FREE(mailbox_name); + + if (err_code != NULL) + *err_code = err; + EM_PROFILE_END(profile_em_core_mail_send); + EM_DEBUG_FUNC_END("ret [%d], err [%d]", ret, err); + return ret; +} + +/* send a saved message */ +EXPORT_API int em_core_mail_send_saved(int account_id, char *input_mailbox_name, emf_option_t *sending_option, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id[%d], input_mailbox_name[%p], sending_option[%p], err_code[%p]", account_id, input_mailbox_name, sending_option, err_code); + + int ret = false; + int err = EMF_ERROR_NONE; + int status = EMF_SEND_FAIL; + + SENDSTREAM *stream = NULL; + ENVELOPE *envelope = NULL; + emf_mailbox_t dest_mbox = {0}; + emf_mail_t *mail = NULL; + emf_account_t *ref_account = NULL; + emf_mail_tbl_t mail_table_data = {0}; + emf_option_t *opt = NULL; + sslstart_t stls = NULL; + void *tmp_stream = NULL; + void *p = NULL; + char *fpath = NULL; + int mail_id = 0; + int handle = 0; + int i = 0; + int total = 0; + char *mailbox_name = NULL; + + if (!account_id || !input_mailbox_name) { + EM_DEBUG_EXCEPTION("EMF_ERROR_INVALID_PARAM"); + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + mail_send_notify(EMF_SEND_PREPARE, 0, 0, account_id, mail_id, err); + + if (!(ref_account = em_core_get_account_reference(account_id))) { + EM_DEBUG_EXCEPTION("em_core_get_account_reference failed [%d]", account_id); + err = EMF_ERROR_INVALID_ACCOUNT; + goto FINISH_OFF; + } + + FINISH_OFF_IF_CANCELED; + + if (sending_option) + opt = sending_option; + else + opt = em_core_get_option(&err); + + /* search mail. */ + if (!em_storage_mail_search_start(NULL, account_id, input_mailbox_name, 0, &handle, &total, true, &err)) { + EM_DEBUG_EXCEPTION("em_storage_mail_search_start failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + + while (i++ < total) { + FINISH_OFF_IF_CANCELED; + + p = NULL; + if (!em_storage_mail_search_result(handle, RETRIEVE_ID, (void **)&p, true, &err)) { + EM_DEBUG_EXCEPTION("em_storage_mail_search_result failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + + mail_id = (int)p; + + if (!em_core_mail_get_mail(mail_id, &mail, &err)) { + EM_DEBUG_EXCEPTION("em_core_mail_get_mail failed [%d]", err); + goto FINISH_OFF; + } + + /* check for email_address validation */ + if (!em_core_verify_email_address_of_mail_header(mail->head, false, &err)) { + EM_DEBUG_EXCEPTION("em_core_verify_email_address_of_mail_header failed [%d]", err); + goto FINISH_OFF; + } + + /* check that this mail was saved in offline-mode. */ + if (mail->info->extra_flags.status != EMF_MAIL_STATUS_SAVED_OFFLINE) { + EM_DEBUG_EXCEPTION(" mail was not saved in offline mode..."); + em_core_mail_free(&mail, 1, &err); mail = NULL; + continue; + } + + if(!em_convert_mail_flag_to_mail_tbl(&(mail->info->flags), &mail_table_data, &err)) { + EM_DEBUG_EXCEPTION("em_convert_mail_flag_to_mail_tbl failed [%d]", err); + goto FINISH_OFF; + } + + mail_table_data.save_status = mail->info->extra_flags.status; + mail_table_data.lock_status = mail->info->extra_flags.lock; + mail_table_data.priority = mail->info->extra_flags.priority; + mail_table_data.report_status = mail->info->extra_flags.report; + + mail->info->extra_flags.status = EMF_MAIL_STATUS_SENDING; + + if (!em_core_mail_get_rfc822(mail, &envelope, &fpath, opt, &err)) { + EM_DEBUG_EXCEPTION("em_core_mail_get_rfc822 falied [%d]", err); + goto FINISH_OFF; + } + + FINISH_OFF_IF_CANCELED; + + /* connect mail server. */ + if (!stream) { + /* if there no security option, unset security. */ + if (!ref_account->sending_security) { + stls = (sslstart_t)mail_parameters(NULL, GET_SSLSTART, NULL); + mail_parameters(NULL, SET_SSLSTART, NULL); + } + + stream = NULL; + if (!em_core_mailbox_open(account_id, (char *)ENCODED_PATH_SMTP, &tmp_stream, &err) || !tmp_stream) { + EM_DEBUG_EXCEPTION("em_core_mailbox_open failed [%d]", err); + + if (err == EMF_ERROR_CONNECTION_BROKEN) + err = EMF_ERROR_CANCELLED; + + status = EMF_SEND_CONNECTION_FAIL; + goto FINISH_OFF; + } + + stream = (SENDSTREAM *)tmp_stream; + + FINISH_OFF_IF_CANCELED; + + mail_send_notify(EMF_SEND_CONNECTION_SUCCEED, 0, 0, account_id, mail_id, err); + + /* reqest of delivery status. */ + if (opt && opt->req_delivery_receipt == EMF_OPTION_REQ_DELIVERY_RECEIPT_ON) { + stream->protocol.esmtp.dsn.want = 1; + stream->protocol.esmtp.dsn.full = 0; + stream->protocol.esmtp.dsn.notify.failure = 1; + stream->protocol.esmtp.dsn.notify.success = 1; + } + + mail_send_notify(EMF_SEND_START, 0, 0, account_id, mail_id, err); + } + + mail_table_data.save_status = EMF_MAIL_STATUS_SENDING; + + /* update mail status to sending. */ + if (!em_storage_change_mail_field(mail_id, UPDATE_EXTRA_FLAG, &mail_table_data, true, &err)) { + EM_DEBUG_EXCEPTION("em_storage_change_mail_field failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + + if (!em_core_mail_send_smtp(stream, envelope, fpath, account_id, mail_id, &err)) { + EM_DEBUG_EXCEPTION("em_core_mail_send_smtp failed [%d]", err); + + mail_table_data.save_status = EMF_MAIL_STATUS_SEND_FAILURE; + + /* update mail status to failure. */ + if (!em_storage_change_mail_field(mail_id, UPDATE_EXTRA_FLAG, &mail_table_data, true, &err)) + EM_DEBUG_EXCEPTION("em_storage_change_mail_field failed [%d]", err); + + if (!em_storage_get_mailboxname_by_mailbox_type(account_id, EMF_MAILBOX_TYPE_OUTBOX, &mailbox_name, false, &err)) { + EM_DEBUG_EXCEPTION("em_storage_get_mailboxname_by_mailbox_type failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + dest_mbox.name = mailbox_name; + dest_mbox.account_id = account_id; + + em_core_mail_move(&mail_id, 1, dest_mbox.name, EMF_MOVED_AFTER_SENDING, 0, NULL); + + goto FINISH_OFF; + } + + mail_table_data.save_status = EMF_MAIL_STATUS_SENT; + + /* update mail status to sent mail. */ + if (!em_storage_change_mail_field(mail_id, UPDATE_EXTRA_FLAG, &mail_table_data, true, &err)) { + EM_DEBUG_EXCEPTION("em_storage_change_mail_field failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + + /* sent mail is moved to 'SENT' box or deleted. */ + if (opt->keep_local_copy) { + EM_SAFE_FREE(mailbox_name); + if (!em_storage_get_mailboxname_by_mailbox_type(account_id, EMF_MAILBOX_TYPE_SENTBOX, &mailbox_name, false, &err)) { + EM_DEBUG_EXCEPTION("em_storage_get_mailboxname_by_mailbox_type failed [%d]", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + dest_mbox.name = mailbox_name; + dest_mbox.account_id = account_id; + + if (!em_core_mail_move(&mail_id, 1, dest_mbox.name, EMF_MOVED_AFTER_SENDING, 0, &err)) + EM_DEBUG_EXCEPTION("em_core_mail_move falied [%d]", err); + } + else { + if (!em_core_mail_delete(account_id, &mail_id, 1, 0, EMF_DELETED_AFTER_SENDING, false, &err)) + EM_DEBUG_EXCEPTION("em_core_mail_delete falied [%d]", err); + } + + em_core_mail_free(&mail, 1, NULL); mail = NULL; + mail_free_envelope(&envelope); envelope = NULL; + + if (fpath) { + remove(fpath); + EM_SAFE_FREE(fpath); + } + } + + + ret = true; + +FINISH_OFF: + if (stream) + smtp_close(stream); + + if (stls) + mail_parameters(NIL, SET_SSLSTART, (void *)stls); + + if (envelope) + mail_free_envelope(&envelope); + + if (handle) { + if (!em_storage_mail_search_end(handle, true, &err)) + EM_DEBUG_EXCEPTION("em_storage_mail_search_end failed [%d]", err); + } + + if (mail) + em_core_mail_free(&mail, 1, NULL); + + if (fpath) { + remove(fpath); + EM_SAFE_FREE(fpath); + } + + EM_SAFE_FREE(mailbox_name); + + if (ret == true) + mail_send_notify(EMF_SEND_FINISH, 0, 0, account_id, mail_id, err); + else { + mail_send_notify(status, 0, 0, account_id, mail_id, err); + em_core_show_popup(account_id, EMF_ACTION_SEND_MAIL, err); + } + + if (err_code != NULL) + *err_code = err; + + return ret; +} + +static int em_core_mail_send_smtp(SENDSTREAM *stream, ENVELOPE *env, char *data_file, int account_id, int mail_id, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("stream[%p], env[%p], data_file[%s], account_id[%d], mail_id[%d], err_code[%p]", stream, env, data_file, account_id, mail_id, err_code); + EM_PROFILE_BEGIN(profile_em_core_mail_send_smtp); + + int ret = false; + int err = EMF_ERROR_NONE; + int recipients = 0; + long total = 0, sent = 0, send_ret = 0, send_err = 0, sent_percent = 0, last_sent_percent = 0; + char buf[2048] = { 0, }; + emf_account_t *ref_account = NULL; + FILE *fp = NULL; + + if (!env || !env->from || (!env->to && !env->cc && !env->bcc)) { + if (env != NULL) + EM_DEBUG_EXCEPTION("EMF_ERROR_INVALID_PARAM"); + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + if (!env->from->mailbox || !env->from->host) { + EM_DEBUG_EXCEPTION("env->from->mailbox[%p], env->from->host[%p]", env->from->mailbox, env->from->host); + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + if (!(ref_account = em_core_get_account_reference(account_id))) { + EM_DEBUG_EXCEPTION("em_core_get_account_reference failed [%d]", account_id); + err = EMF_ERROR_INVALID_ACCOUNT; + goto FINISH_OFF; + } + + EM_DEBUG_LOG("Modifying - MAIL FROM "); + if (ref_account->email_addr == NULL) { + EM_DEBUG_LOG("ref_account->email_addr is null!!"); + SNPRINTF(buf, sizeof(buf), "FROM:<%s@%s>", env->from->mailbox, env->from->host); + } + else + SNPRINTF(buf, sizeof(buf), "FROM:<%s>", ref_account->email_addr); + + /* set DSN for ESMTP */ + if (stream->protocol.esmtp.ok) { + if (stream->protocol.esmtp.eightbit.ok && stream->protocol.esmtp.eightbit.want) + strncat (buf, " BODY=8BITMIME", sizeof(buf)-(strlen(buf)+1)); + + if (stream->protocol.esmtp.dsn.ok && stream->protocol.esmtp.dsn.want) { + EM_DEBUG_LOG("stream->protocol.esmtp.dsn.want is required"); + strncat (buf, stream->protocol.esmtp.dsn.full ? " RET=FULL" : " RET=HDRS", sizeof(buf)-strlen(buf)-1); + if (stream->protocol.esmtp.dsn.envid) + SNPRINTF (buf + strlen (buf), sizeof(buf)-(strlen(buf)), " ENVID=%.100s", stream->protocol.esmtp.dsn.envid); + } + else + EM_DEBUG_LOG("stream->protocol.esmtp.dsn.want is not required"); + } + + EM_PROFILE_BEGIN(profile_prepare_and_head); + send_ret = smtp_send(stream, "RSET", 0); + EM_DEBUG_LOG("[SMTP] RSET --------> %s", stream->reply); + + if (send_ret != SMTP_RESPONSE_OK) { + err = send_ret; + goto FINISH_OFF; + } + + send_ret = smtp_send(stream, "MAIL", buf); + EM_DEBUG_LOG("[SMTP] MAIL %s --------> %s", buf, stream->reply); + + switch (send_ret) { + case SMTP_RESPONSE_OK: + break; + + case SMTP_RESPONSE_WANT_AUTH : + case SMTP_RESPONSE_WANT_AUTH2: + EM_DEBUG_EXCEPTION("SMTP error : authentication required..."); + err = EMF_ERROR_AUTHENTICATE; + goto FINISH_OFF; + + case SMTP_RESPONSE_UNAVAIL: + EM_DEBUG_EXCEPTION("SMTP error : mailbox unavailable..."); + err = EMF_ERROR_MAILBOX_FAILURE; + goto FINISH_OFF; + + default: + err = send_ret; + goto FINISH_OFF; + } + + if (env->to) { + send_ret = smtp_rcpt(stream, env->to, &send_err); + EM_DEBUG_LOG("[SMTP] RCPT TO : <%s@%s> ... --------> %s", env->to->mailbox, env->to->host, env->to->error ? env->to->error : stream->reply); + if (send_ret) { + err = stream->replycode; + goto FINISH_OFF; + } + + if (!send_err) + recipients++; + } + + if (env->cc) { + send_ret = smtp_rcpt(stream, env->cc, &send_err); + EM_DEBUG_LOG("[SMTP] RCPT TO : <%s@%s> ... --------> %s", env->cc->mailbox, env->cc->host, env->cc->error ? env->cc->error : stream->reply); + if (send_ret) { + err = stream->replycode; + goto FINISH_OFF; + } + + if (!send_err) + recipients++; + } + + if (env->bcc) { + send_ret = smtp_rcpt(stream, env->bcc, &send_err); + EM_DEBUG_LOG("[SMTP] RCPT TO : <%s@%s> ... --------> %s", env->bcc->mailbox, env->bcc->host, env->bcc->error ? env->bcc->error : stream->reply); + if (send_ret) { + err = stream->replycode; + goto FINISH_OFF; + } + + if (!send_err) + recipients++; + } + + + if (send_err) { + EM_DEBUG_EXCEPTION("One or more recipients failed..."); + err = EMF_ERROR_INVALID_ADDRESS; + } + + if (!recipients) { + EM_DEBUG_EXCEPTION("No valid recipients..."); + + switch (stream->replycode) { + case SMTP_RESPONSE_UNAVAIL: + case SMTP_RESPONSE_WANT_AUTH : + case SMTP_RESPONSE_WANT_AUTH2: + err = EMF_ERROR_AUTH_REQUIRED; + break; + + default: + err = EMF_ERROR_INVALID_ADDRESS; + break; + } + goto FINISH_OFF; + } + + send_ret = smtp_send(stream, "DATA", 0); + EM_DEBUG_LOG("[SMTP] DATA --------> %s", stream->reply); + EM_PROFILE_END(profile_prepare_and_head); + + if (send_ret != SMTP_RESPONSE_READY) { + err = send_ret; + goto FINISH_OFF; + } + + if (data_file) { + EM_PROFILE_BEGIN(profile_open_file); + if (!(fp = fopen(data_file, "r+"))) { + EM_DEBUG_EXCEPTION("fopen(\"%s\") failed...", data_file); + err = EMF_ERROR_SYSTEM_FAILURE; + goto FINISH_OFF; + } + EM_PROFILE_END(profile_open_file); + + +#ifdef __FEATURE_SEND_OPTMIZATION__ + { + char *data = NULL; + int read_size, allocSize, dataSize, gMaxAllocSize = 40960; /* 40KB */ + + fseek(fp, 0, SEEK_END); + total = ftell(fp); + fseek(fp, 0, SEEK_SET); + EM_DEBUG_LOG("total size [%d]", total); + + if (total < gMaxAllocSize) + allocSize = total + 1; + else + allocSize = gMaxAllocSize; + + EM_PROFILE_BEGIN(profile_allocation); + /* Allocate a buffer of max 2MB to read from file */ + data = (char *)em_core_malloc(allocSize); + allocSize--; + EM_PROFILE_END(profile_allocation); + + if (NULL == data) { + err = EMF_ERROR_SMTP_SEND_FAILURE; + goto FINISH_OFF; + } + + while (total) { + if (total < allocSize) + dataSize = total; + else + dataSize = allocSize; + + memset(data, 0x0, dataSize+1); + read_size = fread(data, sizeof (char), dataSize, fp); + + if (read_size != dataSize) { + /* read fail. */ + EM_SAFE_FREE(data); + EM_DEBUG_EXCEPTION("Read from file failed"); + err = EMF_ERROR_SMTP_SEND_FAILURE; + goto FINISH_OFF; + } + sent += read_size; + + EM_DEBUG_LOG("before smtp_soutr_test"); + if (!(send_ret = smtp_soutr_test(stream->netstream, data))) { + EM_SAFE_FREE(data); + EM_DEBUG_EXCEPTION("Failed to send the data "); + err = EMF_ERROR_SMTP_SEND_FAILURE; + goto FINISH_OFF; + } + else { + sent_percent = (int) ((double)sent / (double)total * 100.0); + if (last_sent_percent + 5 <= sent_percent) { + if (!em_storage_notify_network_event(NOTI_SEND_START, account_id, NULL, mail_id, sent_percent)) + EM_DEBUG_EXCEPTION("em_storage_notify_network_event [NOTI_SEND_START] Failed >>>>"); + last_sent_percent = sent_percent; + } + EM_DEBUG_LOG("Sent data Successfully. sent[%d] total[%d]", sent, total); + } + total -= dataSize; + } + + EM_SAFE_FREE(data); + } +#else + fseek(fp, 0, SEEK_END); + total = ftell(fp); + fseek(fp, 0, SEEK_SET); + + while (fgets(buf, 1024, fp)) { +#ifdef FEATURE_SEND_DATA_DEBUG + EM_DEBUG_LOG("%s", buf); +#endif + sent += strlen(buf); + + if (!(send_ret = smtp_soutr(stream->netstream, buf))) + break; + /* Sending Progress Notification */ + sent_percent = (int) ((double)sent / (double)total * 100.0); + if (last_sent_percent + 5 <= sent_percent) { + /* Disabled Temporary + if (!em_storage_notify_network_event(NOTI_SEND_START, account_id, NULL, mail_id, sent_percent)) + EM_DEBUG_EXCEPTION(" em_storage_notify_network_event [NOTI_SEND_START] Failed >>>>"); + */ + last_sent_percent = sent_percent; + } + } + +#endif + if (!send_ret) { + EM_DEBUG_EXCEPTION("smtp_soutr failed - %ld", send_ret); + err = EMF_ERROR_SMTP_SEND_FAILURE; + goto FINISH_OFF; + } + } + + send_ret = smtp_send(stream, ".", 0); + EM_DEBUG_LOG("[SMTP] . --------> %s", stream->reply); + + if (send_ret != SMTP_RESPONSE_OK) { + err = send_ret; + goto FINISH_OFF; + } + + ret = true; + +FINISH_OFF: + if (ret == false) + smtp_send(stream, "RSET", 0); + + if (err_code) + *err_code = err; + + if (fp) + fclose(fp); + EM_PROFILE_END(profile_em_core_mail_send_smtp); + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +/* ------ rfc822 handle --------------------------------------------------- */ +#define RANDOM_NUMBER_LENGTH 35 + +char *em_core_generate_content_id_string(const char *hostname, int *err) +{ + EM_DEBUG_FUNC_BEGIN("hostname[%p]", hostname); + + if (!hostname) { + EM_DEBUG_EXCEPTION("EMF_ERROR_INVALID_PARAM"); + if (err) + *err = EMF_ERROR_INVALID_PARAM; + return NULL; + } + + int cid_length = RANDOM_NUMBER_LENGTH + strlen(hostname) + 2, random_number_1, random_number_2, random_number_3, random_number_4; + char *cid_string = NULL; + + cid_string = malloc(cid_length); + + if (!cid_string) { + if (err) + *err = EMF_ERROR_OUT_OF_MEMORY; + return NULL; + } + + memset(cid_string, 0, cid_length); + + srand(time(NULL) + rand()); + random_number_1 = rand() * rand(); + random_number_2 = rand() * rand(); + random_number_3 = rand() * rand(); + random_number_4 = rand() * rand(); + + SNPRINTF(cid_string, cid_length, "<%08x%08x%08x%08x@%s>", random_number_1, random_number_2, random_number_3, random_number_4, hostname); + + if (err) + *err = EMF_ERROR_NONE; + + EM_DEBUG_FUNC_END("cid_string [%s]", cid_string); + return cid_string; +} + + +/* ------ attach_part ----------------------------------------------------- */ +/* data : if filename NULL, content data. */ +/* else absolute path of file to be attached. */ +/* data_len : length of data. if filename not NULL, ignored. */ +/* file_name : attahcment name. */ +static int attach_part(BODY *body, const unsigned char *data, int data_len, char *filename, char *content_sub_type, int is_inline, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("body[%p], data[%s], data_len[%d], filename[%s], content_sub_type[%s], err_code[%p]", body, data, data_len, filename, content_sub_type, err_code); + + int ret = false; + int error = EMF_ERROR_NONE; + int has_special_character = 0; + int base64_file_name_length = 0; + int i= 0; + gsize bytes_read; + gsize bytes_written; + char *encoded_file_name = NULL; + char *extension = NULL; + char *base64_file_name = NULL; + char *result_file_name = NULL; + char content_disposition[100] = { 0, }; + PARAMETER *last_param = NULL; + PARAMETER *param = NULL; + PART *last_part = NULL; + PART *part = NULL; + SIZEDTEXT source_text; + GError *glib_error = NULL; + CHARSET *result_charset = NULL; + + if (!body) { + EM_DEBUG_EXCEPTION("EMF_ERROR_INVALID_PARAM"); + error = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + if (body->nested.part) { + last_part = body->nested.part; + + if (last_part != NULL) { + while (last_part->next) + last_part = last_part->next; + } + } + + /* PART */ + part = mail_newbody_part(); + if (part == NULL) { + EM_DEBUG_EXCEPTION("mail_newbody_part failed..."); + error = EMF_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + part->next = NULL; + + if (last_part) + last_part->next = part; + else + body->nested.part = part; + + last_part = part; + + /* set data.. */ + /* content_data = (unsigned char *)fs_get(data_len + 1); */ + /* memcpy(content_data, data, data_len); */ + /* content_data[data_len] = 0; */ + + /* part->body.contents.text.data = content_data; */ + /* part->body.contents.text.size = data_len; */ + + if (filename) { /* attachment */ + source_text.data = (unsigned char*)filename; + source_text.size = strlen(filename); + + result_charset = (CHARSET*)utf8_infercharset(&source_text); + + if(result_charset) { + EM_DEBUG_LOG("return_charset->name [%s]", result_charset->name); + encoded_file_name = (char*)g_convert (filename, -1, "UTF-8", result_charset->name, &bytes_read, &bytes_written, &glib_error); + } + else { + i = 0; + while(filename[i]) { + if(filename[i++] & 0x80) { + has_special_character = 1; + break; + } + } + EM_DEBUG_LOG("has_special_character [%d]", has_special_character); + if(has_special_character) + encoded_file_name = (char*)g_convert (filename, -1, "UTF-8", "EUC-KR", &bytes_read, &bytes_written, &glib_error); + } + + EM_DEBUG_LOG("encoded_file_name [%s]", encoded_file_name); + + if(encoded_file_name == NULL) + encoded_file_name = strdup(filename); + + if(!em_core_encode_base64(encoded_file_name, strlen(encoded_file_name), &base64_file_name, (unsigned long*)&base64_file_name_length, &error)) { + EM_DEBUG_EXCEPTION("em_core_encode_base64 failed. error [%d]", error); + goto FINISH_OFF; + } + + result_file_name = em_core_replace_string(base64_file_name, "\015\012", ""); + + EM_DEBUG_LOG("base64_file_name_length [%d]", base64_file_name_length); + + if(result_file_name) { + EM_SAFE_FREE(encoded_file_name); + encoded_file_name = em_core_malloc(strlen(result_file_name) + 15); + if(!encoded_file_name) { + EM_DEBUG_EXCEPTION("em_core_malloc failed."); + goto FINISH_OFF; + } + snprintf(encoded_file_name, strlen(result_file_name) + 15, "=?UTF-8?B?%s?=", result_file_name); + EM_DEBUG_LOG("encoded_file_name [%s]", encoded_file_name); + } + + extension = em_core_get_extension_from_file_path(filename, NULL); + + part->body.type = em_core_get_content_type(extension, NULL); + if(part->body.type == TYPEIMAGE) + part->body.subtype = strdup(extension); + else + part->body.subtype = cpystr("octet-stream"); + + part->body.encoding = ENCBINARY; + part->body.size.bytes = data_len; + + if (data) + part->body.sparep = EM_SAFE_STRDUP((char *)data); /* file path */ + else + part->body.sparep = NULL; + + SNPRINTF(content_disposition, sizeof(content_disposition), "%s", "attachment"); + + part->body.disposition.type = cpystr(content_disposition); + + /* BODY PARAMETER */ + /* another parameter or get parameter-list from this function-parameter */ + param = mail_newbody_parameter(); + if (param == NULL) { + EM_DEBUG_EXCEPTION("mail_newbody_parameter failed..."); + error = EMF_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + param->attribute = cpystr("name"); + param->value = cpystr(encoded_file_name); + param->next = NULL; + last_param = param; + last_part->body.parameter = last_param; + + if (is_inline) { + /* CONTENT-ID */ + part->body.id = em_core_generate_content_id_string("com.samsung.slp.email", &error); + part->body.type = TYPEIMAGE; + /* EM_SAFE_FREE(part->body.subtype); */ + /* part->body.subtype = EM_SAFE_STRDUP(content_sub_type); */ + } + + /* DISPOSITION PARAMETER */ + param = mail_newbody_parameter(); + if (param == NULL) { + EM_DEBUG_EXCEPTION("mail_newbody_parameter failed..."); + error = EMF_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + param->attribute = cpystr("filename"); + param->value = cpystr(encoded_file_name); + param->next = NULL; + last_param = param; + last_part->body.disposition.parameter = last_param; + + if (is_inline) + last_part->body.disposition.type = EM_SAFE_STRDUP("inline"); + } + else { + /* text body (plain/html) */ + part->body.type = TYPETEXT; + + part->body.size.bytes = data_len; + if (data) + part->body.sparep = EM_SAFE_STRDUP((char *)data); /* file path */ + else + part->body.sparep = NULL; + + + if (!content_sub_type) { + /* Plain text body */ + part->body.encoding = ENC8BIT; + part->body.subtype = cpystr("plain"); + last_param = part->body.parameter; + + if (last_param != NULL) { + while (last_param->next) + last_param = last_param->next; + } + + param = mail_newbody_parameter(); + + if (param == NULL) { + EM_DEBUG_EXCEPTION("mail_newbody_parameter failed..."); + error = EMF_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + param->attribute = cpystr("CHARSET"); + + if (data != NULL) { + gchar *extract_charset_plain = g_path_get_basename((const gchar *)data); + if (extract_charset_plain != NULL && extract_charset_plain[0] != '\0') + param->value = cpystr(extract_charset_plain); + g_free(extract_charset_plain); + } + else + param->value = cpystr("UTF-8"); + + if(!param->value) + param->value = cpystr("UTF-8"); + + param->next = NULL; + + if (last_param != NULL) + last_param->next = param; + else + part->body.parameter = param; + } + else { + /* HTML text body */ + part->body.encoding = ENC8BIT; + part->body.subtype = cpystr(content_sub_type); + + last_param = part->body.parameter; + + if (last_param != NULL) { + while (last_param->next) + last_param = last_param->next; + } + + param = mail_newbody_parameter(); + + if (param == NULL) { + EM_DEBUG_EXCEPTION("mail_newbody_parameter failed..."); + error = EMF_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + param->attribute = cpystr("CHARSET"); + + char *pHtml = NULL; + if (data != NULL) { + gchar *extract_charset = g_path_get_basename((const gchar *)data); + if (extract_charset != NULL) { + if ((pHtml = strstr(extract_charset, ".htm")) != NULL) { + extract_charset[pHtml-extract_charset] = '\0'; + param->value = cpystr(extract_charset); + } + } + + if(!param->value) + param->value = cpystr("UTF-8"); + + EM_SAFE_FREE(extract_charset); + } + else + param->value = cpystr("UTF-8"); + param->next = NULL; + + if (last_param != NULL) + last_param->next = param; + else + part->body.parameter = param; + } + + /* NOTE : need to require this code. */ + /* sprintf(content_disposition, "%s\0", "inline"); */ + if (is_inline) { + SNPRINTF(content_disposition, sizeof(content_disposition), "%s", "inline"); + part->body.disposition.type = cpystr(content_disposition); + } + } + + ret = true; + +FINISH_OFF: + EM_SAFE_FREE(encoded_file_name); + EM_SAFE_FREE(base64_file_name); + if (err_code != NULL) + *err_code = error; + EM_DEBUG_FUNC_END(); + return ret; +} + +static PART *attach_mutipart_with_sub_type(BODY *parent_body, char *sub_type, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("parent_body[%p], sub_type [%s], err_code[%p]", parent_body, sub_type, err_code); + + int error = EMF_ERROR_NONE; + + PART *tail_part_cur = NULL; + PART *new_part = NULL; + + if (!parent_body || !sub_type) { + EM_DEBUG_EXCEPTION("EMF_ERROR_INVALID_PARAM"); + error = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + if (parent_body->nested.part) { + tail_part_cur = parent_body->nested.part; + + if (tail_part_cur != NULL) { + while (tail_part_cur->next) + tail_part_cur = tail_part_cur->next; + } + } + + new_part = mail_newbody_part(); + + if (new_part == NULL) { + EM_DEBUG_EXCEPTION("EMF_ERROR_OUT_OF_MEMORY"); + error = EMF_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + + } + + new_part->next = NULL; + new_part->body.type = TYPEMULTIPART; + new_part->body.subtype = EM_SAFE_STRDUP(sub_type); + + if (tail_part_cur) + tail_part_cur->next = new_part; + else + parent_body->nested.part = new_part; + +FINISH_OFF: + + if (err_code) + *err_code = error; + + EM_DEBUG_FUNC_END(); + + return new_part; +} + +static int attach_attachment_to_body(BODY **multipart_body, BODY *text_body, emf_attachment_info_t *atch, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("multipart_body[%p], text_body[%p], atch[%p], err_code[%p]", multipart_body, text_body, atch, err_code); + + int ret = false; + int error = EMF_ERROR_NONE; + BODY *frame_body = NULL; + /* make multipart body(multipart frame_body..) .. that has not content.. */ + + if (!multipart_body || !text_body || !atch) { + EM_DEBUG_EXCEPTION(" multipart_body[%p], text_body[%p], atch[%p]", multipart_body, text_body, atch); + error = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + frame_body = mail_newbody(); + if (frame_body == NULL) { + EM_DEBUG_EXCEPTION("mail_newbody failed..."); + error = EMF_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + frame_body->type = TYPEMULTIPART; + frame_body->contents.text.data = NULL; + frame_body->contents.text.size = 0; + frame_body->size.bytes = 0; + + /* insert original text_body to frame_body.. */ + if (!attach_part(frame_body, text_body->sparep, 0, NULL, NULL, false, &error)) { + EM_DEBUG_EXCEPTION(" attach_part failed [%d]", error); + goto FINISH_OFF; + } + + /* insert files.. */ + emf_attachment_info_t *p = atch; + char *name = NULL; + struct stat st_buf; + + while (p) { + EM_DEBUG_LOG("insert files - attachment id[%d]", p->attachment_id); + if (stat(p->savename, &st_buf) == 0) { + if (!p->name) { + if (!em_core_get_file_name(p->savename, &name, &error)) { + EM_DEBUG_EXCEPTION("em_core_get_file_name failed [%d]", error); + goto FINISH_OFF; + } + } + else + name = p->name; + + if (!attach_part(frame_body, (unsigned char *)p->savename, 0, name, NULL, false, &error)) { + EM_DEBUG_EXCEPTION("attach_part failed [%d]", error); + goto FINISH_OFF; + } + } + + p = p->next; + } + + ret = true; + +FINISH_OFF: + if (ret == true) + *multipart_body = frame_body; + else if (frame_body != NULL) + mail_free_body(&frame_body); + + if (err_code != NULL) + *err_code = error; + EM_DEBUG_FUNC_END(); + return ret; +} + +static char *em_core_encode_rfc2047_text(char *utf8_text, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("utf8_text[%s], err_code[%p]", utf8_text, err_code); + + if (utf8_text == NULL) { + if (err_code != NULL) + *err_code = EMF_ERROR_INVALID_PARAM; + return NULL; + } + + gsize len = strlen(utf8_text); + + EM_DEBUG_FUNC_END(); + + if (len > 0) + return g_strdup_printf("=?UTF-8?B?%s?=", g_base64_encode((const guchar *)utf8_text, len)); + else + return EM_SAFE_STRDUP(""); +} + +static void em_core_encode_rfc2047_address(ADDRESS *address, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("address[%p], err_code[%p]", address, err_code); + + while (address) { + if (address->personal) { + char *rfc2047_personal = em_core_encode_rfc2047_text(address->personal, err_code); + EM_SAFE_FREE(address->personal); + address->personal = rfc2047_personal; + } + address = address->next; + } + EM_DEBUG_FUNC_END(); +} + +#define DATE_STR_LENGTH 100 +/* Description : send mail to network(and save to sent-mailbox) or draft-mailbox, */ +/* Parameters : */ +/* mail : */ +/* is_draft : this mail is draft mail. */ +/* file_path : path of file that rfc822 data will be written to. */ +EXPORT_API int em_core_mail_get_rfc822(emf_mail_t *mail, ENVELOPE **env, char **file_path, emf_option_t *sending_option, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("mail[%p], env[%p], file_path[%p], sending_option[%p], err_code[%p]", mail, env, file_path, sending_option, err_code); + + int ret = false; + int error = EMF_ERROR_NONE; + + ENVELOPE *envelope = NULL; + BODY *text_body = NULL, *html_body = NULL; + BODY *root_body = NULL; + PART *part_for_html = NULL, *part_for_text = NULL; + emf_extra_flag_t extra_flag; + char *fname = NULL; + int is_incomplete = 0; + emf_account_t *ref_account = NULL; + char *pAdd = NULL; + + if (!mail || !mail->info || !mail->head) { + if (mail != NULL) + EM_DEBUG_EXCEPTION("mail->info[%p], mail->head[%p]", mail->info, mail->head); + + error = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + if (mail->info->extra_flags.report != EMF_MAIL_REPORT_MDN && !mail->body) { + EM_DEBUG_EXCEPTION("mail->body[%p]", mail->body); + error = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + + ref_account = em_core_get_account_reference(mail->info->account_id); + if (!ref_account) { + EM_DEBUG_EXCEPTION("em_core_get_account_reference failed [%d]", mail->info->account_id); + error = EMF_ERROR_INVALID_ACCOUNT; + goto FINISH_OFF; + } + + if (!(envelope = mail_newenvelope())) { + EM_DEBUG_EXCEPTION("mail_newenvelope failed..."); + error = EMF_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + is_incomplete = mail->info->flags.draft || (mail->info->extra_flags.status == EMF_MAIL_STATUS_SENDING);/* 4 */ + + if (is_incomplete) { + if (ref_account->email_addr && ref_account->email_addr[0] != '\0') { + char *p = cpystr(ref_account->email_addr); + + if (p == NULL) { + EM_DEBUG_EXCEPTION("cpystr failed..."); + error = EMF_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + EM_DEBUG_LOG("Assign envelop->from"); + if (mail->head && mail->head->from) { + char *pAdd = NULL ; + em_core_skip_whitespace(mail->head->from , &pAdd); + EM_DEBUG_LOG("address[pAdd][%s]", pAdd); + + rfc822_parse_adrlist(&envelope->from, pAdd, ref_account->sending_server_addr); + EM_SAFE_FREE(pAdd); + pAdd = NULL ; + } + else + envelope->from = rfc822_parse_mailbox(&p, NULL); + + + EM_SAFE_FREE(p); + if (!envelope->from) { + EM_DEBUG_EXCEPTION("rfc822_parse_mailbox failed..."); + + error = EMF_ERROR_INVALID_ADDRESS; + goto FINISH_OFF; + } + else { + + if (envelope->from->personal == NULL) { + if (sending_option && sending_option->display_name_from && sending_option->display_name_from[0] != '\0') + envelope->from->personal = cpystr(sending_option->display_name_from); + else + envelope->from->personal = (ref_account->display_name && ref_account->display_name[0] != '\0') ? cpystr(ref_account->display_name) : NULL; + } + } + } + + if (ref_account->return_addr && ref_account->return_addr[0] != '\0') { + char *p = cpystr(ref_account->return_addr); + + if (p == NULL) { + EM_DEBUG_EXCEPTION("cpystr failed..."); + + error = EMF_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + envelope->return_path = rfc822_parse_mailbox(&p, NULL); + EM_SAFE_FREE(p); + } + } + else { + if (!mail->head->from || !mail->head->to) { + EM_DEBUG_EXCEPTION("mail->head->from[%p], mail->head->to[%p]", mail->head->from, mail->head->to); + error = EMF_ERROR_INVALID_MAIL; + goto FINISH_OFF; + } + + int i, j; + + if (mail->head->from) { + for (i = 0, j = strlen(mail->head->from); i < j; i++) { + if (mail->head->from[i] == ';') + mail->head->from[i] = ','; + } + } + + if (mail->head->return_path) { + for (i = 0, j = strlen(mail->head->return_path); i < j; i++) { + if (mail->head->return_path[i] == ';') + mail->head->return_path[i] = ','; + } + } + em_core_skip_whitespace(mail->head->from , &pAdd); + EM_DEBUG_LOG("address[pAdd][%s]", pAdd); + + rfc822_parse_adrlist(&envelope->from, pAdd, ref_account->sending_server_addr); + EM_SAFE_FREE(pAdd); + pAdd = NULL ; + + em_core_skip_whitespace(mail->head->return_path , &pAdd); + EM_DEBUG_LOG("address[pAdd][%s]", pAdd); + + rfc822_parse_adrlist(&envelope->return_path, pAdd, ref_account->sending_server_addr); + EM_SAFE_FREE(pAdd); + pAdd = NULL ; + } + + { + int i, j; + + if (mail->head->to) { + for (i = 0, j = strlen(mail->head->to); i < j; i++) { + if (mail->head->to[i] == ';') + mail->head->to[i] = ','; + } + } + + if (mail->head->cc) { + for (i = 0, j = strlen(mail->head->cc); i < j; i++) { + if (mail->head->cc[i] == ';') + mail->head->cc[i] = ','; + } + } + + if (mail->head->bcc) { + for (i = 0, j = strlen(mail->head->bcc); i < j; i++) { + if (mail->head->bcc[i] == ';') + mail->head->bcc[i] = ','; + } + } + } + + em_core_skip_whitespace(mail->head->to , &pAdd); + EM_DEBUG_LOG("address[pAdd][%s]", pAdd); + + rfc822_parse_adrlist(&envelope->to, pAdd, ref_account->sending_server_addr); + EM_SAFE_FREE(pAdd); + pAdd = NULL ; + + EM_DEBUG_LOG("address[mail->head->cc][%s]", mail->head->cc); + em_core_skip_whitespace(mail->head->cc , &pAdd); + EM_DEBUG_LOG("address[pAdd][%s]", pAdd); + + rfc822_parse_adrlist(&envelope->cc, pAdd, ref_account->sending_server_addr); + EM_SAFE_FREE(pAdd); + pAdd = NULL ; + + em_core_skip_whitespace(mail->head->bcc , &pAdd); + rfc822_parse_adrlist(&envelope->bcc, pAdd, ref_account->sending_server_addr); + EM_SAFE_FREE(pAdd); + pAdd = NULL ; + + em_core_encode_rfc2047_address(envelope->return_path, &error); + em_core_encode_rfc2047_address(envelope->from, &error); + em_core_encode_rfc2047_address(envelope->sender, &error); + em_core_encode_rfc2047_address(envelope->reply_to, &error); + em_core_encode_rfc2047_address(envelope->to, &error); + em_core_encode_rfc2047_address(envelope->cc, &error); + em_core_encode_rfc2047_address(envelope->bcc, &error); + + if (mail->head->subject) + envelope->subject = em_core_encode_rfc2047_text(mail->head->subject, &error); + + char date_str[DATE_STR_LENGTH + 1] = { 0, }; + + rfc822_date(date_str); + + if (!is_incomplete) { + struct tm tm1; + + /* modified by stonyroot - prevent issue */ + memset(&tm1, 0x00, sizeof(tm1)); + + tm1.tm_year = mail->head->datetime.year - 1900; + tm1.tm_mon = mail->head->datetime.month - 1; + tm1.tm_mday = mail->head->datetime.day; + tm1.tm_hour = mail->head->datetime.hour; + tm1.tm_min = mail->head->datetime.minute; + tm1.tm_sec = mail->head->datetime.second; + + /* tzset(); */ + time_t t = mktime(&tm1); + + char buf[256] = {0, }; + + if (localtime(&t)) + strftime(buf, 128, "%a, %e %b %Y %H : %M : %S ", localtime(&t)); + else + strftime(buf, 128, "%a, %e %b %Y %H : %M : %S ", (const struct tm *)&tm1); + /* append last 5byes("+0900") */ + strncat(buf, date_str + (strlen(date_str) - 5), DATE_STR_LENGTH); + strncpy(date_str, buf, DATE_STR_LENGTH); + } + + envelope->date = (unsigned char *)cpystr((const char *)date_str); + + memcpy(&extra_flag, &mail->info->extra_flags, sizeof(emf_extra_flag_t)); + + /* check report mail */ + if (mail->info->extra_flags.report != EMF_MAIL_REPORT_MDN) { + /* Non-report mail */ + EM_DEBUG_LOG("mail->body->plain[%s]", mail->body->plain); + EM_DEBUG_LOG("mail->body->html[%s]", mail->body->html); + EM_DEBUG_LOG("mail->body->attachment_num[%d]", mail->body->attachment_num); + + + if ((mail->body->attachment_num > 0) || (mail->body->plain && mail->body->html)) { + EM_DEBUG_LOG("attachment_num : %d", mail->body->attachment_num); + root_body = mail_newbody(); + + if (root_body == NULL) { + EM_DEBUG_EXCEPTION("mail_newbody failed..."); + error = EMF_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + root_body->type = TYPEMULTIPART; + root_body->subtype = EM_SAFE_STRDUP("MIXED"); + root_body->contents.text.data = NULL; + root_body->contents.text.size = 0; + root_body->size.bytes = 0; + + part_for_text = attach_mutipart_with_sub_type(root_body, "ALTERNATIVE", &error); + + if (!part_for_text) { + EM_DEBUG_EXCEPTION("attach_mutipart_with_sub_type [part_for_text] failed [%d]", error); + goto FINISH_OFF; + } + + text_body = &part_for_text->body; + + if (mail->body->plain && strlen(mail->body->plain) > 0) { + EM_DEBUG_LOG("body->plain[%s]", mail->body->plain); + if (!attach_part(text_body, (unsigned char *)mail->body->plain, 0, NULL, NULL, false, &error)) { + EM_DEBUG_EXCEPTION("attach_part failed [%d]", error); + goto FINISH_OFF; + } + } + + if (mail->body->html && strlen(mail->body->html) > 0) { + EM_DEBUG_LOG("body->html[%s]", mail->body->html); + + part_for_html = attach_mutipart_with_sub_type(text_body, "RELATED", &error); + if (!part_for_html) { + EM_DEBUG_EXCEPTION("attach_mutipart_with_sub_type [part_for_html] failed [%d]", error); + goto FINISH_OFF; + } + + if (!attach_part(&(part_for_html->body) , (unsigned char *)mail->body->html, 0, NULL, "html", false, &error)) { + EM_DEBUG_EXCEPTION("attach_part failed [%d]", error); + goto FINISH_OFF; + } + /* + if (mail->body->plain) { + EM_SAFE_FREE(part_for_text->subtype); + part_for_text->subtype = EM_SAFE_STRDUP("ALTERNATIVE"); + } + */ + } + + if (mail->body->attachment) { + emf_attachment_info_t *atch = mail->body->attachment; + char *name = NULL; + BODY *body_to_attach = NULL; + struct stat st_buf; + + do { + EM_DEBUG_LOG("atch->savename[%s], atch->name[%s]", atch->savename, atch->name); + if (stat(atch->savename, &st_buf) == 0) { + EM_DEBUG_LOG("atch->name[%s]", atch->name); + if (!atch->name) { + if (!em_core_get_file_name(atch->savename, &name, &error)) { + EM_DEBUG_EXCEPTION("em_core_get_file_name failed [%d]", error); + goto TRY_NEXT; + } + } + else + name = atch->name; + EM_DEBUG_LOG("name[%s]", name); + + if (atch->inline_content && part_for_html) + body_to_attach = &(part_for_html->body); + else + body_to_attach = root_body; + + if (!attach_part(body_to_attach, (unsigned char *)atch->savename, 0, name, NULL, atch->inline_content, &error)) { + EM_DEBUG_EXCEPTION("attach_part failed [%d]", error); + goto TRY_NEXT; + } + } + +TRY_NEXT: + atch = atch->next; + } + while (atch); + } + text_body = NULL; + } + else { + text_body = mail_newbody(); + + if (text_body == NULL) { + EM_DEBUG_EXCEPTION("mail_newbody failed..."); + + error = EMF_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + text_body->type = TYPETEXT; + text_body->encoding = ENC8BIT; + if (mail->body->plain || mail->body->html) + text_body->sparep = EM_SAFE_STRDUP(mail->body->plain ? mail->body->plain : mail->body->html); + else + text_body->sparep = NULL; + + if (mail->body->html != NULL && mail->body->html[0] != '\0') + text_body->subtype = EM_SAFE_STRDUP("html"); + if (text_body->sparep) + text_body->size.bytes = strlen(text_body->sparep); + else + text_body->size.bytes = 0; + } + } + else { /* Report mail */ + EM_DEBUG_LOG("REPORT MAIL"); + envelope->references = cpystr(mail->head->mid); + + if (em_core_mail_get_report_body(envelope, &root_body, &error)) { + if (!mail->body) { + mail->body = em_core_malloc(sizeof(emf_mail_body_t)); + if (!mail->body) { + EM_DEBUG_EXCEPTION("malloc failed..."); + error = EMF_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + mail->body->plain = EM_SAFE_STRDUP(root_body->nested.part->body.sparep); + mail->body->attachment_num = 1; + + mail->body->attachment = em_core_malloc(sizeof(emf_attachment_info_t)); + if (!mail->body->attachment) { + EM_DEBUG_EXCEPTION("malloc failed..."); + EM_SAFE_FREE(mail->body->plain); + error = EMF_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + mail->body->attachment->downloaded = 1; + mail->body->attachment->savename = EM_SAFE_STRDUP(root_body->nested.part->next->body.sparep); + + char *p = NULL; + + if (!em_core_get_file_name(mail->body->attachment->savename, &p, &error)) { + EM_DEBUG_EXCEPTION("em_core_get_file_name failed [%d]", error); + goto FINISH_OFF; + } + + mail->body->attachment->name = cpystr(p); + } + } + + } + + if (file_path) { + EM_DEBUG_LOG("write rfc822 : file_path[%s]", file_path); + + if (part_for_html) + html_body = &(part_for_html->body); + + if (!em_core_write_rfc822(envelope, root_body ? root_body : text_body, html_body, extra_flag, &fname, &error)) { + EM_DEBUG_EXCEPTION("em_core_write_rfc822 failed [%d]", error); + goto FINISH_OFF; + } + + *file_path = fname; + } + + ret = true; + +FINISH_OFF: + if ((ret == true) && (env != NULL)) + *env = envelope; + else if (envelope != NULL) + mail_free_envelope(&envelope); + + if (text_body != NULL) + mail_free_body(&text_body); + + if (root_body != NULL) + mail_free_body(&root_body); + + if (err_code != NULL) + *err_code = error; + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +static int em_core_mail_get_report_body(ENVELOPE *envelope, BODY **multipart_body, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("envelope[%p], mulitpart_body[%p], err_code[%p]", envelope, multipart_body, err_code); + + int ret = false; + int err = EMF_ERROR_NONE; + + BODY *m_body = NULL; + BODY *p_body = NULL; + BODY *text_body = NULL; + PARAMETER *param = NULL; + emf_attachment_info_t atch; + FILE *fp = NULL; + char *fname = NULL; + char buf[512] = {0x00, }; + int sz = 0; + + if (!envelope || !multipart_body) { + EM_DEBUG_EXCEPTION(" envelope[%p], mulitpart_body[%p]", envelope, multipart_body); + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + if (!(text_body = mail_newbody())) { + EM_DEBUG_EXCEPTION(" mail_newbody failed..."); + err = EMF_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + if (!em_core_get_temp_file_name(&fname, &err)) { + EM_DEBUG_EXCEPTION(" em_core_get_temp_file_name failed [%d]", err); + goto FINISH_OFF; + } + + if (!(fp = fopen(fname, "wb+"))) { + EM_DEBUG_EXCEPTION(" fopen failed - %s", fname); + err = EMF_ERROR_SYSTEM_FAILURE; /* EMF_ERROR_UNKNOWN; */ + goto FINISH_OFF; + } + + if (!envelope->from || !envelope->from->mailbox || !envelope->from->host) { + if (!envelope->from) + EM_DEBUG_EXCEPTION(" envelope->from[%p]", envelope->from); + else + EM_DEBUG_LOG(" envelope->from->mailbox[%p], envelope->from->host[%p]", envelope->from->mailbox, envelope->from->host); + + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + if (envelope->from->personal) + SNPRINTF(buf, sizeof(buf), "%s <%s@%s>", envelope->from->personal, envelope->from->mailbox, envelope->from->host); + else + SNPRINTF(buf, sizeof(buf), "%s@%s", envelope->from->mailbox, envelope->from->host); + + fprintf(fp, "Your message has been read by %s"CRLF_STRING, buf); + fprintf(fp, "Date : %s", envelope->date); + + fclose(fp); fp = NULL; + + if (!em_core_get_file_size(fname, &sz, &err)) { + EM_DEBUG_EXCEPTION(" em_core_get_file_size failed [%d]", err); + goto FINISH_OFF; + } + + text_body->type = TYPETEXT; + text_body->encoding = ENC8BIT; + text_body->sparep = fname; + text_body->size.bytes = (unsigned long)sz; + + if (!em_core_get_temp_file_name(&fname, &err)) { + EM_DEBUG_EXCEPTION(" em_core_get_temp_file_name failed [%d]", err); + goto FINISH_OFF; + } + + if (!(fp = fopen(fname, "wb+"))) { + EM_DEBUG_EXCEPTION(" fopen failed - %s", fname); + err = EMF_ERROR_SYSTEM_FAILURE; /* EMF_ERROR_UNKNOWN; */ + goto FINISH_OFF; + } + + if (!envelope->references) { + EM_DEBUG_EXCEPTION(" envelope->references[%p]", envelope->references); + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + fprintf(fp, "Final-Recipient : rfc822;%s@%s\r", envelope->from->mailbox, envelope->from->host); + fprintf(fp, "Original-Message-ID: %s\r", envelope->references); + fprintf(fp, "Disposition : manual-action/MDN-sent-manually; displayed"); + + fclose(fp); fp = NULL; + + memset(&atch, 0x00, sizeof(atch)); + + atch.savename = fname; + + if (!em_core_get_file_size(fname, &atch.size, &err)) { + EM_DEBUG_EXCEPTION(" em_core_get_file_size failed [%d]", err); + goto FINISH_OFF; + } + + if (!attach_attachment_to_body(&m_body, text_body, &atch, &err)) { + EM_DEBUG_EXCEPTION(" attach_attachment_to_body failed [%d]", err); + goto FINISH_OFF; + } + + text_body->contents.text.data = NULL; + + /* change mail header */ + + /* set content-type to multipart/report */ + m_body->subtype = EM_SAFE_STRDUP("report"); + + /* set report-type parameter in content-type */ + param = em_core_malloc(sizeof(PARAMETER)); + if (!param) { + EM_DEBUG_EXCEPTION(" malloc failed..."); + err = EMF_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + param->attribute = EM_SAFE_STRDUP("report-type"); + param->value = EM_SAFE_STRDUP("disposition-notification"); + param->next = m_body->parameter; + + m_body->parameter = param; + + /* change body-header */ + + p_body = &m_body->nested.part->next->body; + + /* set content-type to message/disposition-notification */ + p_body->type = TYPEMESSAGE; + p_body->encoding = ENC7BIT; + + EM_SAFE_FREE(p_body->subtype); + + p_body->subtype = EM_SAFE_STRDUP("disposition-notification"); + + /* set parameter */ + mail_free_body_parameter(&p_body->parameter); + mail_free_body_parameter(&p_body->disposition.parameter); + + EM_SAFE_FREE(p_body->disposition.type); + + p_body->disposition.type = EM_SAFE_STRDUP("inline"); + + ret = true; + +FINISH_OFF: + if ((ret == true) && (multipart_body != NULL)) + *multipart_body = m_body; + else if (m_body != NULL) + mail_free_body(&m_body); + + if (text_body != NULL) + mail_free_body(&text_body); + + if (fp != NULL) + fclose(fp); + + EM_SAFE_FREE(fname); + + if (err_code != NULL) + *err_code = err; + + return ret; +} + +EXPORT_API int em_core_get_body_buff(char *file_path, char **buff) +{ + EM_DEBUG_FUNC_BEGIN(); + + FILE *r_fp = NULL; + int read_size = 0; + int ret = false; + char *read_buff = NULL; + + + if (file_path) + r_fp = fopen(file_path, "r"); + + if (!r_fp) { + EM_DEBUG_EXCEPTION(" Filename %s failed to open", file_path); + goto FINISH_OFF; + } + + + struct stat stbuf; + stat(file_path, &stbuf); + EM_DEBUG_LOG(" File Size [ %d ] ", stbuf.st_size); + read_buff = calloc(1, (stbuf.st_size+ 1)); + read_size = fread(read_buff, 1, stbuf.st_size, r_fp); + read_buff[stbuf.st_size] = '\0'; + + if (ferror(r_fp)) { + EM_DEBUG_EXCEPTION("file read failed - %s", file_path); + EM_SAFE_FREE(read_buff); + goto FINISH_OFF; + } + + + ret = true; + *buff = read_buff; + + FINISH_OFF: + if (r_fp) /* Prevent Defect - 17424 */ + fclose(r_fp); + + return ret; +} + +EXPORT_API int em_core_mail_get_envelope_body_struct(emf_mail_t *mail, + ENVELOPE **env, + BODY **text_body, + BODY **multipart_body, + int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("mail[%p], env[%p], text_body[%p], multipart_body[%p], err_code[%p]", mail, env, text_body, multipart_body, err_code); + + int ret = false; + int error = EMF_ERROR_NONE; + ENVELOPE *envelope = NULL; + BODY *txt_body = NULL; + BODY *multi_part_body = NULL; + emf_extra_flag_t extra_flag; + int is_incomplete = 0; + emf_account_t *ref_account = NULL; + char *pAdd = NULL ; + + if (!mail || !mail->info || !mail->head || !mail->body) { + EM_DEBUG_EXCEPTION("EMF_ERROR_INVALID_PARAM"); + error = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + ref_account = em_core_get_account_reference(mail->info->account_id); + + if (!ref_account) { + EM_DEBUG_EXCEPTION(" em_core_get_account_reference failed [%d]", mail->info->account_id); + error = EMF_ERROR_INVALID_ACCOUNT; + goto FINISH_OFF; + } + + if (!(envelope = mail_newenvelope())) { + EM_DEBUG_EXCEPTION(" mail_newenvelope failed..."); + error = EMF_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + EM_DEBUG_LOG(" mail_newenvelope created..."); + is_incomplete = mail->info->flags.draft || mail->info->extra_flags.status == EMF_MAIL_STATUS_SENDING;/* 4; */ + if (is_incomplete) { + if (ref_account->email_addr) { + char *p = EM_SAFE_STRDUP(ref_account->email_addr); + + envelope->from = rfc822_parse_mailbox(&p, NULL); + /* mailbox = user id; host = mail-server-addr; */ + if (!envelope->from) { + EM_DEBUG_EXCEPTION("rfc822_parse_mailbox failed..."); + error = EMF_ERROR_INVALID_ADDRESS; + goto FINISH_OFF; + } + else { + envelope->from->personal = ref_account->display_name ? cpystr(ref_account->display_name) : NULL; + } + } + + if (ref_account->return_addr) { + char *p = EM_SAFE_STRDUP(ref_account->return_addr); + envelope->return_path = rfc822_parse_mailbox(&p, NULL); + } + } + else { + if (!mail->head->from || !mail->head->to) { + EM_DEBUG_EXCEPTION(" mail->head->from[%p], mail->head->to[%p]", mail->head->from, mail->head->to); + error = EMF_ERROR_INVALID_MAIL; + goto FINISH_OFF; + } + + em_core_skip_whitespace(mail->head->from , &pAdd); + EM_DEBUG_LOG("address[pAdd][%s]", pAdd); + + rfc822_parse_adrlist(&envelope->from, pAdd, ref_account->sending_server_addr); + EM_SAFE_FREE(pAdd); + pAdd = NULL ; + + em_core_skip_whitespace(mail->head->return_path , &pAdd); + EM_DEBUG_LOG("address[pAdd][%s]", pAdd); + rfc822_parse_adrlist(&envelope->return_path, pAdd, ref_account->sending_server_addr); + EM_SAFE_FREE(pAdd); + pAdd = NULL ; + } + + { + int i, j; + + if (mail->head->to) { + for (i = 0, j = strlen(mail->head->to); i < j; i++) { + if (mail->head->to[i] == ';') + mail->head->to[i] = ','; + } + } + + if (mail->head->cc) { + for (i = 0, j = strlen(mail->head->cc); i < j; i++) { + if (mail->head->cc[i] == ';') + mail->head->cc[i] = ','; + } + } + + if (mail->head->bcc) { + for (i = 0, j = strlen(mail->head->bcc); i < j; i++) { + if (mail->head->bcc[i] == ';') + mail->head->bcc[i] = ','; + } + } + } + + em_core_skip_whitespace(mail->head->to , &pAdd); + EM_DEBUG_LOG("address[pAdd][%s]", pAdd); + + rfc822_parse_adrlist(&envelope->to, pAdd, ref_account->sending_server_addr); + EM_SAFE_FREE(pAdd); + pAdd = NULL ; + + em_core_skip_whitespace(mail->head->cc , &pAdd); + + rfc822_parse_adrlist(&envelope->cc, pAdd, ref_account->sending_server_addr); + EM_SAFE_FREE(pAdd); + pAdd = NULL ; + + em_core_skip_whitespace(mail->head->bcc , &pAdd); + EM_DEBUG_LOG("address[pAdd][%s]", pAdd); + rfc822_parse_adrlist(&envelope->bcc, pAdd, ref_account->sending_server_addr); + EM_SAFE_FREE(pAdd); + pAdd = NULL ; + em_core_encode_rfc2047_address(envelope->return_path, &error); + em_core_encode_rfc2047_address(envelope->from, &error); + em_core_encode_rfc2047_address(envelope->sender, &error); + em_core_encode_rfc2047_address(envelope->reply_to, &error); + em_core_encode_rfc2047_address(envelope->to, &error); + em_core_encode_rfc2047_address(envelope->cc, &error); + em_core_encode_rfc2047_address(envelope->bcc, &error); + + + if (mail->head->subject) + envelope->subject = em_core_encode_rfc2047_text(mail->head->subject, &error); + + char date_str[DATE_STR_LENGTH] = { 0, }; + + rfc822_date(date_str); + + if (!is_incomplete) { + struct tm tm1; + + /* modified by stonyroot - prevent issue */ + memset(&tm1, 0x00, sizeof(tm1)); + + tm1.tm_year = mail->head->datetime.year - 1900; + tm1.tm_mon = mail->head->datetime.month - 1; + tm1.tm_mday = mail->head->datetime.day; + tm1.tm_hour = mail->head->datetime.hour; + tm1.tm_min = mail->head->datetime.minute; + tm1.tm_sec = mail->head->datetime.second; + + /* tzset(); */ + time_t t = mktime(&tm1); + + char buf[256] = {0x00, }; + + if (localtime(&t)) + strftime(buf, 128, "%a, %e %b %Y %H : %M : %S ", localtime(&t)); + else + strftime(buf, 128, "%a, %e %b %Y %H : %M : %S ", (const struct tm *)&tm1); + + /* append last 5byes("+0900") */ + strncat(buf, date_str + (strlen(date_str) - 5), sizeof(buf) - 1); + strncpy(date_str, buf, DATE_STR_LENGTH - 1); + } + + envelope->date = (unsigned char *)cpystr((const char *)date_str); + + memcpy(&extra_flag, &mail->info->extra_flags, sizeof(emf_extra_flag_t)); + + /* check report mail */ + if (mail->info->extra_flags.report != EMF_MAIL_REPORT_MDN) { + txt_body = mail_newbody(); + if (txt_body == NULL) { + EM_DEBUG_EXCEPTION(" mail_newbody failed..."); + + error = EMF_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + txt_body->type = TYPETEXT; + txt_body->encoding = ENC8BIT; + if (mail->body && mail->body->plain) { + if (mail->body->plain) + txt_body->sparep = EM_SAFE_STRDUP(mail->body->plain); + else + txt_body->sparep = NULL; + + txt_body->size.bytes = (int)strlen(mail->body->plain); + } + + if (mail->body) { + if (mail->body->attachment) { + if (!attach_attachment_to_body(&multi_part_body, txt_body, mail->body->attachment, &error)) { + EM_DEBUG_EXCEPTION("attach_attachment_to_body failed [%d]", error); + goto FINISH_OFF; + } + } + } + } + else { /* Report mail */ + if (mail->head || mail->head->mid) + envelope->references = cpystr(mail->head->mid); + if (em_core_mail_get_report_body(envelope, &multi_part_body, &error)) { + if (!mail->body) { + mail->body = em_core_malloc(sizeof(emf_mail_body_t)); + if (!mail->body) { + EM_DEBUG_EXCEPTION("malloc failed..."); + + error = EMF_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + mail->body->plain = EM_SAFE_STRDUP(multi_part_body->nested.part->body.sparep); + mail->body->attachment_num = 1; + + mail->body->attachment = em_core_malloc(sizeof(emf_attachment_info_t)); + if (!mail->body->attachment) { + EM_DEBUG_EXCEPTION("malloc failed..."); + + EM_SAFE_FREE(mail->body->plain); + error = EMF_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + mail->body->attachment->downloaded = 1; + mail->body->attachment->savename = EM_SAFE_STRDUP(multi_part_body->nested.part->next->body.sparep); + + char *p = NULL; + if (!em_core_get_file_name(mail->body->attachment->savename, &p, &error)) { + EM_DEBUG_EXCEPTION("em_core_get_file_name failed [%d]", error); + + goto FINISH_OFF; + } + + mail->body->attachment->name = cpystr(p); + } + } + } + ret = true; + +FINISH_OFF: + if (ret == true) { + if (env != NULL) + *env = envelope; + if (txt_body != NULL) + *text_body = txt_body; + if (multi_part_body != NULL) + *multipart_body = multi_part_body; + } + else { + if (envelope != NULL) + mail_free_envelope(&envelope); + if (txt_body != NULL) + mail_free_body(&txt_body); + if (multi_part_body != NULL) + mail_free_body(&multi_part_body); + } + + if (err_code != NULL) + *err_code = error; + return ret; +} diff --git a/email-core/em-core-sound.c b/email-core/em-core-sound.c new file mode 100755 index 0000000..5bd2553 --- /dev/null +++ b/email-core/em-core-sound.c @@ -0,0 +1,759 @@ +/* +* email-service +* +* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. +* +* Contact: Kyuho Jo <kyuho.jo@samsung.com>, Sunghyun Kwon <sh0701.kwon@samsung.com> +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + + +#include <stdlib.h> +#include "emf-dbglog.h" +#include "em-storage.h" +#include "em-core-mailbox.h" +#include "em-core-sound.h" + +static MMHandleType email_mmhandle = MM_PLAYER_STATE_NONE; +static alarm_id_t email_alarm_id = 0; +static int email_vibe_handle = 0; + +static char *filename; +alarm_entry_t *alarm_info = NULL; + +#ifdef __FEATURE_USE_PTHREAD__ +static pthread_mutex_t sound_mutex = PTHREAD_MUTEX_INITIALIZER; +static pthread_cond_t sound_condition = PTHREAD_COND_INITIALIZER; +static pthread_mutex_t mmhandle_mutex = PTHREAD_MUTEX_INITIALIZER; +static thread_t g_alert_thread; +#else /* _USE_PTHREAD */ +static GMutex *_sound_event_available_lock = NULL; +static GCond *_sound_event_available_signal = NULL; +static pthread_mutex_t mmhandle_mutex = NULL; +static thread_t g_alert_thread; +#endif /* _USE_PTHREAD */ + +int em_core_alert_sound_init() +{ + int ret = MM_ERROR_NONE; + if ((ret = mm_session_init(MM_SESSION_TYPE_NOTIFY)) != MM_ERROR_NONE) + EM_DEBUG_EXCEPTION("mm_session_int failed"); + + return ret; +} + +int em_core_alert_alarm_init() +{ + int ret = ALARMMGR_RESULT_SUCCESS; + + ret = alarmmgr_init("email-service-0"); + if (ret != 0) + EM_DEBUG_EXCEPTION("alarmmgr_init failed : [%d]", ret); + + return ret; +} + +int em_core_alert_sound_filepath_init() +{ + filename = (char *)em_core_malloc(MAX_LENGTH); + if (filename == NULL) { + EM_DEBUG_EXCEPTION("Memory malloc error"); + return false; + } + + memset(filename, 0, MAX_LENGTH); + + return true; +} +int em_core_alert_vibe_init() +{ + email_vibe_handle = device_haptic_open(DEV_IDX_0, 0); + if (!email_vibe_handle) { + EM_DEBUG_EXCEPTION("device_haptic_open failed"); + return false; + } + + return true; +} + +void em_core_noti_key_changed_cb(keynode_t *key_node, void *data) +{ + int ret = 0; + + switch (vconf_keynode_get_type(key_node)) { + case VCONF_TYPE_INT: + ret = alarmmgr_remove_alarm(email_alarm_id); + if (ret != ALARMMGR_RESULT_SUCCESS) { + EM_DEBUG_EXCEPTION("delete of alarm id failed"); + } + em_core_set_repetition_alarm(vconf_keynode_get_int(key_node)); + break; + case VCONF_TYPE_STRING: + filename = vconf_keynode_get_str(key_node); + break; + default: + EM_DEBUG_EXCEPTION("Invalid key type"); + break; + } + return; +} + +bool em_core_noti_init(void *data) +{ + struct appdata *ap = data; + + if (vconf_notify_key_changed(VCONFKEY_SETAPPL_NOTI_EMAIL_ALERT_REP_TYPE_INT, em_core_noti_key_changed_cb, ap) < 0) { + EM_DEBUG_EXCEPTION("Register failed : alert type"); + return false; + } + + if (vconf_notify_key_changed(VCONFKEY_SETAPPL_NOTI_EMAIL_RINGTONE_PATH_STR, em_core_noti_key_changed_cb, ap) < 0) { + EM_DEBUG_EXCEPTION("Register failed : Ringtone path"); + return false; + } + + return true; +} + +int em_core_alert_init() +{ + EM_DEBUG_FUNC_BEGIN(); + + int err = 0; + + if (!em_core_alert_sound_filepath_init()) { + EM_DEBUG_EXCEPTION("em_core_alert_sound_filepath_init failed"); + return false; + } + + if ((err = em_core_alert_sound_init()) != MM_ERROR_NONE) { + EM_DEBUG_EXCEPTION("em_core_alert_sound_init failed : [%d]", err); + return false; + } + + if ((err = em_core_alert_alarm_init()) != ALARMMGR_RESULT_SUCCESS) { + EM_DEBUG_EXCEPTION("em_core_alert_alarm_init failed : [%d]", err); + return false; + } + + if (!em_core_alert_vibe_init()) { + EM_DEBUG_EXCEPTION("em_core_alert_vibe_init failed"); + return false; + } + + if (!em_core_noti_init(NULL)) { + EM_DEBUG_EXCEPTION("em_core_noti_init failed"); + return false; + } + + EM_DEBUG_FUNC_END(); + return true; +} + +bool em_core_set_mp_filepath(const char *key) +{ + filename = vconf_get_str(key); + if (filename == NULL) + return false; + + return true; +} + +int em_core_mp_player_state_cb(int message, void *param, void *user_param) +{ + switch (message) + { + case MM_MESSAGE_ERROR: + EM_DEBUG_LOG("Error is happened."); + if (email_mmhandle) { + em_core_sound_mp_player_destory(); + } + break; + case MM_MESSAGE_BEGIN_OF_STREAM: + EM_DEBUG_LOG("Play is started."); + break; + case MM_MESSAGE_END_OF_STREAM: + EM_DEBUG_LOG("End of stream."); + ENTER_CRITICAL_SECTION(mmhandle_mutex); + if (email_mmhandle) + { + em_core_sound_mp_player_stop(); + em_core_sound_mp_player_destory(); + } + LEAVE_CRITICAL_SECTION(mmhandle_mutex); + break; + default: + EM_DEBUG_LOG("Message = %d", message); + break; + } + return 1; +} + +bool em_core_sound_mp_player_create() +{ + EM_DEBUG_FUNC_BEGIN(); + int err = 0; + + if ((err = mm_player_create(&email_mmhandle)) != MM_ERROR_NONE) { + EM_DEBUG_EXCEPTION("mm_player create fail [%d]", err); + return false; + } + EM_DEBUG_FUNC_END(); + return true; +} + +bool em_core_vibration_create() +{ + EM_DEBUG_FUNC_BEGIN(); + + email_vibe_handle = device_haptic_open(DEV_IDX_0, 0); + + if (email_vibe_handle < 0) { + EM_DEBUG_EXCEPTION("vibration create failed"); + return false; + } + EM_DEBUG_FUNC_END(); + return true; +} + +bool em_core_alarm_create() +{ + EM_DEBUG_FUNC_BEGIN(); + + alarm_info = alarmmgr_create_alarm(); + + if (alarm_info == NULL) { + EM_DEBUG_EXCEPTION("alarm create failed"); + return false; + } + + EM_DEBUG_FUNC_END(); + return true; +} + +bool em_core_alarm_destory() +{ + EM_DEBUG_FUNC_BEGIN(); + + int ret; + ret = alarmmgr_free_alarm(alarm_info); + + if (ret != ALARMMGR_RESULT_SUCCESS) { + EM_DEBUG_EXCEPTION("alarm free failed"); + return false; + } + + EM_DEBUG_FUNC_END(); + return true; +} + +bool em_core_alert_create() +{ + EM_DEBUG_FUNC_BEGIN(); + + /* Create the alarm handle */ + if (!em_core_alarm_create()) { + EM_DEBUG_EXCEPTION("em_core_alarm_create failed."); + return false; + } + + /* Set the music file in alert */ + if (!em_core_set_mp_filepath(VCONFKEY_SETAPPL_NOTI_EMAIL_RINGTONE_PATH_STR)) + if (!em_core_set_mp_filepath(VCONFKEY_SETAPPL_DEFAULT_NOTI_EMAIL_RINGTONE_PATH_STR)) { + EM_DEBUG_EXCEPTION("em_core_set_mp_filepath failed."); + return false; + } + + EM_DEBUG_FUNC_END(); + return true; +} + +bool em_core_alert_destory() +{ + EM_DEBUG_FUNC_BEGIN(); + int ret = 0; + + /* Destroy the music player handle */ + if (!em_core_sound_mp_player_destory()) { + EM_DEBUG_EXCEPTION("em_core_sound_mp_player_destory fail"); + return false; + } + + /* Destroy the vibration handle */ + if (!em_core_vibration_destory()) { + EM_DEBUG_EXCEPTION("em_core_vibration_destory fail"); + return false; + } + + /* Destroy the alarm handle */ + ret = alarmmgr_free_alarm(alarm_info); + if (ret != ALARMMGR_RESULT_SUCCESS) { + EM_DEBUG_EXCEPTION("alarmmgr_free_alarm fail"); + return false; + } + + /* Set the music file in alert */ + EM_SAFE_FREE(filename); + + EM_DEBUG_FUNC_END(); + return true; +} + +gboolean mp_player_timeout_cb(void *data) +{ + EM_DEBUG_FUNC_BEGIN(); + + ENTER_CRITICAL_SECTION(mmhandle_mutex); + if (email_mmhandle == MM_PLAYER_STATE_PLAYING) + { + em_core_sound_mp_player_stop(); + em_core_sound_mp_player_destory(); + } + LEAVE_CRITICAL_SECTION(mmhandle_mutex); + + EM_DEBUG_FUNC_END(); + return false; +} + +gboolean vibration_timeout_cb(void *data) +{ + EM_DEBUG_FUNC_BEGIN(); + + em_core_vibration_stop(); + em_core_vibration_destory(); + + EM_DEBUG_FUNC_END(); + return false; +} + +bool em_core_vibration_start(int haptic_level) +{ + EM_DEBUG_FUNC_BEGIN(); + int ret = 0; + int vibPattern = EFFCTVIBE_NOTIFICATION; + + if (haptic_level == 0) { + EM_DEBUG_LOG("The level of haptic is zero"); + return true; + } + + ret = device_haptic_play_pattern(email_vibe_handle, vibPattern, HAPTIC_TEST_ITERATION, haptic_level); + + if (ret != 0) { + EM_DEBUG_EXCEPTION("Fail to play haptic : [%d]", ret); + return false; + } + + if ((ret = g_timeout_add(TIMER, (GSourceFunc) vibration_timeout_cb, NULL) <= 0)) + { + EM_DEBUG_EXCEPTION("play_alert - Failed to start timer [%d]", ret); + return false; + } + + EM_DEBUG_FUNC_END(); + return true; +} + +int em_core_vibration_stop() +{ + int err = MM_ERROR_NONE; + if ((err = device_haptic_stop_play(email_vibe_handle)) != 0) + EM_DEBUG_EXCEPTION("Fail to stop haptic : [%d]", err); + + return err; +} + +int em_core_vibration_destory() +{ + int err = MM_ERROR_NONE; + if ((err = device_haptic_close(email_vibe_handle)) != 0) + EM_DEBUG_EXCEPTION("Fail to close haptic : [%d]", err); + + return err; +} +int em_core_sound_mp_player_start(char *filepath) +{ + EM_DEBUG_FUNC_BEGIN(); + + int err = MM_ERROR_NONE; + +/* + int volume = -1; + + + if ((err = vconf_get_int(VCONFKEY_SETAPPL_NOTI_SOUND_VOLUME_INT, &volume)) == -1) + { + EM_DEBUG_LOG("vconf_get_int failed \n"); + return err; + } +*/ + mm_player_set_message_callback(email_mmhandle, em_core_mp_player_state_cb, (void *)email_mmhandle); + + EM_DEBUG_LOG("Before mm_player_set_attribute filepath = %s", filepath); + if ((err = mm_player_set_attribute(email_mmhandle, NULL, "sound_volume_type", MM_SOUND_VOLUME_TYPE_NOTIFICATION, "profile_uri", filepath, strlen(filepath), NULL)) != MM_ERROR_NONE) + { + EM_DEBUG_EXCEPTION("mm_player_set_attribute faile [ %d ] ", err); + return err; + } + + EM_DEBUG_LOG("After mm_player_set_attribute"); + + if ((err = mm_player_realize(email_mmhandle)) != MM_ERROR_NONE) + { + EM_DEBUG_EXCEPTION("mm_player_realize fail [%d]", err); + return err; + } + + if ((err = mm_player_start(email_mmhandle)) != MM_ERROR_NONE) + { + EM_DEBUG_EXCEPTION("mm_player_start fail [%d]", err); + return err; + } + + if ((err = g_timeout_add(TIMER, (GSourceFunc)mp_player_timeout_cb, NULL) <= 0)) + { + EM_DEBUG_EXCEPTION("g_timeout_add - Failed to start timer"); + return err; + } + + EM_DEBUG_FUNC_END(); + return err; +} + +int em_core_sound_mp_player_stop() +{ + EM_DEBUG_FUNC_BEGIN(); + + int err = MM_ERROR_NONE; + + if ((err = mm_player_stop(email_mmhandle)) != MM_ERROR_NONE) + { + EM_DEBUG_EXCEPTION("mm_player_stop fail [%d]", err); + return err; + } + + if ((err = mm_player_unrealize(email_mmhandle)) != MM_ERROR_NONE) + { + EM_DEBUG_EXCEPTION("mm_player_unrealize [%d]", err); + return err; + } + + EM_DEBUG_FUNC_END(); + return err; +} + +bool em_core_sound_mp_player_destory() +{ + EM_DEBUG_FUNC_BEGIN(); + + int err = MM_ERROR_NONE; + + if ((err = mm_player_destroy(email_mmhandle)) != MM_ERROR_NONE) { + EM_DEBUG_EXCEPTION("mm_player_destory [%d]", err); + return false; + } + + EM_DEBUG_FUNC_END(); + return true; +} + +int get_vconf_data(int key, int *return_value) +{ + EM_DEBUG_FUNC_BEGIN(); + int err = -1, value = 0; + + switch (key) + { + case EMAIL_SOUND_STATUS: + err = vconf_get_bool(VCONFKEY_SETAPPL_SOUND_STATUS_BOOL, &value); + EM_DEBUG_LOG("EMAIL_SOUND_STATUS[%d]", value); + break; + case EMAIL_VIBE_STATUS: + err = vconf_get_bool(VCONFKEY_SETAPPL_VIBRATION_STATUS_BOOL, &value); + EM_DEBUG_LOG("EMAIL_VIBRATION_STATUS[%d]", value); + break; + case EMAIL_ALERT_REP_TYPE: + err = vconf_get_int(VCONFKEY_SETAPPL_NOTI_EMAIL_ALERT_REP_TYPE_INT, &value); + EM_DEBUG_LOG("EMAIL_ALERT_REP_TYPE[%d]", value); + break; + case EMAIL_ALERT_VOLUME: + err = vconf_get_int(VCONFKEY_SETAPPL_NOTI_SOUND_VOLUME_INT, &value); + EM_DEBUG_LOG("EMAIL_ALERT_VOLUME[%d]", value); + break; + case EMAIL_ALERT_VIBE_STENGTH: + err = vconf_get_int(VCONFKEY_SETAPPL_NOTI_VIBRATION_LEVEL_INT, &value); + EM_DEBUG_LOG("EMAIL_ALERT_VIBE_STENGTH[%d]", value); + break; + default: + { + EM_DEBUG_LOG("Uuknown request\n"); + return false; + } + } + + if (err == -1) + { + EM_DEBUG_LOG("Vconf_get_int failed\n"); + return false; + } + + *return_value = value; + EM_DEBUG_FUNC_END(); + return true; +} + +int em_core_get_alert_type() +{ + EM_DEBUG_FUNC_BEGIN(); + int sound_status = 0, vibe_status = 0; + int err; + int alert_type = -1; + + if (!(err = get_vconf_data(EMAIL_SOUND_STATUS, &sound_status))) + { + EM_DEBUG_EXCEPTION("Don't get sound status"); + return err; + } + + if (!(err = get_vconf_data(EMAIL_VIBE_STATUS, &vibe_status))) + { + EM_DEBUG_EXCEPTION("Don't get vibration status"); + return err; + } + + if (sound_status && vibe_status) + alert_type = EMAIL_ALERT_TYPE_MELODY_AND_VIB; + else if (sound_status) + alert_type = EMAIL_ALERT_TYPE_MELODY; + else if (vibe_status) + alert_type = EMAIL_ALERT_TYPE_VIB; + else + alert_type = EMAIL_ALERT_TYPE_MUTE; + + return alert_type; +} + + +EXPORT_API int em_core_alert_loop_start(int *err_code) +{ + EM_DEBUG_FUNC_BEGIN(); + + int thread_error; + + if (err_code != NULL) + *err_code = EMF_ERROR_NONE; + + if (g_alert_thread) + { + EM_DEBUG_EXCEPTION("Alert service is already running..."); + if (err_code != NULL) + *err_code = EMF_ERROR_UNKNOWN; + + return 1; + } + + THREAD_CREATE(g_alert_thread, start_alert_thread, NULL, thread_error); + if (thread_error != 0) + { + EM_DEBUG_EXCEPTION("Cannot create alert thread"); + if (err_code != NULL) + *err_code = EMF_ERROR_SYSTEM_FAILURE; + + return -1; + } + + if (err_code != NULL) + *err_code = EMF_ERROR_NONE; + + return 0; +} + +int em_core_alarm_timeout_cb(int timer_id, void *user_parm) +{ + EM_DEBUG_FUNC_BEGIN(); + + int err = EMF_ERROR_NONE; + int total_unread_count = 0; + int total_mail_count = 0; + emf_mailbox_t mailbox; + + memset(&mailbox, 0x00, sizeof(emf_mailbox_t)); + + mailbox.account_id = ALL_ACCOUNT; + mailbox.name = NULL; + + if (!em_core_mailbox_get_mail_count(&mailbox, &total_mail_count, &total_unread_count, &err)) { + EM_DEBUG_EXCEPTION("em_core_mailbox_get_mail_count failed - %d\n", err); + return false; + } + + EM_DEBUG_LOG(">>>> total_unread_count : [%d]\n", total_unread_count); + + if (total_unread_count) { + start_alert(); + } + + EM_DEBUG_FUNC_END(); + return true; +} + +bool set_alarm(int repetition_time) +{ + EM_DEBUG_FUNC_BEGIN(); + + int ret = 0; + alarm_date_t alarm_date; + time_t current_time; + struct tm current_tm; + + time(¤t_time); + localtime_r(¤t_time, ¤t_tm); + + alarm_date.year = 0; + alarm_date.month = 0; + alarm_date.day = 0; + + EM_DEBUG_LOG("Current time : [%d]-[%d]-[%d]", current_tm.tm_hour, current_tm.tm_min, current_tm.tm_sec); + + if (current_tm.tm_min + repetition_time < 60) { + alarm_date.hour = current_tm.tm_hour; + alarm_date.min = current_tm.tm_min + repetition_time; + } else { + if (current_tm.tm_hour < 12) { + alarm_date.hour = current_tm.tm_hour + 1; + } else { + alarm_date.hour = (current_tm.tm_hour + 1) % 12; + } + + alarm_date.min = (current_tm.tm_min + repetition_time) % 60; + } + + alarm_date.sec = current_tm.tm_sec; + + alarmmgr_set_time(alarm_info, alarm_date); + alarmmgr_set_repeat_mode(alarm_info, ALARM_REPEAT_MODE_ONCE, 0); + alarmmgr_set_type(alarm_info, ALARM_TYPE_VOLATILE); + alarmmgr_add_alarm_with_localtime(alarm_info, NULL, &email_alarm_id); + + ret = alarmmgr_set_cb(em_core_alarm_timeout_cb, NULL); + + if (ret != 0) { + EM_DEBUG_EXCEPTION("Failed : alarmmgr_set_cb() -> error[%d]", ret); + return false; + } + + EM_DEBUG_LOG("Alarm time : [%d]-[%d]-[%d]-[%d]-[%d]-[%d]", alarm_date.year, alarm_date.month, alarm_date.day, alarm_date.hour, alarm_date.min, alarm_date.sec); + EM_DEBUG_FUNC_END(); + return true; +} + +void em_core_set_repetition_alarm(int repetition) +{ + EM_DEBUG_FUNC_BEGIN(); + + int repetition_time = 0; + + switch (repetition) { + case EMAIL_GCONF_VALUE_REPEAT_NONE: + repetition_time = 0; + break; + case EMAIL_GCONF_VALUE_REPEAT_2MINS: + repetition_time = 2; + break; + case EMAIL_GCONF_VALUE_REPEAT_5MINS: + repetition_time = 5; + break; + case EMAIL_GCONF_VALUE_REPEAT_10MINS: + repetition_time = 10; + break; + default: + EM_DEBUG_EXCEPTION("Invalid repetition time"); + return; + } + + EM_DEBUG_LOG("repetition time is %d", repetition_time); + + if (repetition_time > 0) { + set_alarm(repetition_time); + } + + EM_DEBUG_FUNC_END(); +} + +void *start_alert_thread(void *arg) +{ + EM_DEBUG_FUNC_END(); + + int err = 0; + int level = 0; + + if (!em_core_alert_init()) + { + EM_DEBUG_EXCEPTION("Error : em_core_alert_init failed"); + return 0; + } + + + while (1) { + if (!em_core_alert_create()) { + EM_DEBUG_EXCEPTION("Error : em_core_alert_create failed"); + return 0; + } + + err = get_vconf_data(EMAIL_ALERT_REP_TYPE, &level); + em_core_set_repetition_alarm(level); + + ENTER_CRITICAL_SECTION(sound_mutex); + SLEEP_CONDITION_VARIABLE(sound_condition , sound_mutex); + + err = get_vconf_data(EMAIL_ALERT_VIBE_STENGTH, &level); + + switch (em_core_get_alert_type()) + { + case EMAIL_ALERT_TYPE_MELODY: + em_core_sound_mp_player_create(); + em_core_sound_mp_player_start(filename); + break; + case EMAIL_ALERT_TYPE_VIB: + em_core_vibration_create(); + em_core_vibration_start(level); + break; + case EMAIL_ALERT_TYPE_MELODY_AND_VIB: + em_core_vibration_create(); + em_core_vibration_start(level); + em_core_sound_mp_player_create(); + em_core_sound_mp_player_start(filename); + break; + case EMAIL_ALERT_TYPE_MUTE: + EM_DEBUG_LOG("Alert type is mute!!"); + break; + default: + EM_DEBUG_EXCEPTION("alert type is strange"); + em_core_alert_destory(); + break; + } + LEAVE_CRITICAL_SECTION(sound_mutex); + + em_core_alarm_destory(); + } + return 0; +} + +EXPORT_API void start_alert() +{ + ENTER_CRITICAL_SECTION(sound_mutex); + WAKE_CONDITION_VARIABLE(sound_condition); + LEAVE_CRITICAL_SECTION(sound_mutex); +} diff --git a/email-core/em-core-timer.c b/email-core/em-core-timer.c new file mode 100755 index 0000000..add3a4f --- /dev/null +++ b/email-core/em-core-timer.c @@ -0,0 +1,110 @@ +/* +* email-service +* +* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. +* +* Contact: Kyuho Jo <kyuho.jo@samsung.com>, Sunghyun Kwon <sh0701.kwon@samsung.com> +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + + +#include <stdlib.h> +#include <string.h> +#include <sys/time.h> +#include <signal.h> +#include <unistd.h> +#include <stdio.h> +#include <time.h> +#include <errno.h> +#include <sys/signal.h> +/* #include <pthread.h> */ +#include <sys/timeb.h> +#include "em-core-timer.h" +#include "emf-dbglog.h" +#include <dbus/dbus-glib.h> + + +typedef struct +{ + EMF_TIMER_CALLBACK user_callback_function; + void *callback_user_data; + int time_id; +}em_timer_callback_data; + + +EXPORT_API int +em_core_timer_ex_callback(void *a_pData) +{ + EM_DEBUG_LOG("[em_core_timer_ex_callback] enter\n"); + void *pUserData = NULL; + + + g_thread_init(NULL); + dbus_g_thread_init (); + + em_timer_callback_data *pTimerData = (em_timer_callback_data *)a_pData; + if (pTimerData != NULL) + { + EMF_TIMER_CALLBACK pfn_UserCB = pTimerData->user_callback_function; + pUserData = pTimerData->callback_user_data; + if (pUserData) + EM_DEBUG_LOG("em_core_timer_ex_callback >>> data : %s", (char *)pTimerData->callback_user_data); + EM_SAFE_FREE(pTimerData); + pfn_UserCB(pUserData); + } + + + g_thread_init(NULL); + dbus_g_thread_init (); + + EM_DEBUG_LOG("[em_core_timer_ex_callback] leave\n"); + + if (pUserData) + return 0; + else + return 1; +} + + + +EXPORT_API int +em_core_set_timer_ex(long a_nSetTimeValue, EMF_TIMER_CALLBACK a_pCallBack, void *a_pData) +{ + EM_DEBUG_LOG("em_core_set_timer_ex %d", a_nSetTimeValue); + em_timer_callback_data *pTimerData = NULL; + pTimerData = malloc(sizeof(em_timer_callback_data)); + char *data = NULL; + if (!pTimerData) + return -1; + memset(pTimerData, 0x00, sizeof(em_timer_callback_data)); + if (a_pData) + EM_DEBUG_LOG("em_core_set_timer_ex >>> data : %s", (char *)a_pData); + + pTimerData->user_callback_function = a_pCallBack; + if (a_pData) { + data = (char *) a_pData; + pTimerData->callback_user_data = EM_SAFE_STRDUP(data); + } + pTimerData->time_id = g_timeout_add(a_nSetTimeValue, em_core_timer_ex_callback, pTimerData); + return pTimerData->time_id; +} + +EXPORT_API void +em_core_kill_timer_ex(int a_nTimerID) +{ + EM_DEBUG_LOG("[em_core_kill_timer_ex] a_nTimerID %d", a_nTimerID); + g_source_remove(a_nTimerID); +} + diff --git a/email-core/em-core-utils.c b/email-core/em-core-utils.c new file mode 100755 index 0000000..823781e --- /dev/null +++ b/email-core/em-core-utils.c @@ -0,0 +1,3183 @@ +/* +* email-service +* +* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. +* +* Contact: Kyuho Jo <kyuho.jo@samsung.com>, Sunghyun Kwon <sh0701.kwon@samsung.com> +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + + +/****************************************************************************** + * File: em-core-utils.c + * Desc: Mail Utils + * + * Auth: + * + * History: + * 2006.08.16 : created + *****************************************************************************/ +#include <glib.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> +#include <errno.h> +#include <stdio.h> +#include <dlfcn.h> +#include <sys/time.h> +#include <unistd.h> +#include <sys/stat.h> +#include <sys/vfs.h> +#include <vconf.h> +#include <regex.h> +#include <malloc.h> + +#include <contacts-svc.h> +#include <notification.h> + +#include "emf-types.h" +#include "em-core-global.h" +#include "em-core-utils.h" +#include "emf-dbglog.h" +#include "em-core-mesg.h" +#include "em-core-event.h" +#include "em-core-mailbox.h" +#include "em-core-account.h" +#include "em-core-mailbox-sync.h" +#include "em-core-mime.h" +#include "em-core-sound.h" +#include "Msg_Convert.h" + +#define LED_TIMEOUT_SECS 12 +#define G_DISPLAY_LENGTH 256 + +#define DIR_SEPERATOR_CH '/' +#define EMAIL_CH_QUOT '"' +#define EMAIL_CH_BRACKET_S '<' +#define EMAIL_CH_BRACKET_E '>' +#define EMAIL_CH_COMMA ',' +#define EMAIL_CH_SEMICOLON ';' +#define EMAIL_CH_ROUND_BRACKET_S '(' +#define EMAIL_CH_ROUND_BRACKET_E ')' +#define EMAIL_CH_SQUARE_BRACKET_S '[' +#define EMAIL_CH_SQUARE_BRACKET_E ']' +#define EMAIL_CH_SPACE ' ' + +static char _g_display[G_DISPLAY_LENGTH]; + + +typedef struct _em_transaction_info_type_t { + int mail_id; + int handle; + struct _em_transaction_info_type_t *next; + +} em_transaction_info_type_t; + +em_transaction_info_type_t *g_transaction_info_list; + +static emf_option_t g_mail_option = +{ + 0, /* priority */ + 1, /* keep_local_copy */ + 0, /* req_delivery_receipt */ + 0, /* req_read_receipt */ + 0, /* download_limit */ + 0, /* block_address */ + 0, /* block_subject */ + NULL, /* diplay name */ +}; + +static emf_session_t g_session_list[SESSION_MAX] = { {0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0},}; + + +typedef struct em_core_account_list_t em_core_account_list_t; +struct em_core_account_list_t { + emf_account_t *account; + em_core_account_list_t *next; +}; + +static em_core_account_list_t **g_account_reference = NULL; + +EXPORT_API +char *em_core_convert_mutf7_to_utf8(char *mailbox_name) +{ + EM_DEBUG_FUNC_BEGIN(); + return (char *)(utf8_from_mutf7((unsigned char *)mailbox_name)); +} + +EXPORT_API int em_core_set_account_reference(em_core_account_list_t **account_list, int account_num, int *err_code) +{ + g_account_reference = (em_core_account_list_t **)account_list; + return 1; +} + +emf_option_t *em_core_get_option(int *err_code) +{ + if (err_code != NULL) + *err_code = EMF_ERROR_NONE; + + return &g_mail_option; +} + +EXPORT_API int em_core_set_option(emf_option_t *opt, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("opt[%p], err_code[%p]", opt, err_code); + + int err = EMF_ERROR_NONE; + + if (!opt) { + EM_DEBUG_EXCEPTION("opt[%p]", opt); + + if (err_code != NULL) + *err_code = EMF_ERROR_INVALID_PARAM; + return false; + } + + memset(_g_display, 0, G_DISPLAY_LENGTH); + memcpy(&g_mail_option, opt, sizeof(g_mail_option)); + + if (opt->display_name_from && opt->display_name_from[0] != '\0') { + strncpy(_g_display, opt->display_name_from, G_DISPLAY_LENGTH - 1); + g_mail_option.display_name_from = _g_display; + } + else + g_mail_option.display_name_from = NULL; + + if (err_code != NULL) + *err_code = err; + + return true; +} + + + + + +/* in smtp case, path argument must be ENCODED_PATH_SMTP */ +int em_core_get_long_encoded_path_with_account_info(emf_account_t *account, char *path, int delimiter, char **long_enc_path, int *err_code) +{ + EM_PROFILE_BEGIN(emCorelongEncodedpath); + EM_DEBUG_FUNC_BEGIN("account[%p], path[%s], delimiter[%d], long_enc_path[%p], err_code[%p]", account, path, delimiter, long_enc_path, err_code); + + int ret = false; + int error = EMF_ERROR_NONE; + char *p = NULL; + + size_t long_enc_path_len = 0; + + if (path == NULL || (path && strncmp(path, ENCODED_PATH_SMTP, strlen(ENCODED_PATH_SMTP)) != 0)) { /* imap or pop3 */ + EM_DEBUG_LOG("account->receiving_server_addr[%p]", account->receiving_server_addr); + EM_DEBUG_LOG("account->receiving_server_addr[%s]", account->receiving_server_addr); + + if (!account->receiving_server_addr) { + EM_DEBUG_EXCEPTION("account->receiving_server_addr is null"); + error = EMF_ERROR_INVALID_ACCOUNT; + goto FINISH_OFF; + } + + long_enc_path_len = strlen(account->receiving_server_addr) + (path ? strlen(path) : 0) + 64; + + *long_enc_path = em_core_malloc(long_enc_path_len); + if (!*long_enc_path) { + EM_DEBUG_EXCEPTION("malloc failed..."); + error = EMF_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + p = *long_enc_path; + + /* ex:"{mai.test.com:143/imap} or {mai.test.com:143/imap/tls}my-mailbox" */ + + SNPRINTF(p, long_enc_path_len, "{%s:%d/%s/user=%d", + account->receiving_server_addr, + account->port_num, + account->receiving_server_type == EMF_SERVER_TYPE_POP3 ? "pop3" : "imap", account->account_id); + + if (account->use_security & 0x01) { + strncat(p, "/ssl", long_enc_path_len-(strlen(p)+1)); + /* strcat(p, "/tryssl"); */ + } + + /* Currently, receiving servers doesn't require tls. + if (account->use_security & 0x02) + strncat(p, "/tls", long_enc_path_len-(strlen(p)+1)); + else + strncat(p, "/notls", long_enc_path_len-(strlen(p)+1)); + */ + + if (account->apop) { + EM_DEBUG_LOG("em_core_get_long_encoded_path - apop - %d", account->apop); + strncat(p, "/apop", long_enc_path_len-(strlen(p)+1)); + EM_DEBUG_LOG("long_enc_path - %s", p); + } + } + else { /* smtp */ + long_enc_path_len = strlen(account->sending_server_addr) + 64; + + *long_enc_path = em_core_malloc(strlen(account->sending_server_addr) + 64); + if (!*long_enc_path) { + EM_DEBUG_EXCEPTION("\t malloc failed...\n"); + + error = EMF_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + p = *long_enc_path; + + /* ex:"mail.test.com:25/smtp" */ + + SNPRINTF(p, long_enc_path_len, "%s:%d/%s", + account->sending_server_addr, + account->sending_port_num, + "smtp"); + + if (account->sending_auth) { + SNPRINTF(p + strlen(p), long_enc_path_len-(strlen(p)), "/user=%d", account->account_id); + } + + if (account->sending_security & 0x01) { + strncat(p, "/ssl", long_enc_path_len-(strlen(p)+1)); + /* strcat(p, "/tryssl"); */ + } + if (account->sending_security & 0x02) + strncat(p, "/tls", long_enc_path_len-(strlen(p)+1)); + else + strncat(p, "/notls", long_enc_path_len-(strlen(p)+1)); + } + + if (path == NULL || (path && strncmp(path, ENCODED_PATH_SMTP, strlen(ENCODED_PATH_SMTP)) != 0)) { + strncat(p, "}", long_enc_path_len-(strlen(p)+1)); + + if (path != NULL) { + char *enc_name = NULL; + + if (!em_core_get_encoded_mailbox_name(path, &enc_name, &error)) { + EM_DEBUG_EXCEPTION("em_core_get_encoded_mailbox_name failed - %d", error); + *long_enc_path = NULL; + goto FINISH_OFF; + } + + if (enc_name) { + strncat(p, enc_name, long_enc_path_len-(strlen(p)+1)); + EM_SAFE_FREE(enc_name); + } + } + } + + ret = true; + +FINISH_OFF: + if (ret != true) + EM_SAFE_FREE(p); + + if (err_code != NULL) + *err_code = error; + EM_PROFILE_END(emCorelongEncodedpath); + return ret; +} + +int em_core_get_long_encoded_path(int account_id, char *path, int delimiter, char **long_enc_path, int *err_code) +{ + EM_PROFILE_BEGIN(emCorelongEncodedpath); + EM_DEBUG_FUNC_BEGIN("account_id[%d], delimiter[%d], long_enc_path[%p], err_code[%p]", account_id, delimiter, long_enc_path, err_code); + + int ret = false; + int error = EMF_ERROR_NONE; + + emf_account_t *ref_account = em_core_get_account_reference(account_id); + if (!ref_account) { + EM_DEBUG_EXCEPTION("em_core_get_account_reference failed [%d]", account_id); + error = EMF_ERROR_INVALID_ACCOUNT; + goto FINISH_OFF; + } + + if (em_core_get_long_encoded_path_with_account_info(ref_account, path, delimiter, long_enc_path, &error) == false) { + EM_DEBUG_EXCEPTION("em_core_get_long_encoded_path_with_account_info failed [%d]", error); + goto FINISH_OFF; + } + + ret = true; + +FINISH_OFF: + if (err_code != NULL) + *err_code = error; + EM_PROFILE_END(emCorelongEncodedpath); + return ret; +} + +int em_core_upper_path(char *path) +{ + int i = 0, is_utf7 = 0, len = path ? (int)strlen(path) : -1; + for (; i < len; i++) { + if (path[i] == '&' || path[i] == 5) { + is_utf7 = 1; + } + else { + if (is_utf7) { + if (path[i] == '-') is_utf7 = 0; + } + else { + path[i] = toupper(path[i]); + } + } + } + + return 1; +} + +int em_core_get_encoded_mailbox_name(char *name, char **enc_name, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("name[%s], enc_name[%p], err_code[%p]", name, enc_name, err_code); + + if (!name || !enc_name) { + if (err_code != NULL) + *err_code = EMF_ERROR_INVALID_PARAM; + EM_DEBUG_FUNC_END(); + return false; + } + + /* encoding mailbox name (Charset->UTF8->UTF7) */ + + *enc_name = em_core_malloc(strlen(name)+1); + if (*enc_name == NULL) { + EM_DEBUG_EXCEPTION("malloc failed..."); + if (err_code != NULL) + *err_code = EMF_ERROR_OUT_OF_MEMORY; + EM_DEBUG_FUNC_END(); + return false; + } + + strcpy(*enc_name, name); + + if (err_code != NULL) + *err_code = EMF_ERROR_NONE; + + EM_DEBUG_FUNC_END(); + return true; +} + +int em_core_upper_string(char *str) +{ + int i = str ? (int)strlen(str) : -1; + for (; i >= 0; i--) + str[i] = toupper(str[i]); + return 1; +} + +int em_core_get_temp_file_name(char **filename, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("filename[%p], err_code[%p]", filename, err_code); + + int ret = false; + int error = EMF_ERROR_NONE; + + if (filename == NULL) { + EM_DEBUG_EXCEPTION("\t filename[%p]\n", filename); + error = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + char tempname[512] = {0x00, }; + struct timeval tv; + + + gettimeofday(&tv, NULL); + srand(tv.tv_usec); + + /* Create Directory If deleted by user*/ + em_storage_create_dir_if_delete(); + + SNPRINTF(tempname, sizeof(tempname), "%s%c%s%c%d", MAILHOME, DIR_SEPERATOR_CH, MAILTEMP, DIR_SEPERATOR_CH, rand()); + + char *p = EM_SAFE_STRDUP(tempname); + if (p == NULL) { + EM_DEBUG_EXCEPTION("\t strdup failed...\n"); + error = EMF_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + *filename = p; + + ret = true; + +FINISH_OFF: + if (err_code != NULL) + *err_code = error; + EM_DEBUG_FUNC_END(); + return ret; +} + +int em_core_get_file_name(char *path, char **filename, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("path[%s], filename[%p], err_code[%p]", path, filename, err_code); + + int ret = false; + int error = EMF_ERROR_NONE; + + if (!path || !filename) { + EM_DEBUG_EXCEPTION("path[%p], filename[%p]", path, filename); + + error = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + int i = (int)strlen(path); + + /* get filename */ + for (; i >= 0; i--) + if (path[i] == DIR_SEPERATOR_CH) + break; + + *filename = path + i + 1; + + ret = true; + +FINISH_OFF: + if (err_code != NULL) + *err_code = error; + EM_DEBUG_FUNC_END(); + return ret; +} + +int em_core_get_file_size(char *path, int *size, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("path[%s], size[%p], err_code[%p]", path, size, err_code); + + int ret = false; + int error = EMF_ERROR_NONE; + + if ((path == NULL) || (size == NULL)) { + EM_DEBUG_EXCEPTION("\t path[%p], size[%p]\n", path, size); + + error = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + struct stat st_buf; + + if (stat(path, &st_buf) < 0) { + EM_DEBUG_EXCEPTION("\t stat failed - %s\n", path); + + error = EMF_ERROR_SYSTEM_FAILURE; + goto FINISH_OFF; + } + + *size = st_buf.st_size; + + ret = true; + +FINISH_OFF: + if (err_code != NULL) + *err_code = error; + EM_DEBUG_FUNC_END(); + return ret; +} + +void* em_core_malloc(unsigned len) +{ + /* EM_DEBUG_LOG("Memory allocation size[%d] bytes", len); */ + void *p = NULL; + + if (len <= 0) { + EM_DEBUG_EXCEPTION("len should be positive.[%d]", len); + return NULL; + } + + p = malloc(len); + + if (p) + memset(p, 0x00, len); + else + EM_DEBUG_EXCEPTION("malloc failed"); + return p; +} + +EXPORT_API char* em_core_replace_string(char *source_string, char *old_string, char *new_string) +{ + EM_DEBUG_FUNC_BEGIN(); + char *result_buffer = NULL; + char *p = NULL; + int buffer_length = 0; + + EM_IF_NULL_RETURN_VALUE(source_string, NULL); + EM_IF_NULL_RETURN_VALUE(old_string, NULL); + EM_IF_NULL_RETURN_VALUE(new_string, NULL); + + p = strstr(source_string, old_string); + + if (p == NULL) { + EM_DEBUG_EXCEPTION("old_string not found in source_string"); + EM_DEBUG_FUNC_END("return NULL"); + return NULL; + } + + EM_DEBUG_LOG("p[%s] ", p); /* temp */ + buffer_length = strlen(source_string) + 1024; + EM_DEBUG_LOG("buffer_length[%d] ", buffer_length); /* temp */ + result_buffer = (char *)em_core_malloc(buffer_length); + + if (!result_buffer) { + EM_DEBUG_EXCEPTION("em_core_malloc failed"); + return NULL; + } + + strncpy(result_buffer, source_string, p - source_string); + snprintf(result_buffer + strlen(result_buffer), buffer_length - strlen(result_buffer), "%s%s", new_string, p + strlen(old_string)); + + EM_DEBUG_FUNC_END("result_buffer[%s]", result_buffer); + return result_buffer; +} + +static int _em_core_check_host(char *host) +{ + if (!host) + return 0; + return strncmp(host, ".SYNTAX-ERROR.", strlen(".SYNTAX-ERROR.")); +} + +void em_core_skip_whitespace(char *addr_str, char **pAddr) +{ + EM_DEBUG_FUNC_BEGIN("addr_str[%p]", addr_str); + + if (!addr_str) + return ; + char *str = addr_str; + char ptr[strlen(str)+1] ; + int i, j = 0; + + str = addr_str ; + for (i = 0; str[i] != NULL_CHAR ; i++) { + if (str[i] != SPACE && str[i] != TAB && str[i] != CR && str[i] != LF) + ptr[j++] = str[i]; + } + ptr[j] = NULL_CHAR; + + *pAddr = EM_SAFE_STRDUP(ptr); + EM_DEBUG_FUNC_END("ptr[%s]", ptr); +} + +EXPORT_API char* em_core_skip_whitespace_without_strdup(char *source_string) +{ + EM_DEBUG_FUNC_BEGIN("source_string[%p]", source_string); + + if (!source_string) + return NULL; + int i; + + for (i = 0; source_string[i] != NULL_CHAR ; i++) { + if (source_string[i] != SPACE) /* || source_string[i] != TAB || source_string[i] != CR || source_string[i] || LF) */ + break; + } + + EM_DEBUG_FUNC_END("i[%d]", i); + return source_string + i; +} + +int em_core_get_address_count(char *addr_str, int *count, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("addr_str[%s], count[%p], err_code[%p]", addr_str, count, err_code); + + int ret = false; + int error = EMF_ERROR_NONE; + + ADDRESS *addr = NULL; + ADDRESS *p_addr = NULL; + int i = 0, j; + char *p = NULL; + + + if (!count) { + EM_DEBUG_EXCEPTION("addr_str[%s], count[%p]", addr_str, count); + error = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + if (addr_str != NULL) { + em_core_skip_whitespace(addr_str, &p); + EM_DEBUG_LOG("em_core_skip_whitespace[p][%s]", p); + + + for (i = 0, j = strlen(p); i < j; i++) + if (p[i] == ';') p[i] = ','; + rfc822_parse_adrlist(&addr, p, NULL); + EM_SAFE_FREE(p); + + + for (p_addr = addr, i = 0; p_addr; p_addr = p_addr->next, i++) { + if (p_addr->mailbox && p_addr->host) { + if (!strncmp(p_addr->mailbox, "UNEXPECTED_DATA_AFTER_ADDRESS", strlen("UNEXPECTED_DATA_AFTER_ADDRESS")) || !strncmp(p_addr->mailbox, "INVALID_ADDRESS", strlen("INVALID_ADDRESS")) || !strncmp(p_addr->host, ".SYNTAX-ERROR.", strlen(".SYNTAX-ERROR."))) { + EM_DEBUG_LOG("Invalid address "); + continue; + } + } + if ((!p_addr->mailbox) || (_em_core_check_host(p_addr->host) == 0)) { + EM_DEBUG_EXCEPTION("\t invalid address : mailbox[%s], host[%s]\n", p_addr->mailbox, p_addr->host); + + error = EMF_ERROR_INVALID_ADDRESS; + /* goto FINISH_OFF; */ + } + } + } + + *count = i; + if (error != EMF_ERROR_INVALID_ADDRESS) + ret = true; + +FINISH_OFF: + if (addr) + mail_free_address(&addr); + + if (err_code != NULL) + *err_code = error; + EM_DEBUG_FUNC_END(); + return ret; +} + +EXPORT_API int em_core_set_network_error(int err_code) +{ + emf_session_t *session = NULL; + + EM_DEBUG_FUNC_BEGIN(); + + em_core_get_current_session(&session); + + if (!session) + return false; + + session->network = err_code; + EM_DEBUG_FUNC_END(); + return true; +} + +int em_core_get_empty_session(emf_session_t **session) +{ + EM_DEBUG_FUNC_BEGIN("session[%p]", session); + + /* lock()... */ + + int i; + + for (i = 0; i < SESSION_MAX; i++) { + if (!g_session_list[i].status) { + memset(g_session_list+i, 0x00, sizeof(emf_session_t)); + g_session_list[i].tid = GPOINTER_TO_INT(THREAD_SELF()); + g_session_list[i].status = true; + break; + } + } + + /* unlock()... */ + + if (session != NULL) + *session = (i != SESSION_MAX) ? &g_session_list[i] : NULL; + EM_DEBUG_FUNC_END(); + return (i != SESSION_MAX) ? true : false; +} + +int em_core_clear_session(emf_session_t *session) +{ + EM_DEBUG_FUNC_BEGIN(); + + if (session) + memset(session, 0x00, sizeof(emf_session_t)); + EM_DEBUG_FUNC_END(); + return true; +} + +int em_core_get_current_session(emf_session_t **session) +{ + EM_DEBUG_FUNC_BEGIN("session[%p]", session); + + int i; + + for (i = 0; i < SESSION_MAX; i++) { + if (g_session_list[i].tid == GPOINTER_TO_INT(THREAD_SELF())) { + if (session) + *session = g_session_list + i; + + break; + } + } + + if (session) + *session = (i != SESSION_MAX) ? g_session_list + i : NULL; + EM_DEBUG_FUNC_END(); + return (i != SESSION_MAX) ? true : false; +} + +int em_core_check_unread_mail() +{ + EM_DEBUG_FUNC_BEGIN(); + + int ret = false; + int err = EMF_ERROR_NONE; + int total_unread_count = 0; + int total_mail_count = 0; + emf_mailbox_t mailbox; + + memset(&mailbox, 0x00, sizeof(emf_mailbox_t)); + + /* ALL_ACCOUNT used, so not calling em_storage_get_mailboxname_by_mailbox_type to get mailbox name */ + mailbox.account_id = ALL_ACCOUNT; + mailbox.name = NULL; + + if (!em_core_mailbox_get_mail_count(&mailbox, &total_mail_count, &total_unread_count, &err)) { + EM_DEBUG_EXCEPTION("em_core_mailbox_get_mail_count failed [%d]", err); + goto FINISH_OFF; + } + + EM_DEBUG_LOG("total_unread_count [%d]", total_unread_count); + + /* set unread count to badge */ + if ( vconf_set_int(VCONF_KEY_UNREAD_MAIL_COUNT, total_unread_count) != 0 ) { + EM_DEBUG_EXCEPTION("vconf_set_int failed"); + err = EMF_ERROR_GCONF_FAILURE; + goto FINISH_OFF; + } + + EM_DEBUG_LOG("db/badge/com.samsung.email - set[%d]", total_unread_count); + + ret = true; +FINISH_OFF: + + return ret; +} + +int em_core_add_notification(int account_id, int mail_id, char *title, char *content, time_t log_time) +{ + EM_DEBUG_FUNC_BEGIN(); + int ret = true; + + EM_DEBUG_FUNC_END(); + return ret; +} + +int em_core_show_popup(int id, emf_action_t action, int error) +{ + EM_DEBUG_FUNC_BEGIN("id[%d], action[%d], error[%d]", id, action, error); + + int ret = false; + time_t log_time = 0; + struct tm *log_time_tm; + + time(&log_time); + log_time_tm = localtime(&log_time); + log_time = mktime(log_time_tm); + + EM_DEBUG_LOG("sec[%d], min[%d], hour[%d], day[%d], month[%d], year[%d]" ,log_time_tm->tm_sec, log_time_tm->tm_min, log_time_tm->tm_hour, log_time_tm->tm_mday, log_time_tm->tm_mon, log_time_tm->tm_year); +#ifdef __FEATURE_PROGRESS_IN_OUTBOX__ + if (action == EMF_ACTION_SEND_MAIL && error != EMF_ERROR_CANCELLED) { + /* In case email is cancelled using cancel button in Outbox there is no need to show Cancel/Retry Pop up */ +#else + if (action == EMF_ACTION_SEND_MAIL) { +#endif + emf_mail_tbl_t *mail_table_data = NULL; + + if (error == 0) /* error 0 means 'this is not error' */ + return true; + + if (id <= 0) { + EM_DEBUG_LOG("Invalid mail_id"); + return false; + } + + if (!em_storage_get_mail_by_id(id, &mail_table_data, true, NULL)) { + EM_DEBUG_LOG("Mail not found"); + return false; + } + + if (!em_core_add_notification(mail_table_data->account_id + 1000, id, "Failed to send mail", mail_table_data->subject, log_time)) { + EM_DEBUG_EXCEPTION("em_core_notification_set error"); + return false; + } + + if (!em_storage_free_mail(&mail_table_data, 1, NULL)) + EM_DEBUG_EXCEPTION("em_storage_free_mail Failed"); + + ret = true; + } + EM_DEBUG_FUNC_END(); + return ret; +} + + +/* storage space handling - 210709 */ +int em_core_get_storage_status(void) +{ + EM_DEBUG_FUNC_BEGIN(); + int storage_status = 0, nError = 0; + + g_type_init(); + +#ifdef STORAGE_STATUS + nError = vconf_get_int(PS_KEY_SYSTEM_STORAGE_MOVI_STATUS, + &storage_status); +#endif /* STORAGE_STATUS */ + + if (nError == -1) { + EM_DEBUG_EXCEPTION("vconf_get_int Failed"); + return false; + } + EM_DEBUG_FUNC_END(); + return storage_status; +} + +int em_core_is_storage_full(int *err_code) +{ + EM_DEBUG_FUNC_BEGIN(); + + int ret = false; + int err = EMF_ERROR_NONE; + struct statfs buf = {0}; + + if (statfs(DATA_PATH, &buf) == -1) { + EM_DEBUG_EXCEPTION("statfs(\"%s\") failed - %d", DATA_PATH, errno); + err = EMF_ERROR_SYSTEM_FAILURE; /* lEMF_ERROR_UNKNOWN; */ + goto FINISH_OFF; + } + else { + long i_free = (buf.f_bfree * buf.f_bsize) / (1024 * 1024); + EM_DEBUG_LOG("f_bfree[%d] f_bsize[%d]", buf.f_bfree, buf.f_bsize); + EM_DEBUG_LOG("Free space of storage is[%ld] MB.", i_free); + if (i_free < EM_STORAGE_LIMITATION_FREE_SPACE) + err = EMF_ERROR_MAIL_MEMORY_FULL; + } + + if (err == EMF_ERROR_MAIL_MEMORY_FULL) + ret = true; + +FINISH_OFF: + if (err_code != NULL) + *err_code = err; + EM_DEBUG_FUNC_END("ret[%d]", ret); + return ret; +} + +int em_core_get_mail_size(emf_mail_t *mail_src, int *error_code) +{ + EM_DEBUG_FUNC_BEGIN("mail_src[%p], err_code[%p]", mail_src, error_code); + EM_PROFILE_BEGIN(profile_em_core_get_mail_size); + + emf_attachment_info_t *atch = NULL; + struct stat st_buf; + int mail_size = 0; /* size of the plain text body and attachments */ + int err = EMF_ERROR_NONE; + + if (!mail_src || !mail_src->body) { + if (mail_src) { + if (mail_src->body) + EM_DEBUG_LOG("mail_src[%p], mail_src->body[%p], mail_src->body->plain[%p]", mail_src, mail_src->body, mail_src->body->plain); + else + EM_DEBUG_LOG(" mail_src[%p], mail_src->body[%p]", mail_src, mail_src->body); + } + else + EM_DEBUG_LOG("mail_src[%p]", mail_src); + + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + mail_size = 0; + if (mail_src->body->plain != NULL) { + if (stat(mail_src->body->plain, &st_buf) < 0) { + EM_DEBUG_EXCEPTION("mail_src->body->plain stat(\"%s\") failed...", mail_src->body->plain); + err = EMF_ERROR_INVALID_MAIL; + goto FINISH_OFF; + } + + mail_size += st_buf.st_size; + + } + + if (mail_src->body->html != NULL) { + if (stat(mail_src->body->html, &st_buf) < 0) { + EM_DEBUG_EXCEPTION("mail_src->body->html stat(\"%s\") failed...", mail_src->body->html); + err = EMF_ERROR_INVALID_MAIL; + goto FINISH_OFF; + } + + mail_size += st_buf.st_size; + } + + atch = mail_src->body->attachment; + + while (atch) { + if (stat(atch->savename, &st_buf) < 0) { + EM_DEBUG_EXCEPTION("stat(\"%s\") failed...", atch->savename); + err = EMF_ERROR_INVALID_MAIL; /* EMF_ERROR_INVALID_PATH; */ + goto FINISH_OFF; + } + + mail_size += st_buf.st_size; + atch = atch->next; + } + + +FINISH_OFF: + if (error_code) + *error_code = err; + EM_PROFILE_END(profile_em_core_get_mail_size); + EM_DEBUG_FUNC_END(); + return (err == EMF_ERROR_NONE ? mail_size : 0); +} + + +int em_core_calc_mail_size(emf_mail_data_t *input_mail_data, emf_attachment_data_t *input_attachment_data_list, int input_attachment_count, int *output_size) +{ + EM_DEBUG_FUNC_BEGIN("input_mail_data[%p], input_attachment_data_list[%p], input_attachment_count[%d], output_size[%p]", input_mail_data, input_attachment_data_list, input_attachment_count, output_size); + + struct stat st_buf; + int mail_size = 0; /* size of the plain text body and attachments */ + int err = EMF_ERROR_NONE; + int i = 0; + + if (!input_mail_data || (input_attachment_count && !input_attachment_data_list) || (!input_attachment_count &&input_attachment_data_list) || !output_size) { + EM_DEBUG_EXCEPTION("EMF_ERROR_INVALID_PARAM"); + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + if (input_mail_data->file_path_plain != NULL) { + if (stat(input_mail_data->file_path_plain, &st_buf) < 0) { + EM_DEBUG_EXCEPTION("input_mail_data->file_path_plain : stat(\"%s\") failed...", input_mail_data->file_path_plain); + err = EMF_ERROR_INVALID_MAIL; + goto FINISH_OFF; + } + + mail_size += st_buf.st_size; + + } + + if (input_mail_data->file_path_html != NULL) { + if (stat(input_mail_data->file_path_html, &st_buf) < 0) { + EM_DEBUG_EXCEPTION("input_mail_data->file_path_html : stat(\"%s\") failed...", input_mail_data->file_path_html); + err = EMF_ERROR_INVALID_MAIL; + goto FINISH_OFF; + } + + mail_size += st_buf.st_size; + } + + for(i = 0; i < input_attachment_count; i++) { + if (stat(input_attachment_data_list[i].attachment_path, &st_buf) < 0) { + EM_DEBUG_EXCEPTION("stat(\"%s\") failed...", input_attachment_data_list[i].attachment_path); + err = EMF_ERROR_INVALID_MAIL; + goto FINISH_OFF; + } + mail_size += st_buf.st_size; + } + + *output_size = mail_size; + +FINISH_OFF: + + EM_DEBUG_FUNC_END("mail_size [%d]", mail_size); + return err; +} + + +int em_storage_get_emf_error_from_em_storage_error(int error) +{ + switch (error) { + case EM_STORAGE_ERROR_NONE: + return EMF_ERROR_NONE; + + case EM_STORAGE_ERROR_INVALID_PARAM: + return EMF_ERROR_INVALID_PARAM; + + case EM_STORAGE_ERROR_ACCOUNT_NOT_FOUND: + return EMF_ERROR_ACCOUNT_NOT_FOUND; + + case EM_STORAGE_ERROR_MAIL_NOT_FOUND: + return EMF_ERROR_MAIL_NOT_FOUND; + + case EM_STORAGE_ERROR_MAILBOX_NOT_FOUND: + return EMF_ERROR_MAILBOX_NOT_FOUND; + + case EM_STORAGE_ERROR_ATTACHMENT_NOT_FOUND: + return EMF_ERROR_ATTACHMENT_NOT_FOUND; + + case EM_STORAGE_ERROR_CONTACT_NOT_FOUND: + return EMF_ERROR_CONTACT_NOT_FOUND; + + case EM_STORAGE_ERROR_FILE_NOT_FOUND: + return EMF_ERROR_FILE_NOT_FOUND; + + case EM_STORAGE_ERROR_DATA_NOT_FOUND: + return EMF_ERROR_DATA_NOT_FOUND; + + case EM_STORAGE_ERROR_NO_MORE_DATA: + return EMF_ERROR_NO_MORE_DATA; + + case EM_STORAGE_ERROR_DATA_TOO_LONG: + return EMF_ERROR_DATA_TOO_LONG; + + case EM_STORAGE_ERROR_DATA_TOO_SMALL: + return EMF_ERROR_DATA_TOO_SMALL; + + case EM_STORAGE_ERROR_OUT_OF_MEMORY: + return EMF_ERROR_OUT_OF_MEMORY; + + case EM_STORAGE_ERROR_CONNECTION_FAILURE: + return EMF_ERROR_CONNECTION_FAILURE; + + case EM_STORAGE_ERROR_SYSTEM_FAILURE: + return EMF_ERROR_SYSTEM_FAILURE; + + case EM_STORAGE_ERROR_RULE_NOT_FOUND: + return EMF_ERROR_FILTER_NOT_FOUND; + + case EM_STORAGE_ERROR_DB_IS_FULL: + return EMF_ERROR_MAIL_MEMORY_FULL; + + case EM_STORAGE_ERROR_DB_FAILURE: + return EMF_ERROR_DB_FAILURE; + + case EM_STORAGE_ERROR_MAIL_MAX_COUNT: + return EMF_ERROR_MAIL_MAX_COUNT; + + case EM_STORAGE_ERROR_MMC_NOT_FOUND: + return EMF_ERROR_NO_MMC_INSERTED; + + case EM_STORAGE_ERROR_ALREADY_EXISTS: + return EMF_ERROR_ALREADY_EXISTS; + + case EM_STORAGE_ERROR_UNKNOWN: + default: + return EMF_ERROR_UNKNOWN; + } + + return EMF_ERROR_UNKNOWN; +} + + +/* parse the Full mailbox Path and Get the Alias Name of the Mailbox */ +char *em_core_get_alias_of_mailbox(const char *mailbox_path) +{ + EM_DEBUG_FUNC_BEGIN(); + EM_IF_NULL_RETURN_VALUE(mailbox_path, NULL); + + guint index = 0; + gchar **token_list = NULL; + gchar *mailbox = NULL, *name = NULL; + char *converted_name; + + + mailbox = g_strdup(mailbox_path); + token_list = g_strsplit_set(mailbox, "/", -1); + + if (mailbox) + g_free(mailbox); + + while (token_list[index] != NULL) + index++; + + name = g_strdup(token_list[index - 1]); + g_strfreev(token_list); + + converted_name = em_core_convert_mutf7_to_utf8(name); + + if (name) + g_free(name); + + EM_DEBUG_FUNC_END(); + return converted_name; +} + +EXPORT_API int em_core_open_contact_db_library(void) +{ + EM_DEBUG_FUNC_BEGIN(); + int err; + int ret = false; + + if ((err = contacts_svc_connect()) == CTS_SUCCESS) + EM_DEBUG_LOG("Open Contact Service Success"); + else { + EM_DEBUG_EXCEPTION("contact_db_service_connect failed - %d", err); + return false; + } + ret = true; + + EM_DEBUG_FUNC_END(); + return ret; + +} + +EXPORT_API void em_core_close_contact_db_library() +{ + EM_DEBUG_FUNC_BEGIN(); + int err; + + if ((err = contacts_svc_disconnect()) == CTS_SUCCESS) + EM_DEBUG_LOG("Close Contact Service Success"); + else + EM_DEBUG_EXCEPTION("Close Contact Service Fail[%d]", err); + EM_DEBUG_FUNC_END(); + return; +} + +#define EMAIL_ACCOUNT_RGEX "([a-z0-9!#$%&'*+/=?^_`{|}~-]+.)*[a-z0-9!#$%&'*+/=?^_`{|}~-]+" +#define EMAIL_DOMAIN_RGEX "([a-z0-9!#$%&'*+/=?^_`{|}~-]+.)+[a-z0-9!#$%&'*+/=?^_`{|}~-]+" + +#define EMAIL_ADDR_RGEX "[[:space:]]*<"EMAIL_ACCOUNT_RGEX"@"EMAIL_DOMAIN_RGEX">[[:space:]]*" +#define EMAIL_ALIAS_RGEX "([[:space:]]*\"[^\"]*\")?"EMAIL_ADDR_RGEX +#define EMAIL_ALIAS_LIST_RGEX "^("EMAIL_ALIAS_RGEX"[;,])*"EMAIL_ALIAS_RGEX"[;,]?[[:space:]]*$" + +#define EMAIL_ADDR_WITHOUT_BRACKET_RGEX "[[:space:]]*"EMAIL_ACCOUNT_RGEX"@"EMAIL_DOMAIN_RGEX"[[:space:]]*" +#define EMAIL_ALIAS_WITHOUT_BRACKET_RGEX "([[:space:]]*\"[^\"]*\")?"EMAIL_ADDR_WITHOUT_BRACKET_RGEX +#define EMAIL_ALIAS_LIST_WITHOUT_BRACKET_RGEX "("EMAIL_ALIAS_WITHOUT_BRACKET_RGEX"[;,])*"EMAIL_ADDR_WITHOUT_BRACKET_RGEX"[;,]?[[:space:]]*$" + +EXPORT_API int em_core_verify_email_address(char *address, int without_bracket, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("address[%s] without_bracket[%d]", address, without_bracket); + + /* this following code verfies the email alias string using reg. exp. */ + regex_t alias_list_regex = {0}; + int ret = false, error = EMF_ERROR_NONE; + char *reg_rule = NULL; + + if(!address || strlen(address) == 0) { + EM_DEBUG_EXCEPTION("EMF_ERROR_INVALID_PARAM"); + if (err_code) + *err_code = EMF_ERROR_INVALID_PARAM; + return false; + } + + if(without_bracket) + reg_rule = EMAIL_ALIAS_LIST_WITHOUT_BRACKET_RGEX; + else + reg_rule = EMAIL_ALIAS_LIST_RGEX; + + if (regcomp(&alias_list_regex, reg_rule, REG_ICASE | REG_EXTENDED)) { + EM_DEBUG_EXCEPTION("email alias regex unrecognized"); + if (err_code) + *err_code = EMF_ERROR_UNKNOWN; + return false; + } + + int alias_len = strlen(address) + 1; + regmatch_t pmatch[alias_len]; + + bzero(pmatch, alias_len); + + if (regexec(&alias_list_regex, address, alias_len, pmatch, 0) == REG_NOMATCH) + EM_DEBUG_LOG("failed :[%s]", address); + else { + EM_DEBUG_LOG("success :[%s]", address); + ret = true; + } + + regfree(&alias_list_regex); + + if (err_code) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API int em_core_verify_email_address_of_mail_header(emf_mail_head_t *mail_header, int without_bracket, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("mail_header[%p] without_bracket[%d]", mail_header, without_bracket); + char *address_array[4] = { mail_header->to, mail_header->cc, mail_header->bcc, mail_header->from}; + int ret = false, err = EMF_ERROR_NONE, i; + + /* check for email_address validation */ + for (i = 0; i < 4; i++) { + if (address_array[i] && address_array[i][0] != 0) { + if (!em_core_verify_email_address(address_array[i] , without_bracket, &err)) { + err = EMF_ERROR_INVALID_ADDRESS; + EM_DEBUG_EXCEPTION("Invalid Email Address [%d][%s]", i, address_array[i]); + goto FINISH_OFF; + } + } + } + ret = true; +FINISH_OFF: + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API int em_core_verify_email_address_of_mail_data(emf_mail_data_t *mail_data, int without_bracket, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("mail_data[%p] without_bracket[%d]", mail_data, without_bracket); + char *address_array[4] = { mail_data->full_address_from, mail_data->full_address_to, mail_data->full_address_cc, mail_data->full_address_bcc}; + int ret = false, err = EMF_ERROR_NONE, i; + + /* check for email_address validation */ + for (i = 0; i < 4; i++) { + if (address_array[i] && address_array[i][0] != 0) { + if (!em_core_verify_email_address(address_array[i] , without_bracket, &err)) { + err = EMF_ERROR_INVALID_ADDRESS; + EM_DEBUG_EXCEPTION("Invalid Email Address [%d][%s]", i, address_array[i]); + goto FINISH_OFF; + } + } + } + ret = true; +FINISH_OFF: + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API int em_core_get_server_time(void *mail_stream, int account_id, char *uid, int msgno, time_t *log_time, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN(); + + int ret_code = false; + int err = EMF_ERROR_NONE; + emf_account_t *account = NULL; + emf_mailbox_t mailbox = { 0 }; + MESSAGECACHE *elt = NULL; + char datetime[DATETIME_LENGTH] = { 0, }; + emf_datetime_t date = { 0 }; + struct tm tm1 = { 0 }; + time_t t = time(NULL); + + + if (!mail_stream || (!uid && msgno < 1)) { + EM_DEBUG_EXCEPTION("Param is NULL"); + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + mailbox.account_id = account_id; + mailbox.mail_stream = mail_stream; + + if (!(account = em_core_get_account_reference(account_id))) { + EM_DEBUG_EXCEPTION("em_core_get_account_reference failed - %d", account_id); + err = EMF_ERROR_INVALID_ACCOUNT; + goto FINISH_OFF; + } + if (msgno < 1) { /* get msgno from server */ + if (!em_core_mail_get_msgno_by_uid(account, &mailbox, uid, &msgno, &err)) { + EM_DEBUG_EXCEPTION("em_core_mail_get_msgno_by_uid failed message_no : %d ", err); + goto FINISH_OFF; + } + } + if (!(elt = mail_elt(mailbox.mail_stream, msgno))) { + EM_DEBUG_EXCEPTION("mail_elt failed..."); + err = EMF_ERROR_UNKNOWN; + goto FINISH_OFF; + } + SNPRINTF(datetime, sizeof(datetime), "%04d%02d%02d%02d%02d%02d", + BASEYEAR + elt->year, elt->month, elt->day, elt->hours, elt->minutes, elt->seconds); + + EM_DEBUG_LOG("datetime[%s]", datetime); + + if (!em_convert_string_to_datetime(datetime, &date, &err)) + EM_DEBUG_EXCEPTION("em_convert_string_to_datetime failed - %d", err); + + tm1.tm_year = date.year - 1900; + tm1.tm_mon = date.month - 1; + tm1.tm_mday = date.day; + tm1.tm_hour = date.hour; + tm1.tm_min = date.minute; + tm1.tm_sec = date.second; + t = mktime(&tm1); + + *log_time = t; + ret_code = true; + +FINISH_OFF: + + if (err_code) + *err_code = err; + + EM_DEBUG_FUNC_END(); + return ret_code; +} + +static int em_core_get_first_address(const char *full_address, char **alias, char **address) +{ + EM_DEBUG_FUNC_BEGIN(); + + if (full_address == NULL || alias == NULL || address == NULL){ + EM_DEBUG_EXCEPTION("Invalid Param : full_address[%p], alias[%p], address[%p]", full_address, alias, address); + return false; + } + + char *s = NULL; + char *alias_start = NULL; + char *alias_end = NULL; + char *alias_cursor = NULL; + char *address_start = NULL; + char *address_end = NULL; + char *first_address = NULL; + + if (full_address){ + s = (char *)strchr((char *)full_address, ';'); + if (s == NULL) + first_address = strdup(full_address); /* only one address */ + else + first_address = strndup(full_address, s - full_address); /* over two addresses */ + + /* get alias */ + *alias = NULL; + if ((alias_start = (char *)strchr((char *)first_address, '\"'))){ + alias_start++; + alias_cursor = alias_start; + while ((alias_cursor = (char *)strchr((char *)(alias_cursor), '\"'))){ + alias_end = alias_cursor; + alias_cursor++; + if (*alias_cursor == 0) + break; + } + if (alias_end) { /* there is "alias" */ + *alias = strndup(alias_start, alias_end - alias_start); + EM_DEBUG_LOG("alias [%s]", *alias); + } + } + + /* get address */ + *address = NULL; + if (alias_end == NULL) + s = first_address; + else + s = alias_end+1; + if ((address_start = (char *)strchr((char *)s, '<'))){ + address_start++; + if ((address_end = (char *)strchr((char *)address_start, '>'))) + *address = strndup(address_start, address_end - address_start); /* (alias) <(addr)> ... */ + else + *address = strdup(s); + } + else + *address = strdup(s); /* (addr) ; ... : no alias */ + } + + EM_SAFE_FREE(first_address); + EM_DEBUG_FUNC_END(); + return true; +} + +EXPORT_API void em_core_fill_address_information_of_mail_tbl(emf_mail_tbl_t *mail_data) +{ + EM_DEBUG_FUNC_BEGIN("mail_data [%p]", mail_data); + + char *first_alias = NULL; + char *first_address = NULL; + char *recipient = NULL; + + /* sender alias & address */ + if (em_core_get_first_address(mail_data->full_address_from, &first_alias, &first_address) == true) { + if (first_alias == NULL) { + mail_data->alias_sender = EM_SAFE_STRDUP(first_address); + } + else { + mail_data->alias_sender = first_alias; + first_alias = NULL; + } + mail_data->email_address_sender = first_address; + first_address = NULL; + } + + /* recipient alias & address */ + if (mail_data->full_address_to != NULL) + recipient = mail_data->full_address_to; + else if (mail_data->full_address_cc != NULL) + recipient = mail_data->full_address_cc; + else if (mail_data->full_address_bcc != NULL) + recipient = mail_data->full_address_bcc; + + if (em_core_get_first_address(recipient, &first_alias, &first_address) == true) { + if (first_alias == NULL) + mail_data->alias_recipient = EM_SAFE_STRDUP(first_address); + else + mail_data->alias_recipient = first_alias; + + mail_data->email_address_recipient = first_address; + } + EM_DEBUG_FUNC_END(); +} + + +EXPORT_API int em_core_get_preview_text_from_file(const char *input_plain_path, const char *input_html_path, int input_preview_buffer_length, char **output_preview_buffer) +{ + EM_DEBUG_FUNC_BEGIN("input_plain_path[%p], input_html_path[%p], input_preview_buffer_length [%d], output_preview_buffer[%p]", input_plain_path, input_html_path, input_preview_buffer_length, output_preview_buffer); + + int err = EMF_ERROR_NONE; + unsigned int byte_read = 0; + unsigned int byte_written = 0; + int result_strlen = 0; + int local_preview_buffer_length = 0; + char *local_preview_text = NULL; + char *encoding_type = NULL; + char *utf8_encoded_string = NULL; + FILE *fp = NULL; + GError *glib_error = NULL; + struct stat st_buf; + + if (!output_preview_buffer) { + EM_DEBUG_EXCEPTION("EMF_ERROR_INVALID_PARAM"); + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + local_preview_buffer_length = input_preview_buffer_length * 2; + + if (input_html_path != NULL) { + /* get preview text from html file */ + if( (err = em_core_get_encoding_type_from_file_path(input_html_path, &encoding_type)) != EMF_ERROR_NONE) { + EM_DEBUG_EXCEPTION("em_core_get_encoding_type_from_file_path failed [%s]", err); + goto FINISH_OFF; + } + + if (stat(input_html_path, &st_buf) < 0) { + EM_DEBUG_EXCEPTION("stat(\"%s\") failed...", input_html_path); + err = EMF_ERROR_INVALID_MAIL; + goto FINISH_OFF; + } + + if (!(fp = fopen(input_html_path, "r"))) { + EM_DEBUG_EXCEPTION("fopen failed [%s]", input_html_path); + err = EMF_ERROR_SYSTEM_FAILURE; + goto FINISH_OFF; + } + + if (!(local_preview_text = (char*)em_core_malloc(sizeof(char) * (st_buf.st_size + 1)))) { + EM_DEBUG_EXCEPTION("em_core_malloc failed"); + err = EMF_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + byte_read = fread(local_preview_text, sizeof(char), st_buf.st_size, fp); + + if (ferror(fp)) { + EM_DEBUG_EXCEPTION("fread failed [%s]", input_plain_path); + err = EMF_ERROR_SYSTEM_FAILURE; + goto FINISH_OFF; + } + + if ( (err = em_core_strip_HTML(local_preview_text)) != EMF_ERROR_NONE) { + EM_DEBUG_EXCEPTION("em_core_strip_HTML failed"); + goto FINISH_OFF; + } + + result_strlen = EM_SAFE_STRLEN(local_preview_text); + } + + if (local_preview_text == NULL && input_plain_path != NULL) { + /* get preview text from plain text file */ + if( (err = em_core_get_encoding_type_from_file_path(input_plain_path, &encoding_type)) != EMF_ERROR_NONE) { + EM_DEBUG_EXCEPTION("em_core_get_encoding_type_from_file_path failed [%s]", err); + goto FINISH_OFF; + } + + if (!(fp = fopen(input_plain_path, "r"))) { + EM_DEBUG_EXCEPTION("fopen failed [%s]", input_plain_path); + err = EMF_ERROR_SYSTEM_FAILURE; + goto FINISH_OFF; + } + + if (!(local_preview_text = (char*)em_core_malloc(sizeof(char) * local_preview_buffer_length))) { + EM_DEBUG_EXCEPTION("em_core_malloc failed"); + goto FINISH_OFF; + } + + byte_read = fread(local_preview_text, sizeof(char), local_preview_buffer_length - 1, fp); + + if (ferror(fp)) { + EM_DEBUG_EXCEPTION("fread failed [%s]", input_plain_path); + err = EMF_ERROR_SYSTEM_FAILURE; + goto FINISH_OFF; + } + result_strlen = byte_read; + } + + + if(local_preview_text) { + if(encoding_type && strcasecmp(encoding_type, "UTF-8") != 0) { + EM_DEBUG_LOG("encoding_type [%s]", encoding_type); + utf8_encoded_string = (char*)g_convert (local_preview_text, -1, "UTF-8", encoding_type, &byte_read, &byte_written, &glib_error); + + if(utf8_encoded_string) { + EM_SAFE_FREE(local_preview_text); + local_preview_text = utf8_encoded_string; + } + else + EM_DEBUG_EXCEPTION("g_convert failed"); + } + + if (!(*output_preview_buffer = (char*)em_core_malloc(sizeof(char) * (result_strlen + 1)))) { + EM_DEBUG_EXCEPTION("em_core_malloc failed"); + err = EMF_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + EM_SAFE_STRNCPY(*output_preview_buffer, local_preview_text, result_strlen); + /* EM_DEBUG_LOG("local_preview_text[%s], byte_read[%d], result_strlen[%d]", local_preview_text, byte_read, result_strlen); */ + } + +FINISH_OFF: + + EM_SAFE_FREE(local_preview_text); + EM_SAFE_FREE(encoding_type); + + if (fp != NULL) + fclose(fp); + + EM_DEBUG_FUNC_END("err [%d]", err); + return err; +} + +EXPORT_API int em_core_add_transaction_info(int mail_id, int handle , int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("mail_id[%d], handle[%d]", mail_id, handle); + + int ret = false; + int err = EMF_ERROR_NONE ; + em_transaction_info_type_t *pTransinfo = NULL ; + em_transaction_info_type_t *pTemp = NULL; + + EM_DEBUG_LOG("g_transaction_info_list[%p]", g_transaction_info_list); + pTransinfo = g_transaction_info_list ; + + if (!(pTemp = em_core_malloc(sizeof(em_transaction_info_type_t)))) { + EM_DEBUG_EXCEPTION("malloc failed..."); + err = EMF_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + pTemp->mail_id = mail_id ; + pTemp->handle = handle; + + if (!pTransinfo) { + pTransinfo = pTemp ; + g_transaction_info_list = pTransinfo ; + } + else { + while (pTransinfo->next) + pTransinfo = pTransinfo->next; + pTransinfo->next = pTemp; + } + ret = true ; + +FINISH_OFF: + + if (err_code) + *err_code = err; + EM_DEBUG_FUNC_END("g_transaction_info_list[%p]", g_transaction_info_list); + return ret; +} + +EXPORT_API int em_core_get_handle_by_mailId_from_transaction_info(int mail_id, int *pHandle) +{ + EM_DEBUG_FUNC_BEGIN("mail_id[%d], handle[%p]", mail_id, pHandle); + + int ret = false; + em_transaction_info_type_t *pTransinfo = NULL ; + + if (g_transaction_info_list == NULL) { + EM_DEBUG_EXCEPTION("g_transaction_info_list NULL"); + return false; + } + pTransinfo = g_transaction_info_list; + + do { + EM_DEBUG_LOG("pTransinfo->mail_id[%d]", pTransinfo->mail_id); + if (pTransinfo->mail_id == mail_id) { + *pHandle = pTransinfo->handle; + ret = true; + EM_DEBUG_LOG("*pHandle[%d]", *pHandle); + break; + } + else + pTransinfo = pTransinfo->next ; + }while (pTransinfo); + EM_DEBUG_FUNC_END(); + return ret; +} + +EXPORT_API int em_core_delete_transaction_info_by_mailId(int mail_id ) +{ + EM_DEBUG_FUNC_BEGIN("mail_id[%d]", mail_id); + + em_transaction_info_type_t *pTransinfo ; + em_transaction_info_type_t *pTemp = NULL; + + if (g_transaction_info_list == NULL) { + EM_DEBUG_EXCEPTION("g_transaction_info_list NULL"); + return false; + } + pTransinfo = g_transaction_info_list; + + EM_DEBUG_LOG("pTransinfo[%p]", pTransinfo); + + do { + EM_DEBUG_LOG("pTransinfo->mail_id[%d]", pTransinfo->mail_id); + if (pTransinfo->mail_id == mail_id) { + pTemp = pTransinfo->next ; + if (!pTemp) { + EM_SAFE_FREE(pTransinfo) ; + g_transaction_info_list = NULL; + } + else { + pTransinfo->mail_id = pTransinfo->next->mail_id; + pTransinfo->handle = pTransinfo->next->handle ; + pTransinfo->next = pTransinfo->next->next; + + EM_SAFE_FREE(pTemp); + } + break; + } + else { + pTransinfo = pTransinfo->next ; + } + + }while (pTransinfo); + EM_DEBUG_FUNC_END(); + return true; +} + + +#include <regex.h> + +int reg_replace (char *input_source_text, char *input_old_pattern_string, char *input_new_string) +{ + EM_DEBUG_FUNC_BEGIN("input_source_text [%p], input_old_pattern_string [%p], input_new_string [%p]", input_source_text, input_old_pattern_string, input_new_string); + int error_code = EMF_ERROR_NONE; + char *pos = NULL; + int so, n, nmatch, source_text_length, n_count = 1; + regmatch_t *pmatch = NULL; + regex_t reg_pattern; + + if(!input_source_text || !input_old_pattern_string || !input_new_string) { + EM_DEBUG_EXCEPTION("EMF_ERROR_INVALID_PARAM"); + error_code = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + source_text_length = strlen(input_source_text); + + regcomp(®_pattern, input_old_pattern_string, REG_ICASE); + + nmatch = reg_pattern.re_nsub + 1; + + EM_DEBUG_LOG("nmatch [%d]", nmatch); + + if(nmatch < 1) { + EM_DEBUG_EXCEPTION("EMF_ERROR_INVALID_DATA"); + error_code = EMF_ERROR_INVALID_DATA; + goto FINISH_OFF; + } + + pmatch = (regmatch_t*)em_core_malloc(sizeof(regmatch_t) * nmatch); + + if(pmatch == NULL) { + EM_DEBUG_EXCEPTION("EMF_ERROR_OUT_OF_MEMORY"); + error_code = EMF_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + for (pos = input_new_string; *pos ; pos++) { + if (*pos == '\\' && *(pos + 1) > '0' && *(pos + 1) <= '9') { + + so = pmatch[*(pos + 1) - 48].rm_so; + n = pmatch[*(pos + 1) - 48].rm_eo - so; + + EM_DEBUG_LOG("so [%d], n [%d]", so, n); + + if (so < 0 || strlen (input_new_string) + n - 1 > source_text_length) + break; + + memmove (pos + n, pos + 2, strlen (pos) - 1); + memmove (pos, input_source_text + so, n); + pos = pos + n - 2; + } + } + + for (pos = input_source_text; !regexec (®_pattern, pos, 1, pmatch, 0);) { + n = pmatch[0].rm_eo - pmatch[0].rm_so; + pos += pmatch[0].rm_so; + + memmove (pos + strlen (input_new_string), pos + n, strlen (pos) - n + 1); + memmove (pos, input_new_string, strlen (input_new_string)); + pos += strlen (input_new_string); + n_count++; + } + +FINISH_OFF: + + EM_SAFE_FREE(pmatch); + regfree (®_pattern); + + EM_DEBUG_FUNC_END("error_code [%d]", error_code); + return error_code; +} + + +EXPORT_API int em_core_strip_HTML(char *source_string) +{ + EM_DEBUG_FUNC_BEGIN("source_string [%p]", source_string); + + int result = EMF_ERROR_NONE; + + reg_replace(source_string, CR_STRING, ""); + reg_replace(source_string, LF_STRING, ""); + reg_replace(source_string, TAB_STRING, ""); + reg_replace(source_string, "<head[^>]*>", "<head>"); /* "<()*head([^>])*>", "<head>" */ + reg_replace(source_string, "<*/head>", "</head>"); /* "(<()*(/)()*head()*>)", "</head>" */ + reg_replace(source_string, "<head>.*</head>", ""); /* "(<head>).*(</head>)", "" */ + + reg_replace(source_string, "<*/p>", LF_STRING); + + /* "<[^>]*>", " */ + reg_replace(source_string, "<[^>]*>", ""); + + + /* "•", " * */ + /* reg_replace(source_string, "•", " * "); */ + + /* "‹", "< */ + /* reg_replace(source_string, "‹", "<"); */ + + /* "›", "> */ + /* reg_replace(source_string, "›", ">"); */ + + /* "™", "(tm) */ + /* reg_replace(source_string, "™", "(tm)"); */ + + /* "⁄", "/ */ + /* reg_replace(source_string, "⁄", "/"); */ + + /* "<", "< */ + reg_replace(source_string, "<", "<"); + + /* ">", "> */ + reg_replace(source_string, ">", ">"); + + /* "©", "(c) */ + /* reg_replace(source_string, "©", "(c)"); */ + + /* """, "\' */ + reg_replace(source_string, """, "\'"); + + /* " ", " */ + reg_replace(source_string, " ", " "); + + reg_replace(source_string, "\n\n", ""); + reg_replace(source_string, " ", ""); + + EM_DEBUG_FUNC_END(); + + return result; +} + +#define MAX_NOTI_STRING_LENGTH 8096 + +EXPORT_API int em_core_convert_structure_to_string(void *struct_var, char **encoded_string, emf_convert_struct_type_e type) +{ + EM_DEBUG_FUNC_BEGIN("Struct type[%d]", type); + + char *buf = NULL; + char delimiter[] = {0x01, 0x00}; + int error_code = EMF_ERROR_NONE; + + buf = (char *) malloc(MAX_NOTI_STRING_LENGTH * sizeof(char)); + if (NULL == buf) { + error_code = EMF_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + switch (type) { + case EMF_CONVERT_STRUCT_TYPE_MAIL_LIST_ITEM: { + emf_mail_list_item_t *item = (emf_mail_list_item_t *)struct_var; + SNPRINTF(buf, MAX_NOTI_STRING_LENGTH, + "%d%c" /* int mail_id ; */ + "%d%c" /* int account_id ; */ + "%s%c" /* char mailbox_name[STRING_LENGTH_FOR_DISPLAY] ; */ + "%s%c" /* char from[STRING_LENGTH_FOR_DISPLAY] ; */ + "%s%c" /* char from_email_address[MAX_EMAIL_ADDRESS_LENGTH]; */ + "%s%c" /* char recipients[STRING_LENGTH_FOR_DISPLAY] ; */ + "%s%c" /* char subject[STRING_LENGTH_FOR_DISPLAY] ; */ + "%d%c" /* int is_text_downloaded ; */ + "%s%c" /* char datetime[MAX_DATETIME_STRING_LENGTH] ; */ + "%d%c" /* int flags_seen_field ; */ + "%d%c" /* int priority ; */ + "%d%c" /* int save_status ; */ + "%d%c" /* int is_locked ; */ + "%d%c" /* int is_report_mail ; */ + "%d%c" /* int recipients_count ; */ + "%d%c" /* int has_attachment ; */ + "%d%c" /* int has_drm_attachment ; */ + "%s%c" /* char previewBodyText[MAX_PREVIEW_TEXT_LENGTH] ; */ + "%d%c" /* int thread_id ; */ + "%d%c", /* int thread_item_count ; */ + + item->mail_id, delimiter[0], + item->account_id, delimiter[0], + item->mailbox_name, delimiter[0], + item->from, delimiter[0], + item->from_email_address, delimiter[0], + item->recipients, delimiter[0], + item->subject, delimiter[0], + item->is_text_downloaded, delimiter[0], + item->datetime, delimiter[0], + item->flags_seen_field, delimiter[0], + item->priority, delimiter[0], + item->save_status, delimiter[0], + item->is_locked, delimiter[0], + item->is_report_mail, delimiter[0], + item->recipients_count, delimiter[0], + item->has_attachment, delimiter[0], + item->has_drm_attachment, delimiter[0], + item->previewBodyText, delimiter[0], + item->thread_id, delimiter[0], + item->thread_item_count, delimiter[0] + ); + } + break; + } + +FINISH_OFF: + if (encoded_string) + *encoded_string = buf; + EM_DEBUG_FUNC_END("Struct -> String:[%s]\n", buf); + return error_code; +} + +EXPORT_API int em_core_convert_string_to_structure(const char *encoded_string, void **struct_var, emf_convert_struct_type_e type) +{ + EM_DEBUG_FUNC_BEGIN(); + + int ret = false; + void *temp_struct = NULL; + char *buff = NULL; + char *current_pos = NULL; + char *found_pos = NULL; + char delimiter[] = {0x01, 0x00}; + int error_code = EMF_ERROR_NONE; + + EM_DEBUG_LOG("Struct Type[%d], String:[%s]", type, encoded_string); + + buff = (char *)EM_SAFE_STRDUP(encoded_string); + if (NULL == buff) { + error_code = EMF_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + switch (type) { + case EMF_CONVERT_STRUCT_TYPE_MAIL_LIST_ITEM: { + emf_mail_list_item_t *item = (emf_mail_list_item_t *)malloc(sizeof(emf_mail_list_item_t)); + if (NULL == item) { + error_code = EMF_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + temp_struct = (void *)item; + + current_pos = buff; + + /* mail_id */ + found_pos = strstr(current_pos, delimiter); + if (NULL == found_pos) { + error_code = EMF_ERROR_INVALID_DATA; + goto FINISH_OFF; + } + *found_pos = NULL_CHAR; + item->mail_id = atoi(current_pos); + EM_DEBUG_LOG("mail_id[%d]", item->mail_id); + current_pos = found_pos + 1; + + /* account_id */ + found_pos = strstr(current_pos, delimiter); + if (NULL == found_pos) { + error_code = EMF_ERROR_INVALID_DATA; + goto FINISH_OFF; + } + *found_pos = NULL_CHAR; + item->account_id = atoi(current_pos); + EM_DEBUG_LOG("account_id[%d]", item->account_id); + current_pos = found_pos + 1; + + /* mailbox_name */ + found_pos = strstr(current_pos, delimiter); + if (NULL == found_pos) { + error_code = EMF_ERROR_INVALID_DATA; + goto FINISH_OFF; + } + *found_pos = NULL_CHAR; + strncpy(item->mailbox_name, current_pos, STRING_LENGTH_FOR_DISPLAY-1); + EM_DEBUG_LOG("mailbox_name[%s]", item->mailbox_name); + current_pos = found_pos + 1; + + /* from */ + found_pos = strstr(current_pos, delimiter); + if (NULL == found_pos) { + error_code = EMF_ERROR_INVALID_DATA; + goto FINISH_OFF; + } + *found_pos = NULL_CHAR; + strncpy(item->from, current_pos, STRING_LENGTH_FOR_DISPLAY-1); + EM_DEBUG_LOG("from[%s]", item->from); + current_pos = found_pos + 1; + + /* from_email_address */ + found_pos = strstr(current_pos, delimiter); + if (NULL == found_pos) { + error_code = EMF_ERROR_INVALID_DATA; + goto FINISH_OFF; + } + *found_pos = NULL_CHAR; + strncpy(item->from_email_address, current_pos, STRING_LENGTH_FOR_DISPLAY-1); + EM_DEBUG_LOG("from_email_address[%s]", item->from_email_address); + current_pos = found_pos + 1; + + /* recipients */ + found_pos = strstr(current_pos, delimiter); + if (NULL == found_pos) { + error_code = EMF_ERROR_INVALID_DATA; + goto FINISH_OFF; + } + *found_pos = NULL_CHAR; + strncpy(item->recipients, current_pos, STRING_LENGTH_FOR_DISPLAY-1); + EM_DEBUG_LOG("recipients[%s]", item->recipients); + current_pos = found_pos + 1; + + /* subject */ + found_pos = strstr(current_pos, delimiter); + if (NULL == found_pos) { + error_code = EMF_ERROR_INVALID_DATA; + goto FINISH_OFF; + } + *found_pos = NULL_CHAR; + strncpy(item->subject, current_pos, STRING_LENGTH_FOR_DISPLAY-1); + EM_DEBUG_LOG("subject[%s]", item->subject); + current_pos = found_pos + 1; + + /* is_text_downloaded */ + found_pos = strstr(current_pos, delimiter); + if (NULL == found_pos) { + error_code = EMF_ERROR_INVALID_DATA; + goto FINISH_OFF; + } + *found_pos = NULL_CHAR; + item->is_text_downloaded = atoi(current_pos); + EM_DEBUG_LOG("is_text_downloaded[%d]", item->is_text_downloaded); + current_pos = found_pos + 1; + + /* datatime */ + found_pos = strstr(current_pos, delimiter); + if (NULL == found_pos) { + error_code = EMF_ERROR_INVALID_DATA; + goto FINISH_OFF; + } + *found_pos = NULL_CHAR; + strncpy(item->datetime, current_pos, MAX_DATETIME_STRING_LENGTH-1); + EM_DEBUG_LOG("datetime[%s]", item->datetime); + current_pos = found_pos + 1; + + /* flags_seen_field */ + found_pos = strstr(current_pos, delimiter); + if (NULL == found_pos) { + error_code = EMF_ERROR_INVALID_DATA; + goto FINISH_OFF; + } + *found_pos = NULL_CHAR; + item->flags_seen_field = atoi(current_pos); + EM_DEBUG_LOG("flags_seen_field[%d]", item->flags_seen_field); + current_pos = found_pos + 1; + + /* priority */ + found_pos = strstr(current_pos, delimiter); + if (NULL == found_pos) { + error_code = EMF_ERROR_INVALID_DATA; + goto FINISH_OFF; + } + *found_pos = NULL_CHAR; + item->priority = atoi(current_pos); + EM_DEBUG_LOG("priority[%d]", item->priority); + current_pos = found_pos + 1; + + /* save_status */ + found_pos = strstr(current_pos, delimiter); + if (NULL == found_pos) { + error_code = EMF_ERROR_INVALID_DATA; + goto FINISH_OFF; + } + *found_pos = NULL_CHAR; + item->save_status = atoi(current_pos); + EM_DEBUG_LOG("save_status[%d]", item->save_status); + current_pos = found_pos + 1; + + /* is_locked */ + found_pos = strstr(current_pos, delimiter); + if (NULL == found_pos) { + error_code = EMF_ERROR_INVALID_DATA; + goto FINISH_OFF; + } + *found_pos = NULL_CHAR; + item->is_locked = atoi(current_pos); + EM_DEBUG_LOG("is_locked[%d]", item->is_locked); + current_pos = found_pos + 1; + + /* is_report_mail */ + found_pos = strstr(current_pos, delimiter); + if (NULL == found_pos) { + error_code = EMF_ERROR_INVALID_DATA; + goto FINISH_OFF; + } + *found_pos = NULL_CHAR; + item->is_report_mail = atoi(current_pos); + EM_DEBUG_LOG("is_report_mail[%d]", item->is_report_mail); + current_pos = found_pos + 1; + + /* recipients_count */ + found_pos = strstr(current_pos, delimiter); + if (NULL == found_pos) { + error_code = EMF_ERROR_INVALID_DATA; + goto FINISH_OFF; + } + *found_pos = NULL_CHAR; + item->recipients_count = atoi(current_pos); + EM_DEBUG_LOG("is_report_mail[%d]", item->recipients_count); + current_pos = found_pos + 1; + + /* has_attachment */ + found_pos = strstr(current_pos, delimiter); + if (NULL == found_pos) { + error_code = EMF_ERROR_INVALID_DATA; + goto FINISH_OFF; + } + *found_pos = NULL_CHAR; + item->has_attachment = atoi(current_pos); + EM_DEBUG_LOG("has_attachment[%d]", item->has_attachment); + current_pos = found_pos + 1; + + /* has_drm_attachment */ + found_pos = strstr(current_pos, delimiter); + if (NULL == found_pos) { + error_code = EMF_ERROR_INVALID_DATA; + goto FINISH_OFF; + } + *found_pos = NULL_CHAR; + item->has_drm_attachment = atoi(current_pos); + EM_DEBUG_LOG("has_drm_attachment[%d]", item->has_drm_attachment); + current_pos = found_pos + 1; + + /* previewBodyText */ + found_pos = strstr(current_pos, delimiter); + if (NULL == found_pos) { + error_code = EMF_ERROR_INVALID_DATA; + goto FINISH_OFF; + } + *found_pos = NULL_CHAR; + strncpy(item->previewBodyText, current_pos, MAX_PREVIEW_TEXT_LENGTH-1); + EM_DEBUG_LOG("previewBodyText[%s]", item->previewBodyText); + current_pos = found_pos + 1; + + /* thread_id */ + found_pos = strstr(current_pos, delimiter); + if (NULL == found_pos) { + error_code = EMF_ERROR_INVALID_DATA; + goto FINISH_OFF; + } + *found_pos = NULL_CHAR; + item->thread_id = atoi(current_pos); + EM_DEBUG_LOG("thread_id[%d]", item->thread_id); + current_pos = found_pos + 1; + + /* thread_item_count - the last item */ + item->thread_item_count = atoi(current_pos); + EM_DEBUG_LOG("thread_item_count[%d]", item->thread_item_count); + + } + break; + + default: + EM_DEBUG_EXCEPTION("Unknown structure type"); + break; + } + + ret = true; + +FINISH_OFF: + EM_SAFE_FREE(buff); + if (ret == true) { + if (struct_var) + *struct_var = temp_struct; + } + else { + switch (type) { + case EMF_CONVERT_STRUCT_TYPE_MAIL_LIST_ITEM: + EM_SAFE_FREE(temp_struct); + break; + default: + break; + } + } + EM_DEBUG_FUNC_END(); + return error_code; +} + + +/* em_core_send_noti_for_new_mail is not used currently because DBUS could not send very long message.*/ +/* But I think it can be used to notify incomming new mail for replacing NOTI_MAIL_ADD with some modification(uid should be replaced with mail_id). */ +/* This notification is including addtional information comparing NOTI_MAIL_ADD. */ +/* By this change, email application will be able to add email item without additional DB query. */ +/* It might improve performance of sync email. */ +/* kyuho.jo 2010-09-07 */ + +EXPORT_API int em_core_send_noti_for_new_mail(int account_id, char *mailbox_name, char *subject, char *from, char *uid, char *datetime) +{ + EM_DEBUG_FUNC_BEGIN("mailbox_name(%s) subject(%s), from(%s), uid(%s), datetime(%s)", mailbox_name, subject, from, uid, datetime); + int error_code = EMF_ERROR_NONE; + char *param_string = NULL; + + if (mailbox_name == NULL || subject == NULL || from == NULL || uid == NULL || datetime == NULL) { + error_code = EMF_ERROR_INVALID_PARAM; + EM_DEBUG_EXCEPTION("Invalid parameter, mailbox_name(%p), subject(%p), from(%p), uid(%p), datetime(%p)", mailbox_name, subject, from, uid, datetime); + goto FINISH_OFF; + } + + param_string = malloc(strlen(mailbox_name) + strlen(subject) + strlen(from) + strlen(uid) + strlen(datetime) + 5); + + if (param_string == NULL) { + error_code = EMF_ERROR_OUT_OF_MEMORY; + EM_DEBUG_EXCEPTION("Memory allocation for 'param_string' is failed"); + goto FINISH_OFF; + } + + memset(param_string, 0x00, sizeof(param_string)); + /* TODO: account_name, thread_id */ + /* uid -> mail_id */ + SNPRINTF(param_string, sizeof(param_string), "%s%c%s%c%s%c%s%c%s", mailbox_name, 0x01, subject, 0x01, from, 0x01, uid, 0x01, datetime); + + if (em_storage_notify_network_event(NOTI_DOWNLOAD_NEW_MAIL, account_id, param_string, 0, 0) == 0) { /* failed */ + error_code = EMF_ERROR_UNKNOWN; + EM_DEBUG_EXCEPTION("em_storage_notify_network_event is failed"); + goto FINISH_OFF; + } + +FINISH_OFF: + if (param_string) + free(param_string); + EM_DEBUG_FUNC_END(); + return error_code; +} + + +EXPORT_API +int em_core_find_tag_for_thread_view(char *subject, int *result) +{ + EM_DEBUG_FUNC_BEGIN(); + int error_code = EMF_ERROR_NONE; + char *copy_of_subject = NULL; + + EM_IF_NULL_RETURN_VALUE(subject, EMF_ERROR_INVALID_PARAM); + EM_IF_NULL_RETURN_VALUE(result, EMF_ERROR_INVALID_PARAM); + + *result = FALSE; + + copy_of_subject = EM_SAFE_STRDUP(subject); + + if (copy_of_subject == NULL) { + EM_DEBUG_EXCEPTION("strdup is failed \n"); + goto FINISH_OFF; + } + + em_core_upper_string(copy_of_subject); + EM_DEBUG_LOG("em_core_upper_string result : %s\n", copy_of_subject); + + if (strstr(copy_of_subject, "RE:") == NULL) { + if (strstr(copy_of_subject, "FWD:") == NULL) { + if (strstr(copy_of_subject, "FW:") != NULL) + *result = TRUE; + } + else + *result = TRUE; + } + else + *result = TRUE; + +FINISH_OFF: + EM_SAFE_FREE(copy_of_subject); + + EM_DEBUG_FUNC_END("result : %d", *result); + + return error_code; +} + + +EXPORT_API +int em_core_find_pos_stripped_subject_for_thread_view(char *subject, char *stripped_subject) +{ + EM_DEBUG_FUNC_BEGIN(); + int error_code = EMF_ERROR_NONE; + int gap; + char *copy_of_subject = NULL, *curpos = NULL, *result; + + EM_IF_NULL_RETURN_VALUE(subject, EMF_ERROR_INVALID_PARAM); + EM_IF_NULL_RETURN_VALUE(stripped_subject, EMF_ERROR_INVALID_PARAM); + + copy_of_subject = EM_SAFE_STRDUP(subject); + + if (copy_of_subject == NULL) { + EM_DEBUG_EXCEPTION("strdup is failed"); + goto FINISH_OFF; + } + + em_core_upper_string(copy_of_subject); + curpos = copy_of_subject; + + EM_DEBUG_LOG("em_core_upper_string result : %s", copy_of_subject); + + while ((result = strstr(curpos, "RE:")) != NULL) { + curpos = result + 3; + EM_DEBUG_LOG("RE result : %s", curpos); + } + + while ((result = strstr(curpos, "FWD:")) != NULL) { + curpos = result + 4; + EM_DEBUG_LOG("FWD result : %s", curpos); + } + + while ((result = strstr(curpos, "FW:")) != NULL) { + curpos = result + 3; + EM_DEBUG_LOG("FW result : %s", curpos); + } + + while (curpos != NULL && *curpos == ' ') { + curpos++; + } + + gap = curpos - copy_of_subject; + + strcpy(stripped_subject, subject + gap); + +FINISH_OFF: + EM_SAFE_FREE(copy_of_subject); + + if (error_code == EMF_ERROR_NONE && stripped_subject) + EM_DEBUG_LOG("result[%s]", stripped_subject); + + EM_DEBUG_FUNC_END("error_code[%d]", error_code); + return error_code; +} + +#define MAX_TITLE_LENGTH 1024 +EXPORT_API int em_core_update_notification_for_unread_mail(int account_id) +{ + EM_DEBUG_FUNC_BEGIN("account_id[%d]", account_id); + int error_code = EMF_ERROR_NONE; + notification_error_e noti_err = NOTIFICATION_ERROR_NONE; + + if((noti_err = notification_update(NULL)) != NOTIFICATION_ERROR_NONE) { + EM_DEBUG_EXCEPTION("notification_update failed"); + goto FINISH_OFF; + } + +FINISH_OFF: + + EM_DEBUG_FUNC_END("return [%d]", error_code); + return error_code; +} + +EXPORT_API int em_core_finalize_sync(int account_id, int *error) +{ + EM_DEBUG_FUNC_BEGIN("account_id [%d], error [%p]", account_id, error); + int err = EMF_ERROR_NONE, ret = true, result_sync_status = SYNC_STATUS_FINISHED; + emf_mail_account_tbl_t *account_tbl = NULL; + + if (!em_storage_update_sync_status_of_account(account_id, SET_TYPE_MINUS, SYNC_STATUS_SYNCING, true, &err)) + EM_DEBUG_EXCEPTION("em_storage_update_sync_status_of_account failed [%d]", err); + + if (!em_storage_get_sync_status_of_account(ALL_ACCOUNT, &result_sync_status, &err)) + EM_DEBUG_EXCEPTION("em_storage_get_sync_status_of_account failed [%d]", err); + + if ( result_sync_status == SYNC_STATUS_HAVE_NEW_MAILS) { + if (!em_core_update_notification_for_unread_mail(ALL_ACCOUNT)) + EM_DEBUG_EXCEPTION("em_core_update_notification_for_unread_mail failed"); + em_core_check_unread_mail(); + /* Temp.. exception for EAS */ + if(account_id >= FIRST_ACCOUNT_ID) + em_storage_get_account_by_id(account_id, EMF_ACC_GET_OPT_DEFAULT, &account_tbl, true, &err); + if(account_tbl && account_tbl->receiving_server_type != EMF_SERVER_TYPE_ACTIVE_SYNC) + start_alert(); + } + + EM_DEBUG_FUNC_END(); + return ret; +} + +EXPORT_API int em_core_clear_all_notifications() +{ + int account_count = 0, i; + emf_mail_account_tbl_t *account_list; + int error_code = EMF_ERROR_NONE; + + if(!em_storage_get_account_list(&account_count, &account_list, true, false, &error_code)) { + EM_DEBUG_EXCEPTION("em_storage_get_account_list failed"); + goto FINISH_OFF; + } + + for(i = 0; i < account_count; i++) { + em_core_delete_notification_by_account(account_list[i].account_id); + } + +FINISH_OFF: + if(account_count) { + em_storage_free_account(&account_list, account_count, NULL); + } + + EM_DEBUG_FUNC_END("return[%d]", error_code); + return error_code; +} + +EXPORT_API int em_core_add_notification_for_unread_mail_by_mail_header(int account_id, int mail_id, emf_mail_head_t *mail_header) +{ + EM_DEBUG_FUNC_BEGIN("mail_id[%d], mail_header[%p]", mail_id, mail_header); + EM_PROFILE_BEGIN(profile_em_core_add_notification_for_unread_mail); + + int error_code = EMF_ERROR_NONE; + struct tm log_time_tm; + time_t log_time = 0; + + if (mail_header == NULL) { + EM_DEBUG_EXCEPTION("mail_header is NULL"); + error_code = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + memset(&log_time_tm, 0, sizeof(struct tm)); + + log_time_tm.tm_sec = mail_header->datetime.second; + log_time_tm.tm_min = mail_header->datetime.minute; + log_time_tm.tm_hour = mail_header->datetime.hour; + log_time_tm.tm_mday = mail_header->datetime.day; + log_time_tm.tm_mon = mail_header->datetime.month; + log_time_tm.tm_year = mail_header->datetime.year + 70; + + EM_DEBUG_LOG("sec[%d], min[%d], hour[%d], day[%d], month[%d], year[%d]" + , log_time_tm.tm_sec, log_time_tm.tm_min, log_time_tm.tm_hour, log_time_tm.tm_mday, log_time_tm.tm_mon, log_time_tm.tm_year); + + log_time = mktime(&log_time_tm); + + EM_DEBUG_LOG("log_time[%d]", log_time); + + if (!em_core_add_notification(account_id, mail_id, mail_header->from, mail_header->subject, log_time)) { + EM_DEBUG_EXCEPTION("Failed the em_core_fill_notification_set"); + goto FINISH_OFF; + } +FINISH_OFF: + + EM_PROFILE_END(profile_em_core_add_notification_for_unread_mail); + EM_DEBUG_FUNC_END("return[%d]", error_code); + return error_code; +} + +EXPORT_API int em_core_add_notification_for_unread_mail(emf_mail_data_t *input_mail_data) +{ + EM_DEBUG_FUNC_BEGIN("input_mail_data[%p]", input_mail_data); + + int error_code = EMF_ERROR_NONE; + struct tm log_time_tm = { 0 }; + time_t log_time = 0; + emf_datetime_t datetime_data = { 0 }; + + if (input_mail_data == NULL) { + EM_DEBUG_EXCEPTION("input_mail_data is NULL"); + error_code = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + if(!em_convert_string_to_datetime(input_mail_data->datetime, &datetime_data, &error_code)) { + EM_DEBUG_EXCEPTION("em_convert_string_to_datetime failed"); + goto FINISH_OFF; + } + + log_time_tm.tm_sec = datetime_data.second; + log_time_tm.tm_min = datetime_data.minute; + log_time_tm.tm_hour = datetime_data.hour; + log_time_tm.tm_mday = datetime_data.day; + log_time_tm.tm_mon = datetime_data.month; + log_time_tm.tm_year = datetime_data.year + 70; + + EM_DEBUG_LOG("sec[%d], min[%d], hour[%d], day[%d], month[%d], year[%d]" + , log_time_tm.tm_sec, log_time_tm.tm_min, log_time_tm.tm_hour, log_time_tm.tm_mday, log_time_tm.tm_mon, log_time_tm.tm_year); + + log_time = mktime(&log_time_tm); + + EM_DEBUG_LOG("log_time[%d]", log_time); + + if (!em_core_add_notification(input_mail_data->account_id, input_mail_data->mail_id, input_mail_data->full_address_from, input_mail_data->subject, log_time)) { + EM_DEBUG_EXCEPTION("em_core_add_notification failed"); + goto FINISH_OFF; + } +FINISH_OFF: + + EM_DEBUG_FUNC_END("return[%d]", error_code); + return error_code; +} + + +EXPORT_API int em_core_delete_notification_for_read_mail(int mail_id) +{ + EM_DEBUG_FUNC_BEGIN(); + int error_code = EMF_ERROR_NONE; + EM_DEBUG_FUNC_END(); + return error_code; +} + +#define EAS_EXECUTABLE_PATH "/usr/bin/eas-engine" + +EXPORT_API int em_core_delete_notification_by_account(int account_id) +{ + EM_DEBUG_FUNC_BEGIN("account_id [%d]", account_id); + int error_code = EMF_ERROR_NONE; + EM_DEBUG_FUNC_END(); + return error_code; +} + +#ifdef __FEATURE_BULK_DELETE_MOVE_UPDATE_REQUEST_OPTI__ + +/** + * @fn em_core_convert_to_uid_range_set(emf_id_set_t* id_set, int id_set_count, emf_uid_range_set **uid_range_set, int range_len, int *err_code) + * Prepare a linked list of uid ranges with each node having a uid_range and lowest and highest uid in it. + * + *@author h.gahlaut@samsung.com + * @param[in] id_set Specifies the array of mail_id and corresponding server_mail_id sorted by server_mail_ids in ascending order + * @param[in] id_set_count Specifies the no. of cells in id_set array i.e. no. of sets of mail_ids and server_mail_ids + * @param[in] range_len Specifies the maximum length of string of range allowed. + * @param[out] uid_range_set Returns the uid_ranges formed in the form of a linked list with head stored in uid_range_set pointer + * @param[out] err_code Returns the error code. + * @remarks An example of a uid_range formed is 2:6,8,10,14:15,89, + * While using it the caller should remove the ending, (comma) + * @return This function returns true on success or false on failure. + */ + +EXPORT_API int em_core_convert_to_uid_range_set(emf_id_set_t *id_set, int id_set_count, emf_uid_range_set **uid_range_set, int range_len, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN(); + + int ret = false; + int error = EM_STORAGE_ERROR_NONE; + + if (NULL == id_set || id_set_count <= 0 || NULL == uid_range_set) { + EM_DEBUG_EXCEPTION(" Invalid Parameter id_set[%p] id_set_count[%d] uid_range_set[%p]", id_set, id_set_count, uid_range_set); + error = EM_STORAGE_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + int i = 0; + unsigned long current_uid = 0; + unsigned long first_uid = 0; + unsigned long last_uid = 0; + const int max_subset_string_size = MAX_SUBSET_STRING_SIZE; + char subset_string[MAX_SUBSET_STRING_SIZE] = {0,}; + emf_uid_range_set *current_node = NULL; /* current_node denotes the current node under processing in the linked list of uid_range_set that is to be formed*/ + + if (range_len < (max_subset_string_size + 1)) /* 1 for ending NULL character */ { + EM_DEBUG_EXCEPTION(" Invalid Parameter range_len[%d]", range_len); + error = EM_STORAGE_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + EM_DEBUG_LOG("id set count[%d] range_len[%d]", id_set_count, range_len); + + do { + first_uid = last_uid = current_uid = id_set[i].server_mail_id; + /* Start subset string by putting first server mail id in it from id_set*/ + memset(subset_string, 0x00, max_subset_string_size); + SNPRINTF(subset_string, max_subset_string_size, "%lu", first_uid); + ++i; + + /* Check if only one server mail id was left in id_set */ + if (i >= id_set_count) { + /* No more server mail id left in id_set */ + if (false == em_core_append_subset_string_to_uid_range(subset_string, ¤t_node, uid_range_set, range_len, first_uid, last_uid)) { + EM_DEBUG_EXCEPTION("em_core_append_subset_string_to_uid_range failed"); + goto FINISH_OFF; + } + break; + } + else { + /* More server mail id are present in id_set. Find out if first:last_uid is to be formed or only first_uid will be subset string */ + do { + current_uid = id_set[i].server_mail_id; + if (current_uid == (last_uid + 1)) { + last_uid = current_uid; + ++i; + } + else { + memset(subset_string, 0x00, max_subset_string_size); + if (first_uid != last_uid) /* Form subset string by first_uid:last_uid */ + SNPRINTF(subset_string, max_subset_string_size, "%lu:%lu", first_uid, last_uid); + else /* Form subset string by first_uid */ + SNPRINTF(subset_string, max_subset_string_size, "%lu", first_uid); + + if (false == em_core_append_subset_string_to_uid_range(subset_string, ¤t_node, uid_range_set, range_len, first_uid, last_uid)) { + EM_DEBUG_EXCEPTION("em_core_append_subset_string_to_uid_range failed"); + goto FINISH_OFF; + } + /* To Start formation of new subset string break out of inner loop */ + break; + } + + } while (i < id_set_count); + + /* Flow comes here in two cases : + 1. id_set ended and has continuous numbers at end of id_set so form subset string by first_uid:last_uid . in this case last_uid == current_uid + 2. due to break statement */ + + if (last_uid == current_uid) { + /* Case 1 */ + + memset(subset_string, 0x00, max_subset_string_size); + SNPRINTF(subset_string, max_subset_string_size, "%lu:%lu", first_uid, last_uid); + + if (false == em_core_append_subset_string_to_uid_range(subset_string, ¤t_node, uid_range_set, range_len, first_uid, last_uid)) { + EM_DEBUG_EXCEPTION("em_core_append_subset_string_to_uid_range failed"); + goto FINISH_OFF; + } + } + else { + /* Case 2: Do Nothing */ + } + + } + } while (i < id_set_count); + + ret = true; + +FINISH_OFF: + if (NULL != err_code) + *err_code = error; + EM_DEBUG_FUNC_END(); + return ret; + +} + +/** + * @fn em_core_append_subset_string_to_uid_range(char *subset_string, emf_uid_range_set **uid_range_set, int range_len, unsigned long luid, unsigned long huid) + * Appends the subset_string to uid range if the uid range has not exceeded maximum length(range_len), otherwise creates a new node in linked list of uid range set + * and stores the subset_string in its uid_range. Also sets the lowest and highest uids for the corresponsing uid_range + * + * @author h.gahlaut@samsung.com + * @param[in] subset_string Specifies the subset string to be appended. A subset string can be like X:Y or X where X and Y are uids. + * @param[in] range_len Specifies the maximum length of range string allowed. + * @param[in] luid Specifies the lowest uid in subset string + * @param[in] huid Specifies the highest uid in subset string + * @param[out] uid_range_set Returns the uid_ranges formed in the form of a linked list with head stored in uid_range_set pointer + * @param[out] err_code Returns the error code. + * @remarks + * @return This function returns true on success or false on failure. + */ + +int em_core_append_subset_string_to_uid_range(char *subset_string, emf_uid_range_set **current_node_adr, emf_uid_range_set **uid_range_set, int range_len, unsigned long luid, unsigned long huid) +{ + EM_DEBUG_FUNC_BEGIN(); + emf_uid_range_set *current_node = NULL; + + if (NULL == (*uid_range_set)) { + /*This happens only once when list creation starts. Head Node is allocated */ + current_node = (emf_uid_range_set *)em_core_malloc(sizeof(emf_uid_range_set)); + if (NULL == current_node) { + EM_DEBUG_EXCEPTION("em_core_malloc failed"); + return false; + } + + current_node->uid_range = (char *)em_core_malloc(range_len); + + if (NULL == current_node->uid_range) { + EM_DEBUG_EXCEPTION("em_core_malloc failed"); + EM_SAFE_FREE(current_node); + return false; + } + + SNPRINTF(current_node->uid_range, range_len, "%s,", subset_string); + + current_node->lowest_uid = luid; + current_node->highest_uid = huid; + (*uid_range_set) = current_node; + + (*current_node_adr) = current_node; + + } + else { + /* Apart from first call to this function flow will always come here */ + current_node = (*current_node_adr); + int len_sub_string = strlen(subset_string); + int space_left_in_buffer = range_len - strlen(current_node->uid_range); + + if ((len_sub_string + 1 + 1) <= space_left_in_buffer) /* 1 for comma + 1 for ending null character */ { + SNPRINTF(current_node->uid_range + strlen(current_node->uid_range), space_left_in_buffer, "%s,", subset_string); + current_node->highest_uid = huid; + } + else { + /* No more space left in uid_range string.If continued on it, it will exceeded max size of range_len */ + /* Allocate new node in Uid Range set */ + emf_uid_range_set *new_node = NULL; + + new_node = (emf_uid_range_set *)em_core_malloc(sizeof(emf_uid_range_set)); + + if (NULL == new_node) { + EM_DEBUG_EXCEPTION("em_core_malloc failed"); + return false; + } + + /* Allocate uid_range of new node */ + + new_node->uid_range = (char *)em_core_malloc(range_len); + + if (NULL == new_node->uid_range) { + EM_DEBUG_EXCEPTION("em_core_malloc failed"); + EM_SAFE_FREE(new_node); + return false; + } + + SNPRINTF(new_node->uid_range, range_len, "%s, ", subset_string); + + new_node->lowest_uid = luid; + new_node->highest_uid = huid; + + current_node->next = new_node; + + (*current_node_adr) = new_node; + } + } + EM_DEBUG_FUNC_END(); + return true; +} + +/** + * void em_core_free_uid_range_set(emf_uid_range_set **uid_range_head) + * Frees the linked list of uid ranges + * + * @author h.gahlaut@samsung.com + * @param[in] uid_range_head Head pointer of linked list of uid ranges + * @remarks + * @return This function does not return anything. + */ + +EXPORT_API +void em_core_free_uid_range_set(emf_uid_range_set **uid_range_set) +{ + EM_DEBUG_FUNC_BEGIN(); + + emf_uid_range_set *current_node = NULL; + emf_uid_range_set *uid_range_head = NULL; + + current_node = uid_range_head = (*uid_range_set); /* Make the current node and head ptr point to starting of uid_range_set */ + + while (current_node) { + uid_range_head = current_node->next; /* Move the head ptr to next node*/ + + EM_SAFE_FREE(current_node->uid_range); + EM_SAFE_FREE(current_node); /* Free the current node */ + + current_node = uid_range_head; /* Make the current node point to head ptr */ + } + + (*uid_range_set) = NULL; + EM_DEBUG_FUNC_END(); +} + + +/** + * @fn em_core_form_comma_separated_strings(int numbers[], int num_count, int max_string_len, char *** strings, int *string_count, int *err_code) + * Forms comma separated strings of a give max_string_len from an array of numbers + * + * @author h.gahlaut@samsung.com + * @param[in] numbers Specifies the array of numbers to be converted into comma separated strings. + * @param[in] num_count Specifies the count of numbers in numbers array. + * @param[in] max_string_len Specifies the maximum length of comma separated strings that are to be formed. + * @param[out] strings Returns the base address of a double dimension array which stores the strings. + * @param[out] string_count Returns the number of strings formed. + * @param[out] err_code Returns the error code. + * @remarks If Input to the function is five numbers like 2755 2754 2748 2749 2750 and a given max_string_len is 20. + * Then this function will form two comma separated strings as follows - + * "2755, 2754, 2748" + * "2749, 2750" + * @return This function returns true on success or false on failure. + */ + +EXPORT_API int em_core_form_comma_separated_strings(int numbers[], int num_count, int max_string_len, char *** strings, int *string_count, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN(); + + int error = EM_STORAGE_ERROR_NONE; + int ret = false; + + char **string_list = NULL; + int num_of_strings = 0; + int i = 0; + int j =0; + char num[MAX_INTEGER_LENGTH + 1] = {0, }; + int num_len = 0; + int space_in_buffer = 0; + int len_of_string_formed = 0; + + if (NULL == numbers || num_count <= 0 || \ + max_string_len < (MAX_INTEGER_LENGTH + 2)|| NULL == strings || NULL == string_count) /* 32767, is the highest integer possible in string.This requires 7 bytes of storage in character type array (1 byte for ending NULL and 1 byte for ending comma) so max_string_len should not be less than worst case possible. */ { + EM_DEBUG_EXCEPTION("Invalid Parameter numbers[%p] num_count [%d] max_string_len [%d] strings [%p] string_count[%p]", \ + numbers, num_count, max_string_len, strings, string_count); + error = EM_STORAGE_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + EM_DEBUG_LOG("num_count [%d] max_string_len [%d]", num_count, max_string_len); + + string_list = em_core_malloc(sizeof(char *)); + + if (NULL == string_list) { + EM_DEBUG_EXCEPTION("em_core_malloc failed "); + goto FINISH_OFF; + } + + string_list[num_of_strings] = em_core_malloc(max_string_len); + + if (NULL == string_list[num_of_strings]) { + EM_DEBUG_EXCEPTION("em_core_malloc failed "); + goto FINISH_OFF; + } + + ++num_of_strings; + space_in_buffer = max_string_len; + + for (j = 0; j < num_count;++j) { + memset(num, 0x00, MAX_INTEGER_LENGTH + 1); + SNPRINTF(num, MAX_INTEGER_LENGTH + 1, "%d", numbers[j]); + + num_len = strlen(num); + + len_of_string_formed = strlen(string_list[num_of_strings - 1]); + + space_in_buffer = max_string_len - len_of_string_formed ; + + if (space_in_buffer >= (num_len+1+1)) /* 1 for comma and 1 for ending NULL */ { + SNPRINTF(string_list[num_of_strings - 1] + len_of_string_formed, max_string_len, "%d,", numbers[j]); + } + else { /* Removing comma at end of string */ + string_list[num_of_strings - 1][len_of_string_formed-1] = '\0'; + char **temp = NULL; + temp = (char **)realloc(string_list, sizeof(char *) * (num_of_strings + 1)); /* Allocate new buffer to store a pointer to a new string */ + + if (NULL == temp) { + EM_DEBUG_EXCEPTION("realloc failed"); + goto FINISH_OFF; + } + + memset(temp + num_of_strings, 0X00, sizeof(char *)); + + string_list = temp; + temp = NULL; + string_list[num_of_strings] = em_core_malloc(max_string_len);/* Allocate new buffer to store the string */ + + if (NULL == string_list[num_of_strings]) { + EM_DEBUG_EXCEPTION(" em_core_malloc failed "); + goto FINISH_OFF; + } + ++num_of_strings; + SNPRINTF(string_list[num_of_strings - 1] , max_string_len, "%d,", numbers[j]);/* Start making new string */ + } + } + + /* Removing comma at end of string */ + len_of_string_formed = strlen(string_list[num_of_strings - 1]); + string_list[num_of_strings - 1][len_of_string_formed-1] = '\0'; + ret = true; + +FINISH_OFF: + + if (false == ret) + em_core_free_comma_separated_strings(&string_list, &num_of_strings); + + if (true == ret) { + for (i = 0; i < num_of_strings;++i) + EM_DEBUG_LOG("%s", string_list[i]); + *strings = string_list; + *string_count = num_of_strings; + } + + + if (NULL != err_code) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} +/** + * @fn em_core_free_comma_separated_strings(char *** string_list, int *string_count) + * Frees the double dimensional array of strings. + * + * @author h.gahlaut@samsung.com + * @param[in] uid_range_head Address of base address of double dimensional array of strings. + * @param[in] string_count Address of variable holding the count of strings. + * @remarks + * @return This function does not return anything. + */ +EXPORT_API void em_core_free_comma_separated_strings(char *** string_list, int *string_count) +{ + EM_DEBUG_FUNC_BEGIN(); + int i = 0; + char **str_list = NULL; + int count = 0; + + if (NULL != string_list) { + str_list = *string_list; + + if (0 != *string_count) { + count = *string_count; + for (i = 0; i < count; ++i) + EM_SAFE_FREE(str_list[i]); + } + + EM_SAFE_FREE(str_list); + *string_list = NULL; /* This makes the pointer to be freed as NULL in calling function and saves it from being a dangling pointer for sometime in calling function */ + *string_count = 0; + } + EM_DEBUG_FUNC_END(); +} + + +#endif + + +#include <sys/mman.h> + +/* #define GETSP() ({ unsigned int sp; asm volatile ("mov %0, sp " : "=r"(sp)); sp;}) */ +#define BUF_SIZE 256 +#define PAGE_SIZE (1 << 12) +#define _ALIGN_UP(addr, size) (((addr)+((size)-1))&(~((size)-1))) +#define _ALIGN_DOWN(addr, size) ((addr)&(~((size)-1))) +#define PAGE_ALIGN(addr) _ALIGN_DOWN(addr, PAGE_SIZE) + +int stack_trim(void) +{ + /* + char buf[BUF_SIZE]; + FILE *file; + unsigned int stacktop; + int found = 0; + unsigned int sp; + + asm volatile ("mov %0, sp " : "=r"(sp)); + + sprintf(buf, "/proc/%d/maps", getpid()); + file = fopen(buf, "r"); + while (fgets(buf, BUF_SIZE, file) != NULL) { + if (strstr(buf, "[stack]")) { + found = 1; + break; + } + } + + fclose(file); + + if (found) { + sscanf(buf, "%x-", &stacktop); + if (madvise((void *)PAGE_ALIGN(stacktop), PAGE_ALIGN(sp)-stacktop, MADV_DONTNEED) < 0) + perror("stack madvise fail"); + } + */ + return 1; +} + + +EXPORT_API void em_core_flush_memory() +{ + EM_DEBUG_FUNC_BEGIN(); + /* flush memory in heap */ + malloc_trim(0); + + /* flush memory in stack */ + stack_trim(); + + /* flush memory for sqlite */ + em_storage_flush_db_cache(); + EM_DEBUG_FUNC_END(); +} + +EXPORT_API int em_core_make_attachment_file_name_with_extension(char *source_file_name, char *sub_type, char *result_file_name, int result_file_name_buffer_length, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("source_file_name[%s], sub_type[%s], result_file_name_buffer_length[%d] ", source_file_name, sub_type, result_file_name_buffer_length); + int ret = false, err = EMF_ERROR_NONE; + char *extcheck = NULL; + char attachment_file_name[MAX_PATH + 1] = { 0, }; + + if (!source_file_name || !result_file_name) { + EM_DEBUG_EXCEPTION("Invalid Parameter"); + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + strncpy(attachment_file_name, source_file_name, MAX_PATH); + extcheck = strchr(attachment_file_name, '.'); + + if (extcheck) + EM_DEBUG_LOG("Extension Exist in the Attachment [%s] ", extcheck); + else { /* No extension attached, So add the Extension based on the subtype */ + if (sub_type) { + strcat(attachment_file_name, "."); + strcat(attachment_file_name, sub_type); + EM_DEBUG_LOG("attachment_file_name with extension[%s] ", attachment_file_name); + } + else + EM_DEBUG_LOG("UnKnown Extesnsion"); + + } + memset(result_file_name, 0 , result_file_name_buffer_length); + EM_SAFE_STRNCPY(result_file_name, attachment_file_name, result_file_name_buffer_length - 1); + EM_DEBUG_LOG("*result_file_name[%s]", result_file_name); + ret = true; + +FINISH_OFF: + if (err_code) + *err_code = err; + EM_DEBUG_FUNC_END(); + return ret; +} + +EXPORT_API char *em_core_get_extension_from_file_path(char *source_file_path, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("source_file_path[%s]", source_file_path); + int err = EMF_ERROR_NONE, pos_on_string = 0; + char *extension = NULL; + + if (!source_file_path) { + EM_DEBUG_EXCEPTION("Invalid Parameter"); + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + pos_on_string = strlen(source_file_path) - 1; + + while(pos_on_string > 0 && source_file_path[pos_on_string--] != '.') ; + + if(pos_on_string > 0) + extension = source_file_path + pos_on_string + 2; + + EM_DEBUG_LOG("*extension [%s] pos_on_string [%d]", extension, pos_on_string); + +FINISH_OFF: + if (err_code) + *err_code = err; + EM_DEBUG_FUNC_END(); + return extension; +} + +EXPORT_API int em_core_get_encoding_type_from_file_path(const char *input_file_path, char **output_encoding_type) +{ + EM_DEBUG_FUNC_BEGIN("input_file_path[%d], output_encoding_type[%p]", input_file_path, output_encoding_type); + int err = EMF_ERROR_NONE; + int pos_of_filename = 0; + int pos_of_dot = 0; + int enf_of_string = 0; + int result_string_length = 0; + char *filename = NULL; + char *result_encoding_type = NULL; + + if (!input_file_path || !output_encoding_type) { + EM_DEBUG_EXCEPTION("Invalid Parameter"); + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + enf_of_string = pos_of_filename = strlen(input_file_path) - 1; + + while(pos_of_filename >= 0 && input_file_path[pos_of_filename--] != '/') { + if(input_file_path[pos_of_filename] == '.') + pos_of_dot = pos_of_filename; + } + + if(pos_of_filename != 0) + pos_of_filename += 2; + + filename = (char*)input_file_path + pos_of_filename; + + if(pos_of_dot != 0 && pos_of_dot > pos_of_filename) + result_string_length = pos_of_dot - pos_of_filename; + else + result_string_length = enf_of_string - pos_of_filename; + + EM_DEBUG_LOG("pos_of_dot [%d], pos_of_filename [%d], enf_of_string[%d],result_string_length [%d]", pos_of_dot, pos_of_filename, enf_of_string, result_string_length); + + if( !(result_encoding_type = em_core_malloc(sizeof(char) * (result_string_length + 1))) ) { + EM_DEBUG_EXCEPTION("EMF_ERROR_OUT_OF_MEMORY"); + err = EMF_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + memcpy(result_encoding_type, input_file_path + pos_of_filename, result_string_length); + + EM_DEBUG_LOG("*result_encoding_type [%s]", result_encoding_type); + + *output_encoding_type = result_encoding_type; + +FINISH_OFF: + EM_DEBUG_FUNC_END("err [%d]", err); + return err; +} + + +EXPORT_API int em_core_get_content_type(const char *extension_string, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("extension_string[%s]", extension_string); + int i = 0, err = EMF_ERROR_NONE, result_content_type = TYPEAPPLICATION; + char *image_extension[] = { "jpeg", "jpg", "png", "gif", "bmp", "pic", "agif", "tif", "wbmp" , NULL}; + + if (!extension_string) { + EM_DEBUG_EXCEPTION("Invalid Parameter"); + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + while(image_extension[i]) { + EM_DEBUG_LOG("image_extension[%d] [%s]", i, image_extension[i]); + if(strcasecmp(image_extension[i], extension_string) == 0) { + result_content_type = TYPEIMAGE; + break; + } + i++; + } + +FINISH_OFF: + if (err_code) + *err_code = err; + EM_DEBUG_FUNC_END(); + return result_content_type; +} + +#define DATE_TIME_STRING_LEGNTH 14 + +EXPORT_API char* em_core_get_current_time_string(int *err) +{ + EM_DEBUG_FUNC_BEGIN("err [%p]", err); + + int err_code = EMF_ERROR_NONE; + time_t t = time(NULL); + struct tm *p_tm = NULL; + char *result_date_time = NULL; + + p_tm = gmtime(&t); + + if (!p_tm) { + EM_DEBUG_EXCEPTION("localtime failed..."); + err_code = EMF_ERROR_SYSTEM_FAILURE; + goto FINISH_OFF; + } + + result_date_time = em_core_malloc(DATE_TIME_STRING_LEGNTH + 1); + + SNPRINTF(result_date_time, DATE_TIME_STRING_LEGNTH + 1, "%04d%02d%02d%02d%02d%02d", + p_tm->tm_year + 1900, p_tm->tm_mon + 1, p_tm->tm_mday, + p_tm->tm_hour, p_tm->tm_min, p_tm->tm_sec); + + EM_DEBUG_LOG("result_date_time [%s]", result_date_time); +FINISH_OFF: + + if(err) + *err = err_code; + + EM_DEBUG_FUNC_END(); + return result_date_time; +} + + +#ifdef __LOCAL_ACTIVITY__ +EXPORT_API int em_core_activity_add(emf_activity_tbl_t *new_activity, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN(); + + EM_DEBUG_LOG("\t new_activity[%p], err_code[%p]", new_activity, err_code); + + /* default variable */ + int ret = false; + int err = EMF_ERROR_NONE; + + if (!new_activity) { + EM_DEBUG_LOG("\t new_activity[%p]\n", new_activity); + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + if (!em_storage_add_activity(new_activity, false, &err)) { + EM_DEBUG_LOG("\t em_storage_add_activity falied - %d\n", err); + + goto FINISH_OFF; + } + ret = true; + +FINISH_OFF: + if (err_code) + *err_code = err; + + return ret; +} + +EXPORT_API int em_core_activity_delete(emf_activity_tbl_t *activity, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN(); + + EM_DEBUG_LOG("\t new_activity[%p], err_code[%p]", activity, err_code); + + /* default variable */ + int ret = false; + int err = EMF_ERROR_NONE; + if (!activity) { + EM_DEBUG_LOG("\t new_activity[%p]\n", activity); + + err = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + if (!em_storage_delete_local_activity(activity, true, &err)) { + EM_DEBUG_LOG("\t em_storage_delete_local_activity falied - %d\n", err); + + goto FINISH_OFF; + } + ret = true; + +FINISH_OFF: + if (err_code) + *err_code = err; + + return ret; +} + +EXPORT_API int em_core_get_next_activity_id(int *activity_id, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN(); + + int ret = false; + int err = EMF_ERROR_NONE; + + if (NULL == activity_id) + { + EM_DEBUG_EXCEPTION("\t activity_id[%p]", activity_id); + + err = EM_STORAGE_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + if (false == em_storage_get_next_activity_id(activity_id, &err)) { + EM_DEBUG_LOG("\t em_storage_get_next_activity_id failed - %d\n", err); + goto FINISH_OFF; + } + + ret = true; + + FINISH_OFF: + if (NULL != err_code) { + *err_code = err; + } + + return ret; + +} + +#endif /* __LOCAL_ACTIVITY__ */ + + + +/* EOF */ diff --git a/email-core/em-network/em-network.c b/email-core/em-network/em-network.c new file mode 100755 index 0000000..f967064 --- /dev/null +++ b/email-core/em-network/em-network.c @@ -0,0 +1,487 @@ +/* +* email-service +* +* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. +* +* Contact: Kyuho Jo <kyuho.jo@samsung.com>, Sunghyun Kwon <sh0701.kwon@samsung.com> +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + + + +/****************************************************************************** + * File: em-network.c + * Desc: Data network interface + * + * Auth: + * + * History: + * 2006.11.17 : created + *****************************************************************************/ + +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/stat.h> +#include <signal.h> +#include <netdb.h> +#include <string.h> +#include <unistd.h> +#include <errno.h> +#include <em-storage.h> +#include <vconf.h> +#include "glib.h" + +#include "lnx_inc.h" +#include "utf8aux.h" +#include "c-client.h" +#include "emflib.h" +#include "emf-dbglog.h" +#include "emf-types.h" +#include "em-core-utils.h" +#include "em-core-mailbox.h" + +#ifdef __FEATURE_PARTIAL_BODY_DOWNLOAD__ +#include "em-core-event.h" +#endif + +/* em_core_get_network_status - Get the data network status from vconf */ +static int em_core_get_network_status(int *network_status) +{ + EM_DEBUG_FUNC_BEGIN("network_status [%p]", network_status); + + int value = 0; + + if(!network_status) { + EM_DEBUG_EXCEPTION("EMF_ERROR_INVALID_PARAM"); + return EMF_ERROR_INVALID_PARAM; + } + + if (vconf_get_int(VCONFKEY_NETWORK_STATUS, &value)) { + EM_DEBUG_EXCEPTION("Failed vconf_get_int [VCONFKEY_NETWORK_STATUS]"); + return EMF_ERROR_SYSTEM_FAILURE; + } + + *network_status = value; + + EM_DEBUG_FUNC_END("network_status [%d]", value); + return EMF_ERROR_NONE; +} + +/* Check code for SIM status */ +static int em_core_get_sim_status(int *sim_status) +{ + EM_DEBUG_FUNC_BEGIN(); + int value; + + if(!sim_status) { + EM_DEBUG_EXCEPTION("EMF_ERROR_INVALID_PARAM"); + return EMF_ERROR_INVALID_PARAM; + } + + if (vconf_get_int(VCONFKEY_TELEPHONY_SIM_SLOT, &value) != 0) { + EM_DEBUG_EXCEPTION("Failed vconf_get_int [VCONFKEY_TELEPHONY_SIM_SLOT]"); + return EMF_ERROR_SYSTEM_FAILURE; + } + + *sim_status = value; + + EM_DEBUG_FUNC_END("status[%d]", value); + return EMF_ERROR_NONE; +} + +static int em_core_get_wifi_status(int *wifi_status) +{ + EM_DEBUG_FUNC_BEGIN(); + + int value; + + if(!wifi_status) { + EM_DEBUG_EXCEPTION("EMF_ERROR_INVALID_PARAM"); + return EMF_ERROR_INVALID_PARAM; + } + + if (vconf_get_int(VCONFKEY_WIFI_STATE, &value) != 0) { + EM_DEBUG_EXCEPTION("vconf_get_int failed"); + return EMF_ERROR_SYSTEM_FAILURE; + } + + *wifi_status = value; + + EM_DEBUG_FUNC_END("status[%d]", *wifi_status); + return EMF_ERROR_NONE; +} + + +EXPORT_API int em_core_check_network_status(int *err_code) +{ + EM_DEBUG_FUNC_BEGIN(); + int network_status = 0; + int sim_status = VCONFKEY_TELEPHONY_SIM_UNKNOWN; + int wifi_status = 0; + int err = EMF_ERROR_NONE; + int ret = false; + + if ( (err = em_core_get_network_status(&network_status)) != EMF_ERROR_NONE) { + EM_DEBUG_EXCEPTION("em_core_get_network_status failed [%d]", err); + goto FINISH_OFF; + } + + if(network_status == 0) { + if ( (err = em_core_get_sim_status(&sim_status)) != EMF_ERROR_NONE) { + EM_DEBUG_EXCEPTION("em_core_get_sim_status failed [%d]", err); + goto FINISH_OFF; + } + + if (sim_status != VCONFKEY_TELEPHONY_SIM_INSERTED) { + EM_DEBUG_LOG("EMF_ERROR_NO_SIM_INSERTED"); + if ( (err = em_core_get_wifi_status(&wifi_status)) != EMF_ERROR_NONE) { + EM_DEBUG_EXCEPTION("em_core_get_wifi_status failed [%d]", err); + goto FINISH_OFF; + } + + if (wifi_status == 0) { + EM_DEBUG_EXCEPTION("Furthermore, WIFI is off"); + err = EMF_ERROR_NO_SIM_INSERTED; + goto FINISH_OFF; + } + } + EM_DEBUG_EXCEPTION("EMF_ERROR_NETWORK_NOT_AVAILABLE"); + err = EMF_ERROR_NETWORK_NOT_AVAILABLE; + goto FINISH_OFF; + } + + EM_DEBUG_LOG("Data Network Mode is ON"); + ret = true; + +FINISH_OFF: + + em_core_set_network_error(err); + + if (err_code) + *err_code = err; + + EM_DEBUG_FUNC_END(); + + return ret; +} + +EXPORT_API long em_core_ssl_cert_query_cb(char *reason, char *host, char *cert) +{ + EM_DEBUG_FUNC_BEGIN("reason[%s], host[%s], cert[%s]", reason, host, cert); + int ret = 1; + + /* FIXME : add user interface for Accept or Reject */ + /* 1:Accept - ignore this certificate error */ + /* 0:Reject - stop ssl connection */ + ret = 1; + + EM_DEBUG_FUNC_END("ret[%s]", ret ? "ignore error" : "stop connection"); + return ret; +} + +/* ------ socket read/write handle ---------------------------------------- */ +int _g_canceled = 0; +/* TCPSTREAM = SENDSTREAM->netstream->stream; socket-id = TCPSTREAM->tcpsi, tcpso; */ +/* sockid_in = ((TCPSTREAM*)send_stream->netstream->stream)->tcpsi; */ +/* sockid_out = ((TCPSTREAM*)send_stream->netstream->stream)->tcpso; */ + +EXPORT_API long tcp_getbuffer_lnx(TCPSTREAM *stream, unsigned long size, char *s) +{ + struct timeval tmout; + fd_set readfds; + int nleave, nread, sret, sockid, maxfd; + char *p = s; + int max_timeout = 0; + sockid = stream->tcpsi; + maxfd = sockid + 1; +/* EM_DEBUG_LOG("start sockid %d", sockid); */ + if (sockid < 0) return 0; + + if (stream->ictr > 0) { + int copy_sz; + if (stream->ictr >= size) { + memcpy(p, stream->iptr, size); + copy_sz = size; + } + else { + memcpy(p, stream->iptr, stream->ictr); + copy_sz = stream->ictr; + } + p += copy_sz; + nleave = size - copy_sz; + stream->iptr += copy_sz; + stream->ictr -= copy_sz; + + if (nleave <= 0) { + *p = '\0'; + /* EM_DEBUG_LOG("end"); */ + return 1; + } + } + else { + nleave = size; + } + + while (nleave > 0) { +#ifdef TEST_CANCEL_JOB + if (!em_core_check_thread_status()) { + EM_DEBUG_EXCEPTION("thread canceled"); + tcp_abort(stream); + goto JOB_CANCEL; + } +#endif + /* if (_g_canceled){ */ + /* EM_DEBUG_LOG1("thread canceled\n"); */ + /* tcp_abort(stream); */ + /* return 0; */ + /* } */ + + tmout.tv_usec = 0; + tmout.tv_sec = 1; + FD_ZERO(&readfds); + FD_SET(sockid, &readfds); + + sret = select(maxfd, &readfds, NULL, NULL, &tmout); + if (sret < 0) { + EM_DEBUG_EXCEPTION("select error[%d]\n", errno); + tcp_abort(stream); + return 0; + } + else if (!sret) { + if (max_timeout >= 5) { + EM_DEBUG_EXCEPTION("max select timeout %d", max_timeout); + em_core_set_network_error(EMF_ERROR_NO_RESPONSE); + return 0; + } + EM_DEBUG_EXCEPTION("%d select timeout", max_timeout); + ++max_timeout; + continue; + } + + nread = read(sockid, p, nleave); + if (nread < 0) { + EM_DEBUG_EXCEPTION("socket read error"); +/* if (errno == EINTR) continue; */ + tcp_abort(stream); + return 0; + } + + if (!nread) { + EM_DEBUG_EXCEPTION("socket read no data"); + tcp_abort(stream); + return 0; + } + + p += nread; + nleave -= nread; + } + + *p = '\0'; + + if (_g_canceled) { + EM_DEBUG_EXCEPTION("thread canceled"); + tcp_abort(stream); + return 0; + } + + return 1; +/* EM_DEBUG_LOG("end"); */ +#ifdef TEST_CANCEL_JOB +JOB_CANCEL: + return 0; +#endif +} + +long tcp_getdata_lnx(TCPSTREAM *stream) +{ + struct timeval tmout; + fd_set readfds; + int nread, sret, sockid, maxfd; + int max_timeout = 0; + + sockid = stream->tcpsi; + maxfd = sockid + 1; + + /* EM_DEBUG_LOG("start sockid %d", sockid); */ + if (sockid < 0) return false; + + while (stream->ictr < 1) { +#ifdef TEST_CANCEL_JOB + if (!em_core_check_thread_status()) { + EM_DEBUG_EXCEPTION("thread canceled..."); + tcp_abort(stream); + goto JOB_CANCEL; + } +#endif + + /* if (_g_canceled){ */ + /* EM_DEBUG_LOG1("thread canceled\n"); */ + /* tcp_abort(stream); */ + /* return 0; */ + /* } */ + + tmout.tv_usec = 0;/* 1000*10; */ + tmout.tv_sec = 1; + + FD_ZERO(&readfds); + FD_SET(sockid, &readfds); + + sret = select(maxfd, &readfds, NULL, NULL, &tmout); + + if (sret < 0) { + EM_DEBUG_LOG("select error[%d]", errno); + + tcp_abort(stream); + return false; + } + else if (!sret) { + if (max_timeout >= 50) { + EM_DEBUG_EXCEPTION("max select timeout %d", max_timeout); + + em_core_set_network_error(EMF_ERROR_NO_RESPONSE); + return false; + } + + EM_DEBUG_EXCEPTION("%d select timeout", max_timeout); + + ++max_timeout; + continue; + } + + if ((nread = read(sockid, stream->ibuf, BUFLEN)) < 0) { + EM_DEBUG_EXCEPTION("socket read failed..."); + + em_core_set_network_error(EMF_ERROR_SOCKET_FAILURE); + + /* if (errno == EINTR) contine; */ + tcp_abort(stream); + return false; + } + + if (!nread) { + EM_DEBUG_EXCEPTION("socket read no data..."); + + em_core_set_network_error(EMF_ERROR_INVALID_RESPONSE); + + tcp_abort(stream); + return false; + } + + stream->ictr = nread; + stream->iptr = stream->ibuf; + } + + if (_g_canceled) { + EM_DEBUG_EXCEPTION("\t thread canceled...\n"); + + tcp_abort(stream); + return false; + } + + /* EM_DEBUG_LOG("end"); */ + return true; + +#ifdef TEST_CANCEL_JOB +JOB_CANCEL: + return false; +#endif +} + +EXPORT_API long tcp_sout_lnx(TCPSTREAM *stream, char *string, unsigned long size) +{ + struct timeval tmout; + fd_set writefds; + int sret, nwrite, maxfd, sockid; + int max_timeout = 0; + + sockid = stream->tcpso; + maxfd = sockid + 1; +/* EM_DEBUG_LOG("start sockid %d", sockid); */ + if (sockid < 0) return 0; + + while (size > 0) { +#ifdef TEST_CANCEL_JOB + if (!em_core_check_thread_status()) { + EM_DEBUG_EXCEPTION("thread canceled"); + tcp_abort(stream); + goto JOB_CANCEL; + } +#endif + /* if (_g_canceled){ */ + /* EM_DEBUG_LOG1("thread canceled"); */ + /* tcp_abort(stream); */ + /* return 0; */ + /* } */ + + tmout.tv_usec = 0; + tmout.tv_sec = 1; + FD_ZERO(&writefds); + FD_SET(sockid, &writefds); + + sret = select(maxfd, NULL, &writefds, NULL, &tmout); + if (sret < 0) { + EM_DEBUG_LOG("select error[%d]", errno); + tcp_abort(stream); + return 0; + } + else if (!sret) { + if (max_timeout >= 50) { + EM_DEBUG_EXCEPTION("max select timeout %d", max_timeout); + em_core_set_network_error(EMF_ERROR_NO_RESPONSE); + return 0; + } + EM_DEBUG_EXCEPTION("%d select timeout", max_timeout); + ++max_timeout; + continue; + } + + if (!(nwrite = write(sockid, string, size)) < 0) { + EM_DEBUG_EXCEPTION("socket write error"); +/* if (errno == EINTR) continue; */ + tcp_abort(stream); + return 0; + } + + if (!nwrite) { + EM_DEBUG_EXCEPTION("socket write no data"); + tcp_abort(stream); + return 0; + } + + string += nwrite; + size -= nwrite; + } + + if (_g_canceled) { + EM_DEBUG_EXCEPTION("thread canceled"); + tcp_abort(stream); + return 0; + } +/* EM_DEBUG_LOG("end"); */ + return 1; + +#ifdef TEST_CANCEL_JOB +JOB_CANCEL: + return 0; +#endif +} + +EXPORT_API long tcp_soutr_lnx(TCPSTREAM *stream, char *string) +{ + return tcp_sout_lnx(stream, string, strlen(string)); +} + diff --git a/email-core/em-network/include/em-network.h b/email-core/em-network/include/em-network.h new file mode 100755 index 0000000..abdbe03 --- /dev/null +++ b/email-core/em-network/include/em-network.h @@ -0,0 +1,48 @@ +/* +* email-service +* +* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. +* +* Contact: Kyuho Jo <kyuho.jo@samsung.com>, Sunghyun Kwon <sh0701.kwon@samsung.com> +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/****************************************************************************** + * File : em-network.h + * Desc : + * + * Auth : + * + * History : + * 2011.12.16 : created + *****************************************************************************/ +#ifndef __EM_NETWORK_H__ +#define __EM_NETWORK_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#include "emf-types.h" + +EXPORT_API long em_core_ssl_cert_query_cb(char *reason, char *host, char *cert); +EXPORT_API int em_core_check_network_status(int *err_code); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif diff --git a/email-core/em-storage/em-storage-noti.c b/email-core/em-storage/em-storage-noti.c new file mode 100755 index 0000000..52eceaa --- /dev/null +++ b/email-core/em-storage/em-storage-noti.c @@ -0,0 +1,79 @@ +/* +* email-service +* +* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. +* +* Contact: Kyuho Jo <kyuho.jo@samsung.com>, Sunghyun Kwon <sh0701.kwon@samsung.com> +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <time.h> +#include <sys/types.h> + +#ifdef USE_POWERMGMT +#include <App-manager.h> +#endif + +#include "em-storage.h" +#include "emf-dbglog.h" + +#define EMAIL_SERVICE_GCONF_DIR "/Services/email-service" +#define EMAIL_SERVICE_GCONF_MAIL_FULL "mail-full" + + +#ifdef BACKUP_LCD_DIMMING_STATUS +static GConfValue *g_gconf_backup_value = NULL; +#endif + + + +#ifdef USE_POWERMGMT +EXPORT_API int em_storage_power_management(int *error_code) +{ + EM_DEBUG_FUNC_BEGIN("err_code[%p]", error_code); + int err = EM_STORAGE_ERROR_NONE; + int inst_id = 0; + + app_get_current_inst_id(&inst_id, &err); + + if (AppMgrAppCommand(inst_id, APP_COMMAND_POWER_MGR, APPMGR_SET_PWRMGR_SYS_RUN_STATUS) < 0) { + EM_DEBUG_EXCEPTION("APPMGR_SET_PWRMGR_SYS_RUN_STATUS Failed"); + return false; + } + EM_DEBUG_FUNC_END("APPMGR_SET_PWRMGR_SYS_RUN_STATUS Success"); + + + return true; +} +#endif + +EXPORT_API int em_storage_sleep_on_off(int on, int *error_code) +{ + EM_DEBUG_FUNC_BEGIN(); + return true; +} + +EXPORT_API int em_storage_dimming_on_off(int on, int *error_code) +{ + EM_DEBUG_FUNC_BEGIN("on[%d], err_code[%p]", on, error_code); + + em_storage_sleep_on_off(on, error_code); + + return true; +} diff --git a/email-core/em-storage/em-storage.c b/email-core/em-storage/em-storage.c new file mode 100755 index 0000000..39bb296 --- /dev/null +++ b/email-core/em-storage/em-storage.c @@ -0,0 +1,14242 @@ +/* +* email-service +* +* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. +* +* Contact: Kyuho Jo <kyuho.jo@samsung.com>, Sunghyun Kwon <sh0701.kwon@samsung.com> +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + + +/****************************************************************************** + * File: em_storage.c + * Desc: EMail Framework Storage Library on Sqlite3 + * + * Auth: + * + * History: + * 2007.03.02 : created + *****************************************************************************/ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <time.h> +#include <sys/types.h> +#include <sys/time.h> +#include <sys/wait.h> +#include <glib.h> +#include <sys/stat.h> +#include <unistd.h> +#include <errno.h> +#include <dirent.h> +#include <vconf.h> +#include <sys/mman.h> +#include <ss_manager.h> +#include <fcntl.h> +#include <dbus/dbus.h> +#include <db-util.h> +#include "em-core-utils.h" +#include <pthread.h> +#include "em-storage.h" +#include "emf-dbglog.h" +#include "emf-types.h" + +#define DB_STMT sqlite3_stmt * + +#define SETTING_MEMORY_TEMP_FILE_PATH "/tmp/email_tmp_file" + +#define EMF_STORAGE_CHANGE_NOTI "User.Email.StorageChange" +#define EMF_NETOWRK_CHANGE_NOTI "User.Email.NetworkStatus" + +#define CONTENT_DATA "<head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=" +#define CONTENT_TYPE_DATA "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=" + +#ifndef true +#define true 1 +#define false 0 +#endif + +#define FLAG_SEEN 0x01 +#define FLAG_DELETED 0x02 +#define FLAG_FLAGGED 0x04 +#define FLAG_ANSWERED 0x08 +#define FLAG_OLD 0x10 +#define FLAG_DRAFT 0x20 + +#undef close + +#define ACCOUNT_NAME_LEN_IN_MAIL_ACCOUNT_TBL 50 +#define RECEIVING_SERVER_ADDR_LEN_IN_MAIL_ACCOUNT_TBL 50 +#define EMAIL_ADDR_LEN_IN_MAIL_ACCOUNT_TBL 128 +#define USER_NAME_LEN_IN_MAIL_ACCOUNT_TBL 50 +#define PASSWORD_LEN_IN_MAIL_ACCOUNT_TBL 50 +#define SENDING_SERVER_ADDR_LEN_IN_MAIL_ACCOUNT_TBL 50 +#define SENDING_USER_LEN_IN_MAIL_ACCOUNT_TBL 50 +#define SENDING_PASSWORD_LEN_IN_MAIL_ACCOUNT_TBL 50 +#define DISPLAY_NAME_LEN_IN_MAIL_ACCOUNT_TBL 30 +#define REPLY_TO_ADDR_LEN_IN_MAIL_ACCOUNT_TBL 128 +#define RETURN_ADDR_LEN_IN_MAIL_ACCOUNT_TBL 128 +#define LOGO_ICON_PATH_LEN_IN_MAIL_ACCOUNT_TBL 256 +#define DISPLAY_NAME_FROM_LEN_IN_MAIL_ACCOUNT_TBL 256 +#define SIGNATURE_LEN_IN_MAIL_ACCOUNT_TBL 256 +#define MAILBOX_NAME_LEN_IN_MAIL_BOX_TBL 128 +#define ALIAS_LEN_IN_MAIL_BOX_TBL 128 +#define LOCAL_MBOX_LEN_IN_MAIL_READ_MAIL_UID_TBL 128 +#define MAILBOX_NAME_LEN_IN_MAIL_READ_MAIL_UID_TBL 128 +#define S_UID_LEN_IN_MAIL_READ_MAIL_UID_TBL 128 +#define DATA2_LEN_IN_MAIL_READ_MAIL_UID_TBL 256 +#define VALUE_LEN_IN_MAIL_RULE_TBL 256 +#define DEST_MAILBOX_LEN_IN_MAIL_RULE_TBL 128 +#define MAILBOX_NAME_LEN_IN_MAIL_ATTACHMENT_TBL 128 +#define ATTACHMENT_PATH_LEN_IN_MAIL_ATTACHMENT_TBL 256 +#define ATTACHMENT_NAME_LEN_IN_MAIL_ATTACHMENT_TBL 256 +#define CONTENT_ID_LEN_IN_MAIL_ATTACHMENT_TBL 256 +#define MAILBOX_LEN_IN_MAIL_TBL 128 +#define SERVER_MAILBOX_LEN_IN_MAIL_TBL 128 +#define SERVER_MAIL_ID_LEN_IN_MAIL_TBL 128 +#define FROM_LEN_IN_MAIL_TBL 256 +#define SENDER_LEN_IN_MAIL_TBL 256 +#define REPLY_TO_LEN_IN_MAIL_TBL 256 +#define TO_LEN_IN_MAIL_TBL 3999 +#define CC_LEN_IN_MAIL_TBL 3999 +#define BCC_LEN_IN_MAIL_TBL 3999 +#define RETURN_PATH_LEN_IN_MAIL_TBL 3999 +#define SUBJECT_LEN_IN_MAIL_TBL 1027 +#define THREAD_TOPIC_LEN_IN_MAIL_TBL 256 +#define TEXT_1_LEN_IN_MAIL_TBL 256 +#define TEXT_2_LEN_IN_MAIL_TBL 256 +#define DATETIME_LEN_IN_MAIL_TBL 128 +#define MESSAGE_ID_LEN_IN_MAIL_TBL 256 +#define FROM_CONTACT_NAME_LEN_IN_MAIL_TBL 3999 +#define FROM_EMAIL_ADDRESS_LEN_IN_MAIL_TBL 3999 +#define TO_CONTACT_NAME_LEN_IN_MAIL_TBL 3999 +#define TO_EMAIL_ADDRESS_LEN_IN_MAIL_TBL 3999 +#define MAILBOX_LEN_IN_MAIL_MEETING_TBL 128 +#define LOCATION_LEN_IN_MAIL_MEETING_TBL 1024 +#define GLOBAL_OBJECT_ID_LEN_IN_MAIL_MEETING_TBL 128 +#define STANDARD_NAME_LEN_IN_MAIL_MEETING_TBL 32 +#define DAYLIGHT_NAME_LEN_IN_MAIL_MEETING_TBL 32 +#define PREVIEWBODY_LEN_IN_MAIL_TBL 512 + +/* this define is used for query to change data (delete, insert, update) */ +#define EM_STORAGE_START_WRITE_TRANSACTION(transaction_flag, error_code) \ + if (transaction_flag)\ + {\ + em_storage_shm_mutex_timedlock(&mapped_for_db_lock, 2);\ + if (em_storage_begin_transaction(NULL, NULL, &error_code) == false) \ + {\ + EM_DEBUG_EXCEPTION("em_storage_begin_transaction() error[%d]", error_code);\ + goto FINISH_OFF;\ + }\ + } + +/* this define is used for query to change data (delete, insert, update) */ +#define EM_STORAGE_FINISH_WRITE_TRANSACTION(transaction_flag, result_code, error_code) \ + if (transaction_flag)\ + {\ + if (result_code == true)\ + {\ + if (em_storage_commit_transaction(NULL, NULL, NULL) == false)\ + {\ + error_code = EM_STORAGE_ERROR_DB_FAILURE;\ + result_code = false;\ + }\ + }\ + else\ + {\ + if (em_storage_rollback_transaction(NULL, NULL, NULL) == false)\ + error_code = EM_STORAGE_ERROR_DB_FAILURE;\ + }\ + em_storage_shm_mutex_unlock(&mapped_for_db_lock);\ + } + +/* this define is used for query to read (select) */ +#define EM_STORAGE_START_READ_TRANSACTION(transaction_flag) \ + if (transaction_flag)\ + {\ + /*em_storage_shm_mutex_timedlock(&mapped_for_db_lock, 2);*/\ + } + +/* this define is used for query to read (select) */ +#define EM_STORAGE_FINISH_READ_TRANSACTION(transaction_flag) \ + if (transaction_flag)\ + {\ + /*em_storage_shm_mutex_unlock(&mapped_for_db_lock);*/\ + } + +/* for safety DB operation */ +static char g_db_path[248] = {0x00, }; + + +#ifdef __FEATURE_USE_PTHREAD__ +static pthread_mutex_t _transactionBeginLock = PTHREAD_MUTEX_INITIALIZER; +static pthread_mutex_t _transactionEndLock = PTHREAD_MUTEX_INITIALIZER; +static pthread_mutex_t _dbus_noti_lock = PTHREAD_MUTEX_INITIALIZER; +static pthread_mutex_t _db_handle_lock = PTHREAD_MUTEX_INITIALIZER; +#else /* __FEATURE_USE_PTHREAD__ */ +static GMutex *_transactionBeginLock = NULL; +static GMutex *_transactionEndLock = NULL; +static GMutex *_dbus_noti_lock = NULL; +static GMutex *_db_handle_lock = NULL; +#endif /* __FEATURE_USE_PTHREAD__ */ + +#define _MULTIPLE_DB_HANDLE + +#ifdef _MULTIPLE_DB_HANDLE + +#define _DISCONNECT_DB /* db_util_close(_db_handle); */ + +typedef struct +{ +#ifdef __FEATURE_USE_PTHREAD__ + pthread_t thread_id; +#else + /* TODO : must write codes for g_thread */ +#endif + sqlite3 *db_handle; +} db_handle_t; + +#define MAX_DB_CLIENT 100 + +/* static int _db_handle_count = 0; */ +db_handle_t _db_handle_list[MAX_DB_CLIENT] = {{0, 0}, }; + +sqlite3 *em_storage_get_db_handle() +{ + EM_DEBUG_FUNC_BEGIN(); + int i; + pthread_t current_thread_id = THREAD_SELF(); + sqlite3 *result_db_handle = NULL; + + ENTER_CRITICAL_SECTION(_db_handle_lock); + for (i = 0; i < MAX_DB_CLIENT; i++) + { + if (pthread_equal(current_thread_id, _db_handle_list[i].thread_id)) + { + EM_DEBUG_LOG("found db handle at [%d]", i); + result_db_handle = _db_handle_list[i].db_handle; + break; + } + } + LEAVE_CRITICAL_SECTION(_db_handle_lock); + + if (!result_db_handle) + EM_DEBUG_EXCEPTION("Can't find proper handle for [%d]", current_thread_id); + + EM_DEBUG_FUNC_END(); + return result_db_handle; +} + +int em_storage_set_db_handle(sqlite3 *db_handle) +{ + EM_DEBUG_FUNC_BEGIN(); + int i, error_code = EMF_ERROR_MAX_EXCEEDED; + pthread_t current_thread_id = THREAD_SELF(); + + ENTER_CRITICAL_SECTION(_db_handle_lock); + for (i = 0; i < MAX_DB_CLIENT; i++) { + if (_db_handle_list[i].thread_id == 0) { + _db_handle_list[i].thread_id = current_thread_id; + _db_handle_list[i].db_handle = db_handle; + EM_DEBUG_LOG("current_thread_id [%d], index [%d]", current_thread_id, i); + error_code = EMF_ERROR_NONE; + break; + } + } + LEAVE_CRITICAL_SECTION(_db_handle_lock); + + if (error_code == EMF_ERROR_MAX_EXCEEDED) + EM_DEBUG_EXCEPTION("Exceeded the limitation of db client. Can't find empty slot in _db_handle_list."); + + EM_DEBUG_FUNC_END("error_code [%d]", error_code); + return error_code; +} + +int em_storage_remove_db_handle() +{ + EM_DEBUG_FUNC_BEGIN(); + int i, error_code = EMF_ERROR_MAX_EXCEEDED; + ENTER_CRITICAL_SECTION(_db_handle_lock); + for (i = 0; i < MAX_DB_CLIENT; i++) + { + if (_db_handle_list[i].thread_id == THREAD_SELF()) + { + _db_handle_list[i].thread_id = 0; + _db_handle_list[i].db_handle = NULL; + EM_DEBUG_LOG("index [%d]", i); + error_code = EMF_ERROR_NONE; + break; + } + } + LEAVE_CRITICAL_SECTION(_db_handle_lock); + + if (error_code == EMF_ERROR_MAX_EXCEEDED) + EM_DEBUG_EXCEPTION("Can't find proper thread_id"); + + EM_DEBUG_FUNC_END("error_code [%d]", error_code); + return error_code; +} + + +int em_storage_reset_db_handle_list() +{ + EM_DEBUG_FUNC_BEGIN(); + int i; + + ENTER_CRITICAL_SECTION(_db_handle_lock); + for (i = 0; i < MAX_DB_CLIENT; i++) + { + _db_handle_list[i].thread_id = 0; + _db_handle_list[i].db_handle = NULL; + } + LEAVE_CRITICAL_SECTION(_db_handle_lock) + + EM_DEBUG_FUNC_END(); + return EMF_ERROR_NONE; +} + +sqlite3 *em_storage_get_db_connection() +{ + sqlite3 *tmp_db_handle = em_storage_get_db_handle(); + if (NULL == tmp_db_handle) + tmp_db_handle = em_storage_db_open(NULL); + return tmp_db_handle; +} + + +#else /* _MULTIPLE_DB_HANDLE */ +#define _DISCONNECT_DB /* db_util_close(_db_handle); */ + +sqlite3 *_db_handle = NULL; + +sqlite3 *em_storage_get_db_connection() +{ + if (NULL == _db_handle) + em_storage_db_open(NULL); + return _db_handle; +} +#endif /* _MULTIPLE_DB_HANDLE */ + +/* ------------------------------------------------------------------------------ */ +/* Mutex using shared memory */ +typedef struct +{ + pthread_mutex_t mutex; + int data; +} mmapped_t; + +mmapped_t *mapped_for_db_lock = NULL; +int shm_fd_for_db_lock = 0; + +#ifdef __FEATURE_USE_SHARED_MUTEX_FOR_GENERATING_MAIL_ID__ +mmapped_t *mapped_for_generating_mail_id = NULL; +int shm_fd_for_generating_mail_id = 0; +#endif /* __FEATURE_USE_SHARED_MUTEX_FOR_GENERATING_MAIL_ID__ */ + +#ifdef __FEATURE_USE_SHARED_MUTEX_FOR_PROTECTED_FUNC_CALL__ +#define EM_STORAGE_PROTECTED_FUNC_CALL(function_call, return_value) \ + { em_storage_shm_mutex_timedlock(&mapped_for_db_lock, 2); return_value = function_call; em_storage_shm_mutex_unlock(&mapped_for_db_lock); } +#else /* __FEATURE_USE_SHARED_MUTEX_FOR_PROTECTED_FUNC_CALL__ */ +#define EM_STORAGE_PROTECTED_FUNC_CALL(function_call, return_value) \ + { return_value = function_call; } +#endif /* __FEATURE_USE_SHARED_MUTEX_FOR_PROTECTED_FUNC_CALL__ */ + +EXPORT_API int em_storage_shm_file_init(const char *shm_file_name) +{ + EM_DEBUG_FUNC_BEGIN("shm_file_name [%p]", shm_file_name); + + if(!shm_file_name) { + EM_DEBUG_EXCEPTION("EM_STORAGE_ERROR_INVALID_PARAM"); + return EM_STORAGE_ERROR_INVALID_PARAM; + } + + int fd = shm_open(shm_file_name, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); /* note: permission is not working */ + + if (fd > 0) { + fchmod(fd, 0666); + EM_DEBUG_LOG("** Create SHM FILE **"); + if (ftruncate(fd, sizeof(mmapped_t)) != 0) { + EM_DEBUG_EXCEPTION("ftruncate failed: %s", strerror(errno)); + return EM_STORAGE_ERROR_SYSTEM_FAILURE; + } + + mmapped_t *m = (mmapped_t *)mmap(NULL, sizeof(mmapped_t), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + if (m == MAP_FAILED) { + EM_DEBUG_EXCEPTION("mmap failed: %s", strerror(errno)); + return EM_STORAGE_ERROR_SYSTEM_FAILURE; + } + + m->data = 0; + + pthread_mutexattr_t mattr; + pthread_mutexattr_init(&mattr); + pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_SHARED); + pthread_mutexattr_setrobust_np(&mattr, PTHREAD_MUTEX_ROBUST_NP); + pthread_mutex_init(&(m->mutex), &mattr); + pthread_mutexattr_destroy(&mattr); + } + else { + EM_DEBUG_EXCEPTION("shm_open failed: %s", strerror(errno)); + return EM_STORAGE_ERROR_SYSTEM_FAILURE; + } + close(fd); + EM_DEBUG_FUNC_END(); + return EM_STORAGE_ERROR_NONE; +} + +int em_storage_shm_file_destroy(const char *shm_file_name) +{ + EM_DEBUG_FUNC_BEGIN("shm_file_name [%p]", shm_file_name); + if(!shm_file_name) { + EM_DEBUG_EXCEPTION("EM_STORAGE_ERROR_INVALID_PARAM"); + return EM_STORAGE_ERROR_INVALID_PARAM; + } + + if (shm_unlink(shm_file_name) != 0) + EM_DEBUG_EXCEPTION("shm_unlink failed: %s", strerror(errno)); + EM_DEBUG_FUNC_END(); + return EM_STORAGE_ERROR_NONE; +} + +static int em_storage_shm_mutex_init(const char *shm_file_name, int *param_shm_fd, mmapped_t **param_mapped) +{ + EM_DEBUG_FUNC_BEGIN("shm_file_name [%p] param_shm_fd [%p], param_mapped [%p]", shm_file_name, param_shm_fd, param_mapped); + + if(!shm_file_name || !param_shm_fd || !param_mapped) { + EM_DEBUG_EXCEPTION("EM_STORAGE_ERROR_INVALID_PARAM"); + return EM_STORAGE_ERROR_INVALID_PARAM; + } + + if (!(*param_mapped)) { + EM_DEBUG_LOG("** mapping begin **"); + + if (!(*param_shm_fd)) { /* open shm_file_name at first. Otherwise, the num of files in /proc/pid/fd will be increasing */ + *param_shm_fd = shm_open(shm_file_name, O_RDWR, 0); + if ((*param_shm_fd) == -1) { + EM_DEBUG_EXCEPTION("FAIL: shm_open(): %s", strerror(errno)); + return EM_STORAGE_ERROR_SYSTEM_FAILURE; + } + } + mmapped_t *tmp = (mmapped_t *)mmap(NULL, sizeof(mmapped_t), PROT_READ|PROT_WRITE, MAP_SHARED, (*param_shm_fd), 0); + + if (tmp == MAP_FAILED) { + EM_DEBUG_EXCEPTION("mmap failed: %s", strerror(errno)); + return EM_STORAGE_ERROR_SYSTEM_FAILURE; + } + *param_mapped = tmp; + } + + EM_DEBUG_FUNC_END(); + return EM_STORAGE_ERROR_NONE; +} + +static int em_storage_shm_mutex_timedlock(mmapped_t **param_mapped, int sec) +{ + EM_DEBUG_FUNC_BEGIN("param_mapped [%p], sec [%d]", param_mapped, sec); + + if(!param_mapped) { + EM_DEBUG_EXCEPTION("EM_STORAGE_ERROR_INVALID_PARAM"); + return EM_STORAGE_ERROR_INVALID_PARAM; + } + + struct timespec abs_time; + clock_gettime(CLOCK_REALTIME, &abs_time); + abs_time.tv_sec += sec; + + int err = pthread_mutex_timedlock(&((*param_mapped)->mutex), &abs_time); + + if (err == EOWNERDEAD) { + err = pthread_mutex_consistent_np(&((*param_mapped)->mutex)); + EM_DEBUG_EXCEPTION("Previous owner is dead with lock. Fix mutex : %s", EM_STRERROR(err)); + } + else if (err != 0) { + EM_DEBUG_EXCEPTION("ERROR : %s", EM_STRERROR(err)); + return err; + } + + EM_DEBUG_FUNC_END(); + return EM_STORAGE_ERROR_NONE; +} + +void em_storage_shm_mutex_unlock(mmapped_t **param_mapped) +{ + EM_DEBUG_FUNC_BEGIN(); + pthread_mutex_unlock(&((*param_mapped)->mutex)); + EM_DEBUG_FUNC_END(); +} +/* ------------------------------------------------------------------------------ */ + + +static int _open_counter = 0; +static int g_transaction = false; + +static int em_storage_get_password_file_name(int account_id, char *recv_password_file_name, char *send_password_file_name); +static int em_storage_read_password_ss(char *file_name, char **password); + + +typedef struct { + const char *object_name; + unsigned int data_flag; +} emf_db_object_t; + +static const emf_db_object_t _g_db_tables[] = +{ + { "mail_read_mail_uid_tbl", 1}, + { "mail_tbl", 1}, + { "mail_attachment_tbl", 1}, + { NULL, 0}, +}; + +static const emf_db_object_t _g_db_indexes[] = +{ + { "mail_read_mail_uid_idx1", 1}, + { "mail_idx1", 1}, + { "mail_attachment_idx1", 1}, + { NULL, 1}, +}; + +enum +{ + CREATE_TABLE_MAIL_ACCOUNT_TBL, + CREATE_TABLE_MAIL_BOX_TBL, + CREATE_TABLE_MAIL_READ_MAIL_UID_TBL, + CREATE_TABLE_MAIL_RULE_TBL, + CREATE_TABLE_MAIL_TBL, + CREATE_TABLE_MAIL_ATTACHMENT_TBL, +#ifdef __FEATURE_PARTIAL_BODY_DOWNLOAD__ + CREATE_TABLE_MAIL_PARTIAL_BODY_ACTIVITY_TBL, +#endif + CREATE_TABLE_MAIL_MEETING_TBL, +#ifdef __LOCAL_ACTIVITY__ + CREATE_TABLE_MAIL_LOCAL_ACTIVITY_TBL, +#endif + CREATE_TABLE_MAX, +}; + +enum +{ + DATA1_IDX_IN_MAIL_ACTIVITY_TBL = 0, + TRANSTYPE_IDX_IN_MAIL_ACTIVITY_TBL, + FLAG_IDX_IN_MAIL_ACTIVITY_TBL, +}; + + +enum +{ + ACCOUNT_BIND_TYPE_IDX_IN_MAIL_ACCOUNT_TBL = 0, + ACCOUNT_NAME_IDX_IN_MAIL_ACCOUNT_TBL, + RECEIVING_SERVER_TYPE_TYPE_IDX_IN_MAIL_ACCOUNT_TBL, + RECEIVING_SERVER_ADDR_IDX_IN_MAIL_ACCOUNT_TBL, + EMAIL_ADDR_IDX_IN_MAIL_ACCOUNT_TBL, + USER_NAME_IDX_IN_MAIL_ACCOUNT_TBL, + PASSWORD_IDX_IN_MAIL_ACCOUNT_TBL, + RETRIEVAL_MODE_IDX_IN_MAIL_ACCOUNT_TBL, + PORT_NUM_IDX_IN_MAIL_ACCOUNT_TBL, + USE_SECURITY_IDX_IN_MAIL_ACCOUNT_TBL, + SENDING_SERVER_TYPE_IDX_IN_MAIL_ACCOUNT_TBL, + SENDING_SERVER_ADDR_IDX_IN_MAIL_ACCOUNT_TBL, + SENDING_PORT_NUM_IDX_IN_MAIL_ACCOUNT_TBL, + SENDING_AUTH_IDX_IN_MAIL_ACCOUNT_TBL, + SENDING_SECURITY_IDX_IN_MAIL_ACCOUNT_TBL, + SENDING_USER_IDX_IN_MAIL_ACCOUNT_TBL, + SENDING_PASSWORD_IDX_IN_MAIL_ACCOUNT_TBL, + DISPLAY_NAME_IDX_IN_MAIL_ACCOUNT_TBL, + REPLY_TO_ADDR_IDX_IN_MAIL_ACCOUNT_TBL, + RETURN_ADDR_IDX_IN_MAIL_ACCOUNT_TBL, + ACCOUNT_ID_IDX_IN_MAIL_ACCOUNT_TBL, + KEEP_ON_SERVER_IDX_IN_MAIL_ACCOUNT_TBL, + FLAG1_IDX_IN_MAIL_ACCOUNT_TBL, + FLAG2_IDX_IN_MAIL_ACCOUNT_TBL, + POP_BEFORE_SMTP_IDX_IN_MAIL_ACCOUNT_TBL, + APOP_IDX_IN_MAIL_ACCOUNT_TBL, + LOGO_ICON_PATH_IDX_IN_MAIL_ACCOUNT_TBL, + PRESET_ACCOUNT_IDX_IN_MAIL_ACCOUNT_TBL, + TARGET_STORAGE_IDX_IN_MAIL_ACCOUNT_TBL, + CHECK_INTERVAL_IDX_IN_MAIL_ACCOUNT_TBL, + PRIORITY_IDX_IN_MAIL_ACCOUNT_TBL, + KEEP_LOCAL_COPY_IDX_IN_MAIL_ACCOUNT_TBL, + REQ_DELIVERY_RECEIPT_IDX_IN_MAIL_ACCOUNT_TBL, + REQ_READ_RECEIPT_IDX_IN_MAIL_ACCOUNT_TBL, + DOWNLOAD_LIMIT_IDX_IN_MAIL_ACCOUNT_TBL, + BLOCK_ADDRESS_IDX_IN_MAIL_ACCOUNT_TBL, + BLOCK_SUBJECT_IDX_IN_MAIL_ACCOUNT_TBL, + DISPLAY_NAME_FROM_IDX_IN_MAIL_ACCOUNT_TBL, + REPLY_WITH_BODY_IDX_IN_MAIL_ACCOUNT_TBL, + FORWARD_WITH_FILES_IDX_IN_MAIL_ACCOUNT_TBL, + ADD_MYNAME_CARD_IDX_IN_MAIL_ACCOUNT_TBL, + ADD_SIGNATURE_IDX_IN_MAIL_ACCOUNT_TBL, + SIGNATURE_IDX_IN_MAIL_ACCOUNT_TBL, + ADD_MY_ADDRESS_TO_BCC_IDX_IN_MAIL_ACCOUNT_TBL, + MY_ACCOUNT_ID_IDX_IN_MAIL_ACCOUNT_TBL, + INDEX_COLOR_IDX_IN_MAIL_ACCOUNT_TBL, + SYNC_STATUS_IDX_IN_MAIL_ACCOUNT_TBL, +}; + +enum +{ + TO_RECIPIENT = 0, + CC_RECIPIENT, + BCC_RECIPIENT, +}; +enum +{ + ACCOUNT_ID_IDX_IN_MAIL_BOX_TBL = 0, + LOCAL_YN_IDX_IN_MAIL_BOX_TBL, + MAILBOX_NAME_IDX_IN_MAIL_BOX_TBL, + MAILBOX_TYPE_IDX_IN_MAIL_BOX_TBL, + ALIAS_IDX_IN_MAIL_BOX_TBL, + SYNC_WITH_SERVER_YN_IDX_IN_MAIL_BOX_TBL, + MODIFIABLE_YN_IDX_IN_MAIL_BOX_TBL, + TOTAL_MAIL_COUNT_ON_SERVER_IDX_IN_MAIL_BOX_TBL, + ARCHIVE_IDX_IN_MAIL_BOX_TBL, + MAIL_SLOT_SIZE_IDX_IN_MAIL_BOX_TBL, +}; + +enum +{ + ACCOUNT_ID_IDX_IN_MAIL_READ_MAIL_UID_TBL = 0, + LOCAL_MBOX_IDX_IN_MAIL_READ_MAIL_UID_TBL, + LOCAL_UID_IDX_IN_MAIL_READ_MAIL_UID_TBL, + MAILBOX_NAME_IDX_IN_MAIL_READ_MAIL_UID_TBL, + S_UID_IDX_IN_MAIL_READ_MAIL_UID_TBL, + DATA1_IDX_IN_MAIL_READ_MAIL_UID_TBL, + DATA2_IDX_IN_MAIL_READ_MAIL_UID_TBL, + FLAG_IDX_IN_MAIL_READ_MAIL_UID_TBL, + IDX_NUM_IDX_IN_MAIL_READ_MAIL_UID_TBL, /* unused */ +}; + +enum +{ + ACCOUNT_ID_IDX_IN_MAIL_RULE_TBL = 0, + RULE_ID_IDX_IN_MAIL_RULE_TBL, + TYPE_IDX_IN_MAIL_RULE_TBL, + VALUE_IDX_IN_MAIL_RULE_TBL, + ACTION_TYPE_IDX_IN_MAIL_RULE_TBL, + DEST_MAILBOX_IDX_IN_MAIL_RULE_TBL, + FLAG1_IDX_IN_MAIL_RULE_TBL, + FLAG2_IDX_IN_MAIL_RULE_TBL, +}; + +enum +{ + MAIL_ID_IDX_IN_MAIL_TBL = 0, + ACCOUNT_ID_IDX_IN_MAIL_TBL, + MAILBOX_NAME_IDX_IN_MAIL_TBL, + MAILBOX_TYPE_IDX_IN_MAIL_TBL, + SUBJECT_IDX_IN_MAIL_TBL, + DATETIME_IDX_IN_MAIL_TBL, + SERVER_MAIL_STATUS_IDX_IN_MAIL_TBL, + SERVER_MAILBOX_NAME_IDX_IN_MAIL_TBL, + SERVER_MAIL_ID_IDX_IN_MAIL_TBL, + MESSAGE_ID_IDX_IN_MAIL_TBL, + FULL_ADDRESS_FROM_IDX_IN_MAIL_TBL, + FULL_ADDRESS_REPLY_IDX_IN_MAIL_TBL, + FULL_ADDRESS_TO_IDX_IN_MAIL_TBL, + FULL_ADDRESS_CC_IDX_IN_MAIL_TBL, + FULL_ADDRESS_BCC_IDX_IN_MAIL_TBL, + FULL_ADDRESS_RETURN_IDX_IN_MAIL_TBL, + EMAIL_ADDRESS_SENDER_IDX_IN_MAIL_TBL, + EMAIL_ADDRESS_RECIPIENT_IDX_IN_MAIL_TBL, + ALIAS_SENDER_IDX_IN_MAIL_TBL, + ALIAS_RECIPIENT_IDX_IN_MAIL_TBL, + BODY_DOWNLOAD_STATUS_IDX_IN_MAIL_TBL, + FILE_PATH_PLAIN_IDX_IN_MAIL_TBL, + FILE_PATH_HTML_IDX_IN_MAIL_TBL, + MAIL_SIZE_IDX_IN_MAIL_TBL, + FLAGS_SEEN_FIELD_IDX_IN_MAIL_TBL, + FLAGS_DELETED_FIELD_IDX_IN_MAIL_TBL, + FLAGS_FLAGGED_FIELD_IDX_IN_MAIL_TBL, + FLAGS_ANSWERED_FIELD_IDX_IN_MAIL_TBL, + FLAGS_RECENT_FIELD_IDX_IN_MAIL_TBL, + FLAGS_DRAFT_FIELD_IDX_IN_MAIL_TBL, + FLAGS_FORWARDED_FIELD_IDX_IN_MAIL_TBL, + DRM_STATUS_IDX_IN_MAIL_TBL, + PRIORITY_IDX_IN_MAIL_TBL, + SAVE_STATUS_IDX_IN_MAIL_TBL, + LOCK_STATUS_IDX_IN_MAIL_TBL, + REPORT_STATUS_IDX_IN_MAIL_TBL, + ATTACHMENT_COUNT_IDX_IN_MAIL_TBL, + INLINE_CONTENT_COUNT_IDX_IN_MAIL_TBL, + THREAD_ID_IDX_IN_MAIL_TBL, + THREAD_ITEM_COUNT_IDX_IN_MAIL_TBL, + PREVIEW_TEXT_IDX_IN_MAIL_TBL, + MEETING_REQUEST_STATUS_IDX_IN_MAIL_TBL, + FIELD_COUNT_OF_EMF_MAIL_TBL, /* End of mail_tbl */ +}; + +enum +{ + ATTACHMENT_ID_IDX_IN_MAIL_ATTACHMENT_TBL = 0, + ATTACHMENT_NAME_IDX_IN_MAIL_ATTACHMENT_TBL, + ATTACHMENT_PATH_IDX_IN_MAIL_ATTACHMENT_TBL, + ATTACHMENT_SIZE_IDX_IN_MAIL_ATTACHMENT_TBL, + MAIL_ID_IDX_IN_MAIL_ATTACHMENT_TBL, + ACCOUNT_ID_IDX_IN_MAIL_ATTACHMENT_TBL, + MAILBOX_NAME_IDX_IN_MAIL_ATTACHMENT_TBL, + FILE_YN_IDX_IN_MAIL_ATTACHMENT_TBL, + FLAG1_IDX_IN_MAIL_ATTACHMENT_TBL, + FLAG2_IDX_IN_MAIL_ATTACHMENT_TBL, + FLAG3_IDX_IN_MAIL_ATTACHMENT_TBL, +#ifdef __ATTACHMENT_OPTI__ + ENCODING_IDX_IN_MAIL_ATTACHMENT_TBL, + SECTION_IDX_IN_MAIL_ATTACHMENT_TBL, +#endif +}; + +enum { + IDX_IDX_IN_MAIL_CONTACT_SYNC_TBL = 0, +#ifndef USE_SIMPLE_CONTACT_SYNC_ATTRIBUTES + MAIL_ID_IDX_IN_MAIL_CONTACT_SYNC_TBL, + ACCOUNT_ID_IDX_IN_MAIL_CONTACT_SYNC_TBL, + ADDRESS_TYPE_IDX_IN_MAIL_CONTACT_SYNC_TBL, + ADDRESS_IDX_IDX_IN_MAIL_CONTACT_SYNC_TBL, +#endif + ADDRESS_IDX_IN_MAIL_CONTACT_SYNC_TBL, + CONTACT_ID_IDX_IN_MAIL_CONTACT_SYNC_TBL, + STORAGE_TYPE_IDX_IN_MAIL_CONTACT_SYNC_TBL, + CONTACT_NAME_IDX_IN_MAIL_CONTACT_SYNC_TBL, +#ifndef USE_SIMPLE_CONTACT_SYNC_ATTRIBUTES + DISPLAY_NAME_IDX_IN_MAIL_CONTACT_SYNC_TBL, + FLAG1_IDX_IN_MAIL_CONTACT_SYNC_TBL, +#endif +}; + +/* sowmya.kr 03032010, changes for get list of mails for given addr list */ +typedef struct _em_mail_id_list { + int mail_id; + struct _em_mail_id_list *next; +} em_mail_id_list; + +static char *g_test_query[] = { + /* 1. select mail_account_tbl */ + "SELECT" + " account_bind_type, " + " account_name, " + " receiving_server_type, " + " receiving_server_addr, " + " email_addr, " + " user_name, " + " password, " + " retrieval_mode, " + " port_num, " + " use_security, " + " sending_server_type, " + " sending_server_addr, " + " sending_port_num, " + " sending_auth, " + " sending_security, " + " sending_user, " + " sending_password, " + " display_name, " + " reply_to_addr, " + " return_addr, " + " account_id, " + " keep_on_server, " + " flag1, " + " flag2, " + " pop_before_smtp, " + " apop" + ", logo_icon_path, " + " preset_account, " + " target_storage, " + " check_interval, " + " priority, " + " keep_local_copy, " + " req_delivery_receipt, " + " req_read_receipt, " + " download_limit, " + " block_address, " + " block_subject, " + " display_name_from, " + " reply_with_body, " + " forward_with_files, " + " add_myname_card, " + " add_signature, " + " signature" + ", add_my_address_to_bcc" + ", my_account_id " + ", index_color " + ", sync_status " + " FROM mail_account_tbl", + /* 2. select mail_box_tbl */ + "SELECT " + " mailbox_id, " + " account_id, " + " local_yn, " + " mailbox_name, " + " mailbox_type, " + " alias, " + " sync_with_server_yn, " + " modifiable_yn, " + " total_mail_count_on_server, " + " has_archived_mails, " + " mail_slot_size " + " FROM mail_box_tbl ", + /* 3. select mail_read_mail_uid_tbl */ + "SELECT " + " account_id, " + " local_mbox, " + " local_uid, " + " mailbox_name, " + " s_uid, " + " data1 , " + " data2, " + " flag, " + " idx_num " + " FROM mail_read_mail_uid_tbl ", + /* 4. select mail_rule_tbl */ + "SELECT " + " account_id, " + " rule_id, " + " type, " + " value, " + " action_type, " + " dest_mailbox, " + " flag1, " + " flag2 " + " FROM mail_rule_tbl ", + /* 5. select mail_tbl */ + "SELECT" + " mail_id, " + " account_id, " + " mailbox_name, " + " mailbox_type, " + " subject, " + " date_time, " + " server_mail_status, " + " server_mailbox_name, " + " server_mail_id, " + " message_id, " + " full_address_from, " + " full_address_reply, " + " full_address_to, " + " full_address_cc, " + " full_address_bcc, " + " full_address_return, " + " email_address_sender, " + " email_address_recipient, " + " alias_sender, " + " alias_recipient, " + " body_download_status, " + " file_path_plain, " + " file_path_html, " + " mail_size, " + " flags_seen_field ," + " flags_deleted_field ," + " flags_flagged_field ," + " flags_answered_field ," + " flags_recent_field ," + " flags_draft_field ," + " flags_forwarded_field," + " DRM_status, " + " priority, " + " save_status, " + " lock_status, " + " report_status, " + " attachment_count, " + " inline_content_count, " + " thread_id, " + " thread_item_count, " + " preview_text" + " meeting_request_status, " + " FROM mail_tbl", + /* 6. select mail_attachment_tbl */ + "SELECT " + " attachment_id, " + " attachment_name, " + " attachment_path, " + " attachment_size, " + " mail_id, " + " account_id, " + " mailbox_name, " + " file_yn, " + " flag1, " + " flag2, " + " flag3 " + " FROM mail_attachment_tbl ", + +#ifdef __FEATURE_PARTIAL_BODY_DOWNLOAD__ + "SELECT " + " account_id, " + " mail_id, " + " server_mail_id, " + " activity_id, " + " activity_type, " + " mailbox_name " + " FROM mail_partial_body_activity_tbl ", +#endif + + "SELECT " + " mail_id, " + " account_id, " + " mailbox_name, " + " meeting_response, " + " start_time, " + " end_time, " + " location, " + " global_object_id, " + " offset, " + " standard_name, " + " standard_time_start_date, " + " standard_bias, " + " daylight_name, " + " daylight_time_start_date, " + " daylight_bias " + " FROM mail_meeting_tbl ", + +#ifdef __LOCAL_ACTIVITY__ + "SELECT " + " activity_id, " + " account_id, " + " mail_id, " + " activity_type, " + " server_mailid, " + " src_mbox , " + " dest_mbox " + " FROM mail_local_activity_tbl ", +#endif + NULL, +}; + + +/* ----------- Notification Changes ----------- */ +typedef enum +{ + _NOTI_TYPE_STORAGE, + _NOTI_TYPE_NETWORK +} enotitype_t; + + +EXPORT_API int em_storage_send_noti(enotitype_t notiType, int subType, int data1, int data2, char *data3, int data4) +{ + EM_DEBUG_FUNC_BEGIN(); + EM_PROFILE_BEGIN(profile_em_storage_send_noti); + + int ret = 0; + DBusConnection *connection; + DBusMessage *signal = NULL; + DBusError dbus_error; + dbus_uint32_t error; + const char *nullString = ""; + + ENTER_CRITICAL_SECTION(_dbus_noti_lock); + + dbus_error_init (&dbus_error); + connection = dbus_bus_get(DBUS_BUS_SYSTEM, &dbus_error); + + if (connection == NULL) { + EM_DEBUG_LOG("dbus_bus_get is failed"); + goto FINISH_OFF; + } + + if (notiType == _NOTI_TYPE_STORAGE) { + signal = dbus_message_new_signal("/User/Email/StorageChange", EMF_STORAGE_CHANGE_NOTI, "email"); + + if (signal == NULL) { + EM_DEBUG_EXCEPTION("dbus_message_new_signal is failed"); + goto FINISH_OFF; + } + EM_DEBUG_LOG("/User/Email/StorageChange Signal is created by dbus_message_new_signal"); + + dbus_message_append_args(signal, DBUS_TYPE_INT32, &subType, DBUS_TYPE_INVALID); + dbus_message_append_args(signal, DBUS_TYPE_INT32, &data1, DBUS_TYPE_INVALID); + dbus_message_append_args(signal, DBUS_TYPE_INT32, &data2, DBUS_TYPE_INVALID); + if (data3 == NULL) + dbus_message_append_args(signal, DBUS_TYPE_STRING, &nullString, DBUS_TYPE_INVALID); + else + dbus_message_append_args(signal, DBUS_TYPE_STRING, &data3, DBUS_TYPE_INVALID); + dbus_message_append_args(signal, DBUS_TYPE_INT32, &data4, DBUS_TYPE_INVALID); + } + else if (notiType == _NOTI_TYPE_NETWORK) { + signal = dbus_message_new_signal("/User/Email/NetworkStatus", EMF_NETOWRK_CHANGE_NOTI, "email"); + + if (signal == NULL) { + EM_DEBUG_EXCEPTION("dbus_message_new_signal is failed"); + goto FINISH_OFF; + } + + EM_DEBUG_LOG("/User/Email/NetworkStatus Signal is created by dbus_message_new_signal"); + + dbus_message_append_args(signal, DBUS_TYPE_INT32, &subType, DBUS_TYPE_INVALID); + dbus_message_append_args(signal, DBUS_TYPE_INT32, &data1, DBUS_TYPE_INVALID); + if (data3 == NULL) + dbus_message_append_args(signal, DBUS_TYPE_STRING, &nullString, DBUS_TYPE_INVALID); + else + dbus_message_append_args(signal, DBUS_TYPE_STRING, &data3, DBUS_TYPE_INVALID); + dbus_message_append_args(signal, DBUS_TYPE_INT32, &data2, DBUS_TYPE_INVALID); + dbus_message_append_args(signal, DBUS_TYPE_INT32, &data4, DBUS_TYPE_INVALID); + } + else { + EM_DEBUG_EXCEPTION("Wrong notification type [%d]", notiType); + error = EMF_ERROR_IPC_CRASH; + goto FINISH_OFF; + } + + if (!dbus_connection_send(connection, signal, &error)) { + EM_DEBUG_LOG("dbus_connection_send is failed [%d]", error); + } + else { + EM_DEBUG_LOG("dbus_connection_send is successful"); + ret = 1; + } + +/* EM_DEBUG_LOG("Before dbus_connection_flush"); */ +/* dbus_connection_flush(connection); */ +/* EM_DEBUG_LOG("After dbus_connection_flush"); */ + + ret = true; +FINISH_OFF: + if (signal) + dbus_message_unref(signal); + + LEAVE_CRITICAL_SECTION(_dbus_noti_lock); + EM_PROFILE_END(profile_em_storage_send_noti); + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + + +EXPORT_API int em_storage_notify_storage_event(emf_noti_on_storage_event transaction_type, int data1, int data2 , char *data3, int data4) +{ + EM_DEBUG_FUNC_BEGIN("transaction_type[%d], data1[%d], data2[%d], data3[%p], data4[%d]", transaction_type, data1, data2, data3, data4); + return em_storage_send_noti(_NOTI_TYPE_STORAGE, (int)transaction_type, data1, data2, data3, data4); +} + +EXPORT_API int em_storage_notify_network_event(emf_noti_on_network_event status_type, int data1, char *data2, int data3, int data4) +{ + EM_DEBUG_FUNC_BEGIN("status_type[%d], data1[%d], data2[%p], data3[%d], data4[%d]", status_type, data1, data2, data3, data4); + return em_storage_send_noti(_NOTI_TYPE_NETWORK, (int)status_type, data1, data3, data2, data4); +} + +/* ----------- Notification Changes End----------- */ +static int _getTableFieldDataChar(char **table, char *buf, int index) +{ + if ((table == NULL) || (buf == NULL) || (index < 0)) { + EM_DEBUG_EXCEPTION("table[%p], buf[%p], index[%d]", table, buf, index); + return false; + } + + if (table[index] != NULL) { + *buf = (char)atoi(table[index]); + return true; + } + + /* EM_DEBUG_LOG("Empty field. Set as zero"); */ + + *buf = 0; + return false; +} + +static int _getTableFieldDataInt(char **table, int *buf, int index) +{ + if ((table == NULL) || (buf == NULL) || (index < 0)) { + EM_DEBUG_EXCEPTION("table[%p], buf[%p], index[%d]", table, buf, index); + return false; + } + + if (table[index] != NULL) { + *buf = atoi(table[index]); + return true; + } + + /* EM_DEBUG_LOG("Empty field. Set as zero"); */ + + *buf = 0; + return false; +} + +static int _getTableFieldDataString(char **table, char **buf, int ucs2, int index) +{ + int ret = false; + + if ((table == NULL) || (buf == NULL) || (index < 0)) { + EM_DEBUG_EXCEPTION("table[%p], buf[%p], index[%d]", table, buf, index); + return false; + } + + char *pTemp = table[index]; + int sLen = 0; + if (pTemp == NULL) + *buf = NULL; + else { + sLen = strlen(pTemp); + if(sLen) { + *buf = (char *) em_core_malloc(sLen + 1); + if (*buf == NULL) { + EM_DEBUG_EXCEPTION("malloc is failed"); + goto FINISH_OFF; + } + strncpy(*buf, pTemp, sLen); + } + else + *buf = NULL; + } +#ifdef _PRINT_STORAGE_LOG_ + if (*buf) + EM_DEBUG_LOG("_getTableFieldDataString - buf[%s], index[%d]", *buf, index); + else + EM_DEBUG_LOG("_getTableFieldDataString - No string got "); +#endif + ret = true; +FINISH_OFF: + + return ret; +} + +static int +_getTableFieldDataStringWithoutAllocation(char **table, char *buf, int buffer_size, int ucs2, int index) +{ + if ((table == NULL) || (buf == NULL) || (index < 0)) { + EM_DEBUG_EXCEPTION(" table[%p], buf[%p], index[%d]", table, buf, index); + return false; + } + + char *pTemp = table[index]; + if (pTemp == NULL) + buf = NULL; + else { + memset(buf, 0, buffer_size); + strncpy(buf, pTemp, buffer_size - 1); + } +#ifdef _PRINT_STORAGE_LOG_ + if (buf) + EM_DEBUG_LOG("_getTableFieldDataString - buf[%s], index[%d]", buf, index); + else + EM_DEBUG_LOG("_getTableFieldDataString - No string got "); +#endif + + return true; +} + +static int _getStmtFieldDataChar(DB_STMT hStmt, char *buf, int index) +{ + if ((hStmt == NULL) || (buf == NULL) || (index < 0)) { + EM_DEBUG_EXCEPTION("buf[%p], index[%d]", buf, index); + return false; + } + + if (sqlite3_column_text(hStmt, index) != NULL) { + *buf = (char)sqlite3_column_int(hStmt, index); +#ifdef _PRINT_STORAGE_LOG_ + EM_DEBUG_LOG("_getStmtFieldDataInt [%d]", *buf); +#endif + return true; + } + + EM_DEBUG_LOG("sqlite3_column_int fail. index [%d]", index); + + return false; +} + +static int _getStmtFieldDataInt(DB_STMT hStmt, int *buf, int index) +{ + if ((hStmt == NULL) || (buf == NULL) || (index < 0)) { + EM_DEBUG_EXCEPTION("buf[%p], index[%d]", buf, index); + return false; + } + + if (sqlite3_column_text(hStmt, index) != NULL) { + *buf = sqlite3_column_int(hStmt, index); +#ifdef _PRINT_STORAGE_LOG_ + EM_DEBUG_LOG("_getStmtFieldDataInt [%d]", *buf); +#endif + return true; + } + + EM_DEBUG_LOG("sqlite3_column_int fail. index [%d]", index); + + return false; +} + +static int _getStmtFieldDataString(DB_STMT hStmt, char **buf, int ucs2, int index) +{ + if ((hStmt < 0) || (buf == NULL) || (index < 0)) { + EM_DEBUG_EXCEPTION("hStmt[%d], buf[%p], index[%d]", hStmt, buf, index); + return false; + } + + int sLen = 0; + sLen = sqlite3_column_bytes(hStmt, index); + +#ifdef _PRINT_STORAGE_LOG_ + EM_DEBUG_LOG("_getStmtFieldDataString sqlite3_column_bytes sLen[%d]", sLen); +#endif + + if (sLen > 0) { + *buf = (char *) em_core_malloc(sLen + 1); + strncpy(*buf, (char *)sqlite3_column_text(hStmt, index), sLen); + } + else + *buf = NULL; + +#ifdef _PRINT_STORAGE_LOG_ + if (*buf) + EM_DEBUG_LOG("buf[%s], index[%d]", *buf, index); + else + EM_DEBUG_LOG("_getStmtFieldDataString - No string got"); +#endif + + return false; +} + +static int _getStmtFieldDataStringWithoutAllocation(DB_STMT hStmt, char *buf, int buffer_size, int ucs2, int index) +{ + if ((hStmt < 0) || (buf == NULL) || (index < 0)) { + EM_DEBUG_EXCEPTION("hStmt[%d], buf[%p], buffer_size[%d], index[%d]", hStmt, buf, buffer_size, index); + return false; + } + + int sLen = 0; + sLen = sqlite3_column_bytes(hStmt, index); + +#ifdef _PRINT_STORAGE_LOG_ + EM_DEBUG_LOG("_getStmtFieldDataStringWithoutAllocation sqlite3_column_bytes sLen[%d]", sLen); +#endif + + if (sLen > 0) { + memset(buf, 0, buffer_size); + strncpy(buf, (char *)sqlite3_column_text(hStmt, index), buffer_size - 1); + } + else + strcpy(buf, ""); + +#ifdef _PRINT_STORAGE_LOG_ + EM_DEBUG_LOG("buf[%s], index[%d]", buf, index); +#endif + + return false; +} + +static int _bindStmtFieldDataChar(DB_STMT hStmt, int index, char value) +{ + if ((hStmt == NULL) || (index < 0)) { + EM_DEBUG_EXCEPTION("index[%d]", index); + return false; + } + + int ret = sqlite3_bind_int(hStmt, index+1, (int)value); + + if (ret != SQLITE_OK) { + EM_DEBUG_EXCEPTION("sqlite3_bind_int fail - %d", ret); + return false; + } + + return true; +} + +static int _bindStmtFieldDataInt(DB_STMT hStmt, int index, int value) +{ + if ((hStmt == NULL) || (index < 0)) { + EM_DEBUG_EXCEPTION("index[%d]", index); + return false; + } + + int ret = sqlite3_bind_int(hStmt, index+1, value); + + if (ret != SQLITE_OK) { + EM_DEBUG_EXCEPTION("sqlite3_bind_int fail - %d", ret); + return false; + } + + return true; +} + +static int _bindStmtFieldDataString(DB_STMT hStmt, int index, char *value, int ucs2, int max_len) +{ + if ((hStmt == NULL) || (index < 0)) { + EM_DEBUG_EXCEPTION("index[%d], max_len[%d]", index, max_len); + return false; + } + +#ifdef _PRINT_STORAGE_LOG_ + EM_DEBUG_LOG("hStmt = %p, index = %d, max_len = %d, value = [%s]", hStmt, index, max_len, value); +#endif + + int ret = 0; + if (value != NULL) + ret = sqlite3_bind_text(hStmt, index+1, value, -1, SQLITE_STATIC); + else + ret = sqlite3_bind_text(hStmt, index+1, "", -1, NULL); + + if (ret != SQLITE_OK) { + EM_DEBUG_EXCEPTION("sqlite3_bind_text fail [%d]", ret); + return false; + } + return true; +} + +static int _emf_delete_temp_file(const char *path) +{ + EM_DEBUG_FUNC_BEGIN("path[%p]", path); + + DIR *dp = NULL; + struct dirent *entry = NULL; + + char buf[1024] = {0x00, }; + + if ((dp = opendir(path)) == NULL) { + EM_DEBUG_EXCEPTION("opendir(\"%s\") failed...", path); + return false; + } + + while ((entry = readdir(dp)) != NULL) { + SNPRINTF(buf, sizeof(buf), "%s/%s", path, entry->d_name); + remove(buf); + } + + closedir(dp); + EM_DEBUG_FUNC_END(); + return true; +} + +char *cpy_str(char *src) +{ + char *p = NULL; + + if (src) { + if (!(p = em_core_malloc((int)strlen(src) + 1))) { + EM_DEBUG_EXCEPTION("mailoc failed..."); + return NULL; + } + strncpy(p, src, strlen(src)); + } + + return p; +} + +static void _em_storage_close_once(void) +{ + EM_DEBUG_FUNC_BEGIN(); + + DELETE_CRITICAL_SECTION(_transactionBeginLock); + DELETE_CRITICAL_SECTION(_transactionEndLock); + + EM_DEBUG_FUNC_END(); +} + +EXPORT_API int em_storage_close(int *err_code) +{ + EM_DEBUG_FUNC_BEGIN(); + + int ret = false; + int error = EM_STORAGE_ERROR_NONE; + + em_storage_db_close(&error); + + if (--_open_counter == 0) + _em_storage_close_once(); + + ret = true; + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +static void *_em_storage_open_once(int *err_code) +{ + EM_DEBUG_FUNC_BEGIN(); + + int error = EM_STORAGE_ERROR_NONE; + + mkdir(EMAILPATH, DIRECTORY_PERMISSION); + mkdir(DATA_PATH, DIRECTORY_PERMISSION); + + mkdir(MAILHOME, DIRECTORY_PERMISSION); + + SNPRINTF(g_db_path, sizeof(g_db_path), "%s/%s", MAILHOME, MAILTEMP); + mkdir(g_db_path, DIRECTORY_PERMISSION); + + _emf_delete_temp_file(g_db_path); + + g_transaction = false; + + if (!em_storage_create_table(EMF_CREATE_DB_NORMAL, &error)) { + EM_DEBUG_EXCEPTION(" em_storage_create_table failed - %d", error); + goto FINISH_OFF; + } + +FINISH_OFF: + if (err_code != NULL) + *err_code = error; + + + return NULL; +} + + /* pData : a parameter which is registered when busy handler is registerd */ + /* count : retry count */ +#define EMF_STORAGE_MAX_RETRY_COUNT 20 +static int +em_busy_handler(void *pData, int count) +{ + EM_DEBUG_LOG("Busy Handler Called!!: [%d]", count); + usleep(200000); /* sleep time when SQLITE_LOCK */ + + /* retry will be stopped if busy handler return 0 */ + return EMF_STORAGE_MAX_RETRY_COUNT - count; +} + +static int +em_storage_delete_all_files_and_directories(int *err_code) +{ + EM_DEBUG_FUNC_BEGIN(); + + int error = EM_STORAGE_ERROR_NONE; + int ret = false; + + if (!em_storage_delete_file(EMAIL_SERVICE_DB_FILE_PATH, &error)) { + if (error != EM_STORAGE_ERROR_FILE_NOT_FOUND) { + EM_DEBUG_EXCEPTION("remove failed - %s", EMAIL_SERVICE_DB_FILE_PATH); + goto FINISH_OFF; + } + } + + if (!em_storage_delete_dir(MAILHOME, &error)) { + EM_DEBUG_EXCEPTION("em_storage_delete_dir failed"); + goto FINISH_OFF; + } + + ret = true; + +FINISH_OFF: + if (err_code) + *err_code = error; + EM_DEBUG_FUNC_END(); + return ret; +} + +static int +em_storage_recovery_from_malformed_db_file(int *err_code) +{ + EM_DEBUG_FUNC_BEGIN(); + + int error = EM_STORAGE_ERROR_NONE; + int ret = false; + + /* Delete all files and directories */ + if (!em_storage_delete_all_files_and_directories(&error)) { + EM_DEBUG_EXCEPTION("em_storage_delete_all_files_and_directories failed [%d]", error); + goto FINISH_OFF; + } + + /* Delete all accounts on MyAccount */ + + /* Delete all managed connection to DB */ + em_storage_reset_db_handle_list(); + + ret = true; + +FINISH_OFF: + if (err_code) + *err_code = error; + EM_DEBUG_FUNC_END(); + return ret; +} + + +EXPORT_API int em_db_open(sqlite3 **sqlite_handle, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN(); + int rc = 0; + int error = EM_STORAGE_ERROR_NONE; + int ret = false; + + EM_DEBUG_LOG("*sqlite_handle[%p]", *sqlite_handle); + + if (NULL == *sqlite_handle) { + /* db open */ + EM_DEBUG_LOG("Open DB"); + EM_STORAGE_PROTECTED_FUNC_CALL(db_util_open(EMAIL_SERVICE_DB_FILE_PATH, sqlite_handle, DB_UTIL_REGISTER_HOOK_METHOD), rc); + if (SQLITE_OK != rc) { + EM_DEBUG_EXCEPTION("db_util_open fail:%d -%s", rc, sqlite3_errmsg(*sqlite_handle)); + error = EM_STORAGE_ERROR_DB_FAILURE; + db_util_close(*sqlite_handle); + *sqlite_handle = NULL; + + if (SQLITE_CORRUPT == rc) /* SQLITE_CORRUPT : The database disk image is malformed */ {/* Recovery DB file */ + EM_DEBUG_LOG("The database disk image is malformed. Trying to remove and create database disk image and directories"); + if (!em_storage_recovery_from_malformed_db_file(&error)) { + EM_DEBUG_EXCEPTION("em_storage_recovery_from_malformed_db_file failed [%d]", error); + goto FINISH_OFF; + } + + EM_DEBUG_LOG("Open DB again"); + EM_STORAGE_PROTECTED_FUNC_CALL(db_util_open(EMAIL_SERVICE_DB_FILE_PATH, sqlite_handle, DB_UTIL_REGISTER_HOOK_METHOD), rc); + if (SQLITE_OK != rc) { + EM_DEBUG_EXCEPTION("db_util_open fail:%d -%s", rc, sqlite3_errmsg(*sqlite_handle)); + error = EM_STORAGE_ERROR_DB_FAILURE; + db_util_close(*sqlite_handle); + *sqlite_handle = NULL; + } + } + else + goto FINISH_OFF; + } + EM_DEBUG_LOG(">>>>> DB Handle : *sqlite_handle[%p]", *sqlite_handle); + + /* register busy handler */ + EM_DEBUG_LOG(">>>>> Register busy handler....."); + rc = sqlite3_busy_handler(*sqlite_handle, em_busy_handler, NULL); /* Busy Handler registration, NULL is a parameter which will be passed to handler */ + if (SQLITE_OK != rc) { + EM_DEBUG_EXCEPTION("sqlite3_busy_handler fail:%d -%s", rc, sqlite3_errmsg(*sqlite_handle)); + error = EM_STORAGE_ERROR_DB_FAILURE; + db_util_close(*sqlite_handle); + *sqlite_handle = NULL; + goto FINISH_OFF; + } + } + else { + EM_DEBUG_LOG(">>>>> DB Already Opened......"); + } + + ret = true; + +FINISH_OFF: + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API sqlite3* em_storage_db_open(int *err_code) +{ + EM_DEBUG_FUNC_BEGIN(); +#ifdef _MULTIPLE_DB_HANDLE + sqlite3 *_db_handle = NULL; +#endif + + int error = EM_STORAGE_ERROR_NONE; + + em_storage_shm_mutex_init(SHM_FILE_FOR_DB_LOCK, &shm_fd_for_db_lock, &mapped_for_db_lock); + +#ifdef __FEATURE_USE_SHARED_MUTEX_FOR_GENERATING_MAIL_ID__ + em_storage_shm_mutex_init(SHM_FILE_FOR_MAIL_ID_LOCK, &shm_fd_for_generating_mail_id, &mapped_for_generating_mail_id); +#endif /*__FEATURE_USE_SHARED_MUTEX_FOR_GENERATING_MAIL_ID__ */ + + if (!em_db_open(&_db_handle, &error)) { + EM_DEBUG_EXCEPTION("em_db_open failed[%d]", error); + goto FINISH_OFF; + } + +#ifdef _MULTIPLE_DB_HANDLE + em_storage_set_db_handle(_db_handle); +#endif + +FINISH_OFF: + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%p]", _db_handle); + return _db_handle; +} + +EXPORT_API int em_storage_db_close(int *err_code) +{ + EM_DEBUG_FUNC_BEGIN(); +#ifdef _MULTIPLE_DB_HANDLE + sqlite3 *_db_handle = em_storage_get_db_handle(); +#endif + + int error = EM_STORAGE_ERROR_NONE; + int ret = false; + + DELETE_CRITICAL_SECTION(_transactionBeginLock); + DELETE_CRITICAL_SECTION(_transactionEndLock); + DELETE_CRITICAL_SECTION(_dbus_noti_lock); + + if (_db_handle) { + ret = db_util_close(_db_handle); + + if (ret != SQLITE_OK) { + EM_DEBUG_EXCEPTION(" db_util_close fail - %d", ret); + error = EM_STORAGE_ERROR_DB_FAILURE; + ret = false; + goto FINISH_OFF; + } +#ifdef _MULTIPLE_DB_HANDLE + em_storage_remove_db_handle(); +#endif + _db_handle = NULL; + } + + ret = true; + +FINISH_OFF: + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + + +EXPORT_API int em_storage_open(int *err_code) +{ + EM_DEBUG_FUNC_BEGIN(); + + int ret = false; + int error = EM_STORAGE_ERROR_NONE; + + int retValue; + + retValue = mkdir(DB_PATH, DIRECTORY_PERMISSION); + + EM_DEBUG_LOG("mkdir return- %d", retValue); + EM_DEBUG_LOG("em_storage_open - before db_util_open - pid = %d", getpid()); + + if (em_storage_db_open(&error) == NULL) { + EM_DEBUG_EXCEPTION("em_storage_db_open failed[%d]", error); + goto FINISH_OFF; + } + + + if (_open_counter++ == 0) + _em_storage_open_once(&error); + + ret = true; + +FINISH_OFF: + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + + +EXPORT_API int em_storage_create_table(emf_create_db_t type, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN(); + + int error = EM_STORAGE_ERROR_NONE; + int rc = -1, ret = false; + char sql_query_string[QUERY_SIZE] = {0, }; + char *create_table_query[] = +{ + /* 1. create mail_account_tbl */ + "CREATE TABLE mail_account_tbl \n" + "(\n" + " account_bind_type INTEGER \n" + ", account_name VARCHAR(51) \n" + ", receiving_server_type INTEGER \n" + ", receiving_server_addr VARCHAR(51) \n" + ", email_addr VARCHAR(129) \n" + ", user_name VARCHAR(51) \n" + ", password VARCHAR(51) \n" + ", retrieval_mode INTEGER \n" + ", port_num INTEGER \n" + ", use_security INTEGER \n" + ", sending_server_type INTEGER \n" + ", sending_server_addr VARCHAR(51) \n" + ", sending_port_num INTEGER \n" + ", sending_auth INTEGER \n" + ", sending_security INTEGER \n" + ", sending_user VARCHAR(51) \n" + ", sending_password VARCHAR(51) \n" + ", display_name VARCHAR(31) \n" + ", reply_to_addr VARCHAR(129) \n" + ", return_addr VARCHAR(129) \n" + ", account_id INTEGER PRIMARY KEY \n" + ", keep_on_server INTEGER \n" + ", flag1 INTEGER \n" + ", flag2 INTEGER \n" + ", pop_before_smtp INTEGER \n" /* POP before SMTP authentication */ + ", apop INTEGER \n" /* APOP authentication */ + ", logo_icon_path VARCHAR(256) \n" /* Receiving Option : Account logo icon */ + ", preset_account INTEGER \n" /* Receiving Option : Preset account or not */ + ", target_storage INTEGER \n" /* Receiving Option : Specifies the targetStorage. 0 is phone, 1 is MMC */ + ", check_interval INTEGER \n" /* Receiving Option : Specifies the check interval. Unit is minute */ + ", priority INTEGER \n" /* Sending Option : Specifies the prority. 1=high 3=normal 5=low */ + ", keep_local_copy INTEGER \n" /* Sending Option : */ + ", req_delivery_receipt INTEGER \n" /* Sending Option : */ + ", req_read_receipt INTEGER \n" /* Sending Option : */ + ", download_limit INTEGER \n" /* Sending Option : */ + ", block_address INTEGER \n" /* Sending Option : */ + ", block_subject INTEGER \n" /* Sending Option : */ + ", display_name_from VARCHAR(256) \n" /* Sending Option : */ + ", reply_with_body INTEGER \n" /* Sending Option : */ + ", forward_with_files INTEGER \n" /* Sending Option : */ + ", add_myname_card INTEGER \n" /* Sending Option : */ + ", add_signature INTEGER \n" /* Sending Option : */ + ", signature VARCHAR(256) \n" /* Sending Option : */ + ", add_my_address_to_bcc INTEGER \n" /* Sending Option : */ + ", my_account_id INTEGER \n" /* My Account Id */ + ", index_color INTEGER \n" /* Index color */ + ", sync_status INTEGER \n" /* Sync Status */ + ");", + /* 2. create mail_box_tbl */ + "CREATE TABLE mail_box_tbl \n" + "(\n" + " mailbox_id INTEGER \n" + ", account_id INTEGER \n" + ", local_yn INTEGER \n" + ", mailbox_name VARCHAR(256) \n" + ", mailbox_type INTEGER \n" + ", alias VARCHAR(256) \n" + ", sync_with_server_yn INTEGER \n" + ", modifiable_yn INTEGER \n" + ", total_mail_count_on_server INTEGER \n" + ", has_archived_mails INTEGER \n" + ", mail_slot_size INTEGER \n" + "); \n ", + + /* 3. create mail_read_mail_uid_tbl */ + "CREATE TABLE mail_read_mail_uid_tbl \n" + "(\n" + " account_id INTEGER \n" + ", local_mbox VARCHAR(129) \n" + ", local_uid INTEGER \n" + ", mailbox_name VARCHAR(256) \n" + ", s_uid VARCHAR(129) \n" + ", data1 INTEGER \n" + ", data2 VARCHAR(257) \n" + ", flag INTEGER \n" + ", idx_num INTEGER PRIMARY KEY \n" + "); \n", + /* 4. create mail_rule_tbl */ + "CREATE TABLE mail_rule_tbl \n" + "(\n" + " account_id INTEGER \n" + ", rule_id INTEGER PRIMARY KEY\n" + ", type INTEGER \n" + ", value VARCHAR(257) \n" + ", action_type INTEGER \n" + ", dest_mailbox VARCHAR(129) \n" + ", flag1 INTEGER \n" + ", flag2 INTEGER \n" + "); \n ", + /* 5. create mail_tbl */ + "CREATE TABLE mail_tbl \n" + "(\n" + " mail_id INTEGER PRIMARY KEY \n" + ", account_id INTEGER \n" + ", mailbox_name VARCHAR(129) \n" + ", mailbox_type INTEGER \n" + ", subject UCS2TEXT\ n" + ", date_time VARCHAR(129) \n" /* type change to int or datetime. */ + ", server_mail_status INTEGER \n" + ", server_mailbox_name VARCHAR(129) \n" + ", server_mail_id VARCHAR(129) \n" + ", message_id VARCHAR(257) \n" + ", full_address_from UCS2TEXT \n" + ", full_address_reply UCS2TEXT \n" + ", full_address_to UCS2TEXT \n" + ", full_address_cc UCS2TEXT \n" + ", full_address_bcc UCS2TEXT \n" + ", full_address_return UCS2TEXT \n" + ", email_address_sender UCS2TEXT collation user1 \n" + ", email_address_recipient UCS2TEXT collation user1 \n" + ", alias_sender UCS2TEXT \n" + ", alias_recipient UCS2TEXT \n" + ", body_download_status INTEGER \n" + ", file_path_plain VARCHAR(257) \n" + ", file_path_html VARCHAR(257) \n" + ", mail_size INTEGER \n" + ", flags_seen_field BOOLEAN \n" + ", flags_deleted_field BOOLEAN \n" + ", flags_flagged_field BOOLEAN \n" + ", flags_answered_field BOOLEAN \n" + ", flags_recent_field BOOLEAN \n" + ", flags_draft_field BOOLEAN \n" + ", flags_forwarded_field BOOLEAN \n" + ", DRM_status INTEGER \n" + ", priority INTEGER \n" + ", save_status INTEGER \n" + ", lock_status INTEGER \n" + ", report_status INTEGER \n" + ", attachment_count INTEGER \n" + ", inline_content_count INTEGER \n" + ", thread_id INTEGER \n" + ", thread_item_count INTEGER \n" + ", preview_text UCS2TEXT \n" + ", meeting_request_status INTEGER \n" + ", FOREIGN KEY(account_id) REFERENCES mail_account_tbl(account_id) \n" + "); \n ", + + /* 6. create mail_attachment_tbl */ + "CREATE TABLE mail_attachment_tbl \n" + "(\n" + " attachment_id INTEGER PRIMARY KEY" + ", attachment_name VARCHAR(257) \n" + ", attachment_path VARCHAR(257) \n" + ", attachment_size INTEGER \n" + ", mail_id INTEGER \n" + ", account_id INTEGER \n" + ", mailbox_name VARCHAR(129) \n" + ", file_yn INTEGER \n" + ", flag1 INTEGER \n" + ", flag2 INTEGER \n" + ", flag3 INTEGER \n" +#ifdef __ATTACHMENT_OPTI__ + ", encoding INTEGER \n" + ", section varchar(257) \n" +#endif + "); \n ", + +#ifdef __FEATURE_PARTIAL_BODY_DOWNLOAD__ + + "CREATE TABLE mail_partial_body_activity_tbl \n" + "( \n" + " account_id INTEGER \n" + ", mail_id INTEGER \n" + ", server_mail_id INTEGER \n" + ", activity_id INTEGER PRIMARY KEY \n" + ", activity_type INTEGER \n" + ", mailbox_name VARCHAR(4000) \n" + "); \n ", +#endif + + "CREATE TABLE mail_meeting_tbl \n" + "(\n" + " mail_id INTEGER PRIMARY KEY \n" + ", account_id INTEGER \n" + ", mailbox_name UCS2TEXT \n" + ", meeting_response INTEGER \n" + ", start_time INTEGER \n" + ", end_time INTEGER \n" + ", location UCS2TEXT \n" + ", global_object_id UCS2TEXT \n" + ", offset INTEGER \n" + ", standard_name UCS2TEXT \n" + ", standard_time_start_date INTEGER \n" + ", standard_bias INTEGER \n" + ", daylight_name UCS2TEXT \n" + ", daylight_time_start_date INTEGER \n" + ", daylight_bias INTEGER \n" + "); \n ", + +#ifdef __LOCAL_ACTIVITY__ + "CREATE TABLE mail_local_activity_tbl \n" + "( \n" + " activity_id INTEGER \n" + ", account_id INTEGER \n" + ", mail_id INTEGER \n" + ", activity_type INTEGER \n" + ", server_mailid VARCHAR(129) \n" + ", src_mbox VARCHAR(129) \n" + ", dest_mbox VARCHAR(129) \n" + "); \n ", +#endif + NULL, +}; + + sqlite3 *local_db_handle = em_storage_get_db_connection(); + + EM_DEBUG_LOG("local_db_handle = %p.", local_db_handle); + + char *sql; + char **result; + + sql = "SELECT count(name) FROM sqlite_master WHERE name='mail_account_tbl';"; + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_get_table(local_db_handle, sql, &result, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {goto FINISH_OFF; }, + ("SQL(%s) sqlite3_get_table fail:%d -%s", sql, rc, sqlite3_errmsg(local_db_handle))); + + EM_DEBUG_LOG("em_storage_create_table - result[1] = %s %c", result[1], result[1]); + + if (atoi(result[1]) < 1) { + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, "BEGIN;", NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {goto FINISH_OFF; }, + ("SQL(BEGIN EXCLUSIVE) exec fail:%d -%s", rc, sqlite3_errmsg(local_db_handle))); + + EM_DEBUG_LOG("CREATE TABLE mail_account_tbl"); + + SNPRINTF(sql_query_string, sizeof(sql_query_string), create_table_query[CREATE_TABLE_MAIL_ACCOUNT_TBL]); + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, sql_query_string, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, ("SQL(%s) exec fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + /* create mail_account_tbl unique index */ + SNPRINTF(sql_query_string, sizeof(sql_query_string), "CREATE UNIQUE INDEX mail_account_idx1 ON mail_account_tbl (account_bind_type, account_id)"); + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, sql_query_string, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, ("SQL(%s) exec fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, "END;", NULL, NULL, NULL), rc); + + } /* mail_account_tbl */ + else if (type == EMF_CREATE_DB_CHECK) { + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, g_test_query[CREATE_TABLE_MAIL_ACCOUNT_TBL], NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, ("SQL(%s) exec fail:%d -%s", g_test_query[CREATE_TABLE_MAIL_ACCOUNT_TBL], rc, sqlite3_errmsg(local_db_handle))); + } + + sqlite3_free_table(result); + + + /* 2. create mail_box_tbl */ + sql = "SELECT count(name) FROM sqlite_master WHERE name='mail_box_tbl';"; + /* rc = sqlite3_get_table(local_db_handle, sql, &result, NULL, NULL, NULL); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_get_table(local_db_handle, sql, &result, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {goto FINISH_OFF; }, + ("SQL(%s) sqlite3_get_table fail:%d -%s", sql, rc, sqlite3_errmsg(local_db_handle))); + + if (atoi(result[1]) < 1) { + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, "BEGIN;", NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {goto FINISH_OFF; }, + ("SQL(BEGIN EXCLUSIVE) exec fail:%d -%s", rc, sqlite3_errmsg(local_db_handle))); + + EM_DEBUG_LOG("CREATE TABLE mail_box_tbl"); + + SNPRINTF(sql_query_string, sizeof(sql_query_string), create_table_query[CREATE_TABLE_MAIL_BOX_TBL]); + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, sql_query_string, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) exec fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + /* create mail_local_mailbox_tbl unique index */ + SNPRINTF(sql_query_string, sizeof(sql_query_string), "CREATE UNIQUE INDEX mail_box_idx1 ON mail_box_tbl (account_id, local_yn, mailbox_name)"); + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, sql_query_string, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) exec fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, "END;", NULL, NULL, NULL), rc); + + } /* mail_box_tbl */ + else if (type == EMF_CREATE_DB_CHECK) { + rc = sqlite3_exec(local_db_handle, g_test_query[CREATE_TABLE_MAIL_BOX_TBL], NULL, NULL, NULL); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) exec fail:%d -%s", g_test_query[CREATE_TABLE_MAIL_BOX_TBL], rc, sqlite3_errmsg(local_db_handle))); + } + sqlite3_free_table(result); + + /* 3. create mail_read_mail_uid_tbl */ + sql = "SELECT count(name) FROM sqlite_master WHERE name='mail_read_mail_uid_tbl';"; + /* rc = sqlite3_get_table(local_db_handle, sql, &result, NULL, NULL, NULL); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_get_table(local_db_handle, sql, &result, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {goto FINISH_OFF; }, + ("SQL(%s) sqlite3_get_table fail:%d -%s", sql, rc, sqlite3_errmsg(local_db_handle))); + + + if (atoi(result[1]) < 1) { + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, "BEGIN;", NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {goto FINISH_OFF; }, + ("SQL(BEGIN EXCLUSIVE) exec fail:%d -%s", rc, sqlite3_errmsg(local_db_handle))); + + EM_DEBUG_LOG("CREATE TABLE mail_read_mail_uid_tbl"); + + SNPRINTF(sql_query_string, sizeof(sql_query_string), create_table_query[CREATE_TABLE_MAIL_READ_MAIL_UID_TBL]); + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, sql_query_string, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) exec fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + /* create mail_read_mail_uid_tbl unique index */ + SNPRINTF(sql_query_string, sizeof(sql_query_string), "CREATE UNIQUE INDEX mail_read_mail_uid_idx1 ON mail_read_mail_uid_tbl (account_id, local_mbox, local_uid, mailbox_name, s_uid)"); + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, sql_query_string, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) exec fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, "END;", NULL, NULL, NULL), rc); + + } /* mail_read_mail_uid_tbl */ + else if (type == EMF_CREATE_DB_CHECK) { + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, g_test_query[CREATE_TABLE_MAIL_READ_MAIL_UID_TBL], NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) exec fail:%d -%s", g_test_query[CREATE_TABLE_MAIL_READ_MAIL_UID_TBL], rc, sqlite3_errmsg(local_db_handle))); + } + sqlite3_free_table(result); + + + /* 4. create mail_rule_tbl */ + sql = "SELECT count(name) FROM sqlite_master WHERE name='mail_rule_tbl';"; + /* rc = sqlite3_get_table(local_db_handle, sql, &result, NULL, NULL, NULL); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_get_table(local_db_handle, sql, &result, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {goto FINISH_OFF; }, + ("SQL(%s) sqlite3_get_table fail:%d -%s", sql, rc, sqlite3_errmsg(local_db_handle))); + + if (atoi(result[1]) < 1) { + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, "BEGIN;", NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {goto FINISH_OFF; }, + ("SQL(BEGIN EXCLUSIVE) exec fail:%d -%s", rc, sqlite3_errmsg(local_db_handle))); + + EM_DEBUG_LOG("CREATE TABLE mail_rule_tbl"); + + SNPRINTF(sql_query_string, sizeof(sql_query_string), create_table_query[CREATE_TABLE_MAIL_RULE_TBL]); + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, sql_query_string, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) exec fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, "END;", NULL, NULL, NULL), rc); + + } /* mail_rule_tbl */ + else if (type == EMF_CREATE_DB_CHECK) { + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, g_test_query[CREATE_TABLE_MAIL_RULE_TBL], NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) exec fail:%d -%s", g_test_query[CREATE_TABLE_MAIL_RULE_TBL], rc, sqlite3_errmsg(local_db_handle))); + } + sqlite3_free_table(result); + + + /* 5. create mail_tbl */ + sql = "SELECT count(name) FROM sqlite_master WHERE name='mail_tbl';"; + /* rc = sqlite3_get_table(local_db_handle, sql, &result, NULL, NULL, NULL); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_get_table(local_db_handle, sql, &result, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {goto FINISH_OFF; }, + ("SQL(%s) sqlite3_get_table fail:%d -%s", sql, rc, sqlite3_errmsg(local_db_handle))); + + if (atoi(result[1]) < 1) { + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, "BEGIN;", NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {goto FINISH_OFF; }, + ("SQL(BEGIN EXCLUSIVE) exec fail:%d -%s", rc, sqlite3_errmsg(local_db_handle))); + EM_DEBUG_LOG("CREATE TABLE mail_tbl"); + + SNPRINTF(sql_query_string, sizeof(sql_query_string), create_table_query[CREATE_TABLE_MAIL_TBL]); + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, sql_query_string, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) exec fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + /* create mail_tbl unique index */ + SNPRINTF(sql_query_string, sizeof(sql_query_string), "CREATE UNIQUE INDEX mail_idx1 ON mail_tbl (mail_id, account_id)"); + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, sql_query_string, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) exec fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + /* create mail_tbl index for date_time */ + SNPRINTF(sql_query_string, sizeof(sql_query_string), "CREATE INDEX mail_idx_date_time ON mail_tbl (date_time)"); + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, sql_query_string, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) exec fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + /* create mail_tbl index for thread_item_count */ + SNPRINTF(sql_query_string, sizeof(sql_query_string), "CREATE INDEX mail_idx_thread_mail_count ON mail_tbl (thread_item_count)"); + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, sql_query_string, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) exec fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, "END;", NULL, NULL, NULL), rc); + + /* just one time call */ +/* EFTSInitFTSIndex(FTS_EMAIL_IDX); */ + } /* mail_tbl */ + else if (type == EMF_CREATE_DB_CHECK) { + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, g_test_query[CREATE_TABLE_MAIL_TBL], NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) exec fail:%d -%s", g_test_query[CREATE_TABLE_MAIL_TBL], rc, sqlite3_errmsg(local_db_handle))); + } + sqlite3_free_table(result); + + + /* 6. create mail_attachment_tbl */ + sql = "SELECT count(name) FROM sqlite_master WHERE name='mail_attachment_tbl';"; + /* rc = sqlite3_get_table(local_db_handle, sql, &result, NULL, NULL, NULL); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_get_table(local_db_handle, sql, &result, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {goto FINISH_OFF; }, + ("SQL(%s) sqlite3_get_table fail:%d -%s", sql, rc, sqlite3_errmsg(local_db_handle))); + + if (atoi(result[1]) < 1) { + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, "BEGIN;", NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {goto FINISH_OFF; }, + ("SQL(BEGIN EXCLUSIVE) exec fail:%d -%s", rc, sqlite3_errmsg(local_db_handle))); + EM_DEBUG_LOG("CREATE TABLE mail_attachment_tbl"); + + SNPRINTF(sql_query_string, sizeof(sql_query_string), create_table_query[CREATE_TABLE_MAIL_ATTACHMENT_TBL]); + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, sql_query_string, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) exec fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + /* create mail_attachment_tbl unique index */ + SNPRINTF(sql_query_string, sizeof(sql_query_string), "CREATE UNIQUE INDEX mail_attachment_idx1 ON mail_attachment_tbl (mail_id, attachment_id) "); + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, sql_query_string, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) exec fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, "END;", NULL, NULL, NULL), rc); + + } /* mail_attachment_tbl */ + else if (type == EMF_CREATE_DB_CHECK) { + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, g_test_query[CREATE_TABLE_MAIL_ATTACHMENT_TBL], NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) exec fail:%d -%s", g_test_query[CREATE_TABLE_MAIL_ATTACHMENT_TBL], rc, sqlite3_errmsg(local_db_handle))); + } + sqlite3_free_table(result); + +#ifdef __FEATURE_PARTIAL_BODY_DOWNLOAD__ + + sql = "SELECT count(name) FROM sqlite_master WHERE name='mail_partial_body_activity_tbl';"; + /* rc = sqlite3_get_table(local_db_handle, sql, &result, NULL, NULL, NULL); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_get_table(local_db_handle, sql, &result, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {goto FINISH_OFF; }, + ("SQL(%s) sqlite3_get_table fail:%d -%s", sql, rc, sqlite3_errmsg(local_db_handle))); + + if (atoi(result[1]) < 1) { + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, "BEGIN;", NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {goto FINISH_OFF; }, + ("SQL(BEGIN EXCLUSIVE) exec fail:%d -%s", rc, sqlite3_errmsg(local_db_handle))); + + EM_DEBUG_LOG("CREATE TABLE mail_partial_body_activity_tbl"); + + SNPRINTF(sql_query_string, sizeof(sql_query_string), create_table_query[CREATE_TABLE_MAIL_PARTIAL_BODY_ACTIVITY_TBL]); + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, sql_query_string, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) exec fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, "END;", NULL, NULL, NULL), rc); + + } /* mail_rule_tbl */ + else if (type == EMF_CREATE_DB_CHECK) { + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, g_test_query[CREATE_TABLE_MAIL_PARTIAL_BODY_ACTIVITY_TBL], NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) exec fail:%d -%s", g_test_query[CREATE_TABLE_MAIL_PARTIAL_BODY_ACTIVITY_TBL], rc, sqlite3_errmsg(local_db_handle))); + } + sqlite3_free_table(result); + +#endif /* __FEATURE_PARTIAL_BODY_DOWNLOAD__ */ + + /* create mail_meeting_tbl */ + sql = "SELECT count(name) FROM sqlite_master WHERE name='mail_meeting_tbl';"; + /* rc = sqlite3_get_table(local_db_handle, sql, &result, NULL, NULL, NULL); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_get_table(local_db_handle, sql, &result, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {goto FINISH_OFF; }, + ("SQL(%s) sqlite3_get_table fail:%d -%s", sql, rc, sqlite3_errmsg(local_db_handle))); + + if (atoi(result[1]) < 1) { + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, "BEGIN;", NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {goto FINISH_OFF; }, + ("SQL(BEGIN EXCLUSIVE) exec fail:%d -%s", rc, sqlite3_errmsg(local_db_handle))); + + EM_DEBUG_LOG("CREATE TABLE mail_meeting_tbl"); + + SNPRINTF(sql_query_string, sizeof(sql_query_string), create_table_query[CREATE_TABLE_MAIL_MEETING_TBL]); + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, sql_query_string, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) exec fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + SNPRINTF(sql_query_string, sizeof(sql_query_string), "CREATE UNIQUE INDEX mail_meeting_idx1 ON mail_meeting_tbl (mail_id)"); + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, sql_query_string, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) exec fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, "END;", NULL, NULL, NULL), rc); + + } /* mail_contact_sync_tbl */ + else if (type == EMF_CREATE_DB_CHECK) { + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, g_test_query[CREATE_TABLE_MAIL_MEETING_TBL], NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) exec fail:%d -%s", g_test_query[CREATE_TABLE_MAIL_MEETING_TBL], rc, sqlite3_errmsg(local_db_handle))); + } + sqlite3_free_table(result); + +#ifdef __LOCAL_ACTIVITY__ + + sql = "SELECT count(name) FROM sqlite_master WHERE name='mail_local_activity_tbl';"; + /* rc = sqlite3_get_table(local_db_handle, sql, &result, NULL, NULL, NULL); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_get_table(local_db_handle, sql, &result, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {goto FINISH_OFF; }, + ("SQL(%s) sqlite3_get_table fail:%d -%s", sql, rc, sqlite3_errmsg(local_db_handle))); + + if (atoi(result[1]) < 1) { + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, "BEGIN;", NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {goto FINISH_OFF; }, + ("SQL(BEGIN EXCLUSIVE) exec fail:%d -%s", rc, sqlite3_errmsg(local_db_handle))); + + EM_DEBUG_LOG(" CREATE TABLE mail_local_activity_tbl"); + + SNPRINTF(sql_query_string, sizeof(sql_query_string), create_table_query[CREATE_TABLE_MAIL_LOCAL_ACTIVITY_TBL]); + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, sql_query_string, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) exec fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, "END;", NULL, NULL, NULL), rc); + + } /* mail_rule_tbl */ + else if (type == EMF_CREATE_DB_CHECK) { + rc = sqlite3_exec(local_db_handle, g_test_query[CREATE_TABLE_MAIL_LOCAL_ACTIVITY_TBL], NULL, NULL, NULL); + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, g_test_query[CREATE_TABLE_MAIL_LOCAL_ACTIVITY_TBL], NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) exec fail:%d -%s", g_test_query[CREATE_TABLE_MAIL_LOCAL_ACTIVITY_TBL], rc, sqlite3_errmsg(local_db_handle))); + } + sqlite3_free_table(result); + +#endif /* __LOCAL_ACTIVITY__ */ + + ret = true; + +FINISH_OFF: + if (ret == true) { + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, "END;", NULL, NULL, NULL), rc); + } + else { + /* sqlite3_exec(local_db_handle, "rollback", NULL, NULL, NULL); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, "rollback", NULL, NULL, NULL), rc); + } + + _DISCONNECT_DB; + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +/* Query series --------------------------------------------------------------*/ + +EXPORT_API int em_storage_query_mail_list(const char *conditional_clause, int transaction, emf_mail_list_item_t** result_mail_list, int *result_count, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN(); + EM_PROFILE_BEGIN(em_storage_query_mail_list_func); + + int i = 0, count = 0, rc = -1, to_get_count = (result_mail_list)?0:1; + int local_inline_content_count = 0, local_attachment_count = 0; + int cur_query = 0, base_count = 0, col_index; + int ret = false, error = EM_STORAGE_ERROR_NONE; + emf_mail_list_item_t *mail_list_item_from_tbl = NULL; + char **result = NULL, sql_query_string[QUERY_SIZE] = {0, }; + char *field_list = "mail_id, account_id, mailbox_name, full_address_from, email_address_sender, full_address_to, subject, body_download_status, flags_seen_field, flags_deleted_field, flags_flagged_field, flags_answered_field, flags_recent_field, flags_draft_field, flags_forwarded_field, DRM_status, priority, save_status, lock_status, attachment_count, inline_content_count, date_time, preview_text, thread_id, thread_item_count, meeting_request_status "; + sqlite3 *local_db_handle = em_storage_get_db_connection(); + + EM_IF_NULL_RETURN_VALUE(conditional_clause, false); + EM_IF_NULL_RETURN_VALUE(result_count, false); + + EM_STORAGE_START_READ_TRANSACTION(transaction); + + /* select clause */ + if (to_get_count) /* count only */ + cur_query += SNPRINTF_OFFSET(sql_query_string, cur_query, QUERY_SIZE, "SELECT count(*) FROM mail_tbl"); + else /* mail list in plain form */ + cur_query += SNPRINTF_OFFSET(sql_query_string, cur_query, QUERY_SIZE, "SELECT %s FROM mail_tbl ", field_list); + + cur_query += SNPRINTF_OFFSET(sql_query_string, cur_query, QUERY_SIZE, conditional_clause); + + EM_DEBUG_LOG("em_storage_query_mail_list : query[%s].", sql_query_string); + + /* performing query */ + EM_PROFILE_BEGIN(em_storage_query_mail_list_performing_query); + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_get_table(local_db_handle, sql_query_string, &result, &count, 0, NULL), rc); + EM_DEBUG_DB_EXEC((SQLITE_OK != rc && -1 != rc), {error = EM_STORAGE_ERROR_DB_FAILURE;sqlite3_free_table(result);goto FINISH_OFF; }, + ("SQL(%s) sqlite3_get_table fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + EM_PROFILE_END(em_storage_query_mail_list_performing_query); + + if (!base_count) + base_count = ({ int i=0; char *tmp = field_list; for (i=0; tmp && *(tmp + 1); tmp = index(tmp + 1, ','), i++); i; }); + + col_index = base_count; + + EM_DEBUG_LOG("base_count [%d]", base_count); + + if (to_get_count) { + /* to get mail count */ + count = atoi(result[1]); + EM_DEBUG_LOG("There are [%d] mails.", count); + } + else { + /* to get mail list */ + if (!count) { + EM_DEBUG_EXCEPTION("No mail found..."); + ret = false; + error= EM_STORAGE_ERROR_MAIL_NOT_FOUND; + goto FINISH_OFF; + } + + EM_DEBUG_LOG("There are [%d] mails.", count); + if (!(mail_list_item_from_tbl = (emf_mail_list_item_t*)em_core_malloc(sizeof(emf_mail_list_item_t) * count))) { + EM_DEBUG_EXCEPTION("malloc for mail_list_item_from_tbl failed..."); + error = EM_STORAGE_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + EM_PROFILE_BEGIN(em_storage_query_mail_list_loop); + EM_DEBUG_LOG(">>>> DATA ASSIGN START >> "); + for (i = 0; i < count; i++) { + _getTableFieldDataInt(result, &(mail_list_item_from_tbl[i].mail_id), col_index++); + _getTableFieldDataInt(result, &(mail_list_item_from_tbl[i].account_id), col_index++); + _getTableFieldDataStringWithoutAllocation(result, mail_list_item_from_tbl[i].mailbox_name, STRING_LENGTH_FOR_DISPLAY, 1, col_index++); + _getTableFieldDataStringWithoutAllocation(result, mail_list_item_from_tbl[i].from, STRING_LENGTH_FOR_DISPLAY, 1, col_index++); + _getTableFieldDataStringWithoutAllocation(result, mail_list_item_from_tbl[i].from_email_address, MAX_EMAIL_ADDRESS_LENGTH, 1, col_index++); + _getTableFieldDataStringWithoutAllocation(result, mail_list_item_from_tbl[i].recipients, STRING_LENGTH_FOR_DISPLAY, 1, col_index++); + _getTableFieldDataStringWithoutAllocation(result, mail_list_item_from_tbl[i].subject, STRING_LENGTH_FOR_DISPLAY, 1, col_index++); + _getTableFieldDataInt(result, &(mail_list_item_from_tbl[i].is_text_downloaded), col_index++); + _getTableFieldDataChar(result, &(mail_list_item_from_tbl[i].flags_seen_field), col_index++); + _getTableFieldDataChar(result, &(mail_list_item_from_tbl[i].flags_deleted_field), col_index++); + _getTableFieldDataChar(result, &(mail_list_item_from_tbl[i].flags_flagged_field), col_index++); + _getTableFieldDataChar(result, &(mail_list_item_from_tbl[i].flags_answered_field), col_index++); + _getTableFieldDataChar(result, &(mail_list_item_from_tbl[i].flags_recent_field), col_index++); + _getTableFieldDataChar(result, &(mail_list_item_from_tbl[i].flags_draft_field), col_index++); + _getTableFieldDataChar(result, &(mail_list_item_from_tbl[i].flags_forwarded_field), col_index++); + _getTableFieldDataInt(result, &(mail_list_item_from_tbl[i].has_drm_attachment), col_index++); + _getTableFieldDataInt(result, &(mail_list_item_from_tbl[i].priority), col_index++); + _getTableFieldDataInt(result, &(mail_list_item_from_tbl[i].save_status), col_index++); + _getTableFieldDataInt(result, &(mail_list_item_from_tbl[i].is_locked), col_index++); + _getTableFieldDataInt(result, &local_attachment_count, col_index++); + _getTableFieldDataInt(result, &local_inline_content_count, col_index++); + _getTableFieldDataStringWithoutAllocation(result, mail_list_item_from_tbl[i].datetime, MAX_DATETIME_STRING_LENGTH, 0, col_index++); + _getTableFieldDataStringWithoutAllocation(result, mail_list_item_from_tbl[i].previewBodyText, MAX_PREVIEW_TEXT_LENGTH, 1, col_index++); + _getTableFieldDataInt(result, &(mail_list_item_from_tbl[i].thread_id), col_index++); + _getTableFieldDataInt(result, &(mail_list_item_from_tbl[i].thread_item_count), col_index++); + _getTableFieldDataInt(result, &(mail_list_item_from_tbl[i].is_meeting_request), col_index++); + mail_list_item_from_tbl[i].has_attachment = ((local_attachment_count - local_inline_content_count)>0)?1:0; + } + EM_DEBUG_LOG(">>>> DATA ASSIGN END [count : %d] >> ", count); + EM_PROFILE_END(em_storage_query_mail_list_loop); + } + + sqlite3_free_table(result); + result = NULL; + ret = true; + +FINISH_OFF: + EM_DEBUG_LOG("COUNT [%d]", count); + + if (to_get_count) + *result_count = count; + else { + if (ret == true) { + if (result_mail_list) + *result_mail_list = mail_list_item_from_tbl; + *result_count = count; + } + else + EM_SAFE_FREE(mail_list_item_from_tbl); + } + + EM_STORAGE_FINISH_READ_TRANSACTION(transaction); + _DISCONNECT_DB; + + if (err_code != NULL) + *err_code = error; + + EM_PROFILE_END(em_storage_query_mail_list_func); + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + + +EXPORT_API int em_storage_query_mail_tbl(const char *conditional_clause, int transaction, emf_mail_tbl_t** result_mail_tbl, int *result_count, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("conditional_clause[%s], result_mail_tbl[%p], result_count [%p], transaction[%d], err_code[%p]", conditional_clause, result_mail_tbl, result_count, transaction, err_code); + + if (!conditional_clause) { + EM_DEBUG_EXCEPTION("EM_STORAGE_ERROR_INVALID_PARAM"); + + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + int i, col_index = FIELD_COUNT_OF_EMF_MAIL_TBL, rc, ret = false, count; + int error = EM_STORAGE_ERROR_NONE; + char **result = NULL, sql_query_string[QUERY_SIZE] = {0, }; + emf_mail_tbl_t* p_data_tbl = NULL; + sqlite3 *local_db_handle = em_storage_get_db_connection(); + + EM_STORAGE_START_READ_TRANSACTION(transaction); + + SNPRINTF(sql_query_string, sizeof(sql_query_string), "SELECT * FROM mail_tbl %s", conditional_clause); + + EM_DEBUG_LOG("Query [%s]", sql_query_string); + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_get_table(local_db_handle, sql_query_string, &result, &count, 0, NULL), rc); + EM_DEBUG_DB_EXEC((SQLITE_OK != rc && -1 != rc), {error = EM_STORAGE_ERROR_DB_FAILURE;sqlite3_free_table(result);goto FINISH_OFF; }, + ("SQL(%s) sqlite3_get_table fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + if (!count) { + EM_DEBUG_EXCEPTION("No mail found..."); + ret = false; + error= EM_STORAGE_ERROR_MAIL_NOT_FOUND; + goto FINISH_OFF; + } + + EM_DEBUG_LOG("There are [%d] mails.", count); + if (!(p_data_tbl = (emf_mail_tbl_t*)em_core_malloc(sizeof(emf_mail_tbl_t) * count))) { + EM_DEBUG_EXCEPTION("malloc for emf_mail_tbl_t failed..."); + error = EM_STORAGE_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + EM_DEBUG_LOG(">>>> DATA ASSIGN START >> "); + for (i = 0; i < count; i++) { + _getTableFieldDataInt(result, &(p_data_tbl[i].mail_id), col_index++); + _getTableFieldDataInt(result, &(p_data_tbl[i].account_id), col_index++); + _getTableFieldDataString(result, &(p_data_tbl[i].mailbox_name), 0, col_index++); + _getTableFieldDataInt(result, &(p_data_tbl[i].mailbox_type), col_index++); + _getTableFieldDataString(result, &(p_data_tbl[i].subject), 1, col_index++); + _getTableFieldDataString(result, &(p_data_tbl[i].datetime), 0, col_index++); + _getTableFieldDataInt(result, &(p_data_tbl[i].server_mail_status), col_index++); + _getTableFieldDataString(result, &(p_data_tbl[i].server_mailbox_name), 0, col_index++); + _getTableFieldDataString(result, &(p_data_tbl[i].server_mail_id), 0, col_index++); + _getTableFieldDataString(result, &(p_data_tbl[i].message_id), 0, col_index++); + _getTableFieldDataString(result, &(p_data_tbl[i].full_address_from), 1, col_index++); + _getTableFieldDataString(result, &(p_data_tbl[i].full_address_reply), 1, col_index++); + _getTableFieldDataString(result, &(p_data_tbl[i].full_address_to), 1, col_index++); + _getTableFieldDataString(result, &(p_data_tbl[i].full_address_cc), 1, col_index++); + _getTableFieldDataString(result, &(p_data_tbl[i].full_address_bcc), 1, col_index++); + _getTableFieldDataString(result, &(p_data_tbl[i].full_address_return), 1, col_index++); + _getTableFieldDataString(result, &(p_data_tbl[i].email_address_sender), 1, col_index++); + _getTableFieldDataString(result, &(p_data_tbl[i].email_address_recipient), 1, col_index++); + _getTableFieldDataString(result, &(p_data_tbl[i].alias_sender), 1, col_index++); + _getTableFieldDataString(result, &(p_data_tbl[i].alias_recipient), 1, col_index++); + _getTableFieldDataInt(result, &(p_data_tbl[i].body_download_status), col_index++); + _getTableFieldDataString(result, &(p_data_tbl[i].file_path_plain), 0, col_index++); + _getTableFieldDataString(result, &(p_data_tbl[i].file_path_html), 0, col_index++); + _getTableFieldDataInt(result, &(p_data_tbl[i].mail_size), col_index++); + _getTableFieldDataChar(result, &(p_data_tbl[i].flags_seen_field), col_index++); + _getTableFieldDataChar(result, &(p_data_tbl[i].flags_deleted_field), col_index++); + _getTableFieldDataChar(result, &(p_data_tbl[i].flags_flagged_field), col_index++); + _getTableFieldDataChar(result, &(p_data_tbl[i].flags_answered_field), col_index++); + _getTableFieldDataChar(result, &(p_data_tbl[i].flags_recent_field), col_index++); + _getTableFieldDataChar(result, &(p_data_tbl[i].flags_draft_field), col_index++); + _getTableFieldDataChar(result, &(p_data_tbl[i].flags_forwarded_field), col_index++); + _getTableFieldDataInt(result, &(p_data_tbl[i].DRM_status), col_index++); + _getTableFieldDataInt(result, &(p_data_tbl[i].priority), col_index++); + _getTableFieldDataInt(result, &(p_data_tbl[i].save_status), col_index++); + _getTableFieldDataInt(result, &(p_data_tbl[i].lock_status), col_index++); + _getTableFieldDataInt(result, &(p_data_tbl[i].report_status), col_index++); + _getTableFieldDataInt(result, &(p_data_tbl[i].attachment_count), col_index++); + _getTableFieldDataInt(result, &(p_data_tbl[i].inline_content_count), col_index++); + _getTableFieldDataInt(result, &(p_data_tbl[i].thread_id), col_index++); + _getTableFieldDataInt(result, &(p_data_tbl[i].thread_item_count), col_index++); + _getTableFieldDataString(result, &(p_data_tbl[i].preview_text), 1, col_index++); + _getTableFieldDataInt(result, &(p_data_tbl[i].meeting_request_status), col_index++); + /* check real body file... */ + if (p_data_tbl[i].body_download_status) { + struct stat buf; + + if (p_data_tbl[i].file_path_html && strlen(p_data_tbl[i].file_path_html) > 0) { + if (stat(p_data_tbl[i].file_path_html, &buf) == -1) { + EM_DEBUG_LINE; + p_data_tbl[i].body_download_status = 0; + } + } + else if (p_data_tbl[i].file_path_plain && strlen(p_data_tbl[i].file_path_plain) > 0) { + if (stat(p_data_tbl[i].file_path_plain, &buf) == -1){ + EM_DEBUG_LINE; + p_data_tbl[i].body_download_status = 0; + } + } + else + p_data_tbl[i].body_download_status = 0; + } + } + + ret = true; + +FINISH_OFF: + if(result) + sqlite3_free_table(result); + + if (ret == true) { + if (result_mail_tbl) + *result_mail_tbl = p_data_tbl; + *result_count = count; + } + else + EM_SAFE_FREE(p_data_tbl); + + EM_STORAGE_FINISH_READ_TRANSACTION(transaction); + _DISCONNECT_DB; + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + + +/* Query series --------------------------------------------------------------*/ + +EXPORT_API int em_storage_check_duplicated_account(emf_account_t* account, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN(); + + if (!account) { + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + int rc = -1, ret = false; + int error = EM_STORAGE_ERROR_NONE; + char **result; + int count; + char sql_query_string[QUERY_SIZE] = {0, }; + + sqlite3 *local_db_handle = em_storage_get_db_connection(); + EM_STORAGE_START_READ_TRANSACTION(transaction); + + SNPRINTF(sql_query_string, sizeof(sql_query_string), + "SELECT COUNT(*) FROM mail_account_tbl " + " WHERE " + " email_addr = '%s' AND " + " user_name = '%s' AND " + " receiving_server_type = %d AND " + " receiving_server_addr = '%s' AND " + " sending_user = '%s' AND " + " sending_server_type = %d AND " + " sending_server_addr = '%s'; ", + account->email_addr, + account->user_name, account->receiving_server_type, account->receiving_server_addr, + account->sending_user, account->sending_server_type, account->sending_server_addr + ); + EM_DEBUG_LOG("Query[%s]", sql_query_string); + /* rc = sqlite3_get_table(local_db_handle, sql_query_string, &result, NULL, NULL, NULL); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_get_table(local_db_handle, sql_query_string, &result, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;sqlite3_free_table(result);goto FINISH_OFF; }, + ("SQL(%s) sqlite3_get_table fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + count = atoi(result[1]); + sqlite3_free_table(result); + + EM_DEBUG_LOG("Count of Duplicated Account Information: [%d]", count); + + if (count == 0) { /* not duplicated account */ + ret = true; + EM_DEBUG_LOG("NOT duplicated account: email_addr[%s]", account->email_addr); + } + else { /* duplicated account */ + ret = false; + EM_DEBUG_LOG("The same account already exists. Duplicated account: email_addr[%s]", account->email_addr); + error = EM_STORAGE_ERROR_ALREADY_EXISTS; + } + +FINISH_OFF: + + EM_STORAGE_FINISH_READ_TRANSACTION(transaction); + _DISCONNECT_DB; + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; + +} + +EXPORT_API int em_storage_get_account_count(int *count, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN(); + + if (!count) { + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + int rc = -1, ret = false; + int error = EM_STORAGE_ERROR_NONE; + + DB_STMT hStmt = NULL; + char sql_query_string[QUERY_SIZE] = {0, }; + char err_msg[1024]; + + sqlite3 *local_db_handle = em_storage_get_db_connection(); + EM_STORAGE_START_READ_TRANSACTION(transaction); + SNPRINTF(sql_query_string, sizeof(sql_query_string), "SELECT COUNT(*) FROM mail_account_tbl"); + EM_DEBUG_LOG("SQL STMT [ %s ]", sql_query_string); + /* rc = sqlite3_prepare_v2(local_db_handle, sql_query_string, strlen(sql_query_string), &hStmt, NULL); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_prepare_v2(local_db_handle, sql_query_string, strlen(sql_query_string), &hStmt, NULL), rc); + EM_DEBUG_LOG("Before sqlite3_prepare hStmt = %p", hStmt); + EM_DEBUG_DB_EXEC((SQLITE_OK != rc), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) sqlite3_prepare fail:(%d) %s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + /* rc = sqlite3_step(hStmt); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_step(hStmt), rc); + EM_DEBUG_DB_EXEC((rc != SQLITE_ROW), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("sqlite3_step fail:%d", rc)); + + *count = sqlite3_column_int(hStmt, 0); + + ret = true; + +FINISH_OFF: + + if (hStmt != NULL) { + EM_DEBUG_LOG("Before sqlite3_finalize hStmt = %p", hStmt); + + rc = sqlite3_finalize(hStmt); + hStmt=NULL; + if (rc != SQLITE_OK) { + EM_DEBUG_EXCEPTION("sqlite3_finalize failed - %d: %s", rc, err_msg); + error = EM_STORAGE_ERROR_DB_FAILURE; + } + EM_DEBUG_LOG("sqlite3_finalize- %d", rc); + } + + EM_STORAGE_FINISH_READ_TRANSACTION(transaction); + _DISCONNECT_DB; + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + + +EXPORT_API int em_storage_get_account_list(int *select_num, emf_mail_account_tbl_t** account_list, int transaction, int with_password, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN(); + + int i = 0, count = 0, rc = -1, ret = false; + int error = EM_STORAGE_ERROR_NONE; + emf_mail_account_tbl_t *p_data_tbl = NULL; + + DB_STMT hStmt = NULL; + + if (!select_num || !account_list) { + EM_DEBUG_EXCEPTION("select_num[%p], account_list[%p]", select_num, account_list); + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + sqlite3 *local_db_handle = em_storage_get_db_connection(); + EM_STORAGE_START_READ_TRANSACTION(transaction); + + char sql_query_string[QUERY_SIZE] = {0, }; + char *sql = "SELECT count(*) FROM mail_account_tbl;"; + char **result; + + /* rc = sqlite3_get_table(local_db_handle, sql, &result, NULL, NULL, NULL); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_get_table(local_db_handle, sql, &result, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;sqlite3_free_table(result);goto FINISH_OFF; }, + ("SQL(%s) sqlite3_get_table fail:%d -%s", sql, rc, sqlite3_errmsg(local_db_handle))); + + count = atoi(result[1]); + sqlite3_free_table(result); + + if (!count) { + EM_DEBUG_EXCEPTION("no account found..."); + error = EM_STORAGE_ERROR_ACCOUNT_NOT_FOUND; + ret = true; + goto FINISH_OFF; + } + EM_DEBUG_LOG("count = %d", rc); + SNPRINTF(sql_query_string, sizeof(sql_query_string), "SELECT * FROM mail_account_tbl ORDER BY account_id"); + + /* rc = sqlite3_prepare_v2(local_db_handle, sql_query_string, strlen(sql_query_string), &hStmt, NULL); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_prepare_v2(local_db_handle, sql_query_string, strlen(sql_query_string), &hStmt, NULL), rc); + + EM_DEBUG_LOG("After sqlite3_prepare_v2 hStmt = %p", hStmt); + EM_DEBUG_DB_EXEC((SQLITE_OK != rc), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) sqlite3_prepare fail:(%d) %s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + /* rc = sqlite3_step(hStmt); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_step(hStmt), rc); + EM_DEBUG_DB_EXEC((rc != SQLITE_ROW && rc != SQLITE_DONE), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("sqlite3_step fail:%d", rc)); + if (rc == SQLITE_DONE) { + EM_DEBUG_EXCEPTION("no account found..."); + + error = EM_STORAGE_ERROR_ACCOUNT_NOT_FOUND; + count = 0; + ret = true; + goto FINISH_OFF; + } + + if (!(p_data_tbl = (emf_mail_account_tbl_t*)malloc(sizeof(emf_mail_account_tbl_t) * count))) { + EM_DEBUG_EXCEPTION("malloc failed..."); + error = EM_STORAGE_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + memset(p_data_tbl, 0x00, sizeof(emf_mail_account_tbl_t) * count); + for (i = 0; i < count; i++) { + /* get recordset */ + _getStmtFieldDataInt(hStmt, &(p_data_tbl[i].account_bind_type), ACCOUNT_BIND_TYPE_IDX_IN_MAIL_ACCOUNT_TBL); + _getStmtFieldDataString(hStmt, &(p_data_tbl[i].account_name), 0, ACCOUNT_NAME_IDX_IN_MAIL_ACCOUNT_TBL); + _getStmtFieldDataInt(hStmt, &(p_data_tbl[i].receiving_server_type), RECEIVING_SERVER_TYPE_TYPE_IDX_IN_MAIL_ACCOUNT_TBL); + _getStmtFieldDataString(hStmt, &(p_data_tbl[i].receiving_server_addr), 0, RECEIVING_SERVER_ADDR_IDX_IN_MAIL_ACCOUNT_TBL); + _getStmtFieldDataString(hStmt, &(p_data_tbl[i].email_addr), 0, EMAIL_ADDR_IDX_IN_MAIL_ACCOUNT_TBL); + _getStmtFieldDataString(hStmt, &(p_data_tbl[i].user_name), 0, USER_NAME_IDX_IN_MAIL_ACCOUNT_TBL); + _getStmtFieldDataString(hStmt, &(p_data_tbl[i].password), 0, PASSWORD_IDX_IN_MAIL_ACCOUNT_TBL); + _getStmtFieldDataInt(hStmt, &(p_data_tbl[i].retrieval_mode), RETRIEVAL_MODE_IDX_IN_MAIL_ACCOUNT_TBL); + _getStmtFieldDataInt(hStmt, &(p_data_tbl[i].port_num), PORT_NUM_IDX_IN_MAIL_ACCOUNT_TBL); + _getStmtFieldDataInt(hStmt, &(p_data_tbl[i].use_security), USE_SECURITY_IDX_IN_MAIL_ACCOUNT_TBL); + _getStmtFieldDataInt(hStmt, &(p_data_tbl[i].sending_server_type), SENDING_SERVER_TYPE_IDX_IN_MAIL_ACCOUNT_TBL); + _getStmtFieldDataString(hStmt, &(p_data_tbl[i].sending_server_addr), 0, SENDING_SERVER_ADDR_IDX_IN_MAIL_ACCOUNT_TBL); + _getStmtFieldDataInt(hStmt, &(p_data_tbl[i].sending_port_num), SENDING_PORT_NUM_IDX_IN_MAIL_ACCOUNT_TBL); + _getStmtFieldDataInt(hStmt, &(p_data_tbl[i].sending_auth), SENDING_AUTH_IDX_IN_MAIL_ACCOUNT_TBL); + _getStmtFieldDataInt(hStmt, &(p_data_tbl[i].sending_security), SENDING_SECURITY_IDX_IN_MAIL_ACCOUNT_TBL); + _getStmtFieldDataString(hStmt, &(p_data_tbl[i].sending_user), 0, SENDING_USER_IDX_IN_MAIL_ACCOUNT_TBL); + _getStmtFieldDataString(hStmt, &(p_data_tbl[i].sending_password), 0, SENDING_PASSWORD_IDX_IN_MAIL_ACCOUNT_TBL); + _getStmtFieldDataString(hStmt, &(p_data_tbl[i].display_name), 0, DISPLAY_NAME_IDX_IN_MAIL_ACCOUNT_TBL); + _getStmtFieldDataString(hStmt, &(p_data_tbl[i].reply_to_addr), 0, REPLY_TO_ADDR_IDX_IN_MAIL_ACCOUNT_TBL); + _getStmtFieldDataString(hStmt, &(p_data_tbl[i].return_addr), 0, RETURN_ADDR_IDX_IN_MAIL_ACCOUNT_TBL); + _getStmtFieldDataInt(hStmt, &(p_data_tbl[i].account_id), ACCOUNT_ID_IDX_IN_MAIL_ACCOUNT_TBL); + _getStmtFieldDataInt(hStmt, &(p_data_tbl[i].keep_on_server), KEEP_ON_SERVER_IDX_IN_MAIL_ACCOUNT_TBL); + _getStmtFieldDataInt(hStmt, &(p_data_tbl[i].flag1), FLAG1_IDX_IN_MAIL_ACCOUNT_TBL); + _getStmtFieldDataInt(hStmt, &(p_data_tbl[i].flag2), FLAG2_IDX_IN_MAIL_ACCOUNT_TBL); + _getStmtFieldDataInt(hStmt, &(p_data_tbl[i].pop_before_smtp), POP_BEFORE_SMTP_IDX_IN_MAIL_ACCOUNT_TBL); + _getStmtFieldDataInt(hStmt, &(p_data_tbl[i].apop), APOP_IDX_IN_MAIL_ACCOUNT_TBL); + _getStmtFieldDataString(hStmt, &(p_data_tbl[i].logo_icon_path), 0, LOGO_ICON_PATH_IDX_IN_MAIL_ACCOUNT_TBL); + _getStmtFieldDataInt(hStmt, &(p_data_tbl[i].preset_account), PRESET_ACCOUNT_IDX_IN_MAIL_ACCOUNT_TBL); + _getStmtFieldDataInt(hStmt, &(p_data_tbl[i].target_storage), TARGET_STORAGE_IDX_IN_MAIL_ACCOUNT_TBL); + _getStmtFieldDataInt(hStmt, &(p_data_tbl[i].check_interval), CHECK_INTERVAL_IDX_IN_MAIL_ACCOUNT_TBL); + _getStmtFieldDataInt(hStmt, &(p_data_tbl[i].options.priority), PRIORITY_IDX_IN_MAIL_ACCOUNT_TBL); + _getStmtFieldDataInt(hStmt, &(p_data_tbl[i].options.keep_local_copy), KEEP_LOCAL_COPY_IDX_IN_MAIL_ACCOUNT_TBL); + _getStmtFieldDataInt(hStmt, &(p_data_tbl[i].options.req_delivery_receipt), REQ_DELIVERY_RECEIPT_IDX_IN_MAIL_ACCOUNT_TBL); + _getStmtFieldDataInt(hStmt, &(p_data_tbl[i].options.req_read_receipt), REQ_READ_RECEIPT_IDX_IN_MAIL_ACCOUNT_TBL); + _getStmtFieldDataInt(hStmt, &(p_data_tbl[i].options.download_limit), DOWNLOAD_LIMIT_IDX_IN_MAIL_ACCOUNT_TBL); + _getStmtFieldDataInt(hStmt, &(p_data_tbl[i].options.block_address), BLOCK_ADDRESS_IDX_IN_MAIL_ACCOUNT_TBL); + _getStmtFieldDataInt(hStmt, &(p_data_tbl[i].options.block_subject), BLOCK_SUBJECT_IDX_IN_MAIL_ACCOUNT_TBL); + _getStmtFieldDataString(hStmt, &(p_data_tbl[i].options.display_name_from), 0, DISPLAY_NAME_FROM_IDX_IN_MAIL_ACCOUNT_TBL); + _getStmtFieldDataInt(hStmt, &(p_data_tbl[i].options.reply_with_body), REPLY_WITH_BODY_IDX_IN_MAIL_ACCOUNT_TBL); + _getStmtFieldDataInt(hStmt, &(p_data_tbl[i].options.forward_with_files), FORWARD_WITH_FILES_IDX_IN_MAIL_ACCOUNT_TBL); + _getStmtFieldDataInt(hStmt, &(p_data_tbl[i].options.add_myname_card), ADD_MYNAME_CARD_IDX_IN_MAIL_ACCOUNT_TBL); + _getStmtFieldDataInt(hStmt, &(p_data_tbl[i].options.add_signature), ADD_SIGNATURE_IDX_IN_MAIL_ACCOUNT_TBL); + _getStmtFieldDataString(hStmt, &(p_data_tbl[i].options.signature), 0, SIGNATURE_IDX_IN_MAIL_ACCOUNT_TBL); + _getStmtFieldDataInt(hStmt, &(p_data_tbl[i].options.add_my_address_to_bcc), ADD_MY_ADDRESS_TO_BCC_IDX_IN_MAIL_ACCOUNT_TBL); + _getStmtFieldDataInt(hStmt, &(p_data_tbl[i].my_account_id), MY_ACCOUNT_ID_IDX_IN_MAIL_ACCOUNT_TBL); + _getStmtFieldDataInt(hStmt, &(p_data_tbl[i].index_color), INDEX_COLOR_IDX_IN_MAIL_ACCOUNT_TBL); + if (with_password == true) { + /* get password from the secure storage */ + char recv_password_file_name[MAX_PW_FILE_NAME_LENGTH];/* = p_data_tbl[i].password; */ + char send_password_file_name[MAX_PW_FILE_NAME_LENGTH];;/* = p_data_tbl[i].sending_password; */ + + EM_SAFE_FREE(p_data_tbl[i].password); + EM_SAFE_FREE(p_data_tbl[i].sending_password); + + /* get password file name */ + if ((error = em_storage_get_password_file_name(p_data_tbl[i].account_id, recv_password_file_name, send_password_file_name)) != EM_STORAGE_ERROR_NONE) { + EM_DEBUG_EXCEPTION("em_storage_get_password_file_name failed."); + goto FINISH_OFF; + } + + /* read password from secure storage */ + if ((error = em_storage_read_password_ss(recv_password_file_name, &(p_data_tbl[i].password))) < 0 ) { + EM_DEBUG_EXCEPTION("em_storage_read_password_ss() failed..."); + goto FINISH_OFF; + } + EM_DEBUG_LOG("recv_password_file_name[%s], password[%s]", recv_password_file_name, p_data_tbl[i].password); + + if ((error = em_storage_read_password_ss(send_password_file_name, &(p_data_tbl[i].sending_password))) < 0) { + EM_DEBUG_EXCEPTION("em_storage_read_password_ss() failed..."); + goto FINISH_OFF; + } + EM_DEBUG_LOG("send_password_file_name[%s], password[%s]", send_password_file_name, p_data_tbl[i].sending_password); + } + + /* rc = sqlite3_step(hStmt); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_step(hStmt), rc); + EM_DEBUG_LOG("after sqlite3_step(), i = %d, rc = %d.", i, rc); + EM_DEBUG_DB_EXEC((rc != SQLITE_ROW && rc != SQLITE_DONE), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("sqlite3_step fail:%d", rc)); + } + + ret = true; + +FINISH_OFF: + if (ret == true) { + *account_list = p_data_tbl; + *select_num = count; + EM_DEBUG_LOG("COUNT : %d", count); + } + else if (p_data_tbl != NULL) + em_storage_free_account(&p_data_tbl, count, NULL); + if (hStmt != NULL) { + EM_DEBUG_LOG("Before sqlite3_finalize hStmt = %p", hStmt); + + rc = sqlite3_finalize(hStmt); + hStmt = NULL; + if (rc != SQLITE_OK) { + EM_DEBUG_EXCEPTION("sqlite3_finalize failed - %d", rc); + error = EM_STORAGE_ERROR_DB_FAILURE; + } + } + + EM_STORAGE_FINISH_READ_TRANSACTION(transaction); + _DISCONNECT_DB; + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + + +EXPORT_API int em_storage_get_maildata_by_servermailid(int account_id, char *server_mail_id, emf_mail_tbl_t** mail, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id [%d], server_mail_id[%s], mail[%p], transaction[%d], err_code[%p]", account_id, server_mail_id, mail, transaction, err_code); + + int ret = false, error = EM_STORAGE_ERROR_NONE, result_count; + char conditional_clause[QUERY_SIZE] = {0, }; + emf_mail_tbl_t* p_data_tbl = NULL; + + if (!server_mail_id || !mail) { + EM_DEBUG_EXCEPTION("EM_STORAGE_ERROR_INVALID_PARAM"); + error = EM_STORAGE_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + if (account_id == ALL_ACCOUNT) + SNPRINTF(conditional_clause, QUERY_SIZE, "WHERE UPPER(server_mail_id) =UPPER('%s')", server_mail_id); + else + SNPRINTF(conditional_clause, QUERY_SIZE, "WHERE UPPER(server_mail_id) =UPPER('%s') AND account_id = %d", server_mail_id, account_id); + + EM_DEBUG_LOG("conditional_clause [%s]", conditional_clause); + + if(!em_storage_query_mail_tbl(conditional_clause, transaction, &p_data_tbl, &result_count, &error)) { + EM_DEBUG_EXCEPTION("em_storage_query_mail_tbl failed [%d]", error); + goto FINISH_OFF; + } + + ret = true; + +FINISH_OFF: + if (ret == true) + *mail = p_data_tbl; + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + + +static int em_storage_write_conditional_clause_for_getting_mail_list(int account_id, const char *mailbox_name, emf_email_address_list_t* addr_list, int thread_id, int start_index, int limit_count, int search_type, const char *search_value, emf_sort_type_t sorting, char *conditional_clause_string, int buffer_size, int *err_code) +{ + int cur_clause = 0, conditional_clause_count = 0, i = 0; + + if (account_id < ALL_ACCOUNT) { + EM_DEBUG_EXCEPTION("Invalid account_id [%d]", account_id); + EM_RETURN_ERR_CODE(err_code, EM_STORAGE_ERROR_INVALID_PARAM, false); + } + + /* where clause */ + if (account_id == ALL_ACCOUNT) { + cur_clause += (conditional_clause_count++ == 0)? + SNPRINTF_OFFSET(conditional_clause_string, cur_clause, buffer_size - cur_clause, " WHERE mailbox_type not in (3, 5, 7)"): + SNPRINTF_OFFSET(conditional_clause_string, cur_clause, buffer_size - cur_clause, " AND mailbox_type not in (3, 5, 7)"); + } + else { + cur_clause += (conditional_clause_count++ == 0)? + SNPRINTF_OFFSET(conditional_clause_string, cur_clause, buffer_size - cur_clause, " WHERE account_id = %d", account_id): + SNPRINTF_OFFSET(conditional_clause_string, cur_clause, buffer_size - cur_clause, " AND account_id = %d", account_id); + } + + if (mailbox_name) { + cur_clause += (conditional_clause_count++ == 0)? + SNPRINTF_OFFSET(conditional_clause_string, cur_clause, buffer_size - cur_clause, " WHERE UPPER(mailbox_name) = UPPER('%s')", mailbox_name): + SNPRINTF_OFFSET(conditional_clause_string, cur_clause, buffer_size - cur_clause, " AND UPPER(mailbox_name) = UPPER('%s')", mailbox_name); + } + else if(account_id != ALL_ACCOUNT) { + cur_clause += (conditional_clause_count++ == 0)? + SNPRINTF_OFFSET(conditional_clause_string, cur_clause, buffer_size - cur_clause, " WHERE mailbox_type not in (3, 5, 7)"): + SNPRINTF_OFFSET(conditional_clause_string, cur_clause, buffer_size - cur_clause, " AND mailbox_type not in (3, 5, 7)"); + } + + if (thread_id > 0) { + cur_clause += (conditional_clause_count++ == 0)? + SNPRINTF_OFFSET(conditional_clause_string, cur_clause, buffer_size - cur_clause, " WHERE thread_id = %d ", thread_id): + SNPRINTF_OFFSET(conditional_clause_string, cur_clause, buffer_size - cur_clause, " AND thread_id = %d ", thread_id); + } + else if (thread_id == EMF_LIST_TYPE_THREAD) { + cur_clause += (conditional_clause_count++ == 0)? + SNPRINTF_OFFSET(conditional_clause_string, cur_clause, buffer_size - cur_clause, " WHERE thread_item_count > 0"): + SNPRINTF_OFFSET(conditional_clause_string, cur_clause, buffer_size - cur_clause, " AND thread_item_count > 0"); + } + else if (thread_id == EMF_LIST_TYPE_LOCAL) { + cur_clause += (conditional_clause_count++ == 0)? + SNPRINTF_OFFSET(conditional_clause_string, cur_clause, buffer_size - cur_clause, " WHERE server_mail_status = 0"): + SNPRINTF_OFFSET(conditional_clause_string, cur_clause, buffer_size - cur_clause, " AND server_mail_status = 0"); + } + else if (thread_id == EMF_LIST_TYPE_UNREAD) { + cur_clause += (conditional_clause_count++ == 0)? + SNPRINTF_OFFSET(conditional_clause_string, cur_clause, buffer_size - cur_clause, " WHERE flags_seen_field == 0"): + SNPRINTF_OFFSET(conditional_clause_string, cur_clause, buffer_size - cur_clause, " AND flags_seen_field == 0"); + } + + /* EM_DEBUG_LOG("where clause added [%s]", conditional_clause_string); */ + if (addr_list && addr_list->address_count > 0) { + if (!addr_list->address_type) { + cur_clause += (conditional_clause_count++ == 0)? + SNPRINTF_OFFSET(conditional_clause_string, cur_clause, buffer_size - cur_clause, " WHERE email_address_sender IN(\"%s\"", addr_list->address_list[0]): + SNPRINTF_OFFSET(conditional_clause_string, cur_clause, buffer_size - cur_clause, " AND email_address_sender IN(\"%s\"", addr_list->address_list[0]); + + for (i = 1; i < addr_list->address_count; i++) + cur_clause += SNPRINTF_OFFSET(conditional_clause_string, cur_clause, buffer_size - cur_clause, ",\"%s\"", addr_list->address_list[i]); + + cur_clause += SNPRINTF_OFFSET(conditional_clause_string, cur_clause, buffer_size - cur_clause, ")"); + } else { + cur_clause += (conditional_clause_count++ == 0)? + SNPRINTF_OFFSET(conditional_clause_string, cur_clause, buffer_size - cur_clause, " WHERE full_address_to IN(\"%s\") or full_address_cc IN(\"%s\"", addr_list->address_list[0], addr_list->address_list[0]): + SNPRINTF_OFFSET(conditional_clause_string, cur_clause, buffer_size - cur_clause, " AND full_address_to IN(\"%s\") or full_address_cc IN(\"%s\"", addr_list->address_list[0], addr_list->address_list[0]); + + for (i = 1; i < addr_list->address_count; i++) + cur_clause += SNPRINTF_OFFSET(conditional_clause_string, cur_clause, buffer_size - cur_clause, ",\"%s\"", addr_list->address_list[i]); + + cur_clause += SNPRINTF_OFFSET(conditional_clause_string, cur_clause, buffer_size - cur_clause, ")"); + } + } + + if (search_value) { + switch (search_type) { + case EMF_SEARCH_FILTER_SUBJECT: + cur_clause += SNPRINTF_OFFSET(conditional_clause_string, cur_clause, buffer_size - cur_clause, + " %s (UPPER(subject) LIKE UPPER(\'%%%%%s%%%%\')) ", conditional_clause_count++ ? "AND" : "WHERE", search_value); + break; + case EMF_SEARCH_FILTER_SENDER: + cur_clause += SNPRINTF_OFFSET(conditional_clause_string, cur_clause, buffer_size - cur_clause, + " %s ((UPPER(full_address_from) LIKE UPPER(\'%%%%%s%%%%\')) " + ") ", conditional_clause_count++ ? "AND" : "WHERE", search_value); + break; + case EMF_SEARCH_FILTER_RECIPIENT: + cur_clause += SNPRINTF_OFFSET(conditional_clause_string, cur_clause, buffer_size - cur_clause, + " %s ((UPPER(full_address_to) LIKE UPPER(\'%%%%%s%%%%\')) " + " OR (UPPER(full_address_cc) LIKE UPPER(\'%%%%%s%%%%\')) " + " OR (UPPER(full_address_bcc) LIKE UPPER(\'%%%%%s%%%%\')) " + ") ", conditional_clause_count++ ? "AND" : "WHERE", search_value, search_value, search_value); + break; + case EMF_SEARCH_FILTER_ALL: + cur_clause += SNPRINTF_OFFSET(conditional_clause_string, cur_clause, buffer_size - cur_clause, + " %s (UPPER(subject) LIKE UPPER(\'%%%%%s%%%%\') " + " OR (((UPPER(full_address_from) LIKE UPPER(\'%%%%%s%%%%\')) " + " OR (UPPER(full_address_to) LIKE UPPER(\'%%%%%s%%%%\')) " + " OR (UPPER(full_address_cc) LIKE UPPER(\'%%%%%s%%%%\')) " + " OR (UPPER(full_address_bcc) LIKE UPPER(\'%%%%%s%%%%\')) " + " ) " + " )" + ")", conditional_clause_count++ ? "AND" : "WHERE", search_value, search_value, search_value, search_value, search_value); + break; + } + } + + /* EM_DEBUG_LOG("where clause [%s]", conditional_clause_string); */ + static char sorting_str[][50] = { + " ORDER BY date_time DESC", /* case EMF_SORT_DATETIME_HIGH: */ + " ORDER BY date_time ASC", /* case EMF_SORT_DATETIME_LOW: */ + " ORDER BY full_address_from DESC, date_time DESC", /* case EMF_SORT_SENDER_HIGH: */ + " ORDER BY full_address_from ASC, date_time DESC", /* case EMF_SORT_SENDER_LOW: */ + " ORDER BY full_address_to DESC, date_time DESC", /* case EMF_SORT_RCPT_HIGH: */ + " ORDER BY full_address_to ASC, date_time DESC", /* case EMF_SORT_RCPT_LOW: */ + " ORDER BY subject DESC, date_time DESC", /* case EMF_SORT_SUBJECT_HIGH: */ + " ORDER BY subject ASC, date_time DESC", /* case EMF_SORT_SUBJECT_LOW: */ + " ORDER BY priority DESC, date_time DESC", /* case EMF_SORT_PRIORITY_HIGH: */ + " ORDER BY priority ASC, date_time DESC", /* case EMF_SORT_PRIORITY_LOW: */ + " ORDER BY attachment_count DESC, date_time DESC", /* case EMF_SORT_ATTACHMENT_HIGH: */ + " ORDER BY attachment_count ASC, date_time DESC", /* case EMF_SORT_ATTACHMENT_LOW: */ + " ORDER BY lock_status DESC, date_time DESC", /* case EMF_SORT_FAVORITE_HIGH: */ + " ORDER BY lock_status ASC, date_time DESC", /* case EMF_SORT_FAVORITE_LOW: */ + " ORDER BY mailbox_name DESC, date_time DESC", /* case EMF_SORT_MAILBOX_NAME_HIGH: */ + " ORDER BY mailbox_name ASC, date_time DESC" /* case EMF_SORT_MAILBOX_NAME_LOW: */ + }; + + if (sorting < EMF_SORT_END && sorting >= 0) + cur_clause += SNPRINTF_OFFSET(conditional_clause_string, cur_clause, buffer_size, " %s", sorting_str[sorting]); + else + EM_DEBUG_LOG(" Invalid Sorting order "); + + /* limit clause */ + if (start_index != -1 && limit_count != -1) + cur_clause += SNPRINTF_OFFSET(conditional_clause_string, cur_clause, buffer_size, " LIMIT %d, %d", start_index, limit_count); + + return true; +} + + +/** + * em_storage_get_mail_list - Get the mail list information. + * + * + */ +EXPORT_API int em_storage_get_mail_list(int account_id, const char *mailbox_name, emf_email_address_list_t* addr_list, int thread_id, int start_index, int limit_count, int search_type, const char *search_value, emf_sort_type_t sorting, int transaction, emf_mail_list_item_t** mail_list, int *result_count, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN(); + EM_PROFILE_BEGIN(em_storage_get_mail_list_func); + + int ret = false, error = EM_STORAGE_ERROR_NONE; + char conditional_clause_string[QUERY_SIZE] = { 0, }; + + if (account_id < ALL_ACCOUNT) { + EM_DEBUG_EXCEPTION("Invalid account_id [%d]", account_id); + EM_RETURN_ERR_CODE(err_code, EM_STORAGE_ERROR_INVALID_PARAM, false); + } + EM_IF_NULL_RETURN_VALUE(result_count, false); + + em_storage_write_conditional_clause_for_getting_mail_list(account_id, mailbox_name, addr_list, thread_id, start_index, limit_count, search_type, search_value, sorting, conditional_clause_string, QUERY_SIZE, &error); + + EM_DEBUG_LOG("conditional_clause_string[%s].", conditional_clause_string); + + if(!em_storage_query_mail_list(conditional_clause_string, transaction, mail_list, result_count, &error)) { + EM_DEBUG_EXCEPTION("em_storage_query_mail_list [%d]", error); + goto FINISH_OFF; + } + + ret = true; + +FINISH_OFF: + if (err_code != NULL) + *err_code = error; + + EM_PROFILE_END(em_storage_get_mail_list_func); + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + + +/** + * em_storage_get_mails - Get the Mail list information based on mailbox_name name + * + * + */ +EXPORT_API int em_storage_get_mails(int account_id, const char *mailbox_name, emf_email_address_list_t* addr_list, int thread_id, int start_index, int limit_count, emf_sort_type_t sorting, int transaction, emf_mail_tbl_t** mail_list, int *result_count, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN(); + EM_PROFILE_BEGIN(emStorageGetMails); + + int count = 0, ret = false, error = EM_STORAGE_ERROR_NONE; + emf_mail_tbl_t *p_data_tbl = NULL; + char conditional_clause_string[QUERY_SIZE] = {0, }; + + EM_IF_NULL_RETURN_VALUE(mail_list, false); + EM_IF_NULL_RETURN_VALUE(result_count, false); + + if (!result_count || !mail_list || account_id < ALL_ACCOUNT) { + EM_DEBUG_EXCEPTION("EM_STORAGE_ERROR_INVALID_PARAM"); + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + em_storage_write_conditional_clause_for_getting_mail_list(account_id, mailbox_name, addr_list, thread_id, start_index, limit_count, 0, NULL, sorting, conditional_clause_string, QUERY_SIZE, &error); + + EM_DEBUG_LOG("conditional_clause_string [%s]", conditional_clause_string); + + if(!em_storage_query_mail_tbl(conditional_clause_string, transaction, &p_data_tbl, &count, &error)) { + EM_DEBUG_EXCEPTION("em_storage_query_mail_tbl failed [%d]", error); + goto FINISH_OFF; + } + + ret = true; + +FINISH_OFF: + if (ret == true) { + *mail_list = p_data_tbl; + *result_count = count; + EM_DEBUG_LOG("COUNT : %d", count); + } + else if (p_data_tbl != NULL) + em_storage_free_mail(&p_data_tbl, count, NULL); + + if (err_code != NULL) + *err_code = error; + + EM_PROFILE_END(emStorageGetMails); + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + + + +/** + * em_storage_get_searched_mail_list - Get the mail list information after filtering + * + * + */ +EXPORT_API int em_storage_get_searched_mail_list(int account_id, const char *mailbox_name, int thread_id, int search_type, const char *search_value, int start_index, int limit_count, emf_sort_type_t sorting, int transaction, emf_mail_list_item_t** mail_list, int *result_count, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN(); + + int ret = false, error = EM_STORAGE_ERROR_NONE; + char conditional_clause[QUERY_SIZE] = {0, }; + + EM_IF_NULL_RETURN_VALUE(mail_list, false); + EM_IF_NULL_RETURN_VALUE(result_count, false); + + if (!result_count || !mail_list || account_id < ALL_ACCOUNT) { + EM_DEBUG_EXCEPTION("select_num[%p], Mail_list[%p]", result_count, mail_list); + error = EM_STORAGE_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + em_storage_write_conditional_clause_for_getting_mail_list(account_id, mailbox_name, NULL, thread_id, start_index, limit_count, search_type, search_value, sorting, conditional_clause, QUERY_SIZE, &error); + + EM_DEBUG_LOG("conditional_clause[%s]", conditional_clause); + + if(!em_storage_query_mail_list(conditional_clause, transaction, mail_list, result_count, &error)) { + EM_DEBUG_EXCEPTION("em_storage_query_mail_list [%d]", error); + goto FINISH_OFF; + } + + ret = true; + +FINISH_OFF: + EM_DEBUG_LOG("em_storage_get_searched_mail_list finish off"); + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + + +static int em_storage_get_password_file_name(int account_id, char *recv_password_file_name, char *send_password_file_name) +{ + EM_DEBUG_FUNC_BEGIN("account_id[%d]", account_id); + + if (account_id <= 0 || !recv_password_file_name || !send_password_file_name) { + EM_DEBUG_EXCEPTION("Invalid parameter"); + return EM_STORAGE_ERROR_INVALID_PARAM; + } + + sprintf(recv_password_file_name, ".email_account_%d_recv", account_id); + sprintf(send_password_file_name, ".email_account_%d_send", account_id); + EM_DEBUG_FUNC_END(); + return EM_STORAGE_ERROR_NONE; +} + +static int em_storage_read_password_ss(char *file_name, char **password) +{ + EM_DEBUG_FUNC_BEGIN("file_name[%s], password[%p]", file_name, password); + + if (!file_name || !password) { + EM_DEBUG_EXCEPTION("Invalid Parameter"); + return EM_STORAGE_ERROR_INVALID_PARAM; + } + + size_t buf_len = 0, read_len = 0; + ssm_file_info_t sfi; + char *temp_password = NULL; + int ret = EM_STORAGE_ERROR_NONE; + + if (ssm_getinfo(file_name, &sfi, SSM_FLAG_SECRET_OPERATION, NULL) < 0) { + EM_DEBUG_EXCEPTION("ssm_getinfo() failed."); + ret = EM_STORAGE_ERROR_SYSTEM_FAILURE; + goto FINISH_OFF; + } + + buf_len = sfi.originSize; + EM_DEBUG_LOG("password buf_len[%d]", buf_len); + if ((temp_password = (char *)malloc(buf_len + 1)) == NULL) { + EM_DEBUG_EXCEPTION("malloc failed..."); + + ret = EM_STORAGE_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + memset(temp_password, 0x00, buf_len + 1); + + if (ssm_read(file_name, temp_password, buf_len, &read_len, SSM_FLAG_SECRET_OPERATION, NULL) < 0) { + EM_DEBUG_EXCEPTION("ssm_read() failed."); + ret = EM_STORAGE_ERROR_SYSTEM_FAILURE; + goto FINISH_OFF; + } + + EM_DEBUG_LOG("password_file_name[%s], password[%s], originSize[%d], read len[%d]", file_name, temp_password, sfi.originSize, read_len); + + *password = temp_password; + temp_password = NULL; + +FINISH_OFF: + EM_SAFE_FREE(temp_password); + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + + +EXPORT_API int em_storage_get_account_by_id(int account_id, int pulloption, emf_mail_account_tbl_t **account, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id[%d], pulloption[%d], account[%p], transaction[%d], err_code[%p]", account_id, pulloption, account, transaction, err_code); + + if (!account) { + EM_DEBUG_EXCEPTION("account_id[%d], account[%p]", account_id, account); + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + int ret = false; + int error = EM_STORAGE_ERROR_NONE; + emf_mail_account_tbl_t* p_data_tbl = NULL; + DB_STMT hStmt = NULL; + char sql_query_string[QUERY_SIZE] = {0, }; + int rc = -1; + int sql_len = 0; + char recv_password_file_name[MAX_PW_FILE_NAME_LENGTH]; + char send_password_file_name[MAX_PW_FILE_NAME_LENGTH]; + + sqlite3 *local_db_handle = em_storage_get_db_connection(); + EM_STORAGE_START_READ_TRANSACTION(transaction); + + /* Make query string */ + SNPRINTF(sql_query_string, sizeof(sql_query_string), "SELECT "); + sql_len = strlen(sql_query_string); + + if (pulloption & EMF_ACC_GET_OPT_DEFAULT) { + SNPRINTF(sql_query_string + sql_len, sizeof(sql_query_string) - sql_len, "account_bind_type, receiving_server_type, receiving_server_addr, email_addr, user_name, \ + retrieval_mode, port_num, use_security, sending_server_type, sending_server_addr, sending_port_num, sending_auth, sending_security, sending_user, \ + display_name, reply_to_addr, return_addr, account_id, keep_on_server, flag1, flag2, pop_before_smtp, apop, logo_icon_path, preset_account, target_storage, check_interval, index_color, sync_status, "); + sql_len = strlen(sql_query_string); + } + + if (pulloption & EMF_ACC_GET_OPT_ACCOUNT_NAME) { + SNPRINTF(sql_query_string + sql_len, sizeof(sql_query_string) - sql_len, " account_name, "); + sql_len = strlen(sql_query_string); + } + + /* get from secure storage, not from db */ + if (pulloption & EMF_ACC_GET_OPT_OPTIONS) { + SNPRINTF(sql_query_string + sql_len, sizeof(sql_query_string) - sql_len, " priority, keep_local_copy, req_delivery_receipt, req_read_receipt, download_limit, block_address, block_subject, display_name_from, \ + reply_with_body, forward_with_files, add_myname_card, add_signature, signature, add_my_address_to_bcc, my_account_id, "); + sql_len = strlen(sql_query_string); + } + /* dummy value, FROM WHERE clause */ + SNPRINTF(sql_query_string + sql_len, sizeof(sql_query_string) - sql_len, "0 FROM mail_account_tbl WHERE account_id = %d", account_id); + + /* FROM clause */ + EM_DEBUG_LOG("query = [%s]", sql_query_string); + + /* execute a sql and count rows */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_prepare_v2(local_db_handle, sql_query_string, strlen(sql_query_string), &hStmt, NULL), rc); + EM_DEBUG_DB_EXEC((SQLITE_OK != rc), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) sqlite3_prepare fail:(%d) %s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_step(hStmt), rc); + EM_DEBUG_DB_EXEC((rc != SQLITE_ROW && rc != SQLITE_DONE), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("sqlite3_step fail:%d", rc)); + + if (rc == SQLITE_DONE) { + EM_DEBUG_EXCEPTION("no matched account found..."); + error = EM_STORAGE_ERROR_ACCOUNT_NOT_FOUND; + goto FINISH_OFF; + } + + /* Assign query result to structure */ + if (!(p_data_tbl = (emf_mail_account_tbl_t *)malloc(sizeof(emf_mail_account_tbl_t) * 1))) { + EM_DEBUG_EXCEPTION("malloc failed..."); + error = EM_STORAGE_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + memset(p_data_tbl, 0x00, sizeof(emf_mail_account_tbl_t) * 1); + int col_index = 0; + + if (pulloption & EMF_ACC_GET_OPT_DEFAULT) { + _getStmtFieldDataInt(hStmt, &(p_data_tbl->account_bind_type), col_index++); + _getStmtFieldDataInt(hStmt, &(p_data_tbl->receiving_server_type), col_index++); + _getStmtFieldDataString(hStmt, &(p_data_tbl->receiving_server_addr), 0, col_index++); + _getStmtFieldDataString(hStmt, &(p_data_tbl->email_addr), 0, col_index++); + _getStmtFieldDataString(hStmt, &(p_data_tbl->user_name), 0, col_index++); + _getStmtFieldDataInt(hStmt, &(p_data_tbl->retrieval_mode), col_index++); + _getStmtFieldDataInt(hStmt, &(p_data_tbl->port_num), col_index++); + _getStmtFieldDataInt(hStmt, &(p_data_tbl->use_security), col_index++); + _getStmtFieldDataInt(hStmt, &(p_data_tbl->sending_server_type), col_index++); + _getStmtFieldDataString(hStmt, &(p_data_tbl->sending_server_addr), 0, col_index++); + _getStmtFieldDataInt(hStmt, &(p_data_tbl->sending_port_num), col_index++); + _getStmtFieldDataInt(hStmt, &(p_data_tbl->sending_auth), col_index++); + _getStmtFieldDataInt(hStmt, &(p_data_tbl->sending_security), col_index++); + _getStmtFieldDataString(hStmt, &(p_data_tbl->sending_user), 0, col_index++); + _getStmtFieldDataString(hStmt, &(p_data_tbl->display_name), 0, col_index++); + _getStmtFieldDataString(hStmt, &(p_data_tbl->reply_to_addr), 0, col_index++); + _getStmtFieldDataString(hStmt, &(p_data_tbl->return_addr), 0, col_index++); + _getStmtFieldDataInt(hStmt, &(p_data_tbl->account_id), col_index++); + _getStmtFieldDataInt(hStmt, &(p_data_tbl->keep_on_server), col_index++); + _getStmtFieldDataInt(hStmt, &(p_data_tbl->flag1), col_index++); + _getStmtFieldDataInt(hStmt, &(p_data_tbl->flag2), col_index++); + _getStmtFieldDataInt(hStmt, &(p_data_tbl->pop_before_smtp), col_index++); + _getStmtFieldDataInt(hStmt, &(p_data_tbl->apop), col_index++); + _getStmtFieldDataString(hStmt, &(p_data_tbl->logo_icon_path), 0, col_index++); + _getStmtFieldDataInt(hStmt, &(p_data_tbl->preset_account), col_index++); + _getStmtFieldDataInt(hStmt, &(p_data_tbl->target_storage), col_index++); + _getStmtFieldDataInt(hStmt, &(p_data_tbl->check_interval), col_index++); + _getStmtFieldDataInt(hStmt, &(p_data_tbl->index_color), col_index++); + _getStmtFieldDataInt(hStmt, &(p_data_tbl->sync_status), col_index++); + } + + if (pulloption & EMF_ACC_GET_OPT_ACCOUNT_NAME) + _getStmtFieldDataString(hStmt, &(p_data_tbl->account_name), 0, col_index++); + + if (pulloption & EMF_ACC_GET_OPT_PASSWORD) { + /* get password file name */ + if ((error = em_storage_get_password_file_name(p_data_tbl->account_id, recv_password_file_name, send_password_file_name)) != EM_STORAGE_ERROR_NONE) { + EM_DEBUG_EXCEPTION("em_storage_get_password_file_name failed."); + goto FINISH_OFF; + } + + /* read password from secure storage */ + if ((error = em_storage_read_password_ss(recv_password_file_name, &(p_data_tbl->password))) < 0) { + EM_DEBUG_EXCEPTION(" em_storage_read_password_ss() failed..."); + goto FINISH_OFF; + } + EM_DEBUG_LOG("recv_password_file_name[%s], password[%s]", recv_password_file_name, p_data_tbl->password); + + if ((error = em_storage_read_password_ss(send_password_file_name, &(p_data_tbl->sending_password))) < 0) { + EM_DEBUG_EXCEPTION(" em_storage_read_password_ss() failed..."); + goto FINISH_OFF; + } + EM_DEBUG_LOG("send_password_file_name[%s], password[%s]", send_password_file_name, p_data_tbl->sending_password); + } + + if (pulloption & EMF_ACC_GET_OPT_OPTIONS) { + _getStmtFieldDataInt(hStmt, &(p_data_tbl->options.priority), col_index++); + _getStmtFieldDataInt(hStmt, &(p_data_tbl->options.keep_local_copy), col_index++); + _getStmtFieldDataInt(hStmt, &(p_data_tbl->options.req_delivery_receipt), col_index++); + _getStmtFieldDataInt(hStmt, &(p_data_tbl->options.req_read_receipt), col_index++); + _getStmtFieldDataInt(hStmt, &(p_data_tbl->options.download_limit), col_index++); + _getStmtFieldDataInt(hStmt, &(p_data_tbl->options.block_address), col_index++); + _getStmtFieldDataInt(hStmt, &(p_data_tbl->options.block_subject), col_index++); + _getStmtFieldDataString(hStmt, &(p_data_tbl->options.display_name_from), 0, col_index++); + _getStmtFieldDataInt(hStmt, &(p_data_tbl->options.reply_with_body), col_index++); + _getStmtFieldDataInt(hStmt, &(p_data_tbl->options.forward_with_files), col_index++); + _getStmtFieldDataInt(hStmt, &(p_data_tbl->options.add_myname_card), col_index++); + _getStmtFieldDataInt(hStmt, &(p_data_tbl->options.add_signature), col_index++); + _getStmtFieldDataString(hStmt, &(p_data_tbl->options.signature), 0, col_index++); + _getStmtFieldDataInt(hStmt, &(p_data_tbl->options.add_my_address_to_bcc), col_index++); + _getStmtFieldDataInt(hStmt, &(p_data_tbl->my_account_id), col_index++); + } + + ret = true; + +FINISH_OFF: + if (ret == true) + *account = p_data_tbl; + else { + if (p_data_tbl) + em_storage_free_account((emf_mail_account_tbl_t **)&p_data_tbl, 1, NULL); + } + if (hStmt != NULL) { + rc = sqlite3_finalize(hStmt); + if (rc != SQLITE_OK) { + EM_DEBUG_EXCEPTION("sqlite3_finalize failed - %d", rc); + error = EM_STORAGE_ERROR_DB_FAILURE; + } + } + + EM_STORAGE_FINISH_READ_TRANSACTION(transaction); + _DISCONNECT_DB; + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API int em_storage_get_password_length_of_account(int account_id, int *password_length, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id[%d], password_length[%p], err_code[%p]", account_id, password_length, err_code); + + if (account_id <= 0 || password_length == NULL) { + EM_DEBUG_EXCEPTION("EM_STORAGE_ERROR_INVALID_PARAM"); + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + int ret = false; + int error = EM_STORAGE_ERROR_NONE; + char recv_password_file_name[MAX_PW_FILE_NAME_LENGTH]; + char send_password_file_name[MAX_PW_FILE_NAME_LENGTH]; + char *temp_password = NULL; + + + /* get password file name */ + if ((error = em_storage_get_password_file_name(account_id, recv_password_file_name, send_password_file_name)) != EM_STORAGE_ERROR_NONE) { + EM_DEBUG_EXCEPTION("em_storage_get_password_file_name failed."); + goto FINISH_OFF; + } + + /* read password from secure storage */ + if ((error = em_storage_read_password_ss(recv_password_file_name, &temp_password)) < 0 || !temp_password) { + EM_DEBUG_EXCEPTION(" em_storage_read_password_ss() failed..."); + goto FINISH_OFF; + } + + *password_length = strlen(temp_password); + + EM_DEBUG_LOG("recv_password_file_name[%s], *password_length[%d]", recv_password_file_name, *password_length); + + ret = true; + +FINISH_OFF: + EM_SAFE_FREE(temp_password); + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API int em_storage_update_account(int account_id, emf_mail_account_tbl_t* account, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id[%d], account[%p], transaction[%d], err_code[%p]", account_id, account, transaction, err_code); + + if (account_id < FIRST_ACCOUNT_ID || !account) { + EM_DEBUG_EXCEPTION("EM_STORAGE_ERROR_INVALID_PARAM"); + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + int error = EM_STORAGE_ERROR_NONE; + int rc, ret = false; + + DB_STMT hStmt = NULL; + char sql_query_string[QUERY_SIZE] = {0, }; + char recv_password_file_name[MAX_PW_FILE_NAME_LENGTH]; + char send_password_file_name[MAX_PW_FILE_NAME_LENGTH]; + + sqlite3 *local_db_handle = em_storage_get_db_connection(); + EM_STORAGE_START_WRITE_TRANSACTION(transaction, error); + + SNPRINTF(sql_query_string, sizeof(sql_query_string), + "UPDATE mail_account_tbl SET" + " account_bind_type = ?" + ", account_name = ?" + ", receiving_server_type = ?" + ", receiving_server_addr = ?" + ", email_addr = ?" + ", user_name = ?" + ", retrieval_mode = ?" + ", port_num = ?" + ", use_security = ?" + ", sending_server_type = ?" + ", sending_server_addr = ?" + ", sending_port_num = ?" + ", sending_auth = ?" + ", sending_security = ?" + ", sending_user = ?" + ", display_name = ?" + ", reply_to_addr = ?" + ", return_addr = ?" + ", keep_on_server = ?" + ", flag1 = ?" + ", flag2 = ?" + ", pop_before_smtp = ?" /* POP before SMTP authentication */ + ", apop = ?" /* APOP authentication */ + ", logo_icon_path = ?" /* Receving Option : Account logo icon */ + ", preset_account = ?" /* Receving Option : Preset account or not */ + ", target_storage = ?" /* Receving Option : Specifies the targetStorage. 0 is phone, 1 is MMC */ + ", check_interval = ?" /* Receving Option : Specifies the check interval. Unit is minute */ + ", priority = ?" /* Sending Option : Specifies the prority. 1=high 3=normal 5=low */ + ", keep_local_copy = ?" /* Sending Option : */ + ", req_delivery_receipt = ?" /* Sending Option : */ + ", req_read_receipt = ?" /* Sending Option : */ + ", download_limit = ?" /* Sending Option : */ + ", block_address = ?" /* Sending Option : */ + ", block_subject = ?" /* Sending Option : */ + ", display_name_from = ?" /* Sending Option : */ + ", reply_with_body = ?" /* Sending Option : */ + ", forward_with_files = ?" /* Sending Option : */ + ", add_myname_card = ?" /* Sending Option : */ + ", add_signature = ?" /* Sending Option : */ + ", signature = ?" /* Sending Option : */ + ", add_my_address_to_bcc = ?" /* Sending Option : */ + ", my_account_id = ?" /* Support 'My Account' */ + ", index_color = ?" /* Index color */ + ", sync_status = ?" /* Sync Status */ + " WHERE account_id = ?"); + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_prepare_v2(local_db_handle, sql_query_string, strlen(sql_query_string), &hStmt, NULL), rc); + EM_DEBUG_LOG("After sqlite3_prepare hStmt = %p", hStmt); + EM_DEBUG_DB_EXEC((SQLITE_OK != rc), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) sqlite3_prepare fail:(%d) %s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + int i = 0; + + _bindStmtFieldDataInt(hStmt, i++, account->account_bind_type); + _bindStmtFieldDataString(hStmt, i++, (char *)account->account_name, 0, ACCOUNT_NAME_LEN_IN_MAIL_ACCOUNT_TBL); + _bindStmtFieldDataInt(hStmt, i++, account->receiving_server_type); + _bindStmtFieldDataString(hStmt, i++, (char *)account->receiving_server_addr, 0, RECEIVING_SERVER_ADDR_LEN_IN_MAIL_ACCOUNT_TBL); + _bindStmtFieldDataString(hStmt, i++, (char *)account->email_addr, 0, EMAIL_ADDR_LEN_IN_MAIL_ACCOUNT_TBL); + _bindStmtFieldDataString(hStmt, i++, (char *)account->user_name, 0, USER_NAME_LEN_IN_MAIL_ACCOUNT_TBL); + _bindStmtFieldDataInt(hStmt, i++, account->retrieval_mode); + _bindStmtFieldDataInt(hStmt, i++, account->port_num); + _bindStmtFieldDataInt(hStmt, i++, account->use_security); + _bindStmtFieldDataInt(hStmt, i++, account->sending_server_type); + _bindStmtFieldDataString(hStmt, i++, (char *)account->sending_server_addr, 0, SENDING_SERVER_ADDR_LEN_IN_MAIL_ACCOUNT_TBL); + _bindStmtFieldDataInt(hStmt, i++, account->sending_port_num); + _bindStmtFieldDataInt(hStmt, i++, account->sending_auth); + _bindStmtFieldDataInt(hStmt, i++, account->sending_security); + _bindStmtFieldDataString(hStmt, i++, (char *)account->sending_user, 0, SENDING_USER_LEN_IN_MAIL_ACCOUNT_TBL); + _bindStmtFieldDataString(hStmt, i++, (char *)account->display_name, 0, DISPLAY_NAME_LEN_IN_MAIL_ACCOUNT_TBL); + _bindStmtFieldDataString(hStmt, i++, (char *)account->reply_to_addr, 0, REPLY_TO_ADDR_LEN_IN_MAIL_ACCOUNT_TBL); + _bindStmtFieldDataString(hStmt, i++, (char *)account->return_addr, 0, RETURN_ADDR_LEN_IN_MAIL_ACCOUNT_TBL); + _bindStmtFieldDataInt(hStmt, i++, account->keep_on_server); + _bindStmtFieldDataInt(hStmt, i++, account->flag1); + _bindStmtFieldDataInt(hStmt, i++, account->flag2); + _bindStmtFieldDataInt(hStmt, i++, account->pop_before_smtp); + _bindStmtFieldDataInt(hStmt, i++, account->apop); + _bindStmtFieldDataString(hStmt, i++, account->logo_icon_path, 0, LOGO_ICON_PATH_LEN_IN_MAIL_ACCOUNT_TBL); + _bindStmtFieldDataInt(hStmt, i++, account->preset_account); + _bindStmtFieldDataInt(hStmt, i++, account->target_storage); + _bindStmtFieldDataInt(hStmt, i++, account->check_interval); + _bindStmtFieldDataInt(hStmt, i++, account->options.priority); + _bindStmtFieldDataInt(hStmt, i++, account->options.keep_local_copy); + _bindStmtFieldDataInt(hStmt, i++, account->options.req_delivery_receipt); + _bindStmtFieldDataInt(hStmt, i++, account->options.req_read_receipt); + _bindStmtFieldDataInt(hStmt, i++, account->options.download_limit); + _bindStmtFieldDataInt(hStmt, i++, account->options.block_address); + _bindStmtFieldDataInt(hStmt, i++, account->options.block_subject); + _bindStmtFieldDataString(hStmt, i++, account->options.display_name_from, 0, DISPLAY_NAME_FROM_LEN_IN_MAIL_ACCOUNT_TBL); + _bindStmtFieldDataInt(hStmt, i++, account->options.reply_with_body); + _bindStmtFieldDataInt(hStmt, i++, account->options.forward_with_files); + _bindStmtFieldDataInt(hStmt, i++, account->options.add_myname_card); + _bindStmtFieldDataInt(hStmt, i++, account->options.add_signature); + _bindStmtFieldDataString(hStmt, i++, account->options.signature, 0, SIGNATURE_LEN_IN_MAIL_ACCOUNT_TBL); + if (account->options.add_my_address_to_bcc != 0) + account->options.add_my_address_to_bcc = 1; + _bindStmtFieldDataInt(hStmt, i++, account->options.add_my_address_to_bcc); + _bindStmtFieldDataInt(hStmt, i++, account->my_account_id); + _bindStmtFieldDataInt(hStmt, i++, account->index_color); + _bindStmtFieldDataInt(hStmt, i++, account->sync_status); + _bindStmtFieldDataInt(hStmt, i++, account_id); + + /* rc = sqlite3_step(hStmt); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_step(hStmt), rc); + EM_DEBUG_DB_EXEC((SQLITE_FULL == rc), {error = EM_STORAGE_ERROR_DB_IS_FULL;goto FINISH_OFF; }, + ("sqlite3_step fail:%d", rc)); + EM_DEBUG_DB_EXEC((rc != SQLITE_ROW && rc != SQLITE_DONE), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("sqlite3_step fail:%d", rc)); + + /* validate account existence */ + rc = sqlite3_changes(local_db_handle); + if (rc == 0) { + EM_DEBUG_EXCEPTION(" no matched account found..."); + + error = EM_STORAGE_ERROR_ACCOUNT_NOT_FOUND; + goto FINISH_OFF; + } + + /* get password file name */ + if ((error = em_storage_get_password_file_name(account_id, recv_password_file_name, send_password_file_name)) != EM_STORAGE_ERROR_NONE) { + EM_DEBUG_EXCEPTION("em_storage_get_password_file_name failed."); + goto FINISH_OFF; + } + + /* save passwords to the secure storage */ + EM_DEBUG_LOG("save to the secure storage : recv_file[%s], recv_pass[%s], send_file[%s], send_pass[%s]", recv_password_file_name, account->password, send_password_file_name, account->sending_password); + if (account->password && (strlen(account->password) > 0)) { + if (ssm_write_buffer(account->password, strlen(account->password), recv_password_file_name, SSM_FLAG_SECRET_OPERATION, NULL) < 0) { + EM_DEBUG_EXCEPTION(" ssm_write_buffer failed -recv password : file[%s]", recv_password_file_name); + error = EM_STORAGE_ERROR_SYSTEM_FAILURE; + goto FINISH_OFF; + } + } + + if (account->sending_password && (strlen(account->sending_password) > 0)) { + if (ssm_write_buffer(account->sending_password, strlen(account->sending_password), send_password_file_name, SSM_FLAG_SECRET_OPERATION, NULL) < 0) { + EM_DEBUG_EXCEPTION(" ssm_write_buffer failed -send password : file[%s]", send_password_file_name); + error = EM_STORAGE_ERROR_SYSTEM_FAILURE; + goto FINISH_OFF; + } + } + + if (!em_storage_notify_storage_event(NOTI_ACCOUNT_UPDATE, account->account_id, 0, NULL, 0)) + EM_DEBUG_EXCEPTION(" em_storage_notify_storage_event[ NOTI_ACCOUNT_UPDATE] : Notification Failed >>> "); + ret = true; + +FINISH_OFF: + + if (hStmt != NULL) { + EM_DEBUG_LOG(" Before sqlite3_finalize hStmt = %p", hStmt); + + rc = sqlite3_finalize(hStmt); + if (rc != SQLITE_OK) { + EM_DEBUG_LOG(" sqlite3_finalize failed - %d", rc); + error = EM_STORAGE_ERROR_DB_FAILURE; + } + } + + EM_STORAGE_FINISH_WRITE_TRANSACTION(transaction, ret, error); + + _DISCONNECT_DB; + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API int em_storage_get_sync_status_of_account(int account_id, int *result_sync_status,int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id[%d], result_sync_status [%p], err_code[%p]", account_id, result_sync_status, err_code); + + if(!result_sync_status) { + EM_DEBUG_EXCEPTION("EM_STORAGE_ERROR_INVALID_PARAM"); + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + int error = EM_STORAGE_ERROR_NONE, rc, ret = false, sync_status, count, i, col_index; + char sql_query_string[QUERY_SIZE] = {0, }; + char **result = NULL; + sqlite3 *local_db_handle = em_storage_get_db_connection(); + + if(account_id) + SNPRINTF(sql_query_string, sizeof(sql_query_string), "SELECT sync_status FROM mail_account_tbl WHERE account_id = %d", account_id); + else + SNPRINTF(sql_query_string, sizeof(sql_query_string), "SELECT sync_status FROM mail_account_tbl"); + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_get_table(local_db_handle, sql_query_string, &result, &count, 0, NULL), rc); + EM_DEBUG_DB_EXEC((SQLITE_OK != rc && -1 != rc), {error = EM_STORAGE_ERROR_DB_FAILURE;sqlite3_free_table(result);goto FINISH_OFF; }, + ("SQL(%s) sqlite3_get_table fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + if (!count) { + EM_DEBUG_EXCEPTION("no matched account found..."); + error = EM_STORAGE_ERROR_ACCOUNT_NOT_FOUND; + goto FINISH_OFF; + } + + col_index = 1; + *result_sync_status = 0; + + for(i = 0; i < count; i++) { + _getTableFieldDataInt(result, &sync_status, col_index++); + *result_sync_status |= sync_status; + } + + EM_DEBUG_LOG("sync_status [%d]", sync_status); + + sqlite3_free_table(result); + + ret = true; + +FINISH_OFF: + + _DISCONNECT_DB; + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API int em_storage_update_sync_status_of_account(int account_id, emf_set_type_t set_operator, int sync_status, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id[%d], set_operator[%d], sync_status [%d], transaction[%d], err_code[%p]", account_id, set_operator, sync_status, transaction, err_code); + + int error = EM_STORAGE_ERROR_NONE, rc, ret = false, set_value = sync_status, result_sync_status; + char sql_query_string[QUERY_SIZE] = {0, }; + sqlite3 *local_db_handle = em_storage_get_db_connection(); + + if(set_operator != SET_TYPE_SET && account_id) { + if(!em_storage_get_sync_status_of_account(account_id, &result_sync_status, &error)) { + EM_DEBUG_EXCEPTION("em_storage_get_sync_status_of_account failed [%d]", error); + goto FINISH_OFF; + } + switch(set_operator) { + case SET_TYPE_UNION : + set_value = result_sync_status | set_value; + break; + case SET_TYPE_MINUS : + set_value = result_sync_status & (~set_value); + break; + default: + EM_DEBUG_EXCEPTION("EMF_ERROR_NOT_SUPPORTED [%d]", set_operator); + error = EMF_ERROR_NOT_SUPPORTED; + break; + } + EM_DEBUG_LOG("set_value [%d]", set_value); + } + + EM_STORAGE_START_WRITE_TRANSACTION(transaction, error); + + if(account_id) + SNPRINTF(sql_query_string, sizeof(sql_query_string), "UPDATE mail_account_tbl SET sync_status = %d WHERE account_id = %d", set_value, account_id); + else + SNPRINTF(sql_query_string, sizeof(sql_query_string), "UPDATE mail_account_tbl SET sync_status = %d WHERE receiving_server_type <> 5", set_value); + + EM_DEBUG_LOG("sql_query_string [%s]", sql_query_string); + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, sql_query_string, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) exec fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + rc = sqlite3_changes(local_db_handle); + + if (rc == 0) { + EM_DEBUG_EXCEPTION("no matched account found..."); + error = EM_STORAGE_ERROR_ACCOUNT_NOT_FOUND; + goto FINISH_OFF; + } + + if (!em_storage_notify_storage_event(NOTI_ACCOUNT_UPDATE_SYNC_STATUS, account_id, 0, NULL, 0)) + EM_DEBUG_EXCEPTION("em_storage_notify_storage_event[NOTI_ACCOUNT_UPDATE_SYNC_STATUS] : Notification failed"); + ret = true; + +FINISH_OFF: + + EM_STORAGE_FINISH_WRITE_TRANSACTION(transaction, ret, error); + + _DISCONNECT_DB; + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API int em_storage_add_account(emf_mail_account_tbl_t* account, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account[%p], transaction[%d], err_code[%p]", account, transaction, err_code); + + if (!account) { + EM_DEBUG_EXCEPTION("account[%p], transaction[%d], err_code[%p]", account, transaction, err_code); + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + int rc = -1, ret = false; + int error = EM_STORAGE_ERROR_NONE; + DB_STMT hStmt = NULL; + char sql_query_string[QUERY_SIZE] = {0, }; + char recv_password_file_name[MAX_PW_FILE_NAME_LENGTH]; + char send_password_file_name[MAX_PW_FILE_NAME_LENGTH]; + + sqlite3 *local_db_handle = em_storage_get_db_connection(); + + EM_STORAGE_START_WRITE_TRANSACTION(transaction, error); + + char *sql = "SELECT max(rowid) FROM mail_account_tbl;"; + char **result = NULL; + + /* rc = sqlite3_get_table(local_db_handle, sql, &result, NULL, NULL, NULL); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_get_table(local_db_handle, sql, &result, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;sqlite3_free_table(result);goto FINISH_OFF; }, + ("SQL(%s) sqlite3_get_table fail:%d -%s", sql, rc, sqlite3_errmsg(local_db_handle))); + + if (NULL==result[1]) rc = 1; + else rc = atoi(result[1])+1; + sqlite3_free_table(result); + result = NULL; + + account->account_id = rc; + + if ((error = em_storage_get_password_file_name(account->account_id, recv_password_file_name, send_password_file_name)) != EM_STORAGE_ERROR_NONE) { + EM_DEBUG_EXCEPTION("em_storage_get_password_file_name failed."); + goto FINISH_OFF; + } + + EM_DEBUG_LOG(" >>>> ACCOUNT_ID [ %d ] ", account->account_id); + SNPRINTF(sql_query_string, sizeof(sql_query_string), + "INSERT INTO mail_account_tbl VALUES " + "( " + " ? " + " , ? " + " , ? " + " , ? " + " , ? " + " , ? " + " , ? " /* password - for receving */ + " , ? " + " , ? " + " , ? " + " , ? " + " , ? " + " , ? " + " , ? " + " , ? " + " , ? " + " , ? " /* sending_password */ + " , ? " + " , ? " + " , ? " + " , ? " + " , ? " + " , ? " + " , ? " + " , ? " /* POP before SMTP authentication */ + " , ? " /* APOP Authentication */ + " , ? " + " , ? " + " , ? " + " , ? " + " , ? " + " , ? " + " , ? " + " , ? " + " , ? " + " , ? " + " , ? " + " , ? " + " , ? " + " , ? " + " , ? " + " , ? " + " , ? " + " , ? " /* add full_address_bcc */ + " , ? " /* my account id */ + " , ? " /* index_color */ + " , ? " /* Sync Status */ + ") "); + + + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_prepare_v2(local_db_handle, sql_query_string, strlen(sql_query_string), &hStmt, NULL), rc); + EM_DEBUG_DB_EXEC((SQLITE_OK != rc), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) sqlite3_prepare fail:(%d) %s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + EM_DEBUG_LOG(">>>> SQL STMT [ %s ] ", sql_query_string); + _bindStmtFieldDataInt(hStmt, ACCOUNT_BIND_TYPE_IDX_IN_MAIL_ACCOUNT_TBL, account->account_bind_type); + _bindStmtFieldDataString(hStmt, ACCOUNT_NAME_IDX_IN_MAIL_ACCOUNT_TBL, (char *)account->account_name, 0, ACCOUNT_NAME_LEN_IN_MAIL_ACCOUNT_TBL); + _bindStmtFieldDataInt(hStmt, RECEIVING_SERVER_TYPE_TYPE_IDX_IN_MAIL_ACCOUNT_TBL, account->receiving_server_type); + _bindStmtFieldDataString(hStmt, RECEIVING_SERVER_ADDR_IDX_IN_MAIL_ACCOUNT_TBL, (char *)account->receiving_server_addr, 0, RECEIVING_SERVER_ADDR_LEN_IN_MAIL_ACCOUNT_TBL); + _bindStmtFieldDataString(hStmt, EMAIL_ADDR_IDX_IN_MAIL_ACCOUNT_TBL, (char *)account->email_addr, 0, EMAIL_ADDR_LEN_IN_MAIL_ACCOUNT_TBL); + _bindStmtFieldDataString(hStmt, USER_NAME_IDX_IN_MAIL_ACCOUNT_TBL, (char *)account->user_name, 0, USER_NAME_LEN_IN_MAIL_ACCOUNT_TBL); + _bindStmtFieldDataString(hStmt, PASSWORD_IDX_IN_MAIL_ACCOUNT_TBL, (char *)"", 0, PASSWORD_LEN_IN_MAIL_ACCOUNT_TBL); + _bindStmtFieldDataInt(hStmt, RETRIEVAL_MODE_IDX_IN_MAIL_ACCOUNT_TBL, account->retrieval_mode); + _bindStmtFieldDataInt(hStmt, PORT_NUM_IDX_IN_MAIL_ACCOUNT_TBL, account->port_num); + _bindStmtFieldDataInt(hStmt, USE_SECURITY_IDX_IN_MAIL_ACCOUNT_TBL, account->use_security); + _bindStmtFieldDataInt(hStmt, SENDING_SERVER_TYPE_IDX_IN_MAIL_ACCOUNT_TBL, account->sending_server_type); + _bindStmtFieldDataString(hStmt, SENDING_SERVER_ADDR_IDX_IN_MAIL_ACCOUNT_TBL, (char *)account->sending_server_addr, 0, SENDING_SERVER_ADDR_LEN_IN_MAIL_ACCOUNT_TBL); + _bindStmtFieldDataInt(hStmt, SENDING_PORT_NUM_IDX_IN_MAIL_ACCOUNT_TBL, account->sending_port_num); + _bindStmtFieldDataInt(hStmt, SENDING_AUTH_IDX_IN_MAIL_ACCOUNT_TBL, account->sending_auth); + _bindStmtFieldDataInt(hStmt, SENDING_SECURITY_IDX_IN_MAIL_ACCOUNT_TBL, account->sending_security); + _bindStmtFieldDataString(hStmt, SENDING_USER_IDX_IN_MAIL_ACCOUNT_TBL, (char *)account->sending_user, 0, SENDING_USER_LEN_IN_MAIL_ACCOUNT_TBL); + _bindStmtFieldDataString(hStmt, SENDING_PASSWORD_IDX_IN_MAIL_ACCOUNT_TBL, (char *)"", 0, SENDING_PASSWORD_LEN_IN_MAIL_ACCOUNT_TBL); + _bindStmtFieldDataString(hStmt, DISPLAY_NAME_IDX_IN_MAIL_ACCOUNT_TBL, (char *)account->display_name, 0, DISPLAY_NAME_LEN_IN_MAIL_ACCOUNT_TBL); + _bindStmtFieldDataString(hStmt, REPLY_TO_ADDR_IDX_IN_MAIL_ACCOUNT_TBL, (char *)account->reply_to_addr, 0, REPLY_TO_ADDR_LEN_IN_MAIL_ACCOUNT_TBL); + _bindStmtFieldDataString(hStmt, RETURN_ADDR_IDX_IN_MAIL_ACCOUNT_TBL, (char *)account->return_addr, 0, RETURN_ADDR_LEN_IN_MAIL_ACCOUNT_TBL); + _bindStmtFieldDataInt(hStmt, ACCOUNT_ID_IDX_IN_MAIL_ACCOUNT_TBL, account->account_id); + _bindStmtFieldDataInt(hStmt, KEEP_ON_SERVER_IDX_IN_MAIL_ACCOUNT_TBL, account->keep_on_server); + _bindStmtFieldDataInt(hStmt, FLAG1_IDX_IN_MAIL_ACCOUNT_TBL, account->flag1); + _bindStmtFieldDataInt(hStmt, FLAG2_IDX_IN_MAIL_ACCOUNT_TBL, account->flag2); + _bindStmtFieldDataInt(hStmt, POP_BEFORE_SMTP_IDX_IN_MAIL_ACCOUNT_TBL, account->pop_before_smtp); /* POP before SMTP authentication [deepam.p@siso.com] */ + _bindStmtFieldDataInt(hStmt, APOP_IDX_IN_MAIL_ACCOUNT_TBL, account->apop); /* APOP Support [deepam.p@siso.com] */ + _bindStmtFieldDataString(hStmt, LOGO_ICON_PATH_IDX_IN_MAIL_ACCOUNT_TBL, account->logo_icon_path, 0, LOGO_ICON_PATH_LEN_IN_MAIL_ACCOUNT_TBL); + _bindStmtFieldDataInt(hStmt, PRESET_ACCOUNT_IDX_IN_MAIL_ACCOUNT_TBL, account->preset_account); + _bindStmtFieldDataInt(hStmt, TARGET_STORAGE_IDX_IN_MAIL_ACCOUNT_TBL, account->target_storage); + _bindStmtFieldDataInt(hStmt, CHECK_INTERVAL_IDX_IN_MAIL_ACCOUNT_TBL, account->check_interval); + _bindStmtFieldDataInt(hStmt, PRIORITY_IDX_IN_MAIL_ACCOUNT_TBL, account->options.priority); + _bindStmtFieldDataInt(hStmt, KEEP_LOCAL_COPY_IDX_IN_MAIL_ACCOUNT_TBL, account->options.keep_local_copy); + _bindStmtFieldDataInt(hStmt, REQ_DELIVERY_RECEIPT_IDX_IN_MAIL_ACCOUNT_TBL, account->options.req_delivery_receipt); + _bindStmtFieldDataInt(hStmt, REQ_READ_RECEIPT_IDX_IN_MAIL_ACCOUNT_TBL, account->options.req_read_receipt); + _bindStmtFieldDataInt(hStmt, DOWNLOAD_LIMIT_IDX_IN_MAIL_ACCOUNT_TBL, account->options.download_limit); + _bindStmtFieldDataInt(hStmt, BLOCK_ADDRESS_IDX_IN_MAIL_ACCOUNT_TBL, account->options.block_address); + _bindStmtFieldDataInt(hStmt, BLOCK_SUBJECT_IDX_IN_MAIL_ACCOUNT_TBL, account->options.block_subject); + _bindStmtFieldDataString(hStmt, DISPLAY_NAME_FROM_IDX_IN_MAIL_ACCOUNT_TBL, account->options.display_name_from, 0, DISPLAY_NAME_FROM_LEN_IN_MAIL_ACCOUNT_TBL); + _bindStmtFieldDataInt(hStmt, REPLY_WITH_BODY_IDX_IN_MAIL_ACCOUNT_TBL, account->options.reply_with_body); + _bindStmtFieldDataInt(hStmt, FORWARD_WITH_FILES_IDX_IN_MAIL_ACCOUNT_TBL, account->options.forward_with_files); + _bindStmtFieldDataInt(hStmt, ADD_MYNAME_CARD_IDX_IN_MAIL_ACCOUNT_TBL, account->options.add_myname_card); + _bindStmtFieldDataInt(hStmt, ADD_SIGNATURE_IDX_IN_MAIL_ACCOUNT_TBL, account->options.add_signature); + _bindStmtFieldDataString(hStmt, SIGNATURE_IDX_IN_MAIL_ACCOUNT_TBL, account->options.signature, 0, SIGNATURE_LEN_IN_MAIL_ACCOUNT_TBL); + if (account->options.add_my_address_to_bcc != 0) + account->options.add_my_address_to_bcc = 1; + _bindStmtFieldDataInt(hStmt, ADD_MY_ADDRESS_TO_BCC_IDX_IN_MAIL_ACCOUNT_TBL, account->options.add_my_address_to_bcc); + _bindStmtFieldDataInt(hStmt, MY_ACCOUNT_ID_IDX_IN_MAIL_ACCOUNT_TBL, account->my_account_id); + _bindStmtFieldDataInt(hStmt, INDEX_COLOR_IDX_IN_MAIL_ACCOUNT_TBL, account->index_color); + _bindStmtFieldDataInt(hStmt, SYNC_STATUS_IDX_IN_MAIL_ACCOUNT_TBL, account->sync_status); + + /* rc = sqlite3_step(hStmt); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_step(hStmt), rc); + + EM_DEBUG_DB_EXEC((rc == SQLITE_FULL), {error = EM_STORAGE_ERROR_DB_IS_FULL;goto FINISH_OFF; }, + ("sqlite3_step fail:%d", rc)); + EM_DEBUG_DB_EXEC((rc != SQLITE_ROW && rc != SQLITE_DONE), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("sqlite3_step fail:%d, errmsg = %s.", rc, sqlite3_errmsg(local_db_handle))); + + + /* save passwords to the secure storage */ + EM_DEBUG_LOG("save to the secure storage : recv_file[%s], recv_pass[%s], send_file[%s], send_pass[%s]", recv_password_file_name, account->password, send_password_file_name, account->sending_password); + if (ssm_write_buffer(account->password, strlen(account->password), recv_password_file_name, SSM_FLAG_SECRET_OPERATION, NULL) < 0) { + EM_DEBUG_EXCEPTION("ssm_write_buffer failed - recv password : file[%s]", recv_password_file_name); + error = EM_STORAGE_ERROR_SYSTEM_FAILURE; + goto FINISH_OFF; + } + if (ssm_write_buffer(account->sending_password, strlen(account->sending_password), send_password_file_name, SSM_FLAG_SECRET_OPERATION, NULL) < 0) { + EM_DEBUG_EXCEPTION("ssm_write_buffer failed - send password : file[%s]", send_password_file_name); + error = EM_STORAGE_ERROR_SYSTEM_FAILURE; + goto FINISH_OFF; + } + + if (!em_storage_notify_storage_event(NOTI_ACCOUNT_ADD, account->account_id, 0, NULL, 0)) + EM_DEBUG_EXCEPTION("em_storage_notify_storage_event[NOTI_ACCOUNT_ADD] : Notification failed"); + ret = true; + +FINISH_OFF: + + if (hStmt != NULL) { + rc = sqlite3_finalize(hStmt); + if (rc != SQLITE_OK) { + EM_DEBUG_LOG("sqlite3_finalize failed - %d", rc); + error = EM_STORAGE_ERROR_DB_FAILURE; + } + } + else + EM_DEBUG_LOG("hStmt is NULL!!!"); + + EM_STORAGE_FINISH_WRITE_TRANSACTION(transaction, ret, error); + _DISCONNECT_DB; + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + + +EXPORT_API int em_storage_delete_account(int account_id, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id[%d], transaction[%d], err_code[%p]", account_id, transaction, err_code); + + if (account_id < FIRST_ACCOUNT_ID) { + EM_DEBUG_EXCEPTION(" account_id[%d]", account_id); + + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + int rc = -1, ret = false; + int error = EM_STORAGE_ERROR_NONE; + sqlite3 *local_db_handle = em_storage_get_db_connection(); + EM_STORAGE_START_WRITE_TRANSACTION(transaction, error); + + /* TODO : delete password files - file names can be obtained from db or a rule that makes a name */ + DB_STMT hStmt = NULL; + char sql_query_string[QUERY_SIZE] = {0, }; + char recv_password_file_name[MAX_PW_FILE_NAME_LENGTH]; + char send_password_file_name[MAX_PW_FILE_NAME_LENGTH]; + +/* + memset(sql_query_string, 0x00, sizeof(sql_query_string)); + SNPRINTF(sql_query_string, sizeof(sql_query_string), "SELECT password, sending_password FROM mail_account_tbl WHERE account_id = %d", account_id); + EM_DEBUG_LOG("query = [%s]", sql_query_string); + + execute a sql and count rows + rc = sqlite3_prepare_v2(local_db_handle, sql_query_string, strlen(sql_query_string), &hStmt, NULL); + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_prepare_v2(local_db_handle, sql_query_string, strlen(sql_query_string), &hStmt, NULL), rc); + EM_DEBUG_DB_EXEC((SQLITE_OK != rc), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) sqlite3_prepare fail:(%d) %s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + rc = sqlite3_step(hStmt); + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_step(hStmt), rc); + EM_DEBUG_DB_EXEC((rc != SQLITE_ROW && rc != SQLITE_DONE), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("sqlite3_step fail:%d", rc)); + + if (rc == SQLITE_DONE) { + EM_DEBUG_LOG(" no matched account found..."); + + error = EM_STORAGE_ERROR_ACCOUNT_NOT_FOUND; + goto FINISH_OFF; + } + _getStmtFieldDataString(hStmt, &(recv_password_file_name), 0, 0); + _getStmtFieldDataString(hStmt, &(send_password_file_name), 0, 1); +*/ + /* get password file name */ + if ((error = em_storage_get_password_file_name(account_id, recv_password_file_name, send_password_file_name)) != EM_STORAGE_ERROR_NONE) { + EM_DEBUG_EXCEPTION("em_storage_get_password_file_name failed."); + goto FINISH_OFF; + } + + /* delete from db */ + memset(sql_query_string, 0x00, sizeof(sql_query_string)); + SNPRINTF(sql_query_string, sizeof(sql_query_string), "DELETE FROM mail_account_tbl WHERE account_id = %d", account_id); + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, sql_query_string, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC((rc == SQLITE_FULL), {error = EM_STORAGE_ERROR_DB_IS_FULL;goto FINISH_OFF; }, + ("sqlite3_exec fail:%d", rc)); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) exec fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + /* validate account existence */ + rc = sqlite3_changes(local_db_handle); + if (rc == 0) { + EM_DEBUG_EXCEPTION(" no matched account found..."); + error = EM_STORAGE_ERROR_ACCOUNT_NOT_FOUND; + goto FINISH_OFF; + } + + /* delete from secure storage */ + if (ssm_delete_file(recv_password_file_name, SSM_FLAG_SECRET_OPERATION, NULL) < 0) { + EM_DEBUG_EXCEPTION(" ssm_delete_file failed -recv password : file[%s]", recv_password_file_name); + error = EM_STORAGE_ERROR_SYSTEM_FAILURE; + goto FINISH_OFF; + } + if (ssm_delete_file(send_password_file_name, SSM_FLAG_SECRET_OPERATION, NULL) < 0) { + EM_DEBUG_EXCEPTION(" ssm_delete_file failed -send password : file[%s]", send_password_file_name); + error = EM_STORAGE_ERROR_SYSTEM_FAILURE; + goto FINISH_OFF; + } + ret = true; + +FINISH_OFF: + + if (hStmt != NULL) { + rc = sqlite3_finalize(hStmt); + if (rc != SQLITE_OK) { + EM_DEBUG_LOG(" sqlite3_finalize failed - %d", rc); + error = EM_STORAGE_ERROR_DB_FAILURE; + } + } + + EM_STORAGE_FINISH_WRITE_TRANSACTION(transaction, ret, error); + _DISCONNECT_DB; + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + + +EXPORT_API int em_storage_free_account(emf_mail_account_tbl_t** account_list, int count, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_list[%p], count[%d], err_code[%p]", account_list, count, err_code); + + int ret = false; + int error = EM_STORAGE_ERROR_NONE; + + if (count > 0) { + if (!account_list || !*account_list) { + EM_DEBUG_EXCEPTION("account_list[%p], count[%d]", account_list, count); + error = EM_STORAGE_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + emf_mail_account_tbl_t* p = *account_list; + int i = 0; + + for (; i < count; i++) { + EM_SAFE_FREE(p[i].account_name); + EM_SAFE_FREE(p[i].receiving_server_addr); + EM_SAFE_FREE(p[i].email_addr); + EM_SAFE_FREE(p[i].user_name); + EM_SAFE_FREE(p[i].password); + EM_SAFE_FREE(p[i].sending_server_addr); + EM_SAFE_FREE(p[i].sending_user); + EM_SAFE_FREE(p[i].sending_password); + EM_SAFE_FREE(p[i].display_name); + EM_SAFE_FREE(p[i].reply_to_addr); + EM_SAFE_FREE(p[i].return_addr); + EM_SAFE_FREE(p[i].logo_icon_path); + EM_SAFE_FREE(p[i].options.display_name_from); + EM_SAFE_FREE(p[i].options.signature); + } + + EM_SAFE_FREE(p); + *account_list = NULL; + } + + ret = true; + +FINISH_OFF: + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API int em_storage_get_mailbox_count(int account_id, int local_yn, int *count, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id[%d], local_yn[%d], count[%p], transaction[%d], err_code[%p]", account_id, local_yn, count, transaction, err_code); + + if ((account_id < FIRST_ACCOUNT_ID) || (count == NULL)) { + EM_DEBUG_EXCEPTION(" account_list[%d], local_yn[%d], count[%p]", account_id, local_yn, count); + + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + int rc = -1, ret = false; + int error = EM_STORAGE_ERROR_NONE; + char sql_query_string[QUERY_SIZE] = {0, }; + + sqlite3 *local_db_handle = em_storage_get_db_connection(); + EM_STORAGE_START_READ_TRANSACTION(transaction); + + SNPRINTF(sql_query_string, sizeof(sql_query_string), "SELECT COUNT(*) FROM mail_box_tbl WHERE account_id = %d AND local_yn = %d", account_id, local_yn); + + char **result; + /* rc = sqlite3_get_table(local_db_handle, sql_query_string, &result, NULL, NULL, NULL); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_get_table(local_db_handle, sql_query_string, &result, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;sqlite3_free_table(result);goto FINISH_OFF; }, + ("SQL(%s) sqlite3_get_table fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + *count = atoi(result[1]); + sqlite3_free_table(result); + + + ret = true; + +FINISH_OFF: + + EM_STORAGE_FINISH_READ_TRANSACTION(transaction); + _DISCONNECT_DB; + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API int em_storage_get_mailbox(int account_id, int local_yn, email_mailbox_sort_type_t sort_type, int *select_num, emf_mailbox_tbl_t** mailbox_list, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id[%d], local_yn[%d], select_num[%p], mailbox_list[%p], transaction[%d], err_code[%p]", account_id, local_yn, select_num, mailbox_list, transaction, err_code); + + if (!select_num || !mailbox_list) { + EM_DEBUG_EXCEPTION("Invalid parameters"); + + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + + return false; + } + + int i = 0, rc, count = 0, ret = false, col_index; + int error = EM_STORAGE_ERROR_NONE; + emf_mailbox_tbl_t* p_data_tbl = NULL; + char **result; + DB_STMT hStmt = NULL; + char sql_query_string[QUERY_SIZE] = {0, }; + char *fields = "mailbox_id, account_id, local_yn, mailbox_name, mailbox_type, alias, sync_with_server_yn, modifiable_yn, total_mail_count_on_server, has_archived_mails, mail_slot_size "; + + sqlite3 *local_db_handle = em_storage_get_db_connection(); + EM_STORAGE_START_READ_TRANSACTION(transaction); + + if (account_id == ALL_ACCOUNT) { + SNPRINTF(sql_query_string, sizeof(sql_query_string), "SELECT %s FROM mail_box_tbl ", fields); + if (local_yn == EMF_MAILBOX_FROM_SERVER || local_yn == EMF_MAILBOX_FROM_LOCAL) + SNPRINTF(sql_query_string + strlen(sql_query_string), sizeof(sql_query_string)-(strlen(sql_query_string)+1), " WHERE local_yn = %d ", local_yn); + } + else { + SNPRINTF(sql_query_string, sizeof(sql_query_string), "SELECT %s FROM mail_box_tbl WHERE account_id = %d ", fields, account_id); + if (local_yn == EMF_MAILBOX_FROM_SERVER || local_yn == EMF_MAILBOX_FROM_LOCAL) + SNPRINTF(sql_query_string + strlen(sql_query_string), sizeof(sql_query_string)-(strlen(sql_query_string)+1), " AND local_yn = %d ", local_yn); + } + + switch (sort_type) { + case EMAIL_MAILBOX_SORT_BY_NAME_ASC : + SNPRINTF(sql_query_string + strlen(sql_query_string), sizeof(sql_query_string)-(strlen(sql_query_string)+1), " ORDER BY mailbox_name ASC"); + break; + + case EMAIL_MAILBOX_SORT_BY_NAME_DSC : + SNPRINTF(sql_query_string + strlen(sql_query_string), sizeof(sql_query_string)-(strlen(sql_query_string)+1), " ORDER BY mailbox_name DESC"); + break; + + case EMAIL_MAILBOX_SORT_BY_TYPE_ASC : + SNPRINTF(sql_query_string + strlen(sql_query_string), sizeof(sql_query_string)-(strlen(sql_query_string)+1), " ORDER BY mailbox_type ASC"); + break; + + case EMAIL_MAILBOX_SORT_BY_TYPE_DSC : + SNPRINTF(sql_query_string + strlen(sql_query_string), sizeof(sql_query_string)-(strlen(sql_query_string)+1), " ORDER BY mailbox_type DEC"); + break; + } + + EM_DEBUG_LOG("em_storage_get_mailbox : query[%s]", sql_query_string); + + + /* rc = sqlite3_get_table(local_db_handle, sql_query_string, &result, &count, NULL, NULL); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_get_table(local_db_handle, sql_query_string, &result, &count, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;sqlite3_free_table(result);goto FINISH_OFF; }, + ("SQL(%s) sqlite3_get_table fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))) + + if (!(p_data_tbl = (emf_mailbox_tbl_t*)malloc(sizeof(emf_mailbox_tbl_t) * count))) { + EM_DEBUG_EXCEPTION(" malloc failed..."); + + error = EM_STORAGE_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + memset(p_data_tbl, 0x00, sizeof(emf_mailbox_tbl_t)*count); + + col_index = 11; + + for (i = 0; i < count; i++) { + _getTableFieldDataInt(result, &(p_data_tbl[i].mailbox_id), col_index++); + _getTableFieldDataInt(result, &(p_data_tbl[i].account_id), col_index++); + _getTableFieldDataInt(result, &(p_data_tbl[i].local_yn), col_index++); + _getTableFieldDataString(result, &(p_data_tbl[i].mailbox_name), 0, col_index++); + _getTableFieldDataInt(result, (int *)&(p_data_tbl[i].mailbox_type), col_index++); + _getTableFieldDataString(result, &(p_data_tbl[i].alias), 0, col_index++); + _getTableFieldDataInt(result, &(p_data_tbl[i].sync_with_server_yn), col_index++); + _getTableFieldDataInt(result, &(p_data_tbl[i].modifiable_yn), col_index++); + _getTableFieldDataInt(result, &(p_data_tbl[i].total_mail_count_on_server), col_index++); + _getTableFieldDataInt(result, &(p_data_tbl[i].has_archived_mails), col_index++); + _getTableFieldDataInt(result, &(p_data_tbl[i].mail_slot_size), col_index++); + } + + ret = true; + +FINISH_OFF: + if (result) + sqlite3_free_table(result); + + if (ret == true) { + *mailbox_list = p_data_tbl; + *select_num = count; + EM_DEBUG_LOG("Mailbox Count [ %d]", count); + } + else if (p_data_tbl != NULL) + em_storage_free_mailbox(&p_data_tbl, count, NULL); + + if (hStmt != NULL) { + rc = sqlite3_finalize(hStmt); + if (rc != SQLITE_OK) { + EM_DEBUG_LOG(" sqlite3_finalize failed - %d", rc); + + error = EM_STORAGE_ERROR_DB_FAILURE; + } + } + + EM_STORAGE_FINISH_READ_TRANSACTION(transaction); + _DISCONNECT_DB; + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + + +EXPORT_API int em_storage_get_mailbox_ex(int account_id, int local_yn, int with_count, int *select_num, emf_mailbox_tbl_t** mailbox_list, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id[%d], local_yn[%d], select_num[%p], mailbox_list[%p], transaction[%d], err_code[%p]", account_id, local_yn, select_num, mailbox_list, transaction, err_code); + + if (!select_num || !mailbox_list) { + EM_DEBUG_EXCEPTION("Invalid parameters"); + + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + + return false; + } + + int i = 0; + int rc; + int count = 0; + int ret = false; + int col_index; + int error = EM_STORAGE_ERROR_NONE; + emf_mailbox_tbl_t* p_data_tbl = NULL; + char **result; + DB_STMT hStmt = NULL; + char sql_query_string[QUERY_SIZE] = {0, }; + char *fields = "MBT.mailbox_id, MBT.account_id, local_yn, MBT.mailbox_name, MBT.mailbox_type, alias, sync_with_server_yn, modifiable_yn, total_mail_count_on_server, has_archived_mails, mail_slot_size "; + int add = 0; + int read_count = 0; + int total_count = 0; + + sqlite3 *local_db_handle = em_storage_get_db_connection(); + EM_STORAGE_START_READ_TRANSACTION(transaction); + + add = 0; + if (with_count == 0) { /* without count */ + col_index = 11; + SNPRINTF(sql_query_string, sizeof(sql_query_string), "SELECT %s FROM mail_box_tbl AS MBT", fields); + if (account_id > ALL_ACCOUNT) { + add = 1; + SNPRINTF(sql_query_string + strlen(sql_query_string), sizeof(sql_query_string)-(strlen(sql_query_string)+1), " WHERE account_id = %d ", account_id); + } + } + else { /* with read count and total count */ + col_index = 13; + if (account_id > ALL_ACCOUNT) { + add = 1; + SNPRINTF(sql_query_string, sizeof(sql_query_string), "SELECT %s, total, read FROM mail_box_tbl AS MBT LEFT OUTER JOIN (SELECT mailbox_name, count(mail_id) AS total, SUM(flags_seen_field) AS read FROM mail_tbl WHERE account_id = %d GROUP BY mailbox_name) AS MT ON MBT.mailbox_name = MT.mailbox_name WHERE account_id = %d ", fields, account_id, account_id); + } + else { + SNPRINTF(sql_query_string, sizeof(sql_query_string), "SELECT %s, total, read FROM mail_box_tbl AS MBT LEFT OUTER JOIN (SELECT mailbox_name, count(mail_id) AS total, SUM(flags_seen_field) AS read FROM mail_tbl GROUP BY mailbox_name) AS MT ON MBT.mailbox_name = MT.mailbox_name ", fields); + } + } + + if (local_yn == EMF_MAILBOX_FROM_SERVER || local_yn == EMF_MAILBOX_FROM_LOCAL) { + SNPRINTF(sql_query_string + strlen(sql_query_string), sizeof(sql_query_string)-(strlen(sql_query_string)+1), " %s local_yn = %d ", (add ? "WHERE" : "AND"), local_yn); + } + + SNPRINTF(sql_query_string + strlen(sql_query_string), sizeof(sql_query_string)-(strlen(sql_query_string)+1), " ORDER BY MBT.mailbox_name "); + EM_DEBUG_LOG("query[%s]", sql_query_string); + + + /* rc = sqlite3_get_table(local_db_handle, sql_query_string, &result, &count, NULL, NULL); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_get_table(local_db_handle, sql_query_string, &result, &count, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;sqlite3_free_table(result);goto FINISH_OFF; }, + ("SQL(%s) sqlite3_get_table fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))) + + EM_DEBUG_LOG("result count [%d]", count); + + if (!(p_data_tbl = (emf_mailbox_tbl_t*)malloc(sizeof(emf_mailbox_tbl_t) * count))) { + EM_DEBUG_EXCEPTION("malloc failed..."); + error = EM_STORAGE_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + memset(p_data_tbl, 0x00, sizeof(emf_mailbox_tbl_t)*count); + + for (i = 0; i < count; i++) { + _getTableFieldDataInt(result, &(p_data_tbl[i].mailbox_id), col_index++); + _getTableFieldDataInt(result, &(p_data_tbl[i].account_id), col_index++); + _getTableFieldDataInt(result, &(p_data_tbl[i].local_yn), col_index++); + _getTableFieldDataString(result, &(p_data_tbl[i].mailbox_name), 0, col_index++); + _getTableFieldDataInt(result, (int *)&(p_data_tbl[i].mailbox_type), col_index++); + _getTableFieldDataString(result, &(p_data_tbl[i].alias), 0, col_index++); + _getTableFieldDataInt(result, &(p_data_tbl[i].sync_with_server_yn), col_index++); + _getTableFieldDataInt(result, &(p_data_tbl[i].modifiable_yn), col_index++); + _getTableFieldDataInt(result, &(p_data_tbl[i].total_mail_count_on_server), col_index++); + _getTableFieldDataInt(result, &(p_data_tbl[i].has_archived_mails), col_index++); + _getTableFieldDataInt(result, &(p_data_tbl[i].mail_slot_size), col_index++); + + if (with_count == 1) { + _getTableFieldDataInt(result, &(total_count), col_index++); + p_data_tbl[i].total_mail_count_on_local = total_count; + _getTableFieldDataInt(result, &(read_count), col_index++); + p_data_tbl[i].unread_count = total_count - read_count; /* return unread count, NOT */ + } + /* + EM_DEBUG_LOG("[%d]", i); + EM_DEBUG_LOG("p_data_tbl[%d].mailbox_id[%d]", i, p_data_tbl[i].mailbox_id); + EM_DEBUG_LOG("p_data_tbl[%d].account_id[%d]", i, p_data_tbl[i].account_id); + EM_DEBUG_LOG("p_data_tbl[%d].local_yn[%d]", i, p_data_tbl[i].local_yn); + EM_DEBUG_LOG("p_data_tbl[%d].mailbox_name[%s]", i, p_data_tbl[i].mailbox_name); + EM_DEBUG_LOG("p_data_tbl[%d].mailbox_type[%d]", i, p_data_tbl[i].mailbox_type); + EM_DEBUG_LOG("p_data_tbl[%d].alias[%s]", i, p_data_tbl[i].alias); + EM_DEBUG_LOG("p_data_tbl[%d].sync_with_server_yn[%d]", i, p_data_tbl[i].sync_with_server_yn); + EM_DEBUG_LOG("p_data_tbl[%d].modifiable_yn[%d]", i, p_data_tbl[i].modifiable_yn); + EM_DEBUG_LOG("p_data_tbl[%d].has_archived_mails[%d]", i, p_data_tbl[i].has_archived_mails); + EM_DEBUG_LOG("p_data_tbl[%d].mail_slot_size[%d]", i, p_data_tbl[i].mail_slot_size); + EM_DEBUG_LOG("p_data_tbl[%d].unread_count[%d]", i, p_data_tbl[i].unread_count); + EM_DEBUG_LOG("p_data_tbl[%d].total_mail_count_on_local[%d]", i, p_data_tbl[i].total_mail_count_on_local); + EM_DEBUG_LOG("p_data_tbl[%d].total_mail_count_on_server[%d]", i, p_data_tbl[i].total_mail_count_on_server); + */ + } + + ret = true; + +FINISH_OFF: + if (result) + sqlite3_free_table(result); + + if (ret == true) { + *mailbox_list = p_data_tbl; + *select_num = count; + EM_DEBUG_LOG("Mailbox Count [ %d]", count); + } + else if (p_data_tbl != NULL) + em_storage_free_mailbox(&p_data_tbl, count, NULL); + + if (hStmt != NULL) { + rc = sqlite3_finalize(hStmt); + if (rc != SQLITE_OK) { + EM_DEBUG_LOG(" sqlite3_finalize failed - %d", rc); + + error = EM_STORAGE_ERROR_DB_FAILURE; + } + } + + EM_STORAGE_FINISH_READ_TRANSACTION(transaction); + _DISCONNECT_DB; + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API int em_storage_get_child_mailbox_list(int account_id, char *parent_mailbox_name, int *select_num, emf_mailbox_tbl_t** mailbox_list, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id[%d], parent_mailbox_name[%p], select_num[%p], mailbox_list[%p], transaction[%d], err_code[%p]", account_id, parent_mailbox_name, select_num, mailbox_list, transaction, err_code); + if (account_id < FIRST_ACCOUNT_ID || !select_num || !mailbox_list) { + EM_DEBUG_EXCEPTION("account_id[%d], parent_mailbox_name[%p], select_num[%p], mailbox_list[%p]", account_id, parent_mailbox_name, select_num, mailbox_list); + + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + int i = 0, rc, count = 0, ret = false, col_index; + int error = EM_STORAGE_ERROR_NONE; + emf_mailbox_tbl_t* p_data_tbl = NULL; + char **result; + char sql_query_string[QUERY_SIZE] = {0, }; + char *fields = "mailbox_id, account_id, local_yn, mailbox_name, mailbox_type, alias, sync_with_server_yn, modifiable_yn, total_mail_count_on_server, has_archived_mails, mail_slot_size "; + + sqlite3 *local_db_handle = em_storage_get_db_connection(); + EM_STORAGE_START_READ_TRANSACTION(transaction); + + if (parent_mailbox_name) + SNPRINTF(sql_query_string, sizeof(sql_query_string), "SELECT %s FROM mail_box_tbl WHERE account_id = %d AND UPPER(mailbox_name) LIKE UPPER('%s/%%') ORDER BY mailbox_name", fields, account_id, parent_mailbox_name); + else + SNPRINTF(sql_query_string, sizeof(sql_query_string), "SELECT %s FROM mail_box_tbl WHERE account_id = %d AND (mailbox_name NOT LIKE '%%/%%') ORDER BY mailbox_name", fields, account_id); + + EM_DEBUG_LOG("query : %s", sql_query_string); + + /* rc = sqlite3_get_table(local_db_handle, sql_query_string, &result, &count, NULL, NULL); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_get_table(local_db_handle, sql_query_string, &result, &count, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;sqlite3_free_table(result);goto FINISH_OFF; }, + ("SQL(%s) sqlite3_get_table fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + + if (!(p_data_tbl = (emf_mailbox_tbl_t*)malloc(sizeof(emf_mailbox_tbl_t) * count))) { + EM_DEBUG_EXCEPTION(" malloc failed..."); + error = EM_STORAGE_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + memset(p_data_tbl, 0x00, sizeof(emf_mailbox_tbl_t)*count); + col_index = 11; + + for (i = 0; i < count; i++) { + _getTableFieldDataInt(result, &(p_data_tbl[i].mailbox_id), col_index++); + _getTableFieldDataInt(result, &(p_data_tbl[i].account_id), col_index++); + _getTableFieldDataInt(result, &(p_data_tbl[i].local_yn), col_index++); + _getTableFieldDataString(result, &(p_data_tbl[i].mailbox_name), 0, col_index++); + _getTableFieldDataInt(result, (int *)&(p_data_tbl[i].mailbox_type), col_index++); + _getTableFieldDataString(result, &(p_data_tbl[i].alias), 0, col_index++); + _getTableFieldDataInt(result, &(p_data_tbl[i].sync_with_server_yn), col_index++); + _getTableFieldDataInt(result, &(p_data_tbl[i].modifiable_yn), col_index++); + _getTableFieldDataInt(result, &(p_data_tbl[i].total_mail_count_on_server), col_index++); + _getTableFieldDataInt(result, &(p_data_tbl[i].has_archived_mails), col_index++); + _getTableFieldDataInt(result, &(p_data_tbl[i].mail_slot_size), col_index++); + } + + if (result) + sqlite3_free_table(result); + + ret = true; + +FINISH_OFF: + if (ret == true) { + *mailbox_list = p_data_tbl; + *select_num = count; + EM_DEBUG_LOG(" Mailbox Count [ %d] ", count); + } + else if (p_data_tbl != NULL) + em_storage_free_mailbox(&p_data_tbl, count, NULL); + + EM_STORAGE_FINISH_READ_TRANSACTION(transaction); + _DISCONNECT_DB; + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API int em_storage_get_mailbox_by_modifiable_yn(int account_id, int local_yn, int *select_num, emf_mailbox_tbl_t** mailbox_list, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id[%d], local_yn[%d], select_num[%p], mailbox_list[%p], transaction[%d], err_code[%p]", account_id, local_yn, select_num, mailbox_list, transaction, err_code); + if (account_id < FIRST_ACCOUNT_ID || !select_num || !mailbox_list) { + EM_DEBUG_EXCEPTION("\account_id[%d], local_yn[%d], select_num[%p], mailbox_list[%p]", account_id, local_yn, select_num, mailbox_list); + + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + int i = 0, rc, count = 0, ret = false; + int error = EM_STORAGE_ERROR_NONE; + emf_mailbox_tbl_t* p_data_tbl = NULL; + DB_STMT hStmt = NULL; + char sql_query_string[QUERY_SIZE] = {0, }; + char *fields = "mailbox_id, account_id, local_yn, mailbox_name, mailbox_type, alias, sync_with_server_yn, modifiable_yn, total_mail_count_on_server, has_archived_mails, mail_slot_size "; + + sqlite3 *local_db_handle = em_storage_get_db_connection(); + EM_STORAGE_START_READ_TRANSACTION(transaction); + + SNPRINTF(sql_query_string, sizeof(sql_query_string), "SELECT %s FROM mail_box_tbl WHERE account_id = %d AND modifiable_yn = 0 ORDER BY mailbox_name", fields, account_id); + EM_DEBUG_LOG("sql[%s]", sql_query_string); + + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_prepare_v2(local_db_handle, sql_query_string, strlen(sql_query_string), &hStmt, NULL), rc); + EM_DEBUG_DB_EXEC((SQLITE_OK != rc), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) sqlite3_prepare fail:(%d) %s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + /* rc = sqlite3_step(hStmt); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_step(hStmt), rc); + EM_DEBUG_DB_EXEC((rc != SQLITE_ROW && rc != SQLITE_DONE), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("sqlite3_step fail:%d", rc)); + + char **result; + /* rc = sqlite3_get_table(local_db_handle, sql_query_string, &result, &count, NULL, NULL); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_get_table(local_db_handle, sql_query_string, &result, &count, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;sqlite3_free_table(result);goto FINISH_OFF; }, + ("SQL(%s) sqlite3_get_table fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + sqlite3_free_table(result); + if (count == 0) { + EM_DEBUG_EXCEPTION(" no mailbox_name found..."); + + ret = true; + goto FINISH_OFF; + } + + if (!(p_data_tbl = (emf_mailbox_tbl_t*)malloc(sizeof(emf_mailbox_tbl_t) * count))) { + EM_DEBUG_EXCEPTION(" malloc failed..."); + + error = EM_STORAGE_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + memset(p_data_tbl, 0x00, sizeof(emf_mailbox_tbl_t)*count); + + int col_index = 0; + for (i = 0; i < count; i++) { + col_index = 0; + _getStmtFieldDataInt(hStmt, &(p_data_tbl[i].mailbox_id), col_index++); + _getStmtFieldDataInt(hStmt, &(p_data_tbl[i].account_id), col_index++); + _getStmtFieldDataInt(hStmt, &(p_data_tbl[i].local_yn), col_index++); + _getStmtFieldDataString(hStmt, &(p_data_tbl[i].mailbox_name), 0, col_index++); + _getStmtFieldDataInt(hStmt, (int *)&(p_data_tbl[i].mailbox_type), col_index++); + _getStmtFieldDataString(hStmt, &(p_data_tbl[i].alias), 0, col_index++); + _getStmtFieldDataInt(hStmt, &(p_data_tbl[i].sync_with_server_yn), col_index++); + _getStmtFieldDataInt(hStmt, &(p_data_tbl[i].modifiable_yn), col_index++); + _getStmtFieldDataInt(hStmt, &(p_data_tbl[i].total_mail_count_on_server), col_index++); + _getStmtFieldDataInt(hStmt, &(p_data_tbl[i].has_archived_mails), col_index++); + _getStmtFieldDataInt(hStmt, &(p_data_tbl[i].mail_slot_size), col_index++); + + /* rc = sqlite3_step(hStmt); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_step(hStmt), rc); + EM_DEBUG_DB_EXEC((rc != SQLITE_ROW && rc != SQLITE_DONE), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("sqlite3_step fail:%d", rc)); + } + + ret = true; + +FINISH_OFF: + if (ret == true) { + *mailbox_list = p_data_tbl; + *select_num = count; + EM_DEBUG_LOG("Mailbox Count[%d]", count); + } + else if (p_data_tbl != NULL) + em_storage_free_mailbox(&p_data_tbl, count, NULL); + + if (hStmt != NULL) { + EM_DEBUG_LOG("Before sqlite3_finalize hStmt = %p", hStmt); + + rc = sqlite3_finalize(hStmt); + if (rc != SQLITE_OK) { + EM_DEBUG_EXCEPTION("sqlite3_finalize failed - %d", rc); + error = EM_STORAGE_ERROR_DB_FAILURE; + } + } + EM_STORAGE_FINISH_READ_TRANSACTION(transaction); + _DISCONNECT_DB; + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + + + +EXPORT_API int em_storage_get_mailbox_by_name(int account_id, int local_yn, char *mailbox_name, emf_mailbox_tbl_t** result_mailbox, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id[%d], local_yn[%d], mailbox_name[%s], result_mailbox[%p], transaction[%d], err_code[%p]", account_id, local_yn, mailbox_name, result_mailbox, transaction, err_code); + EM_PROFILE_BEGIN(profile_em_storage_get_mailbox_by_name); + + if (account_id < FIRST_ACCOUNT_ID || !mailbox_name || !result_mailbox) { + EM_DEBUG_EXCEPTION(" account_id[%d], local_yn[%d], mailbox_name[%s], result_mailbox[%p]", account_id, local_yn, mailbox_name, result_mailbox); + + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + int rc, ret = false; + int error = EM_STORAGE_ERROR_NONE; + emf_mailbox_tbl_t* p_data_tbl = NULL; + + DB_STMT hStmt = NULL; + char sql_query_string[QUERY_SIZE] = {0, }; + char *fields = "mailbox_id, account_id, local_yn, mailbox_name, mailbox_type, alias, sync_with_server_yn, modifiable_yn, total_mail_count_on_server, has_archived_mails, mail_slot_size "; + + sqlite3 *local_db_handle = em_storage_get_db_connection(); + EM_STORAGE_START_READ_TRANSACTION(transaction); + + if (local_yn == -1) + SNPRINTF(sql_query_string, sizeof(sql_query_string), "SELECT %s FROM mail_box_tbl WHERE account_id = %d AND mailbox_name = '%s'", fields, account_id, mailbox_name); + else + SNPRINTF(sql_query_string, sizeof(sql_query_string), "SELECT %s FROM mail_box_tbl WHERE account_id = %d AND local_yn = %d AND mailbox_name = '%s'", fields, account_id, local_yn, mailbox_name); + + EM_DEBUG_LOG("query = [%s]", sql_query_string); + + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_prepare_v2(local_db_handle, sql_query_string, strlen(sql_query_string), &hStmt, NULL), rc); + EM_DEBUG_DB_EXEC((SQLITE_OK != rc), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) sqlite3_prepare fail:(%d) %s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + /* rc = sqlite3_step(hStmt); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_step(hStmt), rc); + EM_DEBUG_DB_EXEC((rc != SQLITE_ROW && rc != SQLITE_DONE), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("sqlite3_step fail:%d", rc)); + + if (rc == SQLITE_DONE) { + EM_DEBUG_EXCEPTION("no matched mailbox_name found..."); + error = EM_STORAGE_ERROR_MAILBOX_NOT_FOUND; + goto FINISH_OFF; + } + + if (!(p_data_tbl = (emf_mailbox_tbl_t*)malloc(sizeof(emf_mailbox_tbl_t)))) { + EM_DEBUG_EXCEPTION("malloc failed..."); + error = EM_STORAGE_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + memset(p_data_tbl, 0x00, sizeof(emf_mailbox_tbl_t)); + int col_index = 0; + _getStmtFieldDataInt(hStmt, &(p_data_tbl->mailbox_id), col_index++); + _getStmtFieldDataInt(hStmt, &(p_data_tbl->account_id), col_index++); + _getStmtFieldDataInt(hStmt, &(p_data_tbl->local_yn), col_index++); + _getStmtFieldDataString(hStmt, &(p_data_tbl->mailbox_name), 0, col_index++); + _getStmtFieldDataInt(hStmt, (int *)&(p_data_tbl->mailbox_type), col_index++); + _getStmtFieldDataString(hStmt, &(p_data_tbl->alias), 0, col_index++); + _getStmtFieldDataInt(hStmt, &(p_data_tbl->sync_with_server_yn), col_index++); + _getStmtFieldDataInt(hStmt, &(p_data_tbl->modifiable_yn), col_index++); + _getStmtFieldDataInt(hStmt, &(p_data_tbl->total_mail_count_on_server), col_index++); + _getStmtFieldDataInt(hStmt, &(p_data_tbl->has_archived_mails), col_index++); + _getStmtFieldDataInt(hStmt, &(p_data_tbl->mail_slot_size), col_index++); + + ret = true; + +FINISH_OFF: + if (ret == true) + *result_mailbox = p_data_tbl; + else if (p_data_tbl != NULL) + em_storage_free_mailbox(&p_data_tbl, 1, NULL); + + if (hStmt != NULL) { + rc = sqlite3_finalize(hStmt); + if (rc != SQLITE_OK) { + EM_DEBUG_EXCEPTION(" sqlite3_finalize failed - %d", rc); + error = EM_STORAGE_ERROR_DB_FAILURE; + } + } + + EM_STORAGE_FINISH_READ_TRANSACTION(transaction); + _DISCONNECT_DB; + + if (err_code != NULL) + *err_code = error; + + EM_PROFILE_END(profile_em_storage_get_mailbox_by_name); + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + + +EXPORT_API int em_storage_get_mailbox_by_mailbox_type(int account_id, emf_mailbox_type_e mailbox_type, emf_mailbox_tbl_t** mailbox_name, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id[%d], mailbox_type[%d], mailbox_name[%p], transaction[%d], err_code[%p]", account_id, mailbox_type, mailbox_name, transaction, err_code); + + if (account_id < FIRST_ACCOUNT_ID || (mailbox_type < EMF_MAILBOX_TYPE_INBOX || mailbox_type > EMF_MAILBOX_TYPE_ALL_EMAILS) || !mailbox_name) { + + EM_DEBUG_EXCEPTION(" account_id[%d], mailbox_type[%d], mailbox_name[%p]", account_id, mailbox_type, mailbox_name); + + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + int rc, ret = false; + int error = EM_STORAGE_ERROR_NONE; + emf_mailbox_tbl_t *p_data_tbl = NULL; + emf_mail_account_tbl_t *account = NULL; + DB_STMT hStmt = NULL; + char sql_query_string[QUERY_SIZE] = {0,}; + char *fields = "mailbox_id, account_id, local_yn, mailbox_name, mailbox_type, alias, sync_with_server_yn, modifiable_yn, total_mail_count_on_server, has_archived_mails, mail_slot_size "; + + sqlite3 *local_db_handle = em_storage_get_db_connection(); + EM_STORAGE_START_READ_TRANSACTION(transaction); + + /* validate account */ + /* Check whether the account exists. */ + if (!em_storage_get_account_by_id(account_id, EMF_ACC_GET_OPT_ACCOUNT_NAME, &account, true, &error) || !account) { + EM_DEBUG_EXCEPTION(" em_storage_get_account_by_id failed - %d", error); + goto FINISH_OFF; + } + + if (account) + em_storage_free_account(&account, 1, NULL); + + SNPRINTF(sql_query_string, sizeof(sql_query_string), "SELECT %s FROM mail_box_tbl WHERE account_id = %d AND mailbox_type = %d ", fields, account_id, mailbox_type); + + EM_DEBUG_LOG("query = [%s]", sql_query_string); + + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_prepare_v2(local_db_handle, sql_query_string, strlen(sql_query_string), &hStmt, NULL), rc); + EM_DEBUG_DB_EXEC((SQLITE_OK != rc), {error = EM_STORAGE_ERROR_DB_FAILURE; goto FINISH_OFF; }, ("SQL(%s) sqlite3_prepare fail:(%d) %s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + /* rc = sqlite3_step(hStmt); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_step(hStmt), rc); + EM_DEBUG_DB_EXEC((rc != SQLITE_ROW && rc != SQLITE_DONE), {error = EM_STORAGE_ERROR_DB_FAILURE; goto FINISH_OFF; }, ("sqlite3_step fail:%d", rc)); + + if (rc == SQLITE_DONE) { + EM_DEBUG_EXCEPTION(" no matched mailbox_name found..."); + error = EM_STORAGE_ERROR_MAILBOX_NOT_FOUND; + goto FINISH_OFF; + } + + + if (!(p_data_tbl = (emf_mailbox_tbl_t*)malloc(sizeof(emf_mailbox_tbl_t)))) { + EM_DEBUG_EXCEPTION(" malloc failed..."); + error = EM_STORAGE_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + memset(p_data_tbl, 0x00, sizeof(emf_mailbox_tbl_t)); + + int col_index = 0; + + _getStmtFieldDataInt(hStmt, &(p_data_tbl->mailbox_id), col_index++); + _getStmtFieldDataInt(hStmt, &(p_data_tbl->account_id), col_index++); + _getStmtFieldDataInt(hStmt, &(p_data_tbl->local_yn), col_index++); + _getStmtFieldDataString(hStmt, &(p_data_tbl->mailbox_name), 0, col_index++); + _getStmtFieldDataInt(hStmt, (int *)&(p_data_tbl->mailbox_type), col_index++); + _getStmtFieldDataString(hStmt, &(p_data_tbl->alias), 0, col_index++); + _getStmtFieldDataInt(hStmt, &(p_data_tbl->sync_with_server_yn), col_index++); + _getStmtFieldDataInt(hStmt, &(p_data_tbl->modifiable_yn), col_index++); + _getStmtFieldDataInt(hStmt, &(p_data_tbl->total_mail_count_on_server), col_index++); + _getStmtFieldDataInt(hStmt, &(p_data_tbl->has_archived_mails), col_index++); + _getStmtFieldDataInt(hStmt, &(p_data_tbl->mail_slot_size), col_index++); + + ret = true; + +FINISH_OFF: + if (ret == true) + *mailbox_name = p_data_tbl; + else if (p_data_tbl != NULL) + em_storage_free_mailbox(&p_data_tbl, 1, NULL); + + if (hStmt != NULL) { + rc = sqlite3_finalize(hStmt); + if (rc != SQLITE_OK) { + EM_DEBUG_EXCEPTION("sqlite3_finalize failed - %d", rc); + error = EM_STORAGE_ERROR_DB_FAILURE; + } + } + + EM_STORAGE_FINISH_READ_TRANSACTION(transaction); + _DISCONNECT_DB; + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API int em_storage_get_mailboxname_by_mailbox_type(int account_id, emf_mailbox_type_e mailbox_type, char **mailbox_name, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id[%d], mailbox_type[%d], mailbox_name[%p], transaction[%d], err_code[%p]", account_id, mailbox_type, mailbox_name, transaction, err_code); + if (account_id < FIRST_ACCOUNT_ID || (mailbox_type < EMF_MAILBOX_TYPE_INBOX || mailbox_type > EMF_MAILBOX_TYPE_ALL_EMAILS) || !mailbox_name) { + EM_DEBUG_EXCEPTION("account_id[%d], mailbox_type[%d], mailbox_name[%p]", account_id, mailbox_type, mailbox_name); + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + int rc, ret = false; + int error = EM_STORAGE_ERROR_NONE; + char *p_mailbox = NULL; + emf_mail_account_tbl_t* account = NULL; + DB_STMT hStmt = NULL; + char sql_query_string[QUERY_SIZE] = {0, }; + + sqlite3 *local_db_handle = em_storage_get_db_connection(); + EM_STORAGE_START_READ_TRANSACTION(transaction); + + /* Check whether the account exists. */ + if (!em_storage_get_account_by_id(account_id, EMF_ACC_GET_OPT_ACCOUNT_NAME, &account, true, &error) || !account) { + EM_DEBUG_EXCEPTION("em_storage_get_account_by_id failed - %d", error); + goto FINISH_OFF; + } + + if (account ) + em_storage_free_account(&account, 1, NULL); + + SNPRINTF(sql_query_string, sizeof(sql_query_string), "SELECT mailbox_name FROM mail_box_tbl WHERE account_id = %d AND mailbox_type = %d ", account_id, mailbox_type); + + EM_DEBUG_LOG("query = [%s]", sql_query_string); + + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_prepare_v2(local_db_handle, sql_query_string, strlen(sql_query_string), &hStmt, NULL), rc); + + EM_DEBUG_DB_EXEC((SQLITE_OK != rc), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) sqlite3_prepare fail:(%d) %s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + /* rc = sqlite3_step(hStmt); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_step(hStmt), rc); + EM_DEBUG_DB_EXEC((rc != SQLITE_ROW && rc != SQLITE_DONE), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("sqlite3_step fail:%d", rc)); + + if (rc == SQLITE_DONE) { + EM_DEBUG_EXCEPTION("no matched mailbox_name found..."); + error = EM_STORAGE_ERROR_MAILBOX_NOT_FOUND; + goto FINISH_OFF; + } + + _getStmtFieldDataString(hStmt, &(p_mailbox), 0, 0); + + ret = true; + +FINISH_OFF: + if (ret == true) + *mailbox_name = p_mailbox; + else + EM_SAFE_FREE(p_mailbox); + + if (hStmt != NULL) { + rc = sqlite3_finalize(hStmt); + if (rc != SQLITE_OK) { + EM_DEBUG_EXCEPTION(" sqlite3_finalize failed - %d", rc); + error = EM_STORAGE_ERROR_DB_FAILURE; + } + } + + EM_STORAGE_FINISH_READ_TRANSACTION(transaction); + _DISCONNECT_DB; + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API int em_storage_update_mailbox_modifiable_yn(int account_id, int local_yn, char *mailbox_name, int modifiable_yn, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id [%d], local_yn [%d], mailbox_name [%p], modifiable_yn [%d], transaction [%d], err_code [%p]", account_id, local_yn, mailbox_name, modifiable_yn, transaction, err_code); + int rc, ret = false; + int error = EM_STORAGE_ERROR_NONE; + char sql_query_string[QUERY_SIZE] = {0, }; + + sqlite3 *local_db_handle = em_storage_get_db_connection(); + + EM_STORAGE_START_WRITE_TRANSACTION(transaction, error); + + SNPRINTF(sql_query_string, sizeof(sql_query_string), + "UPDATE mail_box_tbl SET" + " modifiable_yn = %d" + " WHERE account_id = %d" + " AND local_yn = %d" + " AND mailbox_name = '%s'" + , modifiable_yn + , account_id + , local_yn + , mailbox_name); + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, sql_query_string, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) exec fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + ret = true; + +FINISH_OFF: + EM_STORAGE_FINISH_WRITE_TRANSACTION(transaction, ret, error); + _DISCONNECT_DB; + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; + +} + + +EXPORT_API int em_storage_update_mailbox_total_count(int account_id, char *mailbox_name, int total_count_on_server, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id[%d], mailbox_name[%p], total_count_on_server[%d], transaction[%d], err_code[%p]", account_id, mailbox_name, total_count_on_server, transaction, err_code); + int rc, ret = false; + int error = EM_STORAGE_ERROR_NONE; + char sql_query_string[QUERY_SIZE] = {0, }; + + if (account_id <= 0 || !mailbox_name) { + EM_DEBUG_EXCEPTION("account_id[%d], mailbox_name[%p]", account_id, mailbox_name); + + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + sqlite3 *local_db_handle = em_storage_get_db_connection(); + + EM_STORAGE_START_WRITE_TRANSACTION(transaction, error); + + SNPRINTF(sql_query_string, sizeof(sql_query_string), + "UPDATE mail_box_tbl SET" + " total_mail_count_on_server = %d" + " WHERE account_id = %d" + " AND mailbox_name = '%s'" + , total_count_on_server + , account_id + , mailbox_name); + EM_DEBUG_LOG("query[%s]", sql_query_string); + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, sql_query_string, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) exec fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + ret = true; + +FINISH_OFF: + EM_STORAGE_FINISH_WRITE_TRANSACTION(transaction, ret, error); + _DISCONNECT_DB; + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; + +} + + +EXPORT_API int em_storage_update_mailbox(int account_id, int local_yn, char *mailbox_name, emf_mailbox_tbl_t* result_mailbox, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id[%d], local_yn[%d], mailbox_name[%s], result_mailbox[%p], transaction[%d], err_code[%p]", account_id, local_yn, mailbox_name, result_mailbox, transaction, err_code); + + if (account_id < FIRST_ACCOUNT_ID || !mailbox_name || !result_mailbox) { + EM_DEBUG_EXCEPTION(" account_id[%d], local_yn[%d], mailbox_name[%s], result_mailbox[%p]", account_id, local_yn, mailbox_name, result_mailbox); + + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + int rc, ret = false; + int error = EM_STORAGE_ERROR_NONE; + char sql_query_string[QUERY_SIZE] = {0, }; + DB_STMT hStmt = NULL; + int i = 0; + + sqlite3 *local_db_handle = em_storage_get_db_connection(); + EM_STORAGE_START_WRITE_TRANSACTION(transaction, error); + + if (local_yn != -1) { + SNPRINTF(sql_query_string, sizeof(sql_query_string), + "UPDATE mail_box_tbl SET" + " mailbox_id = ?" + ", mailbox_name = ?" + ", mailbox_type = ?" + ", alias = ?" + ", sync_with_server_yn = ?" + ", modifiable_yn= ?" + ", mail_slot_size= ?" + ", total_mail_count_on_server = ?" + " WHERE account_id = %d" + " AND local_yn = %d" + " AND mailbox_name = '%s'" + , account_id + , local_yn + , mailbox_name); + } + else { + SNPRINTF(sql_query_string, sizeof(sql_query_string), + "UPDATE mail_box_tbl SET" + " mailbox_id = ?" + ", mailbox_name = ?" + ", mailbox_type = ?" + ", alias = ?" + ", sync_with_server_yn = ?" + ", modifiable_yn= ?" + ", mail_slot_size= ?" + ", total_mail_count_on_server = ?" + " WHERE account_id = %d" + " AND mailbox_name = '%s'" + , account_id + , mailbox_name); + } + + + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_prepare_v2(local_db_handle, sql_query_string, strlen(sql_query_string), &hStmt, NULL), rc); + EM_DEBUG_DB_EXEC((SQLITE_OK != rc), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) sqlite3_prepare fail:(%d) %s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + _bindStmtFieldDataInt(hStmt, i++, result_mailbox->mailbox_id); + _bindStmtFieldDataString(hStmt, i++, (char *)result_mailbox->mailbox_name ? result_mailbox->mailbox_name : "", 0, MAILBOX_NAME_LEN_IN_MAIL_READ_MAIL_UID_TBL); + _bindStmtFieldDataInt(hStmt, i++, result_mailbox->mailbox_type); + _bindStmtFieldDataString(hStmt, i++, (char *)result_mailbox->alias ? result_mailbox->alias : "", 0, ALIAS_LEN_IN_MAIL_BOX_TBL); + _bindStmtFieldDataInt(hStmt, i++, result_mailbox->sync_with_server_yn); + _bindStmtFieldDataInt(hStmt, i++, result_mailbox->modifiable_yn); + _bindStmtFieldDataInt(hStmt, i++, result_mailbox->mail_slot_size); + _bindStmtFieldDataInt(hStmt, i++, result_mailbox->total_mail_count_on_server); + + /* rc = sqlite3_step(hStmt); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_step(hStmt), rc); + EM_DEBUG_DB_EXEC((rc == SQLITE_FULL), {error = EM_STORAGE_ERROR_DB_IS_FULL;goto FINISH_OFF; }, + ("sqlite3_step fail:%d", rc)); + EM_DEBUG_DB_EXEC((rc != SQLITE_ROW && rc != SQLITE_DONE), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("sqlite3_step fail:%d", rc)); + + ret = true; + +FINISH_OFF: + EM_STORAGE_FINISH_WRITE_TRANSACTION(transaction, ret, error); + _DISCONNECT_DB; + + if (hStmt != NULL) { + rc = sqlite3_finalize(hStmt); + if (rc != SQLITE_OK) { + EM_DEBUG_EXCEPTION(" sqlite3_finalize failed - %d", rc); + error = EM_STORAGE_ERROR_DB_FAILURE; + } + } + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + + +EXPORT_API int em_storage_update_mailbox_type(int account_id, int local_yn, char *mailbox_name, emf_mailbox_tbl_t* target_mailbox, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id[%d], local_yn[%d], mailbox_name[%s], target_mailbox[%p], transaction[%d], err_code[%p]", account_id, local_yn, mailbox_name, target_mailbox, transaction, err_code); + + if (account_id < FIRST_ACCOUNT_ID || !mailbox_name || !target_mailbox) { + EM_DEBUG_EXCEPTION(" account_id[%d], local_yn[%d], mailbox_name[%s], target_mailbox[%p]", account_id, local_yn, mailbox_name, target_mailbox); + + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + int rc, ret = false; + int error = EM_STORAGE_ERROR_NONE; + char sql_query_string[QUERY_SIZE] = {0, }; + + sqlite3 *local_db_handle = em_storage_get_db_connection(); + EM_STORAGE_START_WRITE_TRANSACTION(transaction, error); + + EM_DEBUG_LOG("em_storage_update_mailbox_type"); + + DB_STMT hStmt = NULL; + int i = 0; + + /* Update mail_box_tbl */ + if (local_yn != -1) { + SNPRINTF(sql_query_string, sizeof(sql_query_string), + "UPDATE mail_box_tbl SET" + " mailbox_type = ?" + " WHERE account_id = %d" + " AND local_yn = %d" + " AND mailbox_name = '%s'" + , account_id + , local_yn + , mailbox_name); + } + else { + SNPRINTF(sql_query_string, sizeof(sql_query_string), + "UPDATE mail_box_tbl SET" + " mailbox_type = ?" + " WHERE account_id = %d" + " AND mailbox_name = '%s'" + , account_id + , mailbox_name); + } + + EM_DEBUG_LOG("SQL(%s)", sql_query_string); + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_prepare_v2(local_db_handle, sql_query_string, strlen(sql_query_string), &hStmt, NULL), rc); + EM_DEBUG_DB_EXEC((SQLITE_OK != rc), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) sqlite3_prepare fail:(%d) %s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + _bindStmtFieldDataInt(hStmt, i++, target_mailbox->mailbox_type); + + /* rc = sqlite3_step(hStmt); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_step(hStmt), rc); + EM_DEBUG_DB_EXEC((rc == SQLITE_FULL), {error = EM_STORAGE_ERROR_DB_IS_FULL;goto FINISH_OFF; }, + ("sqlite3_step fail:%d", rc)); + EM_DEBUG_DB_EXEC((rc != SQLITE_ROW && rc != SQLITE_DONE), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("sqlite3_step fail:%d", rc)); + + if (hStmt != NULL) { + rc = sqlite3_finalize(hStmt); + if (rc != SQLITE_OK) { + EM_DEBUG_EXCEPTION(" sqlite3_finalize failed - %d", rc); + error = EM_STORAGE_ERROR_DB_FAILURE; + } + hStmt = NULL; + } + + /* Update mail_tbl */ + i = 0; + SNPRINTF(sql_query_string, sizeof(sql_query_string), + "UPDATE mail_tbl SET" + " mailbox_type = ?" + " WHERE account_id = %d" + " AND mailbox_name = '%s'" + , account_id + , mailbox_name); + + EM_DEBUG_LOG("SQL[%s]", sql_query_string); + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_prepare_v2(local_db_handle, sql_query_string, strlen(sql_query_string), &hStmt, NULL), rc); + EM_DEBUG_DB_EXEC((SQLITE_OK != rc), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) sqlite3_prepare fail:(%d) %s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + _bindStmtFieldDataInt(hStmt, i++, target_mailbox->mailbox_type); + + /* rc = sqlite3_step(hStmt); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_step(hStmt), rc); + EM_DEBUG_DB_EXEC((rc == SQLITE_FULL), {error = EM_STORAGE_ERROR_DB_IS_FULL;goto FINISH_OFF; }, + ("sqlite3_step fail:%d", rc)); + EM_DEBUG_DB_EXEC((rc != SQLITE_ROW && rc != SQLITE_DONE), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("sqlite3_step fail:%d", rc)); + + ret = true; + +FINISH_OFF: + EM_STORAGE_FINISH_WRITE_TRANSACTION(transaction, ret, error); + _DISCONNECT_DB; + + if (hStmt != NULL) { + rc = sqlite3_finalize(hStmt); + if (rc != SQLITE_OK) { + EM_DEBUG_EXCEPTION(" sqlite3_finalize failed - %d", rc); + error = EM_STORAGE_ERROR_DB_FAILURE; + } + } + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + + +EXPORT_API int em_storage_add_mailbox(emf_mailbox_tbl_t* mailbox_name, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("mailbox_name[%p], transaction[%d], err_code[%p]", mailbox_name, transaction, err_code); + + if (!mailbox_name) { + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + int rc, ret = false; + int error = EM_STORAGE_ERROR_NONE; + DB_STMT hStmt = NULL; + char sql_query_string[QUERY_SIZE] = {0,}; + + sqlite3 *local_db_handle = em_storage_get_db_connection(); + EM_STORAGE_START_WRITE_TRANSACTION(transaction, error); + + SNPRINTF(sql_query_string, sizeof(sql_query_string), + "INSERT INTO mail_box_tbl VALUES " + "( ?" /* mailbox_id */ + ", ?" /* account_id */ + ", ?" /* local_yn */ + ", ?" /* mailbox_name */ + ", ?" /* mailbox_type */ + ", ?" /* alias */ + ", ?" /* sync_with_server_yn */ + ", ?" /* modifiable_yn */ + ", ?" /* total_mail_count_on_server */ + ", ?" /* has_archived_mails */ + ", ? )");/* mail_slot_size */ + + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_prepare_v2(local_db_handle, sql_query_string, strlen(sql_query_string), &hStmt, NULL), rc); + EM_DEBUG_LOG("After sqlite3_prepare hStmt = %p", hStmt); + EM_DEBUG_DB_EXEC((SQLITE_OK != rc), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) sqlite3_prepare fail:(%d) %s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + int col_index = 0; + + _bindStmtFieldDataInt(hStmt, col_index++, mailbox_name->mailbox_id); + _bindStmtFieldDataInt(hStmt, col_index++, mailbox_name->account_id); + _bindStmtFieldDataInt(hStmt, col_index++, mailbox_name->local_yn); + _bindStmtFieldDataString(hStmt, col_index++, (char *)mailbox_name->mailbox_name, 0, MAILBOX_NAME_LEN_IN_MAIL_BOX_TBL); + _bindStmtFieldDataInt(hStmt, col_index++, mailbox_name->mailbox_type); + _bindStmtFieldDataString(hStmt, col_index++, (char *)mailbox_name->alias, 0, ALIAS_LEN_IN_MAIL_BOX_TBL); + _bindStmtFieldDataInt(hStmt, col_index++, mailbox_name->sync_with_server_yn); + _bindStmtFieldDataInt(hStmt, col_index++, mailbox_name->modifiable_yn); + _bindStmtFieldDataInt(hStmt, col_index++, mailbox_name->total_mail_count_on_server); + _bindStmtFieldDataInt(hStmt, col_index++, 0); + _bindStmtFieldDataInt(hStmt, col_index++, mailbox_name->mail_slot_size); + + /* rc = sqlite3_step(hStmt); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_step(hStmt), rc); + EM_DEBUG_DB_EXEC((rc != SQLITE_ROW && rc != SQLITE_DONE), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("sqlite3_step fail:%dn", rc)); + + if (!em_storage_notify_storage_event(NOTI_MAILBOX_ADD, mailbox_name->account_id, 0, mailbox_name->mailbox_name, 0)) + EM_DEBUG_EXCEPTION("em_storage_notify_storage_event[ NOTI_MAILBOX_ADD] : Notification Failed"); + ret = true; + +FINISH_OFF: + if (hStmt != NULL) { + EM_DEBUG_LOG("before sqlite3_finalize hStmt = %p", hStmt); + + rc = sqlite3_finalize(hStmt); + if (rc != SQLITE_OK) { + EM_DEBUG_EXCEPTION("sqlite3_finalize failed - %d", rc); + error = EM_STORAGE_ERROR_DB_FAILURE; + } + } + + EM_STORAGE_FINISH_WRITE_TRANSACTION(transaction, ret, error); + _DISCONNECT_DB; + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API int em_storage_set_all_mailbox_modifiable_yn(int account_id, int modifiable_yn, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id[%d], modifiable_yn[%d], err_code[%p]", account_id, modifiable_yn, err_code); + + if (account_id < FIRST_ACCOUNT_ID) { + + EM_DEBUG_EXCEPTION("account_id[%d]", account_id); + + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + int rc, ret = false; + int error = EM_STORAGE_ERROR_NONE; + char sql_query_string[QUERY_SIZE] = {0,}; + + sqlite3 *local_db_handle = em_storage_get_db_connection(); + EM_STORAGE_START_WRITE_TRANSACTION(transaction, error); + + + SNPRINTF(sql_query_string, sizeof(sql_query_string), "UPDATE mail_box_tbl SET modifiable_yn = %d WHERE account_id = %d", modifiable_yn, account_id); + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, sql_query_string, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) exec fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + rc = sqlite3_changes(local_db_handle); + if (rc == 0) + EM_DEBUG_EXCEPTION("All mailbox_name modifiable_yn set to 0 already"); + + + ret = true; + +FINISH_OFF: + EM_STORAGE_FINISH_WRITE_TRANSACTION(transaction, ret, error); + _DISCONNECT_DB; + + if (err_code != NULL) + *err_code = error; + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; + + +} + +EXPORT_API int em_storage_delete_mailbox(int account_id, int local_yn, char *mailbox_name, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id[%d], local_yn[%d], mailbox_name[%p], transaction[%d], err_code[%p]", account_id, local_yn, mailbox_name, transaction, err_code); + + if (account_id < FIRST_ACCOUNT_ID) { + EM_DEBUG_EXCEPTION(" account_id[%d], local_yn[%d], mailbox_name[%p]", account_id, local_yn, mailbox_name); + + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + int rc, ret = false; + int error = EM_STORAGE_ERROR_NONE; + char sql_query_string[QUERY_SIZE] = {0, }; + + sqlite3 *local_db_handle = em_storage_get_db_connection(); + EM_STORAGE_START_WRITE_TRANSACTION(transaction, error); + + if (local_yn == -1) + SNPRINTF(sql_query_string, sizeof(sql_query_string), "DELETE FROM mail_box_tbl WHERE account_id = %d ", account_id); + else + SNPRINTF(sql_query_string, sizeof(sql_query_string), "DELETE FROM mail_box_tbl WHERE account_id = %d AND local_yn = %d ", account_id, local_yn); + + if (mailbox_name) { /* NULL means all mailbox_name */ + SNPRINTF(sql_query_string + strlen(sql_query_string), sizeof(sql_query_string)-(1+ strlen(sql_query_string)), "AND UPPER(mailbox_name) = UPPER('%s')", mailbox_name); + } + + EM_DEBUG_LOG("mailbox sql_query_string [%s]", sql_query_string); + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, sql_query_string, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) exec fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + rc = sqlite3_changes(local_db_handle); + if (rc == 0) { + EM_DEBUG_EXCEPTION(" no (matched) mailbox_name found..."); + error = EM_STORAGE_ERROR_MAILBOX_NOT_FOUND; + ret = true; + } + ret = true; + +FINISH_OFF: + + EM_STORAGE_FINISH_WRITE_TRANSACTION(transaction, ret, error); + _DISCONNECT_DB; + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API int em_storage_free_mailbox(emf_mailbox_tbl_t** mailbox_list, int count, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("mailbox_list[%p], count[%d], err_code[%p]", mailbox_list, count, err_code); + + int ret = false; + int error = EM_STORAGE_ERROR_NONE; + + if (count > 0) { + if (!mailbox_list || !*mailbox_list) { + EM_DEBUG_EXCEPTION(" mailbox_list[%p], count[%d]", mailbox_list, count); + + error = EM_STORAGE_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + emf_mailbox_tbl_t* p = *mailbox_list; + int i = 0; + + for (; i < count; i++) { + EM_SAFE_FREE(p[i].mailbox_name); + EM_SAFE_FREE(p[i].alias); + } + + EM_SAFE_FREE(p); *mailbox_list = NULL; + } + + ret = true; + +FINISH_OFF: + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API int em_storage_get_count_read_mail_uid(int account_id, char *mailbox_name, int *count, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id[%d], mailbox_name[%p], count[%p], transaction[%d], err_code[%p]", account_id, mailbox_name , count, transaction, err_code); + + if (account_id < FIRST_ACCOUNT_ID || !mailbox_name || !count) { /* TODO: confirm me */ + EM_DEBUG_EXCEPTION(" account_id[%d], mailbox_name[%p], count[%p], exist[%p]", account_id, mailbox_name, count); + + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + int rc = -1, ret = false; + int error = EM_STORAGE_ERROR_NONE; + char sql_query_string[QUERY_SIZE] = {0, }; + + sqlite3 *local_db_handle = em_storage_get_db_connection(); + EM_STORAGE_START_READ_TRANSACTION(transaction); + SNPRINTF(sql_query_string, sizeof(sql_query_string), "SELECT COUNT(*) FROM mail_read_mail_uid_tbl WHERE account_id = %d AND mailbox_name = '%s' ", account_id, mailbox_name); + EM_DEBUG_LOG(">>> SQL [ %s ] ", sql_query_string); + + char **result; + /* rc = sqlite3_get_table(local_db_handle, sql_query_string, &result, NULL, NULL, NULL); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_get_table(local_db_handle, sql_query_string, &result, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;sqlite3_free_table(result);goto FINISH_OFF; }, + ("SQL(%s) sqlite3_get_table fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + *count = atoi(result[1]); + sqlite3_free_table(result); + + ret = true; + +FINISH_OFF: + EM_STORAGE_FINISH_READ_TRANSACTION(transaction); + _DISCONNECT_DB; + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + + + +EXPORT_API int em_storage_check_read_mail_uid(int account_id, char *mailbox_name, char *uid, int *exist, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id[%d], mailbox_name[%p], uid[%p], exist[%p], transaction[%d], err_code[%p]", account_id, mailbox_name , uid, exist, transaction, err_code); + + if (account_id < FIRST_ACCOUNT_ID || !uid || !exist) { + EM_DEBUG_EXCEPTION(" account_id[%d], mailbox_name[%p], uid[%p], exist[%p]", account_id, mailbox_name , uid, exist); + + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + int rc = -1, ret = false; + int error = EM_STORAGE_ERROR_NONE; + char sql_query_string[QUERY_SIZE] = {0, }; + sqlite3 *local_db_handle = em_storage_get_db_connection(); + EM_STORAGE_START_READ_TRANSACTION(transaction); + + if (mailbox_name) { + SNPRINTF(sql_query_string, sizeof(sql_query_string), "SELECT COUNT(*) FROM mail_read_mail_uid_tbl WHERE account_id = %d AND mailbox_name = '%s' AND s_uid = '%s' ", account_id, mailbox_name, uid); + } + else { + SNPRINTF(sql_query_string, sizeof(sql_query_string), "SELECT COUNT(*) FROM mail_read_mail_uid_tbl WHERE account_id = %d AND s_uid = '%s' ", account_id, uid); + } + + char **result; + /* rc = sqlite3_get_table(local_db_handle, sql_query_string, &result, NULL, NULL, NULL); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_get_table(local_db_handle, sql_query_string, &result, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;sqlite3_free_table(result);goto FINISH_OFF; }, + ("SQL(%s) sqlite3_get_table fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + *exist = atoi(result[1]); + sqlite3_free_table(result); + + if (*exist > 0) + *exist = 1; + else + *exist = 0; + + ret = true; + +FINISH_OFF: + EM_STORAGE_FINISH_READ_TRANSACTION(transaction); + _DISCONNECT_DB; + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API int em_storage_get_downloaded_mail(int mail_id, emf_mail_tbl_t** mail, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("mail_id[%d], mail[%p], err_code[%p]", mail_id, mail, err_code); + + if (!mail) { + EM_DEBUG_EXCEPTION(" mail_id[%d], mail[%p]", mail_id, mail); + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + int rc, ret = false, temp_rule; + int error = EM_STORAGE_ERROR_NONE; + DB_STMT hStmt = NULL; + char sql_query_string[QUERY_SIZE] = {0, }; + + sqlite3 *local_db_handle = em_storage_get_db_connection(); + EM_STORAGE_START_READ_TRANSACTION(transaction); + + SNPRINTF(sql_query_string, sizeof(sql_query_string), "SELECT * FROM mail_read_mail_uid_tbl WHERE local_uid = %d", mail_id); + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_prepare_v2(local_db_handle, sql_query_string, strlen(sql_query_string), &hStmt, NULL), rc); + EM_DEBUG_LOG("sqlite3_prepare hStmt = %p", hStmt); + + EM_DEBUG_DB_EXEC((SQLITE_OK != rc), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) sqlite3_prepare fail:(%d) %s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + /* rc = sqlite3_step(hStmt); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_step(hStmt), rc); + EM_DEBUG_DB_EXEC((rc != SQLITE_ROW && rc != SQLITE_DONE), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("sqlite3_step fail:%d", rc)); + + *mail = (emf_mail_tbl_t*)malloc(sizeof(emf_mail_tbl_t)); + if (*mail == NULL) { + error = EM_STORAGE_ERROR_OUT_OF_MEMORY; + EM_DEBUG_EXCEPTION("Memory allocation for mail failed."); + goto FINISH_OFF; + + } + memset(*mail, 0x00, sizeof(emf_mail_tbl_t)); + + _getStmtFieldDataInt(hStmt, &((*mail)->account_id), ACCOUNT_ID_IDX_IN_MAIL_READ_MAIL_UID_TBL); + _getStmtFieldDataString(hStmt, &((*mail)->mailbox_name), 0, LOCAL_MBOX_IDX_IN_MAIL_READ_MAIL_UID_TBL); + _getStmtFieldDataInt(hStmt, &((*mail)->mail_id), LOCAL_UID_IDX_IN_MAIL_READ_MAIL_UID_TBL); + _getStmtFieldDataString(hStmt, &((*mail)->server_mailbox_name), 0, MAILBOX_NAME_IDX_IN_MAIL_READ_MAIL_UID_TBL); + _getStmtFieldDataString(hStmt, &((*mail)->server_mail_id), 0, S_UID_IDX_IN_MAIL_READ_MAIL_UID_TBL); + _getStmtFieldDataInt(hStmt, &((*mail)->mail_size), DATA1_IDX_IN_MAIL_READ_MAIL_UID_TBL); + _getStmtFieldDataInt(hStmt, &temp_rule, FLAG_IDX_IN_MAIL_READ_MAIL_UID_TBL); + + (*mail)->server_mail_status = 1; + + ret = true; + +FINISH_OFF: + if (hStmt != NULL) { + EM_DEBUG_LOG("before sqlite3_finalize hStmt = %p", hStmt); + rc = sqlite3_finalize(hStmt); + if (rc != SQLITE_OK) { + EM_DEBUG_EXCEPTION(" sqlite3_finalize failed - %d", rc); + error = EM_STORAGE_ERROR_DB_FAILURE; + } + } + + EM_STORAGE_FINISH_READ_TRANSACTION(transaction); + _DISCONNECT_DB; + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API int em_storage_get_downloaded_list(int account_id, char *local_mbox, emf_mail_read_mail_uid_tbl_t** read_mail_uid, int *count, int transaction, int *err_code) +{ + EM_PROFILE_BEGIN(emStorageGetDownloadList); + EM_DEBUG_FUNC_BEGIN("account_id[%d], local_mbox[%s], read_mail_uid[%p], count[%p], transaction[%d], err_code[%p]", account_id, local_mbox, read_mail_uid, count, transaction, err_code); + if (account_id < FIRST_ACCOUNT_ID || !read_mail_uid || !count) { + EM_DEBUG_EXCEPTION(" account_id[%d], local_mbox[%s], read_mail_uid[%p], count[%p]", account_id, local_mbox, read_mail_uid, count); + + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + int rc, ret = false; + int error = EM_STORAGE_ERROR_NONE; + + DB_STMT hStmt = NULL; + char sql_query_string[QUERY_SIZE] = {0, }; + + emf_mail_read_mail_uid_tbl_t* p_data_tbl = NULL; + int i = 0; + + sqlite3 *local_db_handle = em_storage_get_db_connection(); + EM_STORAGE_START_READ_TRANSACTION(transaction); + + if (local_mbox) + SNPRINTF(sql_query_string, sizeof(sql_query_string), "SELECT * FROM mail_read_mail_uid_tbl WHERE account_id = %d AND UPPER(local_mbox) = UPPER('%s')", account_id, local_mbox); + else + SNPRINTF(sql_query_string, sizeof(sql_query_string), "SELECT * FROM mail_read_mail_uid_tbl WHERE account_id = %d", account_id); + + EM_DEBUG_LOG(" sql_query_string : %s", sql_query_string); + + + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_prepare_v2(local_db_handle, sql_query_string, strlen(sql_query_string), &hStmt, NULL), rc); + EM_DEBUG_LOG("sqlite3_prepare hStmt = %p", hStmt); + EM_DEBUG_DB_EXEC((SQLITE_OK != rc), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) sqlite3_prepare fail:(%d) %s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + /* rc = sqlite3_step(hStmt); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_step(hStmt), rc); + EM_DEBUG_DB_EXEC((rc != SQLITE_ROW && rc != SQLITE_DONE), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("sqlite3_step fail:%d", rc)); + + char **result; + /* rc = sqlite3_get_table(local_db_handle, sql_query_string, &result, count, NULL, NULL); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_get_table(local_db_handle, sql_query_string, &result, count, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;sqlite3_free_table(result);goto FINISH_OFF; }, + ("SQL(%s) sqlite3_get_table fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + sqlite3_free_table(result); + if (*count == 0) { + EM_DEBUG_LOG("No mail found in mail_read_mail_uid_tbl"); + ret = true; + goto FINISH_OFF; + } + + + if (!(p_data_tbl = (emf_mail_read_mail_uid_tbl_t*)malloc(sizeof(emf_mail_read_mail_uid_tbl_t) * *count))) { + EM_DEBUG_EXCEPTION(" malloc failed..."); + error = EM_STORAGE_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + memset(p_data_tbl, 0x00, sizeof(emf_mail_read_mail_uid_tbl_t)* *count); + + for (i = 0; i < *count; ++i) { + _getStmtFieldDataInt(hStmt, &(p_data_tbl[i].account_id), ACCOUNT_ID_IDX_IN_MAIL_READ_MAIL_UID_TBL); + _getStmtFieldDataString(hStmt, &(p_data_tbl[i].local_mbox), 0, LOCAL_MBOX_IDX_IN_MAIL_READ_MAIL_UID_TBL); + _getStmtFieldDataInt(hStmt, &(p_data_tbl[i].local_uid), LOCAL_UID_IDX_IN_MAIL_READ_MAIL_UID_TBL); + _getStmtFieldDataString(hStmt, &(p_data_tbl[i].mailbox_name), 0, MAILBOX_NAME_IDX_IN_MAIL_READ_MAIL_UID_TBL); + _getStmtFieldDataString(hStmt, &(p_data_tbl[i].s_uid), 0, S_UID_IDX_IN_MAIL_READ_MAIL_UID_TBL); + _getStmtFieldDataInt(hStmt, &(p_data_tbl[i].data1), DATA1_IDX_IN_MAIL_READ_MAIL_UID_TBL); + _getStmtFieldDataString(hStmt, &(p_data_tbl[i].data2), 0, DATA2_IDX_IN_MAIL_READ_MAIL_UID_TBL); + _getStmtFieldDataInt(hStmt, &(p_data_tbl[i].flag), FLAG_IDX_IN_MAIL_READ_MAIL_UID_TBL); + /* rc = sqlite3_step(hStmt); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_step(hStmt), rc); + EM_DEBUG_DB_EXEC((rc != SQLITE_ROW && rc != SQLITE_DONE), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("sqlite3_step fail:%d", rc)); + } + + ret = true; + +FINISH_OFF: + if (ret == true) + *read_mail_uid = p_data_tbl; + else if (p_data_tbl) + em_storage_free_read_mail_uid(&p_data_tbl, *count, NULL); + + if (hStmt != NULL) { + EM_DEBUG_LOG(" Before sqlite3_finalize hStmt = %p", hStmt); + rc = sqlite3_finalize(hStmt); + if (rc != SQLITE_OK) { + EM_DEBUG_LOG(" sqlite3_finalize failed - %d", rc); + + error = EM_STORAGE_ERROR_DB_FAILURE; + } + } + + EM_STORAGE_FINISH_READ_TRANSACTION(transaction); + _DISCONNECT_DB; + + if (err_code != NULL) + *err_code = error; + + EM_PROFILE_END(emStorageGetDownloadList); + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API int em_storage_get_downloaded_mail_size(int account_id, char *local_mbox, int local_uid, char *mailbox_name, char *uid, int *mail_size, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id[%d], local_mbox[%p], locacal_uid[%d], mailbox_name[%p], uid[%p], mail_size[%p], transaction[%d], err_code[%p]", account_id, local_mbox, local_uid, mailbox_name, uid, mail_size, transaction, err_code); + + if (account_id < FIRST_ACCOUNT_ID || !mail_size) { + EM_DEBUG_EXCEPTION(" account_id[%d], local_mbox[%p], locacal_uid[%d], mailbox_name[%p], uid[%p], mail_size[%p]", account_id, local_mbox, local_uid, mailbox_name, uid, mail_size); + + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + int rc, ret = false; + int error = EM_STORAGE_ERROR_NONE; + DB_STMT hStmt = NULL; + char sql_query_string[QUERY_SIZE] = {0, }; + + + sqlite3 *local_db_handle = em_storage_get_db_connection(); + EM_STORAGE_START_READ_TRANSACTION(transaction); + + if (mailbox_name) { + SNPRINTF(sql_query_string, sizeof(sql_query_string), + "SELECT IFNULL(MAX(data1), 0) FROM mail_read_mail_uid_tbl " + "WHERE account_id = %d " + "AND local_mbox = '%s' " + "AND local_uid = %d " + "AND mailbox_name = '%s' " + "AND s_uid = '%s'", + account_id, local_mbox, local_uid, mailbox_name, uid); + } + else { + SNPRINTF(sql_query_string, sizeof(sql_query_string), + "SELECT IFNULL(MAX(data1), 0) FROM mail_read_mail_uid_tbl " + "WHERE account_id = %d " + "AND local_mbox = '%s' " + "AND local_uid = %d " + "AND s_uid = '%s'", + account_id, local_mbox, local_uid, uid); + } + + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_prepare_v2(local_db_handle, sql_query_string, strlen(sql_query_string), &hStmt, NULL), rc); + EM_DEBUG_DB_EXEC((SQLITE_OK != rc), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) sqlite3_prepare fail:(%d) %s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + /* rc = sqlite3_step(hStmt); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_step(hStmt), rc); + EM_DEBUG_DB_EXEC((rc != SQLITE_ROW && rc != SQLITE_DONE), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("sqlite3_step fail:%d", rc)); + + if (rc == SQLITE_DONE) { + EM_DEBUG_EXCEPTION(" no matched mail found...."); + error = EM_STORAGE_ERROR_MAIL_NOT_FOUND; + goto FINISH_OFF; + } + + _getStmtFieldDataInt(hStmt, mail_size, 0); + + ret = true; + +FINISH_OFF: + if (hStmt != NULL) { + rc = sqlite3_finalize(hStmt); + if (rc != SQLITE_OK) { + EM_DEBUG_LOG(" sqlite3_finalize failed - %d", rc); + + error = EM_STORAGE_ERROR_DB_FAILURE; + } + } + + EM_STORAGE_FINISH_READ_TRANSACTION(transaction); + _DISCONNECT_DB; + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API int em_storage_add_downloaded_mail(emf_mail_read_mail_uid_tbl_t* read_mail_uid, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("read_mail_uid[%p], transaction[%d], err_code[%p]", read_mail_uid, transaction, err_code); + + if (!read_mail_uid) { + EM_DEBUG_EXCEPTION("read_mail_uid[%p]", read_mail_uid); + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + int rc, rc2, ret = false; + int error = EM_STORAGE_ERROR_NONE; + DB_STMT hStmt = NULL; + char sql_query_string[QUERY_SIZE] = {0, }; + + sqlite3 *local_db_handle = em_storage_get_db_connection(); + EM_STORAGE_START_WRITE_TRANSACTION(transaction, error); + + char *sql = "SELECT max(rowid) FROM mail_read_mail_uid_tbl;"; + char **result = NULL; + + /* rc = sqlite3_get_table(local_db_handle, sql, &result, NULL, NULL, NULL); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_get_table(local_db_handle, sql, &result, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;sqlite3_free_table(result);goto FINISH_OFF; }, + ("SQL(%s) sqlite3_get_table fail:%d -%s", sql, rc, sqlite3_errmsg(local_db_handle))); + + if (NULL==result[1]) rc = 1; + else rc = atoi(result[1])+1; + sqlite3_free_table(result); + + SNPRINTF(sql_query_string, sizeof(sql_query_string), + "INSERT INTO mail_read_mail_uid_tbl VALUES " + "( ?" + ", ?" + ", ?" + ", ?" + ", ?" + ", ?" + ", ?" + ", ?" + ", ? )"); + + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_prepare_v2(local_db_handle, sql_query_string, strlen(sql_query_string), &hStmt, NULL), rc2); + if (rc2 != SQLITE_OK) { + EM_DEBUG_LOG("sqlite3_prepare hStmt = %p", hStmt); + EM_DEBUG_EXCEPTION("SQL(%s) sqlite3_prepare fail:(%d) %s", sql_query_string, rc, sqlite3_errmsg(local_db_handle)); + + error = EM_STORAGE_ERROR_DB_FAILURE; + goto FINISH_OFF; + } + + EM_DEBUG_LOG("account_id VALUE [%d] ", read_mail_uid->account_id); + EM_DEBUG_LOG("local_mbox VALUE [%s] ", read_mail_uid->local_mbox); + EM_DEBUG_LOG("local_uid VALUE [%d] ", read_mail_uid->local_uid); + EM_DEBUG_LOG("mailbox_name VALUE [%s] ", read_mail_uid->mailbox_name); + EM_DEBUG_LOG("s_uid VALUE [%s] ", read_mail_uid->s_uid); + EM_DEBUG_LOG("data1 VALUE [%d] ", read_mail_uid->data1); + EM_DEBUG_LOG("data2 VALUE [%s] ", read_mail_uid->data2); + EM_DEBUG_LOG("flag VALUE [%d] ", read_mail_uid->flag); + EM_DEBUG_LOG("rc VALUE [%d] ", rc); + + _bindStmtFieldDataInt(hStmt, ACCOUNT_ID_IDX_IN_MAIL_READ_MAIL_UID_TBL, read_mail_uid->account_id); + _bindStmtFieldDataString(hStmt, LOCAL_MBOX_IDX_IN_MAIL_READ_MAIL_UID_TBL, (char *)read_mail_uid->local_mbox, 0, LOCAL_MBOX_LEN_IN_MAIL_READ_MAIL_UID_TBL); + _bindStmtFieldDataInt(hStmt, LOCAL_UID_IDX_IN_MAIL_READ_MAIL_UID_TBL, read_mail_uid->local_uid); + _bindStmtFieldDataString(hStmt, MAILBOX_NAME_IDX_IN_MAIL_READ_MAIL_UID_TBL, (char *)read_mail_uid->mailbox_name, 0, MAILBOX_NAME_LEN_IN_MAIL_READ_MAIL_UID_TBL); + _bindStmtFieldDataString(hStmt, S_UID_IDX_IN_MAIL_READ_MAIL_UID_TBL, (char *)read_mail_uid->s_uid, 0, S_UID_LEN_IN_MAIL_READ_MAIL_UID_TBL); + _bindStmtFieldDataInt(hStmt, DATA1_IDX_IN_MAIL_READ_MAIL_UID_TBL, read_mail_uid->data1); + _bindStmtFieldDataString(hStmt, DATA2_IDX_IN_MAIL_READ_MAIL_UID_TBL, (char *)read_mail_uid->data2, 0, DATA2_LEN_IN_MAIL_READ_MAIL_UID_TBL); + _bindStmtFieldDataInt(hStmt, FLAG_IDX_IN_MAIL_READ_MAIL_UID_TBL, read_mail_uid->flag); + _bindStmtFieldDataInt(hStmt, IDX_NUM_IDX_IN_MAIL_READ_MAIL_UID_TBL, rc); + + /* rc = sqlite3_step(hStmt); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_step(hStmt), rc); + EM_DEBUG_DB_EXEC((rc == SQLITE_FULL), {error = EM_STORAGE_ERROR_DB_IS_FULL;goto FINISH_OFF; }, + ("sqlite3_step fail:%d", rc)); + EM_DEBUG_DB_EXEC((rc != SQLITE_ROW && rc != SQLITE_DONE), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("sqlite3_step fail[%d] [%s]", rc, sqlite3_errmsg(local_db_handle))); + + + ret = true; + +FINISH_OFF: + if (hStmt != NULL) { + EM_DEBUG_LOG(" sqlite3_finalize hStmt = %p", hStmt); + + rc = sqlite3_finalize(hStmt); + if (rc != SQLITE_OK) { + EM_DEBUG_LOG(" sqlite3_finalize failed - %d", rc); + error = EM_STORAGE_ERROR_DB_FAILURE; + } + } + + EM_STORAGE_FINISH_WRITE_TRANSACTION(transaction, ret, error); + _DISCONNECT_DB; + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API int em_storage_change_read_mail_uid(int account_id, char *local_mbox, int local_uid, char *mailbox_name, char *uid, emf_mail_read_mail_uid_tbl_t* read_mail_uid, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id[%d], local_mbox[%p], local_uid[%d], mailbox_name[%p], uid[%p], read_mail_uid[%p], transaction[%d], err_code[%p]", account_id, local_mbox, local_uid, mailbox_name, uid, read_mail_uid, transaction, err_code); + + if (account_id < FIRST_ACCOUNT_ID || !read_mail_uid) { + EM_DEBUG_EXCEPTION(" account_id[%d], local_mbox[%p], local_uid[%d], mailbox_name[%p], uid[%p], read_mail_uid[%p]", account_id, local_mbox, local_uid, mailbox_name, uid, read_mail_uid); + + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + int rc, ret = false; + int error = EM_STORAGE_ERROR_NONE; + DB_STMT hStmt = NULL; + char sql_query_string[QUERY_SIZE] = {0, }; + + sqlite3 *local_db_handle = em_storage_get_db_connection(); + + EM_STORAGE_START_WRITE_TRANSACTION(transaction, error); + + SNPRINTF(sql_query_string, sizeof(sql_query_string), + "UPDATE mail_read_mail_uid_tbl SET" + " account_id = ?" + ", local_mbox = ?" + ", local_uid = ?" + ", mailbox_name = ?" + ", s_uid = ?" + ", data1 = ?" + ", data2 = ?" + ", flag = ?" + " WHERE account_id = ?" + " AND local_mbox = ?" + " AND local_uid = ?" + " AND mailbox_name= ?" + " AND s_uid = ?"); + + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_prepare_v2(local_db_handle, sql_query_string, strlen(sql_query_string), &hStmt, NULL), rc); + EM_DEBUG_LOG("sqlite3_prepare hStmt = %p", hStmt); + EM_DEBUG_DB_EXEC((SQLITE_OK != rc), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) sqlite3_prepare fail:(%d) %s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + + int i = 0; + + _bindStmtFieldDataInt(hStmt, i++, read_mail_uid->account_id); + _bindStmtFieldDataString(hStmt, i++, (char *)read_mail_uid->local_mbox, 0, LOCAL_MBOX_LEN_IN_MAIL_READ_MAIL_UID_TBL); + _bindStmtFieldDataInt(hStmt, i++, read_mail_uid->local_uid); + _bindStmtFieldDataString(hStmt, i++, (char *)read_mail_uid->mailbox_name, 0, MAILBOX_NAME_LEN_IN_MAIL_READ_MAIL_UID_TBL); + _bindStmtFieldDataString(hStmt, i++, (char *)read_mail_uid->s_uid, 0, S_UID_LEN_IN_MAIL_READ_MAIL_UID_TBL); + _bindStmtFieldDataInt(hStmt, i++, read_mail_uid->data1); + _bindStmtFieldDataString(hStmt, i++, (char *)read_mail_uid->data2, 0, DATA2_LEN_IN_MAIL_READ_MAIL_UID_TBL); + _bindStmtFieldDataInt(hStmt, i++, read_mail_uid->flag); + _bindStmtFieldDataInt(hStmt, i++, account_id); + _bindStmtFieldDataString(hStmt, i++, (char *)local_mbox, 0, LOCAL_MBOX_LEN_IN_MAIL_READ_MAIL_UID_TBL); + _bindStmtFieldDataInt(hStmt, i++, local_uid); + _bindStmtFieldDataString(hStmt, i++, (char *)mailbox_name, 0, MAILBOX_NAME_LEN_IN_MAIL_READ_MAIL_UID_TBL); + _bindStmtFieldDataString(hStmt, i++, (char *)uid, 0, S_UID_LEN_IN_MAIL_READ_MAIL_UID_TBL); + + /* rc = sqlite3_step(hStmt); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_step(hStmt), rc); + EM_DEBUG_DB_EXEC((rc != SQLITE_ROW && rc != SQLITE_DONE), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("sqlite3_step fail:%d", rc)); + + ret = true; + +FINISH_OFF: + if (hStmt != NULL) { + EM_DEBUG_LOG("sqlite3_finalize hStmt = %p", hStmt); + + rc = sqlite3_finalize(hStmt); + if (rc != SQLITE_OK) { + EM_DEBUG_LOG(" sqlite3_finalize failed - %d", rc); + + error = EM_STORAGE_ERROR_DB_FAILURE; + } + } + + EM_STORAGE_FINISH_WRITE_TRANSACTION(transaction, ret, error); + _DISCONNECT_DB; + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API int em_storage_remove_downloaded_mail(int account_id, char *mailbox_name, char *uid, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id[%d], mailbox_name[%s], uid[%s], transaction[%d], err_code[%p]", account_id, mailbox_name, uid, transaction, err_code); + + if (account_id < FIRST_ACCOUNT_ID) { + EM_DEBUG_EXCEPTION(" account_id[%d], mailbox_name[%s], uid[%s]", account_id, mailbox_name, uid); + + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + int rc, ret = false; + int error = EM_STORAGE_ERROR_NONE; + char sql_query_string[QUERY_SIZE] = {0, }; + + sqlite3 *local_db_handle = em_storage_get_db_connection(); + + EM_STORAGE_START_WRITE_TRANSACTION(transaction, error); + + SNPRINTF(sql_query_string, sizeof(sql_query_string), "DELETE FROM mail_read_mail_uid_tbl WHERE account_id = %d ", account_id); + + if (mailbox_name) { /* NULL means all mailbox_name */ + SNPRINTF(sql_query_string+strlen(sql_query_string), sizeof(sql_query_string) - (1 + strlen(sql_query_string)), "AND mailbox_name = '%s' ", mailbox_name); + } + + if (uid) { /* NULL means all mail */ + SNPRINTF(sql_query_string+strlen(sql_query_string), sizeof(sql_query_string) - (1 + strlen(sql_query_string)), "AND s_uid='%s' ", uid); + } + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, sql_query_string, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) exec fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + + ret = true; + +FINISH_OFF: + + EM_STORAGE_FINISH_WRITE_TRANSACTION(transaction, ret, error); + _DISCONNECT_DB; + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API int em_storage_free_read_mail_uid(emf_mail_read_mail_uid_tbl_t** read_mail_uid, int count, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("read_mail_uid[%p], count[%d], err_code[%p]", read_mail_uid, count, err_code); + + int ret = false; + int error = EM_STORAGE_ERROR_NONE; + + if (count > 0) { + if (!read_mail_uid || !*read_mail_uid) { + EM_DEBUG_EXCEPTION(" read_mail_uid[%p], count[%d]", read_mail_uid, count); + + error = EM_STORAGE_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + emf_mail_read_mail_uid_tbl_t* p = *read_mail_uid; + int i; + + for (i = 0; i < count; i++) { + EM_SAFE_FREE(p[i].local_mbox); + EM_SAFE_FREE(p[i].mailbox_name); + EM_SAFE_FREE(p[i].s_uid); + EM_SAFE_FREE(p[i].data2); + } + + EM_SAFE_FREE(p); *read_mail_uid = NULL; + } + + ret = true; + +FINISH_OFF: + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API int em_storage_get_rule_count(int account_id, int *count, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id[%d], count[%p], transaction[%d], err_code[%p]", account_id, count, transaction, err_code); + + if (account_id != ALL_ACCOUNT || !count) { /* only global rule supported. */ + EM_DEBUG_EXCEPTION(" account_id[%d], count[%p]", account_id, count); + + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + int rc = -1, ret = false; + int error = EM_STORAGE_ERROR_NONE; + char sql_query_string[QUERY_SIZE] = {0, }; + + sqlite3 *local_db_handle = em_storage_get_db_connection(); + EM_STORAGE_START_READ_TRANSACTION(transaction); + + SNPRINTF(sql_query_string, sizeof(sql_query_string), "SELECT COUNT(*) FROM mail_rule_tbl WHERE account_id = %d", account_id); + + char **result; + /* rc = sqlite3_get_table(local_db_handle, sql_query_string, &result, NULL, NULL, NULL); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_get_table(local_db_handle, sql_query_string, &result, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;sqlite3_free_table(result);goto FINISH_OFF; }, + ("SQL(%s) sqlite3_get_table fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + *count = atoi(result[1]); + sqlite3_free_table(result); + + ret = true; + +FINISH_OFF: + EM_STORAGE_FINISH_READ_TRANSACTION(transaction); + _DISCONNECT_DB; + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API int em_storage_get_rule(int account_id, int type, int start_idx, int *select_num, int *is_completed, emf_mail_rule_tbl_t** rule_list, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id[%d], type[%d], start_idx[%d], select_num[%p], is_completed[%p], rule_list[%p], transaction[%d], err_code[%p]", account_id, type, start_idx, select_num, is_completed, rule_list, transaction, err_code); + + if (account_id != ALL_ACCOUNT || !select_num || !is_completed || !rule_list) { /* only global rule supported. */ + EM_DEBUG_EXCEPTION(" account_id[%d], type[%d], start_idx[%d], select_num[%p], is_completed[%p], rule_list[%p]", account_id, type, start_idx, select_num, is_completed, rule_list); + + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + int ret = false; + int error = EM_STORAGE_ERROR_NONE; + + emf_mail_rule_tbl_t* p_data_tbl = NULL; + int i = 0, count = 0; + DB_STMT hStmt = NULL; + char sql_query_string[QUERY_SIZE] = {0, }; + + int rc; + + sqlite3 *local_db_handle = em_storage_get_db_connection(); + EM_STORAGE_START_READ_TRANSACTION(transaction); + + if (type) + SNPRINTF(sql_query_string, sizeof(sql_query_string), "SELECT * FROM mail_rule_tbl WHERE account_id = %d AND type = %d", account_id, type); + else + SNPRINTF(sql_query_string, sizeof(sql_query_string), "SELECT * FROM mail_rule_tbl WHERE account_id = %d ORDER BY type", account_id); + + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_prepare_v2(local_db_handle, sql_query_string, strlen(sql_query_string), &hStmt, NULL), rc); + EM_DEBUG_LOG("sqlite3_prepare hStmt = %p", hStmt); + EM_DEBUG_DB_EXEC((SQLITE_OK != rc), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) sqlite3_prepare fail:(%d) %s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + /* rc = sqlite3_step(hStmt); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_step(hStmt), rc); + EM_DEBUG_DB_EXEC((rc != SQLITE_ROW && rc != SQLITE_DONE), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("sqlite3_step fail:%d", rc)); + + char **result; + /* rc = sqlite3_get_table(local_db_handle, sql_query_string, &result, &count, NULL, NULL); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_get_table(local_db_handle, sql_query_string, &result, &count, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;sqlite3_free_table(result);goto FINISH_OFF; }, + ("SQL(%s) sqlite3_get_table fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + sqlite3_free_table(result); + + if (count == 0) { + EM_DEBUG_LOG(" no matched rule found..."); + ret = true; + goto FINISH_OFF; + } + + + if (!(p_data_tbl = (emf_mail_rule_tbl_t*)malloc(sizeof(emf_mail_rule_tbl_t) * count))) { + EM_DEBUG_EXCEPTION(" malloc failed..."); + + error = EM_STORAGE_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + memset(p_data_tbl, 0x00, sizeof(emf_mail_rule_tbl_t) * count); + + for (i = 0; i < count; i++) { + _getStmtFieldDataInt(hStmt, &(p_data_tbl[i].account_id), ACCOUNT_ID_IDX_IN_MAIL_RULE_TBL); + _getStmtFieldDataInt(hStmt, &(p_data_tbl[i].rule_id), RULE_ID_IDX_IN_MAIL_RULE_TBL); + _getStmtFieldDataInt(hStmt, &(p_data_tbl[i].type), TYPE_IDX_IN_MAIL_RULE_TBL); + _getStmtFieldDataString(hStmt, &(p_data_tbl[i].value), 0, VALUE_IDX_IN_MAIL_RULE_TBL); + _getStmtFieldDataInt(hStmt, &(p_data_tbl[i].action_type), ACTION_TYPE_IDX_IN_MAIL_RULE_TBL); + _getStmtFieldDataString(hStmt, &(p_data_tbl[i].dest_mailbox), 0, DEST_MAILBOX_IDX_IN_MAIL_RULE_TBL); + _getStmtFieldDataInt(hStmt, &(p_data_tbl[i].flag1), FLAG1_IDX_IN_MAIL_RULE_TBL); + _getStmtFieldDataInt(hStmt, &(p_data_tbl[i].flag2), FLAG2_IDX_IN_MAIL_RULE_TBL); + /* rc = sqlite3_step(hStmt); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_step(hStmt), rc); + EM_DEBUG_DB_EXEC((rc != SQLITE_ROW && rc != SQLITE_DONE), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("sqlite3_step fail:%d", rc)); + } + + ret = true; + +FINISH_OFF: + + EM_DEBUG_LOG("[%d] rules found.", count); + + if (ret == true) { + *rule_list = p_data_tbl; + *select_num = count; + } + else if (p_data_tbl != NULL) + em_storage_free_rule(&p_data_tbl, count, NULL); /* CID FIX */ + + if (hStmt != NULL) { + EM_DEBUG_LOG(" sqlite3_finalize hStmt = %p", hStmt); + + rc = sqlite3_finalize(hStmt); + if (rc != SQLITE_OK) { + EM_DEBUG_LOG(" sqlite3_finalize failed - %d", rc); + error = EM_STORAGE_ERROR_DB_FAILURE; + } + } + + + EM_STORAGE_FINISH_READ_TRANSACTION(transaction); + _DISCONNECT_DB; + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API int em_storage_get_rule_by_id(int account_id, int rule_id, emf_mail_rule_tbl_t** rule, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id[%d], rule_id[%d], rule[%p], transaction[%d], err_code[%p]", account_id, rule_id, rule, transaction, err_code); + + if (account_id != ALL_ACCOUNT || !rule) { + EM_DEBUG_EXCEPTION(" account_id[%d], rule_id[%d], rule[%p]", account_id, rule_id, rule); + + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + emf_mail_rule_tbl_t* p_data_tbl = NULL; + int rc, ret = false; + int error = EM_STORAGE_ERROR_NONE; + + DB_STMT hStmt = NULL; + char sql_query_string[QUERY_SIZE] = {0, }; + sqlite3 *local_db_handle = em_storage_get_db_connection(); + EM_STORAGE_START_READ_TRANSACTION(transaction); + + SNPRINTF(sql_query_string, sizeof(sql_query_string), "SELECT * FROM mail_rule_tbl WHERE account_id = %d AND rule_id = %d", account_id, rule_id); + + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_prepare_v2(local_db_handle, sql_query_string, strlen(sql_query_string), &hStmt, NULL), rc); + EM_DEBUG_DB_EXEC((SQLITE_OK != rc), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) sqlite3_prepare fail:(%d) %s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + /* rc = sqlite3_step(hStmt); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_step(hStmt), rc); + EM_DEBUG_DB_EXEC((rc != SQLITE_ROW && rc != SQLITE_DONE), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("sqlite3_step fail:%d", rc)); + + if (rc == SQLITE_DONE) { + EM_DEBUG_EXCEPTION(" no matched rule found..."); + error = EM_STORAGE_ERROR_RULE_NOT_FOUND; + goto FINISH_OFF; + } + + if (!(p_data_tbl = (emf_mail_rule_tbl_t*)malloc(sizeof(emf_mail_rule_tbl_t)))) { + EM_DEBUG_EXCEPTION(" malloc failed..."); + error = EM_STORAGE_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + memset(p_data_tbl, 0x00, sizeof(emf_mail_rule_tbl_t)); + _getStmtFieldDataInt(hStmt, &(p_data_tbl->account_id), ACCOUNT_ID_IDX_IN_MAIL_RULE_TBL); + _getStmtFieldDataInt(hStmt, &(p_data_tbl->rule_id), RULE_ID_IDX_IN_MAIL_RULE_TBL); + _getStmtFieldDataInt(hStmt, &(p_data_tbl->type), TYPE_IDX_IN_MAIL_RULE_TBL); + _getStmtFieldDataString(hStmt, &(p_data_tbl->value), 0, VALUE_IDX_IN_MAIL_RULE_TBL); + _getStmtFieldDataInt(hStmt, &(p_data_tbl->action_type), ACTION_TYPE_IDX_IN_MAIL_RULE_TBL); + _getStmtFieldDataString(hStmt, &(p_data_tbl->dest_mailbox), 0, DEST_MAILBOX_IDX_IN_MAIL_RULE_TBL); + _getStmtFieldDataInt(hStmt, &(p_data_tbl->flag1), FLAG1_IDX_IN_MAIL_RULE_TBL); + _getStmtFieldDataInt(hStmt, &(p_data_tbl->flag2), FLAG2_IDX_IN_MAIL_RULE_TBL); + + ret = true; + +FINISH_OFF: + if (ret == true) + *rule = p_data_tbl; + else if (p_data_tbl != NULL) + em_storage_free_rule(&p_data_tbl, 1, NULL); + + if (hStmt != NULL) { + EM_DEBUG_LOG(" before sqlite3_finalize hStmt = %p", hStmt); + + rc = sqlite3_finalize(hStmt); + if (rc != SQLITE_OK) { + EM_DEBUG_LOG(" sqlite3_finalize failed - %d", rc); + + error = EM_STORAGE_ERROR_DB_FAILURE; + } + } + + + + EM_STORAGE_FINISH_READ_TRANSACTION(transaction); + _DISCONNECT_DB; + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API int em_storage_change_rule(int account_id, int rule_id, emf_mail_rule_tbl_t* new_rule, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id[%d], rule_id[%d], new_rule[%p], transaction[%d], err_code[%p]", account_id, rule_id, new_rule, transaction, err_code); + + if (account_id != ALL_ACCOUNT || !new_rule) { /* only global rule supported. */ + EM_DEBUG_EXCEPTION(" account_id[%d], rule_id[%d], new_rule[%p]", account_id, rule_id, new_rule); + + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + int rc, ret = false; + int error = EM_STORAGE_ERROR_NONE; + + DB_STMT hStmt = NULL; + char sql_query_string[QUERY_SIZE] = {0, }; + sqlite3 *local_db_handle = em_storage_get_db_connection(); + EM_STORAGE_START_WRITE_TRANSACTION(transaction, error); + + SNPRINTF(sql_query_string, sizeof(sql_query_string), + "UPDATE mail_rule_tbl SET" + " type = ?" + ", value = ?" + ", action_type = ?" + ", dest_mailbox = ?" + ", flag1 = ?" + ", flag2 = ?" + " WHERE account_id = ?" + " AND rule_id = ?"); + + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_prepare_v2(local_db_handle, sql_query_string, strlen(sql_query_string), &hStmt, NULL), rc); + EM_DEBUG_LOG(" Before sqlite3_prepare hStmt = %p", hStmt); + EM_DEBUG_DB_EXEC((SQLITE_OK != rc), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) sqlite3_prepare fail:(%d) %s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + int i = 0; + + _bindStmtFieldDataInt(hStmt, i++, new_rule->type); + _bindStmtFieldDataString(hStmt, i++, (char *)new_rule->value, 0, VALUE_LEN_IN_MAIL_RULE_TBL); + _bindStmtFieldDataInt(hStmt, i++, new_rule->action_type); + _bindStmtFieldDataString(hStmt, i++, (char *)new_rule->dest_mailbox, 0, DEST_MAILBOX_LEN_IN_MAIL_RULE_TBL); + _bindStmtFieldDataInt(hStmt, i++, new_rule->flag1); + _bindStmtFieldDataInt(hStmt, i++, new_rule->flag2); + _bindStmtFieldDataInt(hStmt, i++, account_id); + _bindStmtFieldDataInt(hStmt, i++, rule_id); + + /* rc = sqlite3_step(hStmt); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_step(hStmt), rc); + EM_DEBUG_DB_EXEC((rc != SQLITE_ROW && rc != SQLITE_DONE), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("sqlite3_step fail:%d", rc)); + + ret = true; + +FINISH_OFF: + if (hStmt != NULL) { + EM_DEBUG_LOG(" Before sqlite3_finalize hStmt = %p", hStmt); + + rc = sqlite3_finalize(hStmt); + if (rc != SQLITE_OK) { + EM_DEBUG_LOG(" sqlite3_finalize failed - %d", rc); + + error = EM_STORAGE_ERROR_DB_FAILURE; + } + } + + EM_STORAGE_FINISH_WRITE_TRANSACTION(transaction, ret, error); + _DISCONNECT_DB; + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API int em_storage_find_rule(emf_mail_rule_tbl_t* rule, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("rule[%p], transaction[%d], err_code[%p]", rule, transaction, err_code); + + if (!rule || rule->account_id != ALL_ACCOUNT) { /* only global rule supported. */ + if (rule != NULL) + EM_DEBUG_EXCEPTION(" rule->account_id[%d]", rule->account_id); + + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + DB_STMT hStmt = NULL; + char sql_query_string[QUERY_SIZE] = {0, }; + + int error = EM_STORAGE_ERROR_NONE; + int rc, ret = false; + + sqlite3 *local_db_handle = em_storage_get_db_connection(); + EM_STORAGE_START_READ_TRANSACTION(transaction); + + SNPRINTF(sql_query_string, sizeof(sql_query_string), + "SELECT rule_id FROM mail_rule_tbl WHERE type = %d AND UPPER(value) = UPPER('%s')", + rule->type, rule->value); + + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_prepare_v2(local_db_handle, sql_query_string, strlen(sql_query_string), &hStmt, NULL), rc); + EM_DEBUG_DB_EXEC((SQLITE_OK != rc), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) sqlite3_prepare fail:(%d) %s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + /* rc = sqlite3_step(hStmt); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_step(hStmt), rc); + EM_DEBUG_DB_EXEC((rc != SQLITE_ROW && rc != SQLITE_DONE), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("sqlite3_step fail:%d", rc)); + + if (rc == SQLITE_DONE) { + EM_DEBUG_EXCEPTION(" no matched rule found..."); + error = EM_STORAGE_ERROR_RULE_NOT_FOUND; + goto FINISH_OFF; + } + + + ret = true; + +FINISH_OFF: + if (hStmt != NULL) { + EM_DEBUG_LOG("before sqlite3_finalize hStmt = %p", hStmt); + + rc = sqlite3_finalize(hStmt); + if (rc != SQLITE_OK) { + EM_DEBUG_EXCEPTION(" sqlite3_finalize failed - %d", rc); + error = EM_STORAGE_ERROR_DB_FAILURE; + } + } + + + EM_STORAGE_FINISH_READ_TRANSACTION(transaction); + _DISCONNECT_DB; + + if (err_code) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API int em_storage_add_rule(emf_mail_rule_tbl_t* rule, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("rule[%p], transaction[%d], err_code[%p]", rule, transaction, err_code); + + if (!rule || rule->account_id != ALL_ACCOUNT) { /* only global rule supported. */ + if (rule != NULL) + EM_DEBUG_EXCEPTION(" rule->account_id[%d]", rule->account_id); + + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + int rc, rc_2, ret = false; + int error = EM_STORAGE_ERROR_NONE; + DB_STMT hStmt = NULL; + char sql_query_string[QUERY_SIZE] = {0, }; + + + sqlite3 *local_db_handle = em_storage_get_db_connection(); + + EM_STORAGE_START_WRITE_TRANSACTION(transaction, error); + + char *sql; + char **result; + sql = "SELECT max(rowid) FROM mail_rule_tbl;"; + /* rc = sqlite3_get_table(local_db_handle, sql, &result, NULL, NULL, NULL); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_get_table(local_db_handle, sql, &result, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;sqlite3_free_table(result);goto FINISH_OFF; }, + ("SQL(%s) sqlite3_get_table fail:%d -%s", sql, rc, sqlite3_errmsg(local_db_handle))); + + if (NULL==result[1]) + rc = 1; + else + rc = atoi(result[1])+1; + sqlite3_free_table(result); + + SNPRINTF(sql_query_string, sizeof(sql_query_string), + "INSERT INTO mail_rule_tbl VALUES " + "( ?" /* account id */ + ", ?" /* rule_id */ + ", ?" /* type */ + ", ?" /* value */ + ", ?" /* action_type */ + ", ?" /* dest_mailbox */ + ", ?" /* flag1 */ + ", ?)"); /* flag2 */ + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_prepare_v2(local_db_handle, sql_query_string, strlen(sql_query_string), &hStmt, NULL), rc_2); + if (rc_2 != SQLITE_OK) { + EM_DEBUG_EXCEPTION("SQL(%s) sqlite3_prepare fail:(%d) %s", sql_query_string, rc_2, sqlite3_errmsg(local_db_handle)); + error = EM_STORAGE_ERROR_DB_FAILURE; + goto FINISH_OFF; + } + + _bindStmtFieldDataInt(hStmt, ACCOUNT_ID_IDX_IN_MAIL_RULE_TBL, rule->account_id); + _bindStmtFieldDataInt(hStmt, RULE_ID_IDX_IN_MAIL_RULE_TBL, rc); + _bindStmtFieldDataInt(hStmt, TYPE_IDX_IN_MAIL_RULE_TBL, rule->type); + _bindStmtFieldDataString(hStmt, VALUE_IDX_IN_MAIL_RULE_TBL, (char *)rule->value, 0, VALUE_LEN_IN_MAIL_RULE_TBL); + _bindStmtFieldDataInt(hStmt, ACTION_TYPE_IDX_IN_MAIL_RULE_TBL, rule->action_type); + _bindStmtFieldDataString(hStmt, DEST_MAILBOX_IDX_IN_MAIL_RULE_TBL, (char *)rule->dest_mailbox, 0, DEST_MAILBOX_LEN_IN_MAIL_RULE_TBL); + _bindStmtFieldDataInt(hStmt, FLAG1_IDX_IN_MAIL_RULE_TBL, rule->flag1); + _bindStmtFieldDataInt(hStmt, FLAG2_IDX_IN_MAIL_RULE_TBL, rule->flag2); + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_step(hStmt), rc); + EM_DEBUG_DB_EXEC((rc != SQLITE_ROW && rc != SQLITE_DONE), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("sqlite3_step fail:%d", rc)); + + ret = true; + +FINISH_OFF: + if (hStmt != NULL) { + EM_DEBUG_LOG(" Before sqlite3_finalize hStmt = %p", hStmt); + + rc = sqlite3_finalize(hStmt); + if (rc != SQLITE_OK) { + EM_DEBUG_LOG(" sqlite3_finalize failed - %d", rc); + + error = EM_STORAGE_ERROR_DB_FAILURE; + } + } + + EM_STORAGE_FINISH_WRITE_TRANSACTION(transaction, ret, error); + _DISCONNECT_DB; + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API int em_storage_delete_rule(int account_id, int rule_id, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id[%d], rule_id[%d], transaction[%d], err_code[%p]", account_id, rule_id, transaction, err_code); + + if (account_id != ALL_ACCOUNT) { /* only global rule supported. */ + EM_DEBUG_EXCEPTION(" account_id[%d], rule_id[%d]", account_id, rule_id); + + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + int rc, ret = false; + int error = EM_STORAGE_ERROR_NONE; + char sql_query_string[QUERY_SIZE] = {0, }; + + sqlite3 *local_db_handle = em_storage_get_db_connection(); + EM_STORAGE_START_WRITE_TRANSACTION(transaction, error); + + SNPRINTF(sql_query_string, sizeof(sql_query_string), "DELETE FROM mail_rule_tbl WHERE account_id = %d AND rule_id = %d", account_id, rule_id); + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, sql_query_string, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) exec fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + rc = sqlite3_changes(local_db_handle); + if (rc == 0) { + EM_DEBUG_EXCEPTION(" no matched rule found..."); + + error = EM_STORAGE_ERROR_RULE_NOT_FOUND; + goto FINISH_OFF; + } + + ret = true; + +FINISH_OFF: + EM_STORAGE_FINISH_WRITE_TRANSACTION(transaction, ret, error); + _DISCONNECT_DB; + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API int em_storage_free_rule(emf_mail_rule_tbl_t** rule_list, int count, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("rule_list[%p], conut[%d], err_code[%p]", rule_list, count, err_code); + + int ret = false; + int error = EM_STORAGE_ERROR_NONE; + + if (count > 0) { + if (!rule_list || !*rule_list) { + EM_DEBUG_EXCEPTION(" rule_list[%p], conut[%d]", rule_list, count); + + error = EM_STORAGE_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + emf_mail_rule_tbl_t* p = *rule_list; + int i = 0; + + for (; i < count; i++) { + EM_SAFE_FREE(p[i].value); + EM_SAFE_FREE(p[i].dest_mailbox); + } + + EM_SAFE_FREE(p); *rule_list = NULL; + } + +FINISH_OFF: + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API int em_storage_get_mail_count(int account_id, const char *mailbox_name, int *total, int *unseen, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id[%d], mailbox_name[%s], total[%p], unseen[%p], transaction[%d], err_code[%p]", account_id, mailbox_name, total, unseen, transaction, err_code); + + if (!total && !unseen) { /* TODO: confirm me */ + EM_DEBUG_EXCEPTION(" accoun_id[%d], mailbox_name[%s], total[%p], unseen[%p]", account_id, mailbox_name, total, unseen); + + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + int rc = -1, ret = false; + int error = EM_STORAGE_ERROR_NONE; + DB_STMT hStmt = NULL; + char sql_query_string[QUERY_SIZE] = {0, }; + char err_msg[1024]; + + + memset(&sql_query_string, 0x00, sizeof(sql_query_string)); + sqlite3 *local_db_handle = em_storage_get_db_connection(); + EM_STORAGE_START_READ_TRANSACTION(transaction); + + if (total) { + SNPRINTF(sql_query_string, sizeof(sql_query_string), "SELECT COUNT(*) FROM mail_tbl"); + + if (account_id != ALL_ACCOUNT) { + SNPRINTF(sql_query_string + strlen(sql_query_string), sizeof(sql_query_string)-(strlen(sql_query_string)+1), " WHERE account_id = %d", account_id); + if (mailbox_name) + SNPRINTF(sql_query_string + strlen(sql_query_string), sizeof(sql_query_string)-(strlen(sql_query_string)+1), " AND UPPER(mailbox_name) = UPPER('%s')", mailbox_name); + } + else if (mailbox_name) + SNPRINTF(sql_query_string + strlen(sql_query_string), sizeof(sql_query_string)-(strlen(sql_query_string)+1), " WHERE UPPER(mailbox_name) = UPPER('%s')", mailbox_name); + +#ifdef USE_GET_RECORD_COUNT_API + char **result; + /* rc = sqlite3_get_table(local_db_handle, sql_query_string, &result, NULL, NULL, NULL); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_get_table(local_db_handle, sql_query_string, &result, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;sqlite3_free_table(result);goto FINISH_OFF2; }, + ("SQL(%s) sqlite3_get_table fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + *total = atoi(result[1]); + sqlite3_free_table(result); +#else + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_prepare_v2(local_db_handle, sql_query_string, strlen(sql_query_string), &hStmt, NULL), rc); + EM_DEBUG_DB_EXEC((SQLITE_OK != rc), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF2; }, + ("SQL(%s) sqlite3_prepare fail:(%d) %s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + /* rc = sqlite3_step(hStmt); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_step(hStmt), rc); + EM_DEBUG_DB_EXEC((rc != SQLITE_ROW && rc != SQLITE_DONE), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF2; }, + ("sqlite3_step fail:%d", rc)); + _getStmtFieldDataInt(hStmt, total, 0); +#endif /* USE_GET_RECORD_COUNT_API */ + } + + if (unseen) { + SNPRINTF(sql_query_string, sizeof(sql_query_string), "SELECT COUNT(*) FROM mail_tbl WHERE flags_seen_field = 0"); /* fSEEN = 0x01 */ + + if (account_id != ALL_ACCOUNT) + SNPRINTF(sql_query_string + strlen(sql_query_string), sizeof(sql_query_string)-(strlen(sql_query_string)+1), " AND account_id = %d", account_id); + + if (mailbox_name) + SNPRINTF(sql_query_string + strlen(sql_query_string), sizeof(sql_query_string)-(strlen(sql_query_string)+1), " AND mailbox_name = '%s'", mailbox_name); + else + SNPRINTF(sql_query_string + strlen(sql_query_string), sizeof(sql_query_string)-(strlen(sql_query_string)+1), " AND mailbox_type NOT IN (3, 5)"); + + char **result; + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_get_table(local_db_handle, sql_query_string, &result, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;sqlite3_free_table(result);goto FINISH_OFF; }, + ("SQL(%s) sqlite3_get_table fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + *unseen = atoi(result[1]); + sqlite3_free_table(result); + + } +FINISH_OFF: + ret = true; + +FINISH_OFF2: + +#ifndef USE_PREPARED_QUERY_ + if (hStmt != NULL) { + rc = sqlite3_finalize(hStmt); + if (rc != SQLITE_OK) { + EM_DEBUG_LOG(" EDBStmtClearRow failed - %d: %s", rc, err_msg); + error = EM_STORAGE_ERROR_DB_FAILURE; + } + } +#endif + + EM_STORAGE_FINISH_READ_TRANSACTION(transaction); + _DISCONNECT_DB; + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API int em_storage_get_mail_field_by_id(int mail_id, int type, emf_mail_tbl_t** mail, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("mail_id[%d], type[%d], mail[%p], transaction[%d], err_code[%p]", mail_id, type, mail, transaction, err_code); + + if (mail_id <= 0 || !mail) { + EM_DEBUG_EXCEPTION("mail_id[%d], mail[%p]", mail_id, mail); + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + emf_mail_tbl_t* p_data_tbl = (emf_mail_tbl_t*)malloc(sizeof(emf_mail_tbl_t)); + + if (p_data_tbl == NULL) { + EM_DEBUG_EXCEPTION("malloc failed..."); + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_OUT_OF_MEMORY; + return false; + } + + memset(p_data_tbl, 0x00, sizeof(emf_mail_tbl_t)); + DB_STMT hStmt = NULL; + char sql_query_string[QUERY_SIZE] = {0, }; + + int rc, ret = false; + int error = EM_STORAGE_ERROR_NONE; + + sqlite3 *local_db_handle = em_storage_get_db_connection(); + EM_STORAGE_START_READ_TRANSACTION(transaction); + + switch (type) { + case RETRIEVE_SUMMARY: + SNPRINTF(sql_query_string, sizeof(sql_query_string), + "SELECT account_id, mail_id, mailbox_name, server_mail_status, server_mailbox_name, server_mail_id, file_path_plain, file_path_html, flags_seen_field, save_status, lock_status, thread_id, thread_item_count FROM mail_tbl WHERE mail_id = %d", mail_id); + break; + + case RETRIEVE_FIELDS_FOR_DELETE: + SNPRINTF(sql_query_string, sizeof(sql_query_string), + "SELECT account_id, mail_id, server_mail_status, server_mailbox_name, server_mail_id FROM mail_tbl WHERE mail_id = %d", mail_id); + break; + + case RETRIEVE_ACCOUNT: + SNPRINTF(sql_query_string, sizeof(sql_query_string), + "SELECT account_id FROM mail_tbl WHERE mail_id = %d", mail_id); + break; + + case RETRIEVE_FLAG: + SNPRINTF(sql_query_string, sizeof(sql_query_string), + "SELECT account_id, mailbox_name, flags_seen_field, thread_id FROM mail_tbl WHERE mail_id = %d", mail_id); + break; + + default : + EM_DEBUG_EXCEPTION("EM_STORAGE_ERROR_INVALID_PARAM : type [%d]", type); + error = EM_STORAGE_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + EM_DEBUG_LOG("Query [%s]", sql_query_string); + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_prepare_v2(local_db_handle, sql_query_string, strlen(sql_query_string), &hStmt, NULL), rc); + EM_DEBUG_DB_EXEC((SQLITE_OK != rc), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) sqlite3_prepare fail:(%d) %s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + /* rc = sqlite3_step(hStmt); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_step(hStmt), rc); + EM_DEBUG_DB_EXEC((rc != SQLITE_ROW && rc != SQLITE_DONE), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("sqlite3_step fail:%d", rc)); + + if (rc == SQLITE_DONE) { + EM_DEBUG_EXCEPTION("no matched mail found..."); + error = EM_STORAGE_ERROR_MAIL_NOT_FOUND; + goto FINISH_OFF; + } + switch (type) { + case RETRIEVE_SUMMARY: + _getStmtFieldDataInt(hStmt, &(p_data_tbl->account_id), 0); + _getStmtFieldDataInt(hStmt, &(p_data_tbl->mail_id), 1); + _getStmtFieldDataString(hStmt, &(p_data_tbl->mailbox_name), 0, 2); + _getStmtFieldDataInt(hStmt, &(p_data_tbl->server_mail_status), 3); + _getStmtFieldDataString(hStmt, &(p_data_tbl->server_mailbox_name), 0, 4); + _getStmtFieldDataString(hStmt, &(p_data_tbl->server_mail_id), 0, 5); + _getStmtFieldDataString(hStmt, &(p_data_tbl->file_path_plain), 0, 6); + _getStmtFieldDataString(hStmt, &(p_data_tbl->file_path_html), 0, 7); + _getStmtFieldDataChar(hStmt, &(p_data_tbl->flags_seen_field), 8); + _getStmtFieldDataInt(hStmt, &(p_data_tbl->save_status), 9); + _getStmtFieldDataInt(hStmt, &(p_data_tbl->lock_status), 10); + _getStmtFieldDataInt(hStmt, &(p_data_tbl->thread_id), 11); + _getStmtFieldDataInt(hStmt, &(p_data_tbl->thread_item_count), 12); + break; + + case RETRIEVE_FIELDS_FOR_DELETE: + _getStmtFieldDataInt(hStmt, &(p_data_tbl->account_id), 0); + _getStmtFieldDataInt(hStmt, &(p_data_tbl->mail_id), 1); + _getStmtFieldDataInt(hStmt, &(p_data_tbl->server_mail_status), 2); + _getStmtFieldDataString(hStmt, &(p_data_tbl->server_mailbox_name), 0, 3); + _getStmtFieldDataString(hStmt, &(p_data_tbl->server_mail_id), 0, 4); + break; + + case RETRIEVE_ACCOUNT: + _getStmtFieldDataInt(hStmt, &(p_data_tbl->account_id), 0); + break; + + case RETRIEVE_FLAG: + _getStmtFieldDataInt(hStmt, &(p_data_tbl->account_id), 0); + _getStmtFieldDataString(hStmt, &(p_data_tbl->mailbox_name), 0, 1); + _getStmtFieldDataChar(hStmt, &(p_data_tbl->flags_seen_field), 2); + _getStmtFieldDataInt(hStmt, &(p_data_tbl->thread_id), 3); + break; + } + + ret = true; + +FINISH_OFF: + if (ret == true) + *mail = p_data_tbl; + else if (p_data_tbl != NULL) + em_storage_free_mail(&p_data_tbl, 1, NULL); + + if (hStmt != NULL) { + EM_DEBUG_LOG("Before sqlite3_finalize hStmt = %p", hStmt); + + rc = sqlite3_finalize(hStmt); + if (rc != SQLITE_OK) { + EM_DEBUG_EXCEPTION("sqlite3_finalize failed - %d", rc); + error = EM_STORAGE_ERROR_DB_FAILURE; + } + } + + + EM_STORAGE_FINISH_READ_TRANSACTION(transaction); + _DISCONNECT_DB; + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API int em_storage_get_mail_field_by_multiple_mail_id(int mail_ids[], int number_of_mails, int type, emf_mail_tbl_t** mail, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("mail_ids[%p], number_of_mails [%d], type[%d], mail[%p], transaction[%d], err_code[%p]", mail_ids, number_of_mails, type, mail, transaction, err_code); + + if (number_of_mails <= 0 || !mail_ids) { + EM_DEBUG_EXCEPTION("EM_STORAGE_ERROR_INVALID_PARAM"); + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + emf_mail_tbl_t* p_data_tbl = (emf_mail_tbl_t*)em_core_malloc(sizeof(emf_mail_tbl_t) * number_of_mails); + + if (p_data_tbl == NULL) { + EM_DEBUG_EXCEPTION("malloc failed..."); + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_OUT_OF_MEMORY; + return false; + } + + DB_STMT hStmt = NULL; + int ret = false; + int error = EM_STORAGE_ERROR_NONE; + int i = 0, item_count = 0, rc = -1, field_count, col_index, cur_sql_query_string = 0; + char **result = NULL; + char sql_query_string[QUERY_SIZE] = {0, }; + + sqlite3 *local_db_handle = em_storage_get_db_connection(); + EM_STORAGE_START_READ_TRANSACTION(transaction); + + switch (type) { + case RETRIEVE_SUMMARY: + cur_sql_query_string = SNPRINTF(sql_query_string, sizeof(sql_query_string), + "SELECT account_id, mail_id, mailbox_name, server_mail_status, server_mailbox_name, server_mail_id, file_path_plain, file_path_html, flags_seen_field, save_status, lock_status, thread_id, thread_item_count FROM mail_tbl WHERE mail_id in ("); + field_count = 13; + break; + + case RETRIEVE_FIELDS_FOR_DELETE: + cur_sql_query_string = SNPRINTF(sql_query_string, sizeof(sql_query_string), + "SELECT account_id, mail_id, server_mail_status, server_mailbox_name, server_mail_id FROM mail_tbl WHERE mail_id in ("); + field_count = 5; + break; + + case RETRIEVE_ACCOUNT: + cur_sql_query_string = SNPRINTF(sql_query_string, sizeof(sql_query_string), + "SELECT account_id FROM mail_tbl WHERE mail_id in ("); + field_count = 1; + break; + + case RETRIEVE_FLAG: + cur_sql_query_string = SNPRINTF(sql_query_string, sizeof(sql_query_string), + "SELECT account_id, mailbox_name, flags_seen_field, thread_id FROM mail_tbl WHERE mail_id in ("); + field_count = 4; + break; + + default : + EM_DEBUG_EXCEPTION("EM_STORAGE_ERROR_INVALID_PARAM : type [%d]", type); + error = EM_STORAGE_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + for(i = 0; i < number_of_mails; i++) + cur_sql_query_string += SNPRINTF_OFFSET(sql_query_string, cur_sql_query_string, QUERY_SIZE, "%d,", mail_ids[i]); + sql_query_string[strlen(sql_query_string) - 1] = ')'; + + EM_DEBUG_LOG("Query [%s], Length [%d]", sql_query_string, strlen(sql_query_string)); + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_get_table(local_db_handle, sql_query_string, &result, &item_count, 0, NULL), rc); + EM_DEBUG_DB_EXEC((SQLITE_OK != rc && -1 != rc), {error = EM_STORAGE_ERROR_DB_FAILURE;sqlite3_free_table(result);goto FINISH_OFF; }, + ("SQL(%s) sqlite3_get_table fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + if (rc == SQLITE_DONE) { + EM_DEBUG_EXCEPTION("no matched mail found..."); + error = EM_STORAGE_ERROR_MAIL_NOT_FOUND; + goto FINISH_OFF; + } + + EM_DEBUG_LOG("item_count [%d]", item_count); + + if(number_of_mails != item_count) { + EM_DEBUG_EXCEPTION("Can't find all emails"); + /* error = EM_STORAGE_ERROR_MAIL_NOT_FOUND; + goto FINISH_OFF; */ /* removed temporarily */ + } + + col_index = field_count; + + for(i = 0; i < item_count; i++) { + switch (type) { + case RETRIEVE_SUMMARY: + _getTableFieldDataInt(result, &(p_data_tbl[i].account_id), col_index++); + _getTableFieldDataInt(result, &(p_data_tbl[i].mail_id), col_index++); + _getTableFieldDataString(result, &(p_data_tbl[i].mailbox_name), 0, col_index++); + _getTableFieldDataInt(result, &(p_data_tbl[i].server_mail_status), col_index++); + _getTableFieldDataString(result, &(p_data_tbl[i].server_mailbox_name), 0, col_index++); + _getTableFieldDataString(result, &(p_data_tbl[i].server_mail_id), 0, col_index++); + _getTableFieldDataString(result, &(p_data_tbl[i].file_path_plain), 0, col_index++); + _getTableFieldDataString(result, &(p_data_tbl[i].file_path_html), 0, col_index++); + _getTableFieldDataChar(result, &(p_data_tbl[i].flags_seen_field), col_index++); + _getTableFieldDataInt(result, &(p_data_tbl[i].save_status), col_index++); + _getTableFieldDataInt(result, &(p_data_tbl[i].lock_status), col_index++); + _getTableFieldDataInt(result, &(p_data_tbl[i].thread_id), col_index++); + _getTableFieldDataInt(result, &(p_data_tbl[i].thread_item_count), col_index++); + break; + + case RETRIEVE_FIELDS_FOR_DELETE: + _getTableFieldDataInt(result, &(p_data_tbl[i].account_id), col_index++); + _getTableFieldDataInt(result, &(p_data_tbl[i].mail_id), col_index++); + _getTableFieldDataInt(result, &(p_data_tbl[i].server_mail_status), col_index++); + _getTableFieldDataString(result, &(p_data_tbl[i].server_mailbox_name), 0, col_index++); + _getTableFieldDataString(result, &(p_data_tbl[i].server_mail_id), 0, col_index++); + break; + + case RETRIEVE_ACCOUNT: + _getTableFieldDataInt(result, &(p_data_tbl[i].account_id), col_index++); + break; + + case RETRIEVE_FLAG: + _getTableFieldDataInt(result, &(p_data_tbl[i].account_id), col_index++); + _getTableFieldDataString(result, &(p_data_tbl[i].mailbox_name), 0, col_index++); + _getTableFieldDataChar(result, &(p_data_tbl[i].flags_seen_field), col_index++); + _getTableFieldDataInt(result, &(p_data_tbl[i].thread_id), col_index++); + break; + } + } + + sqlite3_free_table(result); + + ret = true; + +FINISH_OFF: + if (ret == true) + *mail = p_data_tbl; + else if (p_data_tbl != NULL) + em_storage_free_mail(&p_data_tbl, 1, NULL); + + if (hStmt != NULL) { + EM_DEBUG_LOG("Before sqlite3_finalize hStmt = %p", hStmt); + + rc = sqlite3_finalize(hStmt); + if (rc != SQLITE_OK) { + EM_DEBUG_EXCEPTION("sqlite3_finalize failed - %d", rc); + error = EM_STORAGE_ERROR_DB_FAILURE; + } + } + + EM_STORAGE_FINISH_READ_TRANSACTION(transaction); + _DISCONNECT_DB; + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API int em_storage_get_mail_by_id(int mail_id, emf_mail_tbl_t** mail, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("mail_id[%d], mail[%p], transaction[%d], err_code[%p]", mail_id, mail, transaction, err_code); + + if (mail_id <= 0 || !mail) { + EM_DEBUG_EXCEPTION("mail_id[%d], mail[%p]", mail_id, mail); + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + int ret = false, error = EM_STORAGE_ERROR_NONE, count; + char conditional_clause[QUERY_SIZE] = {0, }; + emf_mail_tbl_t* p_data_tbl = NULL; + + SNPRINTF(conditional_clause, QUERY_SIZE, "WHERE mail_id = %d", mail_id); + EM_DEBUG_LOG("query = [%s]", conditional_clause); + + if(!em_storage_query_mail_tbl(conditional_clause, transaction, &p_data_tbl, &count, &error)) { + EM_DEBUG_EXCEPTION("em_storage_query_mail_tbl [%d]", error); + goto FINISH_OFF; + } + + ret = true; + +FINISH_OFF: + if (ret == true) + *mail = p_data_tbl; + else if (p_data_tbl != NULL) + em_storage_free_mail(&p_data_tbl, 1, &error); + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API int em_storage_mail_search_start(emf_mail_search_t* search, int account_id, char *mailbox_name, int sorting, int *search_handle, int *searched, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("search[%p], account_id[%d], mailbox_name[%p], sorting[%d], search_handle[%p], searched[%p], transaction[%d], err_code[%p]", search, account_id, mailbox_name, sorting, search_handle, searched, transaction, err_code); + + if (!search_handle || !searched) { + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + EM_DEBUG_EXCEPTION("EM_STORAGE_ERROR_INVALID_PARAM"); + EM_DEBUG_FUNC_END("false"); + return false; + } + + emf_mail_search_t* p = search; + int error = EM_STORAGE_ERROR_NONE; + DB_STMT hStmt = NULL; + char sql_query_string[QUERY_SIZE] = {0, }; + int rc, ret = false; + int and = false, mail_count = 0; + + sqlite3 *local_db_handle = em_storage_get_db_connection(); + EM_STORAGE_START_READ_TRANSACTION(transaction); + + SNPRINTF(sql_query_string, sizeof(sql_query_string), "SELECT * FROM mail_tbl"); + + if (account_id != ALL_ACCOUNT) { + SNPRINTF(sql_query_string + strlen(sql_query_string), sizeof(sql_query_string)-(strlen(sql_query_string)+1), " WHERE account_id = %d", account_id); + and = true; + } + + if (mailbox_name) { + SNPRINTF(sql_query_string + strlen(sql_query_string), sizeof(sql_query_string)-(strlen(sql_query_string)+1), " %s mailbox_name = '%s'", and ? "AND" : "WHERE", mailbox_name); + and = true; + } + + while (p) { + + if (p->key_type) { + if (!strncmp(p->key_type, "subject", strlen("subject"))) { + SNPRINTF(sql_query_string + strlen(sql_query_string), sizeof(sql_query_string)-(strlen(sql_query_string)+1), " %s subject LIKE '%%%%%s%%%%'", and ? "AND" : "WHERE", p->key_value); + and = true; + } + else if (!strncmp(p->key_type, "full_address_from", strlen("full_address_from"))) { + SNPRINTF(sql_query_string + strlen(sql_query_string), sizeof(sql_query_string)-(strlen(sql_query_string)+1), " %s full_address_from LIKE '%%%%%s%%%%'", and ? "AND" : "WHERE", p->key_value); + and = true; + } + else if (!strncmp(p->key_type, "full_address_to", strlen("full_address_to"))) { + SNPRINTF(sql_query_string + strlen(sql_query_string), sizeof(sql_query_string)-(strlen(sql_query_string)+1), " %s full_address_to LIKE '%%%%%s%%%%'", and ? "AND" : "WHERE", p->key_value); + and = true; + } + else if (!strncmp(p->key_type, "email_address", strlen("email_address"))) { + SNPRINTF(sql_query_string + strlen(sql_query_string), sizeof(sql_query_string)-(strlen(sql_query_string)+1), " %s email_address_sender = '%s' OR email_address_recipient = '%s'", and ? "AND" : "WHERE", p->key_value, p->key_value); + and = true; + } + p = p->next; + } + } + + if (sorting) + SNPRINTF(sql_query_string + strlen(sql_query_string), sizeof(sql_query_string)-(strlen(sql_query_string)+1), " ORDER BY date_time"); + + EM_DEBUG_LOG("sql_query_string [%s]", sql_query_string); + + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_prepare_v2(local_db_handle, sql_query_string, strlen(sql_query_string), &hStmt, NULL), rc); + EM_DEBUG_DB_EXEC((SQLITE_OK != rc), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) sqlite3_prepare fail:(%d) %s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + /* rc = sqlite3_step(hStmt); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_step(hStmt), rc); + EM_DEBUG_DB_EXEC((rc != SQLITE_ROW && rc != SQLITE_DONE), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("sqlite3_step fail:%d", rc)); + + char **result; + /* rc = sqlite3_get_table(local_db_handle, sql_query_string, &result, NULL, NULL, NULL); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_get_table(local_db_handle, sql_query_string, &result, &mail_count, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;sqlite3_free_table(result);goto FINISH_OFF; }, + ("SQL(%s) sqlite3_get_table fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + sqlite3_free_table(result); + + ret = true; + +FINISH_OFF: + if (ret == true) { + *search_handle = (int)hStmt; + *searched = mail_count; + EM_DEBUG_LOG("mail_count [%d]", mail_count); + } + else { + if (hStmt != NULL) { + rc = sqlite3_finalize(hStmt); + if (rc != SQLITE_OK) { + EM_DEBUG_EXCEPTION("sqlite3_finalize failed - %d", rc); + error = EM_STORAGE_ERROR_DB_FAILURE; + } + } + + EM_STORAGE_FINISH_READ_TRANSACTION(transaction); + _DISCONNECT_DB; + } + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API int em_storage_mail_search_result(int search_handle, emf_mail_field_type_t type, void** data, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("search_handle[%d], type[%d], data[%p], transaction[%d], err_code[%p]", search_handle, type, data, transaction, err_code); + + if (search_handle < 0 || !data) { + EM_DEBUG_EXCEPTION(" search_handle[%d], type[%d], data[%p]", search_handle, type, data); + + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + emf_mail_tbl_t* p_data_tbl = NULL; + DB_STMT hStmt = (DB_STMT)search_handle; + int rc, ret = false; + int error = EM_STORAGE_ERROR_NONE; + + switch (type) { + case RETRIEVE_ID: + _getStmtFieldDataInt(hStmt, (int *)data, MAIL_ID_IDX_IN_MAIL_TBL); + break; + + case RETRIEVE_ENVELOPE: + case RETRIEVE_ALL: + if (!(p_data_tbl = em_core_malloc(sizeof(emf_mail_tbl_t)))) { + EM_DEBUG_EXCEPTION(" em_core_malloc failed..."); + + error = EM_STORAGE_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + _getStmtFieldDataInt(hStmt, &(p_data_tbl->mail_id), MAIL_ID_IDX_IN_MAIL_TBL); + _getStmtFieldDataInt(hStmt, &(p_data_tbl->account_id), ACCOUNT_ID_IDX_IN_MAIL_TBL); + _getStmtFieldDataString(hStmt, &(p_data_tbl->mailbox_name), 0, MAILBOX_NAME_IDX_IN_MAIL_TBL); + _getStmtFieldDataInt(hStmt, &(p_data_tbl->mail_size), MAIL_SIZE_IDX_IN_MAIL_TBL); + _getStmtFieldDataString(hStmt, &(p_data_tbl->server_mail_id), 0, SERVER_MAIL_ID_IDX_IN_MAIL_TBL); + _getStmtFieldDataString(hStmt, &(p_data_tbl->full_address_from), 1, FULL_ADDRESS_FROM_IDX_IN_MAIL_TBL); + _getStmtFieldDataString(hStmt, &(p_data_tbl->full_address_to), 1, FULL_ADDRESS_TO_IDX_IN_MAIL_TBL); + _getStmtFieldDataString(hStmt, &(p_data_tbl->subject), 1, SUBJECT_IDX_IN_MAIL_TBL); + _getStmtFieldDataInt(hStmt, &(p_data_tbl->body_download_status), BODY_DOWNLOAD_STATUS_IDX_IN_MAIL_TBL); + _getStmtFieldDataString(hStmt, &(p_data_tbl->file_path_plain), 0, FILE_PATH_PLAIN_IDX_IN_MAIL_TBL); + _getStmtFieldDataString(hStmt, &(p_data_tbl->file_path_html), 0, FILE_PATH_HTML_IDX_IN_MAIL_TBL); + _getStmtFieldDataString(hStmt, &(p_data_tbl->datetime), 0, DATETIME_IDX_IN_MAIL_TBL); + _getStmtFieldDataChar(hStmt, &(p_data_tbl->flags_seen_field), FLAGS_SEEN_FIELD_IDX_IN_MAIL_TBL); + _getStmtFieldDataInt(hStmt, &(p_data_tbl->DRM_status), DRM_STATUS_IDX_IN_MAIL_TBL); + _getStmtFieldDataInt(hStmt, &(p_data_tbl->priority), PRIORITY_IDX_IN_MAIL_TBL); + _getStmtFieldDataInt(hStmt, &(p_data_tbl->save_status), SAVE_STATUS_IDX_IN_MAIL_TBL); + _getStmtFieldDataInt(hStmt, &(p_data_tbl->lock_status), LOCK_STATUS_IDX_IN_MAIL_TBL); + _getStmtFieldDataInt(hStmt, &(p_data_tbl->report_status), REPORT_STATUS_IDX_IN_MAIL_TBL); + _getStmtFieldDataString(hStmt, &(p_data_tbl->preview_text), 1, PREVIEW_TEXT_IDX_IN_MAIL_TBL); + _getStmtFieldDataInt(hStmt, &(p_data_tbl->meeting_request_status), MEETING_REQUEST_STATUS_IDX_IN_MAIL_TBL); + + if (type == RETRIEVE_ALL) { + _getStmtFieldDataInt(hStmt, &(p_data_tbl->server_mail_status), SERVER_MAIL_STATUS_IDX_IN_MAIL_TBL); + _getStmtFieldDataString(hStmt, &(p_data_tbl->server_mailbox_name), 0, SERVER_MAILBOX_NAME_IDX_IN_MAIL_TBL); + _getStmtFieldDataString(hStmt, &(p_data_tbl->full_address_reply), 1, FULL_ADDRESS_REPLY_IDX_IN_MAIL_TBL); + _getStmtFieldDataString(hStmt, &(p_data_tbl->full_address_cc), 1, FULL_ADDRESS_CC_IDX_IN_MAIL_TBL); + _getStmtFieldDataString(hStmt, &(p_data_tbl->full_address_bcc), 1, FULL_ADDRESS_BCC_IDX_IN_MAIL_TBL); + _getStmtFieldDataString(hStmt, &(p_data_tbl->full_address_return), 1, FULL_ADDRESS_RETURN_IDX_IN_MAIL_TBL); + _getStmtFieldDataString(hStmt, &(p_data_tbl->message_id), 0, MESSAGE_ID_IDX_IN_MAIL_TBL); + _getStmtFieldDataString(hStmt, &(p_data_tbl->email_address_sender), 1, EMAIL_ADDRESS_SENDER_IDX_IN_MAIL_TBL); + _getStmtFieldDataString(hStmt, &(p_data_tbl->email_address_recipient), 1, EMAIL_ADDRESS_RECIPIENT_IDX_IN_MAIL_TBL); + _getStmtFieldDataInt(hStmt, &(p_data_tbl->attachment_count), ATTACHMENT_COUNT_IDX_IN_MAIL_TBL); + _getStmtFieldDataString(hStmt, &(p_data_tbl->preview_text), 1, PREVIEW_TEXT_IDX_IN_MAIL_TBL); + + } + + if (p_data_tbl->body_download_status) { + struct stat buf; + + if (p_data_tbl->file_path_html) { + if (stat(p_data_tbl->file_path_html, &buf) == -1) + p_data_tbl->body_download_status = 0; + } + else if (p_data_tbl->file_path_plain) { + if (stat(p_data_tbl->file_path_plain, &buf) == -1) + p_data_tbl->body_download_status = 0; + } + else + p_data_tbl->body_download_status = 0; + } + + *((emf_mail_tbl_t**)data) = p_data_tbl; + break; + + case RETRIEVE_SUMMARY: + if (!(p_data_tbl = malloc(sizeof(emf_mail_tbl_t)))) { + EM_DEBUG_EXCEPTION(" malloc failed..."); + + error = EM_STORAGE_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + memset(p_data_tbl, 0x00, sizeof(emf_mail_tbl_t)); + + _getStmtFieldDataInt(hStmt, &(p_data_tbl->mail_id), MAIL_ID_IDX_IN_MAIL_TBL); + _getStmtFieldDataInt(hStmt, &(p_data_tbl->account_id), ACCOUNT_ID_IDX_IN_MAIL_TBL); + _getStmtFieldDataString(hStmt, &(p_data_tbl->mailbox_name), 0, MAILBOX_NAME_IDX_IN_MAIL_TBL); + _getStmtFieldDataInt(hStmt, &(p_data_tbl->server_mail_status), SERVER_MAIL_STATUS_IDX_IN_MAIL_TBL); + _getStmtFieldDataString(hStmt, &(p_data_tbl->server_mailbox_name), 0, SERVER_MAILBOX_NAME_IDX_IN_MAIL_TBL); + _getStmtFieldDataString(hStmt, &(p_data_tbl->server_mail_id), 0, SERVER_MAIL_ID_IDX_IN_MAIL_TBL); + + *((emf_mail_tbl_t**)data) = p_data_tbl; + break; + + case RETRIEVE_ADDRESS: + if (!(p_data_tbl = malloc(sizeof(emf_mail_tbl_t)))) { + EM_DEBUG_EXCEPTION(" malloc failed..."); + error = EM_STORAGE_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + memset(p_data_tbl, 0x00, sizeof(emf_mail_tbl_t)); + _getStmtFieldDataInt(hStmt, &(p_data_tbl->mail_id), MAIL_ID_IDX_IN_MAIL_TBL); + _getStmtFieldDataString(hStmt, &(p_data_tbl->email_address_sender), 1, EMAIL_ADDRESS_SENDER_IDX_IN_MAIL_TBL); + _getStmtFieldDataString(hStmt, &(p_data_tbl->email_address_recipient), 1, EMAIL_ADDRESS_RECIPIENT_IDX_IN_MAIL_TBL); + *((emf_mail_tbl_t**)data) = p_data_tbl; + break; + + default: + break; + } + + /* rc = sqlite3_step(hStmt); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_step(hStmt), rc); + EM_DEBUG_DB_EXEC((rc != SQLITE_ROW && rc != SQLITE_DONE), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("sqlite3_step fail:%d", rc)); + + ret = true; + +FINISH_OFF: + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API int em_storage_mail_search_end(int search_handle, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("search_handle[%d], transaction[%d], err_code[%p]", search_handle, transaction, err_code); + + int error = EM_STORAGE_ERROR_NONE; + int rc, ret = false; + + if (search_handle < 0) { + EM_DEBUG_EXCEPTION(" search_handle[%d]", search_handle); + error = EM_STORAGE_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + DB_STMT hStmt = (DB_STMT)search_handle; + + EM_DEBUG_LOG(" Before sqlite3_finalize hStmt = %p", hStmt); + + rc = sqlite3_finalize(hStmt); + if (rc != SQLITE_OK) { + EM_DEBUG_EXCEPTION(" sqlite3_finalize failed - %d", rc); + error = EM_STORAGE_ERROR_DB_FAILURE; + } + + ret = true; + +FINISH_OFF: + EM_STORAGE_FINISH_READ_TRANSACTION(transaction); + _DISCONNECT_DB; + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API int em_storage_change_mail(int mail_id, emf_mail_tbl_t* mail, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("mail_id[%d], mail[%p], transaction[%d], err_code[%p]", mail_id, mail, transaction, err_code); + + if (mail_id <= 0 || !mail) { + EM_DEBUG_EXCEPTION(" mail_id[%d], mail[%p]", mail_id, mail); + + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + DB_STMT hStmt = NULL; + char sql_query_string[QUERY_SIZE] = {0, }; + int rc = -1; + int ret = false; + int error = EM_STORAGE_ERROR_NONE; + + sqlite3 *local_db_handle = em_storage_get_db_connection(); + + EM_STORAGE_START_WRITE_TRANSACTION(transaction, error); + + SNPRINTF(sql_query_string, sizeof(sql_query_string), + "UPDATE mail_tbl SET" + " mail_id = ?" + ", account_id = ?" + ", mailbox_name = ?" + ", mail_size = ?" + ", server_mail_status = ?" + ", server_mailbox_name = ?" + ", server_mail_id = ?" + ", full_address_from = ?" + ", full_address_reply = ?" /* 10 */ + ", full_address_to = ?" + ", full_address_cc = ?" + ", full_address_bcc = ?" + ", full_address_return = ?" + ", subject = ?" + ", body_download_status = ?" + ", file_path_plain = ?" + ", file_path_html = ?" + ", date_time = ?" + ", flags_seen_field = ?" + ", flags_deleted_field = ?" + ", flags_flagged_field = ?" + ", flags_answered_field = ?" + ", flags_recent_field = ?" + ", flags_draft_field = ?" + ", flags_forwarded_field = ?" + ", DRM_status = ?" + ", priority = ?" + ", save_status = ?" + ", lock_status = ?" + ", message_id = ?" + ", report_status = ?" + ", preview_text = ?" + " WHERE mail_id = %d AND account_id != 0 " + , mail_id); + + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_prepare_v2(local_db_handle, sql_query_string, strlen(sql_query_string), &hStmt, NULL), rc); + EM_DEBUG_DB_EXEC((SQLITE_OK != rc), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) sqlite3_prepare fail:(%d) %s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + + int i = 0; + + _bindStmtFieldDataInt(hStmt, i++, mail->mail_id); + _bindStmtFieldDataInt(hStmt, i++, mail->account_id); + _bindStmtFieldDataString(hStmt, i++, (char *)mail->mailbox_name, 0, MAILBOX_LEN_IN_MAIL_TBL); + _bindStmtFieldDataInt(hStmt, i++, mail->mail_size); + _bindStmtFieldDataInt(hStmt, i++, mail->server_mail_status); + _bindStmtFieldDataString(hStmt, i++, (char *)mail->server_mailbox_name, 0, SERVER_MAILBOX_LEN_IN_MAIL_TBL); + _bindStmtFieldDataString(hStmt, i++, (char *)mail->server_mail_id, 0, SERVER_MAIL_ID_LEN_IN_MAIL_TBL); + _bindStmtFieldDataString(hStmt, i++, (char *)mail->full_address_from, 1, FROM_LEN_IN_MAIL_TBL); + _bindStmtFieldDataString(hStmt, i++, (char *)mail->full_address_reply, 1, REPLY_TO_LEN_IN_MAIL_TBL); + _bindStmtFieldDataString(hStmt, i++, (char *)mail->full_address_to, 1, TO_LEN_IN_MAIL_TBL); + _bindStmtFieldDataString(hStmt, i++, (char *)mail->full_address_cc, 1, CC_LEN_IN_MAIL_TBL); + _bindStmtFieldDataString(hStmt, i++, (char *)mail->full_address_bcc, 1, BCC_LEN_IN_MAIL_TBL); + _bindStmtFieldDataString(hStmt, i++, (char *)mail->full_address_return, 1, RETURN_PATH_LEN_IN_MAIL_TBL); + _bindStmtFieldDataString(hStmt, i++, (char *)mail->subject, 1, SUBJECT_LEN_IN_MAIL_TBL); + _bindStmtFieldDataInt(hStmt, i++, mail->body_download_status); + _bindStmtFieldDataString(hStmt, i++, (char *)mail->file_path_plain, 0, TEXT_1_LEN_IN_MAIL_TBL); + _bindStmtFieldDataString(hStmt, i++, (char *)mail->file_path_html, 0, TEXT_2_LEN_IN_MAIL_TBL); + _bindStmtFieldDataString(hStmt, i++, (char *)mail->datetime, 0, DATETIME_LEN_IN_MAIL_TBL); + _bindStmtFieldDataChar(hStmt, i++, mail->flags_seen_field); + _bindStmtFieldDataChar(hStmt, i++, mail->flags_deleted_field); + _bindStmtFieldDataChar(hStmt, i++, mail->flags_flagged_field); + _bindStmtFieldDataChar(hStmt, i++, mail->flags_answered_field); + _bindStmtFieldDataChar(hStmt, i++, mail->flags_recent_field); + _bindStmtFieldDataChar(hStmt, i++, mail->flags_draft_field); + _bindStmtFieldDataChar(hStmt, i++, mail->flags_forwarded_field); + _bindStmtFieldDataInt(hStmt, i++, mail->DRM_status); + _bindStmtFieldDataInt(hStmt, i++, mail->priority); + _bindStmtFieldDataInt(hStmt, i++, mail->save_status); + _bindStmtFieldDataInt(hStmt, i++, mail->lock_status); + _bindStmtFieldDataString(hStmt, i++, (char *)mail->message_id, 0, MESSAGE_ID_LEN_IN_MAIL_TBL); + _bindStmtFieldDataInt(hStmt, i++, mail->report_status); + _bindStmtFieldDataString(hStmt, i++, (char *)mail->preview_text, 1, PREVIEWBODY_LEN_IN_MAIL_TBL); + /* rc = sqlite3_step(hStmt); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_step(hStmt), rc); + EM_DEBUG_DB_EXEC((rc != SQLITE_ROW && rc != SQLITE_DONE), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("sqlite3_step fail:%d", rc)); + + rc = sqlite3_changes(local_db_handle); + if (rc == 0) { + EM_DEBUG_EXCEPTION(" no matched mail found..."); + error = EM_STORAGE_ERROR_MAIL_NOT_FOUND; + goto FINISH_OFF; + } + + if (!em_storage_notify_storage_event(NOTI_MAIL_UPDATE, mail->account_id, mail->mail_id, mail->mailbox_name, 0)) + EM_DEBUG_EXCEPTION(" em_storage_notify_storage_event Failed [ NOTI_MAIL_UPDATE ] >>>> "); + + ret = true; + +FINISH_OFF: + if (hStmt != NULL) { + EM_DEBUG_LOG("Before sqlite3_finalize hStmt = %p", hStmt); + rc = sqlite3_finalize(hStmt); + if (rc != SQLITE_OK) { + EM_DEBUG_EXCEPTION("sqlite3_finalize failed - %d", rc); + error = EM_STORAGE_ERROR_DB_FAILURE; + } + } + + EM_STORAGE_FINISH_WRITE_TRANSACTION(transaction, ret, error); + _DISCONNECT_DB; + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API int em_storage_modify_mailbox_of_mails(char *old_mailbox_name, char *new_mailbox_name, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("old_mailbox_name[%p], new_mailbox_name[%p], transaction[%d], err_code[%p]", old_mailbox_name, new_mailbox_name, transaction, err_code); + + if (!old_mailbox_name && !new_mailbox_name) { + EM_DEBUG_EXCEPTION(" old_mailbox_name[%p], new_mailbox_name[%p]", old_mailbox_name, new_mailbox_name); + + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + int rc = -1; + int ret = false; + int error = EM_STORAGE_ERROR_NONE; + char sql_query_string[QUERY_SIZE] = {0, }; + + sqlite3 *local_db_handle = em_storage_get_db_connection(); + + EM_STORAGE_START_WRITE_TRANSACTION(transaction, error); + + EM_DEBUG_LOG("Old Mailbox Name [ %s ] , New Mailbox name [ %s ] ", old_mailbox_name, new_mailbox_name); + + SNPRINTF(sql_query_string, sizeof(sql_query_string), "UPDATE mail_tbl SET mailbox_name = '%s' WHERE mailbox_name = '%s'", new_mailbox_name, old_mailbox_name); + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, sql_query_string, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) exec fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + rc = sqlite3_changes(local_db_handle); + if (rc == 0) { + EM_DEBUG_EXCEPTION(" no matched mail found..."); + + error = EM_STORAGE_ERROR_MAIL_NOT_FOUND; + goto FINISH_OFF; + } + + EM_DEBUG_LOG(" Modification done in mail_read_mail_uid_tbl based on Mailbox name "); + /* Modify the mailbox_name name in mail_read_mail_uid_tbl table */ + SNPRINTF(sql_query_string, sizeof(sql_query_string), "UPDATE mail_read_mail_uid_tbl SET mailbox_name = '%s' WHERE mailbox_name = '%s'", new_mailbox_name, old_mailbox_name); + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, sql_query_string, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) exec fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + rc = sqlite3_changes(local_db_handle); + if (rc == 0) { + EM_DEBUG_EXCEPTION(" no matched mail found..."); + error = EM_STORAGE_ERROR_MAIL_NOT_FOUND; + goto FINISH_OFF; + } + + if (!em_storage_notify_storage_event(NOTI_MAILBOX_UPDATE, 1, 0, new_mailbox_name, 0)) + EM_DEBUG_EXCEPTION(" em_storage_notify_storage_event[ NOTI_MAILBOX_UPDATE] : Notification Failed >>> "); + + ret = true; + +FINISH_OFF: + + EM_STORAGE_FINISH_WRITE_TRANSACTION(transaction, ret, error); + _DISCONNECT_DB; + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +/** + * em_storage_clean_save_status(int save_status, int *err_code) - set the all mail status to the set value + * + * + **/ +EXPORT_API int em_storage_clean_save_status(int save_status, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("save_status[%d], err_code[%p]", save_status, err_code); + + EM_IF_NULL_RETURN_VALUE(err_code, false); + + int ret = false; + int error = EM_STORAGE_ERROR_NONE; + int rc = 0; + char sql_query_string[QUERY_SIZE] = {0, }; + sqlite3 *local_db_handle = em_storage_get_db_connection(); + + memset(sql_query_string, 0x00, sizeof(sql_query_string)); + SNPRINTF(sql_query_string, sizeof(sql_query_string), "UPDATE mail_tbl SET save_status = %d WHERE save_status = %d", save_status, EMF_MAIL_STATUS_SENDING); + EM_DEBUG_LOG("Query [%s]", sql_query_string); + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, sql_query_string, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) exec fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + rc = sqlite3_changes(local_db_handle); + if (rc == 0) { + EM_DEBUG_LOG(" No Matched Mail Exists "); + error = EM_STORAGE_ERROR_MAIL_NOT_FOUND; + } + + ret = true; + +FINISH_OFF: + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API int em_storage_set_field_of_mails_with_integer_value(int account_id, int mail_ids[], int mail_ids_count, char *field_name, int value, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id [%d], mail_ids[%p], mail_ids_count[%d], field_name[%s], value[%d], transaction[%d], err_code[%p]", account_id, mail_ids, mail_ids_count, field_name, value, transaction, err_code); + int i, error, rc, ret = false, cur_mail_id_string = 0, mail_id_string_buffer_length = 0; + char sql_query_string[QUERY_SIZE] = {0, }, *mail_id_string_buffer = NULL, *parameter_string = NULL; + sqlite3 *local_db_handle = em_storage_get_db_connection(); + + if (!mail_ids || !field_name || account_id == 0) { + EM_DEBUG_EXCEPTION("EM_STORAGE_ERROR_INVALID_PARAM"); + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + /* Generating mail id list string */ + mail_id_string_buffer_length = MAIL_ID_STRING_LENGTH * mail_ids_count; + + mail_id_string_buffer = em_core_malloc(mail_id_string_buffer_length); + + if(!mail_id_string_buffer) { + EM_DEBUG_EXCEPTION("em_core_malloc failed"); + error = EM_STORAGE_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + for(i = 0; i < mail_ids_count; i++) + cur_mail_id_string += SNPRINTF_OFFSET(mail_id_string_buffer, cur_mail_id_string, mail_id_string_buffer_length, "%d,", mail_ids[i]); + + if(strlen(mail_id_string_buffer) > 1) + mail_id_string_buffer[strlen(mail_id_string_buffer) - 1] = NULL_CHAR; + + /* Generating notification parameter string */ + parameter_string = em_core_malloc(mail_id_string_buffer_length + strlen(field_name) + 2); + + if(!parameter_string) { + EM_DEBUG_EXCEPTION("em_core_malloc failed"); + error = EM_STORAGE_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + SNPRINTF(parameter_string, QUERY_SIZE, "%s%c%s", field_name, 0x01, mail_id_string_buffer); + + /* Write query string */ + SNPRINTF(sql_query_string, QUERY_SIZE, "UPDATE mail_tbl SET %s = %d WHERE mail_id in (%s) AND account_id = %d", field_name, value, mail_id_string_buffer, account_id); + + /* Execute query */ + EM_STORAGE_START_WRITE_TRANSACTION(transaction, error); + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, sql_query_string, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) exec fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + if (sqlite3_changes(local_db_handle) == 0) + EM_DEBUG_LOG("no mail matched..."); + + ret = true; + +FINISH_OFF: + EM_STORAGE_FINISH_WRITE_TRANSACTION(transaction, ret, error); + _DISCONNECT_DB; + + if (ret && parameter_string && !em_storage_notify_storage_event(NOTI_MAIL_FIELD_UPDATE, account_id, 0, parameter_string, value)) + EM_DEBUG_EXCEPTION("em_storage_notify_storage_event failed : NOTI_MAIL_FIELD_UPDATE [%s,%d]", field_name, value); + + EM_SAFE_FREE(mail_id_string_buffer); + EM_SAFE_FREE(parameter_string); + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API int em_storage_change_mail_field(int mail_id, emf_mail_change_type_t type, emf_mail_tbl_t* mail, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("mail_id[%d], type[%d], mail[%p], transaction[%d], err_code[%p]", mail_id, type, mail, transaction, err_code); + + if (mail_id <= 0 || !mail) { + EM_DEBUG_EXCEPTION(" mail_id[%d], type[%d], mail[%p]", mail_id, type, mail); + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + int ret = false; + int error = EM_STORAGE_ERROR_NONE; + int move_flag = 0; + DB_STMT hStmt = NULL; + char sql_query_string[QUERY_SIZE] = {0, }; + + int rc = 0; + int i = 0; + + char *mailbox_name = NULL; + + sqlite3 *local_db_handle = em_storage_get_db_connection(); + EM_STORAGE_START_WRITE_TRANSACTION(transaction, error); + + switch (type) { + case APPEND_BODY: + SNPRINTF(sql_query_string, sizeof(sql_query_string), + "UPDATE mail_tbl SET" + " body_download_status = ?" + ", file_path_plain = ?" + ", file_path_html = ?" + ", flags_seen_field = ?" + ", flags_deleted_field = ?" + ", flags_flagged_field = ?" + ", flags_answered_field = ?" + ", flags_recent_field = ?" + ", flags_draft_field = ?" + ", flags_forwarded_field = ?" + ", DRM_status = ?" + ", attachment_count = ?" + ", preview_text= ?" + ", meeting_request_status = ? " + " WHERE mail_id = %d AND account_id != 0" + , mail_id); + + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_prepare_v2(local_db_handle, sql_query_string, strlen(sql_query_string), &hStmt, NULL), rc); + EM_DEBUG_DB_EXEC((SQLITE_OK != rc), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) sqlite3_prepare fail:(%d) %s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + i = 0; + + _bindStmtFieldDataInt(hStmt, i++, mail->body_download_status); + _bindStmtFieldDataString(hStmt, i++, (char *)mail->file_path_plain, 0, TEXT_1_LEN_IN_MAIL_TBL); + _bindStmtFieldDataString(hStmt, i++, (char *)mail->file_path_html, 0, TEXT_2_LEN_IN_MAIL_TBL); + _bindStmtFieldDataInt(hStmt, i++, mail->flags_seen_field); + _bindStmtFieldDataInt(hStmt, i++, mail->flags_deleted_field); + _bindStmtFieldDataInt(hStmt, i++, mail->flags_deleted_field); + _bindStmtFieldDataInt(hStmt, i++, mail->flags_flagged_field); + _bindStmtFieldDataInt(hStmt, i++, mail->flags_answered_field); + _bindStmtFieldDataInt(hStmt, i++, mail->flags_recent_field); + _bindStmtFieldDataInt(hStmt, i++, mail->flags_draft_field); + _bindStmtFieldDataInt(hStmt, i++, mail->flags_forwarded_field); + _bindStmtFieldDataInt(hStmt, i++, mail->DRM_status); + _bindStmtFieldDataInt(hStmt, i++, mail->attachment_count); + _bindStmtFieldDataString(hStmt, i++, (char *)mail->preview_text, 0, PREVIEWBODY_LEN_IN_MAIL_TBL); + _bindStmtFieldDataInt(hStmt, i++, mail->meeting_request_status); + break; + + case UPDATE_MAILBOX: { + int err; + emf_mailbox_tbl_t *mailbox_name; + + if (!em_storage_get_mailbox_by_name(mail->account_id, -1, mail->mailbox_name, &mailbox_name, false, &err)) { + EM_DEBUG_EXCEPTION(" em_storage_get_mailbox_by_name failed - %d", err); + err = em_storage_get_emf_error_from_em_storage_error(err); + goto FINISH_OFF; + } + + SNPRINTF(sql_query_string, sizeof(sql_query_string), + "UPDATE mail_tbl SET" + " mailbox_name = '%s'" + ",mailbox_type = '%d'" + " WHERE mail_id = %d AND account_id != 0" + , mail->mailbox_name ? mail->mailbox_name : "" + , mailbox_name->mailbox_type + , mail_id); + move_flag = 1; + + + EM_DEBUG_LOG("Query [%s]", sql_query_string); + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_prepare_v2(local_db_handle, sql_query_string, strlen(sql_query_string), &hStmt, NULL), rc); + EM_DEBUG_DB_EXEC((SQLITE_OK != rc), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) sqlite3_prepare fail:(%d) %s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + } + break; + + case UPDATE_FLAG: + SNPRINTF(sql_query_string, sizeof(sql_query_string), + "UPDATE mail_tbl SET" + " flags_seen_field = %d" + ",flags_deleted_field = %d" + ",flags_flagged_field = %d" + ",flags_answered_field = %d" + ",flags_recent_field = %d" + ",flags_draft_field = %d" + ",flags_forwarded_field = %d" + " WHERE mail_id = %d AND account_id != 0" + , mail->flags_seen_field + , mail->flags_deleted_field + , mail->flags_flagged_field + , mail->flags_answered_field + , mail->flags_recent_field + , mail->flags_draft_field + , mail->flags_forwarded_field + , mail_id); + EM_DEBUG_LOG("Query [%s]", sql_query_string); + + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_prepare_v2(local_db_handle, sql_query_string, strlen(sql_query_string), &hStmt, NULL), rc); + EM_DEBUG_DB_EXEC((SQLITE_OK != rc), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) sqlite3_prepare fail:(%d) %s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + break; + + case UPDATE_EXTRA_FLAG: + SNPRINTF(sql_query_string, sizeof(sql_query_string), + "UPDATE mail_tbl SET" + " priority = %d" + ", save_status = %d" + ", lock_status = %d" + ", report_status = %d" + ", DRM_status = %d" + " WHERE mail_id = %d AND account_id != 0" + , mail->priority + , mail->save_status + , mail->lock_status + , mail->report_status + , mail->DRM_status + , mail_id); + EM_DEBUG_LOG("Query [%s]", sql_query_string); + + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_prepare_v2(local_db_handle, sql_query_string, strlen(sql_query_string), &hStmt, NULL), rc); + EM_DEBUG_DB_EXEC((SQLITE_OK != rc), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) sqlite3_prepare fail:(%d) %s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + break; + + case UPDATE_STICKY_EXTRA_FLAG: + SNPRINTF(sql_query_string, sizeof(sql_query_string), + "UPDATE mail_tbl SET" + " lock_status = %d" + " WHERE mail_id = %d AND account_id != 0" + , mail->lock_status + , mail_id); + EM_DEBUG_LOG("Query [%s]", sql_query_string); + + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_prepare_v2(local_db_handle, sql_query_string, strlen(sql_query_string), &hStmt, NULL), rc); + EM_DEBUG_DB_EXEC((SQLITE_OK != rc), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) sqlite3_prepare fail:(%d) %s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + break; + + case UPDATE_MAIL: + SNPRINTF(sql_query_string, sizeof(sql_query_string), + "UPDATE mail_tbl SET" + " full_address_from = ?" + ", full_address_reply = ?" + ", full_address_to = ?" + ", full_address_cc = ?" + ", full_address_bcc = ?" + ", full_address_return = ?" + ", subject = ?" + ", file_path_plain = ?" + ", date_time = ?" + ", flags_seen_field = ?" + ", flags_deleted_field = ?" + ", flags_flagged_field = ?" + ", flags_answered_field = ?" + ", flags_recent_field = ?" + ", flags_draft_field = ?" + ", flags_forwarded_field = ?" + ", priority = ?" + ", save_status = ?" + ", lock_status = ?" + ", report_status = ?" + ", DRM_status = ?" + ", file_path_html = ?" + ", mail_size = ?" + ", preview_text = ?" + ", body_download_status = ?" + ", attachment_count = ?" + ", inline_content_count = ?" + ", meeting_request_status = ?" + " WHERE mail_id = %d AND account_id != 0" + , mail_id); + + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_prepare_v2(local_db_handle, sql_query_string, strlen(sql_query_string), &hStmt, NULL), rc); + EM_DEBUG_LOG(" before sqlite3_prepare hStmt = %p", hStmt); + EM_DEBUG_DB_EXEC((SQLITE_OK != rc), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) sqlite3_prepare fail:(%d) %s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + i = 0; + _bindStmtFieldDataString(hStmt, i++, (char *)mail->full_address_from, 1, FROM_LEN_IN_MAIL_TBL); + _bindStmtFieldDataString(hStmt, i++, (char *)mail->full_address_reply, 1, REPLY_TO_LEN_IN_MAIL_TBL); + _bindStmtFieldDataString(hStmt, i++, (char *)mail->full_address_to, 1, TO_LEN_IN_MAIL_TBL); + _bindStmtFieldDataString(hStmt, i++, (char *)mail->full_address_cc, 1, CC_LEN_IN_MAIL_TBL); + _bindStmtFieldDataString(hStmt, i++, (char *)mail->full_address_bcc, 1, BCC_LEN_IN_MAIL_TBL); + _bindStmtFieldDataString(hStmt, i++, (char *)mail->full_address_return, 1, RETURN_PATH_LEN_IN_MAIL_TBL); + _bindStmtFieldDataString(hStmt, i++, (char *)mail->subject, 1, SUBJECT_LEN_IN_MAIL_TBL); + _bindStmtFieldDataString(hStmt, i++, (char *)mail->file_path_plain, 0, TEXT_1_LEN_IN_MAIL_TBL); + _bindStmtFieldDataString(hStmt, i++, (char *)mail->datetime, 0, DATETIME_LEN_IN_MAIL_TBL); + _bindStmtFieldDataChar(hStmt, i++, mail->flags_seen_field); + _bindStmtFieldDataChar(hStmt, i++, mail->flags_deleted_field); + _bindStmtFieldDataChar(hStmt, i++, mail->flags_flagged_field); + _bindStmtFieldDataChar(hStmt, i++, mail->flags_answered_field); + _bindStmtFieldDataChar(hStmt, i++, mail->flags_recent_field); + _bindStmtFieldDataChar(hStmt, i++, mail->flags_draft_field); + _bindStmtFieldDataChar(hStmt, i++, mail->flags_forwarded_field); + _bindStmtFieldDataInt(hStmt, i++, mail->priority); + _bindStmtFieldDataInt(hStmt, i++, mail->save_status); + _bindStmtFieldDataInt(hStmt, i++, mail->lock_status); + _bindStmtFieldDataInt(hStmt, i++, mail->report_status); + _bindStmtFieldDataInt(hStmt, i++, mail->DRM_status); + _bindStmtFieldDataString(hStmt, i++, (char *)mail->file_path_html, 0, TEXT_2_LEN_IN_MAIL_TBL); + _bindStmtFieldDataInt(hStmt, i++, mail->mail_size); + _bindStmtFieldDataString(hStmt, i++, (char *)mail->preview_text, 1, PREVIEWBODY_LEN_IN_MAIL_TBL); + _bindStmtFieldDataInt(hStmt, i++, mail->body_download_status); + _bindStmtFieldDataInt(hStmt, i++, mail->attachment_count); + _bindStmtFieldDataInt(hStmt, i++, mail->inline_content_count); + _bindStmtFieldDataInt(hStmt, i++, mail->meeting_request_status); + break; + + case UPDATE_DATETIME: { + static char buf[16]; + time_t t = time(NULL); + + struct tm *p_tm = localtime(&t); + if (!p_tm) { + EM_DEBUG_EXCEPTION(" localtime failed..."); + error = EM_STORAGE_ERROR_SYSTEM_FAILURE; + goto FINISH_OFF; + } + + SNPRINTF(buf, sizeof(buf), + "%04d%02d%02d%02d%02d%02d", + p_tm->tm_year + 1900, + p_tm->tm_mon + 1, + p_tm->tm_mday, + p_tm->tm_hour, + p_tm->tm_min, + p_tm->tm_sec); + + SNPRINTF(sql_query_string, sizeof(sql_query_string), + "UPDATE mail_tbl SET" + " date_time = '%s'" + " WHERE mail_id = %d AND account_id != 0" + , buf + , mail_id); + + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_prepare_v2(local_db_handle, sql_query_string, strlen(sql_query_string), &hStmt, NULL), rc); + EM_DEBUG_DB_EXEC((SQLITE_OK != rc), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) sqlite3_prepare fail:(%d) %s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + break; + } + + case UPDATE_FROM_CONTACT_INFO: + EM_DEBUG_LOG("NVARCHAR : em_storage_change_mail_field - mail change type is UPDATE_FROM_CONTACT_INFO"); + SNPRINTF(sql_query_string, sizeof(sql_query_string), + "UPDATE mail_tbl SET" + " email_address_sender = ?," + " WHERE mail_id = %d", + mail_id); + + hStmt = NULL; + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_prepare_v2(local_db_handle, sql_query_string, strlen(sql_query_string), &hStmt, NULL), rc); + EM_DEBUG_DB_EXEC((SQLITE_OK != rc), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) sqlite3_prepare fail:(%d) %s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + i = 0; + _bindStmtFieldDataString(hStmt, i++, (char *)mail->email_address_sender, 1, FROM_EMAIL_ADDRESS_LEN_IN_MAIL_TBL); + break; + + case UPDATE_TO_CONTACT_INFO: + EM_DEBUG_LOG("NVARCHAR : em_storage_change_mail_field - mail change type is UPDATE_TO_CONTACT_INFO"); + SNPRINTF(sql_query_string, sizeof(sql_query_string), + "UPDATE mail_tbl SET" + " email_address_recipient = ?," + " WHERE mail_id = %d", + mail_id); + + hStmt = NULL; + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_prepare_v2(local_db_handle, sql_query_string, strlen(sql_query_string), &hStmt, NULL), rc); + EM_DEBUG_DB_EXEC((SQLITE_OK != rc), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) sqlite3_prepare fail:(%d) %s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + i = 0; + _bindStmtFieldDataString(hStmt, i++, (char *)mail->email_address_recipient, 1, TO_EMAIL_ADDRESS_LEN_IN_MAIL_TBL); + break; + + case UPDATE_ALL_CONTACT_INFO: + EM_DEBUG_LOG("em_storage_change_mail_field - mail change type is UPDATE_ALL_CONTACT_INFO"); + SNPRINTF(sql_query_string, sizeof(sql_query_string), + "UPDATE mail_tbl SET" + " email_address_sender = ?," + " email_address_recipient = ?," + " WHERE mail_id = %d", + mail_id); + + hStmt = NULL; + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_prepare_v2(local_db_handle, sql_query_string, strlen(sql_query_string), &hStmt, NULL), rc); + EM_DEBUG_DB_EXEC((SQLITE_OK != rc), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) sqlite3_prepare fail:(%d) %s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + i = 0; + _bindStmtFieldDataString(hStmt, i++, (char *)mail->email_address_sender, 1, FROM_EMAIL_ADDRESS_LEN_IN_MAIL_TBL); + _bindStmtFieldDataString(hStmt, i++, (char *)mail->email_address_recipient, 1, TO_EMAIL_ADDRESS_LEN_IN_MAIL_TBL); + break; + + +#ifdef __FEATURE_PARTIAL_BODY_DOWNLOAD__ + case UPDATE_PARTIAL_BODY_DOWNLOAD: + + SNPRINTF(sql_query_string, sizeof(sql_query_string), + "UPDATE mail_tbl SET" + " body_download_status = ?" + ", file_path_plain = ?" + ", file_path_html = ?" + ", attachment_count = ?" + ", inline_content_count = ?" + ", preview_text= ?" + " WHERE mail_id = %d" + , mail_id); + + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_prepare_v2(local_db_handle, sql_query_string, strlen(sql_query_string), &hStmt, NULL), rc); + EM_DEBUG_DB_EXEC((SQLITE_OK != rc), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) sqlite3_prepare fail:(%d) %s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + i = 0; + + _bindStmtFieldDataInt(hStmt, i++, mail->body_download_status); + _bindStmtFieldDataString(hStmt, i++, (char *)mail->file_path_plain, 0, TEXT_1_LEN_IN_MAIL_TBL); + _bindStmtFieldDataString(hStmt, i++, (char *)mail->file_path_html, 0, TEXT_2_LEN_IN_MAIL_TBL); + _bindStmtFieldDataInt(hStmt, i++, mail->attachment_count); + _bindStmtFieldDataInt(hStmt, i++, mail->inline_content_count); + _bindStmtFieldDataString(hStmt, i++, (char *)mail->preview_text, 0, PREVIEWBODY_LEN_IN_MAIL_TBL); + + break; + +#endif + + default: + EM_DEBUG_LOG(" type[%d]", type); + + error = EM_STORAGE_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + if (hStmt != NULL) { + /* rc = sqlite3_step(hStmt); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_step(hStmt), rc); + EM_DEBUG_DB_EXEC((rc == SQLITE_FULL), {error = EM_STORAGE_ERROR_DB_IS_FULL;goto FINISH_OFF; }, + ("sqlite3_step fail:%d", rc)); + EM_DEBUG_DB_EXEC((rc != SQLITE_ROW && rc != SQLITE_DONE), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("sqlite3_step fail:%d", rc)); + rc = sqlite3_changes(local_db_handle); + if (rc == 0) { + EM_DEBUG_EXCEPTION(" no matched mail found..."); + + error = EM_STORAGE_ERROR_MAIL_NOT_FOUND; + goto FINISH_OFF; + } + } + + if (mail->account_id == 0) { + emf_mail_tbl_t* mail_for_account = NULL; + if (!em_storage_get_mail_field_by_id(mail_id, RETRIEVE_ACCOUNT, &mail_for_account, true, &error) || !mail_for_account) { + EM_DEBUG_EXCEPTION(" em_storage_get_mail_field_by_id failed - %d", error); +/* error = em_storage_get_emf_error_from_em_storage_error(error); */ + goto FINISH_OFF; + } + mail->account_id = mail_for_account->account_id; + if (mail_for_account) + em_storage_free_mail(&mail_for_account, 1, NULL); + } + + ret = true; + +FINISH_OFF: + + if (hStmt != NULL) { + rc = sqlite3_finalize(hStmt); + if (rc != SQLITE_OK) { + EM_DEBUG_LOG(" sqlite3_finalize failed - %d", rc); + error = EM_STORAGE_ERROR_DB_FAILURE; + } + hStmt = NULL; + } + + EM_STORAGE_FINISH_WRITE_TRANSACTION(transaction, ret, error); + _DISCONNECT_DB; + + /*h.gahlaut@samsung.com: Moving publication of notification after commiting transaction to DB */ + + if (ret == true && move_flag != 1) { + if (!em_storage_get_mailboxname_by_mailbox_type(mail->account_id, EMF_MAILBOX_TYPE_SENTBOX, &mailbox_name, false, &error)) + EM_DEBUG_EXCEPTION(" em_storage_get_mailboxname_by_mailbox_type failed - %d", error); + +#ifdef __FEATURE_PROGRESS_IN_OUTBOX__ + + if (mail->mailbox_name && mailbox_name) { + if (strcmp(mail->mailbox_name, mailbox_name) != 0) { + if (!em_storage_notify_storage_event(NOTI_MAIL_UPDATE, mail->account_id, mail_id, mail->mailbox_name, type)) + EM_DEBUG_EXCEPTION(" em_storage_notify_storage_event Failed [ NOTI_MAIL_UPDATE ] >>>> "); + } + } + else { + /* h.gahlaut@samsung.com: Jan 10, 2011 Publishing noti to refresh outbox when email sending status changes */ + if (!em_storage_notify_storage_event(NOTI_MAIL_UPDATE, mail->account_id, mail_id, NULL, type)) + EM_DEBUG_EXCEPTION(" em_storage_notify_storage_event Failed [ NOTI_MAIL_UPDATE ] "); + } + +#else + + if (mail->mailbox_name && strcmp(mail->mailbox_name, mailbox_name) != 0) { + if (!em_storage_notify_storage_event(NOTI_MAIL_UPDATE, mail->account_id, mail_id, mail->mailbox_name, type)) + EM_DEBUG_EXCEPTION(" em_storage_notify_storage_event Failed [ NOTI_MAIL_UPDATE ] >>>> "); + } + + +#endif + + } + + EM_SAFE_FREE(mailbox_name); + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + + +EXPORT_API int em_storage_get_mail_count_with_draft_flag(int account_id, const char *mailbox_name, int *total, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id[%d], mailbox_name[%s], total[%p], transaction[%d], err_code[%p]", account_id, mailbox_name, total, transaction, err_code); + + if (!total) { + EM_DEBUG_EXCEPTION("accoun_id[%d], mailbox_name[%s], total[%p]", account_id, mailbox_name, total); + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + int rc = -1, ret = false; + int error = EM_STORAGE_ERROR_NONE; + DB_STMT hStmt = NULL; + char sql_query_string[QUERY_SIZE] = {0, }; + + memset(&sql_query_string, 0x00, sizeof(sql_query_string)); + sqlite3 *local_db_handle = em_storage_get_db_connection(); + EM_STORAGE_START_READ_TRANSACTION(transaction); + + if (total) { + SNPRINTF(sql_query_string, sizeof(sql_query_string), "SELECT COUNT(*) FROM mail_tbl WHERE flags_draft_field = 1"); + + if (account_id != ALL_ACCOUNT) + SNPRINTF(sql_query_string + strlen(sql_query_string), sizeof(sql_query_string)-(strlen(sql_query_string)+1), " AND account_id = %d", account_id); + + if (mailbox_name) + SNPRINTF(sql_query_string + strlen(sql_query_string), sizeof(sql_query_string)-(strlen(sql_query_string)+1), " AND mailbox_name = '%s'", mailbox_name); + +#ifdef USE_GET_RECORD_COUNT_API + EM_DEBUG_LOG("Query : [%s]", sql_query_string); + char **result; + /* rc = sqlite3_get_table(local_db_handle, sql_query_string, &result, NULL, NULL, NULL); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_get_table(local_db_handle, sql_query_string, &result, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;sqlite3_free_table(result);goto FINISH_OFF; }, + ("SQL(%s) sqlite3_get_table fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + *total = atoi(result[1]); + sqlite3_free_table(result); +#else + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_prepare_v2(local_db_handle, sql_query_string, strlen(sql_query_string), &hStmt, NULL), rc); + EM_DEBUG_DB_EXEC((SQLITE_OK != rc), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) sqlite3_prepare fail:(%d) %s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + /* rc = sqlite3_step(hStmt); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_step(hStmt), rc); + EM_DEBUG_DB_EXEC((rc != SQLITE_ROW && rc != SQLITE_DONE), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("sqlite3_step fail:%d", rc)); + + _getStmtFieldDataInt(hStmt, total, 0); +#endif /* USE_GET_RECORD_COUNT_API */ + } + ret = true; + +FINISH_OFF: +#ifndef USE_GET_RECORD_COUNT_API + if (hStmt != NULL) { + rc = sqlite3_finalize(hStmt); + if (rc != SQLITE_OK) { + EM_DEBUG_LOG(" sqlite3_finalize failed - %d", rc); + error = EM_STORAGE_ERROR_DB_FAILURE; + } + } +#endif + + EM_STORAGE_FINISH_READ_TRANSACTION(transaction); + _DISCONNECT_DB; + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API int em_storage_get_mail_count_on_sending(int account_id, const char *mailbox_name, int *total, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id[%d], mailbox_name[%s], total[%p], transaction[%d], err_code[%p]", account_id, mailbox_name, total, transaction, err_code); + + if (!total) { + EM_DEBUG_EXCEPTION(" accoun_id[%d], mailbox_name[%s], total[%p]", account_id, mailbox_name, total); + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + int rc = -1, ret = false; + int error = EM_STORAGE_ERROR_NONE; + DB_STMT hStmt = NULL; + char sql_query_string[QUERY_SIZE] = {0, }; + + memset(&sql_query_string, 0x00, sizeof(sql_query_string)); + sqlite3 *local_db_handle = em_storage_get_db_connection(); + EM_STORAGE_START_READ_TRANSACTION(transaction); + + if (total) { + SNPRINTF(sql_query_string, sizeof(sql_query_string), "SELECT COUNT(*) FROM mail_tbl WHERE save_status = %d ", EMF_MAIL_STATUS_SENDING); + + if (account_id != ALL_ACCOUNT) + SNPRINTF(sql_query_string + strlen(sql_query_string), sizeof(sql_query_string)-(strlen(sql_query_string)+1), " AND account_id = %d", account_id); + + if (mailbox_name) + SNPRINTF(sql_query_string + strlen(sql_query_string), sizeof(sql_query_string)-(strlen(sql_query_string)+1), " AND mailbox_name = '%s'", mailbox_name); + +#ifdef USE_GET_RECORD_COUNT_API + char **result; + /* rc = sqlite3_get_table(local_db_handle, sql_query_string, &result, NULL, NULL, NULL); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_get_table(local_db_handle, sql_query_string, &result, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;sqlite3_free_table(result);goto FINISH_OFF; }, + ("SQL(%s) sqlite3_get_table fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + *total = atoi(result[1]); + sqlite3_free_table(result); +#else + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_prepare_v2(local_db_handle, sql_query_string, strlen(sql_query_string), &hStmt, NULL), rc); + EM_DEBUG_DB_EXEC((SQLITE_OK != rc), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) sqlite3_prepare fail:(%d) %s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + /* rc = sqlite3_step(hStmt); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_step(hStmt), rc); + EM_DEBUG_DB_EXEC((rc != SQLITE_ROW && rc != SQLITE_DONE), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("sqlite3_step fail:%d", rc)); + + _getStmtFieldDataInt(hStmt, total, 0); +#endif /* USE_GET_RECORD_COUNT_API */ + } + ret = true; + +FINISH_OFF: +#ifndef USE_GET_RECORD_COUNT_API + if (hStmt != NULL) { + rc = sqlite3_finalize(hStmt); + if (rc != SQLITE_OK) { + EM_DEBUG_LOG(" sqlite3_finalize failed - %d", rc); + + error = EM_STORAGE_ERROR_DB_FAILURE; + } + } +#endif + + EM_STORAGE_FINISH_READ_TRANSACTION(transaction); + _DISCONNECT_DB; + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; + +} + +EXPORT_API int em_storage_increase_mail_id(int *mail_id, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("mail_id[%p], transaction[%d], err_code[%p]", mail_id, transaction, err_code); + + int rc, ret = false; + int error = EM_STORAGE_ERROR_NONE; + int latest_mail_id = 0; + sqlite3 *local_db_handle = NULL; + char *sql = "SELECT MAX(mail_id) FROM mail_tbl;"; + char **result = NULL; + +#ifdef __FEATURE_USE_SHARED_MUTEX_FOR_GENERATING_MAIL_ID__ + em_storage_shm_mutex_timedlock(&mapped_for_generating_mail_id, 2); +#endif /* __FEATURE_USE_SHARED_MUTEX_FOR_GENERATING_MAIL_ID__ */ + + ret = vconf_get_int(VCONF_KEY_LATEST_MAIL_ID, &latest_mail_id); + if (ret < 0 || latest_mail_id == 0) { + EM_DEBUG_LOG("vconf_get_int() failed [%d] or latest_mail_id is zero", ret); + + local_db_handle = em_storage_get_db_connection(); + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_get_table(local_db_handle, sql, &result, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;sqlite3_free_table(result);goto FINISH_OFF; }, + ("SQL(%s) sqlite3_get_table fail:%d -%s", sql, rc, sqlite3_errmsg(local_db_handle))); + if (NULL == result[1]) + rc = 1; + else + rc = atoi(result[1]) + 1; + + sqlite3_free_table(result); + latest_mail_id = rc; + } + + latest_mail_id++; + + ret = vconf_set_int(VCONF_KEY_LATEST_MAIL_ID, latest_mail_id); + + if (mail_id) + *mail_id = latest_mail_id; + +#ifdef __FEATURE_USE_SHARED_MUTEX_FOR_GENERATING_MAIL_ID__ + em_storage_shm_mutex_unlock(&mapped_for_generating_mail_id); +#endif /* __FEATURE_USE_SHARED_MUTEX_FOR_GENERATING_MAIL_ID__ */ + + ret = true; + +FINISH_OFF: + _DISCONNECT_DB; + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + + +EXPORT_API int em_storage_add_mail(emf_mail_tbl_t* mail_tbl_data, int get_id, int transaction, int *err_code) +{ + EM_PROFILE_BEGIN(emStorageMailAdd); + EM_DEBUG_FUNC_BEGIN("mail_tbl_data[%p], get_id[%d], transaction[%d], err_code[%p]", mail_tbl_data, get_id, transaction, err_code); + + if (!mail_tbl_data) { + EM_DEBUG_EXCEPTION("mail_tbl_data[%p], get_id[%d]", mail_tbl_data, get_id); + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + int rc, ret = false; + int error = EM_STORAGE_ERROR_NONE; + static char bufDatetime[30] = {0, }; + DB_STMT hStmt = NULL; + char sql_query_string[QUERY_SIZE] = {0, }; + + sqlite3 *local_db_handle = em_storage_get_db_connection(); + EM_STORAGE_START_WRITE_TRANSACTION(transaction, error); + + if (get_id) { + /* increase unique id */ + char *sql = "SELECT max(rowid) FROM mail_tbl;"; + char **result; + + /* rc = sqlite3_get_table(local_db_handle, sql, &result, NULL, NULL, NULL); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_get_table(local_db_handle, sql, &result, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;sqlite3_free_table(result);goto FINISH_OFF; }, + ("SQL(%s) sqlite3_get_table fail:%d -%s", sql, rc, sqlite3_errmsg(local_db_handle))); + + if (NULL==result[1]) + rc = 1; + else + rc = atoi(result[1])+1; + sqlite3_free_table(result); + mail_tbl_data->mail_id = rc; + mail_tbl_data->thread_id = mail_tbl_data->mail_id; + } + + if (!mail_tbl_data->datetime) { + time_t t = time(NULL); + struct tm *p_tm = localtime(&t); + + if (p_tm) { + SNPRINTF(bufDatetime, sizeof(bufDatetime), "%04d%02d%02d%02d%02d%02d", + p_tm->tm_year + 1900, + p_tm->tm_mon + 1, + p_tm->tm_mday, + p_tm->tm_hour, + p_tm->tm_min, + p_tm->tm_sec); + } + } + else if (strlen(mail_tbl_data->datetime) > 14) { + EM_DEBUG_EXCEPTION("WARNING: the given datatime is too big."); + memcpy(bufDatetime, mail_tbl_data->datetime, 14); + bufDatetime[14] = NULL_CHAR; + } + else + strncpy(bufDatetime, mail_tbl_data->datetime, sizeof(bufDatetime)-1); + + SNPRINTF(sql_query_string, sizeof(sql_query_string), + "INSERT INTO mail_tbl VALUES " + "( ?" /* mail_id */ + ", ?" /* account_id */ + ", ?" /* mailbox_name */ + ", ?" /* mailbox_type */ + ", ?" /* subject */ + ", ?" /* date_time */ + ", ?" /* server_mail_status */ + ", ?" /* server_mailbox_name */ + ", ?" /* server_mail_id */ + ", ?" /* message_id */ + ", ?" /* full_address_from */ + ", ?" /* full_address_reply */ + ", ?" /* full_address_to */ + ", ?" /* full_address_cc */ + ", ?" /* full_address_bcc */ + ", ?" /* full_address_return */ + ", ?" /* email_address_sender */ + ", ?" /* email_address_recipient */ + ", ?" /* alias_sender */ + ", ?" /* alias_recipient */ + ", ?" /* body_download_status */ + ", ?" /* file_path_plain */ + ", ?" /* file_path_html */ + ", ?" /* mail_size */ + ", ?" /* flags_seen_field */ + ", ?" /* flags_deleted_field */ + ", ?" /* flags_flagged_field */ + ", ?" /* flags_answered_field */ + ", ?" /* flags_recent_field */ + ", ?" /* flags_draft_field */ + ", ?" /* flags_forwarded_field */ + ", ?" /* DRM_status */ + ", ?" /* priority */ + ", ?" /* save_status */ + ", ?" /* lock_status */ + ", ?" /* report_status */ + ", ?" /* attachment_count */ + ", ?" /* inline_content_count */ + ", ?" /* thread_id */ + ", ?" /* thread_item_count */ + ", ?" /* preview_text */ + ", ?" /* meeting_request_status */ + ")"); + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_prepare_v2(local_db_handle, sql_query_string, strlen(sql_query_string), &hStmt, NULL), rc); + EM_DEBUG_DB_EXEC((SQLITE_OK != rc), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) sqlite3_prepare fail:(%d) %s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + _bindStmtFieldDataInt(hStmt, MAIL_ID_IDX_IN_MAIL_TBL, mail_tbl_data->mail_id); + _bindStmtFieldDataInt(hStmt, ACCOUNT_ID_IDX_IN_MAIL_TBL, mail_tbl_data->account_id); + _bindStmtFieldDataString(hStmt, MAILBOX_NAME_IDX_IN_MAIL_TBL, (char *)mail_tbl_data->mailbox_name, 0, MAILBOX_LEN_IN_MAIL_TBL); + _bindStmtFieldDataInt(hStmt, MAILBOX_TYPE_IDX_IN_MAIL_TBL, mail_tbl_data->mailbox_type); + _bindStmtFieldDataString(hStmt, SUBJECT_IDX_IN_MAIL_TBL, (char *)mail_tbl_data->subject, 1, SUBJECT_LEN_IN_MAIL_TBL); + _bindStmtFieldDataString(hStmt, DATETIME_IDX_IN_MAIL_TBL, (char *)bufDatetime, 0, DATETIME_LEN_IN_MAIL_TBL); + _bindStmtFieldDataInt(hStmt, SERVER_MAIL_STATUS_IDX_IN_MAIL_TBL, mail_tbl_data->server_mail_status); + _bindStmtFieldDataString(hStmt, SERVER_MAILBOX_NAME_IDX_IN_MAIL_TBL, (char *)mail_tbl_data->server_mailbox_name, 0, SERVER_MAILBOX_LEN_IN_MAIL_TBL); + _bindStmtFieldDataString(hStmt, SERVER_MAIL_ID_IDX_IN_MAIL_TBL, (char *)mail_tbl_data->server_mail_id, 0, SERVER_MAIL_ID_LEN_IN_MAIL_TBL); + _bindStmtFieldDataString(hStmt, MESSAGE_ID_IDX_IN_MAIL_TBL, (char *)mail_tbl_data->message_id, 0, MESSAGE_ID_LEN_IN_MAIL_TBL); + _bindStmtFieldDataString(hStmt, FULL_ADDRESS_FROM_IDX_IN_MAIL_TBL, (char *)mail_tbl_data->full_address_from, 1, FROM_LEN_IN_MAIL_TBL); + _bindStmtFieldDataString(hStmt, FULL_ADDRESS_REPLY_IDX_IN_MAIL_TBL, (char *)mail_tbl_data->full_address_reply, 1, REPLY_TO_LEN_IN_MAIL_TBL); + _bindStmtFieldDataString(hStmt, FULL_ADDRESS_TO_IDX_IN_MAIL_TBL, (char *)mail_tbl_data->full_address_to, 1, TO_LEN_IN_MAIL_TBL); + _bindStmtFieldDataString(hStmt, FULL_ADDRESS_CC_IDX_IN_MAIL_TBL, (char *)mail_tbl_data->full_address_cc, 1, CC_LEN_IN_MAIL_TBL); + _bindStmtFieldDataString(hStmt, FULL_ADDRESS_BCC_IDX_IN_MAIL_TBL, (char *)mail_tbl_data->full_address_bcc, 1, BCC_LEN_IN_MAIL_TBL); + _bindStmtFieldDataString(hStmt, FULL_ADDRESS_RETURN_IDX_IN_MAIL_TBL, (char *)mail_tbl_data->full_address_return, 1, RETURN_PATH_LEN_IN_MAIL_TBL); + _bindStmtFieldDataString(hStmt, EMAIL_ADDRESS_SENDER_IDX_IN_MAIL_TBL, (char *)mail_tbl_data->email_address_sender, 1, FROM_EMAIL_ADDRESS_LEN_IN_MAIL_TBL); + _bindStmtFieldDataString(hStmt, EMAIL_ADDRESS_RECIPIENT_IDX_IN_MAIL_TBL, (char *)mail_tbl_data->email_address_recipient, 1, TO_EMAIL_ADDRESS_LEN_IN_MAIL_TBL); + _bindStmtFieldDataString(hStmt, ALIAS_SENDER_IDX_IN_MAIL_TBL, (char *)mail_tbl_data->alias_sender, 1, FROM_CONTACT_NAME_LEN_IN_MAIL_TBL); + _bindStmtFieldDataString(hStmt, ALIAS_RECIPIENT_IDX_IN_MAIL_TBL, (char *)mail_tbl_data->alias_recipient, 1, FROM_CONTACT_NAME_LEN_IN_MAIL_TBL); + _bindStmtFieldDataInt(hStmt, BODY_DOWNLOAD_STATUS_IDX_IN_MAIL_TBL, mail_tbl_data->body_download_status); + _bindStmtFieldDataString(hStmt, FILE_PATH_PLAIN_IDX_IN_MAIL_TBL, (char *)mail_tbl_data->file_path_plain, 0, TEXT_1_LEN_IN_MAIL_TBL); + _bindStmtFieldDataString(hStmt, FILE_PATH_HTML_IDX_IN_MAIL_TBL, (char *)mail_tbl_data->file_path_html, 0, TEXT_2_LEN_IN_MAIL_TBL); + _bindStmtFieldDataInt(hStmt, MAIL_SIZE_IDX_IN_MAIL_TBL, mail_tbl_data->mail_size); + _bindStmtFieldDataInt(hStmt, FLAGS_SEEN_FIELD_IDX_IN_MAIL_TBL, mail_tbl_data->flags_seen_field); + _bindStmtFieldDataInt(hStmt, FLAGS_DELETED_FIELD_IDX_IN_MAIL_TBL, mail_tbl_data->flags_deleted_field); + _bindStmtFieldDataInt(hStmt, FLAGS_FLAGGED_FIELD_IDX_IN_MAIL_TBL, mail_tbl_data->flags_flagged_field); + _bindStmtFieldDataInt(hStmt, FLAGS_ANSWERED_FIELD_IDX_IN_MAIL_TBL, mail_tbl_data->flags_answered_field); + _bindStmtFieldDataInt(hStmt, FLAGS_RECENT_FIELD_IDX_IN_MAIL_TBL, mail_tbl_data->flags_recent_field); + _bindStmtFieldDataInt(hStmt, FLAGS_DRAFT_FIELD_IDX_IN_MAIL_TBL, mail_tbl_data->flags_draft_field); + _bindStmtFieldDataInt(hStmt, FLAGS_FORWARDED_FIELD_IDX_IN_MAIL_TBL, mail_tbl_data->flags_forwarded_field); + _bindStmtFieldDataInt(hStmt, DRM_STATUS_IDX_IN_MAIL_TBL, mail_tbl_data->DRM_status); + _bindStmtFieldDataInt(hStmt, PRIORITY_IDX_IN_MAIL_TBL, mail_tbl_data->priority); + _bindStmtFieldDataInt(hStmt, SAVE_STATUS_IDX_IN_MAIL_TBL, mail_tbl_data->save_status); + _bindStmtFieldDataInt(hStmt, LOCK_STATUS_IDX_IN_MAIL_TBL, mail_tbl_data->lock_status); + _bindStmtFieldDataInt(hStmt, REPORT_STATUS_IDX_IN_MAIL_TBL, mail_tbl_data->report_status); + _bindStmtFieldDataInt(hStmt, ATTACHMENT_COUNT_IDX_IN_MAIL_TBL, mail_tbl_data->attachment_count); + _bindStmtFieldDataInt(hStmt, INLINE_CONTENT_COUNT_IDX_IN_MAIL_TBL, mail_tbl_data->inline_content_count); + _bindStmtFieldDataInt(hStmt, THREAD_ID_IDX_IN_MAIL_TBL, mail_tbl_data->thread_id); + _bindStmtFieldDataInt(hStmt, THREAD_ITEM_COUNT_IDX_IN_MAIL_TBL, mail_tbl_data->thread_item_count); + _bindStmtFieldDataString(hStmt, PREVIEW_TEXT_IDX_IN_MAIL_TBL, (char *)mail_tbl_data->preview_text, 1, PREVIEWBODY_LEN_IN_MAIL_TBL); + _bindStmtFieldDataInt(hStmt, MEETING_REQUEST_STATUS_IDX_IN_MAIL_TBL, mail_tbl_data->meeting_request_status); + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_step(hStmt), rc); + EM_DEBUG_DB_EXEC((rc == SQLITE_FULL), {error = EM_STORAGE_ERROR_DB_IS_FULL;goto FINISH_OFF; }, ("sqlite3_step fail:%d", rc)); + EM_DEBUG_DB_EXEC((rc != SQLITE_ROW && rc != SQLITE_DONE), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, ("sqlite3_step fail:%d", rc)); + ret = true; + +FINISH_OFF: + + if (hStmt != NULL) { + rc = sqlite3_finalize(hStmt); + if (rc != SQLITE_OK) { + EM_DEBUG_LOG("sqlite3_finalize failed - %d", rc); + error = EM_STORAGE_ERROR_DB_FAILURE; + } + } + + EM_STORAGE_FINISH_WRITE_TRANSACTION(transaction, ret, error); + _DISCONNECT_DB; + + + if (err_code != NULL) + *err_code = error; + + EM_PROFILE_END(emStorageMailAdd); + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API int em_storage_move_multiple_mails(int account_id, char *target_mailbox_name, int mail_ids[], int number_of_mails, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id [%d], target_mailbox_name [%s], mail_ids[%p], number_of_mails [%d], transaction[%d], err_code[%p]", account_id, target_mailbox_name, mail_ids, number_of_mails, transaction, err_code); + + int rc, ret = false, i, cur_conditional_clause = 0; + int error = EM_STORAGE_ERROR_NONE; + char sql_query_string[QUERY_SIZE] = {0, }, conditional_clause[QUERY_SIZE] = {0, }; + emf_mailbox_tbl_t *result_mailbox = NULL; + emf_mailbox_type_e target_mailbox_type = EMF_MAILBOX_TYPE_USER_DEFINED; + + if (!mail_ids || !target_mailbox_name) { + EM_DEBUG_EXCEPTION("EM_STORAGE_ERROR_INVALID_PARAM"); + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + sqlite3 *local_db_handle = em_storage_get_db_connection(); + + if(!em_storage_get_mailbox_by_name(account_id, -1, target_mailbox_name, &result_mailbox, true, &error)) { + EM_DEBUG_EXCEPTION("em_storage_get_mailbox_by_name failed [%d]", error); + goto FINISH_OFF; + } + + if(result_mailbox) { + target_mailbox_type = result_mailbox->mailbox_type; + em_storage_free_mailbox(&result_mailbox, 1, NULL); + } + + cur_conditional_clause = SNPRINTF(conditional_clause, QUERY_SIZE, "WHERE mail_id in ("); + + for(i = 0; i < number_of_mails; i++) + cur_conditional_clause += SNPRINTF_OFFSET(conditional_clause, cur_conditional_clause, QUERY_SIZE, "%d,", mail_ids[i]); + + conditional_clause[strlen(conditional_clause) - 1] = ')'; + + EM_STORAGE_START_WRITE_TRANSACTION(transaction, error); + + /* Updating a mail_tbl */ + + memset(sql_query_string, 0x00, QUERY_SIZE); + SNPRINTF(sql_query_string, QUERY_SIZE, "UPDATE mail_tbl SET mailbox_name = '%s', mailbox_type = %d %s", target_mailbox_name, target_mailbox_type, conditional_clause); + EM_DEBUG_LOG("Query [%s]", sql_query_string); + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, sql_query_string, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {goto FINISH_OFF; }, + ("SQL(%s) exec fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + /* Updating a mail_attachment_tbl */ + + memset(sql_query_string, 0x00, QUERY_SIZE); + SNPRINTF(sql_query_string, QUERY_SIZE, "UPDATE mail_attachment_tbl SET mailbox_name = '%s' %s", target_mailbox_name, conditional_clause); + EM_DEBUG_LOG("Query [%s]", sql_query_string); + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, sql_query_string, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {goto FINISH_OFF; }, + ("SQL(%s) exec fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + /* Updating a mail_meeting_tbl */ + memset(sql_query_string, 0x00, QUERY_SIZE); + SNPRINTF(sql_query_string, QUERY_SIZE, "UPDATE mail_meeting_tbl SET mailbox_name = '%s' %s", target_mailbox_name, conditional_clause); + EM_DEBUG_LOG("Query [%s]", sql_query_string); + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, sql_query_string, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {goto FINISH_OFF; }, + ("SQL(%s) exec fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + /* Updating a mail_read_mail_uid_tbl */ + memset(conditional_clause, 0x00, QUERY_SIZE); + cur_conditional_clause = SNPRINTF(conditional_clause, QUERY_SIZE, "WHERE local_uid in ("); + + for(i = 0; i < number_of_mails; i++) + cur_conditional_clause += SNPRINTF_OFFSET(conditional_clause, cur_conditional_clause, QUERY_SIZE, "%d,", mail_ids[i]); + + conditional_clause[strlen(conditional_clause) - 1] = ')'; + + memset(sql_query_string, 0x00, QUERY_SIZE); + SNPRINTF(sql_query_string, QUERY_SIZE, "UPDATE mail_read_mail_uid_tbl SET mailbox_name = '%s', local_mbox = '%s' %s", target_mailbox_name, target_mailbox_name, conditional_clause); + EM_DEBUG_LOG("Query [%s]", sql_query_string); + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, sql_query_string, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {goto FINISH_OFF; }, + ("SQL(%s) exec fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + ret = true; + +FINISH_OFF: + EM_STORAGE_FINISH_WRITE_TRANSACTION(transaction, ret, error); + _DISCONNECT_DB; + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API int em_storage_delete_mail(int mail_id, int from_server, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("mail_id[%d], transaction[%d], err_code[%p]", mail_id, transaction, err_code); + + if (!mail_id) { + EM_DEBUG_EXCEPTION("mail_id[%d]", mail_id); + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + int rc, ret = false; + int error = EM_STORAGE_ERROR_NONE; + char sql_query_string[QUERY_SIZE] = {0, }; + + sqlite3 *local_db_handle = em_storage_get_db_connection(); + EM_STORAGE_START_WRITE_TRANSACTION(transaction, error); + + memset(sql_query_string, 0x00, sizeof(sql_query_string)); + + SNPRINTF(sql_query_string, sizeof(sql_query_string), "DELETE FROM mail_tbl WHERE mail_id = %d ", mail_id); + EM_DEBUG_LOG("Query [%s]", sql_query_string); + + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, sql_query_string, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {goto FINISH_OFF; }, + ("SQL(%s) exec fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + ret = true; + +FINISH_OFF: + EM_STORAGE_FINISH_WRITE_TRANSACTION(transaction, ret, error); + _DISCONNECT_DB; + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API int em_storage_delete_multiple_mails(int mail_ids[], int number_of_mails, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("mail_ids[%p], number_of_mails [%d], transaction[%d], err_code[%p]", mail_ids, number_of_mails, transaction, err_code); + + int rc, ret = false, i, cur_sql_query_string = 0; + int error = EM_STORAGE_ERROR_NONE; + char sql_query_string[QUERY_SIZE] = {0, }; + + if (!mail_ids) { + EM_DEBUG_EXCEPTION("EM_STORAGE_ERROR_INVALID_PARAM"); + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + sqlite3 *local_db_handle = em_storage_get_db_connection(); + EM_STORAGE_START_WRITE_TRANSACTION(transaction, error); + + cur_sql_query_string = SNPRINTF(sql_query_string, sizeof(sql_query_string), "DELETE FROM mail_tbl WHERE mail_id in ("); + + for(i = 0; i < number_of_mails; i++) + cur_sql_query_string += SNPRINTF_OFFSET(sql_query_string, cur_sql_query_string, QUERY_SIZE, "%d,", mail_ids[i]); + + sql_query_string[strlen(sql_query_string) - 1] = ')'; + + EM_DEBUG_LOG("Query [%s]", sql_query_string); + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, sql_query_string, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {goto FINISH_OFF; }, + ("SQL(%s) exec fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + ret = true; + +FINISH_OFF: + EM_STORAGE_FINISH_WRITE_TRANSACTION(transaction, ret, error); + _DISCONNECT_DB; + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API int em_storage_delete_mail_by_account(int account_id, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id[%d], transaction[%d], err_code[%p]", account_id, transaction, err_code); + + if (account_id < FIRST_ACCOUNT_ID) { + EM_DEBUG_EXCEPTION("account_id[%d]", account_id); + + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + int rc, ret = false; + int error = EM_STORAGE_ERROR_NONE; + char sql_query_string[QUERY_SIZE] = {0, }; + + sqlite3 *local_db_handle = em_storage_get_db_connection(); + EM_STORAGE_START_WRITE_TRANSACTION(transaction, error); + + SNPRINTF(sql_query_string, sizeof(sql_query_string), "DELETE FROM mail_tbl WHERE account_id = %d", account_id); + EM_DEBUG_LOG("Query [%s]", sql_query_string); + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, sql_query_string, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) exec fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + rc = sqlite3_changes(local_db_handle); + if (rc == 0) { + EM_DEBUG_EXCEPTION(" no mail found..."); + error = EM_STORAGE_ERROR_MAIL_NOT_FOUND; + } + + /* Delete all mails mail_read_mail_uid_tbl table based on account id */ + SNPRINTF(sql_query_string, sizeof(sql_query_string), "DELETE FROM mail_read_mail_uid_tbl WHERE account_id = %d", account_id); + EM_DEBUG_LOG("Query [%s]", sql_query_string); + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, sql_query_string, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) exec fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + rc = sqlite3_changes(local_db_handle); + if (rc == 0) { + EM_DEBUG_EXCEPTION("no mail found..."); + error = EM_STORAGE_ERROR_MAIL_NOT_FOUND; + } + + if (!em_storage_notify_storage_event(NOTI_MAIL_DELETE_WITH_ACCOUNT, account_id, 0 , NULL, 0)) + EM_DEBUG_EXCEPTION(" em_storage_notify_storage_event Failed [ NOTI_MAIL_DELETE_ALL ]"); + + ret = true; + +FINISH_OFF: + + EM_STORAGE_FINISH_WRITE_TRANSACTION(transaction, ret, error); + _DISCONNECT_DB; + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API int em_storage_delete_mail_by_mailbox(int account_id, char *mbox, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id[%d], mbox[%p], transaction[%d], err_code[%p]", account_id, mbox, transaction, err_code); + + if (account_id < FIRST_ACCOUNT_ID || !mbox) { + EM_DEBUG_EXCEPTION(" account_id[%d], mbox[%p]", account_id, mbox); + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + int rc, ret = false; + int error = EM_STORAGE_ERROR_NONE; + char sql_query_string[QUERY_SIZE] = {0, }; + + sqlite3 *local_db_handle = em_storage_get_db_connection(); + + EM_STORAGE_START_WRITE_TRANSACTION(transaction, error); + + SNPRINTF(sql_query_string, sizeof(sql_query_string), "DELETE FROM mail_tbl WHERE account_id = %d AND mailbox_name = '%s'", account_id, mbox); + EM_DEBUG_LOG("Query [%s]", sql_query_string); + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, sql_query_string, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) exec fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + + /* Delete Mails from mail_read_mail_uid_tbl */ + SNPRINTF(sql_query_string, sizeof(sql_query_string), "DELETE FROM mail_read_mail_uid_tbl WHERE account_id = %d AND mailbox_name = '%s'", account_id, mbox); + EM_DEBUG_LOG("Query [%s]", sql_query_string); + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, sql_query_string, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) exec fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + if (!em_storage_notify_storage_event(NOTI_MAIL_DELETE_ALL, account_id, 0 , mbox, 0)) + EM_DEBUG_EXCEPTION(" em_storage_notify_storage_event Failed [ NOTI_MAIL_DELETE_ALL ] >>>> "); + + ret = true; + +FINISH_OFF: + EM_STORAGE_FINISH_WRITE_TRANSACTION(transaction, ret, error); + _DISCONNECT_DB; + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API int em_storage_free_mail(emf_mail_tbl_t** mail_list, int count, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("mail_list[%p], count[%d], err_code[%p]", mail_list, count, err_code); + + if (count > 0) { + if ((mail_list == NULL) || (*mail_list == NULL)) { + EM_DEBUG_EXCEPTION("mail_ilst[%p], count[%d]", mail_list, count); + + if (err_code) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + emf_mail_tbl_t* p = *mail_list; + int i = 0; + + for (; i < count; i++, p++) { + EM_SAFE_FREE(p->mailbox_name); + EM_SAFE_FREE(p->server_mailbox_name); + EM_SAFE_FREE(p->server_mail_id); + EM_SAFE_FREE(p->full_address_from); + EM_SAFE_FREE(p->full_address_reply); + EM_SAFE_FREE(p->full_address_to); + EM_SAFE_FREE(p->full_address_cc); + EM_SAFE_FREE(p->full_address_bcc); + EM_SAFE_FREE(p->full_address_return); + EM_SAFE_FREE(p->subject); + EM_SAFE_FREE(p->file_path_plain); + EM_SAFE_FREE(p->file_path_html); + EM_SAFE_FREE(p->datetime); + EM_SAFE_FREE(p->message_id); + EM_SAFE_FREE(p->email_address_sender); + EM_SAFE_FREE(p->email_address_recipient); + EM_SAFE_FREE(p->preview_text); + EM_SAFE_FREE(p->alias_sender); + EM_SAFE_FREE(p->alias_recipient); + } + EM_SAFE_FREE(*mail_list); + } + + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_NONE; + + EM_DEBUG_FUNC_END(); + return true; +} + +EXPORT_API int em_storage_get_attachment_count(int mail_id, int *count, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("mail_id[%d], count[%p], transaction[%d], err_code[%p]", mail_id, count, transaction, err_code); + + if (mail_id <= 0 || !count) { + EM_DEBUG_EXCEPTION("mail_id[%d], count[%p]", mail_id, count); + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + int rc = -1, ret = false; + int error = EM_STORAGE_ERROR_NONE; + char sql_query_string[QUERY_SIZE] = {0, }; + + sqlite3 *local_db_handle = em_storage_get_db_connection(); + EM_STORAGE_START_READ_TRANSACTION(transaction); + + SNPRINTF(sql_query_string, sizeof(sql_query_string), "SELECT COUNT(*) FROM mail_attachment_tbl WHERE mail_id = %d", mail_id); + + char **result; + /* rc = sqlite3_get_table(local_db_handle, sql_query_string, &result, NULL, NULL, NULL); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_get_table(local_db_handle, sql_query_string, &result, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;sqlite3_free_table(result);goto FINISH_OFF; }, + ("SQL(%s) sqlite3_get_table fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + *count = atoi(result[1]); + sqlite3_free_table(result); + + ret = true; + +FINISH_OFF: + + EM_STORAGE_FINISH_READ_TRANSACTION(transaction); + _DISCONNECT_DB; + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API int em_storage_get_attachment_list(int input_mail_id, int input_transaction, emf_mail_attachment_tbl_t** output_attachment_list, int *output_attachment_count) +{ + EM_DEBUG_FUNC_BEGIN("input_mail_id[%d], input_transaction[%d], output_attachment_list[%p], output_attachment_count[%p]", input_mail_id, output_attachment_list, input_transaction, output_attachment_count); + + if (input_mail_id <= 0 || !output_attachment_list || !output_attachment_count) { + EM_DEBUG_EXCEPTION("EM_STORAGE_ERROR_INVALID_PARAM"); + return EM_STORAGE_ERROR_INVALID_PARAM; + } + + int error = EM_STORAGE_ERROR_NONE; + int i = 0; + int rc = -1; + char **result = NULL; + char sql_query_string[QUERY_SIZE] = {0, }; + emf_mail_attachment_tbl_t* p_data_tbl = NULL; + DB_STMT hStmt = NULL; + sqlite3 *local_db_handle = em_storage_get_db_connection(); + + EM_STORAGE_START_READ_TRANSACTION(input_transaction); + SNPRINTF(sql_query_string, sizeof(sql_query_string), "SELECT COUNT(*) FROM mail_attachment_tbl WHERE mail_id = %d", input_mail_id); + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_get_table(local_db_handle, sql_query_string, &result, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;sqlite3_free_table(result);goto FINISH_OFF; }, + ("SQL(%s) sqlite3_get_table fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + *output_attachment_count = atoi(result[1]); + sqlite3_free_table(result); + + if(*output_attachment_count == 0) { + error = EM_STORAGE_ERROR_NONE; + goto FINISH_OFF; + } + + p_data_tbl = (emf_mail_attachment_tbl_t*)em_core_malloc(sizeof(emf_mail_attachment_tbl_t) * (*output_attachment_count)); + + if (!p_data_tbl) { + EM_DEBUG_EXCEPTION("em_core_malloc failed..."); + error = EM_STORAGE_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + SNPRINTF(sql_query_string, sizeof(sql_query_string), "SELECT * FROM mail_attachment_tbl WHERE mail_id = %d ORDER BY attachment_id", input_mail_id); + EM_DEBUG_LOG("sql_query_string [%s]", sql_query_string); + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_prepare_v2(local_db_handle, sql_query_string, strlen(sql_query_string), &hStmt, NULL), rc); + EM_DEBUG_DB_EXEC((SQLITE_OK != rc), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, ("SQL(%s) sqlite3_prepare fail:(%d) %s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_step(hStmt), rc); + EM_DEBUG_DB_EXEC((rc != SQLITE_ROW && rc != SQLITE_DONE), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, ("sqlite3_step fail:%d", rc)); + + if (rc == SQLITE_DONE) { + EM_DEBUG_EXCEPTION("no matched attachment found..."); + error = EM_STORAGE_ERROR_ATTACHMENT_NOT_FOUND; + goto FINISH_OFF; + } + for (i = 0; i < *output_attachment_count; i++) { + _getStmtFieldDataInt(hStmt, &(p_data_tbl[i].attachment_id), ATTACHMENT_ID_IDX_IN_MAIL_ATTACHMENT_TBL); + _getStmtFieldDataString(hStmt, &(p_data_tbl[i].attachment_name), 0, ATTACHMENT_NAME_IDX_IN_MAIL_ATTACHMENT_TBL); + _getStmtFieldDataString(hStmt, &(p_data_tbl[i].attachment_path), 0, ATTACHMENT_PATH_IDX_IN_MAIL_ATTACHMENT_TBL); + _getStmtFieldDataInt(hStmt, &(p_data_tbl[i].attachment_size), ATTACHMENT_SIZE_IDX_IN_MAIL_ATTACHMENT_TBL); + _getStmtFieldDataInt(hStmt, &(p_data_tbl[i].mail_id), MAIL_ID_IDX_IN_MAIL_ATTACHMENT_TBL); + _getStmtFieldDataInt(hStmt, &(p_data_tbl[i].account_id), ACCOUNT_ID_IDX_IN_MAIL_ATTACHMENT_TBL); + _getStmtFieldDataString(hStmt, &(p_data_tbl[i].mailbox_name), 0, MAILBOX_NAME_IDX_IN_MAIL_ATTACHMENT_TBL); + _getStmtFieldDataInt(hStmt, &(p_data_tbl[i].file_yn), FILE_YN_IDX_IN_MAIL_ATTACHMENT_TBL); + _getStmtFieldDataInt(hStmt, &(p_data_tbl[i].flag1), FLAG1_IDX_IN_MAIL_ATTACHMENT_TBL); + _getStmtFieldDataInt(hStmt, &(p_data_tbl[i].flag2), FLAG2_IDX_IN_MAIL_ATTACHMENT_TBL); + _getStmtFieldDataInt(hStmt, &(p_data_tbl[i].flag3), FLAG3_IDX_IN_MAIL_ATTACHMENT_TBL); + + EM_DEBUG_LOG("attachment[%d].attachment_id : %d", i, p_data_tbl[i].attachment_id); + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_step(hStmt), rc); + EM_DEBUG_DB_EXEC((rc != SQLITE_ROW && rc != SQLITE_DONE), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, ("sqlite3_step fail:%d", rc)); + } + +FINISH_OFF: + + if (error == EM_STORAGE_ERROR_NONE) + *output_attachment_list = p_data_tbl; + else if (p_data_tbl != NULL) + em_storage_free_attachment(&p_data_tbl, *output_attachment_count, NULL); + + rc = sqlite3_finalize(hStmt); + + if (rc != SQLITE_OK) { + EM_DEBUG_EXCEPTION("sqlite3_finalize failed [%d]", rc); + error = EM_STORAGE_ERROR_DB_FAILURE; + } + + EM_STORAGE_FINISH_READ_TRANSACTION(input_transaction); + + _DISCONNECT_DB; + + EM_DEBUG_FUNC_END("error [%d]", error); + return error; +} + +EXPORT_API int em_storage_get_attachment(int mail_id, int attachment_id, emf_mail_attachment_tbl_t** attachment, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("mail_id[%d], attachment_id[%d], attachment[%p], transaction[%d], err_code[%p]", mail_id, attachment_id, attachment, transaction, err_code); + + if (mail_id <= 0 || attachment_id <= 0 || !attachment) { + EM_DEBUG_EXCEPTION("mail_id[%d], attachment_id[%d], attachment[%p]", mail_id, attachment_id, attachment); + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + emf_mail_attachment_tbl_t* p_data_tbl = NULL; + char *p = NULL; + int rc, ret = false; + int error = EM_STORAGE_ERROR_NONE; + char sql_query_string[QUERY_SIZE] = {0, }; + + sqlite3 *local_db_handle = em_storage_get_db_connection(); + EM_STORAGE_START_READ_TRANSACTION(transaction); + + SNPRINTF(sql_query_string, sizeof(sql_query_string), "SELECT * FROM mail_attachment_tbl WHERE mail_id = %d AND attachment_id = %d", mail_id, attachment_id); + + sqlite3_stmt* hStmt = NULL; + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_prepare_v2(local_db_handle, sql_query_string, strlen(sql_query_string), &hStmt, NULL), rc); + EM_DEBUG_LOG(" before sqlite3_prepare hStmt = %p", hStmt); + + EM_DEBUG_DB_EXEC((SQLITE_OK != rc), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) sqlite3_prepare fail:(%d) %s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + /* rc = sqlite3_step(hStmt); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_step(hStmt), rc); + EM_DEBUG_DB_EXEC((rc != SQLITE_ROW && rc != SQLITE_DONE), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("sqlite3_step fail:%d", rc)); + + if (rc == SQLITE_DONE) { + EM_DEBUG_EXCEPTION("no matched attachment found..."); + error = EM_STORAGE_ERROR_ATTACHMENT_NOT_FOUND; + goto FINISH_OFF; + } + + if (!(p_data_tbl = (emf_mail_attachment_tbl_t*)malloc(sizeof(emf_mail_attachment_tbl_t) * 1))) { + EM_DEBUG_EXCEPTION("malloc failed..."); + error = EM_STORAGE_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + memset(p_data_tbl, 0x00, sizeof(emf_mail_attachment_tbl_t) * 1); + + p_data_tbl->attachment_id = sqlite3_column_int(hStmt, ATTACHMENT_ID_IDX_IN_MAIL_ATTACHMENT_TBL); + if ((p = (char *)sqlite3_column_text(hStmt, ATTACHMENT_NAME_IDX_IN_MAIL_ATTACHMENT_TBL)) && (int)strlen(p)) + p_data_tbl->attachment_name = cpy_str(p); + if ((p = (char *)sqlite3_column_text(hStmt, ATTACHMENT_PATH_IDX_IN_MAIL_ATTACHMENT_TBL)) && (int)strlen(p)) + p_data_tbl->attachment_path = cpy_str(p); + p_data_tbl->attachment_size = sqlite3_column_int(hStmt, ATTACHMENT_SIZE_IDX_IN_MAIL_ATTACHMENT_TBL); + p_data_tbl->mail_id = sqlite3_column_int(hStmt, MAIL_ID_IDX_IN_MAIL_ATTACHMENT_TBL); + p_data_tbl->account_id = sqlite3_column_int(hStmt, ACCOUNT_ID_IDX_IN_MAIL_ATTACHMENT_TBL); + if ((p = (char *)sqlite3_column_text(hStmt, MAILBOX_NAME_IDX_IN_MAIL_ATTACHMENT_TBL)) && (int)strlen(p)) + p_data_tbl->mailbox_name = cpy_str(p); + p_data_tbl->file_yn = sqlite3_column_int(hStmt, FILE_YN_IDX_IN_MAIL_ATTACHMENT_TBL); + p_data_tbl->flag1 = sqlite3_column_int(hStmt, FLAG1_IDX_IN_MAIL_ATTACHMENT_TBL); + p_data_tbl->flag2 = sqlite3_column_int(hStmt, FLAG2_IDX_IN_MAIL_ATTACHMENT_TBL); + p_data_tbl->flag3 = sqlite3_column_int(hStmt, FLAG3_IDX_IN_MAIL_ATTACHMENT_TBL); + +#ifdef __ATTACHMENT_OPTI__ + p_data_tbl->encoding = sqlite3_column_int(hStmt, ENCODING_IDX_IN_MAIL_ATTACHMENT_TBL); + if ((p = (char *)sqlite3_column_text(hStmt, SECTION_IDX_IN_MAIL_ATTACHMENT_TBL)) && (int)strlen(p)) + p_data_tbl->section= cpy_str(p); +#endif + + ret = true; + +FINISH_OFF: + if (ret == true) + *attachment = p_data_tbl; + + if (hStmt != NULL) { + EM_DEBUG_LOG("Before sqlite3_finalize hStmt = %p", hStmt); + + rc = sqlite3_finalize(hStmt); + if (rc != SQLITE_OK) { + EM_DEBUG_EXCEPTION("sqlite3_finalize failed - %d", rc); + error = EM_STORAGE_ERROR_DB_FAILURE; + } + } + + EM_STORAGE_FINISH_READ_TRANSACTION(transaction); + _DISCONNECT_DB; + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API int em_storage_get_attachment_nth(int mail_id, int nth, emf_mail_attachment_tbl_t** attachment_tbl, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("mail_id[%d], nth[%d], attachment_tbl[%p], transaction[%d], err_code[%p]", mail_id, nth, attachment_tbl, transaction, err_code); + + if (mail_id <= 0 || nth <= 0 || !attachment_tbl) { + EM_DEBUG_EXCEPTION(" mail_id[%d], nth[%d], attachment[%p]", mail_id, nth, attachment_tbl); + + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + emf_mail_attachment_tbl_t* p_data_tbl = NULL; + char *p = NULL; + int rc, ret = false; + int error = EM_STORAGE_ERROR_NONE; + char sql_query_string[QUERY_SIZE] = {0, }; + + sqlite3 *local_db_handle = em_storage_get_db_connection(); + EM_STORAGE_START_READ_TRANSACTION(transaction); + + SNPRINTF(sql_query_string, sizeof(sql_query_string), "SELECT * FROM mail_attachment_tbl WHERE mail_id = %d ORDER BY attachment_id LIMIT %d, 1", mail_id, (nth - 1)); + EM_DEBUG_LOG("query = [%s]", sql_query_string); + + DB_STMT hStmt = NULL; + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_prepare_v2(local_db_handle, sql_query_string, strlen(sql_query_string), &hStmt, NULL), rc); + EM_DEBUG_DB_EXEC((SQLITE_OK != rc), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) sqlite3_prepare fail:(%d) %s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + /* rc = sqlite3_step(hStmt); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_step(hStmt), rc); + EM_DEBUG_DB_EXEC((rc != SQLITE_ROW && rc != SQLITE_DONE), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("sqlite3_step fail:%d", rc)); + + if (rc == SQLITE_DONE) { + EM_DEBUG_EXCEPTION(" no matched attachment found..."); + error = EM_STORAGE_ERROR_ATTACHMENT_NOT_FOUND; + goto FINISH_OFF; + } + + if (!(p_data_tbl = (emf_mail_attachment_tbl_t*)malloc(sizeof(emf_mail_attachment_tbl_t) * 1))) { + EM_DEBUG_EXCEPTION(" malloc failed..."); + error = EM_STORAGE_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + memset(p_data_tbl, 0x00, sizeof(emf_mail_attachment_tbl_t) * 1); + + p_data_tbl->attachment_id = sqlite3_column_int(hStmt, ATTACHMENT_ID_IDX_IN_MAIL_ATTACHMENT_TBL); + if ((p = (char *)sqlite3_column_text(hStmt, ATTACHMENT_NAME_IDX_IN_MAIL_ATTACHMENT_TBL)) && (int)strlen(p)) + p_data_tbl->attachment_name = cpy_str(p); + if ((p = (char *)sqlite3_column_text(hStmt, ATTACHMENT_PATH_IDX_IN_MAIL_ATTACHMENT_TBL)) && (int)strlen(p)) + p_data_tbl->attachment_path = cpy_str(p); + p_data_tbl->attachment_size = sqlite3_column_int(hStmt, ATTACHMENT_SIZE_IDX_IN_MAIL_ATTACHMENT_TBL); + p_data_tbl->mail_id = sqlite3_column_int(hStmt, MAIL_ID_IDX_IN_MAIL_ATTACHMENT_TBL); + p_data_tbl->account_id = sqlite3_column_int(hStmt, ACCOUNT_ID_IDX_IN_MAIL_ATTACHMENT_TBL); + if ((p = (char *)sqlite3_column_text(hStmt, MAILBOX_NAME_IDX_IN_MAIL_ATTACHMENT_TBL)) && (int)strlen(p)) + p_data_tbl->mailbox_name = cpy_str(p); + p_data_tbl->file_yn = sqlite3_column_int(hStmt, FILE_YN_IDX_IN_MAIL_ATTACHMENT_TBL); + p_data_tbl->flag1 = sqlite3_column_int(hStmt, FLAG1_IDX_IN_MAIL_ATTACHMENT_TBL); + p_data_tbl->flag2 = sqlite3_column_int(hStmt, FLAG2_IDX_IN_MAIL_ATTACHMENT_TBL); + p_data_tbl->flag3 = sqlite3_column_int(hStmt, FLAG3_IDX_IN_MAIL_ATTACHMENT_TBL); + +#ifdef __ATTACHMENT_OPTI__ + p_data_tbl->encoding = sqlite3_column_int(hStmt, ENCODING_IDX_IN_MAIL_ATTACHMENT_TBL); + if ((p = (char *)sqlite3_column_text(hStmt, SECTION_IDX_IN_MAIL_ATTACHMENT_TBL)) && (int)strlen(p)) + p_data_tbl->section= cpy_str(p); +#endif + ret = true; + +FINISH_OFF: + if (ret == true) + *attachment_tbl = p_data_tbl; + else if (p_data_tbl != NULL) + em_storage_free_attachment(&p_data_tbl, 1, NULL); + + if (hStmt != NULL) { + EM_DEBUG_LOG("before sqlite3_finalize hStmt = %p", hStmt); + + rc = sqlite3_finalize(hStmt); + if (rc != SQLITE_OK) { + EM_DEBUG_EXCEPTION("sqlite3_finalize failed - %d", rc); + error = EM_STORAGE_ERROR_DB_FAILURE; + } + } + + EM_STORAGE_FINISH_READ_TRANSACTION(transaction); + _DISCONNECT_DB; + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API int em_storage_change_attachment_field(int mail_id, emf_mail_change_type_t type, emf_mail_attachment_tbl_t* attachment, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("mail_id[%d], type[%d], attachment[%p], transaction[%d], err_code[%p]", mail_id, type, attachment, transaction, err_code); + + if (mail_id <= 0 || !attachment) { + EM_DEBUG_EXCEPTION(" mail_id[%d], type[%d], attachment[%p]", mail_id, type, attachment); + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false;; + } + + int rc, ret = false; + int error = EM_STORAGE_ERROR_NONE; + DB_STMT hStmt = NULL; + char sql_query_string[QUERY_SIZE] = {0, }; + + int i = 0; + + sqlite3 *local_db_handle = em_storage_get_db_connection(); + + EM_STORAGE_START_WRITE_TRANSACTION(transaction, error); + + switch (type) { + case UPDATE_MAILBOX: + EM_DEBUG_LOG("UPDATE_MAILBOX"); + if (!attachment->mailbox_name) { + EM_DEBUG_EXCEPTION(" attachment->mailbox_name[%p]", attachment->mailbox_name); + error = EM_STORAGE_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } +#ifdef CONVERT_UTF8_TO_UCS2 + SNPRINTF(sql_query_string, sizeof(sql_query_string), + "UPDATE mail_attachment_tbl SET mailbox_name = '%s' WHERE mail_id = %d", attachment->mailbox_name, mail_id); +#else /* CONVERT_UTF8_TO_UCS2 */ + SNPRINTF(sql_query_string, sizeof(sql_query_string), + "UPDATE mail_attachment_tbl SET mailbox_name = ? WHERE mail_id = %d", mail_id); + + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_prepare_v2(local_db_handle, sql_query_string, strlen(sql_query_string), &hStmt, NULL), rc); + EM_DEBUG_LOG(" Before sqlite3_prepare hStmt = %p", hStmt); + EM_DEBUG_DB_EXEC((SQLITE_OK != rc), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) sqlite3_prepare fail:(%d) %s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + _bindStmtFieldDataString(hStmt, i++, (char *)attachment->mailbox_name, 0, MAILBOX_NAME_LEN_IN_MAIL_ATTACHMENT_TBL); +#endif /* CONVERT_UTF8_TO_UCS2 */ + break; + + case UPDATE_SAVENAME: + EM_DEBUG_LOG("UPDATE_SAVENAME"); + if (!attachment->attachment_path) { + EM_DEBUG_EXCEPTION(" attachment->attachment_path[%p]", attachment->attachment_path); + error = EM_STORAGE_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + +#ifdef CONVERT_UTF8_TO_UCS2 + SNPRINTF(sql_query_string, sizeof(sql_query_string), + "UPDATE mail_attachment_tbl SET" + " attachment_size = %d" + ", attachment_path = '%s'" + ", file_yn = 1" + " WHERE mail_id = %d" + " AND attachment_id = %d" + , attachment->attachment_size + , attachment->attachment_path + , attachment->mail_id + , attachment->attachment_id); +#else /* CONVERT_UTF8_TO_UCS2 */ + SNPRINTF(sql_query_string, sizeof(sql_query_string), + "UPDATE mail_attachment_tbl SET" + " attachment_size = ?" + ", file_yn = 1" + ", attachment_path = ?" + " WHERE mail_id = %d" + " AND attachment_id = %d" + , attachment->mail_id + , attachment->attachment_id); + + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_prepare_v2(local_db_handle, sql_query_string, strlen(sql_query_string), &hStmt, NULL), rc); + EM_DEBUG_LOG(" Before sqlite3_prepare hStmt = %p", hStmt); + EM_DEBUG_DB_EXEC((SQLITE_OK != rc), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) sqlite3_prepare fail:(%d) %s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + _bindStmtFieldDataInt(hStmt, i++, attachment->attachment_size); + _bindStmtFieldDataString(hStmt, i++, (char *)attachment->attachment_path, 0, ATTACHMENT_PATH_LEN_IN_MAIL_ATTACHMENT_TBL); +#endif /* CONVERT_UTF8_TO_UCS2 */ + break; + + default: + EM_DEBUG_LOG("type[%d]", type); + error = EM_STORAGE_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + EM_DEBUG_LOG("query = [%s]", sql_query_string); + +#ifdef CONVERT_UTF8_TO_UCS2 + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, sql_query_string, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) exec fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); +#else + /* rc = sqlite3_step(hStmt); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_step(hStmt), rc); + EM_DEBUG_DB_EXEC((rc != SQLITE_ROW && rc != SQLITE_DONE), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("sqlite3_step fail:%d", rc)); +#endif + ret = true; + +FINISH_OFF: +#ifdef CONVERT_UTF8_TO_UCS2 +#else /* CONVERT_UTF8_TO_UCS2 */ + if (hStmt != NULL) { + EM_DEBUG_LOG(" Before sqlite3_finalize hStmt = %p", hStmt); + rc = sqlite3_finalize(hStmt); + if (rc != SQLITE_OK) { + EM_DEBUG_LOG(" sqlite3_finalize failed - %d", rc); + error = EM_STORAGE_ERROR_DB_FAILURE; + } + } +#endif /* CONVERT_UTF8_TO_UCS2 */ + + EM_STORAGE_FINISH_WRITE_TRANSACTION(transaction, ret, error); + _DISCONNECT_DB; + + if (err_code != NULL) + *err_code = error; + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + + +EXPORT_API int em_storage_rename_mailbox(int account_id, char *old_mailbox_name, char *new_mailbox_name, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id[%d], old_mailbox_name[%p], new_mailbox_name[%p], transaction[%d], err_code[%p]", account_id, old_mailbox_name, new_mailbox_name, transaction, err_code); + + if (account_id < FIRST_ACCOUNT_ID ||!old_mailbox_name || !new_mailbox_name) { + EM_DEBUG_EXCEPTION("Invalid Parameters"); + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + int rc, ret = true; + int error = EM_STORAGE_ERROR_NONE; + char sql_query_string[QUERY_SIZE] = {0, }; + + sqlite3 *local_db_handle = em_storage_get_db_connection(); + + EM_STORAGE_START_WRITE_TRANSACTION(transaction, error); + + SNPRINTF(sql_query_string, sizeof(sql_query_string), + "UPDATE mail_tbl SET" + " mailbox_name = '%s'" + " WHERE account_id = %d" + " AND mailbox_name = '%s'" + , new_mailbox_name + , account_id + , old_mailbox_name); + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, sql_query_string, NULL, NULL, NULL), rc); + + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) exec fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + if (sqlite3_changes(local_db_handle) == 0) + EM_DEBUG_LOG("no mail matched..."); + + + SNPRINTF(sql_query_string, sizeof(sql_query_string), + "UPDATE mail_attachment_tbl SET" + " mailbox_name = '%s'" + " WHERE account_id = %d" + " AND mailbox_name = '%s'" + , new_mailbox_name + , account_id + , old_mailbox_name); + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, sql_query_string, NULL, NULL, NULL), rc); + + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) exec fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + if (sqlite3_changes(local_db_handle) == 0) + EM_DEBUG_LOG("no attachment matched..."); + + SNPRINTF(sql_query_string, sizeof(sql_query_string), + "UPDATE mail_meeting_tbl SET" + " mailbox_name = '%s'" + " WHERE account_id = %d" + " AND mailbox_name = '%s'" + , new_mailbox_name + , account_id + , old_mailbox_name); + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, sql_query_string, NULL, NULL, NULL), rc); + + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) exec fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + if (sqlite3_changes(local_db_handle) == 0) + EM_DEBUG_LOG("no mail_meeting_tbl matched..."); + + ret = true; + +FINISH_OFF: + + EM_STORAGE_FINISH_WRITE_TRANSACTION(transaction, ret, error); + _DISCONNECT_DB; + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + + +EXPORT_API int em_storage_change_attachment_mbox(int account_id, char *old_mailbox_name, char *new_mailbox_name, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id[%d], old_mailbox_name[%p], new_mailbox_name[%p], transaction[%d], err_code[%p]", account_id, old_mailbox_name, new_mailbox_name, transaction, err_code); + + if (account_id < FIRST_ACCOUNT_ID || !old_mailbox_name || !new_mailbox_name) { + EM_DEBUG_EXCEPTION(" account_id[%d], old_mailbox_name[%p], new_mailbox_name[%p]", account_id, old_mailbox_name, new_mailbox_name); + + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + int rc, ret = true; + int error = EM_STORAGE_ERROR_NONE; + char sql_query_string[QUERY_SIZE] = {0, }; + + sqlite3 *local_db_handle = em_storage_get_db_connection(); + + EM_STORAGE_START_WRITE_TRANSACTION(transaction, error); + + SNPRINTF(sql_query_string, sizeof(sql_query_string), + "UPDATE mail_attachment_tbl SET" + " mailbox_name = '%s'" + " WHERE account_id = %d" + " AND mailbox_name = '%s'" + , new_mailbox_name + , account_id + , old_mailbox_name); + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, sql_query_string, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC((SQLITE_FULL == rc), {error = EM_STORAGE_ERROR_DB_IS_FULL;goto FINISH_OFF; }, + ("sqlite3_exec fail:%d", rc)); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) exec fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + rc = sqlite3_changes(local_db_handle); + if (rc == 0) { + EM_DEBUG_EXCEPTION(" no attachment found..."); + } + + ret = true; + +FINISH_OFF: + + EM_STORAGE_FINISH_WRITE_TRANSACTION(transaction, ret, error); + _DISCONNECT_DB; + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + + +EXPORT_API int em_storage_get_new_attachment_no(int *attachment_no, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("attachment_no [%p], err_code[%p]", attachment_no, err_code); + int rc, ret = false; + int error = EM_STORAGE_ERROR_NONE; + char *sql = "SELECT max(rowid) FROM mail_attachment_tbl;"; + char **result; + + if (!attachment_no) { + EM_DEBUG_EXCEPTION("Invalid attachment"); + error = EM_STORAGE_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + *attachment_no = -1; + + sqlite3 *local_db_handle = em_storage_get_db_connection(); + + /* rc = sqlite3_get_table(local_db_handle, sql, &result, NULL, NULL, NULL); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_get_table(local_db_handle, sql, &result, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;sqlite3_free_table(result);goto FINISH_OFF; }, + ("SQL(%s) sqlite3_get_table fail:%d -%s", sql, rc, sqlite3_errmsg(local_db_handle))); + + if (NULL == result[1]) + rc = 1; + else + rc = atoi(result[1])+1; + + sqlite3_free_table(result); + + *attachment_no = rc; + EM_DEBUG_LOG("attachment_no [%d]", *attachment_no); + ret = true; + +FINISH_OFF: + _DISCONNECT_DB; + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API int em_storage_add_attachment(emf_mail_attachment_tbl_t* attachment_tbl, int iscopy, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("attachment_tbl[%p], iscopy[%d], transaction[%d], err_code[%p]", attachment_tbl, iscopy, transaction, err_code); + + char *sql = NULL; + char **result; + int rc, ret = false; + int error = EM_STORAGE_ERROR_NONE; + DB_STMT hStmt = NULL; + char sql_query_string[QUERY_SIZE] = {0, }; + sqlite3 *local_db_handle = em_storage_get_db_connection(); + + if (!attachment_tbl) { + EM_DEBUG_EXCEPTION("attachment_tbl[%p], iscopy[%d]", attachment_tbl, iscopy); + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + EM_STORAGE_START_WRITE_TRANSACTION(transaction, error); + + sql = "SELECT max(rowid) FROM mail_attachment_tbl;"; + /* rc = sqlite3_get_table(local_db_handle, sql, &result, NULL, NULL, NULL); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_get_table(local_db_handle, sql, &result, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;sqlite3_free_table(result);goto FINISH_OFF; }, + ("SQL(%s) sqlite3_get_table fail:%d -%s", sql, rc, sqlite3_errmsg(local_db_handle))); + + if (NULL==result[1]) rc = 1; + else rc = atoi(result[1]) + 1; + sqlite3_free_table(result); + + attachment_tbl->attachment_id = rc; + + SNPRINTF(sql_query_string, sizeof(sql_query_string), + "INSERT INTO mail_attachment_tbl VALUES " + "( ?" /* attachment_id */ + ", ?" /* attachment_name */ + ", ?" /* attachment_path */ + ", ?" /* attachment_size */ + ", ?" /* mail_id */ + ", ?" /* account_id */ + ", ?" /* mailbox_name */ + ", ?" /* file_yn */ + ", ?" /* flag1 */ + ", ?" /* flag2 */ +#ifdef __ATTACHMENT_OPTI__ + ", ?" + ", ?" +#endif + ", ? )");/* flag3 */ + + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_prepare_v2(local_db_handle, sql_query_string, strlen(sql_query_string), &hStmt, NULL), rc); + EM_DEBUG_DB_EXEC((SQLITE_OK != rc), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) sqlite3_prepare fail:(%d) %s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + _bindStmtFieldDataInt(hStmt, ATTACHMENT_ID_IDX_IN_MAIL_ATTACHMENT_TBL, attachment_tbl->attachment_id); + _bindStmtFieldDataString(hStmt, ATTACHMENT_NAME_IDX_IN_MAIL_ATTACHMENT_TBL, (char *)attachment_tbl->attachment_name, 0, ATTACHMENT_NAME_LEN_IN_MAIL_ATTACHMENT_TBL); + _bindStmtFieldDataString(hStmt, ATTACHMENT_PATH_IDX_IN_MAIL_ATTACHMENT_TBL, (char *)attachment_tbl->attachment_path, 0, ATTACHMENT_PATH_LEN_IN_MAIL_ATTACHMENT_TBL); + _bindStmtFieldDataInt(hStmt, ATTACHMENT_SIZE_IDX_IN_MAIL_ATTACHMENT_TBL, attachment_tbl->attachment_size); + _bindStmtFieldDataInt(hStmt, MAIL_ID_IDX_IN_MAIL_ATTACHMENT_TBL, attachment_tbl->mail_id); + _bindStmtFieldDataInt(hStmt, ACCOUNT_ID_IDX_IN_MAIL_ATTACHMENT_TBL, attachment_tbl->account_id); + _bindStmtFieldDataString(hStmt, MAILBOX_NAME_IDX_IN_MAIL_ATTACHMENT_TBL, (char *)attachment_tbl->mailbox_name, 0, MAILBOX_NAME_LEN_IN_MAIL_ATTACHMENT_TBL); + _bindStmtFieldDataInt(hStmt, FILE_YN_IDX_IN_MAIL_ATTACHMENT_TBL, attachment_tbl->file_yn); + _bindStmtFieldDataInt(hStmt, FLAG1_IDX_IN_MAIL_ATTACHMENT_TBL, attachment_tbl->flag1); + _bindStmtFieldDataInt(hStmt, FLAG2_IDX_IN_MAIL_ATTACHMENT_TBL, attachment_tbl->flag2); + _bindStmtFieldDataInt(hStmt, FLAG3_IDX_IN_MAIL_ATTACHMENT_TBL, attachment_tbl->flag3); +#ifdef __ATTACHMENT_OPTI__ + _bindStmtFieldDataInt(hStmt, ENCODING_IDX_IN_MAIL_ATTACHMENT_TBL, attachment_tbl->encoding); + _bindStmtFieldDataString(hStmt, SECTION_IDX_IN_MAIL_ATTACHMENT_TBL, (char *)attachment_tbl->section, 0, ATTACHMENT_LEN_IN_MAIL_ATTACHMENT_TBL); +#endif + + /* rc = sqlite3_step(hStmt); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_step(hStmt), rc); + EM_DEBUG_DB_EXEC((SQLITE_FULL == rc), {error = EM_STORAGE_ERROR_DB_IS_FULL;goto FINISH_OFF; }, + ("sqlite3_step fail:%d", rc)); + EM_DEBUG_DB_EXEC((rc != SQLITE_ROW && rc != SQLITE_DONE), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("sqlite3_step fail:%d", rc)); +/* + SNPRINTF(sql_query_string, sizeof(sql_query_string), + "UPDATE mail_tbl SET attachment_count = 1 WHERE mail_id = %d", attachment_tbl->mail_id); + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, sql_query_string, NULL, NULL, NULL), rc); + + EM_DEBUG_DB_EXEC((SQLITE_FULL == rc), {error = EM_STORAGE_ERROR_DB_IS_FULL;goto FINISH_OFF; }, + ("sqlite3_exec fail:%d", rc)); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) exec fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); +*/ + rc = sqlite3_changes(local_db_handle); + if (rc == 0) { + EM_DEBUG_EXCEPTION(" no matched mail found..."); + error = EM_STORAGE_ERROR_MAIL_NOT_FOUND; + goto FINISH_OFF; + } + + ret = true; + +FINISH_OFF: + if (hStmt != NULL) { + rc = sqlite3_finalize(hStmt); + if (rc != SQLITE_OK) { + EM_DEBUG_EXCEPTION(" sqlite3_finalize failed - %d", rc); + error = EM_STORAGE_ERROR_DB_FAILURE; + } + } + + EM_STORAGE_FINISH_WRITE_TRANSACTION(transaction, ret, error); + _DISCONNECT_DB; + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API int em_storage_update_attachment(emf_mail_attachment_tbl_t* attachment_tbl, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("attachment_tbl[%p], transaction[%d], err_code[%p]", attachment_tbl, transaction, err_code); + + int rc, ret = false, field_idx = 0; + int error = EM_STORAGE_ERROR_NONE; + DB_STMT hStmt = NULL; + char sql_query_string[QUERY_SIZE] = {0, }; + + if (!attachment_tbl) { + EM_DEBUG_EXCEPTION(" attachment_tbl[%p] ", attachment_tbl); + error = EM_STORAGE_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + sqlite3 *local_db_handle = em_storage_get_db_connection(); + + EM_STORAGE_START_WRITE_TRANSACTION(transaction, error); + + SNPRINTF(sql_query_string, sizeof(sql_query_string), + "UPDATE mail_attachment_tbl SET " + " attachment_name = ?" + ", attachment_path = ?" + ", attachment_size = ?" + ", mail_id = ?" + ", account_id = ?" + ", mailbox_name = ?" + ", file_yn = ?" + ", flag1 = ?" + ", flag2 = ?" + ", flag3 = ? " + " WHERE attachment_id = ?;"); + + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_prepare_v2(local_db_handle, sql_query_string, strlen(sql_query_string), &hStmt, NULL), rc); + + EM_DEBUG_DB_EXEC((SQLITE_OK != rc), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) sqlite3_prepare fail:(%d) %s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + _bindStmtFieldDataString(hStmt, field_idx++ , (char *)attachment_tbl->attachment_name, 0, ATTACHMENT_NAME_LEN_IN_MAIL_ATTACHMENT_TBL); + _bindStmtFieldDataString(hStmt, field_idx++ , (char *)attachment_tbl->attachment_path, 0, ATTACHMENT_PATH_LEN_IN_MAIL_ATTACHMENT_TBL); + _bindStmtFieldDataInt(hStmt, field_idx++ , attachment_tbl->attachment_size); + _bindStmtFieldDataInt(hStmt, field_idx++ , attachment_tbl->mail_id); + _bindStmtFieldDataInt(hStmt, field_idx++ , attachment_tbl->account_id); + _bindStmtFieldDataString(hStmt, field_idx++ , (char *)attachment_tbl->mailbox_name, 0, MAILBOX_NAME_LEN_IN_MAIL_ATTACHMENT_TBL); + _bindStmtFieldDataInt(hStmt, field_idx++ , attachment_tbl->file_yn); + _bindStmtFieldDataInt(hStmt, field_idx++ , attachment_tbl->flag1); + _bindStmtFieldDataInt(hStmt, field_idx++ , attachment_tbl->flag2); + _bindStmtFieldDataInt(hStmt, field_idx++ , attachment_tbl->flag3); + _bindStmtFieldDataInt(hStmt, field_idx++ , attachment_tbl->attachment_id); + + /* rc = sqlite3_step(hStmt); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_step(hStmt), rc); + EM_DEBUG_DB_EXEC((SQLITE_FULL == rc), {error = EM_STORAGE_ERROR_DB_IS_FULL;goto FINISH_OFF; }, + ("sqlite3_step fail:%d", rc)); + EM_DEBUG_DB_EXEC((rc != SQLITE_ROW && rc != SQLITE_DONE), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("sqlite3_step fail:%d", rc)); +/* + SNPRINTF(sql_query_string, sizeof(sql_query_string), + "UPDATE mail_tbl SET attachment_count = 1 WHERE mail_id = %d", attachment_tbl->mail_id); + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, sql_query_string, NULL, NULL, NULL), rc); + + EM_DEBUG_DB_EXEC((SQLITE_FULL == rc), {error = EM_STORAGE_ERROR_DB_IS_FULL;goto FINISH_OFF; }, + ("sqlite3_exec fail:%d", rc)); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) exec fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); +*/ + rc = sqlite3_changes(local_db_handle); + if (rc == 0) { + EM_DEBUG_EXCEPTION(" no matched mail found..."); + error = EM_STORAGE_ERROR_MAIL_NOT_FOUND; + goto FINISH_OFF; + } + + ret = true; + +FINISH_OFF: + if (hStmt != NULL) { + rc = sqlite3_finalize(hStmt); + if (rc != SQLITE_OK) { + EM_DEBUG_EXCEPTION(" sqlite3_finalize failed - %d", rc); + error = EM_STORAGE_ERROR_DB_FAILURE; + } + } + + EM_STORAGE_FINISH_WRITE_TRANSACTION(transaction, ret, error); + _DISCONNECT_DB; + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API int em_storage_delete_attachment_on_db(int mail_id, int attachment_id, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("mail_id[%d], attachment_id[%d], transaction[%d], err_code[%p]", mail_id, attachment_id, transaction, err_code); + + if (mail_id < 0 || attachment_id < 0) { + EM_DEBUG_EXCEPTION("mail_id[%d], attachment_id[%d]", mail_id, attachment_id); + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + int rc, ret = false; + int error = EM_STORAGE_ERROR_NONE; + char sql_query_string[QUERY_SIZE] = {0, }; + + sqlite3 *local_db_handle = em_storage_get_db_connection(); + + EM_STORAGE_START_WRITE_TRANSACTION(transaction, error); + + SNPRINTF(sql_query_string, sizeof(sql_query_string), "DELETE FROM mail_attachment_tbl"); + + if (mail_id) /* '0' means all mail */ + SNPRINTF(sql_query_string + strlen(sql_query_string), sizeof(sql_query_string)-(strlen(sql_query_string)+1), " WHERE mail_id = %d", mail_id); + if (attachment_id) /* '0' means all attachment */ + SNPRINTF(sql_query_string + strlen(sql_query_string), sizeof(sql_query_string)-(strlen(sql_query_string)+1), " AND attachment_id = %d", attachment_id); + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, sql_query_string, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) exec fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + ret = true; + +FINISH_OFF: + EM_STORAGE_FINISH_WRITE_TRANSACTION(transaction, ret, error); + _DISCONNECT_DB; + + if (err_code) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API int em_storage_delete_attachment_all_on_db(int account_id, char *mbox, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id[%d], mbox[%p], transaction[%d], err_code[%p]", account_id, mbox, transaction, err_code); + + int error = EM_STORAGE_ERROR_NONE; + int rc, ret = false; + char sql_query_string[QUERY_SIZE] = {0, }; + + sqlite3 *local_db_handle = em_storage_get_db_connection(); + + EM_STORAGE_START_WRITE_TRANSACTION(transaction, error); + + SNPRINTF(sql_query_string, sizeof(sql_query_string), "DELETE FROM mail_attachment_tbl"); + + if (account_id != ALL_ACCOUNT) /* '0' means all account */ + SNPRINTF(sql_query_string + strlen(sql_query_string), sizeof(sql_query_string)-(strlen(sql_query_string)+1), " WHERE account_id = %d", account_id); + + if (mbox) /* NULL means all mailbox_name */ + SNPRINTF(sql_query_string + strlen(sql_query_string), sizeof(sql_query_string)-(strlen(sql_query_string)+1), " %s mailbox_name = '%s'", account_id != ALL_ACCOUNT ? "AND" : "WHERE", mbox); + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, sql_query_string, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) exec fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + ret = true; + +FINISH_OFF: + EM_STORAGE_FINISH_WRITE_TRANSACTION(transaction, ret, error); + _DISCONNECT_DB; + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API int em_storage_free_attachment(emf_mail_attachment_tbl_t** attachment_tbl_list, int count, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("attachment_tbl_list[%p], count[%d], err_code[%p]", attachment_tbl_list, count, err_code); + + if (count > 0) { + if ((attachment_tbl_list == NULL) || (*attachment_tbl_list == NULL)) { + EM_DEBUG_EXCEPTION(" attachment_tbl_list[%p], count[%d]", attachment_tbl_list, count); + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + emf_mail_attachment_tbl_t* p = *attachment_tbl_list; + int i; + + for (i = 0; i < count; i++) { + EM_SAFE_FREE(p[i].mailbox_name); + EM_SAFE_FREE(p[i].attachment_name); + EM_SAFE_FREE(p[i].attachment_path); +#ifdef __ATTACHMENT_OPTI__ + EM_SAFE_FREE(p[i].section); +#endif + } + + EM_SAFE_FREE(p); + *attachment_tbl_list = NULL; + } + + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_NONE; + EM_DEBUG_FUNC_END(); + return true; +} + + + +EXPORT_API int em_storage_begin_transaction(void *d1, void *d2, int *err_code) +{ + EM_PROFILE_BEGIN(emStorageBeginTransaction); + int ret = true; + + ENTER_CRITICAL_SECTION(_transactionBeginLock); + + /* wait for the trnasaction authority to be changed. */ + while (g_transaction) { + EM_DEBUG_LOG(">>>>>>>> Wait for the transaction authority to be changed"); + usleep(50000); + } + + /* take the transaction authority. */ + g_transaction = true; + + LEAVE_CRITICAL_SECTION(_transactionBeginLock); + + sqlite3 *local_db_handle = em_storage_get_db_connection(); + int rc; + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, "BEGIN immediate;", NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {ret = false; }, + ("SQL(BEGIN) exec error:%d -%s", rc, sqlite3_errmsg(local_db_handle))); + if (ret == false && err_code != NULL) + *err_code = EM_STORAGE_ERROR_DB_FAILURE; + + EM_PROFILE_END(emStorageBeginTransaction); + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API int em_storage_commit_transaction(void *d1, void *d2, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN(); + int ret = true; + sqlite3 *local_db_handle = em_storage_get_db_connection(); + + ENTER_CRITICAL_SECTION(_transactionEndLock); + + int rc; + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, "END;", NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {ret = false; }, ("SQL(END) exec error:%d -%s", rc, sqlite3_errmsg(local_db_handle))); + /* release the transaction authority. */ + g_transaction = false; + + LEAVE_CRITICAL_SECTION(_transactionEndLock); + if (ret == false && err_code != NULL) + *err_code = EM_STORAGE_ERROR_DB_FAILURE; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API int em_storage_rollback_transaction(void *d1, void *d2, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN(); + int ret = true; + sqlite3 *local_db_handle = em_storage_get_db_connection(); + int rc; + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, "ROLLBACK;", NULL, NULL, NULL), rc); + + ENTER_CRITICAL_SECTION(_transactionEndLock); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {ret = false; }, + ("SQL(ROLLBACK) exec error:%d -%s", rc, sqlite3_errmsg(local_db_handle))); + + /* release the transaction authority. */ + g_transaction = false; + + LEAVE_CRITICAL_SECTION(_transactionEndLock); + + if (ret == false && err_code != NULL) + *err_code = EM_STORAGE_ERROR_DB_FAILURE; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API int em_storage_is_mailbox_full(int account_id, emf_mailbox_t* mailbox_name, int *result, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id[%d], mailbox_name[%p], result[%p], err_code[%p]", account_id, mailbox_name, result, err_code); + + if (account_id < FIRST_ACCOUNT_ID || !mailbox_name || !result) { + if (mailbox_name) + EM_DEBUG_EXCEPTION("Invalid Parameter. accoun_id[%d], mailbox_name[%p]", account_id, mailbox_name); + + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + + return false; + } + + int ret = false; + int error = EM_STORAGE_ERROR_NONE; + int mail_count = 0; + + if (!em_storage_get_mail_count(account_id, mailbox_name->name, &mail_count, NULL, true, &error)) { + EM_DEBUG_EXCEPTION("em_storage_get_mail_count failed [%d]", error); + goto FINISH_OFF; + } + + if (mailbox_name) { + EM_DEBUG_LOG("mail_count[%d] mail_slot_size[%d]", mail_count, mailbox_name->mail_slot_size); + if (mail_count >= mailbox_name->mail_slot_size) + *result = true; + else + *result = false; + + ret = true; + } + + ret = true; +FINISH_OFF: + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API int em_storage_clear_mail_data(int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("transaction[%d], err_code[%p]", transaction, err_code); + + int rc, ret = false; + int error = EM_STORAGE_ERROR_NONE; + char sql_query_string[QUERY_SIZE] = {0, }; + + const emf_db_object_t* tables = _g_db_tables; + const emf_db_object_t* indexes = _g_db_indexes; + char data_path[256]; + + sqlite3 *local_db_handle = em_storage_get_db_connection(); + EM_STORAGE_START_WRITE_TRANSACTION(transaction, error); + + if (!em_storage_delete_dir(MAILHOME, &error)) { + EM_DEBUG_EXCEPTION(" em_storage_delete_dir failed - %d", error); + + goto FINISH_OFF; + } + + SNPRINTF(data_path, sizeof(data_path), "%s/%s", MAILHOME, MAILTEMP); + + mkdir(MAILHOME, DIRECTORY_PERMISSION); + mkdir(data_path, DIRECTORY_PERMISSION); + + /* first clear index. */ + while (indexes->object_name) { + if (indexes->data_flag) { + SNPRINTF(sql_query_string, sizeof(sql_query_string), "DROP index %s", indexes->object_name); + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, sql_query_string, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) exec fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + } + indexes++; + } + + while (tables->object_name) { + if (tables->data_flag) { + SNPRINTF(sql_query_string, sizeof(sql_query_string), "DROP table %s", tables->object_name); + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, sql_query_string, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) exec fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + } + + tables++; + } + ret = true; + +FINISH_OFF: + EM_STORAGE_FINISH_WRITE_TRANSACTION(transaction, ret, error); + _DISCONNECT_DB; + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} +/*======================= DB File Utils =============================================*/ +#include <dirent.h> +#include <sys/types.h> +#define DIR_SEPERATOR "/" + +char *__em_create_dir_by_file_name(char *file_name) +{ + EM_DEBUG_FUNC_BEGIN("Filename [ %p ]", file_name); + char delims[] = "/"; + char *result = NULL; + + result = strtok(file_name, delims); + + if (result) + EM_DEBUG_LOG(">>>> Directory_name [ %s ]", result); + else + EM_DEBUG_LOG(">>>> No Need to create Directory"); + + return result; +} + +EXPORT_API int em_storage_get_save_name(int account_id, int mail_id, int atch_id, char *fname, char *name_buf, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id[%d], mail_id[%d], atch_id[%d], fname[%s], name_buf[%p], err_code[%p]", account_id, mail_id, atch_id, fname, name_buf, err_code); + EM_PROFILE_BEGIN(profile_em_storage_get_save_name); + + int ret = false; + int error = EM_STORAGE_ERROR_NONE; + char *dir_name = NULL; + char create_dir[1024]={0}; + char *temp_file = NULL; + + if (!name_buf || account_id < FIRST_ACCOUNT_ID || mail_id < 0 || atch_id < 0) { + EM_DEBUG_EXCEPTION(" account_id[%d], mail_id[%d], atch_id[%d], fname[%p], name_buf[%p]", account_id, mail_id, atch_id, fname, name_buf); + error = EM_STORAGE_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + sprintf(name_buf, "%s", MAILHOME); + sprintf(name_buf+strlen(name_buf), "%s%d", DIR_SEPERATOR, account_id); + + if (mail_id > 0) + sprintf(name_buf+strlen(name_buf), "%s%d", DIR_SEPERATOR, mail_id); + + if (atch_id > 0) + sprintf(name_buf+strlen(name_buf), "%s%d", DIR_SEPERATOR, atch_id); + + if (fname) { + temp_file = EM_SAFE_STRDUP(fname); + if (strstr(temp_file, "/")) { + dir_name = __em_create_dir_by_file_name(temp_file); + } + } + + if (dir_name) { + sprintf(create_dir, "%s%s%s", name_buf, DIR_SEPERATOR, dir_name); + EM_DEBUG_LOG(">>>>> DIR PATH [ %s ]", create_dir); + mkdir(create_dir, DIRECTORY_PERMISSION); + EM_SAFE_FREE(temp_file); + } + + + if (fname) { + EM_DEBUG_LOG(">>>>> fname [ %s ]", fname); + sprintf(name_buf+strlen(name_buf), "%s%s", DIR_SEPERATOR, fname); + } + + + EM_DEBUG_LOG(">>>>> name_buf [ %s ]", name_buf); + + ret = true; + +FINISH_OFF: + EM_SAFE_FREE(temp_file); + + if (err_code != NULL) + *err_code = error; + + EM_PROFILE_END(profile_em_storage_get_save_name); + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API int em_storage_get_dele_name(int account_id, int mail_id, int atch_id, char *fname, char *name_buf, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id[%d], mail_id[%d], atch_id[%d], fname[%p], name_buf[%p], err_code[%p]", account_id, mail_id, atch_id, fname, name_buf, err_code); + + if (!name_buf || account_id < FIRST_ACCOUNT_ID) { + EM_DEBUG_EXCEPTION(" account_id[%d], mail_id[%d], atch_id[%d], fname[%p], name_buf[%p]", account_id, mail_id, atch_id, fname, name_buf); + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + sprintf(name_buf+strlen(name_buf), "%s%s%d", MAILHOME, DIR_SEPERATOR, account_id); + + if (mail_id > 0) + sprintf(name_buf+strlen(name_buf), "%s%d", DIR_SEPERATOR, mail_id); + else + goto FINISH_OFF; + + if (atch_id > 0) + sprintf(name_buf+strlen(name_buf), "%s%d", DIR_SEPERATOR, atch_id); + else + goto FINISH_OFF; + +FINISH_OFF: + sprintf(name_buf+strlen(name_buf), ".DELE"); + + EM_DEBUG_FUNC_END(); + return true; +} + +EXPORT_API int em_storage_create_dir(int account_id, int mail_id, int atch_id, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id[%d], mail_id[%d], atch_id[%d], err_code[%p]", account_id, mail_id, atch_id, err_code); + EM_PROFILE_BEGIN(profile_em_core_save_create_dir); + int ret = false; + int error = EM_STORAGE_ERROR_NONE; + + char buf[512]; + struct stat sbuf; + if (account_id >= FIRST_ACCOUNT_ID) { + SNPRINTF(buf, sizeof(buf), "%s%s%d", MAILHOME, DIR_SEPERATOR, account_id); + + if (stat(buf, &sbuf) == 0) { + if ((sbuf.st_mode & S_IFMT) != S_IFDIR) { + EM_DEBUG_EXCEPTION(" a object which isn't directory aleady exists"); + error = EM_STORAGE_ERROR_SYSTEM_FAILURE; + goto FINISH_OFF; + } + } + else { + if (mkdir(buf, DIRECTORY_PERMISSION) != 0) { + EM_DEBUG_EXCEPTION(" mkdir failed [%s]", buf); + EM_DEBUG_EXCEPTION("mkdir failed l(Errno=%d)][ErrStr=%s]", errno, strerror(errno)); + error = EM_STORAGE_ERROR_SYSTEM_FAILURE; + goto FINISH_OFF; + } + } + } + + if (mail_id > 0) { + if (account_id < FIRST_ACCOUNT_ID) { + EM_DEBUG_EXCEPTION("account_id[%d], mail_id[%d], atch_id[%d]", account_id, mail_id, atch_id); + error = EM_STORAGE_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + SNPRINTF(buf+strlen(buf), sizeof(buf), "%s%d", DIR_SEPERATOR, mail_id); + + if (stat(buf, &sbuf) == 0) { + if ((sbuf.st_mode & S_IFMT) != S_IFDIR) { + EM_DEBUG_EXCEPTION(" a object which isn't directory aleady exists"); + + error = EM_STORAGE_ERROR_SYSTEM_FAILURE; + goto FINISH_OFF; + } + } + else { + if (mkdir(buf, DIRECTORY_PERMISSION) != 0) { + EM_DEBUG_EXCEPTION(" mkdir failed [%s]", buf); + EM_DEBUG_EXCEPTION("mkdir failed l (Errno=%d)][ErrStr=%s]", errno, strerror(errno)); + error = EM_STORAGE_ERROR_SYSTEM_FAILURE; + goto FINISH_OFF; + } + } + } + + if (atch_id > 0) { + if (account_id < FIRST_ACCOUNT_ID || mail_id <= 0) { + EM_DEBUG_EXCEPTION(" account_id[%d], mail_id[%d], atch_id[%d]", account_id, mail_id, atch_id); + + error = EM_STORAGE_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + SNPRINTF(buf+strlen(buf), sizeof(buf)-(strlen(buf)+1), "%s%d", DIR_SEPERATOR, atch_id); + + if (stat(buf, &sbuf) == 0) { + if ((sbuf.st_mode & S_IFMT) != S_IFDIR) { + EM_DEBUG_EXCEPTION(" a object which isn't directory aleady exists"); + + error = EM_STORAGE_ERROR_SYSTEM_FAILURE; + goto FINISH_OFF; + } + } + else { + if (mkdir(buf, DIRECTORY_PERMISSION) != 0) { + EM_DEBUG_EXCEPTION(" mkdir failed [%s]", buf); + error = EM_STORAGE_ERROR_SYSTEM_FAILURE; + goto FINISH_OFF; + } + } + } + + ret = true; + +FINISH_OFF: + if (err_code != NULL) + *err_code = error; + + EM_PROFILE_END(profile_em_core_save_create_dir); + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API int em_storage_copy_file(char *src_file, char *dst_file, int sync_status, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("src_file[%s], dst_file[%s], err_code[%p]", src_file, dst_file, err_code); + EM_DEBUG_LOG("Using the fsync function"); + int ret = false; + int error = EM_STORAGE_ERROR_NONE; + struct stat st_buf; + + int fp_src = 0; + int fp_dst = 0; + int nread = 0; + int nwritten = 0; + char *buf = NULL; + int buf_size = 0; + + if (!src_file || !dst_file) { + EM_DEBUG_EXCEPTION("src_file[%p], dst_file[%p]", src_file, dst_file); + + error = EM_STORAGE_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + if (stat(src_file, &st_buf) < 0) { + EM_DEBUG_EXCEPTION("stat(\"%s\") failed...", src_file); + + error = EM_STORAGE_ERROR_SYSTEM_FAILURE; /* EMF_ERROR_INVALID_PATH; */ + goto FINISH_OFF; + } + + buf_size = st_buf.st_size; + EM_DEBUG_LOG(">>>> File Size [ %d ]", buf_size); + buf = (char *)calloc(1, buf_size+1); + + if (!buf) { + EM_DEBUG_EXCEPTION(">>> Memory cannot be allocated"); + error = EM_STORAGE_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + if (buf) { + if (!(fp_src = open(src_file, O_RDONLY))) { + EM_DEBUG_EXCEPTION(">>>> Source Fail open %s Failed [ %d ] - Error [ %s ]", src_file, errno, strerror(errno)); + error = EM_STORAGE_ERROR_SYSTEM_FAILURE; + goto FINISH_OFF; + } + + if (!(fp_dst = open(dst_file, O_CREAT | O_WRONLY, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH))) { + EM_DEBUG_EXCEPTION(">>>> Destination Fail open %s Failed [ %d ] - Error [ %s ]", dst_file, errno, strerror(errno)); + error = EM_STORAGE_ERROR_SYSTEM_FAILURE; + goto FINISH_OFF; + } + + while ((nread = read(fp_src, buf, buf_size)) > 0) { + if (nread > 0 && nread <= buf_size) { + EM_DEBUG_LOG("Nread Value [%d]", nread); + if ((nwritten = write(fp_dst, buf, nread)) != nread) { + EM_DEBUG_EXCEPTION("fwrite failed..."); + error = EM_STORAGE_ERROR_UNKNOWN; + goto FINISH_OFF; + } + EM_DEBUG_LOG("NWRITTEN [%d]", nwritten); + } + } + } + + ret = true; + +FINISH_OFF: + if (fp_src) + close(fp_src); + + if (fp_dst) { + if (sync_status) { + EM_DEBUG_LOG("Before fsync"); + fsync(fp_dst); + } + close(fp_dst); + } + EM_SAFE_FREE(buf); + if (nread < 0 || error == EM_STORAGE_ERROR_UNKNOWN) + remove(dst_file); + + if (err_code != NULL) + *err_code = error; + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} +/* create Directory if user has deleted [deepam.p@samsung.com] */ +EXPORT_API void em_storage_create_dir_if_delete() +{ + EM_DEBUG_FUNC_BEGIN(); + + mkdir(EMAILPATH, DIRECTORY_PERMISSION); + mkdir(DATA_PATH, DIRECTORY_PERMISSION); + + mkdir(MAILHOME, DIRECTORY_PERMISSION); + + SNPRINTF(g_db_path, sizeof(g_db_path), "%s/%s", MAILHOME, MAILTEMP); + mkdir(g_db_path, DIRECTORY_PERMISSION); + + /* _emf_delete_temp_file(g_db_path); */ + EM_DEBUG_FUNC_END(); +} +static +int em_storage_get_temp_file_name(char **filename, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("filename[%p], err_code[%p]", filename, err_code); + + int ret = false; + int error = EMF_ERROR_NONE; + + if (filename == NULL) { + EM_DEBUG_EXCEPTION(" filename[%p]", filename); + error = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + char tempname[512] = {0x00, }; + struct timeval tv; + + gettimeofday(&tv, NULL); + srand(tv.tv_usec); + + SNPRINTF(tempname, sizeof(tempname), "%s%c%s%c%d", MAILHOME, '/', MAILTEMP, '/', rand()); + + char *p = EM_SAFE_STRDUP(tempname); + if (p == NULL) { + EM_DEBUG_EXCEPTION(" strdup failed..."); + error = EMF_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + *filename = p; + + ret = true; + +FINISH_OFF: + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API int em_storage_add_content_type(char *file_path, char *char_set, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("File path [ %p ] Character Set [ %p ] err_code [ %p]", file_path, char_set, err_code); + + EM_IF_NULL_RETURN_VALUE(file_path, false); + EM_IF_NULL_RETURN_VALUE(char_set, false); + EM_IF_NULL_RETURN_VALUE(err_code, false); + + char *buf = NULL; + char *buf1 = NULL; + struct stat st_buf; + int buf_size = 0; + char *low_char_set = NULL; + char *match_str = NULL; + int nwritten = 0; + int ret = false; + int error = EM_STORAGE_ERROR_NONE; + int data_count_to_written = 0; + char *temp_file_name = NULL; + int err = 0; + + FILE* fp_src = NULL; + FILE* fp_dest = NULL; + int nread = 0; + + + if (stat(file_path, &st_buf) < 0) { + EM_DEBUG_EXCEPTION(" stat(\"%s\") failed...", file_path); + + error = EM_STORAGE_ERROR_SYSTEM_FAILURE; /* EMF_ERROR_INVALID_PATH; */ + goto FINISH_OFF; + } + + buf_size = st_buf.st_size; + + EM_DEBUG_LOG(">>>> File Size [ %d ] ", buf_size); + + buf = (char *)calloc(1, buf_size+1); + + if (!buf) { + EM_DEBUG_LOG(">>> Memory cannot be allocated "); + goto FINISH_OFF; + } + + if (!(fp_src = fopen(file_path, "rb"))) { + EM_DEBUG_EXCEPTION(" file_path fopen failed - %s", file_path); + + error = EM_STORAGE_ERROR_SYSTEM_FAILURE; + goto FINISH_OFF; /* 20080509 prevent 28806 - forward null */ + } + + if ((nread = fread(buf, 1, buf_size, fp_src)) > 0) { + if (nread > 0 && nread <= buf_size) { + EM_DEBUG_LOG(">>>> Nread Value [ %d ] ", nread); + + /** + * 1.Add check for whether content type is there. + * 2. If not based on the character set, Append it in File + **/ + + low_char_set = calloc(1, strlen(char_set) + strlen(" \" /></head>") +1); + + strncat(low_char_set, char_set, strlen(char_set)); + + EM_DEBUG_LOG(">>>> CHAR SET [ %s ] ", low_char_set); + + strncat(low_char_set, " \" /></head>", strlen(" \" /></head>")); + + EM_DEBUG_LOG(">>> CHARSET [ %s ] ", low_char_set); + + EM_DEBUG_LOG(">>>>em_storage_add_content_type 1 "); + + match_str = strstr(buf, CONTENT_TYPE_DATA); + EM_DEBUG_LOG(">>>>em_storage_add_content_type 2 "); + + if (match_str == NULL) { + EM_DEBUG_LOG(">>>>em_storage_add_content_type 3 "); + if (fp_src !=NULL) { + fclose(fp_src);fp_src = NULL; + } + data_count_to_written = strlen(low_char_set)+strlen(CONTENT_DATA)+1; + EM_DEBUG_LOG(">>>>em_storage_add_content_type 4 "); + buf1 = (char *)calloc(1, data_count_to_written); + EM_DEBUG_LOG(">>>>em_storage_add_content_type 5 "); + + if (buf1) { + EM_DEBUG_LOG(">>>>em_storage_add_content_type 6 "); + strncat(buf1, CONTENT_DATA, strlen(CONTENT_DATA)); + + EM_DEBUG_LOG(">>>>> BUF 1 [ %s ] ", buf1); + + strncat(buf1, low_char_set, strlen(low_char_set)); + + EM_DEBUG_LOG(">>>> HTML TAG DATA [ %s ] ", buf1); + + + /* 1. Create a temporary file name */ + if (!em_storage_get_temp_file_name(&temp_file_name, &err)) { + EM_DEBUG_EXCEPTION(" em_core_get_temp_file_name failed - %d", err); + if (err_code != NULL) *err_code = err; + EM_SAFE_FREE(temp_file_name); + goto FINISH_OFF; + } + EM_DEBUG_LOG(">>>>>>> TEMP APPEND FILE PATH [ %s ] ", temp_file_name); + + /* Open the Temp file in Append mode */ + if (!(fp_dest = fopen(temp_file_name, "ab"))) { + EM_DEBUG_EXCEPTION(" fopen failed - %s", temp_file_name); + error = EM_STORAGE_ERROR_SYSTEM_FAILURE; + goto FINISH_OFF; /* 20080509 prevent 28806 - forward null */ + } + + /* 2. write the Latest data */ + nwritten = fwrite(buf1, data_count_to_written-1, 1, fp_dest); + + if (nwritten > 0) { + EM_DEBUG_LOG(" Latest Data : [%d ] bytes written ", nwritten); + nwritten = 0; + /* 3. Append old data */ + nwritten = fwrite(buf, nread-1, 1, fp_dest); + + if (nwritten <= 0) { + EM_DEBUG_EXCEPTION(" Error Occured while writing Old data : [%d ] bytes written ", nwritten); + error = EM_STORAGE_ERROR_SYSTEM_FAILURE; + goto FINISH_OFF; + } + else { + EM_DEBUG_LOG(">>>> OLD data appended [ %d ] ", nwritten); + + if (!em_storage_move_file(temp_file_name, file_path, false, &err)) { + EM_DEBUG_EXCEPTION(" em_storage_move_file failed - %d", err); + goto FINISH_OFF; + } + } + + } + else { + EM_DEBUG_EXCEPTION(" Error Occured while writing New data : [%d ] bytes written ", nwritten); + error = EM_STORAGE_ERROR_SYSTEM_FAILURE; + goto FINISH_OFF; + } + + } + + } + EM_DEBUG_LOG(">>>>em_storage_add_content_type 15 "); + + + } + } + + ret = true; +FINISH_OFF: + + EM_SAFE_FREE(buf); + EM_SAFE_FREE(buf1); + EM_SAFE_FREE(low_char_set); + + if (fp_src != NULL) { + fclose(fp_src); + fp_src = NULL; + } + + if (fp_dest != NULL) { + fclose(fp_dest); + fp_dest = NULL; + } + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; + +} + +EXPORT_API int em_storage_move_file(char *src_file, char *dst_file, int sync_status, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("src_file[%p], dst_file[%p], err_code[%p]", src_file, dst_file, err_code); + + int ret = false; + int error = EM_STORAGE_ERROR_NONE; + + if (src_file == NULL || dst_file == NULL) { + EM_DEBUG_EXCEPTION("src_file[%p], dst_file[%p]", src_file, dst_file); + error = EM_STORAGE_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + EM_DEBUG_LOG("src_file[%s], dst_file[%s]", src_file, dst_file); + + if (strcmp(src_file, dst_file) != 0) { + if (rename(src_file, dst_file) != 0) { + if (errno == EXDEV) { /* oldpath and newpath are not on the same mounted file system. (Linux permits a file system to be mounted at multiple points, but rename() */ + /* does not work across different mount points, even if the same file system is mounted on both.) */ + EM_DEBUG_LOG("oldpath and newpath are not on the same mounted file system."); + if (!em_storage_copy_file(src_file, dst_file, sync_status, &error)) { + EM_DEBUG_EXCEPTION("em_storage_copy_file failed - %d", error); + goto FINISH_OFF; + } + remove(src_file); + EM_DEBUG_LOG("src[%s] removed", src_file); + + } + else { + if (errno == ENOENT) { + struct stat temp_file_stat; + if (stat(src_file, &temp_file_stat) < 0) + EM_DEBUG_EXCEPTION("no src file found [%s]", src_file); + if (stat(dst_file, &temp_file_stat) < 0) + EM_DEBUG_EXCEPTION("no dst file found [%s]", src_file); + + EM_DEBUG_EXCEPTION("no file found [%d]", errno); + error = EM_STORAGE_ERROR_FILE_NOT_FOUND; + goto FINISH_OFF; + + } + else { + EM_DEBUG_EXCEPTION("rename failed [%d]", errno); + error = EM_STORAGE_ERROR_SYSTEM_FAILURE; + goto FINISH_OFF; + } + } + } + } + else { + EM_DEBUG_LOG("src[%s] = dst[%d]", src_file, dst_file); + } + + ret = true; + +FINISH_OFF: + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API int em_storage_delete_file(char *src_file, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("src_file[%p], err_code[%p]", src_file, err_code); + + int ret = false; + int error = EM_STORAGE_ERROR_NONE; + + if (src_file == NULL) { + EM_DEBUG_EXCEPTION(" src_file[%p]", src_file); + + error = EM_STORAGE_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + if (remove(src_file) != 0) { + if (errno != ENOENT) { + EM_DEBUG_EXCEPTION(" remove failed - %d", errno); + + error = EM_STORAGE_ERROR_SYSTEM_FAILURE; + goto FINISH_OFF; + } + else { + EM_DEBUG_EXCEPTION(" no file found..."); + + error = EM_STORAGE_ERROR_FILE_NOT_FOUND; + } + } + + ret = true; + +FINISH_OFF: + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + + +EXPORT_API int em_storage_delete_dir(char *src_dir, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("src_dir[%p], err_code[%p]", src_dir, err_code); + + if (src_dir == NULL) { + EM_DEBUG_EXCEPTION(" src_dir[%p]", src_dir); + + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + int error = EM_STORAGE_ERROR_NONE; + + DIR *dirp; + struct dirent *dp; + struct stat sbuf; + char buf[512]; + + dirp = opendir(src_dir); + + if (dirp == NULL) { + if (errno == ENOENT) { + EM_DEBUG_EXCEPTION("directory[%s] does not exist...", src_dir); + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_SYSTEM_FAILURE; + return true; + } + else { + EM_DEBUG_EXCEPTION("opendir failed - %d", errno); + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_SYSTEM_FAILURE; + return false; + } + } + + while ((dp=readdir(dirp))) { + if (strncmp(dp->d_name, ".", strlen(".")) == 0 || strncmp(dp->d_name, "..", strlen("..")) == 0) + continue; + + SNPRINTF(buf, sizeof(buf), "%s/%s", src_dir, dp->d_name); + + if (lstat(buf, &sbuf) == 0 || stat(buf, &sbuf) == 0) { + /* check directory */ + if ((sbuf.st_mode & S_IFMT) == S_IFDIR) { /* directory */ + /* recursive call */ + if (!em_storage_delete_dir(buf, &error)) { + closedir(dirp); + if (err_code != NULL) + *err_code = error; + return false; + } + } + else { /* file */ + if (remove(buf) < 0) { + EM_DEBUG_EXCEPTION("remove failed - %s", buf); + closedir(dirp); + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_SYSTEM_FAILURE; + return false; + } + } + } + else + EM_DEBUG_EXCEPTION("content does not exist..."); + } + + closedir(dirp); + + EM_DEBUG_LOG("remove direcotory [%s]", src_dir); + + /* EM_DEBUG_FUNC_BEGIN(); */ + + if (remove(src_dir) < 0) { + EM_DEBUG_EXCEPTION("remove failed [%s]", src_dir); + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_SYSTEM_FAILURE; + return false; + } + + if (err_code != NULL) + *err_code = error; + + return true; +} + +/* faizan.h@samsung.com */ +EXPORT_API int em_storage_update_server_uid(char *old_server_uid, char *new_server_uid, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("new_server_uid[%s], old_server_uid[%s]", new_server_uid, old_server_uid); + int rc, ret = false; + int error = EM_STORAGE_ERROR_NONE; + char sql_query_string[QUERY_SIZE] = {0, }; + + int transaction = true; + + if (!old_server_uid || !new_server_uid) { + EM_DEBUG_EXCEPTION("Invalid parameters"); + error = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + sqlite3 *local_db_handle = em_storage_get_db_connection(); + + EM_STORAGE_START_WRITE_TRANSACTION(transaction, error); + + SNPRINTF(sql_query_string, sizeof(sql_query_string), + "UPDATE mail_tbl SET server_mail_id=\'%s\' WHERE server_mail_id=%s ", new_server_uid, old_server_uid); + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, sql_query_string, NULL, NULL, NULL), rc); + + EM_DEBUG_DB_EXEC((SQLITE_FULL == rc), {error = EM_STORAGE_ERROR_DB_IS_FULL;goto FINISH_OFF; }, + ("sqlite3_exec fail:%d", rc)); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) exec fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + ret = true; + +FINISH_OFF: + EM_STORAGE_FINISH_WRITE_TRANSACTION(transaction, ret, error); + _DISCONNECT_DB; + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; + +} + +EXPORT_API int em_storage_update_read_mail_uid(int mail_id, char *new_server_uid, char *mbox_name, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("mail_id[%d], new_server_uid[%s], mbox_name[%s]", mail_id, new_server_uid, mbox_name); + + int rc, ret = false; + int error = EM_STORAGE_ERROR_NONE; + char sql_query_string[QUERY_SIZE] = {0, }; + + int transaction = true; + + if (!mail_id || !new_server_uid || !mbox_name) { + EM_DEBUG_EXCEPTION("Invalid parameters"); + error = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + sqlite3 *local_db_handle = em_storage_get_db_connection(); + EM_STORAGE_START_WRITE_TRANSACTION(transaction, error); + + + SNPRINTF(sql_query_string, sizeof(sql_query_string), + "UPDATE mail_read_mail_uid_tbl SET s_uid=\'%s\', local_mbox=\'%s\', mailbox_name=\'%s\' WHERE local_uid=%d ", new_server_uid, mbox_name, mbox_name, mail_id); + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, sql_query_string, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) exec fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + ret = true; + +FINISH_OFF: + + EM_STORAGE_FINISH_WRITE_TRANSACTION(transaction, ret, error); + _DISCONNECT_DB; + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; + +} + + +int em_storage_get_latest_unread_mailid(int account_id, int *mail_id, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN(); + + if ((!mail_id) ||(account_id <= 0 && account_id != -1)) { + EM_DEBUG_EXCEPTION(" mail_id[%p], account_id[%d] ", mail_id, account_id); + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + int ret = false; + int rc = -1; + int error = EM_STORAGE_ERROR_NONE; + DB_STMT hStmt = NULL; + int count = 0; + int mailid = 0; + int transaction = false; + char sql_query_string[QUERY_SIZE] = {0, }; + + sqlite3 *local_db_handle = em_storage_get_db_connection(); + EM_STORAGE_START_READ_TRANSACTION(transaction); + + memset(sql_query_string, 0x00, sizeof(sql_query_string)); + + if (account_id == -1) + SNPRINTF(sql_query_string, sizeof(sql_query_string), "SELECT mail_id FROM mail_tbl WHERE flags_seen_field = 0 ORDER BY mail_id DESC"); + else + SNPRINTF(sql_query_string, sizeof(sql_query_string), "SELECT mail_id FROM mail_tbl WHERE account_id = %d AND flags_seen_field = 0 ORDER BY mail_id DESC", account_id); + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_prepare_v2(local_db_handle, sql_query_string, strlen(sql_query_string), &hStmt, NULL), rc); + EM_DEBUG_LOG(" sqlite3_prepare hStmt = %p", hStmt); + EM_DEBUG_DB_EXEC((SQLITE_OK != rc), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) sqlite3_prepare fail:(%d) %s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_step(hStmt), rc); + EM_DEBUG_DB_EXEC((rc != SQLITE_ROW && rc != SQLITE_DONE), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("sqlite3_step fail:%d", rc)); + + char **result; + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_get_table(local_db_handle, sql_query_string, &result, &count, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;sqlite3_free_table(result);goto FINISH_OFF; }, + ("SQL(%s) sqlite3_get_table fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + sqlite3_free_table(result); + if (count == 0) { + EM_DEBUG_EXCEPTION("no Mails found..."); + ret = false; + error= EM_STORAGE_ERROR_MAIL_NOT_FOUND; + goto FINISH_OFF; + } + + _getStmtFieldDataInt(hStmt, &mailid, 0); + + ret = true; + +FINISH_OFF: + if (hStmt != NULL) { + EM_DEBUG_LOG("Before sqlite3_finalize hStmt = %p", hStmt); + + rc = sqlite3_finalize(hStmt); + if (rc != SQLITE_OK) { + EM_DEBUG_EXCEPTION("sqlite3_finalize failed - %d", rc); + + error = EM_STORAGE_ERROR_DB_FAILURE; + } + } + EM_STORAGE_FINISH_READ_TRANSACTION(transaction); + _DISCONNECT_DB; + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +int setting_system_command(const char *command) + + { + int pid = 0, status = 0; + char *const environ[] = { NULL }; + + if (command == 0) + return 1; + + pid = fork(); + + if (pid == -1) + return -1; + + if (pid == 0) { + char *argv[4]; + + argv[0] = "sh"; + argv[1] = "-c"; + argv[2] = (char *)command; + argv[3] = 0; + + execve("/bin/sh", argv, environ); + abort(); + } + do{ + if (waitpid(pid, &status, 0) == -1) { + if (errno != EINTR) + return -1; + } + else { + return status; + } + } while (1); + + return 0; +} + + +EXPORT_API int em_storage_mail_get_total_diskspace_usage(unsigned long *total_usage, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("total_usage[%p], transaction[%d], err_code[%p]", total_usage, transaction, err_code); + + if (!total_usage) { + EM_DEBUG_EXCEPTION("total_usage[%p]", total_usage); + + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + int ret = false; + int error = EM_STORAGE_ERROR_NONE; + char syscmd[256] = {0}; + FILE *fp = NULL; + unsigned long total_diskusage = 0; + + SNPRINTF(syscmd, sizeof(syscmd), "touch %s", SETTING_MEMORY_TEMP_FILE_PATH); + if (setting_system_command(syscmd) == -1) { + EM_DEBUG_EXCEPTION("em_storage_mail_get_total_diskspace_usage : [Setting > Memory] System Command [%s] is failed", syscmd); + + error = EM_STORAGE_ERROR_SYSTEM_FAILURE; + goto FINISH_OFF; + } + + memset(syscmd, 0, sizeof(syscmd)); + SNPRINTF(syscmd, sizeof(syscmd), "du -hsk %s > %s", EMAILPATH, SETTING_MEMORY_TEMP_FILE_PATH); + EM_DEBUG_LOG(" cmd : %s", syscmd); + if (setting_system_command(syscmd) == -1) { + EM_DEBUG_EXCEPTION("em_storage_mail_get_total_diskspace_usage : Setting > Memory] System Command [%s] is failed", syscmd); + + error = EM_STORAGE_ERROR_SYSTEM_FAILURE; + goto FINISH_OFF; + } + + fp = fopen(SETTING_MEMORY_TEMP_FILE_PATH, "r"); + if (fp == NULL) { + perror(SETTING_MEMORY_TEMP_FILE_PATH); + + error = EM_STORAGE_ERROR_SYSTEM_FAILURE; + goto FINISH_OFF; + } + + char line[256] = {0}; + fgets(line, sizeof(line), fp); + total_diskusage = strtoul(line, NULL, 10); + + fclose(fp); + + memset(syscmd, 0, sizeof(syscmd)); + SNPRINTF(syscmd, sizeof(syscmd), "rm -f %s", SETTING_MEMORY_TEMP_FILE_PATH); + if (setting_system_command(syscmd) == -1) + { + EM_DEBUG_EXCEPTION("em_storage_mail_get_total_diskspace_usage : [Setting > Memory] System Command [%s] is failed", syscmd); + + error = EM_STORAGE_ERROR_SYSTEM_FAILURE; + goto FINISH_OFF; + } + + EM_DEBUG_LOG("[Setting > Memory] @@@@@ Size of Directory [%s] is %ld KB", EMAILPATH, total_diskusage); + + ret = true; + +FINISH_OFF: + if (err_code != NULL) + *err_code = error; + + if (ret) + *total_usage = total_diskusage; + else + *total_usage = 0; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + + +EXPORT_API int em_storage_test(int mail_id, int account_id, char *full_address_to, char *full_address_cc, char *full_address_bcc, int *err_code) +{ + DB_STMT hStmt = NULL; + int ret = false; + int error = EM_STORAGE_ERROR_NONE; + int rc = 0; + char sql_query_string[QUERY_SIZE] = {0, }; + + SNPRINTF(sql_query_string, sizeof(sql_query_string), + "INSERT INTO mail_tbl VALUES " + "( ?" /* mail_id */ + ", ?" /* account_id */ + ", ?" /* mailbox_name */ + ", ?" /* mail_size */ + ", ?" /* server_mail_status */ + ", ?" /* server_mailbox_name */ + ", ?" /* server_mail_id */ + ", ?" /* full_address_from */ + ", ?" /* full_address_reply */ + ", ?" /* full_address_to */ + ", ?" /* full_address_cc */ + ", ?" /* full_address_bcc */ + ", ?" /* full_address_return */ + ", ?" /* subject */ + ", ?" /* body_download_status */ + ", ?" /* file_path_plain */ + ", ?" /* file_path_html */ + ", ?" /* date_time */ + ", ?" /* flags_seen_field */ + ", ?" /* flags_deleted_field */ + ", ?" /* flags_flagged_field */ + ", ?" /* flags_answered_field */ + ", ?" /* flags_recent_field */ + ", ?" /* flags_draft_field */ + ", ?" /* flags_forwarded_field */ + ", ?" /* DRM_status */ + ", ?" /* priority */ + ", ?" /* save_status */ + ", ?" /* lock_status */ + ", ?" /* message_id */ + ", ?" /* report_status */ + ", ?" /* email_address_sender */ + ", ?" /* email_address_recipient */ + ", ?" /* attachment_count */ + ", ?" /* inline_content_count */ + ", ?" /* preview_text */ + ", ?" /* thread_id */ + ", ?" /* mailbox_type */ + ", ?" /* alias_sender */ + ", ?" /* alias_recipient */ + ", ?" /* thread_item_count */ + ", ?" /* meeting_request_status */ + ")"); + + int transaction = true; + sqlite3 *local_db_handle = em_storage_get_db_connection(); + + EM_STORAGE_START_WRITE_TRANSACTION(transaction, error); + + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_prepare_v2(local_db_handle, sql_query_string, strlen(sql_query_string), &hStmt, NULL), rc); + EM_DEBUG_DB_EXEC((SQLITE_OK != rc), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) sqlite3_prepare fail:(%d) %s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + _bindStmtFieldDataInt(hStmt, MAIL_ID_IDX_IN_MAIL_TBL, mail_id); + _bindStmtFieldDataInt(hStmt, ACCOUNT_ID_IDX_IN_MAIL_TBL, account_id); + _bindStmtFieldDataString(hStmt, MAILBOX_NAME_IDX_IN_MAIL_TBL, "OUTBOX", 0, MAILBOX_LEN_IN_MAIL_TBL); + _bindStmtFieldDataInt(hStmt, MAILBOX_TYPE_IDX_IN_MAIL_TBL, EMF_MAILBOX_TYPE_OUTBOX); + _bindStmtFieldDataString(hStmt, SUBJECT_IDX_IN_MAIL_TBL, "save test - long", 1, SUBJECT_LEN_IN_MAIL_TBL); + _bindStmtFieldDataString(hStmt, DATETIME_IDX_IN_MAIL_TBL, "20100316052908", 0, DATETIME_LEN_IN_MAIL_TBL); + _bindStmtFieldDataInt(hStmt, SERVER_MAIL_STATUS_IDX_IN_MAIL_TBL, 0); + _bindStmtFieldDataString(hStmt, SERVER_MAILBOX_NAME_IDX_IN_MAIL_TBL, "", 0, SERVER_MAILBOX_LEN_IN_MAIL_TBL); + _bindStmtFieldDataString(hStmt, SERVER_MAIL_ID_IDX_IN_MAIL_TBL, "", 0, SERVER_MAIL_ID_LEN_IN_MAIL_TBL); + _bindStmtFieldDataString(hStmt, MESSAGE_ID_IDX_IN_MAIL_TBL, "", 0, MESSAGE_ID_LEN_IN_MAIL_TBL); + _bindStmtFieldDataString(hStmt, FULL_ADDRESS_FROM_IDX_IN_MAIL_TBL, "<test08@streaming.s3glab.net>", 1, FROM_LEN_IN_MAIL_TBL); + _bindStmtFieldDataString(hStmt, FULL_ADDRESS_REPLY_IDX_IN_MAIL_TBL, "", 1, REPLY_TO_LEN_IN_MAIL_TBL); + _bindStmtFieldDataString(hStmt, FULL_ADDRESS_TO_IDX_IN_MAIL_TBL, full_address_to, 1, TO_LEN_IN_MAIL_TBL); + _bindStmtFieldDataString(hStmt, FULL_ADDRESS_CC_IDX_IN_MAIL_TBL, full_address_cc, 1, CC_LEN_IN_MAIL_TBL); + _bindStmtFieldDataString(hStmt, FULL_ADDRESS_BCC_IDX_IN_MAIL_TBL, full_address_bcc, 1, BCC_LEN_IN_MAIL_TBL); + _bindStmtFieldDataString(hStmt, FULL_ADDRESS_RETURN_IDX_IN_MAIL_TBL, "", 1, RETURN_PATH_LEN_IN_MAIL_TBL); + _bindStmtFieldDataString(hStmt, EMAIL_ADDRESS_SENDER_IDX_IN_MAIL_TBL, "<sender_name@sender_host.com>", 1, FROM_EMAIL_ADDRESS_LEN_IN_MAIL_TBL); + _bindStmtFieldDataString(hStmt, EMAIL_ADDRESS_RECIPIENT_IDX_IN_MAIL_TBL, "<recipient_name@recipient_host.com>", 1, TO_EMAIL_ADDRESS_LEN_IN_MAIL_TBL); + _bindStmtFieldDataString(hStmt, ALIAS_SENDER_IDX_IN_MAIL_TBL, "send_alias", 1, FROM_EMAIL_ADDRESS_LEN_IN_MAIL_TBL); + _bindStmtFieldDataString(hStmt, ALIAS_RECIPIENT_IDX_IN_MAIL_TBL, "recipient_alias", 1, TO_EMAIL_ADDRESS_LEN_IN_MAIL_TBL); + _bindStmtFieldDataInt(hStmt, BODY_DOWNLOAD_STATUS_IDX_IN_MAIL_TBL, 1); + _bindStmtFieldDataString(hStmt, FILE_PATH_PLAIN_IDX_IN_MAIL_TBL, "/opt/system/rsr/email/.emfdata/7/348/UTF-8", 0, TEXT_1_LEN_IN_MAIL_TBL); + _bindStmtFieldDataString(hStmt, FILE_PATH_HTML_IDX_IN_MAIL_TBL, "", 0, TEXT_2_LEN_IN_MAIL_TBL); + _bindStmtFieldDataInt(hStmt, MAIL_SIZE_IDX_IN_MAIL_TBL, 4); + _bindStmtFieldDataChar(hStmt, FLAGS_SEEN_FIELD_IDX_IN_MAIL_TBL, 0); + _bindStmtFieldDataChar(hStmt, FLAGS_DELETED_FIELD_IDX_IN_MAIL_TBL, 0); + _bindStmtFieldDataChar(hStmt, FLAGS_FLAGGED_FIELD_IDX_IN_MAIL_TBL, 0); + _bindStmtFieldDataChar(hStmt, FLAGS_ANSWERED_FIELD_IDX_IN_MAIL_TBL, 0); + _bindStmtFieldDataChar(hStmt, FLAGS_RECENT_FIELD_IDX_IN_MAIL_TBL, 0); + _bindStmtFieldDataChar(hStmt, FLAGS_DRAFT_FIELD_IDX_IN_MAIL_TBL, 0); + _bindStmtFieldDataChar(hStmt, FLAGS_FORWARDED_FIELD_IDX_IN_MAIL_TBL, 0); + _bindStmtFieldDataInt(hStmt, DRM_STATUS_IDX_IN_MAIL_TBL, 0); + _bindStmtFieldDataInt(hStmt, PRIORITY_IDX_IN_MAIL_TBL, 0); + _bindStmtFieldDataInt(hStmt, SAVE_STATUS_IDX_IN_MAIL_TBL, 0); + _bindStmtFieldDataInt(hStmt, LOCK_STATUS_IDX_IN_MAIL_TBL, 0); + _bindStmtFieldDataInt(hStmt, REPORT_STATUS_IDX_IN_MAIL_TBL, 0); + _bindStmtFieldDataInt(hStmt, ATTACHMENT_COUNT_IDX_IN_MAIL_TBL, 0); + _bindStmtFieldDataInt(hStmt, INLINE_CONTENT_COUNT_IDX_IN_MAIL_TBL, 0); + _bindStmtFieldDataInt(hStmt, ATTACHMENT_COUNT_IDX_IN_MAIL_TBL, 0); + _bindStmtFieldDataInt(hStmt, THREAD_ID_IDX_IN_MAIL_TBL, 0); + _bindStmtFieldDataInt(hStmt, THREAD_ITEM_COUNT_IDX_IN_MAIL_TBL, 0); + _bindStmtFieldDataString(hStmt, PREVIEW_TEXT_IDX_IN_MAIL_TBL, "preview body", 1, PREVIEWBODY_LEN_IN_MAIL_TBL); + _bindStmtFieldDataInt(hStmt, MEETING_REQUEST_STATUS_IDX_IN_MAIL_TBL, 0); + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_step(hStmt), rc); + EM_DEBUG_DB_EXEC((rc == SQLITE_FULL), {error = EM_STORAGE_ERROR_DB_IS_FULL;goto FINISH_OFF; }, + ("sqlite3_step fail:%d", rc)); + EM_DEBUG_DB_EXEC((rc != SQLITE_ROW && rc != SQLITE_DONE), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("sqlite3_step fail:%d", rc)); + ret = true; +FINISH_OFF: + if (hStmt != NULL) { + rc = sqlite3_finalize(hStmt); + if (rc != SQLITE_OK) { + EM_DEBUG_LOG("sqlite3_finalize failed - %d", rc); + + error = EM_STORAGE_ERROR_DB_FAILURE; + } + } + + + EM_STORAGE_FINISH_WRITE_TRANSACTION(transaction, ret, error); + _DISCONNECT_DB; + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + + +EXPORT_API int em_storage_get_max_mail_count() +{ + return EM_STORAGE_MAIL_MAX; +} + +EXPORT_API int em_storage_get_thread_id_of_thread_mails(emf_mail_tbl_t *mail_tbl, int *thread_id, int *result_latest_mail_id_in_thread, int *thread_item_count) +{ + EM_DEBUG_FUNC_BEGIN(); + EM_PROFILE_BEGIN(profile_em_storage_get_thread_id_of_thread_mails); + int rc = 0, query_size = 0, query_size_account = 0; + int account_id; + char *mailbox_name = NULL, *subject = NULL, *date_time = NULL; + int err_code = EM_STORAGE_ERROR_NONE; + char *sql_query_string = NULL, *sql_account = NULL; + char *sql_format = "SELECT thread_id, date_time, mail_id FROM mail_tbl WHERE subject like \'%%%q\' AND mailbox_type NOT IN (3, 5, 7)"; + char *sql_format_account = " AND account_id = %d "; + char *sql_format_order_by = " ORDER BY date_time DESC "; + char **result = NULL, latest_date_time[18]; + char stripped_subject[1025]; + int count = 0, result_thread_id = -1, latest_mail_id_in_thread = -1; + sqlite3 *local_db_handle = em_storage_get_db_connection(); + + EM_IF_NULL_RETURN_VALUE(mail_tbl, EMF_ERROR_INVALID_PARAM); + EM_IF_NULL_RETURN_VALUE(thread_id, EMF_ERROR_INVALID_PARAM); + EM_IF_NULL_RETURN_VALUE(result_latest_mail_id_in_thread, EMF_ERROR_INVALID_PARAM); + EM_IF_NULL_RETURN_VALUE(thread_item_count, EMF_ERROR_INVALID_PARAM); + + if (mail_tbl->mailbox_type == EMF_MAILBOX_TYPE_TRASH || + mail_tbl->mailbox_type == EMF_MAILBOX_TYPE_SPAMBOX || + mail_tbl->mailbox_type == EMF_MAILBOX_TYPE_ALL_EMAILS) { + EM_DEBUG_LOG("the mail in trash, spambox, all email could not be thread mail."); + goto FINISH_OFF; + } + + account_id = mail_tbl->account_id; + mailbox_name = mail_tbl->mailbox_name; + subject = mail_tbl->subject; + date_time = mail_tbl->datetime; + + memset(latest_date_time, 0, 18); + + EM_DEBUG_LOG("subject : %s", subject); + + if (em_core_find_pos_stripped_subject_for_thread_view(subject, stripped_subject) != EMF_ERROR_NONE) { + EM_DEBUG_EXCEPTION("em_core_find_pos_stripped_subject_for_thread_view is failed"); + err_code = EM_STORAGE_ERROR_UNKNOWN; + result_thread_id = -1; + goto FINISH_OFF; + } + + if (strlen(stripped_subject) < 2) { + result_thread_id = -1; + goto FINISH_OFF; + } + + EM_DEBUG_LOG("em_core_find_pos_stripped_subject_for_thread_view returns[len = %d] = %s", strlen(stripped_subject), stripped_subject); + + if (account_id > 0) { + query_size_account = 3 + strlen(sql_format_account); + sql_account = malloc(query_size_account); + if (sql_account == NULL) { + EM_DEBUG_EXCEPTION("malloc for sql_account is failed %d", query_size_account); + err_code = EM_STORAGE_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + snprintf(sql_account, query_size_account, sql_format_account, account_id); + } + + query_size = strlen(sql_format) + strlen(stripped_subject) + 50 + query_size_account + strlen(sql_format_order_by); /* + query_size_mailbox; */ + + sql_query_string = malloc(query_size); + + if (sql_query_string == NULL) { + EM_DEBUG_EXCEPTION("malloc for sql is failed %d", query_size); + err_code = EM_STORAGE_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + sqlite3_snprintf(query_size, sql_query_string, sql_format, stripped_subject); + /* snprintf(sql_query_string, query_size, sql_format, stripped_subject); */ + if (account_id > 0) + strcat(sql_query_string, sql_account); + + strcat(sql_query_string, sql_format_order_by); + strcat(sql_query_string, ";"); + + EM_DEBUG_LOG("Query : %s", sql_query_string); + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_get_table(local_db_handle, sql_query_string, &result, &count, NULL, NULL), rc); + + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {err_code = EM_STORAGE_ERROR_DB_FAILURE;sqlite3_free_table(result);goto FINISH_OFF; }, + ("SQL(%s) sqlite3_get_table fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + EM_DEBUG_LOG("Result rows count : %d", count); + + if (count == 0) + result_thread_id = -1; + else { + _getTableFieldDataInt(result, &result_thread_id, 3); + _getTableFieldDataStringWithoutAllocation(result, (char *)latest_date_time, 18, 1, 4); + _getTableFieldDataInt(result, &latest_mail_id_in_thread, 5); + + if (mail_tbl->datetime && strcmp(latest_date_time, mail_tbl->datetime) > 0) + *result_latest_mail_id_in_thread = latest_mail_id_in_thread; + else + *result_latest_mail_id_in_thread = mail_tbl->mail_id; + EM_DEBUG_LOG("latest_mail_id_in_thread [%d], mail_id [%d]", latest_mail_id_in_thread, mail_tbl->mail_id); + } + +FINISH_OFF: + *thread_id = result_thread_id; + *thread_item_count = count; + + EM_DEBUG_LOG("Result thread id : %d", *thread_id); + EM_DEBUG_LOG("Result count : %d", *thread_item_count); + EM_DEBUG_LOG("err_code : %d", err_code); + + EM_SAFE_FREE(sql_account); + EM_SAFE_FREE(sql_query_string); + + sqlite3_free_table(result); + + EM_PROFILE_END(profile_em_storage_get_thread_id_of_thread_mails); + + return err_code; +} + + +EXPORT_API int em_storage_get_thread_information(int thread_id, emf_mail_tbl_t** mail_tbl, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN(); + + int count = 0, ret = false; + int error = EM_STORAGE_ERROR_NONE; + emf_mail_tbl_t *p_data_tbl = NULL; + char conditional_clause[QUERY_SIZE] = {0, }; + + EM_IF_NULL_RETURN_VALUE(mail_tbl, false); + + SNPRINTF(conditional_clause, QUERY_SIZE, "WHERE thread_id = %d AND thread_item_count > 0", thread_id); + EM_DEBUG_LOG("conditional_clause [%s]", conditional_clause); + + if(!em_storage_query_mail_tbl(conditional_clause, transaction, &p_data_tbl, &count, &error)) { + EM_DEBUG_EXCEPTION("em_storage_query_mail_tbl failed [%d]", error); + goto FINISH_OFF; + } + + if(p_data_tbl) + EM_DEBUG_LOG("thread_id : %d, thread_item_count : %d", p_data_tbl[0].thread_id, p_data_tbl[0].thread_item_count); + + ret = true; + +FINISH_OFF: + if (ret == true) + *mail_tbl = p_data_tbl; + else if (p_data_tbl != NULL) + em_storage_free_mail(&p_data_tbl, 1, NULL); + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + + +EXPORT_API int em_storage_get_sender_list(int account_id, const char *mailbox_name, int search_type, const char *search_value, emf_sort_type_t sorting, emf_sender_list_t** sender_list, int *sender_count, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id [%d], mailbox_name [%p], search_type [%d], search_value [%p], sorting [%d], sender_list[%p], sender_count[%p] err_code[%p]" + , account_id , mailbox_name , search_type , search_value , sorting , sender_list, sender_count, err_code); + + if ((!sender_list) ||(!sender_count)) { + EM_DEBUG_EXCEPTION("EM_STORAGE_ERROR_INVALID_PARAM"); + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + int rc = -1, ret = false; + int error = EM_STORAGE_ERROR_NONE; + int count = 0; + int i, col_index = 0; + int read_count = 0; + emf_sender_list_t *p_sender_list = NULL; + char sql_query_string[QUERY_SIZE] = {0, }; + char **result = NULL; + sqlite3 *local_db_handle = em_storage_get_db_connection(); + + SNPRINTF(sql_query_string, sizeof(sql_query_string), + "SELECT email_address_sender, alias_sender, COUNT(email_address_sender), SUM(flags_seen_field = 1) " + "FROM mail_tbl "); + + /* mailbox_name */ + if (mailbox_name) + SNPRINTF(sql_query_string + strlen(sql_query_string), QUERY_SIZE-(strlen(sql_query_string)+1), " WHERE UPPER(mailbox_name) = UPPER('%s') ", mailbox_name); + else /* NULL means all mailbox_name. but except for trash(3), spambox(5), all emails(for GMail, 7) */ + SNPRINTF(sql_query_string + strlen(sql_query_string), QUERY_SIZE-(strlen(sql_query_string)+1), " WHERE mailbox_type not in (3, 5, 7) "); + + /* account id */ + /* '0' (ALL_ACCOUNT) means all account */ + if (account_id > ALL_ACCOUNT) + SNPRINTF(sql_query_string + strlen(sql_query_string), QUERY_SIZE-(strlen(sql_query_string)+1), " AND account_id = %d ", account_id); + + if (search_value) { + switch (search_type) { + case EMF_SEARCH_FILTER_SUBJECT: + SNPRINTF(sql_query_string + strlen(sql_query_string), QUERY_SIZE-(strlen(sql_query_string)+1), + " AND (UPPER(subject) LIKE UPPER(\'%%%%%s%%%%\')) ", search_value); + break; + case EMF_SEARCH_FILTER_SENDER: + SNPRINTF(sql_query_string + strlen(sql_query_string), QUERY_SIZE-(strlen(sql_query_string)+1), + " AND ((UPPER(full_address_from) LIKE UPPER(\'%%%%%s%%%%\')) " + ") ", search_value); + break; + case EMF_SEARCH_FILTER_RECIPIENT: + SNPRINTF(sql_query_string + strlen(sql_query_string), QUERY_SIZE-(strlen(sql_query_string)+1), + " AND ((UPPER(full_address_to) LIKE UPPER(\'%%%%%s%%%%\')) " + " OR (UPPER(full_address_cc) LIKE UPPER(\'%%%%%s%%%%\')) " + " OR (UPPER(full_address_bcc) LIKE UPPER(\'%%%%%s%%%%\')) " + ") ", search_value, search_value, search_value); + break; + case EMF_SEARCH_FILTER_ALL: + SNPRINTF(sql_query_string + strlen(sql_query_string), QUERY_SIZE-(strlen(sql_query_string)+1), + " AND (UPPER(subject) LIKE UPPER(\'%%%%%s%%%%\') " + " OR (((UPPER(full_address_from) LIKE UPPER(\'%%%%%s%%%%\')) " + " OR (UPPER(full_address_to) LIKE UPPER(\'%%%%%s%%%%\')) " + " OR (UPPER(full_address_cc) LIKE UPPER(\'%%%%%s%%%%\')) " + " OR (UPPER(full_address_bcc) LIKE UPPER(\'%%%%%s%%%%\')) " + " ) " + " )" + ")", search_value, search_value, search_value, search_value, search_value); + break; + } + } + + + /* sorting option is not available now. The order of sender list is ascending order by display name */ + SNPRINTF(sql_query_string + strlen(sql_query_string), sizeof(sql_query_string)-(strlen(sql_query_string)+1), + "GROUP BY email_address_sender " + "ORDER BY UPPER(alias_sender) "); + + EM_DEBUG_LOG("query[%s]", sql_query_string); + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_get_table(local_db_handle, sql_query_string, &result, &count, 0, NULL), rc); + EM_DEBUG_DB_EXEC((SQLITE_OK != rc && -1 != rc), {error = EM_STORAGE_ERROR_DB_FAILURE;sqlite3_free_table(result);goto FINISH_OFF; }, + ("SQL(%s) sqlite3_get_table fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + EM_DEBUG_LOG("Count of Sender [%d]", count); + + if (!(p_sender_list = (emf_sender_list_t*)em_core_malloc(sizeof(emf_sender_list_t) * count))) { + EM_DEBUG_EXCEPTION("em_core_malloc failed..."); + error = EM_STORAGE_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + col_index = 4; + + EM_DEBUG_LOG(">>>> DATA ASSIGN START >>"); + for (i = 0; i < count; i++) { + _getTableFieldDataString(result, &(p_sender_list[i].address), 1, col_index++); + _getTableFieldDataString(result, &(p_sender_list[i].display_name), 1, col_index++); + _getTableFieldDataInt(result, &(p_sender_list[i].total_count), col_index++); + _getTableFieldDataInt(result, &(read_count), col_index++); + p_sender_list[i].unread_count = p_sender_list[i].total_count - read_count; /* unread count = total - read */ + } + EM_DEBUG_LOG(">>>> DATA ASSIGN END [count : %d] >>", count); + + sqlite3_free_table(result); + result = NULL; + + ret = true; + +FINISH_OFF: + if (ret == true) { + *sender_list = p_sender_list; + *sender_count = count; + EM_DEBUG_LOG(">>>> COUNT : %d >>", count); + } + else if (p_sender_list != NULL) + em_storage_free_sender_list(&p_sender_list, count); + + _DISCONNECT_DB; + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API int em_storage_free_sender_list(emf_sender_list_t **sender_list, int count) +{ + EM_DEBUG_FUNC_BEGIN("sender_list[%p], count[%d]", sender_list, count); + + int err = EMF_ERROR_NONE; + + if (count > 0) { + if (!sender_list || !*sender_list) { + EM_DEBUG_EXCEPTION("sender_list[%p], count[%d]", sender_list, count); + err = EMF_ERROR_INVALID_PARAM; + return err; + } + + emf_sender_list_t* p = *sender_list; + int i = 0; + + for (; i < count; i++) { + EM_SAFE_FREE(p[i].address); + EM_SAFE_FREE(p[i].display_name); + } + + EM_SAFE_FREE(p); + *sender_list = NULL; + } + + return err; +} + +#ifdef _CONTACT_SUBSCRIBE_CHANGE_ + +#define MAX_BUFFER_LEN 8096 +#define DEBUG_EMAIL + +#ifdef DEBUG_EMAIL +static void em_storage_contact_sync_print_email_list(int contact_id, char *display_name, GSList *email_list) +{ + EM_DEBUG_FUNC_BEGIN(); + + int i; + GSList *cursor = NULL; + + EM_DEBUG_LOG("===================================================================================="); + EM_DEBUG_LOG("Contact ID : [%d] Display Name : [%s]", contact_id, display_name); + EM_DEBUG_LOG("===================================================================================="); + EM_DEBUG_LOG(" order email_type email"); + EM_DEBUG_LOG("===================================================================================="); + i = 0; + for (cursor = email_list; cursor; cursor = g_slist_next(cursor)) { + EM_DEBUG_LOG("[%d] [%d] [%-35s]", + i, + contacts_svc_value_get_int(cursor->data, CTS_EMAIL_VAL_TYPE_INT), + contacts_svc_value_get_str(cursor->data, CTS_EMAIL_VAL_ADDR_STR)); + i++; + } + EM_DEBUG_LOG("===================================================================================="); +} +#endif + +EXPORT_API int em_storage_contact_sync_insert(int contact_id, char *display_name, GSList *email_list, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN(); + + int ret = false; + + int rc = 0; + char address_list[MAX_BUFFER_LEN]; + int address_list_len = 0; + int error; + int index = 0; + int is_first = 1; + DB_STMT hStmt = NULL; + char sql_query_string[QUERY_SIZE] = {0, }; + GSList *cursor; + const char *email_address = NULL; + char *display_name_in_mail_tbl = NULL; + + EM_DEBUG_LOG(" Contact ID : [%d] Display Name : [%s] email_list[%p]", contact_id, display_name, email_list); + if (display_name == NULL || email_list == NULL) { + EM_DEBUG_LOG(" Input Parameter is NULL"); + return false; + } + +#ifdef DEBUG_EMAIL + em_storage_contact_sync_print_email_list(contact_id, display_name, email_list); +#endif + + /* Make address list */ + cursor = email_list; + is_first = 1; + address_list_len = 0; + for (;cursor; cursor = g_slist_next(cursor)) { + email_address = contacts_svc_value_get_str(cursor->data, CTS_EMAIL_VAL_ADDR_STR); + if (strlen(email_address) <= 0) + continue; + if (is_first) { + is_first = 0; + snprintf(address_list+address_list_len, sizeof(address_list) - (1 + address_list_len), "'%s' ", email_address); + address_list_len = strlen(address_list); + } + else { + snprintf(address_list+address_list_len, sizeof(address_list) - (1 + address_list_len), ", '%s' ", email_address); + address_list_len = strlen(address_list); + } + } + EM_DEBUG_LOG("address list[%s]", address_list); + + int display_name_in_mail_tbl_len = strlen(display_name) + 4; + display_name_in_mail_tbl = (char *) malloc(sizeof(char)*display_name_in_mail_tbl_len); + if (display_name_in_mail_tbl == NULL) { + EM_DEBUG_EXCEPTION("Out of memory"); + goto FINISH_OFF; + } + snprintf(display_name_in_mail_tbl, display_name_in_mail_tbl_len - 1, "\"%s\"", display_name); + EM_DEBUG_LOG("display_name_in_mail_tbl[%s]", display_name_in_mail_tbl); + + /* Update mail_tbl : from_contact_name, to_contact_name */ + memset(sql_query_string, 0x00, sizeof(sql_query_string)); + snprintf(sql_query_string, sizeof(sql_query_string), "UPDATE mail_tbl SET from_contact_id = %d, from_contact_name = ? WHERE email_address_sender IN ( %s );", contact_id, address_list); + EM_DEBUG_LOG(" Query[%s]", sql_query_string); + + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_prepare_v2(local_db_handle, sql_query_string, strlen(sql_query_string), &hStmt, NULL), rc); + EM_DEBUG_DB_EXEC((SQLITE_OK != rc), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) sqlite3_prepare fail:(%d) %s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + index = 0; + _bindStmtFieldDataString(hStmt, index++, (char *)display_name_in_mail_tbl, 0, 0); + + /* rc = sqlite3_step(hStmt); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_step(hStmt), rc); + EM_DEBUG_DB_EXEC((rc != SQLITE_ROW && rc != SQLITE_DONE), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("sqlite3_step fail:%d", rc)); + + if (hStmt != NULL) { + rc = sqlite3_finalize(hStmt); + if (rc != SQLITE_OK) { + EM_DEBUG_LOG(" sqlite3_finalize failed - %d", rc); + goto FINISH_OFF; + } + } + + memset(sql_query_string, 0x00, sizeof(sql_query_string)); + snprintf(sql_query_string, sizeof(sql_query_string), "UPDATE mail_tbl SET to_contact_id = %d, to_contact_name = ? WHERE email_address_recipient IN ( %s );", contact_id, address_list); + EM_DEBUG_LOG(" Query[%s]", sql_query_string); + + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_prepare_v2(local_db_handle, sql_query_string, strlen(sql_query_string), &hStmt, NULL), rc); + EM_DEBUG_DB_EXEC((SQLITE_OK != rc), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) sqlite3_prepare fail:(%d) %s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + index = 0; + _bindStmtFieldDataString(hStmt, index++, (char *)display_name_in_mail_tbl, 0, 0); + + /* rc = sqlite3_step(hStmt); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_step(hStmt), rc); + EM_DEBUG_DB_EXEC((rc != SQLITE_ROW && rc != SQLITE_DONE), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("sqlite3_step fail:%d", rc)); + + if (hStmt != NULL) { + rc = sqlite3_finalize(hStmt); + if (rc != SQLITE_OK) { + EM_DEBUG_LOG(" sqlite3_finalize failed - %d", rc); + goto FINISH_OFF; + } + } + + ret = true; +FINISH_OFF: + EM_SAFE_FREE(display_name_in_mail_tbl); + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API int em_storage_contact_sync_update(int contact_id, char *display_name, GSList *email_list, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN(); + + int ret = false; + int rc = 0; + char address_list[MAX_BUFFER_LEN]; + int address_list_len = 0; + int error; + DB_STMT hStmt = NULL; + char sql_query_string[QUERY_SIZE] = {0, }; + int index = 0; + int is_first = 1; + int row, col; + GSList *cursor; + const char *email_address = NULL; + char *display_name_in_mail_tbl = NULL; + + EM_DEBUG_LOG(" Contact ID : [%d] Display Name : [%s] email_list[%p]", contact_id, display_name, email_list); + if (display_name == NULL || email_list == NULL) { + EM_DEBUG_LOG(" Input Parameter is NULL"); + return false; + } + +#ifdef DEBUG_EMAIL + em_storage_contact_sync_print_email_list(contact_id, display_name, email_list); +#endif + + /* Make address list */ + cursor = email_list; + is_first = 1; + address_list_len = 0; + for (;cursor; cursor = g_slist_next(cursor)) { + email_address = contacts_svc_value_get_str(cursor->data, CTS_EMAIL_VAL_ADDR_STR); + if (strlen(email_address) <= 0) + continue; + if (is_first) { + is_first = 0; + snprintf(address_list+address_list_len, sizeof(address_list) - (1 + address_list_len), "'%s' ", email_address); + address_list_len = strlen(address_list); + } + else { + snprintf(address_list+address_list_len, sizeof(address_list) - (1 + address_list_len), ", '%s' ", email_address); + address_list_len = strlen(address_list); + } + } + EM_DEBUG_LOG("address list[%s]", address_list); + + int display_name_in_mail_tbl_len = strlen(display_name) + 4; + display_name_in_mail_tbl = (char *) malloc(sizeof(char)*display_name_in_mail_tbl_len); + if (display_name_in_mail_tbl == NULL) { + EM_DEBUG_EXCEPTION("Out of memory"); + goto FINISH_OFF; + } + snprintf(display_name_in_mail_tbl, display_name_in_mail_tbl_len - 1, "\"%s\"", display_name); + EM_DEBUG_LOG("display_name_in_mail_tbl[%s]", display_name_in_mail_tbl); + + + /* Update mail_tbl : deleted emails full_address_from contact */ + char **result2 = NULL; + memset(sql_query_string, 0x00, sizeof(sql_query_string)); + snprintf(sql_query_string, sizeof(sql_query_string), "UPDATE mail_tbl SET from_contact_id = -1, from_contact_name = alias_sender " + " WHERE from_contact_id = %d " + " AND email_address_sender NOT IN ( %s ); ", + contact_id, address_list); + EM_DEBUG_LOG(" Query[%s]", sql_query_string); + rc = sqlite3_get_table(local_db_handle, sql_query_string, &result2, &row, &col, NULL); + EM_DEBUG_DB_EXEC((SQLITE_OK != rc), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) sqlite3_prepare fail:(%d) %s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + sqlite3_free_table(result2); + + memset(sql_query_string, 0x00, sizeof(sql_query_string)); + snprintf(sql_query_string, sizeof(sql_query_string), "UPDATE mail_tbl SET to_contact_id = -1, to_contact_name = alias_recipient " + " WHERE to_contact_id = %d " + " AND email_address_recipient NOT IN ( %s ); ", + contact_id, address_list); + EM_DEBUG_LOG(" Query[%s]", sql_query_string); + rc = sqlite3_get_table(local_db_handle, sql_query_string, &result2, &row, &col, NULL); + EM_DEBUG_DB_EXEC((SQLITE_OK != rc), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) sqlite3_prepare fail:(%d) %s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + sqlite3_free_table(result2); + + /* Update mail_tbl : inserted emails from contact */ + memset(sql_query_string, 0x00, sizeof(sql_query_string)); + snprintf(sql_query_string, sizeof(sql_query_string), "UPDATE mail_tbl SET from_contact_name = ?, from_contact_id = %d WHERE email_address_sender IN ( %s ); ", + contact_id, address_list); + EM_DEBUG_LOG(" Query[%s]", sql_query_string); + /* rc = sqlite3_prepare_v2(local_db_handle, sql_query_string, strlen(sql_query_string), &hStmt, NULL); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_prepare_v2(local_db_handle, sql_query_string, strlen(sql_query_string), &hStmt, NULL), rc); + EM_DEBUG_DB_EXEC((SQLITE_OK != rc), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) sqlite3_prepare fail:(%d) %s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + index = 0; + _bindStmtFieldDataString(hStmt, index++, (char *)display_name_in_mail_tbl, 0, 0); + + /* rc = sqlite3_step(hStmt); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_step(hStmt), rc); + EM_DEBUG_DB_EXEC((rc != SQLITE_ROW && rc != SQLITE_DONE), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("sqlite3_step fail:%d", rc)); + + if (hStmt != NULL) { + rc = sqlite3_finalize(hStmt); + if (rc != SQLITE_OK) { + EM_DEBUG_LOG(" sqlite3_finalize failed - %d", rc); + goto FINISH_OFF; + } + } + + memset(sql_query_string, 0x00, sizeof(sql_query_string)); + snprintf(sql_query_string, sizeof(sql_query_string), "UPDATE mail_tbl SET to_contact_name = ?, to_contact_id = %d WHERE email_address_recipient IN ( %s ); ", + contact_id, address_list); + EM_DEBUG_LOG(" Query[%s]", sql_query_string); + /* rc = sqlite3_prepare_v2(local_db_handle, sql_query_string, strlen(sql_query_string), &hStmt, NULL); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_prepare_v2(local_db_handle, sql_query_string, strlen(sql_query_string), &hStmt, NULL), rc); + EM_DEBUG_DB_EXEC((SQLITE_OK != rc), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) sqlite3_prepare fail:(%d) %s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + index = 0; + _bindStmtFieldDataString(hStmt, index++, (char *)display_name_in_mail_tbl, 0, 0); + + /* rc = sqlite3_step(hStmt); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_step(hStmt), rc); + EM_DEBUG_DB_EXEC((rc != SQLITE_ROW && rc != SQLITE_DONE), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("sqlite3_step fail:%d", rc)); + + if (hStmt != NULL) { + rc = sqlite3_finalize(hStmt); + if (rc != SQLITE_OK) { + EM_DEBUG_LOG(" sqlite3_finalize failed - %d", rc); + goto FINISH_OFF; + } + } + + ret = true; +FINISH_OFF: + EM_SAFE_FREE(display_name_in_mail_tbl); + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API int em_storage_contact_sync_delete(int contact_id, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN(); + + int rc; + int ret = false; + sqlite3_stmt* hStmt = NULL; + int error; + char sql_query_string[QUERY_SIZE] = {0, }; + + /* Update mail_tbl : set display name to alias */ + memset(sql_query_string, 0x00, sizeof(sql_query_string)); + snprintf(sql_query_string, sizeof(sql_query_string), "UPDATE mail_tbl SET from_contact_id = -1, from_contact_name = alias_sender WHERE from_contact_id = %d", contact_id); + EM_DEBUG_LOG(" Query[%s]", sql_query_string); + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_prepare_v2(local_db_handle, sql_query_string, strlen(sql_query_string), &hStmt, NULL), rc); + EM_DEBUG_DB_EXEC((SQLITE_OK != rc), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) sqlite3_prepare fail:(%d) %s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + /* rc = sqlite3_step(hStmt); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_step(hStmt), rc); + EM_DEBUG_DB_EXEC((rc != SQLITE_ROW && rc != SQLITE_DONE), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("sqlite3_step fail:%d", rc)); + + if (hStmt != NULL) { /* finalize and reuse hStmt later */ + rc = sqlite3_finalize(hStmt); + if (rc != SQLITE_OK) { + EM_DEBUG_LOG(" sqlite3_finalize failed - %d", rc); + } + } + + memset(sql_query_string, 0x00, sizeof(sql_query_string)); + snprintf(sql_query_string, sizeof(sql_query_string), "UPDATE mail_tbl SET to_contact_id = -1, to_contact_name = alias_recipient WHERE to_contact_id = %d", contact_id); + EM_DEBUG_LOG(" Query[%s]", sql_query_string); + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_prepare_v2(local_db_handle, sql_query_string, strlen(sql_query_string), &hStmt, NULL), rc); + EM_DEBUG_DB_EXEC((SQLITE_OK != rc), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) sqlite3_prepare fail:(%d) %s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + /* rc = sqlite3_step(hStmt); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_step(hStmt), rc); + EM_DEBUG_DB_EXEC((rc != SQLITE_ROW && rc != SQLITE_DONE), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("sqlite3_step fail:%d", rc)); + + if (hStmt != NULL) { /* finalize and reuse hStmt later */ + rc = sqlite3_finalize(hStmt); + if (rc != SQLITE_OK) { + EM_DEBUG_LOG(" sqlite3_finalize failed - %d", rc); + } + } + + ret = true; +FINISH_OFF: + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +#endif /* _CONTACT_SUBSCRIBE_CHANGE_ */ + + +EXPORT_API int em_storage_free_address_info_list(emf_address_info_list_t **address_info_list) +{ + EM_DEBUG_FUNC_BEGIN("address_info_list[%p]", address_info_list); + + int err = EMF_ERROR_NONE; + emf_address_info_t *p_address_info = NULL; + GList *list = NULL; + GList *node = NULL; + int i = 0; + + if (!address_info_list || !*address_info_list) { + EM_DEBUG_EXCEPTION("address_info_list[%p]", address_info_list); + err = EMF_ERROR_INVALID_PARAM; + return err; + } + + /* delete GLists */ + for (i = EMF_ADDRESS_TYPE_FROM; i <= EMF_ADDRESS_TYPE_BCC; i++) { + switch (i) { + case EMF_ADDRESS_TYPE_FROM: + list = (*address_info_list)->from; + break; + case EMF_ADDRESS_TYPE_TO: + list = (*address_info_list)->to; + break; + case EMF_ADDRESS_TYPE_CC: + list = (*address_info_list)->cc; + break; + case EMF_ADDRESS_TYPE_BCC: + list = (*address_info_list)->bcc; + break; + } + + /* delete dynamic-allocated memory for each item */ + node = g_list_first(list); + while (node != NULL) { + p_address_info = (emf_address_info_t*)node->data; + EM_SAFE_FREE(p_address_info->address); + EM_SAFE_FREE(p_address_info->display_name); + EM_SAFE_FREE(node->data); + + node = g_list_next(node); + } + } + + EM_SAFE_FREE(*address_info_list); + *address_info_list = NULL; + + EM_DEBUG_FUNC_END("err [%d]", err); + return err; +} +#ifdef __FEATURE_PARTIAL_BODY_DOWNLOAD__ + +EXPORT_API int em_storage_add_pbd_activity(emf_event_partial_body_thd* local_activity, int *activity_id, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("local_activity[%p], activity_id[%p], transaction[%d], err_code[%p]", local_activity, activity_id, transaction, err_code); + + if (!local_activity || !activity_id) { + EM_DEBUG_EXCEPTION("local_activity[%p], transaction[%d], activity_id[%p], err_code[%p]", local_activity, activity_id, transaction, err_code); + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + int rc = -1; + int ret = false; + int error = EM_STORAGE_ERROR_NONE; + int i = 0; + + char sql_query_string[QUERY_SIZE] = {0, }; + DB_STMT hStmt = NULL; + sqlite3 *local_db_handle = em_storage_get_db_connection(); + EM_STORAGE_START_WRITE_TRANSACTION(transaction, error); + memset(sql_query_string, 0x00, sizeof(sql_query_string)); + SNPRINTF(sql_query_string, sizeof(sql_query_string), + "INSERT INTO mail_partial_body_activity_tbl VALUES " + "( " + "? " /* Account ID */ + ",?" /* Local Mail ID */ + ",?" /* Server mail ID */ + ",?" /* Activity ID */ + ",?" /* Activity type*/ + ",?" /* Mailbox name*/ + ") "); + + char *sql = "SELECT max(rowid) FROM mail_partial_body_activity_tbl;"; + char **result = NULL; + + /* rc = sqlite3_get_table(local_db_handle, sql, &result, NULL, NULL, NULL); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_get_table(local_db_handle, sql, &result, NULL, NULL, NULL), rc); + + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;sqlite3_free_table(result);goto FINISH_OFF; }, + ("SQL(%s) sqlite3_get_table fail:%d -%s", sql, rc, sqlite3_errmsg(local_db_handle))); + + if (NULL==result[1]) rc = 1; + else rc = atoi(result[1])+1; + sqlite3_free_table(result); + result = NULL; + + *activity_id = local_activity->activity_id = rc; + + EM_DEBUG_LOG(">>>>> ACTIVITY ID [ %d ], MAIL ID [ %d ], ACTIVITY TYPE [ %d ], SERVER MAIL ID [ %lu ]", \ + local_activity->activity_id, local_activity->mail_id, local_activity->activity_type, local_activity->server_mail_id); + + if (local_activity->mailbox_name) + EM_DEBUG_LOG(" MAILBOX NAME [ %s ]", local_activity->mailbox_name); + + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_prepare_v2(local_db_handle, sql_query_string, strlen(sql_query_string), &hStmt, NULL), rc); + EM_DEBUG_DB_EXEC((SQLITE_OK != rc), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) sqlite3_prepare fail:(%d) %s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + EM_DEBUG_LOG(">>>> SQL STMT [ %s ]", sql_query_string); + + _bindStmtFieldDataInt(hStmt, i++, local_activity->account_id); + _bindStmtFieldDataInt(hStmt, i++, local_activity->mail_id); + _bindStmtFieldDataInt(hStmt, i++, local_activity->server_mail_id); + _bindStmtFieldDataInt(hStmt, i++, local_activity->activity_id); + _bindStmtFieldDataInt(hStmt, i++, local_activity->activity_type); + _bindStmtFieldDataString(hStmt, i++ , (char *)local_activity->mailbox_name, 0, 3999); + + /* rc = sqlite3_step(hStmt); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_step(hStmt), rc); + + EM_DEBUG_DB_EXEC((rc == SQLITE_FULL), {error = EM_STORAGE_ERROR_DB_IS_FULL;goto FINISH_OFF; }, + ("sqlite3_step fail:%d", rc)); + EM_DEBUG_DB_EXEC((rc != SQLITE_ROW && rc != SQLITE_DONE), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("sqlite3_step fail:%d, errmsg = %s.", rc, sqlite3_errmsg(local_db_handle))); + + ret = true; + +FINISH_OFF: + + if (hStmt != NULL) { + EM_DEBUG_LOG("Before sqlite3_finalize hStmt = %p", hStmt); + + rc = sqlite3_finalize(hStmt); + hStmt = NULL; + if (rc != SQLITE_OK) { + EM_DEBUG_EXCEPTION("sqlite3_finalize failed - %d", rc); + error = EM_STORAGE_ERROR_DB_FAILURE; + } + } + + EM_STORAGE_FINISH_WRITE_TRANSACTION(transaction, ret, error); + _DISCONNECT_DB; + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + + +EXPORT_API int em_storage_get_pbd_mailbox_list(int account_id, char *** mailbox_list, int *count, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id[%d], mailbox_list[%p], count[%p] err_code[%p]", account_id, mailbox_list, count, err_code); + + if (account_id < FIRST_ACCOUNT_ID || NULL == &mailbox_list || NULL == count) { + EM_DEBUG_EXCEPTION("account_id[%d], mailbox_list[%p], count[%p] err_code[%p]", account_id, mailbox_list, count, err_code); + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + int ret = false; + int error = EM_STORAGE_ERROR_NONE; + char **result; + int i = 0, rc = -1; + char **mbox_list = NULL; + DB_STMT hStmt = NULL; + char sql_query_string[QUERY_SIZE] = {0, }; + + sqlite3 *local_db_handle = em_storage_get_db_connection(); + + EM_STORAGE_START_READ_TRANSACTION(transaction); + + memset(sql_query_string, 0x00, sizeof(sql_query_string)); + SNPRINTF(sql_query_string, sizeof(sql_query_string), "SELECT count(distinct mailbox_name) FROM mail_partial_body_activity_tbl WHERE account_id = %d order by mailbox_name", account_id); + + /* rc = sqlite3_get_table(local_db_handle, sql_query_string, &result, NULL, NULL, NULL); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_get_table(local_db_handle, sql_query_string, &result, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;sqlite3_free_table(result);goto FINISH_OFF; }, + ("SQL(%s) sqlite3_get_table fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + *count = atoi(result[1]); + sqlite3_free_table(result); + + if (!*count) { + EM_DEBUG_EXCEPTION(" no mailbox_name found..."); + error = EM_STORAGE_ERROR_MAILBOX_NOT_FOUND; + ret = true; + goto FINISH_OFF; + } + EM_DEBUG_LOG("Mailbox count = %d", *count); + + memset(sql_query_string, 0x00, sizeof(sql_query_string)); + + /* SNPRINTF(g_sql_query, sizeof(g_sql_query), "SELECT distinct mailbox_name FROM mail_partial_body_activity_tbl WHERE account_id = %d order by activity_id", account_id); */ + SNPRINTF(sql_query_string, sizeof(sql_query_string), "SELECT distinct mailbox_name FROM mail_partial_body_activity_tbl WHERE account_id = %d order by mailbox_name", account_id); + + EM_DEBUG_LOG(" Query [%s]", sql_query_string); + + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_prepare_v2(local_db_handle, sql_query_string, strlen(sql_query_string), &hStmt, NULL), rc); + + EM_DEBUG_LOG(" Bbefore sqlite3_prepare hStmt = %p", hStmt); + EM_DEBUG_DB_EXEC((SQLITE_OK != rc), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) sqlite3_prepare fail:(%d) %s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + /* rc = sqlite3_step(hStmt); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_step(hStmt), rc); + EM_DEBUG_DB_EXEC((rc != SQLITE_ROW), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("sqlite3_step fail:%d", rc)); + + if (NULL == (mbox_list = (char **)em_core_malloc(sizeof(char *) * (*count)))) { + EM_DEBUG_EXCEPTION(" em_core_malloc failed..."); + error = EM_STORAGE_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + memset(mbox_list, 0x00, sizeof(char *) * (*count)); + + for (i = 0; i < (*count); i++) { + _getStmtFieldDataString(hStmt, &mbox_list[i], 0, ACCOUNT_IDX_MAIL_PARTIAL_BODY_ACTIVITY_TBL); + /* rc = sqlite3_step(hStmt); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_step(hStmt), rc); + /* EM_DEBUG_LOG("In em_storage_get_pdb_mailbox_list() loop, After sqlite3_step(), , i = %d, rc = %d.", i, rc); */ + EM_DEBUG_DB_EXEC((rc != SQLITE_ROW && rc != SQLITE_DONE), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("sqlite3_step fail:%d", rc)); + EM_DEBUG_LOG("mbox_list %s", mbox_list[i]); + } + + ret = true; + +FINISH_OFF: + if (ret == true) + *mailbox_list = mbox_list; + + if (hStmt != NULL) { + EM_DEBUG_LOG("Before sqlite3_finalize hStmt = %p", hStmt); + + rc = sqlite3_finalize(hStmt); + hStmt = NULL; + if (rc != SQLITE_OK) { + EM_DEBUG_EXCEPTION(" sqlite3_finalize failed - %d", rc); + error = EM_STORAGE_ERROR_DB_FAILURE; + } + } + + EM_STORAGE_FINISH_READ_TRANSACTION(transaction); + _DISCONNECT_DB; + if (err_code != NULL) + *err_code = error; + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + + +EXPORT_API int em_storage_get_pbd_account_list(int **account_list, int *count, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("mailbox_list[%p], count[%p] err_code[%p]", account_list, count, err_code); + + if (NULL == &account_list || NULL == count) { + EM_DEBUG_EXCEPTION("mailbox_list[%p], count[%p] err_code[%p]", account_list, count, err_code); + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + int ret = false; + int error = EM_STORAGE_ERROR_NONE; + char *sql; + char **result; + int i = 0, rc = -1; + int *result_account_list = NULL; + DB_STMT hStmt = NULL; + char sql_query_string[QUERY_SIZE] = {0, }; + + sqlite3 *local_db_handle = em_storage_get_db_connection(); + + EM_STORAGE_START_READ_TRANSACTION(transaction); + + + sql = "SELECT count(distinct account_id) FROM mail_partial_body_activity_tbl"; + + /* rc = sqlite3_get_table(local_db_handle, sql, &result, NULL, NULL, NULL); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_get_table(local_db_handle, sql, &result, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;sqlite3_free_table(result);goto FINISH_OFF; }, + ("SQL(%s) sqlite3_get_table fail:%d -%s", sql, rc, sqlite3_errmsg(local_db_handle))); + + *count = atoi(result[1]); + sqlite3_free_table(result); + + if (!*count) { + EM_DEBUG_EXCEPTION("no account found..."); + error = EM_STORAGE_ERROR_MAILBOX_NOT_FOUND; + ret = true; + goto FINISH_OFF; + } + + EM_DEBUG_LOG("Account count [%d]", *count); + + memset(sql_query_string, 0x00, sizeof(sql_query_string)); + + SNPRINTF(sql_query_string, sizeof(sql_query_string), "SELECT distinct account_id FROM mail_partial_body_activity_tbl"); + + EM_DEBUG_LOG("Query [%s]", sql_query_string); + + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_prepare_v2(local_db_handle, sql_query_string, strlen(sql_query_string), &hStmt, NULL), rc); + + EM_DEBUG_LOG("Before sqlite3_prepare hStmt = %p", hStmt); + EM_DEBUG_DB_EXEC((SQLITE_OK != rc), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) sqlite3_prepare fail:(%d) %s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + /* rc = sqlite3_step(hStmt); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_step(hStmt), rc); + EM_DEBUG_DB_EXEC((rc != SQLITE_ROW), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("sqlite3_step fail:%d", rc)); + + if (NULL == (result_account_list = (int *)em_core_malloc(sizeof(int) * (*count)))) { + EM_DEBUG_EXCEPTION(" em_core_malloc failed..."); + error = EM_STORAGE_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + memset(result_account_list, 0x00, sizeof(int) * (*count)); + + for (i = 0; i < (*count); i++) { + _getStmtFieldDataInt(hStmt, result_account_list + i, 0); + /* rc = sqlite3_step(hStmt); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_step(hStmt), rc); + EM_DEBUG_DB_EXEC((rc != SQLITE_ROW && rc != SQLITE_DONE), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("sqlite3_step fail:%d", rc)); + EM_DEBUG_LOG("account id -> %d", result_account_list[i]); + } + + ret = true; + +FINISH_OFF: + if (ret == true) + *account_list = result_account_list; + + if (hStmt != NULL) { + EM_DEBUG_LOG("Before sqlite3_finalize hStmt = %p", hStmt); + + rc = sqlite3_finalize(hStmt); + hStmt = NULL; + if (rc != SQLITE_OK) { + EM_DEBUG_EXCEPTION("sqlite3_finalize failed - %d", rc); + error = EM_STORAGE_ERROR_DB_FAILURE; + } + } + + EM_STORAGE_FINISH_READ_TRANSACTION(transaction); + _DISCONNECT_DB; + if (err_code != NULL) + *err_code = error; + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + + + +EXPORT_API int em_storage_get_pbd_activity_data(int account_id, char *mailbox_name, emf_event_partial_body_thd** event_start, int *count, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id[%d], event_start[%p], err_code[%p]", account_id, event_start, err_code); + + if (account_id < FIRST_ACCOUNT_ID || NULL == event_start || NULL == mailbox_name || NULL == count) { + EM_DEBUG_EXCEPTION("account_id[%d], emf_event_partial_body_thd[%p], mailbox_name[%p], count[%p], err_code[%p]", account_id, event_start, mailbox_name, count, err_code); + + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + int rc = -1; + int ret = false; + char **result; + int error = EM_STORAGE_ERROR_NONE; + int i = 0; + DB_STMT hStmt = NULL; + emf_event_partial_body_thd* event_list = NULL; + char sql_query_string[QUERY_SIZE] = {0, }; + + sqlite3 *local_db_handle = em_storage_get_db_connection(); + + EM_STORAGE_START_READ_TRANSACTION(transaction); + + memset(sql_query_string, 0x00, sizeof(sql_query_string)); + SNPRINTF(sql_query_string, sizeof(sql_query_string), "SELECT count(*) FROM mail_partial_body_activity_tbl WHERE account_id = %d AND mailbox_name = '%s' order by activity_id", account_id, mailbox_name); + + /* rc = sqlite3_get_table(local_db_handle, sql_query_string, &result, NULL, NULL, NULL); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_get_table(local_db_handle, sql_query_string, &result, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;sqlite3_free_table(result);goto FINISH_OFF; }, + ("SQL(%s) sqlite3_get_table fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + *count = atoi(result[1]); + sqlite3_free_table(result); + + EM_DEBUG_LOG("Query = [%s]", sql_query_string); + + if (!*count) { + EM_DEBUG_EXCEPTION("No matched activity found in mail_partial_body_activity_tbl"); + + error = EM_STORAGE_ERROR_MAIL_NOT_FOUND; + ret = true; + goto FINISH_OFF; + } + EM_DEBUG_LOG("Activity Count = %d", *count); + + memset(sql_query_string, 0x00, sizeof(sql_query_string)); + SNPRINTF(sql_query_string, sizeof(sql_query_string), "SELECT * FROM mail_partial_body_activity_tbl WHERE account_id = %d AND mailbox_name = '%s' order by activity_id", account_id, mailbox_name); + + EM_DEBUG_LOG("Query [%s]", sql_query_string); + + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_prepare_v2(local_db_handle, sql_query_string, strlen(sql_query_string), &hStmt, NULL), rc); + + EM_DEBUG_LOG(" Bbefore sqlite3_prepare hStmt = %p", hStmt); + EM_DEBUG_DB_EXEC((SQLITE_OK != rc), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) sqlite3_prepare fail:(%d) %s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + /* rc = sqlite3_step(hStmt); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_step(hStmt), rc); + EM_DEBUG_DB_EXEC((rc != SQLITE_ROW), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("sqlite3_step fail:%d", rc)); + + if (!(event_list = (emf_event_partial_body_thd*)em_core_malloc(sizeof(emf_event_partial_body_thd) * (*count)))) { + EM_DEBUG_EXCEPTION("Malloc failed"); + + error = EM_STORAGE_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + memset(event_list, 0x00, sizeof(emf_event_partial_body_thd) * (*count)); + + for (i=0; i < (*count); i++) { + _getStmtFieldDataInt(hStmt, &(event_list[i].account_id), ACCOUNT_IDX_MAIL_PARTIAL_BODY_ACTIVITY_TBL); + _getStmtFieldDataInt(hStmt, &(event_list[i].mail_id), MAIL_IDX_IN_MAIL_PARTIAL_BODY_ACTIVITY_TBL); + _getStmtFieldDataInt(hStmt, (int *)&(event_list[i].server_mail_id), SERVER_MAIL_IDX_IN_MAIL_PARTIAL_BODY_ACTIVITY_TBL); + _getStmtFieldDataInt(hStmt, &(event_list[i].activity_id), ACTIVITY_IDX_IN_MAIL_PARTIAL_BODY_ACTIVITY_TBL); + _getStmtFieldDataInt(hStmt, &(event_list[i].activity_type), ACTIVITY_TYPE_IDX_IN_MAIL_PARTIAL_BODY_ACTIVITY_TBL); + _getStmtFieldDataString(hStmt, &(event_list[i].mailbox_name), 0, MAILBOX_NAME_IDX_IN_MAIL_PARTIAL_BODY_ACTIVITY_TBL); + + /* rc = sqlite3_step(hStmt); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_step(hStmt), rc); + /* EM_DEBUG_LOG("In em_storage_get_pbd_activity_data() loop, After sqlite3_step(), , i = %d, rc = %d.", i, rc); */ + EM_DEBUG_DB_EXEC((rc != SQLITE_ROW && rc != SQLITE_DONE), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("sqlite3_step fail:%d", rc)); + + event_list[i].event_type = 0; + } + + ret = true; + +FINISH_OFF: + if (true == ret) + *event_start = event_list; + else { + if (event_list) { + for (i=0; i < (*count); i++) + EM_SAFE_FREE(event_list[i].mailbox_name); + EM_SAFE_FREE(event_list); + } + } + + if (hStmt != NULL) { + EM_DEBUG_LOG("Before sqlite3_finalize hStmt = %p", hStmt); + + rc = sqlite3_finalize(hStmt); + hStmt = NULL; + if (rc != SQLITE_OK) { + EM_DEBUG_LOG("sqlite3_finalize failed - %d", rc); + error = EM_STORAGE_ERROR_DB_FAILURE; + } + } + + EM_STORAGE_FINISH_READ_TRANSACTION(transaction); + _DISCONNECT_DB; + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + + + +EXPORT_API int em_storage_delete_pbd_activity(int account_id, int mail_id, int activity_id, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id[%d], mail_id[%d] , activity_id[%d], transaction[%d], err_code[%p]", account_id, mail_id, activity_id, transaction, err_code); + + + if (account_id < FIRST_ACCOUNT_ID || activity_id < 0 || mail_id <= 0) { + EM_DEBUG_EXCEPTION("account_id[%d], mail_id[%d], activity_id[%d], transaction[%d], err_code[%p]", account_id, mail_id, activity_id, transaction, err_code); + + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + int rc = -1; + int ret = false; + int error = EM_STORAGE_ERROR_NONE; + char sql_query_string[QUERY_SIZE] = {0, }; + + sqlite3 *local_db_handle = em_storage_get_db_connection(); + + EM_STORAGE_START_WRITE_TRANSACTION(transaction, error); + memset(sql_query_string, 0x00, sizeof(sql_query_string)); + + if (activity_id == 0) + SNPRINTF(sql_query_string, sizeof(sql_query_string), "DELETE FROM mail_partial_body_activity_tbl WHERE account_id = %d AND mail_id = %d", account_id, mail_id); + else + SNPRINTF(sql_query_string, sizeof(sql_query_string), "DELETE FROM mail_partial_body_activity_tbl WHERE account_id = %d AND activity_id = %d", account_id, activity_id); + + EM_DEBUG_LOG("Query [%s]", sql_query_string); + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, sql_query_string, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC((rc == SQLITE_FULL), {error = EM_STORAGE_ERROR_DB_IS_FULL;goto FINISH_OFF; }, + ("sqlite3_exec fail:%d", rc)); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) exec fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + /* validate activity existence */ + rc = sqlite3_changes(local_db_handle); + if (rc == 0) { + EM_DEBUG_EXCEPTION("No matching activity found"); + error = EM_STORAGE_ERROR_DATA_NOT_FOUND; + ret = true; + goto FINISH_OFF; + } + + ret = true; + +FINISH_OFF: + + EM_STORAGE_FINISH_WRITE_TRANSACTION(transaction, ret, error); + + _DISCONNECT_DB; + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API int em_storage_get_mailbox_pbd_activity_count(int account_id, char *mailbox_name, int *activity_count, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id[%d], activity_count[%p], err_code[%p]", account_id, activity_count, err_code); + + if (account_id < FIRST_ACCOUNT_ID || NULL == activity_count || NULL == err_code) { + EM_DEBUG_EXCEPTION("account_id[%d], activity_count[%p], err_code[%p]", account_id, activity_count, err_code); + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + int rc = -1; + int ret = false; + int error = EM_STORAGE_ERROR_NONE; + char sql_query_string[QUERY_SIZE] = {0, }; + + DB_STMT hStmt = NULL; + + sqlite3 *local_db_handle = em_storage_get_db_connection(); + + EM_STORAGE_START_READ_TRANSACTION(transaction); + memset(sql_query_string, 0x00, sizeof(sql_query_string)); + + SNPRINTF(sql_query_string, sizeof(sql_query_string), "SELECT count(*) FROM mail_partial_body_activity_tbl WHERE account_id = %d and mailbox_name = '%s'", account_id, mailbox_name); + + EM_DEBUG_LOG(" Query [%s]", sql_query_string); + + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_prepare_v2(local_db_handle, sql_query_string, strlen(sql_query_string), &hStmt, NULL), rc); + EM_DEBUG_LOG("before sqlite3_prepare hStmt = %p", hStmt); + EM_DEBUG_DB_EXEC((SQLITE_OK != rc), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) sqlite3_prepare fail:(%d) %s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + /* rc = sqlite3_step(hStmt); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_step(hStmt), rc); + EM_DEBUG_DB_EXEC((rc != SQLITE_ROW), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("sqlite3_step fail:%d", rc)); + + _getStmtFieldDataInt(hStmt, activity_count, 0); + + EM_DEBUG_LOG("No. of activities in activity table [%d]", *activity_count); + + ret = true; + +FINISH_OFF: + + if (hStmt != NULL) { + EM_DEBUG_LOG("Before sqlite3_finalize hStmt = %p", hStmt); + rc = sqlite3_finalize(hStmt); + hStmt=NULL; + if (rc != SQLITE_OK) { + EM_DEBUG_EXCEPTION("sqlite3_finalize failed - %d", rc); + error = EM_STORAGE_ERROR_DB_FAILURE; + } + EM_DEBUG_LOG("sqlite3_finalize- %d", rc); + } + + EM_STORAGE_FINISH_READ_TRANSACTION(transaction); + _DISCONNECT_DB; + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + + +EXPORT_API int em_storage_get_pbd_activity_count(int *activity_count, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("activity_count[%p], err_code[%p]", activity_count, err_code); + + if (NULL == activity_count || NULL == err_code) { + EM_DEBUG_EXCEPTION("activity_count[%p], err_code[%p]", activity_count, err_code); + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + int rc = -1; + int ret = false; + int error = EM_STORAGE_ERROR_NONE; + DB_STMT hStmt = NULL; + char sql_query_string[QUERY_SIZE] = {0, }; + + sqlite3 *local_db_handle = em_storage_get_db_connection(); + + EM_STORAGE_START_READ_TRANSACTION(transaction); + memset(sql_query_string, 0x00, sizeof(sql_query_string)); + + SNPRINTF(sql_query_string, sizeof(sql_query_string), "SELECT count(*) FROM mail_partial_body_activity_tbl;"); + + EM_DEBUG_LOG(" Query [%s]", sql_query_string); + + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_prepare_v2(local_db_handle, sql_query_string, strlen(sql_query_string), &hStmt, NULL), rc); + EM_DEBUG_LOG(" before sqlite3_prepare hStmt = %p", hStmt); + EM_DEBUG_DB_EXEC((SQLITE_OK != rc), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) sqlite3_prepare fail:(%d) %s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + /* rc = sqlite3_step(hStmt); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_step(hStmt), rc); + EM_DEBUG_DB_EXEC((rc != SQLITE_ROW), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("sqlite3_step fail:%d", rc)); + + _getStmtFieldDataInt(hStmt, activity_count, 0); + + EM_DEBUG_LOG("No. of activities in activity table [%d]", *activity_count); + + ret = true; + +FINISH_OFF: + + + if (hStmt != NULL) { + EM_DEBUG_LOG("Before sqlite3_finalize hStmt = %p", hStmt); + + rc = sqlite3_finalize(hStmt); + hStmt=NULL; + if (rc != SQLITE_OK) { + EM_DEBUG_EXCEPTION("sqlite3_finalize failed - %d", rc); + error = EM_STORAGE_ERROR_DB_FAILURE; + } + EM_DEBUG_LOG("sqlite3_finalize- %d", rc); + } + + EM_STORAGE_FINISH_READ_TRANSACTION(transaction); + _DISCONNECT_DB; + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API int em_storage_delete_full_pbd_activity_data(int account_id, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id[%d], transaction[%d], err_code[%p]", account_id, transaction, err_code); + if (account_id < FIRST_ACCOUNT_ID) { + EM_DEBUG_EXCEPTION("account_id[%d], transaction[%d], err_code[%p]", account_id, transaction, err_code); + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + int rc = -1; + int ret = false; + int error = EM_STORAGE_ERROR_NONE; + char sql_query_string[QUERY_SIZE] = {0, }; + + sqlite3 *local_db_handle = em_storage_get_db_connection(); + EM_STORAGE_START_WRITE_TRANSACTION(transaction, error); + memset(sql_query_string, 0x00, sizeof(sql_query_string)); + SNPRINTF(sql_query_string, sizeof(sql_query_string), "DELETE FROM mail_partial_body_activity_tbl WHERE account_id = %d", account_id); + + EM_DEBUG_LOG("Query [%s]", sql_query_string); + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, sql_query_string, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC((rc == SQLITE_FULL), {error = EM_STORAGE_ERROR_DB_IS_FULL;goto FINISH_OFF; }, + ("sqlite3_exec fail:%d", rc)); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) exec fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + + rc = sqlite3_changes(local_db_handle); + if (rc == 0) { + EM_DEBUG_EXCEPTION("No matching activities found in mail_partial_body_activity_tbl"); + error = EM_STORAGE_ERROR_DATA_NOT_FOUND; + ret = true; + goto FINISH_OFF; + } + + ret = true; + +FINISH_OFF: + + EM_STORAGE_FINISH_WRITE_TRANSACTION(transaction, ret, error); + _DISCONNECT_DB; + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +/*Himanshu[h.gahlaut]-> Added below API to update mail_partial_body_activity_tbl +if a mail is moved before its partial body is downloaded.Currently not used but should be used if mail move from server is enabled*/ + +EXPORT_API int em_storage_update_pbd_activity(char *old_server_uid, char *new_server_uid, char *mbox_name, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("old_server_uid[%s], new_server_uid[%s], mbox_name[%s]", old_server_uid, new_server_uid, mbox_name); + + int rc = -1, ret = false; + int error = EM_STORAGE_ERROR_NONE; + char sql_query_string[QUERY_SIZE] = {0, }; + + int transaction = true; + + if (!old_server_uid || !new_server_uid || !mbox_name) { + EM_DEBUG_EXCEPTION("Invalid parameters"); + error = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + sqlite3 *local_db_handle = em_storage_get_db_connection(); + EM_STORAGE_START_WRITE_TRANSACTION(transaction, error); + memset(sql_query_string, 0x00, sizeof(sql_query_string)); + SNPRINTF(sql_query_string, sizeof(sql_query_string), + "UPDATE mail_partial_body_activity_tbl SET server_mail_id = %s , mailbox_name=\'%s\' WHERE server_mail_id = %s ", new_server_uid, mbox_name, old_server_uid); + + EM_DEBUG_LOG("Query [%s]", sql_query_string); + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, sql_query_string, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC((rc == SQLITE_FULL), {error = EM_STORAGE_ERROR_DB_IS_FULL;goto FINISH_OFF; }, + ("sqlite3_exec fail:%d", rc)); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) exec fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + rc = sqlite3_changes(local_db_handle); + if (rc == 0) { + EM_DEBUG_EXCEPTION("No matching found in mail_partial_body_activity_tbl"); + error = EM_STORAGE_ERROR_DATA_NOT_FOUND; + goto FINISH_OFF; + } + + ret = true; + +FINISH_OFF: + + EM_STORAGE_FINISH_WRITE_TRANSACTION(transaction, ret, error); + _DISCONNECT_DB; + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + + +EXPORT_API int em_storage_create_file(char *data_string, size_t file_size, char *dst_file_name, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("file_size[%d] , dst_file_name[%s], err_code[%p]", file_size, dst_file_name, err_code); + + int ret = false; + int error = EM_STORAGE_ERROR_NONE; + + FILE* fp_dst = NULL; + + if (!data_string || !dst_file_name) { + EM_DEBUG_EXCEPTION("data_string[%p], dst_file_name[%p]", data_string, dst_file_name); + error = EM_STORAGE_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + fp_dst = fopen(dst_file_name, "w"); + + if (!fp_dst) { + EM_DEBUG_EXCEPTION("fopen failed - %s", dst_file_name); + if (errno == 28) + error = EMF_ERROR_MAIL_MEMORY_FULL; + else + error = EM_STORAGE_ERROR_SYSTEM_FAILURE; + goto FINISH_OFF; + } + + if (fwrite(data_string, 1, file_size, fp_dst) < 0) { + EM_DEBUG_EXCEPTION("fwrite failed..."); + error = EM_STORAGE_ERROR_UNKNOWN; + goto FINISH_OFF; + } + + ret = true; + +FINISH_OFF: + + if (fp_dst != NULL) + fclose(fp_dst); + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +#endif /* __FEATURE_PARTIAL_BODY_DOWNLOAD__ */ + + + +#ifdef __FEATURE_BULK_DELETE_MOVE_UPDATE_REQUEST_OPTI__ + +EXPORT_API int em_storage_update_read_mail_uid_by_server_uid(char *old_server_uid, char *new_server_uid, char *mbox_name, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN(); + int rc = -1; + int ret = false; + int error = EM_STORAGE_ERROR_NONE; + char sql_query_string[QUERY_SIZE] = {0, }; + + int transaction = true; + + if (!old_server_uid || !new_server_uid || !mbox_name) { + EM_DEBUG_EXCEPTION("Invalid parameters"); + error = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + EM_DEBUG_LOG("old_server_uid[%s], new_server_uid[%s], mbox_name[%s]", old_server_uid, new_server_uid, mbox_name); + + sqlite3 *local_db_handle = em_storage_get_db_connection(); + EM_STORAGE_START_WRITE_TRANSACTION(transaction, error); + + + SNPRINTF(sql_query_string, sizeof(sql_query_string), + "UPDATE mail_read_mail_uid_tbl SET s_uid=\'%s\' , local_mbox=\'%s\', mailbox_name=\'%s\' WHERE s_uid=%s ", new_server_uid, mbox_name, mbox_name, old_server_uid); + + EM_DEBUG_LOG(" Query [%s]", sql_query_string); + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, sql_query_string, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC((rc == SQLITE_FULL), {error = EM_STORAGE_ERROR_DB_IS_FULL;goto FINISH_OFF; }, + ("sqlite3_exec fail:%d", rc)); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) exec fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + + rc = sqlite3_changes(local_db_handle); + if (rc == 0) + { + EM_DEBUG_EXCEPTION("No matching found in mail_partial_body_activity_tbl"); + error = EM_STORAGE_ERROR_DATA_NOT_FOUND; + goto FINISH_OFF; + } + + + ret = true; + +FINISH_OFF: + + EM_STORAGE_FINISH_WRITE_TRANSACTION(transaction, ret, error); + _DISCONNECT_DB; + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; + +} + + +/** + * @fn em_storage_get_id_set_from_mail_ids(int mail_ids[], int mail_id_count, emf_id_set_t** server_uids, int *id_set_count, int *err_code); + * Prepare an array of mail_id and corresponding server mail id. + * + *@author h.gahlaut@samsung.com + * @param[in] mail_ids Specifies the comma separated string of mail_ids. Maximaum size of string should be less than or equal to (QUERY_SIZE - 88) + * where 88 is the length of fixed keywords including ending null character in the QUERY to be formed + * @param[out] idset Returns the array of mail_id and corresponding server_mail_id sorted by server_mail_ids + * @param[out] id_set_count Returns the no. of cells in idset array i.e. no. of sets of mail_ids and server_mail_ids + * @param[out] err_code Returns the error code. + * @remarks An Example of Query to be exexuted in this API: + * SELECT local_uid, s_uid from mail_read_mail_uid_tbl where local_uid in (12, 13, 56, 78); + * @return This function returns true on success or false on failure. + */ + +EXPORT_API int em_storage_get_id_set_from_mail_ids(char *mail_ids, emf_id_set_t** idset, int *id_set_count, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN(); + EM_PROFILE_BEGIN(EmStorageGetIdSetFromMailIds); + + int error = EM_STORAGE_ERROR_NONE; + int ret = false; + emf_id_set_t* p_id_set = NULL; + int count = 0; + const int buf_size = QUERY_SIZE; + char sql_query_string[QUERY_SIZE] = {0, }; + int space_left_in_query_buffer = buf_size; + int i = 0; + int rc = -1; + char *server_mail_id = NULL; + char **result = NULL; + int col_index = 0; + + + if (NULL == mail_ids || NULL == idset || NULL == id_set_count) { + EM_DEBUG_EXCEPTION("Invalid Parameters mail_ids[%p] idset[%p] id_set_count [%p]", mail_ids, idset, id_set_count); + error = EM_STORAGE_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + sqlite3 *local_db_handle = em_storage_get_db_connection(); + + SNPRINTF(sql_query_string, space_left_in_query_buffer, "SELECT local_uid, s_uid FROM mail_read_mail_uid_tbl WHERE local_uid in (%s) ORDER BY s_uid", mail_ids); + + EM_DEBUG_LOG("SQL Query formed [%s] ", sql_query_string); + + /* rc = sqlite3_get_table(local_db_handle, sql_query_string, &result, &count, 0, NULL); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_get_table(local_db_handle, sql_query_string, &result, &count, 0, NULL), rc); + EM_DEBUG_DB_EXEC((SQLITE_OK != rc && -1 != rc), {error = EM_STORAGE_ERROR_DB_FAILURE;sqlite3_free_table(result);goto FINISH_OFF; }, + ("SQL(%s) sqlite3_get_table fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + EM_DEBUG_LOG(" Count of mails [%d ]", count); + + if (count <= 0) { + EM_DEBUG_EXCEPTION("Can't find proper mail"); + error = EM_STORAGE_ERROR_DATA_NOT_FOUND; + goto FINISH_OFF; + } + + + if (NULL == (p_id_set = (emf_id_set_t*)em_core_malloc(sizeof(emf_id_set_t) * count))) { + EM_DEBUG_EXCEPTION(" em_core_malloc failed..."); + error = EM_STORAGE_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + col_index = 2; + + EM_PROFILE_BEGIN(EmStorageGetIdSetFromMailIds_Loop); + EM_DEBUG_LOG(">>>> DATA ASSIGN START"); + for (i = 0; i < count; i++) { + _getTableFieldDataInt(result, &(p_id_set[i].mail_id), col_index++); + _getTableFieldDataString(result, &server_mail_id, 1, col_index++); + p_id_set[i].server_mail_id = strtoul(server_mail_id, NULL, 10); + EM_SAFE_FREE(server_mail_id); + } + EM_DEBUG_LOG(">>>> DATA ASSIGN END [count : %d]", count); + EM_PROFILE_END(EmStorageGetIdSetFromMailIds_Loop); + + sqlite3_free_table(result); + result = NULL; + + ret = true; + + FINISH_OFF: + + if (ret == true) { + *idset = p_id_set; + *id_set_count = count; + EM_DEBUG_LOG(" idset[%p] id_set_count [%d]", *idset, *id_set_count); + } + else + EM_SAFE_FREE(p_id_set); + + _DISCONNECT_DB; + + if (err_code != NULL) + *err_code = error; + + EM_PROFILE_END(EmStorageGetIdSetFromMailIds); + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + + + +#endif + +EXPORT_API int em_storage_delete_triggers_from_lucene() +{ + EM_DEBUG_FUNC_BEGIN(); + int rc, ret = true, transaction = true; + int error = EM_STORAGE_ERROR_NONE; + char sql_query_string[QUERY_SIZE] = {0, }; + + sqlite3 *local_db_handle = em_storage_get_db_connection(); + EM_STORAGE_START_WRITE_TRANSACTION(transaction, error); + + SNPRINTF(sql_query_string, sizeof(sql_query_string), "DROP TRIGGER triggerDelete;"); + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, sql_query_string, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) exec fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + SNPRINTF(sql_query_string, sizeof(sql_query_string), "DROP TRIGGER triggerInsert;"); + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, sql_query_string, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) exec fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + + SNPRINTF(sql_query_string, sizeof(sql_query_string), "DROP TRIGGER triggerUpdate;"); + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, sql_query_string, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) exec fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + ret = true; + +FINISH_OFF: + + EM_STORAGE_FINISH_WRITE_TRANSACTION(transaction, ret, error); + + _DISCONNECT_DB; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API int em_storage_filter_mails_by_rule(int account_id, char *dest_mailbox_name, emf_mail_rule_tbl_t *rule, int ** filtered_mail_id_list, int *count_of_mails, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id[%d], dest_mailbox_name[%p] rule[%p], filtered_mail_id_list[%p], count_of_mails[%p], err_code[%p]", account_id, dest_mailbox_name, rule, filtered_mail_id_list, count_of_mails, err_code); + + if ((account_id <= 0) || (!dest_mailbox_name) || (!rule) || (!rule->value)|| (!filtered_mail_id_list) || (!count_of_mails)) { + EM_DEBUG_EXCEPTION("Invalid Parameter"); + + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + int rc = -1, ret = false, error = EM_STORAGE_ERROR_NONE; + int count = 0, col_index = 0, i = 0, where_pararaph_length = 0, *mail_list = NULL; + char **result = NULL, *where_pararaph = NULL; + char sql_query_string[QUERY_SIZE] = {0, }; + + sqlite3 *local_db_handle = em_storage_get_db_connection(); + + SNPRINTF(sql_query_string, sizeof(sql_query_string), "SELECT mail_id FROM mail_tbl "); + + EM_DEBUG_LOG("rule->value [%s]", rule->value); + + where_pararaph_length = strlen(rule->value) + 100; + where_pararaph = malloc(sizeof(char) * where_pararaph_length); + + if (where_pararaph == NULL) { + EM_DEBUG_EXCEPTION("malloc failed for where_pararaph."); + error = EM_STORAGE_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + memset(where_pararaph, 0, sizeof(char) * where_pararaph_length); + + EM_DEBUG_LOG("rule->type [%d], rule->flag2[%d]", rule->type, rule->flag2); + + if (rule->type == EMF_FILTER_FROM) { + if (rule->flag2 == RULE_TYPE_INCLUDES) + SNPRINTF(where_pararaph, where_pararaph_length, "WHERE account_id = %d AND mailbox_type NOT in (3,5) AND full_address_from like \'%%%s%%\'", account_id, rule->value); + else /* RULE_TYPE_EXACTLY */ + SNPRINTF(where_pararaph, where_pararaph_length, "WHERE account_id = %d AND mailbox_type NOT in (3,5) AND full_address_from = \'%s\'", account_id, rule->value); + } + else if (rule->type == EMF_FILTER_SUBJECT) { + if (rule->flag2 == RULE_TYPE_INCLUDES) + SNPRINTF(where_pararaph, where_pararaph_length, "WHERE account_id = %d AND mailbox_type NOT in (3,5) AND subject like \'%%%s%%\'", account_id, rule->value); + else /* RULE_TYPE_EXACTLY */ + SNPRINTF(where_pararaph, where_pararaph_length, "WHERE account_id = %d AND mailbox_type NOT in (3,5) AND subject = \'%s\'", account_id, rule->value); + } + else { + error = EM_STORAGE_ERROR_INVALID_PARAM; + EM_DEBUG_EXCEPTION("rule->type is invald"); + goto FINISH_OFF; + } + + if (strlen(sql_query_string) + strlen(where_pararaph) < QUERY_SIZE) + strcat(sql_query_string, where_pararaph); + + EM_DEBUG_LOG("query[%s]", sql_query_string); + + /* rc = sqlite3_get_table(local_db_handle, sql_query_string, &result, &count, 0, NULL); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_get_table(local_db_handle, sql_query_string, &result, &count, 0, NULL), rc); + EM_DEBUG_DB_EXEC((SQLITE_OK != rc && -1 != rc), {error = EM_STORAGE_ERROR_DB_FAILURE;sqlite3_free_table(result);goto FINISH_OFF; }, + ("SQL(%s) sqlite3_get_table fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + EM_DEBUG_LOG("Count of mails [%d]", count); + + if (count) { + mail_list = malloc(sizeof(int) * count); + if (mail_list == NULL) { + EM_DEBUG_EXCEPTION("malloc failed for mail_list."); + error = EM_STORAGE_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + col_index = 1; + + for (i = 0; i < count; i++) + _getTableFieldDataInt(result, &(mail_list[i]), col_index++); + + SNPRINTF(sql_query_string, sizeof(sql_query_string), "UPDATE mail_tbl SET mailbox_name = \'%s\', mailbox_type = 5 ", dest_mailbox_name); + + if (strlen(sql_query_string) + strlen(where_pararaph) < QUERY_SIZE) + strcat(sql_query_string, where_pararaph); + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, sql_query_string, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) exec fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + } + + *filtered_mail_id_list = mail_list; + + ret = true; + +FINISH_OFF: + + sqlite3_free_table(result); + result = NULL; + + _DISCONNECT_DB; + + EM_SAFE_FREE(where_pararaph); + + if (ret && count_of_mails) + *count_of_mails = count; + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +#define EMF_SLOT_UNIT 25 + +EXPORT_API int em_storage_set_mail_slot_size(int account_id, char *mailbox_name, int new_slot_size, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id[%d], mailbox_name[%p] new_slot_size[%d], err_code[%p]", account_id, mailbox_name, new_slot_size, err_code); + int rc = -1, ret = false, err = EM_STORAGE_ERROR_NONE; + int where_pararaph_length = 0; + char *where_pararaph = NULL; + char sql_query_string[QUERY_SIZE] = {0, }; + int and = 0; + sqlite3 *local_db_handle = em_storage_get_db_connection(); + + EM_STORAGE_START_WRITE_TRANSACTION(transaction, err); + + if (new_slot_size > 0) + SNPRINTF(sql_query_string, sizeof(sql_query_string), "UPDATE mail_box_tbl SET mail_slot_size = %d ", new_slot_size); + else if (new_slot_size == 0) + SNPRINTF(sql_query_string, sizeof(sql_query_string), "UPDATE mail_box_tbl SET mail_slot_size = mail_slot_size + %d ", EMF_SLOT_UNIT); + else + SNPRINTF(sql_query_string, sizeof(sql_query_string), "UPDATE mail_box_tbl SET mail_slot_size = mail_slot_size + %d ", new_slot_size * -1); + + + if (mailbox_name) + where_pararaph_length = strlen(mailbox_name) + 80; + else + where_pararaph_length = 50; + + if (new_slot_size == 0) + where_pararaph_length += 70; + + where_pararaph = malloc(sizeof(char) * where_pararaph_length); + if (where_pararaph == NULL) { + EM_DEBUG_EXCEPTION("Memory allocation failed for where_pararaph"); + err = EMF_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + memset(where_pararaph, 0x00, where_pararaph_length); + + if (account_id > ALL_ACCOUNT) { + and = 1; + if (mailbox_name) + SNPRINTF(where_pararaph, where_pararaph_length, "WHERE account_id = %d AND mailbox_name = '%s' ", account_id, mailbox_name); + else + SNPRINTF(where_pararaph, where_pararaph_length, "WHERE account_id = %d ", account_id); + } + + if (new_slot_size == 0) + SNPRINTF(where_pararaph + strlen(where_pararaph), where_pararaph_length - strlen(where_pararaph), " %s total_mail_count_on_server > mail_slot_size ", (and ? "AND" : "WHERE")); + + if (strlen(sql_query_string) + strlen(where_pararaph) < QUERY_SIZE) + strcat(sql_query_string, where_pararaph); + else { + EM_DEBUG_EXCEPTION("Query buffer overflowed !!!"); + err = EMF_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + EM_DEBUG_LOG("query[%s]", sql_query_string); + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, sql_query_string, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {err = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) exec fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + ret = true; + +FINISH_OFF: + + EM_STORAGE_FINISH_WRITE_TRANSACTION(transaction, ret, err); + + _DISCONNECT_DB; + + EM_SAFE_FREE(where_pararaph); + + if (err_code != NULL) + *err_code = err; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API int em_storage_add_meeting_request(int account_id, char *mailbox_name, emf_meeting_request_t* meeting_req, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id[%d], mailbox_name[%s], meeting_req[%p], transaction[%d], err_code[%p]", account_id, mailbox_name, meeting_req, transaction, err_code); + + if (!meeting_req || meeting_req->mail_id <= 0) { + if (meeting_req) + EM_DEBUG_EXCEPTION("mail_id[%]d", meeting_req->mail_id); + + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + + return false; + } + + int rc = -1; + int ret = false; + int error = EM_STORAGE_ERROR_NONE; + DB_STMT hStmt = NULL; + char sql_query_string[QUERY_SIZE] = {0, }; + int col_index = 0; + time_t temp_unix_time = 0; + + sqlite3 *local_db_handle = em_storage_get_db_connection(); + EM_STORAGE_START_WRITE_TRANSACTION(transaction, error); + + SNPRINTF(sql_query_string, sizeof(sql_query_string), + "INSERT INTO mail_meeting_tbl VALUES " + "( ?" /* mail_id */ + ", ?" /* account_id */ + ", ?" /* mailbox_name */ + ", ?" /* meeting_response */ + ", ?" /* start_time */ + ", ?" /* end_time */ + ", ?" /* location */ + ", ?" /* global_object_id */ + ", ?" /* offset */ + ", ?" /* standard_name */ + ", ?" /* standard_time_start_date */ + ", ?" /* standard_biad */ + ", ?" /* daylight_name */ + ", ?" /* daylight_time_start_date */ + ", ?" /* daylight_bias */ + " )"); + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_prepare_v2(local_db_handle, sql_query_string, strlen(sql_query_string), &hStmt, NULL), rc); + if (rc != SQLITE_OK) { + EM_DEBUG_LOG(" before sqlite3_prepare hStmt = %p", hStmt); + EM_DEBUG_EXCEPTION("SQL(%s) sqlite3_prepare fail:(%d) %s", sql_query_string, rc, sqlite3_errmsg(local_db_handle)); + + error = EM_STORAGE_ERROR_DB_FAILURE; + goto FINISH_OFF; + } + + col_index = 0; + /* + EM_DEBUG_LOG(">>>>> meeting_req->mail_id[%d]", meeting_req->mail_id); + EM_DEBUG_LOG(">>>>> account_id[%d]", account_id); + EM_DEBUG_LOG(">>>>> mailbox_name[%s]", mailbox_name); + EM_DEBUG_LOG(">>>>> meeting_req->meeting_response[%d]", meeting_req->meeting_response); + EM_DEBUG_LOG(">>>>> meeting_req->start_time[%s]", asctime(&(meeting_req->start_time))); + EM_DEBUG_LOG(">>>>> meeting_req->end_time[%s]", asctime(&(meeting_req->end_time))); + EM_DEBUG_LOG(">>>>> meeting_req->location[%s]", meeting_req->location); + EM_DEBUG_LOG(">>>>> meeting_req->global_object_id[%s]", meeting_req->global_object_id); + EM_DEBUG_LOG(">>>>> meeting_req->time_zone.offset_from_GMT[%d]", meeting_req->time_zone.offset_from_GMT); + EM_DEBUG_LOG(">>>>> meeting_req->time_zone.standard_name[%s]", meeting_req->time_zone.standard_name); + EM_DEBUG_LOG(">>>>> meeting_req->time_zone.standard_time_start_date[%s]", asctime(&(meeting_req->time_zone.standard_time_start_date))); + EM_DEBUG_LOG(">>>>> meeting_req->time_zone.standard_bias[%d]", meeting_req->time_zone.standard_bias); + EM_DEBUG_LOG(">>>>> meeting_req->time_zone.daylight_name[%s]", meeting_req->time_zone.daylight_name); + EM_DEBUG_LOG(">>>>> meeting_req->time_zone.daylight_time_start_date[%s]", asctime(&(meeting_req->time_zone.daylight_time_start_date))); + EM_DEBUG_LOG(">>>>> meeting_req->time_zone.daylight_bias[%d]", meeting_req->time_zone.daylight_bias); + */ + _bindStmtFieldDataInt(hStmt, col_index++, meeting_req->mail_id); + _bindStmtFieldDataInt(hStmt, col_index++, account_id); + _bindStmtFieldDataString(hStmt, col_index++, (char *)mailbox_name, 0, MAILBOX_LEN_IN_MAIL_MEETING_TBL); + _bindStmtFieldDataInt(hStmt, col_index++, meeting_req->meeting_response); + + temp_unix_time = timegm(&(meeting_req->start_time)); + _bindStmtFieldDataInt(hStmt, col_index++, temp_unix_time); + temp_unix_time = timegm(&(meeting_req->end_time)); + _bindStmtFieldDataInt(hStmt, col_index++, temp_unix_time); + + _bindStmtFieldDataString(hStmt, col_index++, (char *)meeting_req->location, 0, LOCATION_LEN_IN_MAIL_MEETING_TBL); + _bindStmtFieldDataString(hStmt, col_index++, (char *)meeting_req->global_object_id, 0, GLOBAL_OBJECT_ID_LEN_IN_MAIL_MEETING_TBL); + + _bindStmtFieldDataInt(hStmt, col_index++, meeting_req->time_zone.offset_from_GMT); + _bindStmtFieldDataString(hStmt, col_index++, (char *)meeting_req->time_zone.standard_name, 0, STANDARD_NAME_LEN_IN_MAIL_MEETING_TBL); + temp_unix_time = timegm(&(meeting_req->time_zone.standard_time_start_date)); + _bindStmtFieldDataInt(hStmt, col_index++, temp_unix_time); + _bindStmtFieldDataInt(hStmt, col_index++, meeting_req->time_zone.standard_bias); + + _bindStmtFieldDataString(hStmt, col_index++, (char *)meeting_req->time_zone.daylight_name, 0, DAYLIGHT_NAME_LEN_IN_MAIL_MEETING_TBL); + temp_unix_time = timegm(&(meeting_req->time_zone.daylight_time_start_date)); + _bindStmtFieldDataInt(hStmt, col_index++, temp_unix_time); + _bindStmtFieldDataInt(hStmt, col_index++, meeting_req->time_zone.daylight_bias); + + /* rc = sqlite3_step(hStmt); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_step(hStmt), rc); + EM_DEBUG_DB_EXEC((rc == SQLITE_FULL), {error = EM_STORAGE_ERROR_DB_IS_FULL;goto FINISH_OFF; }, + ("sqlite3_step fail:%d", rc)); + EM_DEBUG_DB_EXEC((rc != SQLITE_ROW && rc != SQLITE_DONE), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("sqlite3_step fail:%d", rc)); + + ret = true; + +FINISH_OFF: + if (hStmt != NULL) { + EM_DEBUG_LOG("before sqlite3_finalize hStmt = %p", hStmt); + + rc = sqlite3_finalize(hStmt); + if (rc != SQLITE_OK) { + EM_DEBUG_LOG(" sqlite3_finalize failed - %d", rc); + error = EM_STORAGE_ERROR_DB_FAILURE; + } + } + + EM_STORAGE_FINISH_WRITE_TRANSACTION(transaction, ret, error); + _DISCONNECT_DB; + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API int em_storage_get_meeting_request(int mail_id, emf_meeting_request_t ** meeting_req, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN(); + + int count = 0; + int rc = -1; + int ret = false; + int error = EM_STORAGE_ERROR_NONE; + emf_meeting_request_t *p_temp_meeting_req = NULL; + int col_index = 0; + time_t temp_unix_time; + + EM_IF_NULL_RETURN_VALUE(meeting_req, false); + + DB_STMT hStmt = NULL; + char sql_query_string[QUERY_SIZE] = {0, }; + + sqlite3 *local_db_handle = em_storage_get_db_connection(); + EM_STORAGE_START_READ_TRANSACTION(transaction); + + SNPRINTF(sql_query_string, sizeof(sql_query_string), + "SELECT mail_id, meeting_response, start_time, end_time, location, global_object_id, offset, standard_name, standard_time_start_date, standard_bias, daylight_name, daylight_time_start_date, daylight_bias " + " FROM mail_meeting_tbl " + " WHERE mail_id = %d", mail_id); + EM_DEBUG_LOG("sql : %s ", sql_query_string); + + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_prepare_v2(local_db_handle, sql_query_string, strlen(sql_query_string), &hStmt, NULL), rc); + + EM_DEBUG_DB_EXEC((SQLITE_OK != rc), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) sqlite3_prepare fail:(%d) %s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + /* rc = sqlite3_step(hStmt); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_step(hStmt), rc); + EM_DEBUG_DB_EXEC((rc != SQLITE_ROW && rc != SQLITE_DONE), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("sqlite3_step fail:%d", rc)); + + if (rc == SQLITE_DONE) { + EM_DEBUG_EXCEPTION(" no Meeting request found..."); + count = 0; + ret = false; + error= EM_STORAGE_ERROR_DATA_NOT_FOUND; + goto FINISH_OFF; + } + + if (!(p_temp_meeting_req = (emf_meeting_request_t*)malloc(sizeof(emf_meeting_request_t)))) { + EM_DEBUG_EXCEPTION(" malloc failed..."); + error = EM_STORAGE_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + memset(p_temp_meeting_req, 0x00, sizeof(emf_meeting_request_t)); + + col_index = 0; + + _getStmtFieldDataInt(hStmt, &(p_temp_meeting_req->mail_id), col_index++); + _getStmtFieldDataInt(hStmt, (int *)&(p_temp_meeting_req->meeting_response), col_index++); + _getStmtFieldDataInt(hStmt, (int *)(&temp_unix_time), col_index++); + gmtime_r(&temp_unix_time, &(p_temp_meeting_req->start_time)); + _getStmtFieldDataInt(hStmt, (int *)(&temp_unix_time), col_index++); + gmtime_r(&temp_unix_time, &(p_temp_meeting_req->end_time)); + _getStmtFieldDataString(hStmt, &p_temp_meeting_req->location, 1, col_index++); + _getStmtFieldDataStringWithoutAllocation(hStmt, p_temp_meeting_req->global_object_id, GLOBAL_OBJECT_ID_LEN_IN_MAIL_MEETING_TBL, 1, col_index++); + _getStmtFieldDataInt(hStmt, &(p_temp_meeting_req->time_zone.offset_from_GMT), col_index++); + + _getStmtFieldDataStringWithoutAllocation(hStmt, p_temp_meeting_req->time_zone.standard_name, STANDARD_NAME_LEN_IN_MAIL_MEETING_TBL, 1, col_index++); + _getStmtFieldDataInt(hStmt, (int *)(&temp_unix_time), col_index++); + gmtime_r(&temp_unix_time, &(p_temp_meeting_req->time_zone.standard_time_start_date)); + _getStmtFieldDataInt(hStmt, &(p_temp_meeting_req->time_zone.standard_bias), col_index++); + + _getStmtFieldDataStringWithoutAllocation(hStmt, p_temp_meeting_req->time_zone.daylight_name, DAYLIGHT_NAME_LEN_IN_MAIL_MEETING_TBL, 1, col_index++); + _getStmtFieldDataInt(hStmt, (int *)(&temp_unix_time), col_index++); + gmtime_r(&temp_unix_time, &(p_temp_meeting_req->time_zone.daylight_time_start_date)); + _getStmtFieldDataInt(hStmt, &(p_temp_meeting_req->time_zone.daylight_bias), col_index++); + + /* + EM_DEBUG_LOG(">>>>> meeting_req->mail_id[%d]", p_temp_meeting_req->mail_id); + EM_DEBUG_LOG(">>>>> meeting_req->meeting_response[%d]", p_temp_meeting_req->meeting_response); + EM_DEBUG_LOG(">>>>> meeting_req->start_time[%s]", asctime(&(p_temp_meeting_req->start_time))); + EM_DEBUG_LOG(">>>>> meeting_req->end_time[%s]", asctime(&(p_temp_meeting_req->end_time))); + EM_DEBUG_LOG(">>>>> meeting_req->location[%s]", p_temp_meeting_req->location); + EM_DEBUG_LOG(">>>>> meeting_req->global_object_id[%s]", p_temp_meeting_req->global_object_id); + EM_DEBUG_LOG(">>>>> meeting_req->time_zone.offset_from_GMT[%d]", p_temp_meeting_req->time_zone.offset_from_GMT); + EM_DEBUG_LOG(">>>>> meeting_req->time_zone.standard_name[%s]", p_temp_meeting_req->time_zone.standard_name); + EM_DEBUG_LOG(">>>>> meeting_req->time_zone.standard_time_start_date[%s]", asctime(&(p_temp_meeting_req->time_zone.standard_time_start_date))); + EM_DEBUG_LOG(">>>>> meeting_req->time_zone.standard_bias[%d]", p_temp_meeting_req->time_zone.standard_bias); + EM_DEBUG_LOG(">>>>> meeting_req->time_zone.daylight_name[%s]", p_temp_meeting_req->time_zone.daylight_name); + EM_DEBUG_LOG(">>>>> meeting_req->time_zone.daylight_time_start_date[%s]", asctime(&(p_temp_meeting_req->time_zone.daylight_time_start_date))); + EM_DEBUG_LOG(">>>>> meeting_req->time_zone.daylight_bias[%d]", p_temp_meeting_req->time_zone.daylight_bias); + */ + ret = true; + +FINISH_OFF: + if (ret == true) + *meeting_req = p_temp_meeting_req; + else { + EM_SAFE_FREE(p_temp_meeting_req); + } + + if (hStmt != NULL) { + EM_DEBUG_LOG("before sqlite3_finalize hStmt = %p", hStmt); + + rc = sqlite3_finalize(hStmt); + hStmt = NULL; + if (rc != SQLITE_OK) { + EM_DEBUG_EXCEPTION("sqlite3_finalize failed - %d", rc); + error = EM_STORAGE_ERROR_DB_FAILURE; + } + } + + EM_STORAGE_FINISH_READ_TRANSACTION(transaction); + _DISCONNECT_DB; + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + + +EXPORT_API int em_storage_update_meeting_request(emf_meeting_request_t* meeting_req, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("meeting_req[%p], transaction[%d], err_code[%p]", meeting_req, transaction, err_code); + + int ret = false; + int error = EM_STORAGE_ERROR_NONE; + int rc; + DB_STMT hStmt = NULL; + char sql_query_string[QUERY_SIZE] = {0, }; + time_t temp_unix_time = 0; + + if (!meeting_req) { + EM_DEBUG_EXCEPTION("Invalid Parameter!"); + error = EM_STORAGE_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + sqlite3 *local_db_handle = em_storage_get_db_connection(); + EM_STORAGE_START_WRITE_TRANSACTION(transaction, error); + + memset(sql_query_string, 0x00, sizeof(sql_query_string)); + SNPRINTF(sql_query_string, sizeof(sql_query_string), + "UPDATE mail_meeting_tbl " + "SET " + /* " account_id = ?, " // not update here, this can be changed when move or copy */ + /* " mailbox_name = ?, " // not update here, this can be changed when move or copy */ + " meeting_response = ?, " + " start_time = ?, " + " end_time = ?, " + " location = ?, " + " global_object_id = ?, " + " offset = ?, " + " standard_name = ?, " + " standard_time_start_date = ?, " + " standard_bias = ?, " + " daylight_name = ?, " + " daylight_time_start_date = ?, " + " daylight_bias = ? " + "WHERE mail_id = %d", + meeting_req->mail_id); + + EM_DEBUG_LOG("SQL(%s)", sql_query_string); + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_prepare_v2(local_db_handle, sql_query_string, strlen(sql_query_string), &hStmt, NULL), rc); + EM_DEBUG_DB_EXEC((SQLITE_OK != rc), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) sqlite3_prepare fail:(%d) %s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); +/* + EM_DEBUG_LOG(">>>>> meeting_req->mail_id[%d]", meeting_req->mail_id); + EM_DEBUG_LOG(">>>>> meeting_req->meeting_response[%d]", meeting_req->meeting_response); + EM_DEBUG_LOG(">>>>> meeting_req->start_time[%s]", asctime(&(meeting_req->start_time))); + EM_DEBUG_LOG(">>>>> meeting_req->end_time[%s]", asctime(&(meeting_req->end_time))); + EM_DEBUG_LOG(">>>>> meeting_req->location[%s]", meeting_req->location); + EM_DEBUG_LOG(">>>>> meeting_req->global_object_id[%s]", meeting_req->global_object_id); + EM_DEBUG_LOG(">>>>> meeting_req->time_zone.offset_from_GMT[%d]", meeting_req->time_zone.offset_from_GMT); + EM_DEBUG_LOG(">>>>> meeting_req->time_zone.standard_name[%s]", meeting_req->time_zone.standard_name); + EM_DEBUG_LOG(">>>>> meeting_req->time_zone.standard_time_start_date[%s]", asctime(&(meeting_req->time_zone.standard_time_start_date))); + EM_DEBUG_LOG(">>>>> meeting_req->time_zone.standard_bias[%d]", meeting_req->time_zone.standard_bias); + EM_DEBUG_LOG(">>>>> meeting_req->time_zone.daylight_name[%s]", meeting_req->time_zone.daylight_name); + EM_DEBUG_LOG(">>>>> meeting_req->time_zone.daylight_time_start_date[%s]", asctime(&(meeting_req->time_zone.daylight_time_start_date))); + EM_DEBUG_LOG(">>>>> meeting_req->time_zone.daylight_bias[%d]", meeting_req->time_zone.daylight_bias); +*/ + int col_index = 0; + + _bindStmtFieldDataInt(hStmt, col_index++, meeting_req->meeting_response); + temp_unix_time = timegm(&(meeting_req->start_time)); + _bindStmtFieldDataInt(hStmt, col_index++, temp_unix_time); + temp_unix_time = timegm(&(meeting_req->end_time)); + _bindStmtFieldDataInt(hStmt, col_index++, temp_unix_time); + _bindStmtFieldDataString(hStmt, col_index++, meeting_req->location, 1, LOCATION_LEN_IN_MAIL_MEETING_TBL); + _bindStmtFieldDataString(hStmt, col_index++, meeting_req->global_object_id, 1, GLOBAL_OBJECT_ID_LEN_IN_MAIL_MEETING_TBL); + _bindStmtFieldDataInt(hStmt, col_index++, meeting_req->time_zone.offset_from_GMT); + _bindStmtFieldDataString(hStmt, col_index++, meeting_req->time_zone.standard_name, 1, STANDARD_NAME_LEN_IN_MAIL_MEETING_TBL); + temp_unix_time = timegm(&(meeting_req->time_zone.standard_time_start_date)); + _bindStmtFieldDataInt(hStmt, col_index++, temp_unix_time); + _bindStmtFieldDataInt(hStmt, col_index++, meeting_req->time_zone.standard_bias); + _bindStmtFieldDataString(hStmt, col_index++, meeting_req->time_zone.daylight_name, 1, DAYLIGHT_NAME_LEN_IN_MAIL_MEETING_TBL); + temp_unix_time = timegm(&(meeting_req->time_zone.daylight_time_start_date)); + _bindStmtFieldDataInt(hStmt, col_index++, temp_unix_time); + _bindStmtFieldDataInt(hStmt, col_index++, meeting_req->time_zone.daylight_bias); + + /* rc = sqlite3_step(hStmt); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_step(hStmt), rc); + EM_DEBUG_DB_EXEC((rc != SQLITE_ROW && rc != SQLITE_DONE), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("sqlite3_step fail:%d", rc)); + ret = true; + + +FINISH_OFF: + EM_STORAGE_FINISH_WRITE_TRANSACTION(transaction, ret, error); + + if (hStmt != NULL) { + EM_DEBUG_LOG("before sqlite3_finalize hStmt = %p", hStmt); + + rc = sqlite3_finalize(hStmt); + if (rc != SQLITE_OK) { + EM_DEBUG_EXCEPTION(" sqlite3_finalize failed - %d", rc); + + error = EM_STORAGE_ERROR_DB_FAILURE; + } + } + + _DISCONNECT_DB; + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + + +EXPORT_API int em_storage_change_meeting_request_field(int account_id, char *mailbox_name, emf_mail_change_type_t type, emf_meeting_request_t* meeting_req, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id[%d], mailbox_name[%s], type[%d], meeting_req[%p], transaction[%d], err_code[%p]", account_id, mailbox_name, type, meeting_req, transaction, err_code); + + if (account_id <= 0 || !meeting_req || meeting_req->mail_id <= 0) { + if (meeting_req) + EM_DEBUG_EXCEPTION("mail_id[%d]", meeting_req->mail_id); + + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false;; + } + + int rc; + int ret = false; + int error = EM_STORAGE_ERROR_NONE; + DB_STMT hStmt = NULL; + char sql_query_string[QUERY_SIZE] = {0, }; + + int col_index = 0; + + sqlite3 *local_db_handle = em_storage_get_db_connection(); + + EM_STORAGE_START_WRITE_TRANSACTION(transaction, error); + + switch (type) { + case UPDATE_MAILBOX: + EM_DEBUG_LOG(">>>>> UPDATE_MAILBOX : Move"); + if (!mailbox_name) { + EM_DEBUG_EXCEPTION(" mailbox_name[%p]", mailbox_name); + error = EM_STORAGE_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + SNPRINTF(sql_query_string, sizeof(sql_query_string), + "UPDATE mail_meeting_tbl SET mailbox_name = ? WHERE mail_id = %d", meeting_req->mail_id); + + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_prepare_v2(local_db_handle, sql_query_string, strlen(sql_query_string), &hStmt, NULL), rc); + EM_DEBUG_LOG(" Before sqlite3_prepare hStmt = %p", hStmt); + EM_DEBUG_DB_EXEC((SQLITE_OK != rc), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) sqlite3_prepare fail:(%d) %s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + _bindStmtFieldDataString(hStmt, col_index++, (char *)mailbox_name, 0, MAILBOX_LEN_IN_MAIL_MEETING_TBL); + break; + + default: + EM_DEBUG_LOG("type[%d]", type); + + error = EM_STORAGE_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + EM_DEBUG_LOG("Query = [%s]", sql_query_string); + + /* rc = sqlite3_step(hStmt); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_step(hStmt), rc); + EM_DEBUG_DB_EXEC((rc != SQLITE_ROW && rc != SQLITE_DONE), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("sqlite3_step fail:%d", rc)); + + ret = true; + +FINISH_OFF: + if (hStmt != NULL) { + EM_DEBUG_LOG(" Before sqlite3_finalize hStmt = %p", hStmt); + rc = sqlite3_finalize(hStmt); + if (rc != SQLITE_OK) { + EM_DEBUG_EXCEPTION(" sqlite3_finalize failed - %d", rc); + error = EM_STORAGE_ERROR_DB_FAILURE; + } + } + + EM_STORAGE_FINISH_WRITE_TRANSACTION(transaction, ret, error); + _DISCONNECT_DB; + + if (err_code != NULL) + *err_code = error; + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + + +EXPORT_API int em_storage_change_meeting_request_mailbox(int account_id, char *old_mailbox_name, char *new_mailbox_name, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id[%d], old_mailbox_name[%p], new_mailbox_name[%p], transaction[%d], err_code[%p]", account_id, old_mailbox_name, new_mailbox_name, transaction, err_code); + + if (account_id < FIRST_ACCOUNT_ID || !old_mailbox_name || !new_mailbox_name) { + EM_DEBUG_EXCEPTION("account_id[%d], old_mailbox_name[%p], new_mailbox_name[%p]", account_id, old_mailbox_name, new_mailbox_name); + + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + int rc; + int ret = true; + int error = EM_STORAGE_ERROR_NONE; + char sql_query_string[QUERY_SIZE] = {0, }; + + sqlite3 *local_db_handle = em_storage_get_db_connection(); + + EM_STORAGE_START_WRITE_TRANSACTION(transaction, error); + + EM_DEBUG_LOG("Update mailbox_name - searching by mailbox_name name"); + SNPRINTF(sql_query_string, sizeof(sql_query_string), + "UPDATE mail_meeting_tbl SET" + " mailbox_name = '%s'" + " WHERE account_id = %d" + " AND mailbox_name = '%s'" + , new_mailbox_name + , account_id + , old_mailbox_name); + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, sql_query_string, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC((SQLITE_FULL == rc), {error = EM_STORAGE_ERROR_DB_IS_FULL;goto FINISH_OFF; }, + ("sqlite3_exec fail:%d", rc)); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) exec fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + rc = sqlite3_changes(local_db_handle); + if (rc == 0) + EM_DEBUG_EXCEPTION("NO meetring request found..."); + + ret = true; + +FINISH_OFF: + + EM_STORAGE_FINISH_WRITE_TRANSACTION(transaction, ret, error); + _DISCONNECT_DB; + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + + +EXPORT_API int em_storage_delete_meeting_request(int account_id, int mail_id, char *mailbox_name, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id[%d], mail_id[%d], mailbox_name[%s], transaction[%d], err_code[%p]", account_id, mail_id, mailbox_name, transaction, err_code); + + if (account_id < ALL_ACCOUNT || mail_id < 0) { + EM_DEBUG_EXCEPTION(" account_id[%d], mail_id[%d]", account_id, mail_id); + + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + int rc; + int ret = false; + int error = EM_STORAGE_ERROR_NONE; + int and = false; + char sql_query_string[QUERY_SIZE] = {0, }; + + sqlite3 *local_db_handle = em_storage_get_db_connection(); + EM_STORAGE_START_WRITE_TRANSACTION(transaction, error); + + SNPRINTF(sql_query_string, sizeof(sql_query_string), "DELETE FROM mail_meeting_tbl "); + + if (account_id != ALL_ACCOUNT) { /* NOT '0' means a specific account. '0' means all account */ + SNPRINTF(sql_query_string + strlen(sql_query_string), sizeof(sql_query_string)-(strlen(sql_query_string)+1), " WHERE account_id = %d", account_id); + and = true; + } + if (mail_id > 0) { + SNPRINTF(sql_query_string + strlen(sql_query_string), sizeof(sql_query_string)-(strlen(sql_query_string)+1), " %s mail_id = %d", (and ? "AND" : "WHERE"), mail_id); + and = true; + } + if (mailbox_name) { /* NULL means all mailbox_name */ + SNPRINTF(sql_query_string + strlen(sql_query_string), sizeof(sql_query_string)-(strlen(sql_query_string)+1), " %s mailbox_name = '%s'", (and ? "AND" : "WHERE"), mailbox_name); + } + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, sql_query_string, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) exec fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + ret = true; + +FINISH_OFF: + EM_STORAGE_FINISH_WRITE_TRANSACTION(transaction, ret, error); + _DISCONNECT_DB; + + if (err_code) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API int em_storage_free_meeting_request(emf_meeting_request_t **meeting_req, int count, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("meeting_req[%p], count[%d], err_code[%p]", meeting_req, count, err_code); + + int ret = false; + int error = EM_STORAGE_ERROR_NONE; + int i = 0; + emf_meeting_request_t *cursor; + + if (count > 0) { + if (!meeting_req || !*meeting_req) { + EM_DEBUG_EXCEPTION("meeting_req[%p], count[%d]", meeting_req, count); + error = EM_STORAGE_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + for (i = 0; i < count; i++) { + cursor = (*meeting_req) + i; + EM_SAFE_FREE(cursor->location); + } + EM_SAFE_FREE(*meeting_req); + } + + ret = true; + +FINISH_OFF: + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; + +} + + +EXPORT_API int em_storage_get_overflowed_mail_id_list(int account_id, char *mailbox_name, int mail_slot_size, int **mail_id_list, int *mail_id_count, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id [%d], mailbox_name [%p], mail_slot_size [%d], mail_id_list [%p], mail_id_count [%p], transaction [%d], err_code [%p]", account_id, mailbox_name, mail_slot_size, mail_id_list, mail_id_count, transaction, err_code); + EM_PROFILE_BEGIN(profile_em_storage_get_overflowed_mail_id_list); + char sql_query_string[QUERY_SIZE] = {0, }; + char **result = NULL; + int rc = -1, ret = false; + int error = EM_STORAGE_ERROR_NONE; + int counter = 0, col_index = 0; + int result_mail_id_count = 0; + int *result_mail_id_list = NULL; + + if (!mailbox_name || !mail_id_list || !mail_id_count || account_id < 1) { + EM_DEBUG_EXCEPTION("Invalid Parameter"); + error = EMF_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + SNPRINTF(sql_query_string, sizeof(sql_query_string), "SELECT mail_id FROM mail_tbl WHERE account_id = %d AND mailbox_name = '%s' ORDER BY date_time DESC LIMIT %d, 10000", account_id, mailbox_name, mail_slot_size); + + EM_DEBUG_LOG("query[%s].", sql_query_string); + + sqlite3 *local_db_handle = em_storage_get_db_connection(); + EM_STORAGE_START_READ_TRANSACTION(transaction); + + /* rc = sqlite3_get_table(local_db_handle, sql_query_string, &result, &result_mail_id_count, 0, NULL); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_get_table(local_db_handle, sql_query_string, &result, &result_mail_id_count, 0, NULL), rc); + EM_DEBUG_DB_EXEC((SQLITE_OK != rc && -1 != rc), {error = EM_STORAGE_ERROR_DB_FAILURE;sqlite3_free_table(result);goto FINISH_OFF; }, + ("SQL(%s) sqlite3_get_table fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + if (!result_mail_id_count) { + EM_DEBUG_LOG("No mail found..."); + ret = false; + error= EM_STORAGE_ERROR_MAIL_NOT_FOUND; + goto FINISH_OFF; + } + + EM_DEBUG_LOG("There are [%d] overflowed mails in mailbox_name [%s]", result_mail_id_count, mailbox_name); + + if (!(result_mail_id_list = (int *)malloc(sizeof(int) * result_mail_id_count))) { + EM_DEBUG_EXCEPTION("malloc for result_mail_id_list failed..."); + error = EM_STORAGE_ERROR_OUT_OF_MEMORY; + sqlite3_free_table(result); + goto FINISH_OFF; + } + + memset(result_mail_id_list, 0x00, sizeof(int) * result_mail_id_count); + + col_index = 1; + + for (counter = 0; counter < result_mail_id_count; counter++) + _getTableFieldDataInt(result, result_mail_id_list + counter, col_index++); + + ret = true; + +FINISH_OFF: + EM_DEBUG_LOG("finish off [%d]", ret); + + if (result) + sqlite3_free_table(result); + + if (ret == true) { + *mail_id_list = result_mail_id_list; + *mail_id_count = result_mail_id_count; + } + else + EM_SAFE_FREE(result_mail_id_list); + + EM_STORAGE_FINISH_READ_TRANSACTION(transaction); + _DISCONNECT_DB; + + if (err_code != NULL) + *err_code = error; + + EM_PROFILE_END(profile_em_storage_get_overflowed_mail_id_list); + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + + +EXPORT_API int em_storage_get_thread_id_by_mail_id(int mail_id, int *thread_id, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("mail_id[%d], thread_id[%p], err_code[%p]", mail_id, thread_id, err_code); + + if (mail_id == 0 || thread_id == NULL) { + EM_DEBUG_EXCEPTION("Invalid Parameter"); + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + int rc = -1, ret = false; + int err = EM_STORAGE_ERROR_NONE; + char sql_query_string[QUERY_SIZE] = {0, }; + char **result; + int result_count = 0; + + sqlite3 *local_db_handle = em_storage_get_db_connection(); + + memset(sql_query_string, 0, QUERY_SIZE); + SNPRINTF(sql_query_string, sizeof(sql_query_string), "SELECT thread_id FROM mail_tbl WHERE mail_id = %d", mail_id); + + /* rc = sqlite3_get_table(local_db_handle, sql_query_string, &result, &result_count, 0, NULL); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_get_table(local_db_handle, sql_query_string, &result, &result_count, 0, NULL), rc); + EM_DEBUG_DB_EXEC((SQLITE_OK != rc && -1 != rc), {err = EM_STORAGE_ERROR_DB_FAILURE;sqlite3_free_table(result);goto FINISH_OFF; }, + ("SQL(%s) sqlite3_get_table fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + if (!result_count) { + EM_DEBUG_EXCEPTION("No mail found..."); + ret = false; + err= EM_STORAGE_ERROR_MAIL_NOT_FOUND; + /* sqlite3_free_table(result); */ + goto FINISH_OFF; + } + + _getTableFieldDataInt(result, thread_id, 1); + + sqlite3_free_table(result); + + ret = true; + +FINISH_OFF: + + _DISCONNECT_DB; + + if (err_code != NULL) + *err_code = err; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + + +EXPORT_API int em_storage_update_latest_thread_mail(int account_id, int thread_id, int latest_mail_id, int thread_item_count, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id [%d], thread_id[%d], latest_mail_id [%d], thread_item_count[%d], err_code[%p]", account_id, thread_id, latest_mail_id, thread_item_count, err_code); + + if (thread_id == 0) { + EM_DEBUG_EXCEPTION("Invalid Parameter"); + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + int rc = -1, ret = false; + int err = EM_STORAGE_ERROR_NONE; + char sql_query_string[QUERY_SIZE] = {0, }; + char **result; + int result_count = 0; + + sqlite3 *local_db_handle = em_storage_get_db_connection(); + + if (thread_item_count == 0 || latest_mail_id == 0) { + memset(sql_query_string, 0, QUERY_SIZE); + SNPRINTF(sql_query_string, sizeof(sql_query_string), "SELECT mail_id, count(*) FROM (SELECT account_id, mail_id, thread_id, mailbox_type FROM mail_tbl ORDER BY date_time) WHERE account_id = %d AND thread_id = %d AND mailbox_type NOT in (3,5,7)", account_id, thread_id); + + /* rc = sqlite3_get_table(local_db_handle, sql_query_string, &result, &result_count, 0, NULL); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_get_table(local_db_handle, sql_query_string, &result, &result_count, 0, NULL), rc); + EM_DEBUG_DB_EXEC((SQLITE_OK != rc && -1 != rc), {err = EM_STORAGE_ERROR_DB_FAILURE;sqlite3_free_table(result);goto FINISH_OFF; }, + ("SQL(%s) sqlite3_get_table fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + EM_DEBUG_LOG("result_count[%d]", result_count); + if (result_count == 0) { + EM_DEBUG_EXCEPTION("No mail found..."); + ret = false; + err= EM_STORAGE_ERROR_MAIL_NOT_FOUND; + sqlite3_free_table(result); + goto FINISH_OFF; + } + + _getTableFieldDataInt(result, &latest_mail_id, 2); + _getTableFieldDataInt(result, &thread_item_count, 3); + + EM_DEBUG_LOG("latest_mail_id[%d]", latest_mail_id); + EM_DEBUG_LOG("thread_item_count[%d]", thread_item_count); + + sqlite3_free_table(result); + } + + EM_STORAGE_START_WRITE_TRANSACTION(transaction, err); + + /* if (thread_item_count > 1) */ + /* { */ + memset(sql_query_string, 0, QUERY_SIZE); + SNPRINTF(sql_query_string, sizeof(sql_query_string), "UPDATE mail_tbl SET thread_item_count = 0 WHERE account_id = %d AND thread_id = %d", account_id, thread_id); + EM_DEBUG_LOG("query[%s]", sql_query_string); + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, sql_query_string, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {err = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) exec fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + /* } */ + + memset(sql_query_string, 0, QUERY_SIZE); + SNPRINTF(sql_query_string, sizeof(sql_query_string), "UPDATE mail_tbl SET thread_item_count = %d WHERE account_id = %d AND mail_id = %d ", thread_item_count, account_id, latest_mail_id); + EM_DEBUG_LOG("query[%s]", sql_query_string); + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, sql_query_string, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {err = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) exec fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + ret = true; + +FINISH_OFF: + + EM_STORAGE_FINISH_WRITE_TRANSACTION(transaction, ret, err); + + _DISCONNECT_DB; + + if (err_code != NULL) + *err_code = err; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + + +EXPORT_API void +em_storage_flush_db_cache() +{ + sqlite3_release_memory(-1); +} + +#ifdef __LOCAL_ACTIVITY__ +/** + * em_storage_add_activity - Add Email Local activity during OFFLINE mode + * + */ +EXPORT_API int em_storage_add_activity(emf_activity_tbl_t* local_activity, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN(); + + EM_DEBUG_LOG(" local_activity[%p], transaction[%d], err_code[%p]", local_activity, transaction, err_code); + + int rc = -1, ret = false; + int error = EM_STORAGE_ERROR_NONE; + DB_STMT hStmt = NULL; + char sql_query_string[8192] = { 0x00, }; + int i = 0; + + if (!local_activity) { + EM_DEBUG_EXCEPTION(" local_activity[%p], transaction[%d], err_code[%p]", local_activity, transaction, err_code); + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + sqlite3 *local_db_handle = em_storage_get_db_connection(); + memset(sql_query_string, 0x00 , sizeof(sql_query_string)); + EM_STORAGE_START_WRITE_TRANSACTION(transaction, error); + + SNPRINTF(sql_query_string, sizeof(sql_query_string), "INSERT INTO mail_local_activity_tbl VALUES (?, ?, ?, ?, ?, ?, ?)"); + + EM_DEBUG_LOG(">>>>> ACTIVITY ID [ %d ] ", local_activity->activity_id); + EM_DEBUG_LOG(">>>>> MAIL ID [ %d ] ", local_activity->mail_id); + EM_DEBUG_LOG(">>>>> ACCOUNT ID [ %d ] ", local_activity->account_id); + EM_DEBUG_LOG(">>>>> ACTIVITY TYPE [ %d ] ", local_activity->activity_type); + EM_DEBUG_LOG(">>>>> SERVER MAIL ID [ %s ] ", local_activity->server_mailid); + EM_DEBUG_LOG(">>>>> SOURCE MAILBOX [ %s ] ", local_activity->src_mbox); + EM_DEBUG_LOG(">>>>> DEST MAILBOX [ %s ] ", local_activity->dest_mbox); + + EM_DEBUG_LOG(">>>> SQL STMT [ %s ] ", sql_query_string); + + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_prepare_v2(local_db_handle, sql_query_string, strlen(sql_query_string), &hStmt, NULL), rc); + EM_DEBUG_DB_EXEC((SQLITE_OK != rc), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) sqlite3_prepare fail:(%d) %s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + EM_DEBUG_LOG(">>>> SQL STMT [ %s ] ", sql_query_string); + + + + + _bindStmtFieldDataInt(hStmt, i++, local_activity->activity_id); + _bindStmtFieldDataInt(hStmt, i++, local_activity->account_id); + _bindStmtFieldDataInt(hStmt, i++, local_activity->mail_id); + _bindStmtFieldDataInt(hStmt, i++, local_activity->activity_type); + _bindStmtFieldDataString(hStmt, i++ , (char *)local_activity->server_mailid, 0, SERVER_MAIL_ID_LEN_IN_MAIL_TBL); + _bindStmtFieldDataString(hStmt, i++ , (char *)local_activity->src_mbox, 0, MAILBOX_NAME_LEN_IN_MAIL_BOX_TBL); + _bindStmtFieldDataString(hStmt, i++ , (char *)local_activity->dest_mbox, 0, MAILBOX_NAME_LEN_IN_MAIL_BOX_TBL); + + /* rc = sqlite3_step(hStmt); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_step(hStmt), rc); + + EM_DEBUG_DB_EXEC((rc == SQLITE_FULL), {error = EM_STORAGE_ERROR_DB_IS_FULL;goto FINISH_OFF; }, + ("sqlite3_step fail:%d", rc)); + EM_DEBUG_DB_EXEC((rc != SQLITE_ROW && rc != SQLITE_DONE), {error = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("sqlite3_step fail:%d, errmsg = %s.", rc, sqlite3_errmsg(local_db_handle))); + + ret = true; + +FINISH_OFF: + + if (hStmt != NULL) { + rc = sqlite3_finalize(hStmt); + if (rc != SQLITE_OK) { + EM_DEBUG_LOG(" sqlite3_finalize failed - %d", rc); + + error = EM_STORAGE_ERROR_DB_FAILURE; + } + } + else { + EM_DEBUG_LOG(" >>>>>>>>>> hStmt is NULL!!!"); + } + + EM_STORAGE_FINISH_WRITE_TRANSACTION(transaction, ret, error); + _DISCONNECT_DB; + + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +/** + * em_storage_get_activity - Get the Local activity Information + * + * + */ +EXPORT_API int em_storage_get_activity(int account_id, int activityid, emf_activity_tbl_t** activity_list, int *select_num, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN(); + + int i = 0, count = 0, rc = -1, ret = false; + int error = EM_STORAGE_ERROR_NONE; + emf_activity_tbl_t *p_activity_tbl = NULL; + char sql_query_string[1024] = {0x00, }; + char **result = NULL; + int col_index ; + + EM_IF_NULL_RETURN_VALUE(activity_list, false); + EM_IF_NULL_RETURN_VALUE(select_num, false); + + + if (!select_num || !activity_list || account_id <= 0 || activityid < 0) { + EM_DEBUG_LOG(" select_num[%p], activity_list[%p] account_id [%d] activityid [%d] ", select_num, activity_list, account_id, activityid); + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + EM_STORAGE_START_READ_TRANSACTION(transaction); + + memset(sql_query_string, 0x00, sizeof(sql_query_string)); + + if (activityid == ALL_ACTIVITIES) { + SNPRINTF(sql_query_string, sizeof(sql_query_string), "SELECT * FROM mail_local_activity_tbl WHERE account_id = %d order by activity_id", account_id); + } + else { + SNPRINTF(sql_query_string, sizeof(sql_query_string), "SELECT * FROM mail_local_activity_tbl WHERE account_id = %d AND activity_id = %d ", account_id, activityid); + } + + EM_DEBUG_LOG("Query [%s]", sql_query_string); + + + /* rc = sqlite3_get_table(local_db_handle, sql_query_string, &result, &count, NULL, NULL); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_get_table(local_db_handle, sql_query_string, &result, &count, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;sqlite3_free_table(result);goto FINISH_OFF; }, + ("SQL(%s) sqlite3_get_table fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + + + col_index = 7; + + if (!(p_activity_tbl = (emf_activity_tbl_t*)em_core_malloc(sizeof(emf_activity_tbl_t) * count))) { + EM_DEBUG_EXCEPTION(" em_core_malloc failed..."); + error = EM_STORAGE_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + + for (i = 0; i < count; i++) { + EM_DEBUG_LOG("result[%d] - %s ", col_index, result[col_index]); + if (result[col_index]) + p_activity_tbl[i].activity_id = atoi(result[col_index++]); + + EM_DEBUG_LOG("result[%d] - %s ", col_index, result[col_index]); + if (result[col_index]) + p_activity_tbl[i].account_id = atoi(result[col_index++]); + + EM_DEBUG_LOG("result[%d] - %s ", col_index, result[col_index]); + if (result[col_index]) + p_activity_tbl[i].mail_id = atoi(result[col_index++]); + + EM_DEBUG_LOG("result[%d] - %s ", col_index, result[col_index]); + if (result[col_index]) + p_activity_tbl[i].activity_type = atoi(result[col_index++]); + + + EM_DEBUG_LOG("result[%d] - %s ", col_index, result[col_index]); + if (result[col_index] && strlen(result[col_index])>0) + p_activity_tbl[i].server_mailid = EM_SAFE_STRDUP(result[col_index++]); + else + col_index++; + + EM_DEBUG_LOG("result[%d] - %s ", col_index, result[col_index]); + if (result[col_index] && strlen(result[col_index])>0) + p_activity_tbl[i].src_mbox = EM_SAFE_STRDUP(result[col_index++]); + else + col_index++; + + EM_DEBUG_LOG("result[%d] - %s ", col_index, result[col_index]); + if (result[col_index] && strlen(result[col_index])>0) + p_activity_tbl[i].dest_mbox = EM_SAFE_STRDUP(result[col_index++]); + else + col_index++; + + } + + if (result) + sqlite3_free_table(result); + + ret = true; + +FINISH_OFF: + + + if (ret == true) { + *activity_list = p_activity_tbl; + *select_num = count; + EM_DEBUG_LOG(">>>> COUNT : %d >> ", count); + } + else if (p_activity_tbl != NULL) { + em_storage_free_local_activity(&p_activity_tbl, count, NULL); + } + + EM_STORAGE_FINISH_READ_TRANSACTION(transaction); + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + + +EXPORT_API int em_storage_get_next_activity_id(int *activity_id, int *err_code) +{ + + EM_DEBUG_FUNC_BEGIN(); + + int ret = false; + int err = EMF_ERROR_NONE; + int rc = -1; + char *sql = NULL; + char **result = NULL; + + if (NULL == activity_id) + { + EM_DEBUG_EXCEPTION(" activity_id[%p]", activity_id); + + err = EM_STORAGE_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + /* increase unique id */ + + sql = "SELECT max(rowid) FROM mail_local_activity_tbl;"; + + /* rc = sqlite3_get_table(local_db_handle, sql, &result, NULL, NULL, NULL); n EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_get_table(local_db_handle, sql, &result, NULL, NULL, NULL), rc); */ + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {err = EM_STORAGE_ERROR_DB_FAILURE;sqlite3_free_table(result);goto FINISH_OFF; }, + ("SQL(%s) sqlite3_get_table fail:%d -%s", sql, rc, sqlite3_errmsg(local_db_handle))); + + if (NULL==result[1]) + rc = 1; + else + rc = atoi(result[1])+1; + + *activity_id = rc; + + if (result) + sqlite3_free_table(result); + + ret = true; + + FINISH_OFF: + + if (NULL != err_code) { + *err_code = err; + } + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; + +} + +EXPORT_API int em_storage_get_activity_id_list(int account_id, int ** activity_id_list, int *activity_id_count, int lowest_activity_type, int highest_activity_type, int transaction, int *err_code) +{ + + EM_DEBUG_FUNC_BEGIN(); + + EM_DEBUG_LOG(" account_id[%d], activity_id_list[%p], activity_id_count[%p] err_code[%p]", account_id, activity_id_list, activity_id_count, err_code); + + if (account_id <= 0|| NULL == activity_id_list || NULL == activity_id_count ||lowest_activity_type <=0 || highest_activity_type <= 0) { + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + int ret = false; + int error = EM_STORAGE_ERROR_NONE; + int i = 0, rc = -1, count = 0; + char sql_query_string[1024] = {0x00, }; + int *activity_ids = NULL; + int col_index = 0; + char **result = NULL; + + EM_STORAGE_START_READ_TRANSACTION(transaction); + + memset(sql_query_string, 0x00, sizeof(sql_query_string)); + + SNPRINTF(sql_query_string, sizeof(sql_query_string), "SELECT distinct activity_id FROM mail_local_activity_tbl WHERE account_id = %d AND activity_type >= %d AND activity_type <= %d order by activity_id", account_id, lowest_activity_type, highest_activity_type); + + EM_DEBUG_LOG(" Query [%s]", sql_query_string); + + /* rc = sqlite3_get_table(local_db_handle, sql_query_string, &result, &count, NULL, NULL); */ + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_get_table(local_db_handle, sql_query_string, &result, &count, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {error = EM_STORAGE_ERROR_DB_FAILURE;sqlite3_free_table(result);goto FINISH_OFF; }, + ("SQL(%s) sqlite3_get_table fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + col_index = 1; + + EM_DEBUG_LOG(" Activity COUNT : %d ... ", count); + + if (NULL == (activity_ids = (int *)em_core_malloc(sizeof(int) * count))) { + EM_DEBUG_EXCEPTION(" em_core_malloc failed..."); + error = EM_STORAGE_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + for (i = 0; i < count; i++) { + activity_ids[i] = atoi(result[col_index]); + col_index++; + EM_DEBUG_LOG("activity_id %d", activity_ids[i]); + } + + ret = true; + +FINISH_OFF: + + + if (ret == true) { + *activity_id_count = count; + *activity_id_list = activity_ids; + + } + else if (activity_ids != NULL) /* Prevent defect - 216566 */ + EM_SAFE_FREE(activity_ids); + + + EM_STORAGE_FINISH_READ_TRANSACTION(transaction); + if (err_code != NULL) { + *err_code = error; + } + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +EXPORT_API int em_storage_free_activity_id_list(int *activity_id_list, int *error_code) +{ + EM_DEBUG_FUNC_BEGIN(); + + int error = EM_STORAGE_ERROR_NONE; + int ret = false; + + EM_DEBUG_LOG(" activity_id_list [%p]", activity_id_list); + + if (NULL == activity_id_list) { + error = EM_STORAGE_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + else { + free(activity_id_list); + activity_id_list = NULL; + } + + + ret= true; + + FINISH_OFF: + + if (NULL != error_code) { + *error_code = error; + } + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +/** + * em_storage_delete_local_activity - Deletes the Local acitivity Generated based on activity_type + * or based on server mail id + * + */ +EXPORT_API int em_storage_delete_local_activity(emf_activity_tbl_t* local_activity, int transaction, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN(); + + + EM_DEBUG_LOG(" local_activity[%p] ", local_activity); + + if (!local_activity) { + EM_DEBUG_EXCEPTION(" local_activity[%p] ", local_activity); + if (err_code != NULL) + *err_code = EM_STORAGE_ERROR_INVALID_PARAM; + return false; + } + + int rc = -1, ret = false; /* Prevent_FIX */ + int err = EM_STORAGE_ERROR_NONE; + int query_and = 0; + int query_where = 0; + char sql_query_string[8192] = { 0x00, }; + EM_STORAGE_START_WRITE_TRANSACTION(transaction, error); + + memset(sql_query_string, 0x00, sizeof(sql_query_string)); + + SNPRINTF(sql_query_string, sizeof(sql_query_string), "DELETE FROM mail_local_activity_tbl "); + + EM_DEBUG_LOG(">>> Query [ %s ] ", sql_query_string); + + if (local_activity->account_id) { + SNPRINTF(sql_query_string + strlen(sql_query_string), sizeof(sql_query_string)-(strlen(sql_query_string)+1), + " WHERE account_id = %d ", local_activity->account_id); + query_and = 1; + query_where = 1; + } + + if (local_activity->server_mailid) { + SNPRINTF(sql_query_string + strlen(sql_query_string), sizeof(sql_query_string)-(strlen(sql_query_string)+1), + " %s %s server_mailid = '%s' ", query_where? "": "WHERE", query_and? "AND":"", local_activity->server_mailid); + query_and = 1; + query_where = 1; + } + + + if (local_activity->mail_id) { + EM_DEBUG_LOG(">>>> MAIL ID [ %d ] , ACTIVITY TYPE [%d ]", local_activity->mail_id, local_activity->activity_type); + + SNPRINTF(sql_query_string + strlen(sql_query_string), sizeof(sql_query_string)-(strlen(sql_query_string)+1), + " %s %s mail_id = %d ", query_where? "": "WHERE", query_and? "AND":"", local_activity->mail_id); + + query_and = 1; + query_where = 1; + + } + + if (local_activity->activity_type > 0) { + SNPRINTF(sql_query_string + strlen(sql_query_string), sizeof(sql_query_string)-(strlen(sql_query_string)+1), + " %s %s activity_type = %d ", query_where? "": "WHERE", query_and? "AND" : "" , local_activity->activity_type); + } + + if (local_activity->activity_id > 0) { + SNPRINTF(sql_query_string + strlen(sql_query_string), sizeof(sql_query_string)-(strlen(sql_query_string)+1), + " %s %s activity_id = %d ", query_where? "": "WHERE", query_and? "AND" : "" , local_activity->activity_id); + + } + + EM_DEBUG_LOG(">>>>> Query [ %s ] ", sql_query_string); + + EM_STORAGE_PROTECTED_FUNC_CALL(sqlite3_exec(local_db_handle, sql_query_string, NULL, NULL, NULL), rc); + EM_DEBUG_DB_EXEC(SQLITE_OK != rc, {err = EM_STORAGE_ERROR_DB_FAILURE;goto FINISH_OFF; }, + ("SQL(%s) exec fail:%d -%s", sql_query_string, rc, sqlite3_errmsg(local_db_handle))); + + rc = sqlite3_changes(local_db_handle); + if (rc == 0) { + EM_DEBUG_EXCEPTION(" no (matched) mailbox_name found..."); + err = EM_STORAGE_ERROR_MAILBOX_NOT_FOUND; + } + + ret = true; + +FINISH_OFF: + EM_STORAGE_FINISH_WRITE_TRANSACTION(transaction, ret, error); + if (err_code != NULL) + *err_code = err; + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + +/** +* em_storage_free_local_activity - Free the Local Activity data +*/ +EXPORT_API int em_storage_free_local_activity(emf_activity_tbl_t **local_activity_list, int count, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN(); + + EM_DEBUG_LOG(" local_activity_list[%p], count[%d], err_code[%p]", local_activity_list, count, err_code); + + int ret = false; + int error = EM_STORAGE_ERROR_INVALID_PARAM; + + if (count > 0) { + if (!local_activity_list || !*local_activity_list) { + EM_DEBUG_EXCEPTION(" local_activity_list[%p], count[%d]", local_activity_list, count); + + error = EM_STORAGE_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + emf_activity_tbl_t* p = *local_activity_list; + int i = 0; + if (p) { + for (; i < count; i++) { + EM_SAFE_FREE(p[i].dest_mbox); + EM_SAFE_FREE(p[i].src_mbox); + EM_SAFE_FREE(p[i].server_mailid); + } + + free(p); *local_activity_list = NULL; + } + } + + ret = true; + +FINISH_OFF: + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; + +} +#endif /* __LOCAL_ACTIVITY__ */ + + +/*EOF*/ diff --git a/email-core/em-storage/include/em-storage.h b/email-core/em-storage/include/em-storage.h new file mode 100755 index 0000000..dd470c6 --- /dev/null +++ b/email-core/em-storage/include/em-storage.h @@ -0,0 +1,1539 @@ +/* +* email-service +* +* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. +* +* Contact: Kyuho Jo <kyuho.jo@samsung.com>, Sunghyun Kwon <sh0701.kwon@samsung.com> +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + + +/****************************************************************************** + * File : em-storage.h + * Desc : Mail Framework Storage Library Header + * + * Auth : + * + * History : + * 2006.07.28 : created + *****************************************************************************/ +#ifndef __EM_STORAGE_H__ +#define __EM_STORAGE_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#define __USE_UNIX98 +#define __USE_GNU + +#include "emf-types.h" +#include "em-core-types.h" +#include <sqlite3.h> + + +#if !defined(EXPORT_API) +#define EXPORT_API __attribute__((visibility("default"))) +#endif + + +#define DB_PATH "/opt/dbspace" +#define EMAIL_SERVICE_DB_FILE_PATH "/opt/dbspace/.email-service.db" + +#define EMAILPATH DATA_PATH"/email" +#define MAILHOME DATA_PATH"/email/.emfdata" +#define DIRECTORY_PERMISSION 0755 + + +#define MAILTEMP "tmp" +#define FIRST_ACCOUNT_ID 1 + + +#ifdef __FEATURE_BULK_DELETE_MOVE_UPDATE_REQUEST_OPTI__ +#define QUERY_SIZE 8192 +#define MAX_INTEGER_LENGTH 5 /* 32767 -> 5 bytes */ + +typedef struct +{ + int mail_id; + unsigned long server_mail_id; +} emf_id_set_t; + +#endif /* __FEATURE_BULK_DELETE_MOVE_UPDATE_REQUEST_OPTI__ */ + + +typedef struct +{ + int account_bind_type; + char *account_name; + int receiving_server_type; + char *receiving_server_addr; + char *email_addr; + char *user_name; + char *password; + int retrieval_mode; + int port_num; + int use_security; + int sending_server_type; + char *sending_server_addr; + int sending_port_num; + int sending_auth; + int sending_security; + char *sending_user; + char *sending_password; + char *display_name; + char *reply_to_addr; + char *return_addr; + int account_id; + int keep_on_server; + int flag1; /* Specifies the downloading option 0 is subject only, 1 is text body, 2 is normal. */ + int flag2; + int pop_before_smtp; /* POP before SMTP Authentication */ + int apop; /* APOP authentication */ + char *logo_icon_path; /* Account logo icon */ + int preset_account; /* Preset account or not */ + emf_option_t options; /* Specifies the Sending options */ + int target_storage; /* Specifies the targetStorage. 0 is phone, 1 is MMC */ + int check_interval; /* Specifies the check interval */ + int my_account_id; /* Specifies accout id of my account */ + int index_color; /* index color in RGB */ + int sync_status; /* Sync Status */ +} +emf_mail_account_tbl_t; + +typedef struct +{ + int account_id; /* MUST BE '0' : currently, only global rule supported. */ + int rule_id; + int type; /* from/subject/body */ + char *value; + int action_type; /* move/block/delete */ + char *dest_mailbox; /* destination mailbox */ + int flag1; /* for rule ON/OFF */ + int flag2; /* For rule type INCLUDE/Exactly SAME AS */ +} +emf_mail_rule_tbl_t; + +/* mail_box_tbl table entity */ +typedef struct +{ + int mailbox_id; + int account_id; + int local_yn; + char *mailbox_name; + emf_mailbox_type_e mailbox_type; + char *alias; + int sync_with_server_yn; /* whether mailbox is a sync IMAP mailbox */ + int modifiable_yn; /* whether mailbox is able to be deleted/modified */ + int unread_count; /* Removed. 16-Dec-2010, count unread mails at the moment it is required. not store in the DB */ + int total_mail_count_on_local; /* Specifies the total number of mails in the mailbox in the local DB. count unread mails at the moment it is required. not store in the DB */ + int total_mail_count_on_server; /* Specifies the total number of mails in the mailbox in the mail server */ + int has_archived_mails; + int mail_slot_size; +} emf_mailbox_tbl_t; + +/* mail_read_uid_tbl table entity */ +typedef struct +{ + int account_id; + char *local_mbox; + int local_uid; + char *mailbox_name; /* server mailbox */ + char *s_uid; /* uid on server */ + int data1; /* rfc822 size */ + char *data2; + int flag; /* rule id */ + int reserved; +} emf_mail_read_mail_uid_tbl_t; + +typedef struct +{ + int mail_id; + int account_id; + char *mailbox_name; + int mailbox_type; + char *subject; + char *datetime; /* YYYYMMDDHHMMSS */ + int server_mail_status; + char *server_mailbox_name; + char *server_mail_id; + char *message_id; + char *full_address_from; + char *full_address_reply; + char *full_address_to; + char *full_address_cc; + char *full_address_bcc; + char *full_address_return; + char *email_address_sender; + char *email_address_recipient; + char *alias_sender; + char *alias_recipient; + int body_download_status; + char *file_path_plain; + char *file_path_html; + int mail_size; + char flags_seen_field; + char flags_deleted_field; + char flags_flagged_field; + char flags_answered_field; + char flags_recent_field; + char flags_draft_field; + char flags_forwarded_field; + int DRM_status; + int priority; + int save_status; + int lock_status; + int report_status; + int attachment_count; + int inline_content_count; + int thread_id; + int thread_item_count; + char *preview_text; + int meeting_request_status; +} emf_mail_tbl_t; + +/* mail_attachment_tbl entity */ +typedef struct +{ + int attachment_id; + char *attachment_name; + char *attachment_path; + int attachment_size; + int mail_id; + int account_id; + char *mailbox_name; + int file_yn; + int flag1; /* drm 1 */ + int flag2; /* drm 2 */ + int flag3; /* inline content status */ +#ifdef __ATTACHMENT_OPTI__ + int encoding; + char *section; +#endif +} emf_mail_attachment_tbl_t; + +/* mail_contact_sync_tbl table entity */ +typedef struct +{ + char *contact_name; + char *email_address[15]; + int storage_type; + int contact_id; +} emf_mail_contact_sync_tbl_t; + +typedef enum { + RETRIEVE_ALL = 1, /* mail */ + RETRIEVE_ENVELOPE, /* mail envelope */ + RETRIEVE_SUMMARY, /* mail summary */ + RETRIEVE_FIELDS_FOR_DELETE, /* account_id, mail_id, server_mail_yn, server_mailbox, server_mail_id */ + RETRIEVE_ACCOUNT, /* account_id */ + RETRIEVE_FLAG, /* mailbox, flag1, thread_id */ + RETRIEVE_ID, /* mail_id */ + RETRIEVE_ADDRESS, /* mail_id, contact_info */ +} emf_mail_field_type_t; + +typedef enum { + EMF_CONTACT_TYPE_FROM = 1, + EMF_CONTACT_TYPE_TO, + EMF_CONTACT_TYPE_CC, + EMF_CONTACT_TYPE_BCC, + EMF_CONTACT_TYPE_REPLY, + EMF_CONTACT_TYPE_RETURN, +} emf_mail_contact_type_t; + +typedef struct _emf_mail_search_t { + char *key_type; + char *key_value; + struct _emf_mail_search_t *next; +} +emf_mail_search_t; + +typedef enum { + EMF_CREATE_DB_NORMAL = 0, + EMF_CREATE_DB_CHECK, +} +emf_create_db_t; + +typedef enum { + SET_TYPE_SET = 1, + SET_TYPE_UNION = 2, + SET_TYPE_MINUS = 3, + SET_TYPE_INTERSECT = 4 /* Not supported */ +} emf_set_type_t; + + +/*****************************************************************************/ +/* Errors */ +/*****************************************************************************/ +#define EM_STORAGE_ERROR_NONE 1 /* There is no error. */ +#define EM_STORAGE_ERROR_INVALID_PARAM 2001 /* The parameter is invalid. */ +#define EM_STORAGE_ERROR_ACCOUNT_NOT_FOUND 2002 /* The expected account is not found. */ +#define EM_STORAGE_ERROR_MAIL_NOT_FOUND 2003 /* The expected mail is not found. */ +#define EM_STORAGE_ERROR_MAILBOX_NOT_FOUND 2004 /* The expected mailbox is not found. */ +#define EM_STORAGE_ERROR_ATTACHMENT_NOT_FOUND 2005 /* The expected attachment is not found. */ +#define EM_STORAGE_ERROR_RULE_NOT_FOUND 2006 /* The expected rule is not found. */ +#define EM_STORAGE_ERROR_CONTACT_NOT_FOUND 2007 /* The expected contact is not found. */ +#define EM_STORAGE_ERROR_FILE_NOT_FOUND 2008 /* The expected file is not found. */ +#define EM_STORAGE_ERROR_DATA_NOT_FOUND 2009 /* The expected data is not found. */ +#define EM_STORAGE_ERROR_NO_MORE_DATA 2010 /* There is no more data. */ +#define EM_STORAGE_ERROR_DATA_TOO_LONG 2011 /* The data is too long. */ +#define EM_STORAGE_ERROR_DATA_TOO_SMALL 2012 /* The data is too short. */ +#define EM_STORAGE_ERROR_OUT_OF_MEMORY 2013 /* The system is out of memory. */ +#define EM_STORAGE_ERROR_CONNECTION_FAILURE 2014 /* The agent fails to connect to server. */ +#define EM_STORAGE_ERROR_SYSTEM_FAILURE 2015 /* There is a system error. */ +#define EM_STORAGE_ERROR_DB_IS_FULL 2017 /* The db memory is full. */ +#define EM_STORAGE_ERROR_MAIL_MAX_COUNT 2016 /* there is a max count error. */ +#define EM_STORAGE_ERROR_DB_FAILURE 2018 /* EDB operation failure */ +#define EM_STORAGE_ERROR_ALREADY_EXISTS 2019 +#define EM_STORAGE_ERROR_MMC_NOT_FOUND 2020 +#define EM_STORAGE_ERROR_UNKNOWN 8000 /* There is a unknown error. */ + +/***************************************************************************** + etc +*****************************************************************************/ +#define EM_STORAGE_MAIL_MAX 5000 +#define EM_STORAGE_LIMITATION_FREE_SPACE (5) /* This value is 5MB */ +#define MAX_PW_FILE_NAME_LENGTH 128 /* password file name for secure storage */ + +#ifdef __LOCAL_ACTIVITY__ + +typedef enum +{ + ACTIVITY_FETCHIMAPFOLDER = 1, /* Fetch Mail server Activity */ + ACTIVITY_DELETEMAIL, /* Delete Mail Activity */ + ACTIVITY_MODIFYFLAG, /* Modify Mail flag Activity */ + ACTIVITY_MODIFYSEENFLAG, /* Modify Mail seen flag Activity */ + ACTIVITY_MOVEMAIL, /* Move Mail Activity */ + ACTIVITY_DELETEALLMAIL, /* Delete All Mails activity */ + ACTIVITY_COPYMAIL, /* Copy Mail Activity */ + ACTIVITY_SAVEMAIL, /* Save Mail activity */ + ACTIVITY_DELETEMAIL_SEND, /* New Delete Mail Activity added to be processed by send thread */ +}eActivity_type; + + +/** + * emf_activity_tbl_t - Email Local activity Structure + * + */ +typedef struct +{ + int activity_id; /* Activity ID */ + int account_id; /* Account ID */ + int mail_id; /* Mail ID */ + int activity_type; /* Local Activity Type */ + char *server_mailid; /* Server Mail ID or Mailbox name */ + char *src_mbox; /* Source Mailbox in case of mail_move */ + char *dest_mbox; /* Destination Mailbox name in case of Mail move operation */ + +} emf_activity_tbl_t; + +#endif + +EXPORT_API int em_storage_shm_file_init(const char *shm_file_name); + + +/************** Database Management ***************/ +/* + * em_db_open + * description : open db and register busy handler + */ +EXPORT_API int em_db_open(sqlite3 **sqlite_handle, int *err_code); + +/* + * em_storage_db_open + * + * description : open db and set global variable sqlite_emmb + * arguments : + * return : + */ +EXPORT_API sqlite3* em_storage_db_open(int *err_code); + +/* + * em_storage_db_close + * + * description : close db with global variable sqlite_emmb + * arguments : + * return : + */ +EXPORT_API int em_storage_db_close(int *err_code); + +/* + * em_storage_open + * + * description : initialize storage manager + * arguments : + * return : + */ +EXPORT_API int em_storage_open(int *err_code); + +/* + * em_storage_close + * + * description : cleanup storage manager + * arguments : + * return : + */ +EXPORT_API int em_storage_close(int *err_code); + +/* + * em_storage_create_table + * + * description : create account/address table in database. + * arguments : + * return : + */ +EXPORT_API int em_storage_create_table(emf_create_db_t type, int *err_code); + + +/** + * Check whether there is the same account information in the db + * + * @param[in] account account that + * @param[in] transaction If the argument is true, engine commits transaction or executes rollback. + * @param[out] err_code Error code. + * @remarks N/A + * @return This function returns true if there is no duplicated account. returns false and set error code if there are duplicated accounts or error + */ +EXPORT_API int em_storage_check_duplicated_account(emf_account_t *account, int transaction, int *err_code); + + +/** + * Get number of accounts from account table. + * + * @param[out] count The number of accounts is saved here. + * @param[in] transaction If the argument is true, engine commits transaction or executes rollback. + * @remarks N/A + * @return This function returns 0 on success or error code on failure. + */ +EXPORT_API int em_storage_get_account_count(int *count, int transaction, int *err_code); + +/** + * Get account from account table. + * + * @param[in, out] select_num Upon entry, the argument contains the number of accounts to select. + Upon exit, it is set to the number of accounts to been selected. + * @param[out] account_list The selected accounts is saved here. this pointer must be freed after being used. + * @param[in] transaction If the argument is true, engine commits transaction or executes rollback. + * @remarks N/A + * @return This function returns 0 on success or error code on failure. + */ +EXPORT_API int em_storage_get_account_list(int *select_num, emf_mail_account_tbl_t **account_list, int transaction, int with_password, int *err_code); + +/* + * em_storage_get_account_by_name + * + * description : get account from account table by account name + * arguments : + * db : database pointer + * account_id : account id + * pulloption : option to specify fetching full or partial data + * account : buffer to hold selected account + * this buffer must be free after it has been used. + * return : + */ +/* sowmya.kr, 281209 Adding signature to options in emf_account_t changes */ + +EXPORT_API int em_storage_get_account_by_id(int account_id, int pulloption, emf_mail_account_tbl_t **account, int transaction, int *err_code); + + +/* + * em_storage_get_password_length_of_account + * + * description: get password length of account. + * arguments: + * account_id : account id + * password_length : password length + * return : + */ + +EXPORT_API int em_storage_get_password_length_of_account(int account_id, int *password_length, int* err_code); + +/* + * em_storage_update_account + * + * description : change a account from account table + * arguments : + * account_id : account id + * account : buffer to hold selected account + * return : + */ +EXPORT_API int em_storage_update_account(int account_id, emf_mail_account_tbl_t *account, int transaction, int *err_code); + +/* + * em_storage_get_sync_status_of_account + * + * description : get a sync status field from account table + * arguments : + * account_id : account id + * result_sync_status : sync status value + * return : + */ + +EXPORT_API int em_storage_get_sync_status_of_account(int account_id, int *result_sync_status,int *err_code); + +/* + * em_storage_update_sync_status_of_account + * + * description : update a sync status field from account table + * arguments : + * account_id : account id + * set_operator : set operater. refer emf_set_type_t + * sync_status : sync status value + * return : + */ + +EXPORT_API int em_storage_update_sync_status_of_account(int account_id, emf_set_type_t set_operator, int sync_status, int transaction, int *err_code); + +/* + * em_storage_add_account + * + * description : add a account to account table + * arguments : + * return : + */ +EXPORT_API int em_storage_add_account(emf_mail_account_tbl_t *account, int transaction, int *err_code); + +/* + * em_storage_delete_account + * + * description : delete a account from account table + * arguments : + * db : database pointer + * account_id : account id to be deteted + * return : + */ +EXPORT_API int em_storage_delete_account(int account_id, int transaction, int *err_code); + +/* + * em_storage_free_account + * + * description : free local accout memory + * arguments : + * account_list : double pointer + * count : count of local account + * return : + */ +EXPORT_API int em_storage_free_account(emf_mail_account_tbl_t **account_list, int count, int *err_code); + + +/************** Mailbox(Local box And Imap mailbox) Management ******************/ + +/* + * em_storage_get_mailbox_count + * + * description : get number of mailbox from local mailbox table + * arguments : + * db : database pointer + * count : number of accounts + * return : + */ +EXPORT_API int em_storage_get_mailbox_count(int account_id, int local_yn, int *count, int transaction, int *err_code); + +/* + * em_storage_get_mailbox + * + * description : get local mailbox from local mailbox table + * arguments : + * db : database pointer + * sort_type : in - sorting type. + * select_num : in - number of selected account + * out - number to been selected + * mailbox_list : buffer to hold selected account + * this buffer must be free after it has been used. + * return : + */ +EXPORT_API int em_storage_get_mailbox(int account_id, int local_yn, email_mailbox_sort_type_t sort_type, int *select_num, emf_mailbox_tbl_t **mailbox_list, int transaction, int *err_code); + +/* + * em_storage_get_child_mailbox_list + * + * description : get child mailbox list from given mailbox + * arguments : + * account_id : in - account id + * parent_mailbox_name : in - parent_mailbox_name to fetch child list + * local_yn - in - local mailbox or not + * select_num - out : count of mailboxes + * mailbox_list - out : list of mailboxes + * err_code - out : error code, if any + */ + + +EXPORT_API int em_storage_get_child_mailbox_list(int account_id, char *parent_mailbox_name, int *select_num, emf_mailbox_tbl_t **mailbox_list, int transaction, int *err_code); + +/* + * em_storage_get_mailbox_by_name + * + * description : get local mailbox from local mailbox table by mailbox name + * arguments : + * db : database pointer + * mailbox_name : mailbox name + * mailbox : buffer to hold selected local mailbox + * this buffer must be free after it has been used. + * return : + */ +EXPORT_API int em_storage_get_mailbox_by_name(int account_id, int local_yn, char *mailbox_name, emf_mailbox_tbl_t **mailbox, int transaction, int *err_code); +EXPORT_API int em_storage_get_mailbox_ex(int account_id, int local_yn, int with_count, int *select_num, emf_mailbox_tbl_t **mailbox_list, int transaction, int *err_code); +EXPORT_API int em_storage_get_mailbox_by_mailbox_type(int account_id, emf_mailbox_type_e mailbox_type, emf_mailbox_tbl_t **mailbox, int transaction, int *err_code); +EXPORT_API int em_storage_get_mailboxname_by_mailbox_type(int account_id, emf_mailbox_type_e mailbox_type, char **mailbox, int transaction, int *err_code); + +EXPORT_API int em_storage_update_mailbox_modifiable_yn(int account_id, int local_yn, char *mailbox_name, int modifiable_yn, int transaction, int *err_code); +EXPORT_API int em_storage_update_mailbox_total_count(int account_id, char *mailbox_name, int total_count_on_server, int transaction, int *err_code); + + +/* + * em_storage_update_mailbox + * + * description : change a account from account table + * arguments : + * db : database pointer + * mailbox_name : mailbox name + * mailbox : buffer to hold selected local mailbox + * return : + */ +EXPORT_API int em_storage_update_mailbox(int account_id, int local_yn, char *mailbox_name, emf_mailbox_tbl_t *mailbox, int transaction, int *err_code); + +/* + * em_storage_update_mailbox_type + * + * description : change a mailbox from mailbox tbl + * arguments : + * return : + */ +EXPORT_API int em_storage_update_mailbox_type(int account_id, int local_yn, char *mailbox_name, emf_mailbox_tbl_t *mailbox, int transaction, int *err_code); + +/* + * em_storage_add_mailbox + * + * description : add a local mailbox to local mailbox table + * arguments : + * return : + */ +EXPORT_API int em_storage_add_mailbox(emf_mailbox_tbl_t *mailbox, int transaction, int *err_code); + +/* + * em_storage_delete_mailbox + * + * description : delete a local mailbox from local mailbox table + * arguments : + * db : database pointer + * mailbox_name : mailbox name of record to be deteted + * return : + */ +EXPORT_API int em_storage_delete_mailbox(int account_id, int local_yn, char *mailbox_name, int transaction, int *err_code); + +EXPORT_API int em_storage_rename_mailbox(int account_id, char *old_mailbox_name, char *new_mailbox_name, int transaction, int *err_code); +EXPORT_API int em_storage_get_overflowed_mail_id_list(int account_id, char *mailbox_name, int mail_slot_size, int **mail_id_list, int *mail_id_count, int transaction, int *err_code); +EXPORT_API int em_storage_set_mail_slot_size(int account_id, char *mailbox_name, int new_slot_size, int transaction, int *err_code); + +EXPORT_API int em_storage_set_all_mailbox_modifiable_yn(int account_id, int modifiable_yn, int transaction, int *err_code); +EXPORT_API int em_storage_get_mailbox_by_modifiable_yn(int account_id, int modifiable_yn, int *select_num, emf_mailbox_tbl_t **mailbox_list, int transaction, int *err_code); + +/* + * em_storage_free_mailbox + * + * description : free local mailbox memory + * arguments : + * mailbox_list : double pointer + * count : count of local mailbox + * return : + */ +EXPORT_API int em_storage_free_mailbox(emf_mailbox_tbl_t **mailbox_list, int count, int *err_code); + + +/************** Read Mail UID Management ******************/ + + + +EXPORT_API int em_storage_get_count_read_mail_uid(int account_id, char *mailbox_name, int *count, int transaction, int *err_code); + + +/* + * em_storage_check_read_mail_uid + * + * description : check that this uid exists in uid table + * arguments : + * db : database pointer + * mailbox_name : mailbox name + * s_uid : uid string to be checked + * exist : variable to hold checking result. (0 : not exist, 1 : exist) + * return : + */ +EXPORT_API int em_storage_check_read_mail_uid(int account_id, char *mailbox_name, char *uid, int *exist, int transaction, int *err_code); + +/* + * em_storage_get_read_mail_size + * + * description : get mail size from read mail uid + * arguments : + * db : database pointer + * local_mbox : local mailbox name + * local_uid : mail uid of local mailbox + * mailbox_name : server mailbox name + * uid : mail uid string of server mail + * read_mail_uid : variable to hold read mail uid information + * return : + */ +EXPORT_API int em_storage_get_downloaded_list(int account_id, char *local_mbox, emf_mail_read_mail_uid_tbl_t **read_mail_uid, int *count, int transaction, int *err_code); + +EXPORT_API int em_storage_get_downloaded_mail(int mail_id, emf_mail_tbl_t **mail, int transaction, int *err_code); + +/* + * em_storage_get_read_mail_size + * + * description : get mail size from read mail uid + * arguments : + * db : database pointer + * mailbox_name : mailbox name + * s_uid : mail uid string + * size : variable to hold mail size + * return : + */ +EXPORT_API int em_storage_get_downloaded_mail_size(int account_id, char *local_mbox, int local_uid, char *mailbox_name, char *uid, int *mail_size, int transaction, int *err_code); + +/* + * em_storage_add_downloaded_mail + * + * description : add read mail uid + * arguments : + * return : + */ +EXPORT_API int em_storage_add_downloaded_mail(emf_mail_read_mail_uid_tbl_t *read_mail_uid, int transaction, int *err_code); + +/* + * em_storage_change_read_mail_uid + * + * description : modify read mail uid + * arguments : + * return : + */ +EXPORT_API int em_storage_change_read_mail_uid(int account_id, char *local_mbox, int local_uid, char *mailbox_name, char *uid, + emf_mail_read_mail_uid_tbl_t *read_mail_uid, int transaction, int *err_code); + +/* + * em_storage_remove_downloaded_mail + * + * description : + * arguments : + * return : + */ +EXPORT_API int em_storage_remove_downloaded_mail(int account_id, char *mailbox_name, char *uid, int transaction, int *err_code); + + +EXPORT_API int em_storage_update_read_mail_uid(int mail_id, char *new_server_uid, char *mbox_name, int *err_code); + +/* + * free memroy + */ +EXPORT_API int em_storage_free_read_mail_uid(emf_mail_read_mail_uid_tbl_t **read_mail_uid, int count, int *err_code); + + + +/************** Rules(Filtering) Management ******************/ + +/* + * em_storage_get_rule_count + * + * description : get number of rules from rule table + * arguments : + * db : database pointer + * count : number of accounts + * return : + */ +EXPORT_API int em_storage_get_rule_count(int account_id, int *count, int transaction, int *err_code); + +/* + * em_storage_get_rule + * + * description : get rules from rule table + * arguments : + * db : database pointer + * start_idx : the first index to be selected (min : 0) + * select_num : in - number of selected account + * out - number to been selected + * is_completed : is completed ? + * return : + */ +EXPORT_API int em_storage_get_rule(int account_id, int type, int start_idx, int *select_num, int *is_completed, emf_mail_rule_tbl_t **rule_list, int transaction, int *err_code); + +/* + * em_storage_get_rule + * + * description : get rules from rule table + * arguments : + * return : + */ +EXPORT_API int em_storage_get_rule_by_id(int account_id, int rule_id, emf_mail_rule_tbl_t **rule, int transaction, int *err_code); + +/* + * em_storage_change_rule + * + * description : change a account from account table + * arguments : + * db : database pointer + * mailbox_name : mailbox name + * rule : buffer to hold selected rule + * return : + */ +EXPORT_API int em_storage_change_rule(int account_id, int rule_id, emf_mail_rule_tbl_t *rule, int transaction, int *err_code); + +/* + * em_storage_find_rule + * + * description : find a rule already exists + * arguments : + * return : + */ +EXPORT_API int em_storage_find_rule(emf_mail_rule_tbl_t *rule, int transaction, int *err_code); + +/* + * em_storage_add_rule + * + * description : add a rule to rule table + * arguments : + * return : + */ +EXPORT_API int em_storage_add_rule(emf_mail_rule_tbl_t *rule, int transaction, int *err_code); + +/* + * em_storage_delete_rule + * + * description : delete a rule from rule table + * arguments : + * db : database pointer + * rule : rule to be deteted + * return : + */ +EXPORT_API int em_storage_delete_rule(int account_id, int rule_id, int transaction, int *err_code); + +/* + * em_storage_free_rule + * + * description : free rule memory + * arguments : + * count : count of rule + * return : + */ +EXPORT_API int em_storage_free_rule(emf_mail_rule_tbl_t **rule_list, int count, int *err_code); + + +EXPORT_API int em_storage_filter_mails_by_rule(int account_id, char *dest_mailbox_name, emf_mail_rule_tbl_t *rule, int **filtered_mail_id_list, int *count_of_mails, int *err_code); + +/************** Mail Management ******************/ + +/* + * em_storage_get_mail_count + * + * description : get mail total and unseen count from mail table + * arguments : + * total : total count + * unseen : unseen mail count + * return : + */ +EXPORT_API int em_storage_get_mail_count(int account_id, const char *mailbox, int *total, int *unseen, int transaction, int *err_code); + +/* + * em_storage_get_mail_by_id + * + * description : get mail from mail table by mail id + * arguments : + * mail_id : mail id + * mail : double pointer to hold mail + * return : + */ +EXPORT_API int em_storage_get_mail_by_id(int mail_id, emf_mail_tbl_t **mail, int transaction, int *err_code); + +/* + * em_storage_get_mail + * + * description : get mail from mail table by mail sequence + * arguments : + * account_id : account id + * mailbox : mailbox name + * mail_no : mail sequence number (not mail id) + * mail : double pointer to hold mail + * return : + */ +EXPORT_API int em_storage_get_mail_field_by_id(int mail_id, int type, emf_mail_tbl_t **mail, int transaction, int *err_code); + +/* + * em_storage_get_mail_field_by_multiple_mail_id + * + * description : + * arguments : + * mail_ids : + * number_of_mails : + * type : + * mail : + * transaction : + * err_code : + * return : + */ +EXPORT_API int em_storage_get_mail_field_by_multiple_mail_id(int mail_ids[], int number_of_mails, int type, emf_mail_tbl_t** mail, int transaction, int *err_code); + +/* + * em_storage_query_mail_list + * + * description : query mail list information + */ +EXPORT_API int em_storage_query_mail_list(const char *conditional_clause, int transaction, emf_mail_list_item_t** result_mail_list, int *result_count, int *err_code); + +/* + * em_storage_query_mail_tbl + * + * description : query mail table information + */ +EXPORT_API int em_storage_query_mail_tbl(const char *conditional_clause, int transaction, emf_mail_tbl_t** result_mail_tbl, int *result_count, int *err_code); + +/* + * em_storage_get_mail_list + * + * description : search mail list information + */ +EXPORT_API int em_storage_get_mail_list(int account_id, const char *mailbox_name, emf_email_address_list_t* addr_list, int thread_id, int start_index, int limit_count, int search_type, const char *search_value, emf_sort_type_t sorting, int transaction, emf_mail_list_item_t** mail_list, int *result_count, int *err_code); +/* + * em_storage_get_mails + * + * description : search mail list information + */ +EXPORT_API int em_storage_get_mails(int account_id, const char *mailbox_name, emf_email_address_list_t* addr_list, int thread_id, int start_index, int limit_count, emf_sort_type_t sorting, int transaction, emf_mail_tbl_t** mail_list, int *result_count, int *err_code); +EXPORT_API int em_storage_get_searched_mail_list(int account_id, const char *mailbox_name, int thread_id, int search_type, const char *search_value, int start_index, int limit_count, emf_sort_type_t sorting, int transaction, emf_mail_list_item_t **mail_list, int *result_count, int *err_code); +EXPORT_API int em_storage_get_maildata_by_servermailid(int account_id, char *server_mail_id, emf_mail_tbl_t **mail, int transaction, int *err_code); +EXPORT_API int em_storage_get_latest_unread_mailid(int account_id, int *mail_id, int *err_code); + + +/** + * Prepare mail search. + * + * @param[in] search Specifies the searching condition. + * @param[in] account_id Specifies the account id. if 0, all accounts. + * @param[in] mailbox Specifies the mailbox name. if NULL, all mailboxes. + * @param[in] sorting Specifies the sorting condition. + * @param[out] search_handle the searching handle is saved here. + * @param[out] searched the result count is saved here. + * @remarks N/A + * @return This function returns 0 on success or error code on failure. + */ +EXPORT_API int em_storage_mail_search_start(emf_mail_search_t *search, int account_id, char *mailbox, int sorting, int *search_handle, int *searched, int transaction, int *err_code); + +/* + * em_storage_mail_search_result + * + * description : retrieve mail as searching result + * arguments : + * search_handle : handle to been gotten from em_storage_mail_search_start + * mail : double pointer to hold mail + * return : + */ +EXPORT_API int em_storage_mail_search_result(int search_handle, emf_mail_field_type_t type, void **data, int transaction, int *err_code); + +/* + * em_storage_mail_search_end + * + * description : finish searching + * arguments : + * search_handle : handle to be finished + * return : + */ +EXPORT_API int em_storage_mail_search_end(int search_handle, int transaction, int *err_code); + + + +/* + * em_storage_set_field_of_mails_with_integer_value + * + * description : update a filed of mail + * arguments : + * account_id : Specifies the account id. + * mail_ids : mail id list to be changed + * mail_ids_count : count of mail list + * field_name : specified field name + * value : specified value + * return : + */ +EXPORT_API int em_storage_set_field_of_mails_with_integer_value(int account_id, int mail_ids[], int mail_ids_count, char *field_name, int value, int transaction, int *err_code); + +/* + * em_storage_change_mail_field + * + * description : update partial mail data + * arguments : + * mail_id : mail id + * type : changing type + * mail : mail pointer + * return : + */ +EXPORT_API int em_storage_change_mail_field(int mail_id, emf_mail_change_type_t type, emf_mail_tbl_t *mail, int transaction, int *err_code); + +/* + * em_storage_increase_mail_id + * + * description : increase unique mail id + * arguments : + * mail_id : pointer to store the unique id + * return : + */ + +/* + * em_storage_change_mail + * + * description : update mail + * arguments : + * mail_id : mail id to be changed + * mail : mail pointer + * return : + */ +EXPORT_API int em_storage_change_mail(int mail_id, emf_mail_tbl_t *mail, int transaction, int *err_code); +EXPORT_API int em_storage_clean_save_status(int save_status, int *err_code); +EXPORT_API int em_storage_update_server_uid(char *old_server_uid, char *new_server_uid, int *err_code); +EXPORT_API int em_storage_modify_mailbox_of_mails(char *old_mailbox_name, char *new_mailbox_name, int transaction, int *err_code); + +EXPORT_API int em_storage_increase_mail_id(int *mail_id, int transaction, int *err_code); + +/* + * em_storage_add_mail + * + * description : add a mail to mail table + * arguments : + * mail : mail pointer to be inserted + * get_id : must get uinque id in function + * return : + */ +EXPORT_API int em_storage_add_mail(emf_mail_tbl_t *mail, int get_id, int transaction, int *err_code); + +/* + * em_storage_move_multiple_mails + * + * description : + * arguments : + * account_id : + * target_mailbox_name : + * mail_ids : + * number_of_mails : + * transaction : + * err_code : + * return : + */ +EXPORT_API int em_storage_move_multiple_mails(int account_id, char *target_mailbox_name, int mail_ids[], int number_of_mails, int transaction, int *err_code); + +/* + * em_storage_delete_mail + * + * description : delete mail from mail table + * arguments : + * mail_id : mail id to be deleted. if 0, all mail will be deleted. + * from_server : delete mail on server. + * return : + */ +EXPORT_API int em_storage_delete_mail(int mail_id, int from_server, int transaction, int *err_code); + +/* + * em_storage_delete_mail_by_account + * + * description : delete mail from mail table by account id + * arguments : + * account_id : account id. + * return : + */ +EXPORT_API int em_storage_delete_mail_by_account(int account_id, int transaction, int *err_code); + +/* + * em_storage_delete_mail + * + * description : delete mail from mail table + * arguments : + * account_id : account id. + * mbox : mail box + * return : + */ +EXPORT_API int em_storage_delete_mail_by_mailbox(int account_id, char *mbox, int transaction, int *err_code); + +/* + * em_storage_delete_multiple_mails + * + * description : + * arguments : + * mail_ids : + * number_of_mails : + * transaction : + * err_code : + * return : + */ +EXPORT_API int em_storage_delete_multiple_mails(int mail_ids[], int number_of_mails, int transaction, int *err_code); + +/* + * em_storage_free_mail + * + * description : free memory + * arguments : + * mail_list : mail array + * count : the number of array element + * return : + */ +EXPORT_API int em_storage_free_mail(emf_mail_tbl_t **mail_list, int count, int *err_code); + +/* + * em_storage_get_attachment + * + * description : get attachment from attachment table + * arguments : + * mail_id : mail id + * no : attachment sequence + * attachment : double pointer to hold attachment data + * return : + */ +EXPORT_API int em_storage_get_attachment_count(int mail_id, int *count, int transaction, int *err_code); + +/* + * em_storage_get_attachment_list + * + * description : get attachment list from attachment table + * arguments : + * input_mail_id : mail id + * input_transaction : transaction option + * attachment_list : result attachment list + * output_attachment_count : result attachment count + * return : This function returns EM_STORAGE_ERROR_NONE on success or error code (refer to EM_STORAGE_ERROR__XXX) on failure. + * + */ +EXPORT_API int em_storage_get_attachment_list(int input_mail_id, int input_transaction, emf_mail_attachment_tbl_t** output_attachment_list, int *output_attachment_count); + + +/* + * em_storage_get_attachment + * + * description : get attachment from attachment table + * arguments : + * mail_id : mail id + * no : attachment id + * attachment : double pointer to hold attachment data + * return : + */ +EXPORT_API int em_storage_get_attachment(int mail_id, int no, emf_mail_attachment_tbl_t **attachment, int transaction, int *err_code); + +/* + * em_storage_get_attachment + * + * description : get nth-attachment from attachment table + * arguments : + * mail_id : mail id + * nth : index of the desired attachment (min : 1) + * attachment : double pointer to hold attachment data + * return : + */ +EXPORT_API int em_storage_get_attachment_nth(int mail_id, int nth, emf_mail_attachment_tbl_t **attachment, int transaction, int *err_code); + +/* + * em_storage_change_attachment_field + * + * description : update partial mail attachment data + * arguments : + * mail_id : mail id + * type : changing type + * mail : mail pointer + * return : + */ +EXPORT_API int em_storage_change_attachment_field(int mail_id, emf_mail_change_type_t type, emf_mail_attachment_tbl_t *attachment, int transaction, int *err_code); + +/* + * em_storage_change_attachment_mbox + * + * description : update mailbox from attahcment table + * arguments : + * account_id : account id + * old_mailbox_name : old mail box + * new_mailbox_name : new mail box + * return : + */ +EXPORT_API int em_storage_change_attachment_mbox(int account_id, char *old_mailbox_name, char *new_mailbox_name, int transaction, int *err_code); + +/* Get new attachment id */ +/* + * em_storage_get_new_attachment_no + * + * description : Get new attachment id + * arguments : + * attachment_no : attachment id pointer + * return : + */ + +EXPORT_API int em_storage_get_new_attachment_no(int *attachment_no, int *err_code); + +/* insert attachment to mail attachment table */ +/* + * em_storage_add_attachment + * + * description : insert a attachment to attachment table + * arguments : + * attachment : attachment pointer + * return : + */ +EXPORT_API int em_storage_add_attachment(emf_mail_attachment_tbl_t *attachment, int iscopy, int transaction, int *err_code); + + +EXPORT_API int em_storage_update_attachment(emf_mail_attachment_tbl_t *attachment, int transaction, int *err_code); + +/* delete a mail from mail table */ +/* + * em_storage_delete_attachment_on_db + * + * description : delete attachment from attachment table + * arguments : + * mail_id : mail id to contain attachment + * no : attachment sequence number + * return : + */ +EXPORT_API int em_storage_delete_attachment_on_db(int mail_id, int no, int transaction, int *err_code); + +/* + * em_storage_delete_attachment_all_on_db + * + * description : delete attachment from mail table + * arguments : + * account_id : account id. + * mbox : mail box + * return : + */ +EXPORT_API int em_storage_delete_attachment_all_on_db(int account_id, char *mbox, int transaction, int *err_code); + +/* + * em_storage_free_attachment + * + * description : free memory + * arguments : + * mail_list : mail array + * count : the number of array element + * return : + */ +EXPORT_API int em_storage_free_attachment(emf_mail_attachment_tbl_t **attachment_list, int count, int *err_code); + +/* em_storage_get_mail_count_with_draft_flag - Send number of mails in a mailbox with draft flag enabled */ +EXPORT_API int em_storage_get_mail_count_with_draft_flag(int account_id, const char *mailbox, int *total, int transaction, int *err_code); + +/* em_storage_get_mail_count_on_sending - Send number of mails being sent in a mailbox (status == EMF_MAIL_STATUS_SENDING) */ +EXPORT_API int em_storage_get_mail_count_on_sending(int account_id, const char *mailbox, int *total, int transaction, int * err_code); + +EXPORT_API int em_storage_is_mailbox_full(int account_id, emf_mailbox_t *mailbox, int *result, int *err_code); + +EXPORT_API int em_storage_get_max_mail_count(); + +EXPORT_API int em_storage_mail_get_total_diskspace_usage(unsigned long *total_usage, int transaction, int *err_code); + + +/** + * begin a transaction. + * + * @param[in] d1 Reserved. + * @param[in] d2 Reserved. + * @remarks em_storage_commit_transaction or em_storage_commit_transaction must be called after this function. + * @return This function returns 0 on success or error code on failure. + */ + +EXPORT_API int em_storage_begin_transaction(void *d1, void *d2, int *err_code); + +/** + * commit a transaction. + * + * @param[in] d1 Reserved. + * @param[in] d2 Reserved. + * @remarks N/A + * @return This function returns 0 on success or error code on failure. + */ +EXPORT_API int em_storage_commit_transaction(void *d1, void *d2, int *err_code); + +/** + * rollback db. + * + * @param[in] d1 Reserved. + * @param[in] d2 Reserved. + * @remarks N/A + * @return This function returns 0 on success or error code on failure. + */ +EXPORT_API int em_storage_rollback_transaction(void *d1, void *d2, int *err_code); + +/** + * clear mail data from db. + * + * @param[in] transaction + * @param[out] err_code + * @remarks N/A + * @return This function returns 0 on success or error code on failure. + */ + +EXPORT_API int em_storage_clear_mail_data(int transaction, int *err_code); + +/* + * em_storage_get_save_name + * + * description : get file name for saving data + * arguments : + * account_id : account id + * mail_id : mail id + * atch_id : attachment id + * fname : file name + * name_buf : buffer to hold file name. (MAX : 512Bytes) + * return : + */ +EXPORT_API int em_storage_get_save_name(int account_id, int mail_id, int atch_id, char *fname, char *name_buf, int *err_code); + +/* + * em_storage_get_dele_name + * + * description : get a name for deleting contents from file system. + * arguments : + * account_id : account id + * mail_id : mail id + * atch_id : attachment id + * fname : reserved + * name_buf : buffer to hold file name. (MAX : 512Bytes) + * return : + */ +EXPORT_API int em_storage_get_dele_name(int account_id, int mail_id, int atch_id, char *fname, char *name_buf, int *err_code); + +/* + * em_storage_create_dir + * + * description : create directory + * arguments : + * name_buf : buffer to hold file name. (MAX : 512Bytes) + * no : attachment no. + * return : + */ +EXPORT_API int em_storage_create_dir(int account_id, int mail_id, int atch_id, int *err_code); + +/* + * em_storage_copy_file + * + * description : copy a attachment file + * arguments : + * src_file : source file + * dst_file : destination file + * return : + */ +EXPORT_API int em_storage_copy_file(char *src_file, char *dst_file, int sync_file, int *err_code); + +/* + * em_storage_move_file + * + * description : move a file + * arguments : + * src_file : source file + * dst_file : destination file + * return : + */ +EXPORT_API int em_storage_move_file(char *src_file, char *dst_file, int sync_status, int *err_code); + +/* + * em_storage_move_file + * + * description : delete a file + * arguments : + * src_file : file to be deleted + * return : + */ +EXPORT_API int em_storage_delete_file(char *src_file, int *err_code); + +/* + * em_storage_delete_dir + * + * description : delete a directory + * arguments : + * src_dir : directory to be deleted + * return : + */ +EXPORT_API int em_storage_delete_dir(char *src_dir, int *err_code); + + + +EXPORT_API void em_storage_flush_db_cache(); +EXPORT_API int em_storage_test(int mail_id, int account_id, char *full_address_to, char *full_address_cc, char *full_address_bcc, int *err_code); + +EXPORT_API int em_storage_sleep_on_off(int on, int *error_code); +EXPORT_API int em_storage_dimming_on_off(int on, int *error_code); +#ifdef USE_POWERMGMT +EXPORT_API int em_storage_power_management(int *error_code); +#endif + + + +/** + * em_storage_notify_storage_event - Notification for storage related operations + * + */ +EXPORT_API int em_storage_notify_storage_event(emf_noti_on_storage_event event_type, int data1, int data2 , char *data3, int data4); + +/** + * em_storage_notify_network_event - Notification for network related operations + * + */ +EXPORT_API int em_storage_notify_network_event(emf_noti_on_network_event event_type, int data1, char *data2, int data3, int data4); +EXPORT_API int em_storage_get_sender_list(int account_id, const char *mailbox_name, int search_type, const char *search_value, emf_sort_type_t sorting, emf_sender_list_t** sender_list, int *sender_count, int *err_code); +EXPORT_API int em_storage_free_sender_list(emf_sender_list_t **sender_list, int count); + +/* Handling Thread mail */ +EXPORT_API int em_storage_get_thread_information(int thread_id, emf_mail_tbl_t **mail_table_data, int transaction, int *err_code); +EXPORT_API int em_storage_get_thread_id_of_thread_mails(emf_mail_tbl_t *mail_table_data, int *thread_id, int *result_latest_mail_id_in_thread, int *thread_item_count); +EXPORT_API int em_storage_get_thread_id_by_mail_id(int mail_id, int *thread_id, int *err_code); +EXPORT_API int em_storage_update_latest_thread_mail(int account_id, int thread_id, int latest_mail_id, int thread_item_count, int transaction, int *err_code); + + +#ifdef _CONTACT_SUBSCRIBE_CHANGE_ +EXPORT_API int em_storage_contact_sync_insert(int contact_id, char *display_name, GSList *email_list, int *err_code); +EXPORT_API int em_storage_contact_sync_update(int contact_id, char *display_name, GSList *email_list, int *err_code); +EXPORT_API int em_storage_contact_sync_delete(int contact_id, int *err_code); +#endif + +#ifdef __FEATURE_PARTIAL_BODY_DOWNLOAD__ + +#define BULK_PARTIAL_BODY_DOWNLOAD_COUNT 10 +enum +{ + ACCOUNT_IDX_MAIL_PARTIAL_BODY_ACTIVITY_TBL = 0, + MAIL_IDX_IN_MAIL_PARTIAL_BODY_ACTIVITY_TBL, + SERVER_MAIL_IDX_IN_MAIL_PARTIAL_BODY_ACTIVITY_TBL, + ACTIVITY_IDX_IN_MAIL_PARTIAL_BODY_ACTIVITY_TBL, + ACTIVITY_TYPE_IDX_IN_MAIL_PARTIAL_BODY_ACTIVITY_TBL, + MAILBOX_NAME_IDX_IN_MAIL_PARTIAL_BODY_ACTIVITY_TBL, +}; + + +EXPORT_API int em_storage_get_pbd_activity_data(int account_id, char *mailbox_name, emf_event_partial_body_thd** event_start, int *count, int transaction, int *err_code); +EXPORT_API int em_storage_add_pbd_activity(emf_event_partial_body_thd *local_activity, int *activity_id, int transaction, int *err_code); +EXPORT_API int em_storage_get_pbd_mailbox_list(int account_id, char ***mailbox_list, int *count, int transaction, int *err_code); +EXPORT_API int em_storage_get_pbd_account_list(int **account_list, int *count, int transaction, int *err_code); +EXPORT_API int em_storage_get_pbd_activity_count(int *activity_id_count, int transaction, int *err_code); +EXPORT_API int em_storage_delete_full_pbd_activity_data(int account_id, int transaction, int *err_code); +EXPORT_API int em_storage_delete_pbd_activity(int account_id, int mail_id, int activity_id, int transaction, int *err_code); +EXPORT_API int em_storage_get_mailbox_pbd_activity_count(int account_id, char *mailbox_name, int *activity_count, int transaction, int *err_code); +EXPORT_API int em_storage_update_pbd_activity(char *old_server_uid, char *new_server_uid, char *mbox_name, int *err_code); +EXPORT_API int em_storage_create_file(char *buf, size_t file_size, char *dst_file, int *err_code); + +#endif + +EXPORT_API int em_storage_free_address_info_list(emf_address_info_list_t **address_info_list); + + +EXPORT_API void em_storage_create_dir_if_delete(); +EXPORT_API int em_storage_get_emf_error_from_em_storage_error(int error); + +EXPORT_API void *em_core_malloc(unsigned len); + + +#ifdef __FEATURE_BULK_DELETE_MOVE_UPDATE_REQUEST_OPTI__ +EXPORT_API int em_storage_update_read_mail_uid_by_server_uid(char *old_server_uid, char *new_server_uid, char *mbox_name, int *err_code); + +/** + * @fn em_storage_get_id_set_from_mail_ids(int mail_ids[], int mail_id_count, emf_id_set_t **server_uids, int *id_set_count, int *err_code); + * Prepare an array of mail_id and corresponding server mail id. + * + *@author h.gahlaut@samsung.com + * @param[in] mail_ids Specifies the comma separated string of mail_ids. Maximaum size of string should be less than or equal to (QUERY_SIZE - 88) + * where 88 is the length of fixed keywords including ending null character in the QUERY to be formed + * @param[out] idset Returns the array of mail_id and corresponding server_mail_id sorted by server_mail_ids in ascending order + * @param[out] id_set_count Returns the no. of cells in idset array i.e. no. of sets of mail_ids and server_mail_ids + * @param[out] err_code Returns the error code. + * @remarks An Example of Query to be exexuted in this API : + * SELECT local_uid, s_uid from mail_read_mail_uid_tbl where local_uid in (12, 13, 56, 78); + * @return This function returns true on success or false on failure. + */ + +EXPORT_API int em_storage_get_id_set_from_mail_ids(char *mail_ids, emf_id_set_t **idset, int *id_set_count, int *err_code); + +#endif + +/** + * @fn em_storage_filter_mails_by_rule(int account_id, char dest_mailbox_name, emf_rule_t *rule, int **filtered_mail_id_list, int *count_of_mails, int err_code) + * Move mails by specified rule for spam filtering. + * + * @author kyuho.jo@samsung.com + * @param[in] account_id Account id of the mails and the mailboxes. + * @param[in] dest_mailbox_name Mailbox name of spam mailbox. + * @param[in] rule Filtering rule. + * @param[out] filtered_mail_id_list Mail id list which are filtered by the rule. + * @param[out] count_of_mails Count of mails which are filtered by the rule. + * @param[out] err_code Returns the error code. + + * @remarks + * @return This function returns true on success or false on failure. + */ + +EXPORT_API int em_storage_add_meeting_request(int account_id, char *mailbox_name, emf_meeting_request_t *meeting_req, int transaction, int *err_code); +EXPORT_API int em_storage_get_meeting_request(int mail_id, emf_meeting_request_t **meeting_req, int transaction, int *err_code); +EXPORT_API int em_storage_update_meeting_request(emf_meeting_request_t *meeting_req, int transaction, int *err_code); +EXPORT_API int em_storage_change_meeting_request_field(int account_id, char *mailbox_name, emf_mail_change_type_t type, emf_meeting_request_t *meeting_req, int transaction, int *err_code); +EXPORT_API int em_storage_change_meeting_request_mailbox(int account_id, char *old_mailbox_name, char *new_mailbox_name, int transaction, int *err_code); +EXPORT_API int em_storage_delete_meeting_request(int account_id, int mail_id, char *mailbox_name, int transaction, int *err_code); +EXPORT_API int em_storage_free_meeting_request(emf_meeting_request_t **meeting_req, int count, int *err_code); + +#ifdef __LOCAL_ACTIVITY__ +/* +*em_storage_get_next_activity_id +* +*description : get an activity id for a new activity +*/ +EXPORT_API int em_storage_get_next_activity_id(int *activity_id, int *err_code); + + /* + *em_storage_get_activity_id_list + *description : get the list of activity ids + *arguments : + *return : + * + */ + EXPORT_API int em_storage_get_activity_id_list(int account_id, int **activity_id_list, int *activity_count, int lowest_activity_type, int highest_activity_type, int transaction, int*err_code); + /* + * em_storage_add_activity + * + * description : add an activity to activity table + * arguments : + * return : + */ +EXPORT_API int em_storage_add_activity(emf_activity_tbl_t *local_activity, int transaction, int *err_code); + +/** + * em_storage_get_activity - Get the Local activity from the Mail activity table + * + */ +EXPORT_API int em_storage_get_activity(int account_id, int activity_id, emf_activity_tbl_t **activity_list, int *select_num, int transaction, int *err_code); + +/** + * em_storage_delete_local_activity - Deletes the Local acitivity Generated based on activity_type + * or based on server mail id + * + */ +EXPORT_API int em_storage_delete_local_activity(emf_activity_tbl_t *local_activity, int transaction, int *err_code); + +/** + * em_storage_free_local_activity - Free the allocated Activity data + * + * + */ +EXPORT_API int em_storage_free_local_activity(emf_activity_tbl_t **local_activity_list, int count, int *err_code); + +/** + * em_storage_free_activity_id_list - Free the allocated Activity List data + * + * + */ +EXPORT_API int em_storage_free_activity_id_list(int *activity_id_list, int *error_code); + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __EM_STORAGE_H__ */ +/* EOF */ diff --git a/email-core/include/em-core-account.h b/email-core/include/em-core-account.h new file mode 100755 index 0000000..4cc92a4 --- /dev/null +++ b/email-core/include/em-core-account.h @@ -0,0 +1,83 @@ +/* +* email-service +* +* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. +* +* Contact: Kyuho Jo <kyuho.jo@samsung.com>, Sunghyun Kwon <sh0701.kwon@samsung.com> +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + + + +/****************************************************************************** + * File : em-core-account.h + * Desc : Account Management + * * Auth : + * * History : + * 2010.08.25 : created + *****************************************************************************/ +#ifndef _EM_CORE_ACCOUNT_H_ +#define _EM_CORE_ACCOUNT_H_ + +#include "emf-types.h" +#include "em-core-types.h" +#include "em-storage.h" + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +EXPORT_API emf_account_t *em_core_get_account_reference(int account_id); + +EXPORT_API int em_core_account_validate(int account_id, int *err_code); + +EXPORT_API int em_core_account_delete(int account_id, int *err_code); + +EXPORT_API int em_core_account_create(emf_account_t *account, int *err_code); + +EXPORT_API int em_core_init_account_reference(); + +EXPORT_API int em_core_refresh_account_reference(); + +EXPORT_API int em_core_free_account_reference(); + +EXPORT_API int em_core_account_free(emf_account_t **account_list, int count, int *err_code); + +EXPORT_API int em_core_account_get_list_refer(emf_account_t **account_list, int *count, int *err_code); + +EXPORT_API int em_core_account_validate_with_account_info(emf_account_t *account, int *err_code); + +EXPORT_API int em_core_query_server_info(const char* domain_name, emf_server_info_t **result_server_info); + +EXPORT_API int em_core_free_server_info(emf_server_info_t **target_server_info); + +EXPORT_API int em_core_save_default_account_id(int input_account_id); + +EXPORT_API int em_core_load_default_account_id(int *output_account_id); + + +#ifdef __FEATURE_BACKUP_ACCOUNT__ +EXPORT_API int em_core_backup_accounts(const char *file_path, int *error_code); + +EXPORT_API int em_core_restore_accounts(const char *file_path, int *error_code); +#endif /* __FEATURE_BACKUP_ACCOUNT_ */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /*_EM_CORE_ACCOUNT_H_*/ + diff --git a/email-core/include/em-core-api.h b/email-core/include/em-core-api.h new file mode 100755 index 0000000..5519058 --- /dev/null +++ b/email-core/include/em-core-api.h @@ -0,0 +1,59 @@ +/* +* email-service +* +* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. +* +* Contact: Kyuho Jo <kyuho.jo@samsung.com>, Sunghyun Kwon <sh0701.kwon@samsung.com> +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + + +/****************************************************************************** + * File : em-core-api.h + * Desc : Mail Engine API Header + * + * Auth : + * + * History : + * 2006.08.16 : created + *****************************************************************************/ +#ifndef _EM_CORE_API_H_ +#define _EM_CORE_API_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + + +int em_core_encode_base64(char *src, unsigned long src_len, char **enc, unsigned long* enc_len, int *err_code); + +int em_core_decode_quotedprintable(unsigned char *enc_text, unsigned long enc_len, char **dec_text, unsigned long*dec_len, int *err_code); + +int em_core_decode_base64(unsigned char *enc_text, unsigned long enc_len, char **dec_text, unsigned long* dec_len, int *err_code); + +int em_core_init(int *err_code); + +/* em_core_set_logout_status - Set the logout status */ +EXPORT_API void em_core_set_logout_status(int status); + +/* em_core_get_logout_status - Get the logout status */ +EXPORT_API void em_core_get_logout_status(int *status); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /*_EM_CORE_API_H_*/ diff --git a/email-core/include/em-core-event.h b/email-core/include/em-core-event.h new file mode 100755 index 0000000..a60963c --- /dev/null +++ b/email-core/include/em-core-event.h @@ -0,0 +1,96 @@ +/* +* email-service +* +* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. +* +* Contact: Kyuho Jo <kyuho.jo@samsung.com>, Sunghyun Kwon <sh0701.kwon@samsung.com> +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + + +/****************************************************************************** + * File : em-core-event.h + * Desc : Mail Engine Event Header + * + * Auth : + * + * History : + * 2006.08.16 : created + *****************************************************************************/ +#ifndef __EM_CORE_EVNET_H__ +#define __EM_CORE_EVNET_H__ + +#include "emf-types.h" +#include "em-core-types.h" + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + + +#if !defined(EXPORT_API) +#define EXPORT_API __attribute__((visibility("default"))) +#endif + +void em_core_execute_event_callback(emf_action_t action, int total, int done, int status, int account_id, int mail_id, int handle, int error); +int em_core_get_active_queue_idx(void); + +EXPORT_API int em_core_get_current_thread_type(); +EXPORT_API int em_core_register_event_callback(emf_action_t action, emf_event_callback callback, void *event_data); +EXPORT_API int em_core_unregister_event_callback(emf_action_t action, emf_event_callback callback); +EXPORT_API int em_core_get_pending_event(emf_action_t action, int account_id, int mail_id, emf_event_status_type_t *status); +EXPORT_API int em_core_event_loop_start(int *err_code); +EXPORT_API int em_core_event_loop_stop(int *err_code); +EXPORT_API int em_core_insert_event(emf_event_t *event_data, int *handle, int *err_code); +EXPORT_API int em_core_cancel_thread(int handle, void *arg, int *err_code); +EXPORT_API int em_core_send_event_loop_start(int *err_code); +EXPORT_API int em_core_send_event_loop_stop(int *err_code); +EXPORT_API int em_core_cancel_send_mail_thread(int handle, void *arg, int *err_code); +EXPORT_API int em_core_check_thread_status(void); +EXPORT_API void em_core_get_event_queue_status(int *on_sending, int *on_receiving); +EXPORT_API int em_core_insert_send_event(emf_event_t *event_data, int *handle, int *err_code); +EXPORT_API int em_core_get_receiving_event_queue(emf_event_t **event_queue, int *event_count, int *err); +EXPORT_API int em_core_cancel_all_threads_of_an_account(int account_id); +EXPORT_API int em_core_free_event(emf_event_t *event_data); + +#ifdef _CONTACT_SUBSCRIBE_CHANGE_ +EXPORT_API int em_core_contact_sync_handler(); +EXPORT_API int em_core_init_last_sync_time(void); +EXPORT_API int em_core_set_last_sync_time(int sync_time); +EXPORT_API int em_core_get_last_sync_time(void); +EXPORT_API int em_core_contact_sync_handler(); +#endif + +#ifdef __FEATURE_PARTIAL_BODY_DOWNLOAD__ +/* Please contact -> Himanshu [h.gahlaut@samsung.com] for any explanation in code here under this MACRO */ +EXPORT_API int em_core_insert_partial_body_thread_event(emf_event_partial_body_thd *partial_body_thd_event, int *error_code); +EXPORT_API int em_core_is_partial_body_thd_que_empty(); +EXPORT_API int em_core_is_partial_body_thd_que_full(); +EXPORT_API int em_core_partial_body_thread_loop_start(int *err_code); +EXPORT_API int em_core_clear_partial_body_thd_event_que(int *err_code); +EXPORT_API int em_core_free_partial_body_thd_event(emf_event_partial_body_thd *partial_body_thd_event, int *error_code); +EXPORT_API unsigned int em_core_get_partial_body_thd_id(); +EXPORT_API int em_core_get_pbd_thd_state(); +unsigned int em_core_get_receiving_thd_id(); +#endif + + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif diff --git a/email-core/include/em-core-global.h b/email-core/include/em-core-global.h new file mode 100755 index 0000000..c401a25 --- /dev/null +++ b/email-core/include/em-core-global.h @@ -0,0 +1,56 @@ +/* +* email-service +* +* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. +* +* Contact: Kyuho Jo <kyuho.jo@samsung.com>, Sunghyun Kwon <sh0701.kwon@samsung.com> +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/****************************************************************************** + * File : em-core-global.h + * Desc : Mail Engine Global Header + * + * Auth : + * + * History : + * 2006.08.01 : created + *****************************************************************************/ +#ifndef __EM_CORE_GLOBAL_H__ +#define __EM_CORE_GLOBAL_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#include <glib.h> +#include "vconf-keys.h" +#include "emf-types.h" + +extern emf_account_list_t *g_account_list; +extern int g_account_num; +extern int g_account_retrieved; + +EXPORT_API emf_account_t *em_core_account_get_new_account_ref(); +extern char *strcasestr (__const char *__haystack, __const char *__needle) __THROW __attribute_pure__ __nonnull ((1, 2)); + +extern int pthread_mutexattr_settype (pthread_mutexattr_t *__attr, int __kind) __THROW __nonnull ((1)); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif diff --git a/email-core/include/em-core-imap-idle.h b/email-core/include/em-core-imap-idle.h new file mode 100755 index 0000000..0bce49f --- /dev/null +++ b/email-core/include/em-core-imap-idle.h @@ -0,0 +1,132 @@ +/* +* email-service +* +* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. +* +* Contact: Kyuho Jo <kyuho.jo@samsung.com>, Sunghyun Kwon <sh0701.kwon@samsung.com> +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + + +/** + * + * This file contains functinality related to IMAP IDLE. + * @file em-core-imap-idle.h + * @author + * @version 0.1 + * @brief This file contains functionality to provide IMAP IDLE support in email-service. + */ + +#include "emflib.h" + + +/** + + * @open + * @fn em_core_imap_idle_thread_create(int *err_code) + * @brief Creates a thread that listens for IMAP IDLE Notifications. + * + * @param[out] err_code Specifies the error code returned. + * @remarks N/A + * @return This function returns true on success or false on failure. + */ + +EXPORT_API int em_core_imap_idle_thread_create(int accountID, int *err_code); + +/** + + * @open + * @fn em_core_imap_idle_thread_kill(int *err_code) + * @brief Kills IMAP IDLE thread + * + * @param[out] err_code Specifies the error code returned. + * @remarks N/A + * @return This function returns true on success or false on failure. + */ +EXPORT_API int em_core_imap_idle_thread_kill(int *err_code); + + + +/** + + * @open + * @fn em_core_imap_idle_run(int *err_code, int iAccountID) + * @brief Make a list of mailboxes to IDLE on, connect to all mailboxes in list and start idle loop + * + * @param[out] err_code Specifies the error code returned. + * @remarks N/A + * @return This function returns true on success or false on failure. + */ + +static int em_core_imap_idle_run(int iAccountID); + +/** + + * @open + * @fn em_core_imap_idle_loop_start(emf_mailbox_t *mailbox_list, int num, int *err_code) + * @brief starts a loop which waits on select call. Select call monitors all the socket descriptors in the hold_connection fields of mailbox_list + * + * @param[in] mailbox_list list of mailboxes + * @param[in] num Count of mailboxes in list + * @param[out] err_code Specifies the error code returned. + * @remarks N/A + * @return This function returns true on success or false on failure. + */ +static int em_core_imap_idle_loop_start(emf_mailbox_t *mailbox_list, int num, int *err_code); + + + +/** + + * @open + * @fn em_core_imap_idle_loop_start(emf_mailbox_t *mailbox_list, int num, int *err_code) + * @brief Creates and inserts an event in event queue for syncing mailbox + * + * @param[in] mailbox mailbox to be synced. + * @param[out] err_code Specifies the error code returned. + * @remarks N/A + * @return This function returns true on success or false on failure. + */ +static int em_core_imap_idle_insert_sync_event(emf_mailbox_t *mailbox, int *err_code); + + + +/** + + * @open + * @fn em_core_imap_idle_connect_and_idle_on_mailbox(emf_mailbox_t *mailbox, int *err_code) + * @brief Opens connection to mailbox(selects mailbox) and sends IDLE command + * + * @param[in] mailbox mailbox to IDLE on. + * @param[out] err_code Specifies the error code returned. + * @remarks N/A + * @return This function returns true on success or false on failure. + */ +static int em_core_imap_idle_connect_and_idle_on_mailbox(emf_mailbox_t *mailbox, int *err_code); + + + +/** + + * @open + * @fn em_core_imap_idle_parse_response_stream(emf_mailbox_t *mailbox, int *err_code) + * @brief Gets and parsee the IDLE notification coming from network + * + * @param[in] mailbox mailbox that got IDLE notification. + * @param[out] err_code Specifies the error code returned. + * @remarks N/A + * @return This function returns true on success or false on failure. + */ +static int em_core_imap_idle_parse_response_stream(emf_mailbox_t *mailbox, int *err_code); diff --git a/email-core/include/em-core-imap-mailbox.h b/email-core/include/em-core-imap-mailbox.h new file mode 100755 index 0000000..c566c92 --- /dev/null +++ b/email-core/include/em-core-imap-mailbox.h @@ -0,0 +1,79 @@ +/* +* email-service +* +* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. +* +* Contact: Kyuho Jo <kyuho.jo@samsung.com>, Sunghyun Kwon <sh0701.kwon@samsung.com> +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + + + +/****************************************************************************** + * File : em-core-imap-mailbox.h + * Desc : Mail IMAP mailbox Header + * + * Auth : + * + * History : + * 2006.08.01 : created + *****************************************************************************/ +#ifndef __EM_CORE_IMAP_MAILBOX_H__ +#define __EM_CORE_IMAP_MAILBOX_H__ + + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +EXPORT_API int em_core_mailbox_check_sync_imap_mailbox(emf_mailbox_t *mailbox, int *synchronous, int *err_code); +/** + * Get mailbox list from imap server. + * + * @param[in] account_id Specifies the account ID. + * @param[in] mailbox Specifies the target mailbox. if NULL, get all mailbox. + * @param[in] callback Specifies the callback function for retrieving mailbox list. + * @param[out] err_code Specifies the error code returned. + * @remarks N/A + * @return This function returns true on success or false on failure. + */ +EXPORT_API int em_core_mailbox_sync_mailbox_list(int account_id, char *mailbox, int *err_code); + +/** + * Download mailbox list from imap server. + * + * @param[in] stream Specifies the internal mail stream. + * @param[in] mailbox Specifies the target mailbox. if NULL, get all mailbox. + * @param[out] mailbox_list The returned mailbox are saved here. + * @param[out] count The count of mailbox is saved here. + * @param[out] err_code Specifies the error code returned. + * @remarks N/A + * @return This function returns true on success or false on failure. + */ +EXPORT_API int em_core_mailbox_download_mailbox_list(void *mail_stream, char *mailbox, emf_mailbox_t **mailbox_list, int *count, int *err_code); +EXPORT_API int em_core_mailbox_delete_imap_mailbox(emf_mailbox_t *mailbox, int *err_code); +EXPORT_API int em_core_mailbox_create_imap_mailbox(emf_mailbox_t *mailbox, int *err_code); +EXPORT_API int em_core_mailbox_modify_imap_mailbox(emf_mailbox_t *old_mailbox, emf_mailbox_t *new_mailbox, int *err_code); +int em_core_mailbox_set_sync_imap_mailbox(emf_mailbox_t *mailbox, int synchronous, int *err_code); +EXPORT_API int em_core_mailbox_set_mail_slot_size(int account_id, char *mailbox_name, int new_slot_size, int *err_code); +EXPORT_API int em_core_mailbox_remove_overflowed_mails(emf_mailbox_tbl_t *intput_mailbox_tbl, int *err_code); +EXPORT_API int em_core_mailbox_get_default_mail_slot_count(int *output_count, int *err_code); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif diff --git a/email-core/include/em-core-mailbox-sync.h b/email-core/include/em-core-mailbox-sync.h new file mode 100755 index 0000000..69625e8 --- /dev/null +++ b/email-core/include/em-core-mailbox-sync.h @@ -0,0 +1,179 @@ +/* +* email-service +* +* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. +* +* Contact: Kyuho Jo <kyuho.jo@samsung.com>, Sunghyun Kwon <sh0701.kwon@samsung.com> +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + + +/****************************************************************************** + * File : em-core-mailbox_sync.h + * Desc : Mail Header Sync Header + * + * Auth : + * + * History : + * 2006.08.16 : created + *****************************************************************************/ +#ifndef __EM_CORE_MAILBOX_SYNC_H__ +#define __EM_CORE_MAILBOX_SYNC_H__ + +#include "emf-types.h" +#include "em-storage.h" + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#if !defined(EXPORT_API) +#define EXPORT_API __attribute__((visibility("default"))) +#endif + +#ifdef __FEATURE_PARTIAL_BODY_DOWNLOAD__ + +#define IMAGE_DISPLAY_PARTIAL_BODY_COUNT 30 +typedef struct +{ + char image_file_name[100]; + char *text_image; + char *content_id; + int dec_len; +} emf_image_data; + +typedef struct +{ + char *buffer; + int buflen; +} emf_partial_buffer; + +#endif + +typedef struct em_core_uid_elem { + int msgno; + char *uid; + emf_mail_flag_t flag; + struct em_core_uid_elem *next; +} em_core_uid_list; + +int pop3_mail_calc_rfc822_size(MAILSTREAM *stream, int msgno, int *size, int *err_code); +int pop3_mailbox_get_uids(MAILSTREAM *stream, em_core_uid_list** uid_list, int *err_code); + +int imap4_mail_calc_rfc822_size(MAILSTREAM *stream, int msgno, int *size, int *err_code); +int imap4_mailbox_get_uids(MAILSTREAM *stream, em_core_uid_list** uid_list, int *err_code); + +/** + * Download unread all headers from mail server. + * + * @param[in] input_mailbox_tbl Specifies the mailbox to contain target mailbox name. + * if the mailbox name is NULL, headers are downloaded from all synchronous mailbox. + * the mailbox name is unused in POP3 case. + * @param[in] input_mailbox_tbl_spam Mailbox information of Spambox for filtering blocked mails. + * @param[in] stream_recycle Stream to reuse. + * @param[out] err_code Specifies the error code returned. + * @remarks N/A + * @return This function returns true on success or false on failure. + */ +EXPORT_API int em_core_mailbox_sync_header(emf_mailbox_tbl_t *input_mailbox_tbl, emf_mailbox_tbl_t *input_mailbox_tbl_spam, void *stream_recycle, em_core_uid_list **input_uid_list, int *unread_mail, int *err_code); + +typedef enum +{ + EM_CORE_GET_UIDS_FOR_NO_DELETE = 0, + EM_CORE_GET_UIDS_FOR_DELETE, +} em_core_get_uids_for_delete_t; +/** + * Download UID list from mail server. + * + * @param[in] mailbox Specifies the mailbox to contain target mailbox name. + * the mailbox name is unused in POP3 case. + * @param[out] uid_list The returned UID list is saved in a memory. this argument points to the list. + * @param[out] total Specifies the count of the uid_list. + * @param[in] read_mail_uids Specifies the array of the uids have the seen flag. + * @param[in] count Specifies the count of read_mail_uids. + * @param[in] for_delete Specifies the flag for deleting. (0 = for downloading or retrieving body, 1 = for deleting message) + * @param[out] err_code Specifies the error code returned. + * @remarks N/A + * @return This function returns true on success or false on failure. + */ +int em_core_mailbox_download_uid_all(emf_mailbox_t *mailbox, + em_core_uid_list **uid_list, + int *total, + emf_mail_read_mail_uid_tbl_t *read_mail_uids, + int count, + em_core_get_uids_for_delete_t for_delete, + int *err_code); + + + +/** + * Search a UID from mail server. this function is supported for only IMAP account. + * + * @param[in] mailbox Specifies the mailbox to contain target mailbox name. + * @param[in] uid Specifies the mail uid. + * @param[out] msgno The message number to be related to uid is saved here. + * @param[out] err_code Specifies the error code returned. + * @remarks N/A + * @return This function returns true on success or false on failure. + */ +int em_core_mailbox_download_imap_msgno(emf_mailbox_t *mailbox, char *uid, int *msgno, int *err_code); + +/** + * Get a message number to be related to uid. + * + * @param[in] uid_list Specifies the uid list. + * @param[in] uid Specifies the mail uid. + * @param[out] msgno The message number to be related to uid is saved here. + * @param[out] err_code Specifies the error code returned. + * @remarks The uid list must be already saved in fpath before this fucntion is called. + * @return This function returns true on success or false on failure. + */ +int em_core_mailbox_get_msgno(em_core_uid_list *uid_list, char *uid, int *msgno, int *err_code); + +/** + * Get a uid to be related to a message number. + * + * @param[in] uid_list Specifies the uid list. + * @param[in] msgno Specifies the message number. + * @param[out] uid The message uid is saved here. + * @param[out] err_code Specifies the error code returned. + * @remarks The uid list must be already saved in fpath before this fucntion is called. + * @return This function returns true on success or false on failure. + */ +int em_core_mailbox_get_uid(em_core_uid_list *uid_list, int msgno, char **uid, int *err_code); + +/** + * free fetch list. + * + * @param[in] uid_list Specifies the fetch data. + * @param[out] err_code Specifies the error code returned. + * @return This function returns true on success or false on failure. + */ +int em_core_mailbox_free_uids(em_core_uid_list *uid_list, int *err_code); + +EXPORT_API int em_core_mail_sync_from_client_to_server(int account_id, int mail_id, int *err_code); +EXPORT_API int em_core_mail_check_rule(emf_mail_head_t *head, emf_mail_rule_tbl_t *rule, int rule_len, int *matched, int *err_code); + +#ifdef __FEATURE_PARTIAL_BODY_DOWNLOAD__ +EXPORT_API int em_core_bulk_partial_mailbody_download(MAILSTREAM *stream, emf_event_partial_body_thd *pbd_event, int count, int *error); +#endif /* __FEATURE_PARTIAL_BODY_DOWNLOAD__ */ + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif diff --git a/email-core/include/em-core-mailbox.h b/email-core/include/em-core-mailbox.h new file mode 100755 index 0000000..9c1066d --- /dev/null +++ b/email-core/include/em-core-mailbox.h @@ -0,0 +1,91 @@ +/* +* email-service +* +* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. +* +* Contact: Kyuho Jo <kyuho.jo@samsung.com>, Sunghyun Kwon <sh0701.kwon@samsung.com> +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + + + +/****************************************************************************** + * File : em-core-mailbox.h + * Desc : Local Mailbox Management Header + * + * Auth : + * + * History : + * 2006.08.16 : created + *****************************************************************************/ +#ifndef __EM_CORE_MAILBOX_H__ +#define __EM_CORE_MAILBOX_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#include "c-client.h" + +#if !defined(EXPORT_API) +#define EXPORT_API __attribute__((visibility("default"))) +#endif + +typedef enum +{ + EM_CORE_STREAM_TYPE_RECV = 0, + EM_CORE_STREAM_TYPE_SEND, +} em_core_stream_type_t; + +#ifdef __FEATURE_KEEP_CONNECTION__ +EXPORT_API int em_core_remove_connection_info(int account_id); +#endif /* __FEATURE_KEEP_CONNECTION__ */ +/* in SMTP case, path argument must be (ENCODED_PATH_SMTP) */ +/* ex) em_core_mailbox_open(xxx, (char *)ENCODED_PATH_SMTP, xxx, xxx); */ +EXPORT_API int em_core_mailbox_open_with_account_info(emf_account_t *ref_account, char *mailbox, void **mail_stream, int *err_code); +EXPORT_API int em_core_mailbox_open(int account_id, char *mailbox, void **mail_stream, int *err_code); +EXPORT_API int em_core_mailbox_close(int account_id, void *mail_stream); +#ifdef __FEATURE_KEEP_CONNECTION__ +EXPORT_API void em_core_close_receiving_stream(); +EXPORT_API void em_core_close_partial_body_stream(); +EXPORT_API void em_core_reset_streams(); +#endif + +EXPORT_API int em_core_mailbox_get_list_to_be_sync(int account_id, emf_mailbox_t **mailbox_list, int *p_count, int *err_code); +EXPORT_API int em_core_mailbox_get_list(int account_id, emf_mailbox_t **mailbox_list, int *p_count, int *err_code); +EXPORT_API int em_core_mailbox_free(emf_mailbox_t **mailbox_list, int count, int *err_code); +EXPORT_API int em_core_mailbox_get_mail_count(emf_mailbox_t *mailbox, int *total, int *unseen, int *err_code); +EXPORT_API int em_core_mailbox_create(emf_mailbox_t *new_mailbox, int on_server, int *err_code); +EXPORT_API int em_core_mailbox_delete(emf_mailbox_t *mailbox, int on_server, int *err_code); +EXPORT_API int em_core_mailbox_delete_all(emf_mailbox_t *mailbox, int *err_code); +EXPORT_API int em_core_mailbox_update(emf_mailbox_t *old_mailbox, emf_mailbox_t *new_mailbox, int *err_code); +EXPORT_API int em_core_save_local_activity_sync(int account_id, int *err_code); +EXPORT_API void em_core_bind_mailbox_type(emf_mailbox_t *mailbox_list); +EXPORT_API int em_core_send_mail_event(emf_mailbox_t *mailbox, int mail_id , int *err_code); +EXPORT_API int em_core_partial_body_thd_local_activity_sync(int *is_event_inserted, int *err_code); +EXPORT_API int em_core_get_mailbox_by_type(int account_id, emf_mailbox_type_e mailbox_type, emf_mailbox_t *spam_mailbox, int *err_code); + +#ifdef __LOCAL_ACTIVITY__ +EXPORT_API int em_core_local_activity_sync(int account_id, int *err_code); +EXPORT_API int em_core_save_local_activity_sync(int account_id, int *err_code); +#endif + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif diff --git a/email-core/include/em-core-mesg.h b/email-core/include/em-core-mesg.h new file mode 100755 index 0000000..b40949a --- /dev/null +++ b/email-core/include/em-core-mesg.h @@ -0,0 +1,232 @@ +/* +* email-service +* +* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. +* +* Contact: Kyuho Jo <kyuho.jo@samsung.com>, Sunghyun Kwon <sh0701.kwon@samsung.com> +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + + +/****************************************************************************** + * File : em-core-mesg.h + * Desc : Mail Operation Header + * + * Auth : + * + * History : + * 2006.08.16 : created + *****************************************************************************/ +#ifndef __EM_CORE_MESSAGE_H__ +#define __EM_CORE_MESSAGE_H__ + +#include "em-storage.h" +#include <contacts-svc.h> + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#if !defined(EXPORT_API) +#define EXPORT_API __attribute__((visibility("default"))) +#endif + +#define HTML_EXTENSION_STRING ".htm" +#define MAX_PATH_HTML 256 + +#ifdef __FEATURE_BULK_DELETE_MOVE_UPDATE_REQUEST_OPTI__ + +#define MAX_SUBSET_STRING_SIZE 260 +#define MAX_IMAP_COMMAND_LENGTH 1000 +#define MAX_TAG_SIZE 16 + + +typedef struct _emf_uid_range_set +{ + char *uid_range; + unsigned long lowest_uid; + unsigned long highest_uid; + + struct _emf_uid_range_set *next; + +} emf_uid_range_set; + +#endif + + +struct _m_content_info +{ + int grab_type; /* 1 : download text and get attachment names (no saving attachment) - #define GRAB_TYPE_TEXT retrieve text and attachment names */ + /* 2 : download attachment - #define GRAB_TYPE_ATTACHMENT retrieve only attachment */ + int file_no; /* attachment no to be download (min : 1) */ + int report; /* 0 : Non 1 : DSN mail 2 : MDN mail 3 : mail to require MDN */ + + struct text_data + { + char *plain; /* body plain text */ + char *plain_charset; /* charset of body text */ + char *html; /* body html text */ + } text; + + struct attachment_info + { + int type; /* 1 : inline 2 : attachment */ + char *name; /* attachment filename */ + int size; /* attachment size */ + char *save; /* content saving filename */ + int drm; /* 0 : none 1 : object 2 : rights 3 : dcf */ + int drm2; /* 0 : none 1 : FL 2 : CD 3 : SSD 4 : SD */ +#ifdef __ATTACHMENT_OPTI__ + int encoding; /* encoding */ + char *section; /* section number */ +#endif + struct attachment_info *next; + } *file; +}; + + +/** + * Download email body from server. + * + * @param[in] mail_stream Specifies the mail_stream. + * @param[in] mailbox Specifies the mailbox to contain account ID. + * @param[in] mail_id Specifies the mail ID. + * @param[in] callback Specifies the callback function for retrieving download status. + * @param[in] with_attach Specifies the flag for downloading attachments. + * @param[in] limited_size Specifies the size to be downloaded. + * @param[out] err_code Specifies the error code returned. + * @remarks In POP3 case, body and attachment are downloaded in this function. + * In IMAP case, body and attachment list are downloaded and + * attachments must be downloaded in em_core_mail_download_attachment. + * @return This function returns true on success or false on failure. + */ + +EXPORT_API int em_core_mail_download_body_multi_sections_bulk(void *mail_stream, int account_id, int mail_id, int verbose, int with_attach, int limited_size, int event_handle , int *err_code); + + +/** + * Download a email nth-attachment from server. + * + * @param[in] mailbox Specifies the mailbox to contain account ID. + * @param[in] mail_id Specifies the mail ID. + * @param[in] nth Specifies the buffer that a attachment number been saved. the minimum number is "1". + * @param[in] callback Specifies the callback function for retrieving download status. + * @param[in] handle Specifies the handle for stopping downloading. + * @param[out] err_code Specifies the error code returned. + * @remarks This function is used for only IMAP mail. + * @return This function returns true on success or false on failure. + */ +EXPORT_API int em_core_mail_download_attachment(int acconut_id, int mail_id, char *nth, int *err_code); + +EXPORT_API int em_core_mail_get_info(int mail_id, emf_mail_info_t **info, int *err_code); +EXPORT_API int em_core_mail_get_header(int mail_id, emf_mail_head_t **head, int *err_code); +EXPORT_API int em_core_mail_get_body(int mail_id, emf_mail_body_t **body, int *err_code); +EXPORT_API int em_core_mail_move(int mail_ids[], int num, char *dst_mailbox_name, int noti_param_1, int noti_param_2, int *err_code); +EXPORT_API int em_core_mail_add_attachment(int mail_id, emf_attachment_info_t *attachment, int *err_code); +EXPORT_API int em_core_mail_delete_attachment(int mail_id, char *attachment_id, int *err_code); +EXPORT_API int em_core_mail_add_attachment_data(int input_mail_id, emf_attachment_data_t *input_attachment_data); + + +#ifdef __FEATURE_PARTIAL_BODY_DOWNLOAD__ +EXPORT_API int em_core_insert_pbd_activity(emf_event_partial_body_thd *local_activity, int *activity_id, int *err_code) ; +EXPORT_API int em_core_delete_pbd_activity(int account_id, int mail_id, int activity_id, int *err_code); +#endif + +EXPORT_API int em_core_mail_get_contact_info(emf_mail_contact_info_t *contact_info, char *full_address, int *err_code); +EXPORT_API int em_core_mail_get_contact_info_with_update(emf_mail_contact_info_t *contact_info, char *full_address, int mail_id, int *err_code); +EXPORT_API int em_core_mail_free_contact_info(emf_mail_contact_info_t *contact_info, int *err_code); +EXPORT_API int em_core_mail_contact_sync(int mail_id, int *err_code); +EXPORT_API GList *em_core_get_recipients_list(GList *old_recipients_list, char *full_address, int *err_code); +EXPORT_API int em_core_mail_get_address_info_list(int mail_id, emf_address_info_list_t **address_info_list, int *err_code); +EXPORT_API int em_core_mail_get_display_name(CTSvalue *contact_name_value, char **contact_display_name); +EXPORT_API int em_core_mail_get_mail(int msgno, emf_mail_t **mail, int *err_code); +EXPORT_API int em_core_get_mail_data(int input_mail_id, emf_mail_data_t **output_mail_data); + +EXPORT_API int em_core_mail_update_old(int mail_id, emf_mail_t *src_mail, emf_meeting_request_t *src_meeting_req, int *err_code); +EXPORT_API int em_core_update_mail(emf_mail_data_t *input_mail_data, emf_attachment_data_t *input_attachment_data_list, int input_attachment_count, emf_meeting_request_t* input_meeting_request, int sync_server); + +EXPORT_API int em_core_fetch_flags(int account_id, int mail_id, emf_mail_flag_t *mail_flag, int *err_code); +EXPORT_API int em_core_mail_delete_from_local(int account_id, int *mail_ids, int num, int noti_param_1, int noti_param_2, int *err_code); +EXPORT_API int em_core_mail_get_msgno_by_uid(emf_account_t *account, emf_mailbox_t *mailbox, char *uid, int *msgno, int *err_code); + +/** + * Delete mails. + * + * @param[in] account_id Specifies the account id. + * @param[in] mail_id Specifies the array for mail id. + * @param[in] num Specifies the number of id. + * @param[in] from_server Specifies whether mails is deleted from server. + * @param[in] callback Specifies the callback function for delivering status during deleting. + * @param[in] noti_param_1 Specifies the first parameter for notification. + * @param[in] noti_param_2 Specifies the second parameter for notification. + * @param[out] err_code Specifies the error code returned. + * @remarks N/A + * @return This function returns true on success or false on failure. + */ +EXPORT_API int em_core_mail_delete(int account_id, int mail_id[], int num, int from_server, int noti_param_1, int noti_param_2, int *err_code); + +/** + * Delete mails. + * + * @param[in] mailbox Specifies the mailbox. this argument is for account id or mailbox name. + * @param[in] with_server Specifies whether mails is also deleted from server. + * @param[in] callback Specifies the callback function for delivering status during deleting. + * @param[out] err_code Specifies the error code returned. + * @remarks N/A + * @return This function returns true on success or false on failure. + */ +EXPORT_API int em_core_mail_delete_all(emf_mailbox_t *mailbox, int with_server, int *err_code); + +EXPORT_API int em_core_mail_info_free(emf_mail_info_t **mail_info_list, int count, int *err_code); +EXPORT_API int em_core_mail_body_free(emf_mail_body_t **mail_body_list, int count, int *err_code); +EXPORT_API int em_core_mail_head_free(emf_mail_head_t **mail_head_list, int count, int *err_code); +EXPORT_API int em_core_mail_free(emf_mail_t **mail_list, int count, int *err_code); +EXPORT_API int em_core_free_mail_data(emf_mail_data_t **mail_list, int count, int *err_code); +EXPORT_API void em_core_mime_free_content_info(struct _m_content_info *cnt_info); +EXPORT_API int em_core_mail_attachment_info_free(emf_attachment_info_t **atch_info, int *err_code); +EXPORT_API int em_core_free_attachment_data(emf_attachment_data_t **attachment_data_list, int attachment_data_count, int *err_code); + +EXPORT_API int em_core_mail_move_from_server(int account_id, char *src_mailbox, int mail_ids[], int num, char *dest_mailbox, int *error_code); +EXPORT_API int em_core_mail_sync_flag_with_server(int mail_id, int *err_code); +EXPORT_API int em_core_mail_sync_seen_flag_with_server(int mail_ids[], int num, int *err_code); +EXPORT_API int em_core_mail_get_attachment(int mail_id, char *attachment_no, emf_attachment_info_t **attachment, int *err_code); +EXPORT_API int em_core_get_attachment_data_list(int input_mail_id, emf_attachment_data_t **output_attachment_data, int *output_attachment_count); +EXPORT_API int em_core_mail_modify_extra_flag(int mail_id, emf_extra_flag_t new_flag, int *err_code); +EXPORT_API int em_core_mail_modify_flag(int mail_id, emf_mail_flag_t new_flag, int sticky_flag, int *err_code); +EXPORT_API int em_core_mail_get_size(int mail_id, int *mail_size, int *err_code); +EXPORT_API int em_core_mail_set_flags_field(int account_id, int mail_ids[], int num, emf_flags_field_type field_type, int value, int *err_code); +EXPORT_API char* em_core_convert_mutf7_to_utf8(char *mailbox_name); +EXPORT_API int em_core_convert_string_to_structure(const char *encoded_string, void **struct_var, emf_convert_struct_type_e type); + +EXPORT_API int em_core_mail_get_info_from_mail_tbl(emf_mail_info_t **pp_mail_info, emf_mail_tbl_t *mail , int *err_code); +EXPORT_API int em_core_mail_get_header_from_mail_tbl(emf_mail_head_t **header, emf_mail_tbl_t *mail , int *err_code); +EXPORT_API int em_core_mail_get_body_from_mail_tbl(emf_mail_body_t **p_body, emf_mail_tbl_t *mail, int *err_code); + + +#ifdef __FEATURE_BULK_DELETE_MOVE_UPDATE_REQUEST_OPTI__ +EXPORT_API int em_core_mail_sync_flags_field_with_server(int mail_ids[], int num, emf_flags_field_type field_type, int value, int *err_code); +EXPORT_API int em_core_mail_move_from_server_ex(int account_id, char *src_mailbox, int mail_ids[], int num, char *dest_mailbox, int *error_code); +#endif + +#ifdef __ATTACHMENT_OPTI__ +EXPORT_API int em_core_mail_download_attachment_bulk(/*emf_mailbox_t *mailbox, */ int account_id, int mail_id, char *nth, int *err_code); +#endif +EXPORT_API int em_core_mail_filter_by_rule(emf_rule_t *filter_info, int *err_code); +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif +/* EOF */ diff --git a/email-core/include/em-core-mime.h b/email-core/include/em-core-mime.h new file mode 100755 index 0000000..f95fd42 --- /dev/null +++ b/email-core/include/em-core-mime.h @@ -0,0 +1,58 @@ +/* +* email-service +* +* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. +* +* Contact: Kyuho Jo <kyuho.jo@samsung.com>, Sunghyun Kwon <sh0701.kwon@samsung.com> +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + + +/****************************************************************************** + * File : em-core-mime.h + * Desc : MIME Operation Header + * + * Auth : + * + * History : + * 2011.04.14 : created + *****************************************************************************/ +#ifndef __EM_CORE_MIME_H__ +#define __EM_CORE_MIME_H__ + +#include "em-core-types.h" +#include "c-client.h" +#include "em-storage.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +char *em_core_mime_get_line_from_file(void *stream, char *buf, int size, int *err_code); +int em_core_mime_parse_mime(void *stream, int is_file, struct _m_content_info *cnt_info, int *err_code); +EXPORT_API int em_core_get_attribute_value_of_body_part(PARAMETER *input_param, char *atribute_name, char *output_value, int output_buffer_length, int with_rfc2047_text, int *err_code); +EXPORT_API int em_core_get_body_part_list_full(MAILSTREAM *stream, int msg_uid, int account_id, int mail_id, BODY *body, struct _m_content_info *cnt_info, int *err_code, PARTLIST * section_list, int event_handle); +EXPORT_API int em_core_get_body(MAILSTREAM *stream, int account_id, int mail_id, int msg_uid, BODY *body, struct _m_content_info *cnt_info, int *err_code); +EXPORT_API int em_core_get_body_structure(MAILSTREAM *stream, int msg_uid, BODY **body, int *err_code); +EXPORT_API char *em_core_decode_rfc2047_text(char *rfc2047_text, int *err_code); +EXPORT_API int em_core_decode_body_text(char *enc_buf, int enc_len, int enc_type, int *dec_len, int *err_code); +EXPORT_API int em_core_set_fetch_body_section(BODY *body, int enable_inline_list, int *total_mail_size, int *err_code); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif +/* EOF */ diff --git a/email-core/include/em-core-smtp.h b/email-core/include/em-core-smtp.h new file mode 100755 index 0000000..e968a77 --- /dev/null +++ b/email-core/include/em-core-smtp.h @@ -0,0 +1,66 @@ +/* +* email-service +* +* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. +* +* Contact: Kyuho Jo <kyuho.jo@samsung.com>, Sunghyun Kwon <sh0701.kwon@samsung.com> +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + + + +/****************************************************************************** + * File : em-core-smtp.h + * Desc : Mail SMTP Header + * + * Auth : + * + * History : + * 2006.08.16 : created + *****************************************************************************/ +#ifndef __EM_CORE_SMTP_H__ +#define __EM_CORE_SMTP_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +/* /#include "emflib.h" */ +#include <stdio.h> +#include "c-client.h" + +#if !defined(EXPORT_API) +#define EXPORT_API __attribute__((visibility("default"))) +#endif + + +EXPORT_API int em_core_mail_send(int account_id, char *mailbox, int mail_id, emf_option_t *sending_option, int *err_code); + +EXPORT_API int em_core_mail_send_saved(int account_id, char *mailbox, emf_option_t *sending_option, int *err_code); + +EXPORT_API int em_core_mail_get_rfc822(emf_mail_t *mail, ENVELOPE **env, char **file_path, emf_option_t *sending_option, int *err_code); + +EXPORT_API int em_core_mail_save(int account_id, char *mailbox_name, emf_mail_t *mail_src, emf_meeting_request_t *meeting_req, int from_composer, int *err_code); + +EXPORT_API int em_core_add_mail(emf_mail_data_t *input_mail_data, emf_attachment_data_t *input_attachment_data_list, int input_attachment_count, emf_meeting_request_t *input_meeting_request, int input_sync_server); + +EXPORT_API int em_core_mail_add_meeting_request(int account_id, char *mailbox_name, emf_meeting_request_t *meeting_req, int *err_code); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif diff --git a/email-core/include/em-core-sound-conflict.h b/email-core/include/em-core-sound-conflict.h new file mode 100755 index 0000000..a56ea74 --- /dev/null +++ b/email-core/include/em-core-sound-conflict.h @@ -0,0 +1,20 @@ +/* +* email-service +* +* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. +* +* Contact: Kyuho Jo <kyuho.jo@samsung.com>, Sunghyun Kwon <sh0701.kwon@samsung.com> +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ diff --git a/email-core/include/em-core-sound.h b/email-core/include/em-core-sound.h new file mode 100755 index 0000000..34fbe1c --- /dev/null +++ b/email-core/include/em-core-sound.h @@ -0,0 +1,71 @@ +/* +* email-service +* +* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. +* +* Contact: Kyuho Jo <kyuho.jo@samsung.com>, Sunghyun Kwon <sh0701.kwon@samsung.com> +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + + +#include <vconf-keys.h> +#include <vconf.h> +#include <mm_player.h> +#include <mm_error.h> +#include <mm_session_private.h> +#include <devman_haptic.h> +#include <alarm.h> + +#define MAX_LENGTH 255 +#define TIMER 7000 +#define HAPTIC_TEST_ITERATION 1 + +void em_core_set_repetition_alarm(int repetition); +int em_core_vibration_destory(); +int em_core_vibration_stop(); +int em_core_sound_mp_player_stop(); +bool em_core_sound_mp_player_destory(); +void *start_alert_thread(void *arg); +EXPORT_API int em_core_alert_loop_start(int *err_code); +EXPORT_API void start_alert(); + +#ifdef Min +#undef Min +#endif + +typedef enum +{ + EMAIL_SOUND_STATUS, + EMAIL_VIBE_STATUS, + EMAIL_ALERT_REP_TYPE, + EMAIL_ALERT_VOLUME, + EMAIL_ALERT_VIBE_STENGTH, +} EMAIL_SETTING_t; + +typedef enum +{ + EMAIL_ALERT_TYPE_MELODY, + EMAIL_ALERT_TYPE_VIB, + EMAIL_ALERT_TYPE_MELODY_AND_VIB, + EMAIL_ALERT_TYPE_MUTE, +} EMAIL_ALERT_TYPE; + +typedef enum +{ + EMAIL_GCONF_VALUE_REPEAT_NONE = 0, + EMAIL_GCONF_VALUE_REPEAT_2MINS, + EMAIL_GCONF_VALUE_REPEAT_5MINS, + EMAIL_GCONF_VALUE_REPEAT_10MINS, +} EMAIL_ALERT_REPEAT_ALARM; diff --git a/email-core/include/em-core-timer.h b/email-core/include/em-core-timer.h new file mode 100755 index 0000000..e64cdbe --- /dev/null +++ b/email-core/include/em-core-timer.h @@ -0,0 +1,52 @@ +/* +* email-service +* +* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. +* +* Contact: Kyuho Jo <kyuho.jo@samsung.com>, Sunghyun Kwon <sh0701.kwon@samsung.com> +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + + + +typedef void (*EMF_TIMER_CALLBACK)(void *a_pData); + +/** + * Callback for timeout action + * + * @param[in] a_pData Specifies the data passed to callback. + * @return This function returns true for repeat alerts or false for mail resend. + */ +EXPORT_API int em_core_timer_ex_callback(void *a_pData); + +/** + * Set timer + * + * @param[in] a_nSetTimeValue Specifies the timeout value. + * @param[in] a_pCallBack Specifies the Callback to be called on timeout + * @param[in] a_pData Specifies the pointer to user data to be passed to Callback. + * @remarks N/A + * @return This function returns the timer id. + */ +EXPORT_API int em_core_set_timer_ex(long a_nSetTimeValue, EMF_TIMER_CALLBACK a_pCallBack, void *a_pData); + +/** + * Kill timer. + * + * @param[in] a_nTimerID Specifies the timer id. + * @remarks N/A + * @return This function returns void. + */ +EXPORT_API void em_core_kill_timer_ex(int a_nTimerID); diff --git a/email-core/include/em-core-types.h b/email-core/include/em-core-types.h new file mode 100755 index 0000000..a115cc5 --- /dev/null +++ b/email-core/include/em-core-types.h @@ -0,0 +1,320 @@ +/* +* email-service +* +* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. +* +* Contact: Kyuho Jo <kyuho.jo@samsung.com>, Sunghyun Kwon <sh0701.kwon@samsung.com> +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + + +/****************************************************************************** + * File : em-core-types.h + * Desc : defines data structures and macros + * + * Auth : + * + * History : + * 2011.04.05 : created + *****************************************************************************/ +#ifndef __EM_CORE_TYPES_H__ +#define __EM_CORE_TYPES_H__ + +#include <pthread.h> +#include "emf-types.h" + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplu */ + +#if !defined(EXPORT_API) +#define EXPORT_API __attribute__((visibility("default"))) +#endif + +/* ----------------------------------------------------------------------------- */ +/* Feature definitions */ +#define __FEATURE_USING_MY_ACCOUNT__ +#define __FEATURE_BACKUP_ACCOUNT__ +#define __FEATURE_MOVE_TO_OUTBOX_FIRST__ +/* #define __FEATURE_PARTIAL_BODY_FOR_POP3__ */ +/* #define __FEATURE_KEEP_CONNECTION__ */ +#define __FEATURE_DRM__ +#define __FEATURE_PARTIAL_BODY_DOWNLOAD__ +#define __FEATURE_HEADER_OPTIMIZATION__ +#define __FEATURE_SEND_OPTMIZATION__ +#define __FEATURE_DOWNLOAD_BODY_ATTACHMENT_OPTIMIZATION__ +#define __FEATURE_BULK_DELETE_MOVE_UPDATE_REQUEST_OPTI__ +#define __FEATURE_SYNC_CLIENT_TO_SERVER__ +#define __FEATURE_PROGRESS_IN_OUTBOX__ +#define __FEATURE_AUTO_POLLING__ +#define __FEATURE_DEBUG_LOG__ +#define __FEATURE_USE_PTHREAD__ +#define __FEATURE_USE_SHARED_MUTEX_FOR_GENERATING_MAIL_ID__ +/* #define __FEATURE_USE_SHARED_MUTEX_FOR_PROTECTED_FUNC_CALL__ */ +#define __FEATURE_SUPPORT_ACTIVE_SYNC__ + +#define __HEADER_OPTIMIZATION__ /* Will be removed */ +#define __DOWNLOAD_BODY_ATTACHMENT_OPTIMIZATION__ /* Will be removed */ + +/* ----------------------------------------------------------------------------- */ +/* Macro */ +#ifndef NULL +#define NULL (char *)0 +#endif + +#define SESSION_MAX 5 +#define IMAP_2004_LOG 1 +#define TEXT_SIZE 161 +#define MAILBOX_COUNT 6 +#define PARTIAL_DOWNLOAD_SIZE 1024 +#define PARTIAL_BODY_SIZE_IN_BYTES 15360 /* Partial Body download - 15K */ +#define NO_LIMITATION 0 +#define MAX_MAILBOX_TYPE 100 +#define EMF_SYNC_ALL_MAILBOX 1 +#define EMF_ATTACHMENT_MAX_COUNT 512 +#define DOWNLOAD_MAX_BUFFER_SIZE 8000 +#define LOCAL_MAX_BUFFER_SIZE 1000000 +#define IMAP_MAX_COMMAND_LENGTH 1000 +#define DOWNLOAD_NOTI_INTERVAL_PERCENT 5 /* notify every 5% */ +#define DOWNLOAD_NOTI_INTERVAL_SIZE 51200 /* notify every 50k */ +#define MAX_PATH 4096 /* /usr/src/linux-2.4.20-8/include/linux/limits.h */ +#define DATETIME_LENGTH 16 +#define MAIL_ID_STRING_LENGTH 10 + +#define DIR_SEPERATOR "/" + +#define DATA_PATH "/opt/data" +#define DB_PATH "/opt/dbspace" +#define EMAIL_SERVICE_DB_FILE_PATH "/opt/dbspace/.email-service.db" + +#define VCONF_KEY_LAST_SYNC_TIME "db/email/last_sync_time" +#define VCONF_KEY_DEFAULT_SLOT_SIZE "db/email/slot_size" +#define VCONF_KEY_LATEST_MAIL_ID "db/email/latest_mail_id" +#define VCONF_KEY_DEFAULT_ACCOUNT_ID "db/email/defaultaccount" +#define VCONF_KEY_UNREAD_MAIL_COUNT "db/badge/com.samsung.email" + +#define MIME_SUBTYPE_DRM_OBJECT "vnd.oma.drm.message" +#define MIME_SUBTYPE_DRM_RIGHTS "vnd.oma.drm.rights+xml" +#define MIME_SUBTYPE_DRM_DCF "vnd.oma.drm.dcf" + +#define SHM_FILE_FOR_DB_LOCK "/.email_shm_db_lock" + +#ifdef __FEATURE_USE_SHARED_MUTEX_FOR_GENERATING_MAIL_ID__ +#define SHM_FILE_FOR_MAIL_ID_LOCK "/.email_shm_mail_id_lock" +#endif /* __FEATURE_USE_SHARED_MUTEX_FOR_GENERATING_MAIL_ID__ */ + +#define CR '\r' +#define LF '\n' +#define SPACE ' ' +#define TAB '\t' +#define NULL_CHAR '\0' +#define TAB_STRING "\t" +#define CR_STRING "\r" +#define LF_STRING "\n" +#define CRLF_STRING "\r\n" + +#define SYNC_STATUS_FINISHED 0 /* BIN 00000000 */ +#define SYNC_STATUS_SYNCING 1 /* BIN 00000001 */ +#define SYNC_STATUS_HAVE_NEW_MAILS 2 /* BIN 00000010 */ + +#define GRAB_TYPE_TEXT 1 /* retrieve text and attachment list */ +#define GRAB_TYPE_ATTACHMENT 2 /* retrieve attachment */ + +#define SAVE_TYPE_SIZE 1 /* only get content size */ +#define SAVE_TYPE_BUFFER 2 /* save content to buffer */ +#define SAVE_TYPE_FILE 3 /* save content to temporary file */ + +#define FINISH_OFF_IF_CANCELED if (!em_core_check_thread_status()) { err = EMF_ERROR_CANCELLED; goto FINISH_OFF; } +#define CHECK_JOB_CANCELED() {if (!em_core_check_thread_status()) goto JOB_CANCEL; } + +#define SNPRINTF(buff, size, format, args...) snprintf(buff, size, format, ##args) +#define SNPRINTF_OFFSET(base_buf, offset, base_size, format, args...) \ + ({\ + int _offset = offset;\ + snprintf(base_buf + _offset, base_size - _offset - 1, format, ##args);\ + }) + +#ifdef __FEATURE_USE_PTHREAD__ +#define THREAD_CREATE(tv, func, param, err) { EM_DEBUG_LOG("THREAD_CREATE "#tv); err = pthread_create(&tv, NULL, func, param); } +#define THREAD_CREATE_JOINABLE(tv, func, err) { pthread_attr_t attr; EM_DEBUG_LOG("THREAD_CREATE_JOINABLE "#tv); \ + pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);\ + err = pthread_create(&tv, &attr, func, NULL); pthread_attr_destroy(&attr); } +#define THREAD_JOIN(tv) {EM_DEBUG_LOG("THREAD_JOIN "#tv); pthread_join(tv, NULL); } +#define THREAD_SELF() pthread_self() +#define THREAD_DETACH(tv) pthread_detach(tv) +#define INITIALIZE_CRITICAL_SECTION(cs) {EM_DEBUG_LOG("INITIALIZE_CRITICAL_SECTION "#cs); pthread_mutex_init(&cs, NULL); } +#define ENTER_CRITICAL_SECTION(cs) {EM_DEBUG_LOG("ENTER_CRITICAL_SECTION "#cs); pthread_mutex_lock(&cs); } +#define TRY_ENTER_CRITICAL_SECTION(cs) {EM_DEBUG_LOG("TRY_ENTER_CRITICAL_SECTION "#cs); pthread_mutex_trylock(&cs); } +#define LEAVE_CRITICAL_SECTION(cs) {EM_DEBUG_LOG("LEAVE_CRITICAL_SECTION "#cs); pthread_mutex_unlock(&cs); } +#define DELETE_CRITICAL_SECTION(cs) {EM_DEBUG_LOG("DELETE_CRITICAL_SECTION "#cs); pthread_mutex_destroy(&cs); } + +#define INITIALIZE_CONDITION_VARIABLE(cv) {EM_DEBUG_LOG("INITIALIZE_CONDITION_VARIABLE "#cv); pthread_cond_init(&cv, NULL); } +#define SLEEP_CONDITION_VARIABLE(cv, cs) {EM_DEBUG_LOG("SLEEP_CONDITION_VARIABLE "#cv); pthread_cond_wait(&cv, &cs); } +#define WAKE_CONDITION_VARIABLE(cv) {EM_DEBUG_LOG("WAKE_CONDITION_VARIABLE "#cv); pthread_cond_signal(&cv); } +#define DELETE_CONDITION_VARIABLE(cv) {EM_DEBUG_LOG("DELETE_CONDITION_VARIABLE "#cv); pthread_cond_destroy(&cv); } + +#define INITIALIZE_RECURSIVE_CRITICAL_SECTION(cs) { EM_DEBUG_LOG("INITIALIZE_RECURSIVE_CRITICAL_SECTION "#cs); \ + if (cs == NULL) {pthread_mutex_lock(&_send_event_available_lock); pthread_mutexattr_t attr; cs = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t));\ + pthread_mutexattr_init(&attr); pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP);\ + pthread_mutex_init(cs, &attr);pthread_mutexattr_destroy(&attr); pthread_mutex_unlock(&_send_event_available_lock);}} +#define ENTER_RECURSIVE_CRITICAL_SECTION(cs) {EM_DEBUG_LOG("ENTER_RECURSIVE_CRITICAL_SECTION "#cs); if(cs) pthread_mutex_lock(cs);} +#define TRY_ENTER_RECURSIVE_CRITICAL_SECTION(cs) {EM_DEBUG_LOG("TRY_ENTER_RECURSIVE_CRITICAL_SECTION "#cs); if(cs) pthread_mutex_trylock(cs);} +#define LEAVE_RECURSIVE_CRITICAL_SECTION(cs) {EM_DEBUG_LOG("LEAVE_RECURSIVE_CRITICAL_SECTION "#cs); if(cs) pthread_mutex_unlock(cs);} +#define DELETE_RECURSIVE_CRITICAL_SECTION(cs) {EM_DEBUG_LOG("DELETE_RECURSIVE_CRITICAL_SECTION "#cs); if(cs) pthread_mutex_destroy(cs);} +typedef pthread_t thread_t; +#else /* __FEATURE_USE_PTHREAD__ */ +#define THREAD_CREATE(tv, func, param, err) {EM_DEBUG_LOG("THREAD_CREATE "#tv); tv = g_thread_create(func, param, FALSE, NULL); if (tv == NULL) err = -1; else err = 0; } +#define THREAD_CREATE_JOINABLE(tv, func, err) {EM_DEBUG_LOG("THREAD_CREATE_JOINABLE "#tv); tv = g_thread_create(func, NULL, TRUE, NULL); if (tv == NULL) err = -1; else err = 0; } +#define THREAD_JOIN(tv) {EM_DEBUG_LOG("THREAD_JOIN "#tv); g_thread_join(tv); } +#define THREAD_SELF() g_thread_self() +#define INITIALIZE_CRITICAL_SECTION(cs) {EM_DEBUG_LOG("INITIALIZE_CRITICAL_SECTION "#cs); if (cs == NULL) cs = g_mutex_new(); } +#define ENTER_CRITICAL_SECTION(cs) {EM_DEBUG_LOG("ENTER_CRITICAL_SECTION "#cs); if (cs) g_mutex_lock(cs); } +#define TRY_ENTER_CRITICAL_SECTION(cs) {EM_DEBUG_LOG("TRY_ENTER_CRITICAL_SECTION "#cs); if (cs) g_mutex_trylock(cs); } +#define LEAVE_CRITICAL_SECTION(cs) {EM_DEBUG_LOG("LEAVE_CRITICAL_SECTION "#cs); if (cs) g_mutex_unlock(cs); } +#define DELETE_CRITICAL_SECTION(cs) {EM_DEBUG_LOG("DELETE_CRITICAL_SECTION "#cs); if (cs) g_mutex_free(cs); cs = NULL; } + +#define INITIALIZE_CONDITION_VARIABLE(cv) {EM_DEBUG_LOG("INITIALIZE_CONDITION_VARIABLE "#cv); if (cv == NULL) cv = g_cond_new(); } +#define SLEEP_CONDITION_VARIABLE(cv, cs) {EM_DEBUG_LOG("SLEEP_CONDITION_VARIABLE "#cv); if (cv) g_cond_wait(cv, cs); } +#define WAKE_CONDITION_VARIABLE(cv) {EM_DEBUG_LOG("WAKE_CONDITION_VARIABLE "#cv); if (cv) g_cond_signal(cv); } +#define DELETE_CONDITION_VARIABLE(cv) {EM_DEBUG_LOG("DELETE_CONDITION_VARIABLE "#cv); if (cv) g_cond_free(cv); cv = NULL; } + +#define INITIALIZE_RECURSIVE_CRITICAL_SECTION(cs) {EM_DEBUG_LOG("INITIALIZE_RECURSIVE_CRITICAL_SECTION "#cs); g_static_rec_mutex_init(&cs); } +#define ENTER_RECURSIVE_CRITICAL_SECTION(cs) {EM_DEBUG_LOG("ENTER_RECURSIVE_CRITICAL_SECTION "#cs); g_static_rec_mutex_lock(&cs); } +#define TRY_ENTER_RECURSIVE_CRITICAL_SECTION(cs) {EM_DEBUG_LOG("TRY_ENTER_RECURSIVE_CRITICAL_SECTION "#cs); g_static_rec_mutex_trylock(&cs); } +#define LEAVE_RECURSIVE_CRITICAL_SECTION(cs) {EM_DEBUG_LOG("LEAVE_RECURSIVE_CRITICAL_SECTION "#cs); g_static_rec_mutex_unlock(&cs); } +#define DELETE_RECURSIVE_CRITICAL_SECTION(cs) {EM_DEBUG_LOG("DELETE_RECURSIVE_CRITICAL_SECTION "#cs); g_static_rec_mutex_free(&cs); } +typedef GThread* thread_t; +#endif /* __FEATURE_USE_PTHREAD__ */ + +#define SMTP_RESPONSE_OK 250 +#define SMTP_RESPONSE_READY 354 +#define SMTP_RESPONSE_WANT_AUTH 505 +#define SMTP_RESPONSE_WANT_AUTH2 530 +#define SMTP_RESPONSE_UNAVAIL 550 +/* ----------------------------------------------------------------------------- */ +/* Type */ +typedef enum +{ + _SERVICE_THREAD_TYPE_NONE = 0, + _SERVICE_THREAD_TYPE_RECEIVING = 1, + _SERVICE_THREAD_TYPE_SENDING = 2, +#ifdef __FEATURE_PARTIAL_BODY_DOWNLOAD__ + _SERVICE_THREAD_TYPE_PBD = 3, +#endif /* __FEATURE_PARTIAL_BODY_DOWNLOAD__ */ +} emf_service_thread_type; + + +typedef enum +{ + EMF_PROTOCOL_POP3 = 1, + EMF_PROTOCOL_IMAP, + EMF_PROTOCOL_SMTP, + EMF_PROTOCOL_NONE = 0, +} emf_protocol_type_t; + +#ifdef __FEATURE_KEEP_CONNECTION__ +enum +{ + EMF_STREAM_STATUS_DISCONNECTED = 0, + EMF_STREAM_STATUS_CONNECTED = 1 +} ; +#endif /* __FEATURE_KEEP_CONNECTION__ */ + +/* event information */ +typedef struct +{ + int account_id; /* in general, account id */ + emf_event_type_t type; + emf_event_status_type_t status; + char *event_param_data_1; /* in general, mailbox name (exception in em_core_mail_send, em_core_mail_send_saved it is emf_option_t **/ + char *event_param_data_2; + char *event_param_data_3; + int event_param_data_4; + int event_param_data_5; + int event_param_data_6; /* in general, notification parameter #1 */ + int event_param_data_7; /* in general, notification parameter #2 */ +} emf_event_t; + + +typedef struct +{ + int num; + void *data; +} emf_callback_holder_t; + + +typedef struct emf_search_key_t emf_search_key_t; +struct emf_search_key_t +{ + int type; + char *value; + emf_search_key_t *next; +}; + +typedef struct +{ + int tid; + emf_protocol_type_t protocol; + void *stream; + int auth; + int network; + int error; + int status; +} emf_session_t; + +#ifdef __FEATURE_KEEP_CONNECTION__ + +typedef struct emf_connection_info +{ + int account_id; + int sending_server_stream_status; + void *sending_server_stream; + int receiving_server_stream_status; + void *receiving_server_stream; + struct emf_connection_info *next; +} emf_connection_info_t; +#endif /* __FEATURE_KEEP_CONNECTION__ */ + +typedef void (*emf_event_callback)(int total, int done, int status, int account_id, int mail_id, int handle, void *user_data, int error); + +/* ----------------------------------------------------------------------------- */ +/* Please contact Himanshu [h.gahlaut@samsung.com] for any explanation in code here under __FEATURE_PARTIAL_BODY_DOWNLOAD__ MACRO */ +#ifdef __FEATURE_PARTIAL_BODY_DOWNLOAD__ +typedef enum +{ + ACTIVITY_PARTIAL_BODY_DOWNLOAD_IMAP4 = 1, + ACTIVITY_PARTIAL_BODY_DOWNLOAD_POP3_WAIT, + ACTIVITY_PARTIAL_BODY_DOWNLOAD_POP3_ACTIVE +} emf_pdb_activity_type_e; + +typedef struct +{ + int account_id; + int mail_id; + unsigned long server_mail_id; + int activity_id; + char *mailbox_name; + emf_event_type_t event_type; /* Event Type Null means event is created from local activitys */ + int activity_type; /* Activity Type Null means event is created from event queue */ + +} emf_event_partial_body_thd; +#endif /* __FEATURE_PARTIAL_BODY_DOWNLOAD__ */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __EM_CORE_TYPES_H_ */ diff --git a/email-core/include/em-core-utils.h b/email-core/include/em-core-utils.h new file mode 100755 index 0000000..1dda87f --- /dev/null +++ b/email-core/include/em-core-utils.h @@ -0,0 +1,217 @@ +/* +* email-service +* +* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. +* +* Contact: Kyuho Jo <kyuho.jo@samsung.com>, Sunghyun Kwon <sh0701.kwon@samsung.com> +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + + +/****************************************************************************** + * File : em-core-utils.h + * Desc : Mail Utils Header + * + * Auth : + * + * History : + * 2006.08.16 : created + *****************************************************************************/ +#ifndef __EM_CORE_UTILS_H__ +#define __EM_CORE_UTILS_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#include "emf-types.h" +#include "em-storage.h" +#include "em-core-global.h" +#include "em-core-mesg.h" +#ifdef __FEATURE_BULK_DELETE_MOVE_UPDATE_REQUEST_OPTI__ +#include "em-core-mesg.h" +#endif + +#if !defined(EXPORT_API) +#define EXPORT_API __attribute__((visibility("default"))) +#endif + +/* This is used for em_core_get_long_encoded_path */ +#define ENCODED_PATH_SMTP "UHDF_ENCODED_PATH_SMTP_EKJD" + +typedef int (*emf_get_unread_email_count_cb)(int unread, int *err_code); + +/* parse the Full mailbox Path and get the Alias Name of the Mailbox */ +char *em_core_get_alias_of_mailbox(const char *mailbox_path); + +/* Parse the Mailbox Path and get the Account Email address */ +EXPORT_API emf_option_t *em_core_get_option(int *err_code); +EXPORT_API int em_core_set_option(emf_option_t *opt, int *err_code); +int em_core_upper_path(char *path); +int em_core_upper_string(char *str); +int em_core_get_temp_file_name(char **filename, int *err_code); +int em_core_get_long_encoded_path(int account_id, char *path, int delimiter, char **long_enc_path, int *err_code); +int em_core_get_encoded_mailbox_name(char *name, char **enc_name, int *err_code); +int em_core_get_file_name(char *path, char **filename, int *err_code); +int em_core_get_file_size(char *path, int *size, int *err_code); +int em_core_get_mail_size(emf_mail_t *mail_src, int *error_code); +int em_core_calc_mail_size(emf_mail_data_t *mail_data_src, emf_attachment_data_t *attachment_data_src, int attachment_count, int *error_code); +int em_core_get_actual_mail_size(char *pBodyPlane, char *pBodyHtml, struct attachment_info *pAttachment, int *error_code); +int em_core_get_address_count(char *addr_str, int *to_num, int *err_code); + +void em_core_skip_whitespace(char *addr_str , char **pAddr); +EXPORT_API char *em_core_skip_whitespace_without_strdup(char *source_string); +EXPORT_API char* em_core_replace_string(char *source_string, char *old_string, char *new_string); +EXPORT_API int em_core_set_network_error(int err_code); +EXPORT_API int em_core_check_unread_mail(); +int em_core_is_storage_full(int *error); +int em_core_show_popup(int id, emf_action_t action, int error); +int em_core_get_long_encoded_path_with_account_info(emf_account_t *account, char *path, int delimiter, char **long_enc_path, int *err_code); +EXPORT_API int em_storage_get_emf_error_from_em_storage_error(int error); +EXPORT_API int em_core_open_contact_db_library(void); +EXPORT_API void em_core_close_contact_db_library(); +EXPORT_API void em_core_flush_memory(); +EXPORT_API int em_core_get_server_time(void *mail_stream , int account_id, char *uid, int msgno, time_t *log_time, int *err_code); +EXPORT_API void em_core_fill_address_information_of_mail_tbl(emf_mail_tbl_t *mail_data); +EXPORT_API int em_core_add_transaction_info(int mail_id , int handle , int *err_code); +EXPORT_API int em_core_get_handle_by_mailId_from_transaction_info(int mail_id , int *pHandle); +EXPORT_API int em_core_delete_transaction_info_by_mailId(int mail_id); +EXPORT_API int em_core_get_preview_text_from_file(const char *input_plain_path, const char *input_html_path, int input_preview_buffer_length, char **output_preview_buffer); +EXPORT_API int em_core_strip_HTML(char *source_string); +EXPORT_API int em_core_send_noti_for_new_mail(int account_id, char *mailbox_name, char *subject, char *from, char *uid, char *datetime); +EXPORT_API int em_core_find_pos_stripped_subject_for_thread_view(char *subject, char *stripped_subject); +EXPORT_API int em_core_find_tag_for_thread_view(char *subject, int *result); +EXPORT_API int em_core_check_send_mail_thread_status(); +EXPORT_API int em_core_make_attachment_file_name_with_extension(char *source_file_name, char *sub_type, char *result_file_name, int result_file_name_buffer_length, int *err_code); +EXPORT_API char *em_core_get_extension_from_file_path(char *source_file_path, int *err_code); +EXPORT_API int em_core_get_encoding_type_from_file_path(const char *input_file_path, char **output_encoding_type); +EXPORT_API int em_core_get_content_type(const char *extension_string, int *err_code); +EXPORT_API char* em_core_get_current_time_string(int *err_code); + + +/* Session Handling */ +EXPORT_API int em_core_get_empty_session(emf_session_t **session); +EXPORT_API int em_core_clear_session(emf_session_t *session); +EXPORT_API int em_core_get_current_session(emf_session_t **session); + +/* For notification */ +EXPORT_API int em_core_update_notification_for_unread_mail(int account_id); +EXPORT_API int em_core_clear_all_notifications(); +EXPORT_API int em_core_add_notification_for_unread_mail_by_mail_header(int account_id, int mail_id, emf_mail_head_t *mail_header); +EXPORT_API int em_core_add_notification_for_unread_mail(emf_mail_data_t *input_mail_data); +EXPORT_API int em_core_delete_notification_for_read_mail(int mail_id); +EXPORT_API int em_core_delete_notification_by_account(int account_id); +EXPORT_API int em_core_finalize_sync(int account_id, int *error); + +EXPORT_API int em_core_verify_email_address(char *address, int without_bracket, int *err_code); +EXPORT_API int em_core_verify_email_address_of_mail_header(emf_mail_head_t *mail_header, int without_bracket, int *err_code); +EXPORT_API int em_core_verify_email_address_of_mail_data(emf_mail_data_t *mail_data, int without_bracket, int *err_code); + + +#ifdef __FEATURE_BULK_DELETE_MOVE_UPDATE_REQUEST_OPTI__ + +/** + * @fn em_core_convert_to_uid_range_set(emf_id_set_t *id_set, int id_set_count, emf_uid_range_set **uid_range_set, int range_len, int *err_code) + * Prepare a linked list of uid ranges with each node having a uid_range and lowest and highest uid in it. + * + *@author h.gahlaut@samsung.com + * @param[in] id_set Specifies the array of mail_id and corresponding server_mail_id sorted by server_mail_ids in ascending order + * @param[in] id_set_count Specifies the no. of cells in id_set array i.e. no. of sets of mail_ids and server_mail_ids + * @param[in] range_len Specifies the maximum length of string of range allowed. + * @param[out] uid_range_set Returns the uid_ranges formed in the form of a linked list with head stored in uid_range_set pointer + * @param[out] err_code Returns the error code. + * @remarks An example of a uid_range formed is 2 : 6, 8, 10, 14 : 15, 89, + * While using it the caller should remove the ending , (comma) + * @return This function returns true on success or false on failure. + */ + +EXPORT_API int em_core_convert_to_uid_range_set(emf_id_set_t *id_set, int id_set_count, emf_uid_range_set **uid_range_set, int range_len, int *err_code); + +/** + * void em_core_free_uid_range_set(emf_uid_range_set **uid_range_head) + * Frees the linked list of uid ranges + * + * @author h.gahlaut@samsung.com + * @param[in] uid_range_head Head pointer of linked list of uid ranges + * @remarks + * @return This function does not return anything. + */ +EXPORT_API void em_core_free_uid_range_set(emf_uid_range_set **uid_range_set); + +/** + * @fn em_core_append_subset_string_to_uid_range(char *subset_string, emf_uid_range_set **uid_range_set, int range_len, unsigned long luid, unsigned long huid) + * Appends the subset_string to uid range if the uid range has not exceeded maximum length(range_len), otherwise creates a new node in linked list of uid range set + * and stores the subset_string in its uid_range. Also sets the lowest and highest uids for the corresponsing uid_range + * + * @author h.gahlaut@samsung.com + * @param[in] subset_string Specifies the subset string to be appended. A subset string can be like X : Y or X where X and Y are uids. + * @param[in] range_len Specifies the maximum length of range string allowed. + * @param[in] luid Specifies the lowest uid in subset string + * @param[in] huid Specifies the highest uid in subset string + * @param[out] uid_range_set Returns the uid_ranges formed in the form of a linked list with head stored in uid_range_set pointer + * @param[out] err_code Returns the error code. + * @remarks + * @return This function returns true on success or false on failure. + */ + +int em_core_append_subset_string_to_uid_range(char *subset_string, emf_uid_range_set **current_node_adr, emf_uid_range_set **uid_range_set, int range_len, unsigned long luid, unsigned long huid); + +/** + * @fn em_core_form_comma_separated_strings(int numbers[], int num_count, int max_string_len, char ***strings, int *string_count, int *err_code) + * Forms comma separated strings of a give max_string_len from an array of numbers + * + * @author h.gahlaut@samsung.com + * @param[in] numbers Specifies the array of numbers to be converted into comma separated strings. + * @param[in] num_count Specifies the count of numbers in numbers array. + * @param[in] max_string_len Specifies the maximum length of comma separated strings that are to be formed. + * @param[out] strings Returns the base address of a double dimension array which stores the strings. + * @param[out] string_count Returns the number of strings formed. + * @param[out] err_code Returns the error code. + * @remarks If Input to the function is five numbers like 2755 2754 2748 2749 2750 and a given max_string_len is 20. + * Then this function will form two comma separated strings as follows - + * "2755, 2754, 2748" + * "2749, 2750" + * @return This function returns true on success or false on failure. + */ +EXPORT_API int em_core_form_comma_separated_strings(int numbers[], int num_count, int max_string_len, char ***strings, int *string_count, int *err_code); + +/** + * @fn em_core_free_comma_separated_strings(char ***string_list, int *string_count) + * Frees the double dimensional array of strings. + * + * @author h.gahlaut@samsung.com + * @param[in] uid_range_head Address of base address of double dimensional array of strings. + * @param[in] string_count Address of variable holding the count of strings. + * @remarks + * @return This function does not return anything. + */ + +EXPORT_API void em_core_free_comma_separated_strings(char ***string_list, int *string_count); + +#endif + +#ifdef __LOCAL_ACTIVITY__ +/* Added to get next activity id sequence */ +EXPORT_API int em_core_get_next_activity_id(int *activity_id, int *err_code); +EXPORT_API int em_core_activity_add(emf_activity_tbl_t *new_activity, int *err_code); +EXPORT_API int em_core_activity_delete(emf_activity_tbl_t *activity, int *err_code); +#endif /* __LOCAL_ACTIVITY__ */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __EM_CORE_UTILS_H__ */ |