From 23e973d6909d0785f0fe6a4659490ad428675648 Mon Sep 17 00:00:00 2001 From: Sunghyun Kwon Date: Mon, 6 Jul 2015 10:47:48 +0900 Subject: [PATCH] Missing files Change-Id: I1c5df65a0556864a3dff8244fc4985be4f47be1b --- LICENSE | 227 + email-core/email-core-auto-download.c | 820 ++++ email-core/email-core-container.c | 419 ++ email-core/email-core-gmime.c | 5046 ++++++++++++++++++++ email-core/email-core-pgp.c | 797 ++++ email-core/include/email-core-auto-download.h | 59 + email-core/include/email-core-container.h | 45 + email-core/include/email-core-gmime.h | 84 + email-core/include/email-core-pgp.h | 50 + utilities/test-application/include/testapp-gmime.h | 31 + utilities/test-application/testapp-gmime.c | 189 + 11 files changed, 7767 insertions(+) create mode 100755 LICENSE create mode 100755 email-core/email-core-auto-download.c create mode 100644 email-core/email-core-container.c create mode 100755 email-core/email-core-gmime.c create mode 100644 email-core/email-core-pgp.c create mode 100755 email-core/include/email-core-auto-download.h create mode 100644 email-core/include/email-core-container.h create mode 100644 email-core/include/email-core-gmime.h create mode 100644 email-core/include/email-core-pgp.h create mode 100755 utilities/test-application/include/testapp-gmime.h create mode 100644 utilities/test-application/testapp-gmime.c diff --git a/LICENSE b/LICENSE new file mode 100755 index 0000000..7d6a5a6 --- /dev/null +++ b/LICENSE @@ -0,0 +1,227 @@ +Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved. + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. + +------------------------------------------------------------------------------- +Copyright (c) 2005-2010, Troy D. Hanson http://tpl.sourceforge.net +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER +OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + diff --git a/email-core/email-core-auto-download.c b/email-core/email-core-auto-download.c new file mode 100755 index 0000000..5e4d1d3 --- /dev/null +++ b/email-core/email-core-auto-download.c @@ -0,0 +1,820 @@ +/* +* email-service +* +* Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved. +* +* Contact: Minsoo Kim , Kyuho Jo , +* Sunghyun Kwon +* +* 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 +#include +#include +#include +#include +#include "email-storage.h" +#include "email-utilities.h" +#include "email-daemon.h" +#include "email-network.h" +#include "email-core-global.h" +#include "email-core-account.h" +#include "email-core-event.h" +#include "email-core-utils.h" +#include "email-core-mailbox.h" +#include "email-core-imap-mailbox.h" +#include "email-core-mail.h" +#include "email-core-mailbox-sync.h" +#include "email-core-smtp.h" +#include "email-core-utils.h" +#include "email-debug-log.h" +#include "email-types.h" +#include "email-internal-types.h" +#include "email-core-auto-download.h" + +/*----------------------------------------------------------------------------- + * Auto Download Event Queue + *---------------------------------------------------------------------------*/ +INTERNAL_FUNC thread_t g_auto_download_thread; +INTERNAL_FUNC pthread_cond_t _auto_downalod_available_signal = PTHREAD_COND_INITIALIZER; +INTERNAL_FUNC pthread_mutex_t *_auto_download_queue_lock = NULL; + +INTERNAL_FUNC GQueue *g_auto_download_que = NULL; +INTERNAL_FUNC int g_auto_download_loop = 1; +INTERNAL_FUNC int auto_download_thread_run = 0; + +#define AUTO_DOWNLOAD_QUEUE_MAX 100 + +static void* worker_auto_download_queue(void *arg); + +INTERNAL_FUNC int emcore_start_auto_download_loop(int *err_code) +{ + EM_DEBUG_FUNC_BEGIN(); + int thread_error; + + if (err_code != NULL) + *err_code = EMAIL_ERROR_NONE; + + if (g_auto_download_thread) { + EM_DEBUG_EXCEPTION("auto downlaod thread is already running..."); + if (err_code != NULL) + *err_code = EMAIL_ERROR_UNKNOWN; + return true; + } + + g_auto_download_que = g_queue_new(); + g_queue_init(g_auto_download_que); + g_auto_download_loop = 1; + + /* initialize lock */ + INITIALIZE_RECURSIVE_CRITICAL_SECTION(_auto_download_queue_lock); + + /* create thread */ + THREAD_CREATE(g_auto_download_thread, worker_auto_download_queue, NULL, thread_error); + + if (thread_error != 0) { + EM_DEBUG_EXCEPTION("cannot create thread"); + g_auto_download_loop = 0; + if (err_code != NULL) + *err_code = EMAIL_ERROR_SYSTEM_FAILURE; + return false; + } + + if (err_code != NULL) + *err_code = EMAIL_ERROR_NONE; + + return true; +} + + +INTERNAL_FUNC int emcore_auto_download_loop_continue(void) +{ + return g_auto_download_loop; +} + + +INTERNAL_FUNC int emcore_stop_auto_download_loop(int *err_code) +{ + EM_DEBUG_FUNC_BEGIN(); + + if (err_code != NULL) + *err_code = EMAIL_ERROR_NONE; + + if (!g_auto_download_thread) { + if (err_code != NULL) + *err_code = EMAIL_ERROR_UNKNOWN; + return false; + } + + /* stop event_data loop */ + g_auto_download_loop = 0; + + WAKE_CONDITION_VARIABLE(_auto_downalod_available_signal); + + /* wait for thread finished */ + THREAD_JOIN(g_auto_download_thread); + + g_queue_free(g_auto_download_que); + + g_auto_download_thread = 0; + + DELETE_RECURSIVE_CRITICAL_SECTION(_auto_download_queue_lock); + DELETE_CONDITION_VARIABLE(_auto_downalod_available_signal); + + if (err_code != NULL) + *err_code = EMAIL_ERROR_NONE; + EM_DEBUG_FUNC_END(); + return true; +} + + +INTERNAL_FUNC int emcore_insert_auto_download_event(email_event_auto_download *event_data, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("event_data[%p], err_code[%p]", event_data, err_code); + + if (!event_data) { + EM_DEBUG_EXCEPTION("Invalid Parameter"); + if (err_code != NULL) + *err_code = EMAIL_ERROR_INVALID_PARAM; + return false; + } + + if (!g_auto_download_thread) { + EM_DEBUG_EXCEPTION("g_auto_download_thread is not ready"); + if (err_code != NULL) + *err_code = EMAIL_ERROR_LOAD_ENGINE_FAILURE; + return false; + } + + int ret = false; + int error = EMAIL_ERROR_NONE; + int q_length = 0; + + ENTER_RECURSIVE_CRITICAL_SECTION(_auto_download_queue_lock); + + if (g_auto_download_que) + q_length = g_queue_get_length(g_auto_download_que); + EM_DEBUG_LOG("Q Length : [%d]", q_length); + + if (q_length > AUTO_DOWNLOAD_QUEUE_MAX) { + EM_DEBUG_EXCEPTION("auto download que is full..."); + error = EMAIL_ERROR_EVENT_QUEUE_FULL; + ret = false; + } else { + event_data->status = EMAIL_EVENT_STATUS_WAIT; + g_queue_push_tail(g_auto_download_que, event_data); + //WAKE_CONDITION_VARIABLE(_auto_downalod_available_signal); + ret = true; + } + + LEAVE_RECURSIVE_CRITICAL_SECTION(_auto_download_queue_lock); + + if (err_code) { + EM_DEBUG_LOG("ERR [%d]", error); + *err_code = error; + } + + return ret; +} + + +INTERNAL_FUNC int emcore_retrieve_auto_download_event(email_event_auto_download **event_data, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("event_data[%p], err_code[%p]", event_data, err_code); + + int ret = false; + int error = EMAIL_ERROR_NONE; + int q_length = 0; + //email_event_auto_download *poped = NULL; + email_event_auto_download *head_event = NULL; + + if (g_auto_download_que) + q_length = g_queue_get_length(g_auto_download_que); + EM_DEBUG_LOG("Q Length : [%d]", q_length); + + if (!q_length) { + error = EMAIL_ERROR_EVENT_QUEUE_EMPTY; + EM_DEBUG_LOG("QUEUE is empty"); + goto FINISH_OFF; + } + + while (1) { + head_event = (email_event_auto_download *)g_queue_peek_head(g_auto_download_que); + if (!head_event) { + error = EMAIL_ERROR_EVENT_QUEUE_EMPTY; + EM_DEBUG_LOG_DEV ("QUEUE is empty"); + break; + } + + /*if (head_event->status != EMAIL_EVENT_STATUS_WAIT) { + EM_DEBUG_LOG("EVENT STATUS [%d]", head_event->status); + poped = g_queue_pop_head(g_auto_download_que); + if (poped) { + EM_SAFE_FREE(poped); + } else { + error = EMAIL_ERROR_EVENT_QUEUE_EMPTY; + EM_DEBUG_LOG("QUEUE is empty"); + break; + } + } else*/ + { + head_event->status = EMAIL_EVENT_STATUS_STARTED; + *event_data = head_event; + ret = true; + break; + } + } + +FINISH_OFF: + + if (err_code != NULL) + *err_code = error; + + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + + +INTERNAL_FUNC int emcore_is_auto_download_queue_empty(void) +{ + EM_DEBUG_FUNC_BEGIN(); + + int ret = false; + int q_length = 0; + + ENTER_RECURSIVE_CRITICAL_SECTION(_auto_download_queue_lock); + + if (g_auto_download_que) + q_length = g_queue_get_length(g_auto_download_que); + + EM_DEBUG_LOG("Q Length : [%d]", q_length); + + if (q_length <= 0) { + EM_DEBUG_LOG("auto downlaod que is empty..."); + ret = true; + } + + LEAVE_RECURSIVE_CRITICAL_SECTION(_auto_download_queue_lock); + EM_DEBUG_FUNC_END("ret [%d]", ret); + return ret; +} + + +INTERNAL_FUNC int emcore_is_auto_download_queue_full(void) +{ + EM_DEBUG_FUNC_BEGIN(); + + int ret = false; + int q_length = 0; + + ENTER_RECURSIVE_CRITICAL_SECTION(_auto_download_queue_lock); + + if (g_auto_download_que) + q_length = g_queue_get_length(g_auto_download_que); + + EM_DEBUG_LOG("Q Length : [%d]", q_length); + + if (q_length > AUTO_DOWNLOAD_QUEUE_MAX) { + EM_DEBUG_LOG("auto downlaod que is full..."); + ret = true; + } + + LEAVE_RECURSIVE_CRITICAL_SECTION(_auto_download_queue_lock); + EM_DEBUG_FUNC_END(); + return ret; +} + + +INTERNAL_FUNC int emcore_clear_auto_download_queue(void) +{ + EM_DEBUG_FUNC_BEGIN(); + int ret = false; + int i = 0; + int q_length = 0; + email_event_auto_download *pop_elm = NULL; + + ENTER_RECURSIVE_CRITICAL_SECTION(_auto_download_queue_lock); + + q_length = g_auto_download_que? g_queue_get_length (g_auto_download_que): 0; + + for (i = 0; i < q_length; i++) { + pop_elm = (email_event_auto_download *)g_queue_peek_nth(g_auto_download_que, i); + + if (pop_elm) { + EM_SAFE_FREE(pop_elm); + } + } + + g_queue_clear(g_auto_download_que); + ret = true; + + LEAVE_RECURSIVE_CRITICAL_SECTION(_auto_download_queue_lock); + EM_DEBUG_FUNC_END(); + return ret; +} + + +static void* worker_auto_download_queue(void *arg) +{ + EM_DEBUG_FUNC_BEGIN(); + int err = EMAIL_ERROR_NONE; + + int ai = 0; + int mi = 0; + int di = 0; + int account_count = 0; + int mailbox_count = 0; + int activity_count = 0; + int activity_list_count = 0; + int *account_list = NULL; + int *mailbox_list = NULL; + email_event_auto_download *event_data = NULL; + email_event_auto_download *started_event = NULL; + email_event_auto_download *activity_list = NULL; + + + if (!emstorage_open(NULL, &err)) { + EM_DEBUG_EXCEPTION("emstorage_open falied [%d]", err); + return false; + } + + /* check that event_data loop is continuous */ + while (emcore_auto_download_loop_continue()) { + + ENTER_RECURSIVE_CRITICAL_SECTION(_auto_download_queue_lock); + + if (!emcore_retrieve_auto_download_event(&event_data, &err)) { + /* no event_data pending */ + if (err != EMAIL_ERROR_EVENT_QUEUE_EMPTY) { + LEAVE_RECURSIVE_CRITICAL_SECTION(_auto_download_queue_lock); + continue; + } + + activity_count = 0; + if (!emstorage_get_auto_download_activity_count(NULL, &activity_count, false, &err)) { + EM_DEBUG_LOG("emstorage_get_auto_download_activity_count failed [%d]", err); + goto CHECK_CONTINUE; + } + + if (activity_count <= 0) { + EM_DEBUG_LOG("auto download activity count is 0"); + goto CHECK_CONTINUE; + } + + account_count = 0; + EM_SAFE_FREE(account_list); + if (!emstorage_get_auto_download_account_list(NULL, &account_list, &account_count, false, &err)) { + EM_DEBUG_EXCEPTION(" emstorage_get_auto_download_account_list failed.. [%d]", err); + goto CHECK_CONTINUE; + } + + if (account_count <= 0 || !account_list) { + EM_DEBUG_LOG("auto download account count is 0"); + goto CHECK_CONTINUE; + } + + for (ai = 0; ai < account_count; ai++) { + + email_account_t *account_ref = NULL; + if (!(account_ref = emcore_get_account_reference(NULL, account_list[ai], false))) { + EM_DEBUG_EXCEPTION("emcore_get_account_reference failed [%d]", account_list[ai]); + err = EMAIL_ERROR_INVALID_ACCOUNT; + continue; + } + + if (!(account_ref->wifi_auto_download)) { + if (account_ref) { + emcore_free_account(account_ref); + EM_SAFE_FREE(account_ref); + } + + continue; + } + + if (account_ref) { + emcore_free_account(account_ref); + EM_SAFE_FREE(account_ref); + } + + mailbox_count = 0; + EM_SAFE_FREE(mailbox_list); + if (!emstorage_get_auto_download_mailbox_list(NULL, account_list[ai], &mailbox_list, &mailbox_count, false, &err)) { + EM_DEBUG_EXCEPTION(" emstorage_get_auto_download_mailbox_list failed.. [%d]", err); + goto CHECK_CONTINUE; + } + + if (mailbox_count <= 0 || !mailbox_list) { + EM_DEBUG_LOG("auto download mailbox count is 0"); + goto CHECK_CONTINUE; + } + + for (mi = 0; mi < mailbox_count; mi++) { + emstorage_mailbox_tbl_t *target_mailbox = NULL; + + activity_list_count = 0; + EM_SAFE_FREE(activity_list); + + if ((err = emstorage_get_mailbox_by_id(NULL, mailbox_list[mi], &target_mailbox)) != EMAIL_ERROR_NONE) { + EM_DEBUG_EXCEPTION("emstorage_get_mailbox_by_id failed. [%d]", err); + } + + if (target_mailbox) { + if (target_mailbox->mailbox_type != EMAIL_MAILBOX_TYPE_INBOX) { + EM_DEBUG_LOG("Not INBOX mail, skip to next"); + emstorage_free_mailbox(&target_mailbox, 1, NULL); + continue; + } + emstorage_free_mailbox(&target_mailbox, 1, NULL); + } + + if (!emstorage_get_auto_download_activity(NULL, account_list[ai], mailbox_list[mi], &activity_list, &activity_list_count, false, &err)) { + EM_DEBUG_EXCEPTION(" emstorage_get_auto_download_activity failed.. [%d]", err); + goto CHECK_CONTINUE; + } + + if (activity_list_count <= 0 || !activity_list) { + EM_DEBUG_LOG("auto download activity count is 0"); + goto CHECK_CONTINUE; + } + + for (di = 0; di < activity_list_count; di++) { + email_event_auto_download *activity = NULL; + activity = (email_event_auto_download *)em_malloc(sizeof(email_event_auto_download)); + if (!activity) { + EM_DEBUG_EXCEPTION("Malloc failed"); + err = EMAIL_ERROR_OUT_OF_MEMORY; + goto CHECK_CONTINUE; + } + + activity->activity_id = activity_list[di].activity_id; + activity->status = 0; + activity->account_id = activity_list[di].account_id; + activity->mail_id = activity_list[di].mail_id; + activity->server_mail_id = activity_list[di].server_mail_id; + activity->mailbox_id = activity_list[di].mailbox_id; + + if (!emcore_insert_auto_download_event(activity, &err)) { + EM_DEBUG_EXCEPTION("emcore_insert_auto_download_event is failed [%d]", err); + EM_SAFE_FREE(activity); + if (err == EMAIL_ERROR_EVENT_QUEUE_FULL) goto CHECK_CONTINUE; + } + } + } + } + +CHECK_CONTINUE: + + EM_SAFE_FREE(account_list); + EM_SAFE_FREE(mailbox_list); + EM_SAFE_FREE(activity_list); + + if (!emcore_is_auto_download_queue_empty()) { + LEAVE_RECURSIVE_CRITICAL_SECTION(_auto_download_queue_lock); + continue; + } + + auto_download_thread_run = 0; + //go to sleep when queue is empty + SLEEP_CONDITION_VARIABLE(_auto_downalod_available_signal, *_auto_download_queue_lock); + EM_DEBUG_LOG("Wake up by _auto_downalod_available_signal"); + LEAVE_RECURSIVE_CRITICAL_SECTION(_auto_download_queue_lock); + } + else { + LEAVE_RECURSIVE_CRITICAL_SECTION(_auto_download_queue_lock); + EM_DEBUG_LOG_DEV(">>>>>>>>>>>>>>> Got auto download event_data !!! <<<<<<<<<<<<<<<"); + int state1 = 0, state2 = 0, state3 = 0, wifi_status = 0; + char uid_str[50] = {0, }; + emstorage_mail_tbl_t *mail = NULL; + emstorage_mailbox_tbl_t *target_mailbox = NULL; + email_account_t *account_ref = NULL; + auto_download_thread_run = 1; + + if ((err = emnetwork_get_wifi_status(&wifi_status)) != EMAIL_ERROR_NONE) { + EM_DEBUG_EXCEPTION("emnetwork_get_wifi_status failed [%d]", err); + } + + EM_DEBUG_LOG("WIFI Status [%d]", wifi_status); + + if ((state1 = emcore_get_pbd_thd_state()) == true || + (state2 = emcore_is_event_queue_empty()) == false || + (state3 = emcore_is_send_event_queue_empty()) == false || + (wifi_status <= 1)) { + + EM_DEBUG_LOG("Auto Download Thread going to SLEEP"); + + ENTER_RECURSIVE_CRITICAL_SECTION(_auto_download_queue_lock); + auto_download_thread_run = 0; + SLEEP_CONDITION_VARIABLE(_auto_downalod_available_signal, *_auto_download_queue_lock); + EM_DEBUG_LOG("Wake up by _auto_downalod_available_signal"); + LEAVE_RECURSIVE_CRITICAL_SECTION(_auto_download_queue_lock); + + auto_download_thread_run = 1; + } + + if (!(account_ref = emcore_get_account_reference(event_data->multi_user_name, event_data->account_id, false))) { + EM_DEBUG_EXCEPTION("emcore_get_account_reference failed [%d]", event_data->account_id); + err = EMAIL_ERROR_INVALID_ACCOUNT; + goto POP_HEAD; + } + + if (!(account_ref->wifi_auto_download)) { + EM_DEBUG_LOG("ACCOUNT[%d] AUTO DOWNLOAD MODE OFF", event_data->account_id); + goto POP_HEAD; + } + + if (account_ref) { + emcore_free_account(account_ref); + EM_SAFE_FREE(account_ref); + } + + if ((err = emstorage_get_mailbox_by_id(event_data->multi_user_name, event_data->mailbox_id, &target_mailbox)) != EMAIL_ERROR_NONE) { + EM_DEBUG_EXCEPTION("emstorage_get_mailbox_by_id failed. [%d]", err); + } + + if (target_mailbox) { + if (target_mailbox->mailbox_type != EMAIL_MAILBOX_TYPE_INBOX) { + EM_DEBUG_LOG("Not INBOX mail, skip to next"); + emstorage_free_mailbox(&target_mailbox, 1, NULL); + goto DELETE_ACTIVITY; + } + + emstorage_free_mailbox(&target_mailbox, 1, NULL); + } + + /* Handling storage full */ + if ((err = emcore_is_storage_full()) == EMAIL_ERROR_MAIL_MEMORY_FULL) { + EM_DEBUG_EXCEPTION("Storage is full"); + + ENTER_RECURSIVE_CRITICAL_SECTION(_auto_download_queue_lock); + auto_download_thread_run = 0; + SLEEP_CONDITION_VARIABLE(_auto_downalod_available_signal, *_auto_download_queue_lock); + EM_DEBUG_LOG("Wake up by _auto_downalod_available_signal"); + LEAVE_RECURSIVE_CRITICAL_SECTION(_auto_download_queue_lock); + + continue; + } + + snprintf(uid_str, sizeof(uid_str), "%ld", event_data->server_mail_id); + if (!emstorage_get_maildata_by_servermailid(event_data->multi_user_name, event_data->mailbox_id, uid_str, &mail, true, &err) || !mail) { + EM_DEBUG_EXCEPTION("emstorage_get_mail_data_by_servermailid failed : [%d]", err); + } + else { + if (mail->body_download_status & EMAIL_BODY_DOWNLOAD_STATUS_FULLY_DOWNLOADED) { + EM_DEBUG_LOG("fully downloaded mail"); + } + else { + EM_DEBUG_LOG("#####AUTO DOWNLOAD BODY: ACCOUNT_ID[%d] MAILBOX_ID[%d] MAIL_ID[%d] UID[%d] ACTIVITY[%d]#####", + event_data->account_id, event_data->mailbox_id, + event_data->mail_id, event_data->server_mail_id, event_data->activity_id); + + if (!emcore_gmime_download_body_sections(event_data->multi_user_name, NULL, event_data->account_id, event_data->mail_id, + 1, NO_LIMITATION, -1, 0, 1, &err)) + EM_DEBUG_EXCEPTION("emcore_gmime_download_body_sections failed - %d", err); + } + + if (mail->attachment_count > 0) { + int i = 0; + int j = 0; + int attachment_count = 0; + emstorage_attachment_tbl_t *attachment_list = NULL; + + if ((err = emstorage_get_attachment_list(event_data->multi_user_name, event_data->mail_id, true, &attachment_list, &attachment_count)) != EMAIL_ERROR_NONE ) { + EM_DEBUG_EXCEPTION("emstorage_get_attachment_list failed [%d]", err); + } else { + for (i = 0; i < attachment_count; i++) { + if (attachment_list[i].attachment_inline_content_status) + continue; + + j++; + + if (attachment_list[i].attachment_save_status) + continue; + + EM_DEBUG_LOG("#####AUTO DOWNLOAD ATTACHMENT[%d]: ACCOUNT_ID[%d] MAILBOX_ID[%d] MAIL_ID[%d] UID[%d] ACTIVITY[%d]#####", + j, event_data->account_id, event_data->mailbox_id, + event_data->mail_id, event_data->server_mail_id, event_data->activity_id); + + if (!emcore_gmime_download_attachment(event_data->multi_user_name, event_data->mail_id, j, 0, -1, 1, &err)) + EM_DEBUG_EXCEPTION("emcore_gmime_download_attachment failed [%d]", err); + } + + if (attachment_list) + emstorage_free_attachment(&attachment_list, attachment_count, NULL); + } + } + + if (mail) + emstorage_free_mail(&mail, 1, NULL); + } + +DELETE_ACTIVITY: + if (!emcore_delete_auto_download_activity(event_data->multi_user_name, event_data->account_id, event_data->mail_id, event_data->activity_id, &err)) { + EM_DEBUG_EXCEPTION("emcore_delete_auto_download_activity failed [%d]", err); + } + + +POP_HEAD: + /* free event itself */ + ENTER_RECURSIVE_CRITICAL_SECTION(_auto_download_queue_lock); + started_event = g_queue_pop_head(g_auto_download_que); + LEAVE_RECURSIVE_CRITICAL_SECTION(_auto_download_queue_lock); + if (!started_event) { + EM_DEBUG_EXCEPTION("Failed to g_queue_pop_head"); + } + else { + EM_SAFE_FREE(started_event->multi_user_name); + EM_SAFE_FREE(started_event); + } + + if (account_ref) { + emcore_free_account(account_ref); + EM_SAFE_FREE(account_ref); + } + + em_flush_memory(); + } + } + + if (!emstorage_close(&err)) + EM_DEBUG_EXCEPTION("emstorage_close falied [%d]", err); + + emcore_close_recv_stream_list(); + + EM_DEBUG_FUNC_END(); + return SUCCESS; +} + + +INTERNAL_FUNC int emcore_insert_auto_download_job(char *multi_user_name, int account_id, int mailbox_id, int mail_id, int auto_download_on, char *uid, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("account_id [%d], maibox_id[%d], mail_id[%d], uid[%p]", account_id, mailbox_id, mail_id, uid); + + int ret = false; + int err = EMAIL_ERROR_NONE; + int event_pushed = 0; + email_event_auto_download *ad_event = NULL; + + if (account_id < FIRST_ACCOUNT_ID || mailbox_id <= 0 || mail_id < 0 || !uid) { + EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM"); + err = EMAIL_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + ad_event = (email_event_auto_download *)em_malloc(sizeof(email_event_auto_download)); + + if (!ad_event) { + EM_DEBUG_EXCEPTION("em_malloc failed..."); + err = EMAIL_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + ad_event->status = 0; + ad_event->account_id = account_id; + ad_event->mail_id = mail_id; + ad_event->server_mail_id = strtoul(uid, NULL, 0); + ad_event->mailbox_id = mailbox_id; + ad_event->multi_user_name = EM_SAFE_STRDUP(multi_user_name); + + if (!emcore_insert_auto_download_activity(ad_event, &(ad_event->activity_id), &err)) { + EM_DEBUG_EXCEPTION("Inserting auto download activity failed with error[%d]", err); + goto FINISH_OFF; + } + else { + ret = true; + + if (!auto_download_on) { + goto FINISH_OFF; + } + + if (emcore_is_auto_download_queue_full()) { + EM_DEBUG_LOG("Activity inserted only in DB .. Queue is Full"); + } + else { + if (!emcore_insert_auto_download_event(ad_event, &err)) { + EM_DEBUG_EXCEPTION("emcore_insert_auto_download_event is failed [%d]", err); + goto FINISH_OFF; + } + event_pushed = 1; + } + } + +FINISH_OFF: + + if (!event_pushed) { + EM_SAFE_FREE(ad_event->multi_user_name); + EM_SAFE_FREE(ad_event); + } + + EM_DEBUG_FUNC_END(); + return ret; +} + + +INTERNAL_FUNC int emcore_insert_auto_download_activity(email_event_auto_download *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 = EMAIL_ERROR_INVALID_PARAM; + return false; + } + + int ret = false; + int err = EMAIL_ERROR_NONE; + int before_tr_begin = 0; + + if (!emstorage_begin_transaction(local_activity->multi_user_name, NULL, NULL, &err)) { + EM_DEBUG_EXCEPTION("emstorage_begin_transaction failed [%d]", err); + before_tr_begin = 1; + goto FINISH_OFF; + } + + if (!emstorage_add_auto_download_activity(local_activity->multi_user_name, local_activity, activity_id, false, &err)) { + EM_DEBUG_EXCEPTION("emstorage_add_auto_download_activity failed [%d]", err); + goto FINISH_OFF; + } + + ret = true; + +FINISH_OFF: + if (ret == true) { /* COMMIT TRANSACTION; */ + if (emstorage_commit_transaction(local_activity->multi_user_name, NULL, NULL, NULL) == false) { + err = EMAIL_ERROR_DB_FAILURE; + ret = false; + } + } else { /* ROLLBACK TRANSACTION; */ + if (!before_tr_begin && emstorage_rollback_transaction(local_activity->multi_user_name, NULL, NULL, NULL) == false) + err = EMAIL_ERROR_DB_FAILURE; + } + + if (err_code != NULL) + *err_code = err; + EM_DEBUG_FUNC_END(); + return ret; +} + + +INTERNAL_FUNC int emcore_delete_auto_download_activity(char *multi_user_name, 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 = EMAIL_ERROR_INVALID_PARAM; + return false; + } + + int ret = false; + int err = EMAIL_ERROR_NONE; + int before_tr_begin = 0; + + if (!emstorage_begin_transaction(multi_user_name, NULL, NULL, &err)) { + EM_DEBUG_EXCEPTION("emstorage_begin_transaction failed [%d]", err); + before_tr_begin = 1; + goto FINISH_OFF; + } + + if (!emstorage_delete_auto_download_activity(multi_user_name, account_id, mail_id, activity_id, false, &err)) { + EM_DEBUG_EXCEPTION("emstorage_delete_auto_download_activity failed [%d]", err); + goto FINISH_OFF; + } + else if (err == EMAIL_ERROR_DATA_NOT_FOUND) + err = EMAIL_ERROR_NONE; + + ret = true; + +FINISH_OFF: + + if (ret == true) { /* COMMIT TRANSACTION; */ + if (emstorage_commit_transaction(multi_user_name, NULL, NULL, NULL) == false) { + err = EMAIL_ERROR_DB_FAILURE; + ret = false; + } + } else { /* ROLLBACK TRANSACTION; */ + if (!before_tr_begin && emstorage_rollback_transaction(multi_user_name, NULL, NULL, NULL) == false) + err = EMAIL_ERROR_DB_FAILURE; + } + + if (err_code != NULL) + *err_code = err; + EM_DEBUG_FUNC_END(); + return ret; +} + + diff --git a/email-core/email-core-container.c b/email-core/email-core-container.c new file mode 100644 index 0000000..1631331 --- /dev/null +++ b/email-core/email-core-container.c @@ -0,0 +1,419 @@ +/* +* email-service +* +* Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved. +* +* Contact: Kyuho Jo , Sunghyun Kwon +* +* 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 functionality related to KNOX + * to interact with email-service. + * @file email-core-container.c + * @author + * @version 0.1 + * @brief This file contains functionality to provide KNOX support in email-service. + */ +#ifdef __FEATURE_CONTAINER_ENABLE__ +#include +#endif /* __FEATURE_CONTAINER_ENABLE__ */ + +#include "email-utilities.h" +#include "email-core-container.h" +#include "email-debug-log.h" + +int vsm_state_handle = 0; +int vsm_event_handle = 0; +#ifdef __FEATURE_CONTAINER_ENABLE__ +vsm_context_h container; + + +static int container_state_listener(vsm_zone_h zone, vsm_zone_state_t state, void *user_data) +{ + EM_DEBUG_FUNC_BEGIN(); + EM_DEBUG_LOG("Container name : [%s]", vsm_get_zone_name(zone)); + EM_DEBUG_LOG("Container state : [%d]", state); + EM_DEBUG_FUNC_END(); + return 0; +} + +static int container_event_listener(vsm_zone_h zone, vsm_zone_event_t event, void *user_data) +{ + EM_DEBUG_FUNC_BEGIN(); + EM_DEBUG_LOG("Container name : [%s]", vsm_get_zone_name(zone)); + EM_DEBUG_LOG("Container event : [%d]", event); + EM_DEBUG_FUNC_END(); + return 0; +} +#endif /* __FEATURE_CONTAINER_ENABLE__ */ + +INTERNAL_FUNC void emcore_create_container() +{ + EM_DEBUG_FUNC_BEGIN(); +#ifdef __FEATURE_CONTAINER_ENABLE__ + container = NULL; + + container = vsm_create_context(); + if (container == NULL) { + EM_DEBUG_EXCEPTION("vsm_create_context failed"); + return; + } + + vsm_state_handle = vsm_add_state_changed_callback(container, container_state_listener, NULL); + + vsm_event_handle = vsm_add_event_callback(container, container_event_listener, NULL); +#endif /* __FEATURE_CONTAINER_ENABLE__ */ + EM_DEBUG_FUNC_END(); +} + +INTERNAL_FUNC void emcore_destroy_container() +{ + EM_DEBUG_FUNC_BEGIN(); +#ifdef __FEATURE_CONTAINER_ENABLE__ + + if (container) { + vsm_del_state_changed_callback(container, vsm_state_handle); + + vsm_del_event_callback(container, vsm_event_handle); + + vsm_cleanup_context(container); + + container = NULL; + } +#endif /* __FEATURE_CONTAINER_ENABLE__ */ + + EM_DEBUG_FUNC_END(); +} + +static gboolean mainloop_callback(GIOChannel *channel, GIOCondition condition, void *data) +{ + EM_DEBUG_FUNC_BEGIN(); + +#ifdef __FEATURE_CONTAINER_ENABLE__ + vsm_context_h ctx = (vsm_context_h)data; + + EM_DEBUG_LOG("Enter event loop"); + vsm_enter_eventloop(ctx, 0, 0); + EM_DEBUG_LOG("Finish event loop"); +#endif /* __FEATURE_CONTAINER_ENABLE__ */ + + EM_DEBUG_FUNC_END(); + return TRUE; +} + +INTERNAL_FUNC void emcore_bind_vsm_context() +{ + EM_DEBUG_FUNC_BEGIN(); + +#ifdef __FEATURE_CONTAINER_ENABLE__ + int fd; + + GIOChannel *domain_channel = NULL; + + fd = vsm_get_poll_fd(container); + + domain_channel = g_io_channel_unix_new(fd); + if (domain_channel == NULL) { + EM_DEBUG_EXCEPTION("Channel allocation failed\n"); + return; + } + + g_io_add_watch(domain_channel, G_IO_IN, mainloop_callback, container); +#endif /* __FEATURE_CONTAINER_ENABLE__ */ + + EM_DEBUG_FUNC_END(); +} + +INTERNAL_FUNC int emcore_get_container_path(char *multi_user, char **container_path) +{ + EM_DEBUG_FUNC_BEGIN(); + int err = EMAIL_ERROR_NONE; + + if (multi_user == NULL) { + EM_DEBUG_LOG("user_name is NULL"); + return EMAIL_ERROR_INVALID_PARAM; + } + +#ifdef __FEATURE_CONTAINER_ENABLE__ + if (container == NULL) { + EM_DEBUG_LOG("Container not intialize"); + return EMAIL_ERROR_CONTAINER_NOT_INITIALIZATION; + } + + vsm_zone_h zone = NULL; + char *p_container_path = NULL; + char errno_buf[ERRNO_BUF_SIZE] = {0}; + + if (EM_SAFE_STRLEN(multi_user) == 0) { + EM_DEBUG_LOG("multi_user name is NULL"); + goto FINISH_OFF; + } + + EM_DEBUG_LOG("name : [%s], container : [%p]", multi_user, container); + zone = vsm_lookup_zone_by_name(container, multi_user); + if (zone == NULL) { + EM_DEBUG_EXCEPTION("NULL returned : %s, %d", EM_STRERROR(errno_buf), errno); + err = EMAIL_ERROR_CONTAINER_GET_DOMAIN; + goto FINISH_OFF; + } + + p_container_path = (char *)vsm_get_zone_rootpath(zone); + +FINISH_OFF: + + if (container_path) + *container_path = EM_SAFE_STRDUP(p_container_path); + +#endif /* __FEATURE_CONTAINER_ENABLE__ */ + EM_DEBUG_FUNC_END(); + return err; +} + +INTERNAL_FUNC int emcore_get_user_name(int pid, char **multi_user) +{ + EM_DEBUG_FUNC_BEGIN(); + + int err = EMAIL_ERROR_NONE; + + if (pid <= 0) { + EM_DEBUG_EXCEPTION("Invalid parameter"); + return EMAIL_ERROR_INVALID_PARAM; + } +#ifdef __FEATURE_CONTAINER_ENABLE__ + + char *user_name = NULL; + vsm_zone_h zone = NULL; + char errno_buf[ERRNO_BUF_SIZE] = {0}; + + EM_DEBUG_LOG("pid : [%d], container : [%p]", pid, container); + zone = vsm_lookup_zone_by_pid(container, pid); + if (zone == NULL) { + EM_DEBUG_EXCEPTION("NULL returned : %s, %d", EM_STRERROR(errno_buf), errno); + err = EMAIL_ERROR_CONTAINER_GET_DOMAIN; + goto FINISH_OFF; + } + + user_name = (char *)vsm_get_zone_name(zone); + EM_DEBUG_LOG("user_name : [%s]", user_name); + +FINISH_OFF: + + if (multi_user) + *multi_user = EM_SAFE_STRDUP(user_name); + +#endif /* __FEATURE_CONTAINER_ENABLE__ */ + EM_DEBUG_FUNC_END(); + return err; +} + +INTERNAL_FUNC int emcore_lookup_zone_by_name(char *user_name) +{ + EM_DEBUG_FUNC_BEGIN(); + int ret = false; + + if (EM_SAFE_STRLEN(user_name) == 0) { + EM_DEBUG_LOG("user_name is NULL"); + return ret; + } + +#ifdef __FEATURE_CONTAINER_ENABLE__ + if (container == NULL) { + EM_DEBUG_LOG("Container not intialize"); + return ret; + } + + vsm_zone_h zone = NULL; + char errno_buf[ERRNO_BUF_SIZE] = {0}; + + EM_DEBUG_LOG("name : [%s], container : [%p]", user_name, container); + zone = vsm_lookup_zone_by_name(container, user_name); + if (zone == NULL) { + EM_DEBUG_EXCEPTION("NULL returned : %s, %d", EM_STRERROR(errno_buf), errno); + goto FINISH_OFF; + } + + ret = true; + +FINISH_OFF: + +#endif /* __FEATURE_CONTAINER_ENABLE__ */ + EM_DEBUG_FUNC_END(); + return ret; +} + +INTERNAL_FUNC void emcore_set_declare_link(const char *file_path) +{ + EM_DEBUG_FUNC_BEGIN(); + +#ifdef __FEATURE_CONTAINER_ENABLE__ + if (container == NULL) { + EM_DEBUG_EXCEPTION("Not initialize"); + return; + } + + int ret = 0; + if ((ret = vsm_declare_link(container, file_path /* src path */, file_path /* dst path */)) != 0) { + EM_DEBUG_EXCEPTION("vsm_declare_link failed : [%s] [%d]", file_path, ret); + } +#endif /* __FEATURE_CONTAINER_ENABLE__ */ + + EM_DEBUG_FUNC_END(); +} + +#ifdef __FEATURE_CONTAINER_ENABLE__ +void iterate_callback(vsm_zone_h zone, void *user_data) +{ + EM_DEBUG_FUNC_BEGIN(); + char *zone_name = NULL; + GList *zone_name_list = (GList *)user_data; + + zone_name = EM_SAFE_STRDUP(vsm_get_zone_name(zone)); + if (EM_SAFE_STRLEN(zone_name) > 0) + zone_name_list = g_list_append(zone_name_list, zone_name); + + EM_DEBUG_FUNC_END(); +} +#endif /* __FEATURE_CONTAINER_ENABLE__ */ + +INTERNAL_FUNC int emcore_get_zone_name_list(GList **output_name_list) +{ + EM_DEBUG_FUNC_BEGIN(); + int err = EMAIL_ERROR_NONE; + int ret = 0; + GList *zone_name_list = NULL; + GList *node = NULL; + + if (output_name_list == NULL) { + EM_DEBUG_EXCEPTION("Invalid parameter"); + err = EMAIL_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + +#ifdef __FEATURE_CONTAINER_ENABLE__ + if (container == NULL) { + EM_DEBUG_EXCEPTION("Not initialize"); + err = EMAIL_ERROR_CONTAINER_CREATE_FAILED; + goto FINISH_OFF; + } + + zone_name_list = g_list_alloc(); + if (zone_name_list == NULL) { + EM_DEBUG_EXCEPTION("g_list_alloc failed"); + err = EMAIL_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + if ((ret = vsm_iterate_zone(container, iterate_callback, (void *)zone_name_list)) < 0) { + EM_DEBUG_EXCEPTION("vsm_iterate_domain failed : [%d]", ret); + err = EMAIL_ERROR_CONTAINER_ITERATE_DOMAIN; + goto FINISH_OFF; + } +#endif /* __FEATURE_CONTAINER_ENABLE__ */ + +FINISH_OFF: + + if (err != EMAIL_ERROR_NONE) { + node = g_list_first(zone_name_list); + while (node != NULL) { + /* Free the domain name */ + EM_SAFE_FREE(node->data); + node = g_list_next(node); + } + g_list_free(zone_name_list); + zone_name_list = NULL; + } + + if (output_name_list) + *output_name_list = zone_name_list; + + EM_DEBUG_FUNC_END(); + return err; +} + +INTERNAL_FUNC int emcore_get_canonicalize_path(char *db_path, char **output_path) +{ + EM_DEBUG_FUNC_BEGIN(); + int err = EMAIL_ERROR_NONE; + +#ifdef __FEATURE_CONTAINER_ENABLE__ + int ret = 0; + ret = vsm_canonicalize_path(db_path, output_path); + if (ret < 0) { + EM_DEBUG_EXCEPTION("vsm_canonicalize_path failed : [%d]", ret); + err = EMAIL_ERROR_FILE_NOT_FOUND; + } +#endif /* __FEATURE_CONTAINER_ENABLE__ */ + + EM_DEBUG_FUNC_END(); + return err; +} + +INTERNAL_FUNC int emcore_set_join_zone(char *multi_user_name, void **join_zone) +{ + EM_DEBUG_FUNC_BEGIN(); + int err = EMAIL_ERROR_NONE; +#ifdef __FEATURE_CONTAINER_ENABLE__ + char errno_buf[ERRNO_BUF_SIZE] = {0}; + vsm_zone_h temp_zone = NULL; + vsm_zone_h p_join_zone = NULL; + + if (EM_SAFE_STRLEN(multi_user_name) == 0) { + EM_DEBUG_LOG("multi_user_name is NULL"); + return err; + } + + temp_zone = vsm_lookup_zone_by_name(container, multi_user_name); + if (temp_zone == NULL) { + EM_DEBUG_EXCEPTION("NULL returned : %s %d", EM_STRERROR(errno_buf), errno); + err = EMAIL_ERROR_CONTAINER_LOOKUP_ZONE_FAILED; + goto FINISH_OFF; + } + + p_join_zone = vsm_join_zone(temp_zone); + if (p_join_zone == NULL) { + EM_DEBUG_EXCEPTION("NULL returned : %s %d", EM_STRERROR(errno_buf), errno); + err = EMAIL_ERROR_CONTAINER_JOIN_ZONE_FAILED; + goto FINISH_OFF; + } + +FINISH_OFF: + + if (join_zone) + *join_zone = (void *)p_join_zone; + +#endif /* __FEATURE_CONTAINER_ENABLE__ */ + EM_DEBUG_FUNC_END(); + return err; +} + +INTERNAL_FUNC void emcore_unset_join_zone(void *join_zone) +{ + EM_DEBUG_FUNC_BEGIN(); +#ifdef __FEATURE_CONTAINER_ENABLE__ + + char errno_buf[ERRNO_BUF_SIZE] = {0}; + vsm_zone_h temp_zone = NULL; + + + temp_zone = vsm_join_zone((vsm_zone_h)join_zone); + if (temp_zone == NULL) { + EM_DEBUG_EXCEPTION("NULL returned : %s %d", EM_STRERROR(errno_buf), errno); + } + +#endif /* __FEATURE_CONTAINER_ENABLE__ */ + EM_DEBUG_FUNC_END(); +} diff --git a/email-core/email-core-gmime.c b/email-core/email-core-gmime.c new file mode 100755 index 0000000..0cb95a4 --- /dev/null +++ b/email-core/email-core-gmime.c @@ -0,0 +1,5046 @@ +/* +* email-service +* +* Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved. +* +* Contact: Minsoo Kim , Kyuho Jo , +* Sunghyun Kwon +* +* 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 +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "email-internal-types.h" +#include "email-utilities.h" +#include "email-core-global.h" +#include "email-core-utils.h" +#include "email-core-mail.h" +#include "email-core-mime.h" +#include "email-core-gmime.h" +#include "email-storage.h" +#include "email-core-event.h" +#include "email-core-account.h" +#include "email-core-signal.h" +#include "email-core-mailbox-sync.h" +#include "email-debug-log.h" + +static int multipart_status = 0; + +static void emcore_gmime_pop3_parse_foreach_cb(GMimeObject *parent, GMimeObject *part, gpointer user_data); +static void emcore_gmime_eml_parse_foreach_cb(GMimeObject *parent, GMimeObject *part, gpointer user_data); +static int emcore_gmime_parse_mime_header(GMimeMessage *message, struct _rfc822header *rfc822_header); + + +INTERNAL_FUNC void emcore_gmime_init(void) +{ + EM_DEBUG_FUNC_BEGIN(); + +#if !GLIB_CHECK_VERSION(2, 31, 0) + g_thread_init(NULL); +#endif + g_mime_init(0); + +#ifdef __FEATURE_SECURE_PGP__ + setenv("GNUPGHOME", "/opt/usr/apps/com.samsung.email/data/.gnupg", 1); +#endif + + EM_DEBUG_FUNC_END(); +} + +INTERNAL_FUNC void emcore_gmime_shutdown(void) +{ + EM_DEBUG_FUNC_BEGIN(); + + g_mime_shutdown(); + + EM_DEBUG_FUNC_END(); +} + + +INTERNAL_FUNC int emcore_gmime_imap_parse_mime_partial(char *rfc822header_str, char *bodytext_str, struct _m_content_info *cnt_info) +{ + EM_DEBUG_FUNC_BEGIN(); + + EM_DEBUG_LOG_DEV("RFC822H:%s", rfc822header_str); + EM_DEBUG_LOG_DEV("BODYTEXT:%s", bodytext_str); + + GMimeStream *stream = NULL; + GMimeMessage *message = NULL; + GMimeParser *parser = NULL; + char *fulltext = NULL; + + fulltext = g_strconcat(rfc822header_str, "\r\n\r\n", bodytext_str, NULL); + + stream = g_mime_stream_mem_new_with_buffer(fulltext, EM_SAFE_STRLEN(fulltext)); + + parser = g_mime_parser_new_with_stream(stream); + if (stream) g_object_unref(stream); + + message = g_mime_parser_construct_message(parser); + if (parser) g_object_unref(parser); + if (!message) { /* prevent null check for message */ + EM_DEBUG_EXCEPTION("g_mime_parser_construct_message error"); + EM_SAFE_FREE(fulltext); + return false; + } + + EM_DEBUG_LOG_DEV("Sender:%s", g_mime_message_get_sender(message)); + EM_DEBUG_LOG_DEV("Reply To:%s", g_mime_message_get_reply_to(message)); + EM_DEBUG_LOG_DEV("Subject:%s", g_mime_message_get_subject(message)); + EM_DEBUG_LOG_DEV("Date:%s", g_mime_message_get_date_as_string(message)); + EM_DEBUG_LOG_DEV("Message ID:%s", g_mime_message_get_message_id(message)); + + g_mime_message_foreach(message, emcore_gmime_imap_parse_foreach_cb, (gpointer)cnt_info); + + EM_SAFE_FREE(fulltext); + + if (message) g_object_unref (message); + + EM_DEBUG_FUNC_END(); + return true; +} + +INTERNAL_FUNC int emcore_gmime_pop3_parse_mime(char *eml_path, struct _m_content_info *cnt_info, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("cnt_info[%p], err_code[%p]", cnt_info, err_code); + EM_DEBUG_LOG_SEC("eml_path[%s]", eml_path); + + GMimeStream *stream = NULL; + GMimeMessage *message = NULL; + GMimeParser *parser = NULL; + int fd = 0; + int err = EMAIL_ERROR_NONE; + + err = em_open(eml_path, O_RDONLY, 0, &fd); + if (err != EMAIL_ERROR_NONE) { + EM_DEBUG_EXCEPTION("holder open failed : holder is a filename that will be saved."); + if (err_code) + *err_code = err; + return false; /*prevent 34936*/ + } + + stream = g_mime_stream_fs_new(fd); + + parser = g_mime_parser_new_with_stream(stream); + if (stream) g_object_unref(stream); + + message = g_mime_parser_construct_message(parser); + if (parser) g_object_unref(parser); + if (!message) { /* prevent null check for message */ + EM_DEBUG_EXCEPTION("g_mime_parser_construct_message error"); + return false; + } + + EM_DEBUG_LOG_DEV("Sender:%s", g_mime_message_get_sender(message)); + EM_DEBUG_LOG_DEV("Reply To:%s", g_mime_message_get_reply_to(message)); + EM_DEBUG_LOG_DEV("Subject:%s", g_mime_message_get_subject(message)); + EM_DEBUG_LOG_DEV("Date:%s", g_mime_message_get_date_as_string(message)); + EM_DEBUG_LOG_DEV("Message ID:%s", g_mime_message_get_message_id(message)); + + if (g_strrstr(g_mime_message_get_sender(message), "mmsc.plusnet.pl") != NULL || + g_strrstr(g_mime_message_get_sender(message), "mms.t-mobile.pl") != NULL) { + cnt_info->attachment_only = 1; + } + + g_mime_message_foreach(message, emcore_gmime_pop3_parse_foreach_cb, (gpointer)cnt_info); + + EM_SAFE_CLOSE (fd); + + if (message) g_object_unref (message); + + EM_DEBUG_FUNC_END(); + return true; +} + + +INTERNAL_FUNC int emcore_gmime_eml_parse_mime(char *eml_path, + struct _rfc822header *rfc822_header, + struct _m_content_info *cnt_info, + int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("cnt_info[%p], err_code[%p]", cnt_info, err_code); + EM_DEBUG_LOG_SEC("eml_path[%s]", eml_path); + + GMimeStream *stream = NULL; + GMimeMessage *message = NULL; + GMimeParser *parser = NULL; + int fd = 0; + int err = EMAIL_ERROR_NONE; + + err = em_open(eml_path, O_RDONLY, 0, &fd); + if (err != EMAIL_ERROR_NONE) { + EM_DEBUG_EXCEPTION("holder open failed : holder is a filename that will be saved."); + if (err_code) + *err_code = err; + return false; /*prevent 34936*/ + } + + multipart_status = 0; + + stream = g_mime_stream_fs_new(fd); + + parser = g_mime_parser_new_with_stream(stream); + if (stream) g_object_unref(stream); + + message = g_mime_parser_construct_message(parser); + if (parser) g_object_unref(parser); + if (!message) { /* prevent null check for message */ + EM_DEBUG_EXCEPTION("g_mime_parser_construct_message error"); + return false; + } + + EM_DEBUG_LOG_DEV("Sender:%s", g_mime_message_get_sender(message)); + EM_DEBUG_LOG_DEV("Reply To:%s", g_mime_message_get_reply_to(message)); + EM_DEBUG_LOG_DEV("Subject:%s", g_mime_message_get_subject(message)); + EM_DEBUG_LOG_DEV("Date:%s", g_mime_message_get_date_as_string(message)); + EM_DEBUG_LOG_DEV("Message ID:%s", g_mime_message_get_message_id(message)); + + emcore_gmime_parse_mime_header(message, rfc822_header); + + g_mime_message_foreach(message, emcore_gmime_eml_parse_foreach_cb, (gpointer)cnt_info); + + EM_SAFE_CLOSE (fd); + + if (message) g_object_unref (message); + + EM_DEBUG_FUNC_END(); + return true; +} + + +static void emcore_gmime_pop3_parse_foreach_cb(GMimeObject *parent, GMimeObject *part, gpointer user_data) +{ + EM_DEBUG_FUNC_BEGIN("parent[%p], part[%p], user_data[%p]", parent, part, user_data); + + int error = EMAIL_ERROR_NONE; + char *msg_tmp_content_path = NULL; + char *content_path = NULL; + struct _m_content_info *cnt_info = (struct _m_content_info *)user_data; + + if (GMIME_IS_MESSAGE_PART(part)) { + + EM_DEBUG_LOG("Message Part"); + GMimeMessage *message = NULL; + GMimeContentType *msg_ctype = NULL; + GMimeContentDisposition *msg_disposition = NULL; + GMimeStream *out_stream; + char *msg_ctype_type = NULL; + char *msg_ctype_subtype = NULL; + char *msg_ctype_name = NULL; + char *msg_disposition_str = NULL; + char *msg_disposition_filename = NULL; + char *msg_content_id = NULL; + int real_size = 0; + int msg_fd = 0; + + if (cnt_info->grab_type != (GRAB_TYPE_TEXT|GRAB_TYPE_ATTACHMENT) && + cnt_info->grab_type != GRAB_TYPE_ATTACHMENT) { + goto FINISH_OFF; + } + + message = g_mime_message_part_get_message((GMimeMessagePart *)part); + if (!message) { + EM_DEBUG_EXCEPTION("Message is NULL"); + goto FINISH_OFF; + } + + /*Content Type*/ + msg_ctype = g_mime_object_get_content_type(part); + msg_ctype_type = (char *)g_mime_content_type_get_media_type(msg_ctype); + msg_ctype_subtype = (char *)g_mime_content_type_get_media_subtype(msg_ctype); + msg_ctype_name = (char *)g_mime_content_type_get_parameter(msg_ctype, "name"); + EM_DEBUG_LOG("Content-Type[%s/%s]", msg_ctype_type, msg_ctype_subtype); + EM_DEBUG_LOG_SEC("RFC822/Message Content-Type-Name[%s]", msg_ctype_name); + /*Content Type - END*/ + + /*Content Disposition*/ + msg_disposition = g_mime_object_get_content_disposition(part); + if (msg_disposition) { + msg_disposition_str = (char *)g_mime_content_disposition_get_disposition(msg_disposition); + msg_disposition_filename = (char *)g_mime_content_disposition_get_parameter(msg_disposition, "filename"); + if (EM_SAFE_STRLEN(msg_disposition_filename) == 0) + msg_disposition_filename = NULL; + } + EM_DEBUG_LOG("RFC822/Message Disposition[%s]", msg_disposition_str); + EM_DEBUG_LOG_SEC("RFC822/Message Disposition-Filename[%s]", msg_disposition_filename); + /*Content Disposition - END*/ + + /*Content ID*/ + msg_content_id = (char *)g_mime_object_get_content_id(part); + EM_DEBUG_LOG("RFC822/Message Content-ID:%s", msg_content_id); + + /*save message content to tmp file*/ + if (!emcore_get_temp_file_name(&msg_tmp_content_path, &error)) { + EM_DEBUG_EXCEPTION("emcore_get_temp_file_name failed [%d]", error); + goto FINISH_OFF; + } + EM_DEBUG_LOG_SEC("Temporary Content Path[%s]", msg_tmp_content_path); + + msg_fd = open(msg_tmp_content_path, O_WRONLY|O_CREAT, 0644); + if (msg_fd < 0) { + EM_DEBUG_EXCEPTION("open failed"); + goto FINISH_OFF; + } + + out_stream = g_mime_stream_fs_new(msg_fd); + real_size = g_mime_object_write_to_stream(GMIME_OBJECT(message), out_stream); + if (out_stream) g_object_unref(out_stream); + + if (real_size <= 0) { + EM_DEBUG_EXCEPTION("g_mime_object_write_to_stream failed"); + goto FINISH_OFF; + } + + if (msg_disposition_str && g_ascii_strcasecmp(msg_disposition_str, GMIME_DISPOSITION_ATTACHMENT) == 0) { + EM_DEBUG_LOG("RFC822/Message is ATTACHMENT"); + + struct attachment_info *file = NULL; + struct attachment_info *temp_file = cnt_info->file; + char *utf8_text = NULL; + int err = EMAIL_ERROR_NONE; + + file = em_malloc(sizeof(struct attachment_info)); + if (file == NULL) { + EM_DEBUG_EXCEPTION("em_malloc failed..."); + goto FINISH_OFF; + } + + file->type = ATTACHMENT; + if (msg_disposition_filename) file->name = g_strdup(msg_disposition_filename); + else if (msg_ctype_name) file->name = g_strdup(msg_ctype_name); + else if (msg_content_id) file->name = g_strdup(msg_content_id); + else file->name = g_strdup("unknown"); + + if (msg_content_id) file->content_id = g_strdup(msg_content_id); + + if (!(utf8_text = g_mime_utils_header_decode_text(file->name))) { + EM_DEBUG_EXCEPTION("g_mime_utils_header_decode_text failed [%d]", err); + } + EM_DEBUG_LOG_SEC("utf8_text : [%s]", utf8_text); + + if (utf8_text) { + EM_SAFE_FREE(file->name); + file->name = EM_SAFE_STRDUP(utf8_text); + } + EM_SAFE_FREE(utf8_text); + + if(msg_ctype_type && msg_ctype_subtype) { + char mime_type_buffer[128] = {0,}; + snprintf(mime_type_buffer, sizeof(mime_type_buffer), "%s/%s", msg_ctype_type, msg_ctype_subtype); + file->attachment_mime_type = g_strdup(mime_type_buffer); + } + + file->save = g_strdup(msg_tmp_content_path); + file->size = real_size; + file->save_status = 1; + + while (temp_file && temp_file->next) + temp_file = temp_file->next; + + if (temp_file == NULL) + cnt_info->file = file; + else + temp_file->next = file; + } + + //g_mime_message_foreach(message, emcore_gmime_pop3_parse_foreach_cb, user_data); + } else if (GMIME_IS_MESSAGE_PARTIAL(part)) { + EM_DEBUG_LOG("Partial Part"); + //TODO + } else if (GMIME_IS_MULTIPART(part)) { + EM_DEBUG_LOG("Multi Part"); + GMimeMultipart *multi_part = NULL; + multi_part = (GMimeMultipart *)part; + + int multi_count = g_mime_multipart_get_count(multi_part); + EM_DEBUG_LOG("Multi Part Count:%d", multi_count); + EM_DEBUG_LOG("Boundary:%s\n\n", g_mime_multipart_get_boundary(multi_part)); + + if (GMIME_IS_MULTIPART_SIGNED(part)) + cnt_info->text.mime_entity = emcore_gmime_get_mime_entity_signed_message(part); + + } else if (GMIME_IS_PART(part)) { + EM_DEBUG_LOG("Part"); + int content_size = 0; + + GMimePart *leaf_part = NULL; + leaf_part = (GMimePart *)part; + + EM_DEBUG_LOG("Content ID:%s", g_mime_part_get_content_id(leaf_part)); + EM_DEBUG_LOG_SEC("Description:%s", g_mime_part_get_content_description(leaf_part)); + EM_DEBUG_LOG_SEC("MD5:%s", g_mime_part_get_content_md5(leaf_part)); + + int content_disposition_type = 0; + char *content_location = (char *)g_mime_part_get_content_location(leaf_part); + EM_DEBUG_LOG_SEC("Location:%s", content_location); + + GMimeObject *mobject = (GMimeObject *)part; + + /*Content ID*/ + char *content_id = (char *)g_mime_object_get_content_id(mobject); + + /*Content Disposition*/ + GMimeContentDisposition *disposition = NULL; + char *disposition_str = NULL; + char *disposition_filename = NULL; + disposition = g_mime_object_get_content_disposition(mobject); + if (disposition) { + disposition_str = (char *)g_mime_content_disposition_get_disposition(disposition); + disposition_filename = (char *)g_mime_content_disposition_get_parameter(disposition, "filename"); + if (EM_SAFE_STRLEN(disposition_filename) == 0) disposition_filename = NULL; + } + EM_DEBUG_LOG("Disposition[%s]", disposition_str); + EM_DEBUG_LOG_SEC("Disposition-Filename[%s]", disposition_filename); + /*Content Disposition - END*/ + + /*Content Type*/ + GMimeContentType *ctype = NULL; + char *ctype_type = NULL; + char *ctype_subtype = NULL; + char *ctype_charset = NULL; + char *ctype_name = NULL; + + ctype = g_mime_object_get_content_type(mobject); + ctype_type = (char *)g_mime_content_type_get_media_type(ctype); + ctype_subtype = (char *)g_mime_content_type_get_media_subtype(ctype); + ctype_charset = (char *)g_mime_content_type_get_parameter(ctype, "charset"); + ctype_name = (char *)g_mime_content_type_get_parameter(ctype, "name"); + if (EM_SAFE_STRLEN(ctype_name) == 0) ctype_name = NULL; + EM_DEBUG_LOG("Content-Type[%s/%s]", ctype_type, ctype_subtype); + EM_DEBUG_LOG("Content-Type-Charset[%s]", ctype_charset); + EM_DEBUG_LOG("Content-Type-Name[%s]", ctype_name); + /*Content Type - END*/ + + /*Content*/ + if (!emcore_get_temp_file_name(&content_path, &error)) { + EM_DEBUG_EXCEPTION("emcore_get_temp_file_name failed [%d]", error); + goto FINISH_OFF; + } + EM_DEBUG_LOG_SEC("Temporary Content Path[%s]", content_path); + + + GMimeContentEncoding enc = g_mime_part_get_content_encoding(leaf_part); + switch(enc) { + case GMIME_CONTENT_ENCODING_DEFAULT: + EM_DEBUG_LOG("Encoding:ENCODING_DEFAULT"); + break; + case GMIME_CONTENT_ENCODING_7BIT: + EM_DEBUG_LOG("Encoding:ENCODING_7BIT"); + break; + case GMIME_CONTENT_ENCODING_8BIT: + EM_DEBUG_LOG("Encoding:ENCODING_8BIT"); + break; + case GMIME_CONTENT_ENCODING_BINARY: + EM_DEBUG_LOG("Encoding:ENCODING_BINARY"); + break; + case GMIME_CONTENT_ENCODING_BASE64: + EM_DEBUG_LOG("Encoding:ENCODING_BASE64"); + break; + case GMIME_CONTENT_ENCODING_QUOTEDPRINTABLE: + EM_DEBUG_LOG("Encoding:ENCODING_QUOTEDPRINTABLE"); + break; + case GMIME_CONTENT_ENCODING_UUENCODE: + EM_DEBUG_LOG("Encoding:ENCODING_UUENCODE"); + break; + + default: + break; + } + + GMimeDataWrapper *data = g_mime_part_get_content_object(leaf_part); + if (data) { + int fd; + fd = open(content_path, O_WRONLY|O_CREAT, 0644); + if (fd < 0) { + EM_DEBUG_EXCEPTION("open failed"); + goto FINISH_OFF; + } + + GMimeStream *out_stream; + out_stream = g_mime_stream_fs_new(fd); + + //g_mime_data_wrapper_set_stream(data, out_stream); + //g_mime_data_wrapper_set_encoding(data, enc); + g_mime_data_wrapper_write_to_stream(data, out_stream); + if (out_stream) g_object_unref(out_stream); + emcore_get_file_size(content_path, &content_size, NULL); + } + /*Content - END*/ + + /*Figure out TEXT or ATTACHMENT(INLINE) ?*/ + int result = false; + if (disposition_str && g_ascii_strcasecmp(disposition_str, GMIME_DISPOSITION_ATTACHMENT) == 0) { + content_disposition_type = ATTACHMENT; + EM_DEBUG_LOG("ATTACHMENT"); + } else if ((content_id || content_location) && (ctype_name || disposition_filename)) { + if (cnt_info->attachment_only) { + content_disposition_type = ATTACHMENT; + EM_DEBUG_LOG("ATTACHMENT"); + } else { + content_disposition_type = INLINE_ATTACHMENT; + EM_DEBUG_LOG("INLINE_ATTACHMENT"); + } + } else { + if (content_id && + (emcore_search_string_from_file(cnt_info->text.html, content_id, NULL, &result) == EMAIL_ERROR_NONE && result)) { + content_disposition_type = INLINE_ATTACHMENT; + EM_DEBUG_LOG("INLINE_ATTACHMENT"); + } else if (content_id || content_location) { + if (g_ascii_strcasecmp(ctype_type, "text") == 0 && + (g_ascii_strcasecmp(ctype_subtype, "plain") == 0 || g_ascii_strcasecmp(ctype_subtype, "html") == 0)) { + EM_DEBUG_LOG("TEXT"); + } else { + if (cnt_info->attachment_only) { + content_disposition_type = ATTACHMENT; + EM_DEBUG_LOG("ATTACHMENT"); + } else { + content_disposition_type = INLINE_ATTACHMENT; + EM_DEBUG_LOG("INLINE_ATTACHMENT"); + } + } + } else { + if (g_ascii_strcasecmp(ctype_type, "text") == 0 && + (g_ascii_strcasecmp(ctype_subtype, "plain") == 0 || g_ascii_strcasecmp(ctype_subtype, "html") == 0)) { + EM_DEBUG_LOG("TEXT"); + } else { + content_disposition_type = ATTACHMENT; + EM_DEBUG_LOG("ATTACHMENT"); + } + } + } + + if (content_disposition_type != ATTACHMENT && content_disposition_type != INLINE_ATTACHMENT) { + /*TEXT*/ + EM_DEBUG_LOG("TEXT"); + if (ctype_type && g_ascii_strcasecmp(ctype_type, "text") == 0) { + if (!ctype_charset || g_ascii_strcasecmp(ctype_charset, "X-UNKNOWN") == 0) { + ctype_charset = "UTF-8"; + } + + if (ctype_subtype && g_ascii_strcasecmp(ctype_subtype, "plain") == 0) { + EM_DEBUG_LOG("TEXT/PLAIN"); + + char *file_content = NULL; + int content_size = 0; + + if (emcore_get_content_from_file(content_path, &file_content, &content_size) != EMAIL_ERROR_NONE) { + EM_DEBUG_EXCEPTION("emcore_get_content_from_file failed"); + } + + if (file_content && content_size > 0) { + char escape = 0x1b; + char detector[25] = {0,}; + snprintf(detector, sizeof(detector), "%c$B", escape); + if (g_strrstr(ctype_charset, "UTF-8") && g_strrstr(file_content, detector)) { + ctype_charset = "ISO-2022-JP"; + } + } + + EM_SAFE_FREE(file_content); + + cnt_info->text.plain_charset = g_strdup(ctype_charset); + cnt_info->text.plain = g_strdup(content_path); + } else if (ctype_subtype && g_ascii_strcasecmp(ctype_subtype, "html") == 0) { + EM_DEBUG_LOG("TEXT/HTML"); + cnt_info->text.html_charset = g_strdup(ctype_charset); + cnt_info->text.html = g_strdup(content_path); + } + } + } else { + /*ATTACHMENT*/ + struct attachment_info *file = NULL; + struct attachment_info *temp_file = NULL; + char *utf8_text = NULL; + int err = EMAIL_ERROR_NONE; + + if (content_disposition_type == ATTACHMENT) { + EM_DEBUG_LOG("ATTACHMENT"); + temp_file = cnt_info->file; + } + else if (content_disposition_type == INLINE_ATTACHMENT) { + EM_DEBUG_LOG("INLINE ATTACHMENT"); + temp_file = cnt_info->inline_file; + } + else { + EM_DEBUG_EXCEPTION("Invalid content_disposition_type"); + goto FINISH_OFF; + } + + file = em_malloc(sizeof(struct attachment_info)); + if (file == NULL) { + EM_DEBUG_EXCEPTION("em_malloc failed..."); + goto FINISH_OFF; + } + + file->type = content_disposition_type; + if (disposition_filename) file->name = g_strdup(disposition_filename); + else if (ctype_name) file->name = g_strdup(ctype_name); + else if (content_id) file->name = g_strdup(content_id); + else file->name = g_strdup("unknown"); + file->content_id = g_strdup(content_id); + + if (!(utf8_text = g_mime_utils_header_decode_text(file->name))) { + EM_DEBUG_EXCEPTION("g_mime_utils_header_decode_text failed [%d]", err); + } + EM_DEBUG_LOG_SEC("utf8_text : [%s]", utf8_text); + + if (utf8_text) { + EM_SAFE_FREE(file->name); + file->name = EM_SAFE_STRDUP(utf8_text); + } + EM_SAFE_FREE(utf8_text); + + /* check inline name duplication */ + if (content_disposition_type == INLINE_ATTACHMENT) { + char *modified_name = NULL; + if (emcore_gmime_check_filename_duplication(file->name, cnt_info)) { + modified_name = emcore_gmime_get_modified_filename_in_duplication(file->name); + EM_SAFE_FREE(file->name); + file->name = modified_name; + modified_name = NULL; + } + emcore_unescape_from_url(file->name, &modified_name); + EM_DEBUG_LOG_SEC("file->name[%s] modified_name[%s]", file->name, modified_name); + EM_SAFE_FREE(file->name); + file->name = modified_name; + } + + /*cid replacement for inline attachment*/ + if (content_disposition_type == INLINE_ATTACHMENT) { + char *file_content = NULL; + int content_size = 0; + + if (emcore_get_content_from_file(cnt_info->text.html, &file_content, &content_size) != EMAIL_ERROR_NONE) { + EM_DEBUG_EXCEPTION("emcore_get_content_from_file failed"); + } + + if (file_content && content_size > 0) { + em_replace_string_ex(&file_content, "cid:", ""); + em_replace_string_ex(&file_content, file->content_id, file->name); + + content_size = EM_SAFE_STRLEN(file_content); + if (emcore_set_content_to_file(file_content, cnt_info->text.html, content_size) != EMAIL_ERROR_NONE) { + EM_DEBUG_EXCEPTION("emcore_set_content_to_file failed"); + } + } + g_free(file_content); /* prevent 39110 */ + } + + if(ctype_type && ctype_subtype) { + char mime_type_buffer[128] = {0,}; + snprintf(mime_type_buffer, sizeof(mime_type_buffer), "%s/%s", ctype_type, ctype_subtype); + file->attachment_mime_type = g_strdup(mime_type_buffer); + } + + file->save = g_strdup(content_path); + file->size = content_size; + + if (ctype_type && g_ascii_strcasecmp(ctype_type, "APPLICATION") == 0) { + if (ctype_subtype && g_ascii_strcasecmp(ctype_subtype, MIME_SUBTYPE_DRM_OBJECT) == 0) + file->drm = EMAIL_ATTACHMENT_DRM_OBJECT; + else if (ctype_subtype && g_ascii_strcasecmp(ctype_subtype, MIME_SUBTYPE_DRM_RIGHTS) == 0) + file->drm = EMAIL_ATTACHMENT_DRM_RIGHTS; + else if (ctype_subtype && g_ascii_strcasecmp(ctype_subtype, MIME_SUBTYPE_DRM_DCF) == 0) + file->drm = EMAIL_ATTACHMENT_DRM_DCF; + } + + while (temp_file && temp_file->next) + temp_file = temp_file->next; + + if (temp_file == NULL) { + if (content_disposition_type == ATTACHMENT) { + cnt_info->file = file; + } else { + cnt_info->inline_file = file; + } + } + else + temp_file->next = file; + } + + EM_SAFE_FREE(content_path); + } + +FINISH_OFF: + + EM_SAFE_FREE(msg_tmp_content_path); + EM_SAFE_FREE(content_path); + EM_DEBUG_FUNC_END(); +} + +static int emcore_gmime_parse_mime_header(GMimeMessage *message, struct _rfc822header *rfc822_header) +{ + EM_DEBUG_FUNC_BEGIN("message[%p], rfc822header[%p]", message, rfc822_header); + + int err = EMAIL_ERROR_NONE; + + if (!message || !rfc822_header) { + err = EMAIL_ERROR_INVALID_PARAM; + return err; + } + + rfc822_header->reply_to = EM_SAFE_STRDUP(g_mime_message_get_reply_to(message)); + EM_DEBUG_LOG_SEC("reply_to : [%s]", rfc822_header->reply_to); + + rfc822_header->date = EM_SAFE_STRDUP(g_mime_message_get_date_as_string(message)); + EM_DEBUG_LOG_SEC("date : [%s]", rfc822_header->date); + + rfc822_header->subject = EM_SAFE_STRDUP(g_mime_message_get_subject(message)); + EM_DEBUG_LOG_SEC("subject : [%s]", rfc822_header->subject); + + rfc822_header->sender = EM_SAFE_STRDUP(g_mime_message_get_sender(message)); + EM_DEBUG_LOG_SEC("sender : [%s]", rfc822_header->sender); + + rfc822_header->to = EM_SAFE_STRDUP(internet_address_list_to_string(g_mime_message_get_recipients(message, GMIME_RECIPIENT_TYPE_TO), false)); + EM_DEBUG_LOG_SEC("to : [%s]", rfc822_header->to); + + rfc822_header->cc = EM_SAFE_STRDUP(internet_address_list_to_string(g_mime_message_get_recipients(message, GMIME_RECIPIENT_TYPE_CC), false)); + EM_DEBUG_LOG_SEC("cc : [%s]", rfc822_header->cc); + + rfc822_header->bcc = EM_SAFE_STRDUP(internet_address_list_to_string(g_mime_message_get_recipients(message, GMIME_RECIPIENT_TYPE_BCC), false)); + EM_DEBUG_LOG_SEC("bcc : [%s]", rfc822_header->bcc); + + rfc822_header->message_id = EM_SAFE_STRDUP(g_mime_message_get_message_id(message)); + EM_DEBUG_LOG("message_id : [%s]", rfc822_header->message_id); + + rfc822_header->content_type = EM_SAFE_STRDUP(g_mime_object_get_header((GMimeObject *)message, "content-type")); + EM_DEBUG_LOG("content_type : [%s]", rfc822_header->content_type); + + rfc822_header->from = EM_SAFE_STRDUP(g_mime_object_get_header((GMimeObject *)message, "from")); + EM_DEBUG_LOG_SEC("from : [%s]", rfc822_header->from); + + rfc822_header->received = EM_SAFE_STRDUP(g_mime_object_get_header((GMimeObject *)message, "received")); + EM_DEBUG_LOG_SEC("received : [%s]", rfc822_header->received); + + rfc822_header->return_path = EM_SAFE_STRDUP(g_mime_object_get_header((GMimeObject *)message, "return-path")); + EM_DEBUG_LOG_SEC("return_path : [%s]", rfc822_header->return_path); + + rfc822_header->priority = EM_SAFE_STRDUP(g_mime_object_get_header((GMimeObject *)message, "x-priority")); + EM_DEBUG_LOG("priority : [%s]", rfc822_header->priority); + + rfc822_header->ms_priority = EM_SAFE_STRDUP(g_mime_object_get_header((GMimeObject *)message, "x-msmail-priority")); + EM_DEBUG_LOG("ms_priority : [%s]", rfc822_header->ms_priority); + + rfc822_header->dsp_noti_to = EM_SAFE_STRDUP(g_mime_object_get_header((GMimeObject *)message, "disposition-notification-to")); + EM_DEBUG_LOG("dsp_noti_to : [%s]", rfc822_header->dsp_noti_to); + + EM_DEBUG_FUNC_END(); + return err; +} + +static void emcore_gmime_eml_parse_foreach_cb(GMimeObject *parent, GMimeObject *part, gpointer user_data) +{ + EM_DEBUG_FUNC_BEGIN("parent[%p], part[%p], user_data[%p]", parent, part, user_data); + + int error = EMAIL_ERROR_NONE; + int save_status = EMAIL_PART_DOWNLOAD_STATUS_NONE; + char *msg_tmp_content_path = NULL; + char *content_path = NULL; + struct _m_content_info *cnt_info = (struct _m_content_info *)user_data; + + if (GMIME_IS_MESSAGE_PART(part)) { + EM_DEBUG_LOG("Message Part"); + GMimeMessage *message = NULL; + GMimeContentType *msg_ctype = NULL; + GMimeContentDisposition *msg_disposition = NULL; + GMimeStream *out_stream; + char *msg_ctype_type = NULL; + char *msg_ctype_subtype = NULL; + char *msg_ctype_name = NULL; + char *msg_disposition_str = NULL; + char *msg_disposition_filename = NULL; + char *msg_content_id = NULL; + int real_size = 0; + int msg_fd = 0; + + save_status = EMAIL_PART_DOWNLOAD_STATUS_NONE; + + if (cnt_info->grab_type != (GRAB_TYPE_TEXT|GRAB_TYPE_ATTACHMENT) && + cnt_info->grab_type != GRAB_TYPE_ATTACHMENT) { + goto FINISH_OFF; + } + + message = g_mime_message_part_get_message((GMimeMessagePart *)part); + if (!message) { + EM_DEBUG_EXCEPTION("Message is NULL"); + goto FINISH_OFF; + } + + /*Content Type*/ + msg_ctype = g_mime_object_get_content_type(part); + msg_ctype_type = (char *)g_mime_content_type_get_media_type(msg_ctype); + msg_ctype_subtype = (char *)g_mime_content_type_get_media_subtype(msg_ctype); + msg_ctype_name = (char *)g_mime_content_type_get_parameter(msg_ctype, "name"); + EM_DEBUG_LOG("Content-Type[%s/%s]", msg_ctype_type, msg_ctype_subtype); + EM_DEBUG_LOG("RFC822/Message Content-Type-Name[%s]", msg_ctype_name); + /*Content Type - END*/ + + /*Content Disposition*/ + msg_disposition = g_mime_object_get_content_disposition(part); + if (msg_disposition) { + msg_disposition_str = (char *)g_mime_content_disposition_get_disposition(msg_disposition); + msg_disposition_filename = (char *)g_mime_content_disposition_get_parameter(msg_disposition, "filename"); + if (EM_SAFE_STRLEN(msg_disposition_filename) == 0) msg_disposition_filename = NULL; + } + EM_DEBUG_LOG("RFC822/Message Disposition[%s]", msg_disposition_str); + EM_DEBUG_LOG_SEC("RFC822/Message Disposition-Filename[%s]", msg_disposition_filename); + /*Content Disposition - END*/ + + /*Content ID*/ + msg_content_id = (char *)g_mime_object_get_content_id(part); + EM_DEBUG_LOG("RFC822/Message Content-ID:%s", msg_content_id); + + /*save message content to tmp file*/ + if (!emcore_get_temp_file_name(&msg_tmp_content_path, &error)) { + EM_DEBUG_EXCEPTION("emcore_get_temp_file_name failed [%d]", error); + goto FINISH_OFF; + } + EM_DEBUG_LOG_SEC("Temporary Content Path[%s]", msg_tmp_content_path); + + msg_fd = open(msg_tmp_content_path, O_WRONLY|O_CREAT, 0644); + if (msg_fd < 0) { + EM_DEBUG_EXCEPTION("open failed"); + goto FINISH_OFF; + } + + out_stream = g_mime_stream_fs_new(msg_fd); + real_size = g_mime_object_write_to_stream(GMIME_OBJECT(message), out_stream); + if (out_stream) g_object_unref(out_stream); + + if (real_size <= 0) { + EM_DEBUG_EXCEPTION("g_mime_object_write_to_stream failed"); + goto FINISH_OFF; + } + + /* rfc822/message type is always saving to the attachment */ + EM_DEBUG_LOG("RFC822/Message is ATTACHMENT"); + + struct attachment_info *file = NULL; + struct attachment_info *temp_file = cnt_info->file; + char *utf8_text = NULL; + int err = EMAIL_ERROR_NONE; + + file = em_malloc(sizeof(struct attachment_info)); + if (file == NULL) { + EM_DEBUG_EXCEPTION("em_malloc failed..."); + goto FINISH_OFF; + } + + file->type = ATTACHMENT; + if (msg_disposition_filename) file->name = g_strdup(msg_disposition_filename); + else if (msg_ctype_name) file->name = g_strdup(msg_ctype_name); + else if (msg_content_id) file->name = g_strdup(msg_content_id); + else file->name = g_strdup("unknown"); + + if (msg_content_id) file->content_id = g_strdup(msg_content_id); + + if (!(utf8_text = g_mime_utils_header_decode_text(file->name))) { + EM_DEBUG_EXCEPTION("g_mime_utils_header_decode_text failed [%d]", err); + } + EM_DEBUG_LOG_SEC("utf8_text : [%s]", utf8_text); + + if (utf8_text) { + EM_SAFE_FREE(file->name); + file->name = EM_SAFE_STRDUP(utf8_text); + } + EM_SAFE_FREE(utf8_text); + + if(msg_ctype_type && msg_ctype_subtype) { + char mime_type_buffer[128] = {0,}; + snprintf(mime_type_buffer, sizeof(mime_type_buffer), "%s/%s", msg_ctype_type, msg_ctype_subtype); + file->attachment_mime_type = g_strdup(mime_type_buffer); + } + + file->save = g_strdup(msg_tmp_content_path); + file->size = real_size; + + while (temp_file && temp_file->next) + temp_file = temp_file->next; + + if (temp_file == NULL) + cnt_info->file = file; + else + temp_file->next = file; + + /* check the partial status */ + int save_status = EMAIL_BODY_DOWNLOAD_STATUS_NONE; + struct _m_content_info *temp_cnt_info = NULL; + struct attachment_info *ai = NULL; + + temp_cnt_info = (struct _m_content_info *)em_malloc(sizeof(struct _m_content_info)); + if (temp_cnt_info == NULL) { + EM_DEBUG_EXCEPTION("em_malloc failed..."); + err = EMAIL_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + g_mime_message_foreach(message, emcore_gmime_eml_parse_foreach_cb, temp_cnt_info); + + save_status = temp_cnt_info->text.plain_save_status; + save_status = temp_cnt_info->text.html_save_status; + + for (ai = temp_cnt_info->file; ai; ai = ai->next) { + save_status = ai->save_status; + } + + for (ai = temp_cnt_info->inline_file; ai; ai = ai->next) { + save_status = ai->save_status; + } + + file->save_status = save_status; + EM_DEBUG_LOG("save_status : [%d], [%d]", file->save_status, save_status); + + if (temp_cnt_info) { + emcore_free_content_info(temp_cnt_info); + EM_SAFE_FREE(temp_cnt_info); + } + + } else if (GMIME_IS_MESSAGE_PARTIAL(part)) { + EM_DEBUG_LOG("Partial Part"); + //TODO + } else if (GMIME_IS_MULTIPART(part)) { + EM_DEBUG_LOG("Multi Part"); + GMimeMultipart *multi_part = NULL; + multi_part = (GMimeMultipart *)part; + + multipart_status = 1; + + int multi_count = g_mime_multipart_get_count(multi_part); + EM_DEBUG_LOG("Multi Part Count:%d", multi_count); + EM_DEBUG_LOG("Boundary:%s\n\n", g_mime_multipart_get_boundary(multi_part)); + + if (GMIME_IS_MULTIPART_SIGNED(part)) + cnt_info->text.mime_entity = emcore_gmime_get_mime_entity_signed_message(part); + + } else if (GMIME_IS_PART(part)) { + EM_DEBUG_LOG("Part"); + int content_size = 0; + + save_status = EMAIL_PART_DOWNLOAD_STATUS_NONE; + + GMimePart *leaf_part = NULL; + leaf_part = (GMimePart *)part; + + EM_DEBUG_LOG("Content ID:%s", g_mime_part_get_content_id(leaf_part)); + EM_DEBUG_LOG("Description:%s", g_mime_part_get_content_description(leaf_part)); + EM_DEBUG_LOG("MD5:%s", g_mime_part_get_content_md5(leaf_part)); + + int content_disposition_type = 0; + char *content_location = (char *)g_mime_part_get_content_location(leaf_part); + EM_DEBUG_LOG_SEC("Location:%s", content_location); + + GMimeObject *mobject = (GMimeObject *)part; + + /*Content ID*/ + char *content_id = (char *)g_mime_object_get_content_id(mobject); + + /*Content Disposition*/ + GMimeContentDisposition *disposition = NULL; + char *disposition_str = NULL; + char *disposition_filename = NULL; + disposition = g_mime_object_get_content_disposition(mobject); + if (disposition) { + disposition_str = (char *)g_mime_content_disposition_get_disposition(disposition); + disposition_filename = (char *)g_mime_content_disposition_get_parameter(disposition, "filename"); + if (EM_SAFE_STRLEN(disposition_filename) == 0) disposition_filename = NULL; + } + EM_DEBUG_LOG("Disposition[%s]", disposition_str); + EM_DEBUG_LOG_SEC("Disposition-Filename[%s]", disposition_filename); + /*Content Disposition - END*/ + + /*Content Type*/ + GMimeContentType *ctype = NULL; + char *ctype_type = NULL; + char *ctype_subtype = NULL; + char *ctype_charset = NULL; + char *ctype_name = NULL; + + ctype = g_mime_object_get_content_type(mobject); + ctype_type = (char *)g_mime_content_type_get_media_type(ctype); + ctype_subtype = (char *)g_mime_content_type_get_media_subtype(ctype); + ctype_charset = (char *)g_mime_content_type_get_parameter(ctype, "charset"); + ctype_name = (char *)g_mime_content_type_get_parameter(ctype, "name"); + if (EM_SAFE_STRLEN(ctype_name) == 0) ctype_name = NULL; + EM_DEBUG_LOG("Content-Type[%s/%s]", ctype_type, ctype_subtype); + EM_DEBUG_LOG("Content-Type-Charset[%s]", ctype_charset); + EM_DEBUG_LOG("Content-Type-Name[%s]", ctype_name); + /*Content Type - END*/ + + /*Content*/ + if (!emcore_get_temp_file_name(&content_path, &error)) { + EM_DEBUG_EXCEPTION("emcore_get_temp_file_name failed [%d]", error); + goto FINISH_OFF; + } + EM_DEBUG_LOG_SEC("Temporary Content Path[%s]", content_path); + + + GMimeContentEncoding enc = g_mime_part_get_content_encoding(leaf_part); + switch(enc) { + case GMIME_CONTENT_ENCODING_DEFAULT: + EM_DEBUG_LOG("Encoding:ENCODING_DEFAULT"); + break; + case GMIME_CONTENT_ENCODING_7BIT: + EM_DEBUG_LOG("Encoding:ENCODING_7BIT"); + break; + case GMIME_CONTENT_ENCODING_8BIT: + EM_DEBUG_LOG("Encoding:ENCODING_8BIT"); + break; + case GMIME_CONTENT_ENCODING_BINARY: + EM_DEBUG_LOG("Encoding:ENCODING_BINARY"); + break; + case GMIME_CONTENT_ENCODING_BASE64: + EM_DEBUG_LOG("Encoding:ENCODING_BASE64"); + break; + case GMIME_CONTENT_ENCODING_QUOTEDPRINTABLE: + EM_DEBUG_LOG("Encoding:ENCODING_QUOTEDPRINTABLE"); + break; + case GMIME_CONTENT_ENCODING_UUENCODE: + EM_DEBUG_LOG("Encoding:ENCODING_UUENCODE"); + break; + + default: + break; + } + + GMimeDataWrapper *data = g_mime_part_get_content_object(leaf_part); + if (data) { + int fd; + fd = open(content_path, O_WRONLY|O_CREAT, 0644); + if (fd < 0) { + EM_DEBUG_EXCEPTION("open failed"); + goto FINISH_OFF; + } + + GMimeStream *out_stream; + out_stream = g_mime_stream_fs_new(fd); + + //g_mime_data_wrapper_set_stream(data, out_stream); + //g_mime_data_wrapper_set_encoding(data, enc); + g_mime_data_wrapper_write_to_stream(data, out_stream); + if (out_stream) g_object_unref(out_stream); + emcore_get_file_size(content_path, &content_size, NULL); + } else { + EM_DEBUG_LOG("Data is NULL"); + goto FINISH_OFF; + } + /*Content - END*/ + + /* Set the partial body */ + GMimeStream *part_stream = g_mime_data_wrapper_get_stream(data); + if (part_stream) { + EM_DEBUG_LOG("part_stream->bound_end : [%lld]", part_stream->bound_end); + EM_DEBUG_LOG("super_stream->position : [%lld]", part_stream->super_stream->position); + EM_DEBUG_LOG("multipart_status : [%d]", multipart_status); + if (multipart_status && part_stream->super_stream->position <= part_stream->bound_end) { + save_status = EMAIL_PART_DOWNLOAD_STATUS_PARTIALLY_DOWNLOADED; + } else { + save_status = EMAIL_PART_DOWNLOAD_STATUS_FULLY_DOWNLOADED; + } + + EM_DEBUG_LOG("save_status : [%d]", save_status); + } + + /*Figure out TEXT or ATTACHMENT(INLINE) ?*/ + int result = false; + cnt_info->total_mail_size += content_size; + if (content_id && (emcore_search_string_from_file(cnt_info->text.html, content_id, NULL, &result) == EMAIL_ERROR_NONE && result)) { + content_disposition_type = INLINE_ATTACHMENT; + cnt_info->total_body_size += content_size; + EM_DEBUG_LOG("INLINE_ATTACHMENT"); + } else if ((disposition_str && g_ascii_strcasecmp(disposition_str, GMIME_DISPOSITION_ATTACHMENT) == 0) || disposition_filename || ctype_name) { + content_disposition_type = ATTACHMENT; + cnt_info->total_attachment_size += content_size; + EM_DEBUG_LOG("ATTACHMENT"); + } else if (ctype_subtype && g_ascii_strcasecmp(ctype_subtype, "delivery-status") == 0) { + content_disposition_type = ATTACHMENT; + cnt_info->total_attachment_size += content_size; + EM_DEBUG_LOG("ATTACHMENT"); + } else if (ctype_subtype && g_ascii_strcasecmp(ctype_subtype, "calendar") == 0) { + content_disposition_type = ATTACHMENT; + cnt_info->total_attachment_size += content_size; + EM_DEBUG_LOG("ATTACHMENT"); + } else { + cnt_info->total_body_size += content_size; + EM_DEBUG_LOG("Not INLINE or ATTACHMENT"); + } + + if (content_disposition_type != ATTACHMENT && content_disposition_type != INLINE_ATTACHMENT) { + /*TEXT*/ + EM_DEBUG_LOG("TEXT"); + if (ctype_type && g_ascii_strcasecmp(ctype_type, "text") == 0) { + if (!ctype_charset || g_ascii_strcasecmp(ctype_charset, "X-UNKNOWN") == 0) { + ctype_charset = "UTF-8"; + } + + if (ctype_subtype && g_ascii_strcasecmp(ctype_subtype, "plain") == 0) { + EM_DEBUG_LOG("TEXT/PLAIN"); + + char *file_content = NULL; + int content_size = 0; + + if (emcore_get_content_from_file(content_path, &file_content, &content_size) != EMAIL_ERROR_NONE) { + EM_DEBUG_EXCEPTION("emcore_get_content_from_file failed"); + } + + if (file_content && content_size > 0) { + char escape = 0x1b; + char detector[25] = {0,}; + snprintf(detector, sizeof(detector), "%c$B", escape); + if (g_strrstr(ctype_charset, "UTF-8") && g_strrstr(file_content, detector)) { + ctype_charset = "ISO-2022-JP"; + } + } + + EM_SAFE_FREE(file_content); + + cnt_info->text.plain_charset = g_strdup(ctype_charset); + cnt_info->text.plain = g_strdup(content_path); + cnt_info->text.plain_save_status = save_status; + } else if (ctype_subtype && g_ascii_strcasecmp(ctype_subtype, "html") == 0) { + EM_DEBUG_LOG("TEXT/HTML"); + cnt_info->text.html_charset = g_strdup(ctype_charset); + cnt_info->text.html = g_strdup(content_path); + cnt_info->text.html_save_status = save_status; + } + } + } else { + /*ATTACHMENT*/ + struct attachment_info *file = NULL; + struct attachment_info *temp_file = NULL; + char *utf8_text = NULL; + int err = EMAIL_ERROR_NONE; + + if (content_disposition_type == ATTACHMENT) { + EM_DEBUG_LOG("ATTACHMENT"); + temp_file = cnt_info->file; + } + else if (content_disposition_type == INLINE_ATTACHMENT) { + EM_DEBUG_LOG("INLINE ATTACHMENT"); + temp_file = cnt_info->inline_file; + } + else { + EM_DEBUG_EXCEPTION("Invalid content_disposition_type"); + goto FINISH_OFF; + } + + file = em_malloc(sizeof(struct attachment_info)); + if (file == NULL) { + EM_DEBUG_EXCEPTION("em_malloc failed..."); + goto FINISH_OFF; + } + + file->type = content_disposition_type; + if (disposition_filename) file->name = g_strdup(disposition_filename); + else if (ctype_name) file->name = g_strdup(ctype_name); + else if (content_id) file->name = g_strdup(content_id); + else if (content_disposition_type == ATTACHMENT) file->name = g_strdup("unknown"); + else if (ctype_subtype && g_ascii_strcasecmp(ctype_subtype, "calendar") == 0) file->name = g_strdup("invite.vcs"); + else file->name = g_strdup("delivery-status"); + file->content_id = g_strdup(content_id); + + if (!(utf8_text = g_mime_utils_header_decode_text(file->name))) { + EM_DEBUG_EXCEPTION("g_mime_utils_header_decode_text failed [%d]", err); + } + EM_DEBUG_LOG_SEC("utf8_text : [%s]", utf8_text); + + if (utf8_text) { + EM_SAFE_FREE(file->name); + file->name = EM_SAFE_STRDUP(utf8_text); + } + EM_SAFE_FREE(utf8_text); + + /* check inline name duplication */ + if (content_disposition_type == INLINE_ATTACHMENT) { + if (emcore_gmime_check_filename_duplication(file->name, cnt_info)) { + char *modified_name= NULL; + modified_name = emcore_gmime_get_modified_filename_in_duplication(file->name); + EM_SAFE_FREE(file->name); + file->name = modified_name; + } + } + + /*cid replacement for inline attachment*/ + if (content_disposition_type == INLINE_ATTACHMENT) { + char *file_content = NULL; + char *encoding_file_name = NULL; + int html_size = 0; + iconv_t cd; + + if (emcore_get_content_from_file(cnt_info->text.html, &file_content, &html_size) != EMAIL_ERROR_NONE) { + EM_DEBUG_EXCEPTION("emcore_get_content_from_file failed"); + } + + EM_DEBUG_LOG_SEC("html_charset : [%s]", cnt_info->text.html_charset); + if (strcasecmp(cnt_info->text.html_charset, "UTF-8") != 0) { + cd = g_mime_iconv_open(cnt_info->text.html_charset, "UTF-8"); + if (cd) { + encoding_file_name = g_mime_iconv_strdup(cd, file->name); + } + + if (cd) + g_mime_iconv_close(cd); + + } else { + encoding_file_name = g_strdup(file->name); + } + + EM_DEBUG_LOG_SEC("File name : [%s], encoding file name : [%s]", file->name, encoding_file_name); + + if (file_content && html_size > 0) { + em_replace_string_ex(&file_content, "cid:", ""); + em_replace_string_ex(&file_content, file->content_id, encoding_file_name); + + html_size = EM_SAFE_STRLEN(file_content); + if (emcore_set_content_to_file(file_content, cnt_info->text.html, html_size) != EMAIL_ERROR_NONE) { + EM_DEBUG_EXCEPTION("emcore_set_content_to_file failed"); + } + } + + g_free(file_content); /* prevent 39110 */ + g_free(encoding_file_name); + } + + if(ctype_type && ctype_subtype) { + char mime_type_buffer[128] = {0,}; + snprintf(mime_type_buffer, sizeof(mime_type_buffer), "%s/%s", ctype_type, ctype_subtype); + file->attachment_mime_type = g_strdup(mime_type_buffer); + } + + file->save_status = save_status; + file->save = g_strdup(content_path); + file->size = content_size; + + if (ctype_type && g_ascii_strcasecmp(ctype_type, "APPLICATION") == 0) { + if (ctype_subtype && g_ascii_strcasecmp(ctype_subtype, MIME_SUBTYPE_DRM_OBJECT) == 0) + file->drm = EMAIL_ATTACHMENT_DRM_OBJECT; + else if (ctype_subtype && g_ascii_strcasecmp(ctype_subtype, MIME_SUBTYPE_DRM_RIGHTS) == 0) + file->drm = EMAIL_ATTACHMENT_DRM_RIGHTS; + else if (ctype_subtype && g_ascii_strcasecmp(ctype_subtype, MIME_SUBTYPE_DRM_DCF) == 0) + file->drm = EMAIL_ATTACHMENT_DRM_DCF; + } + + while (temp_file && temp_file->next) + temp_file = temp_file->next; + + if (temp_file == NULL) { + if (content_disposition_type == ATTACHMENT) { + cnt_info->file = file; + } else { + cnt_info->inline_file = file; + } + } + else + temp_file->next = file; + } + + EM_SAFE_FREE(content_path); + } + +FINISH_OFF: + + EM_SAFE_FREE(msg_tmp_content_path); + EM_SAFE_FREE(content_path); + EM_DEBUG_FUNC_END(); +} + +INTERNAL_FUNC void emcore_gmime_imap_parse_foreach_cb(GMimeObject *parent, GMimeObject *part, gpointer user_data) +{ + EM_DEBUG_FUNC_BEGIN("parent[%p], part[%p], user_data[%p]", parent, part, user_data); + + int error = EMAIL_ERROR_NONE; + struct _m_content_info *cnt_info = (struct _m_content_info *)user_data; + char *content_path = NULL; + + if (GMIME_IS_MESSAGE_PART(part)) { + /* message/rfc822 or message/news */ + GMimeMessage *message = NULL; + GMimeContentType *msg_ctype = NULL; + GMimeContentDisposition *msg_disposition = NULL; + char *msg_ctype_type = NULL; + char *msg_ctype_subtype = NULL; + char *msg_ctype_name = NULL; + char *msg_ctype_size = NULL; + char *msg_disposition_str = NULL; + char *msg_disposition_filename = NULL; + char *msg_content_id = NULL; + unsigned long msg_content_size = 0; + EM_DEBUG_LOG("Message Part"); + + message = g_mime_message_part_get_message((GMimeMessagePart *)part); + if (!message) { + EM_DEBUG_EXCEPTION("Message is NULL"); + goto FINISH_OFF; + } + + /*Content Type*/ + msg_ctype = g_mime_object_get_content_type(part); + msg_ctype_type = (char *)g_mime_content_type_get_media_type(msg_ctype); + msg_ctype_subtype = (char *)g_mime_content_type_get_media_subtype(msg_ctype); + msg_ctype_name = (char *)g_mime_content_type_get_parameter(msg_ctype, "name"); + msg_ctype_size = (char *)g_mime_content_type_get_parameter(msg_ctype, "message_size"); + EM_DEBUG_LOG("Content-Type[%s/%s]", msg_ctype_type, msg_ctype_subtype); + EM_DEBUG_LOG("RFC822/Message Content-Type-Name[%s]", msg_ctype_name); + EM_DEBUG_LOG("Part.size.bytes[%s]", msg_ctype_size); + + if (msg_ctype_size) msg_content_size = atol(msg_ctype_size); + /*Content Type - END*/ + + /*Content Disposition*/ + msg_disposition = g_mime_object_get_content_disposition(part); + if (msg_disposition) { + msg_disposition_str = (char *)g_mime_content_disposition_get_disposition(msg_disposition); + msg_disposition_filename = (char *)g_mime_content_disposition_get_parameter(msg_disposition, "filename"); + if (EM_SAFE_STRLEN(msg_disposition_filename) == 0) msg_disposition_filename = NULL; + } + EM_DEBUG_LOG("RFC822/Message Disposition[%s]", msg_disposition_str); + EM_DEBUG_LOG_SEC("RFC822/Message Disposition-Filename[%s]", msg_disposition_filename); + /*Content Disposition - END*/ + + /*Content ID*/ + msg_content_id = (char *)g_mime_object_get_content_id(part); + EM_DEBUG_LOG("RFC822/Message Content-ID:%s", msg_content_id); + + if (msg_disposition_str && g_ascii_strcasecmp(msg_disposition_str, GMIME_DISPOSITION_ATTACHMENT) == 0) { + EM_DEBUG_LOG("RFC822/Message is ATTACHMENT"); + + struct attachment_info *file = NULL; + struct attachment_info *temp_file = cnt_info->file; + char *utf8_text = NULL; + int err = EMAIL_ERROR_NONE; + + file = em_malloc(sizeof(struct attachment_info)); + if (file == NULL) { + EM_DEBUG_EXCEPTION("em_malloc failed..."); + goto FINISH_OFF; + } + + file->type = ATTACHMENT; + if (msg_disposition_filename) file->name = g_strdup(msg_disposition_filename); + else if (msg_ctype_name) file->name = g_strdup(msg_ctype_name); + else if (msg_content_id) file->name = g_strdup(msg_content_id); + else file->name = g_strdup("unknown"); + + if (msg_content_id) file->content_id = g_strdup(msg_content_id); + + if (!(utf8_text = g_mime_utils_header_decode_text(file->name))) { + EM_DEBUG_EXCEPTION("g_mime_utils_header_decode_text failed [%d]", err); + } + EM_DEBUG_LOG_SEC("utf8_text : [%s]", utf8_text); + + if (utf8_text) { + EM_SAFE_FREE(file->name); + file->name = EM_SAFE_STRDUP(utf8_text); + } + EM_SAFE_FREE(utf8_text); + + if(msg_ctype_type && msg_ctype_subtype) { + char mime_type_buffer[128] = {0,}; + snprintf(mime_type_buffer, sizeof(mime_type_buffer), "%s/%s", msg_ctype_type, msg_ctype_subtype); + file->attachment_mime_type = g_strdup(mime_type_buffer); + } + + file->save = NULL; + file->size = msg_content_size; + file->save_status = 0; + + while (temp_file && temp_file->next) + temp_file = temp_file->next; + + if (temp_file == NULL) + cnt_info->file = file; + else + temp_file->next = file; + } + + //g_mime_message_foreach(message, emcore_gmime_imap_parse_foreach_cb, user_data); + + } else if (GMIME_IS_MESSAGE_PARTIAL(part)) { + /* message/partial */ + + EM_DEBUG_LOG("Partial Part"); + //TODO + } else if (GMIME_IS_MULTIPART(part)) { + /* multipart/mixed, multipart/alternative, + * multipart/related, multipart/signed, + * multipart/encrypted, etc... */ + EM_DEBUG_LOG("Multi Part"); + GMimeMultipart *multi_part = NULL; + multi_part = (GMimeMultipart *)part; + + int multi_count = g_mime_multipart_get_count(multi_part); + EM_DEBUG_LOG("Multi Part Count:%d", multi_count); + EM_DEBUG_LOG("Boundary:%s", g_mime_multipart_get_boundary(multi_part)); + + } else if (GMIME_IS_PART(part)) { + /* a normal leaf part, could be text/plain or + * image/jpeg etc */ + + EM_DEBUG_LOG("Part"); + int download_status = 0; + int content_disposition_type = 0; + char *content_id = NULL; + char *content_location = NULL; + char *disposition_str = NULL; + char *disposition_filename = NULL; + int disposition_size = 0; + char *disposition_size_str = NULL; + char *ctype_type = NULL; + char *ctype_subtype = NULL; + char *ctype_charset = NULL; + char *ctype_name = NULL; + char *ctype_size = NULL; + unsigned long content_size = 0; + int real_size = 0; + + GMimeContentType *ctype = NULL; + GMimeContentDisposition *disposition = NULL; + GMimePart *leaf_part = NULL; + GMimeObject *mobject = (GMimeObject *)part; + leaf_part = (GMimePart *)part; + + /*Content Type*/ + ctype = g_mime_object_get_content_type(mobject); + ctype_type = (char *)g_mime_content_type_get_media_type(ctype); + ctype_subtype = (char *)g_mime_content_type_get_media_subtype(ctype); + ctype_charset = (char *)g_mime_content_type_get_parameter(ctype, "charset"); + ctype_name = (char *)g_mime_content_type_get_parameter(ctype, "name"); + ctype_size = (char *)g_mime_content_type_get_parameter(ctype, "part_size"); + if (EM_SAFE_STRLEN(ctype_name) == 0) ctype_name = NULL; + EM_DEBUG_LOG("Content-Type[%s/%s]", ctype_type, ctype_subtype); + EM_DEBUG_LOG("Content-Type-Charset[%s]", ctype_charset); + EM_DEBUG_LOG_SEC("Content-Type-Name[%s]", ctype_name); + EM_DEBUG_LOG("Part.size.bytes[%s]", ctype_size); + + if (ctype_size) content_size = atol(ctype_size); + /*Content Type - END*/ + + /*Content Disposition*/ + disposition = g_mime_object_get_content_disposition(mobject); + if (disposition) { + disposition_str = (char *)g_mime_content_disposition_get_disposition(disposition); + disposition_filename = (char *)g_mime_content_disposition_get_parameter(disposition, "filename"); + if (EM_SAFE_STRLEN(disposition_filename) == 0) disposition_filename = NULL; + disposition_size_str = (char *)g_mime_content_disposition_get_parameter(disposition, "size"); + if (disposition_size_str) disposition_size = atoi(disposition_size_str); + } + EM_DEBUG_LOG("Disposition[%s]", disposition_str); + EM_DEBUG_LOG_SEC("Disposition-Filename[%s]", disposition_filename); + EM_DEBUG_LOG("Disposition size[%d]", disposition_size); + /*Content Disposition - END*/ + + /*Content ID*/ + content_id = (char *)g_mime_object_get_content_id(mobject); + EM_DEBUG_LOG_SEC("Content-ID:%s", content_id); + + /*Content Location*/ + content_location = (char *)g_mime_part_get_content_location(leaf_part); + EM_DEBUG_LOG_SEC("Content-Location:%s", content_location); + + /*Figure out TEXT or ATTACHMENT(INLINE) ?*/ + int result = false; + if (disposition_str && g_ascii_strcasecmp(disposition_str, GMIME_DISPOSITION_ATTACHMENT) == 0) { + if (content_id && + (emcore_search_string_from_file(cnt_info->text.html, content_id, NULL, &result) == EMAIL_ERROR_NONE && result)) { + content_disposition_type = INLINE_ATTACHMENT; + EM_DEBUG_LOG("INLINE_ATTACHMENT"); + } else { + content_disposition_type = ATTACHMENT; + EM_DEBUG_LOG("ATTACHMENT"); + } + } else if ((content_id || content_location) && (ctype_name || disposition_filename)) { + if (cnt_info->attachment_only) { + content_disposition_type = ATTACHMENT; + EM_DEBUG_LOG("ATTACHMENT"); + } else { + content_disposition_type = INLINE_ATTACHMENT; + EM_DEBUG_LOG("INLINE_ATTACHMENT"); + } + } else { + if (content_id && + (emcore_search_string_from_file(cnt_info->text.html, content_id, NULL, &result) == EMAIL_ERROR_NONE && result)) { + content_disposition_type = INLINE_ATTACHMENT; + EM_DEBUG_LOG("INLINE_ATTACHMENT"); + } else if (content_id || content_location) { + if (g_ascii_strcasecmp(ctype_type, "text") == 0 && + (g_ascii_strcasecmp(ctype_subtype, "plain") == 0 || g_ascii_strcasecmp(ctype_subtype, "html") == 0)) { + EM_DEBUG_LOG("TEXT"); + } else { + if (cnt_info->attachment_only) { + content_disposition_type = ATTACHMENT; + EM_DEBUG_LOG("ATTACHMENT"); + } else { + content_disposition_type = INLINE_ATTACHMENT; + EM_DEBUG_LOG("INLINE_ATTACHMENT"); + } + } + } else { + if (g_ascii_strcasecmp(ctype_type, "text") == 0 && + (g_ascii_strcasecmp(ctype_subtype, "plain") == 0 || g_ascii_strcasecmp(ctype_subtype, "html") == 0)) { + EM_DEBUG_LOG("TEXT"); + } else { + content_disposition_type = ATTACHMENT; + EM_DEBUG_LOG("ATTACHMENT"); + } + } + } + + /*if (content_id && (emcore_search_string_from_file(cnt_info->text.html, content_id, NULL, &result) == EMAIL_ERROR_NONE && result)) { + content_disposition_type = INLINE_ATTACHMENT; + EM_DEBUG_LOG("INLINE_ATTACHMENT"); + } else if ((disposition_str && g_ascii_strcasecmp(disposition_str, GMIME_DISPOSITION_ATTACHMENT) == 0) || disposition_filename || ctype_name) { + content_disposition_type = ATTACHMENT; + EM_DEBUG_LOG("ATTACHMENT"); + }*/ + + if (!emcore_get_temp_file_name(&content_path, &error)) { + EM_DEBUG_EXCEPTION("emcore_get_temp_file_name failed [%d]", error); + goto FINISH_OFF; + } + EM_DEBUG_LOG_SEC("Temporary Content Path[%s]", content_path); + + if (content_disposition_type != ATTACHMENT) { + /*Content*/ + GMimeContentEncoding enc = g_mime_part_get_content_encoding(leaf_part); + switch(enc) { + case GMIME_CONTENT_ENCODING_DEFAULT: + EM_DEBUG_LOG("Encoding:ENCODING_DEFAULT"); + break; + case GMIME_CONTENT_ENCODING_7BIT: + EM_DEBUG_LOG("Encoding:ENCODING_7BIT"); + break; + case GMIME_CONTENT_ENCODING_8BIT: + EM_DEBUG_LOG("Encoding:ENCODING_8BIT"); + break; + case GMIME_CONTENT_ENCODING_BINARY: + EM_DEBUG_LOG("Encoding:ENCODING_BINARY"); + break; + case GMIME_CONTENT_ENCODING_BASE64: + EM_DEBUG_LOG("Encoding:ENCODING_BASE64"); + break; + case GMIME_CONTENT_ENCODING_QUOTEDPRINTABLE: + EM_DEBUG_LOG("Encoding:ENCODING_QUOTEDPRINTABLE"); + break; + case GMIME_CONTENT_ENCODING_UUENCODE: + EM_DEBUG_LOG("Encoding:ENCODING_UUENCODE"); + break; + + default: + break; + } + + GMimeDataWrapper *data = g_mime_part_get_content_object(leaf_part); + if (data) { + EM_DEBUG_LOG_DEV("DataWrapper/ref-cnt[%d]", data->parent_object.ref_count); + int fd = 0; + int src_length = 0; + GMimeStream *out_stream = NULL; + GMimeStream *src_stream = NULL; + + fd = open(content_path, 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; + } + + out_stream = g_mime_stream_fs_new(fd); + src_stream = g_mime_data_wrapper_get_stream(data); + if (src_stream) src_length = g_mime_stream_length(src_stream); + EM_DEBUG_LOG_DEV("Data length [%d]", src_length); + + if (src_length >= content_size) /* fully downloaded */ + download_status = EMAIL_PART_DOWNLOAD_STATUS_FULLY_DOWNLOADED; + else /* partialy downloaded */ + download_status = EMAIL_PART_DOWNLOAD_STATUS_PARTIALLY_DOWNLOADED; + + /*g_mime_data_wrapper_set_stream(data, out_stream); + g_mime_data_wrapper_set_encoding(data, enc);*/ + + g_mime_data_wrapper_write_to_stream(data, out_stream); + if (out_stream) g_object_unref(out_stream); + emcore_get_file_size(content_path, &real_size, NULL); + } + /*Content - END*/ + } + + if (content_disposition_type != ATTACHMENT && content_disposition_type != INLINE_ATTACHMENT) { + /*TEXT*/ + EM_DEBUG_LOG("TEXT"); + + if (ctype_type && g_ascii_strcasecmp(ctype_type, "text") == 0) { + if (!ctype_charset || g_ascii_strcasecmp(ctype_charset, "X-UNKNOWN") == 0) { + ctype_charset = "UTF-8"; + } + + if (ctype_subtype && g_ascii_strcasecmp(ctype_subtype, "plain") == 0) { + EM_DEBUG_LOG("TEXT/PLAIN"); + + char *file_content = NULL; + int content_size = 0; + + if (emcore_get_content_from_file(content_path, &file_content, &content_size) != EMAIL_ERROR_NONE) { + EM_DEBUG_EXCEPTION("emcore_get_content_from_file failed"); + } + + if (file_content && content_size > 0) { + char escape = 0x1b; + char detector[25] = {0,}; + snprintf(detector, sizeof(detector), "%c$B", escape); + if (g_strrstr(ctype_charset, "UTF-8") && g_strrstr(file_content, detector)) { + ctype_charset = "ISO-2022-JP"; + } + } + + EM_SAFE_FREE(file_content); + + cnt_info->text.plain_charset = g_strdup(ctype_charset); + cnt_info->text.plain = g_strdup(content_path); + } else if (ctype_subtype && g_ascii_strcasecmp(ctype_subtype, "html") == 0) { + EM_DEBUG_LOG("TEXT/HTML"); + cnt_info->text.html_charset = g_strdup(ctype_charset); + cnt_info->text.html = g_strdup(content_path); + } + } + } else if (content_disposition_type == INLINE_ATTACHMENT) { + + struct attachment_info *file = NULL; + struct attachment_info *temp_file = cnt_info->inline_file; + char *utf8_text = NULL; + char *file_content = NULL; + int file_size = 0; + int err = EMAIL_ERROR_NONE; + + file = em_malloc(sizeof(struct attachment_info)); + if (file == NULL) { + EM_DEBUG_EXCEPTION("em_malloc failed..."); + goto FINISH_OFF; + } + + file->type = content_disposition_type; + if (disposition_filename) file->name = g_strdup(disposition_filename); + else if (ctype_name) file->name = g_strdup(ctype_name); + else if (content_id) file->name = g_strdup(content_id); + file->content_id = g_strdup(content_id); + + if (file->name && g_strrstr(file->name, "/") != NULL) { + char *tmp_ptr = file->name; + int tmp_len = EM_SAFE_STRLEN(file->name); + int tmpi = 0; + for (tmpi=0; tmpiname[%s]", file->name); + } + + if (!(utf8_text = g_mime_utils_header_decode_text(file->name))) { + EM_DEBUG_EXCEPTION("g_mime_utils_header_decode_text failed [%d]", err); + } + EM_DEBUG_LOG_SEC("utf8_text : [%s]", utf8_text); + + if (utf8_text) { + EM_SAFE_FREE(file->name); + file->name = EM_SAFE_STRDUP(utf8_text); + } + EM_SAFE_FREE(utf8_text); + + /* check inline name duplication */ + char *modified_name = NULL; + if (emcore_gmime_check_filename_duplication(file->name, cnt_info)) { + modified_name = emcore_gmime_get_modified_filename_in_duplication(file->name); + EM_SAFE_FREE(file->name); + file->name = modified_name; + modified_name = NULL; + } + + emcore_unescape_from_url(file->name, &modified_name); + EM_DEBUG_LOG_SEC("file->name[%s] modified_name[%s]", file->name, modified_name); + EM_SAFE_FREE(file->name); + file->name = modified_name; + + /*cid replacement for inline attachment*/ + if (emcore_get_content_from_file(cnt_info->text.html, &file_content, &file_size) != EMAIL_ERROR_NONE) { + EM_DEBUG_EXCEPTION("emcore_get_content_from_file failed"); + } + + if (file_content && file_size > 0) { + em_replace_string_ex(&file_content, "cid:", ""); + em_replace_string_ex(&file_content, file->content_id, file->name); + + file_size = EM_SAFE_STRLEN(file_content); + if (emcore_set_content_to_file(file_content, cnt_info->text.html, file_size) != EMAIL_ERROR_NONE) { + EM_DEBUG_EXCEPTION("emcore_set_content_to_file failed"); + } + } + g_free(file_content); /* prevent 39110 */ + + if(ctype_type && ctype_subtype) { + char mime_type_buffer[128] = {0,}; + snprintf(mime_type_buffer, sizeof(mime_type_buffer), "%s/%s", ctype_type, ctype_subtype); + file->attachment_mime_type = g_strdup(mime_type_buffer); + } + + file->save = g_strdup(content_path); + file->size = disposition_size ? disposition_size : content_size; + if (download_status == EMAIL_PART_DOWNLOAD_STATUS_FULLY_DOWNLOADED) { + file->save_status = 1; + file->size = real_size; + } + else + file->save_status = 0; + + while (temp_file && temp_file->next) + temp_file = temp_file->next; + + if (temp_file == NULL) + cnt_info->inline_file = file; + else + temp_file->next = file; + } else if (content_disposition_type == ATTACHMENT) { + + struct attachment_info *file = NULL; + struct attachment_info *temp_file = cnt_info->file; + char *utf8_text = NULL; + int err = EMAIL_ERROR_NONE; + + file = em_malloc(sizeof(struct attachment_info)); + if (file == NULL) { + EM_DEBUG_EXCEPTION("em_malloc failed..."); + goto FINISH_OFF; + } + + file->type = content_disposition_type; + if (disposition_filename) file->name = g_strdup(disposition_filename); + else if (ctype_name) file->name = g_strdup(ctype_name); + else if (content_id) file->name = g_strdup(content_id); + else file->name = g_strdup("unknown-attachment"); + + file->content_id = g_strdup(content_id); + + if (!(utf8_text = g_mime_utils_header_decode_text(file->name))) { + EM_DEBUG_EXCEPTION("g_mime_utils_header_decode_text failed [%d]", err); + } + EM_DEBUG_LOG_SEC("utf8_text : [%s]", utf8_text); + + if (utf8_text) { + EM_SAFE_FREE(file->name); + file->name = EM_SAFE_STRDUP(utf8_text); + } + EM_SAFE_FREE(utf8_text); + + if(ctype_type && ctype_subtype) { + char mime_type_buffer[128] = {0,}; + snprintf(mime_type_buffer, sizeof(mime_type_buffer), "%s/%s", ctype_type, ctype_subtype); + file->attachment_mime_type = g_strdup(mime_type_buffer); + } + + file->save = g_strdup(content_path); + file->size = disposition_size ? disposition_size : content_size; + file->save_status = 0; + + if (ctype_type && g_ascii_strcasecmp(ctype_type, "APPLICATION") == 0) { + if (ctype_subtype && g_ascii_strcasecmp(ctype_subtype, MIME_SUBTYPE_DRM_OBJECT) == 0) + file->drm = EMAIL_ATTACHMENT_DRM_OBJECT; + else if (ctype_subtype && g_ascii_strcasecmp(ctype_subtype, MIME_SUBTYPE_DRM_RIGHTS) == 0) + file->drm = EMAIL_ATTACHMENT_DRM_RIGHTS; + else if (ctype_subtype && g_ascii_strcasecmp(ctype_subtype, MIME_SUBTYPE_DRM_DCF) == 0) + file->drm = EMAIL_ATTACHMENT_DRM_DCF; + } + + while (temp_file && temp_file->next) + temp_file = temp_file->next; + + if (temp_file == NULL) + cnt_info->file = file; + else + temp_file->next = file; + } + + EM_SAFE_FREE(content_path); + } + +FINISH_OFF: + + EM_SAFE_FREE(content_path); + + EM_DEBUG_FUNC_END(); +} + + +INTERNAL_FUNC void emcore_gmime_imap_parse_full_foreach_cb(GMimeObject *parent, GMimeObject *part, gpointer user_data) +{ + EM_DEBUG_FUNC_BEGIN("parent[%p], part[%p], user_data[%p]", parent, part, user_data); + + int error = EMAIL_ERROR_NONE; + struct _m_content_info *cnt_info = (struct _m_content_info *)user_data; + char *content_path = NULL; + + if (GMIME_IS_MESSAGE_PART(part)) { + EM_DEBUG_LOG("Message Part"); + GMimeContentType *msg_ctype = NULL; + GMimeContentDisposition *msg_disposition = NULL; + char *msg_ctype_type = NULL; + char *msg_ctype_subtype = NULL; + char *msg_ctype_name = NULL; + char *msg_disposition_str = NULL; + char *msg_disposition_filename = NULL; + char *msg_content_id = NULL; + char *msg_tmp_content_path = NULL; + int real_size = 0; + + if (cnt_info->grab_type != (GRAB_TYPE_TEXT | GRAB_TYPE_ATTACHMENT) && + cnt_info->grab_type != GRAB_TYPE_ATTACHMENT) { + goto FINISH_OFF; + } + + /*Content Type*/ + msg_ctype = g_mime_object_get_content_type(part); + msg_ctype_type = (char *)g_mime_content_type_get_media_type(msg_ctype); + msg_ctype_subtype = (char *)g_mime_content_type_get_media_subtype(msg_ctype); + msg_ctype_name = (char *)g_mime_content_type_get_parameter(msg_ctype, "name"); + msg_tmp_content_path = (char *)g_mime_content_type_get_parameter(msg_ctype, "tmp_content_path"); + EM_DEBUG_LOG("Content-Type[%s/%s]", msg_ctype_type, msg_ctype_subtype); + EM_DEBUG_LOG_SEC("RFC822/Message Content-Type-Name[%s]", msg_ctype_name); + EM_DEBUG_LOG_SEC("RFC822/Message Content-Type-tmp-path[%s]", msg_tmp_content_path); + /*Content Type - END*/ + + /*Content Disposition*/ + msg_disposition = g_mime_object_get_content_disposition(part); + if (msg_disposition) { + msg_disposition_str = (char *)g_mime_content_disposition_get_disposition(msg_disposition); + msg_disposition_filename = (char *)g_mime_content_disposition_get_parameter(msg_disposition, "filename"); + if (EM_SAFE_STRLEN(msg_disposition_filename) == 0) msg_disposition_filename = NULL; + } + EM_DEBUG_LOG("RFC822/Message Disposition[%s]", msg_disposition_str); + EM_DEBUG_LOG_SEC("RFC822/Message Disposition-Filename[%s]", msg_disposition_filename); + /*Content Disposition - END*/ + + /*Content ID*/ + msg_content_id = (char *)g_mime_object_get_content_id(part); + EM_DEBUG_LOG("RFC822/Message Content-ID:%s", msg_content_id); + + emcore_get_file_size(msg_tmp_content_path, &real_size, NULL); + if (real_size <= 0) { + EM_DEBUG_EXCEPTION("tmp content file is not valid"); + goto FINISH_OFF; + } + + if (msg_disposition_str && g_ascii_strcasecmp(msg_disposition_str, GMIME_DISPOSITION_ATTACHMENT) == 0) { + EM_DEBUG_LOG("RFC822/Message is ATTACHMENT"); + + struct attachment_info *file = NULL; + struct attachment_info *temp_file = cnt_info->file; + char *utf8_text = NULL; + int err = EMAIL_ERROR_NONE; + + file = em_malloc(sizeof(struct attachment_info)); + if (file == NULL) { + EM_DEBUG_EXCEPTION("em_malloc failed..."); + goto FINISH_OFF; + } + + file->type = ATTACHMENT; + if (msg_disposition_filename) file->name = g_strdup(msg_disposition_filename); + else if (msg_ctype_name) file->name = g_strdup(msg_ctype_name); + else if (msg_content_id) file->name = g_strdup(msg_content_id); + else file->name = g_strdup("unknown"); + + if (msg_content_id) file->content_id = g_strdup(msg_content_id); + + if (!(utf8_text = g_mime_utils_header_decode_text(file->name))) { + EM_DEBUG_EXCEPTION("g_mime_utils_header_decode_text failed [%d]", err); + } + EM_DEBUG_LOG_SEC("utf8_text : [%s]", utf8_text); + + if (utf8_text) { + EM_SAFE_FREE(file->name); + file->name = EM_SAFE_STRDUP(utf8_text); + } + EM_SAFE_FREE(utf8_text); + + if(msg_ctype_type && msg_ctype_subtype) { + char mime_type_buffer[128] = {0,}; + snprintf(mime_type_buffer, sizeof(mime_type_buffer), "%s/%s", msg_ctype_type, msg_ctype_subtype); + file->attachment_mime_type = g_strdup(mime_type_buffer); + } + + file->save = g_strdup(msg_tmp_content_path); + file->size = real_size; + file->save_status = 1; + + while (temp_file && temp_file->next) + temp_file = temp_file->next; + + if (temp_file == NULL) + cnt_info->file = file; + else + temp_file->next = file; + } + + //g_mime_message_foreach(message, emcore_gmime_imap_parse_full_foreach_cb, user_data); + } else if (GMIME_IS_MESSAGE_PARTIAL(part)) { + EM_DEBUG_LOG("Partial Part"); + } else if (GMIME_IS_MULTIPART(part)) { + EM_DEBUG_LOG("Multi Part"); + GMimeMultipart *multi_part = NULL; + multi_part = (GMimeMultipart *)part; + + int multi_count = g_mime_multipart_get_count(multi_part); + EM_DEBUG_LOG("Multi Part Count:%d", multi_count); + EM_DEBUG_LOG("Boundary:%s\n\n", g_mime_multipart_get_boundary(multi_part)); + + } else if (GMIME_IS_PART(part)) { + EM_DEBUG_LOG("Part"); + int content_disposition_type = 0; + int real_size = 0; + char *content_id = NULL; + char *content_location = NULL; + char *disposition_str = NULL; + char *disposition_filename = NULL; + char *ctype_type = NULL; + char *ctype_subtype = NULL; + char *ctype_charset = NULL; + char *ctype_name = NULL; + char *ctype_size = NULL; + char *tmp_path = NULL; + + GMimeContentType *ctype = NULL; + GMimeContentDisposition *disposition = NULL; + GMimePart *leaf_part = NULL; + GMimeObject *mobject = (GMimeObject *)part; + leaf_part = (GMimePart *)part; + + /*Content Type*/ + ctype = g_mime_object_get_content_type(mobject); + ctype_type = (char *)g_mime_content_type_get_media_type(ctype); + ctype_subtype = (char *)g_mime_content_type_get_media_subtype(ctype); + ctype_charset = (char *)g_mime_content_type_get_parameter(ctype, "charset"); + ctype_name = (char *)g_mime_content_type_get_parameter(ctype, "name"); + ctype_size = (char *)g_mime_content_type_get_parameter(ctype, "part_size"); + if (EM_SAFE_STRLEN(ctype_name) == 0) ctype_name = NULL; + EM_DEBUG_LOG("Content-Type[%s/%s]", ctype_type, ctype_subtype); + EM_DEBUG_LOG("Content-Type-Charset[%s]", ctype_charset); + EM_DEBUG_LOG_SEC("Content-Type-Name[%s]", ctype_name); + /*Content Type - END*/ + + /*Content Disposition*/ + disposition = g_mime_object_get_content_disposition(mobject); + if (disposition) { + disposition_str = (char *)g_mime_content_disposition_get_disposition(disposition); + disposition_filename = (char *)g_mime_content_disposition_get_parameter(disposition, "filename"); + if (EM_SAFE_STRLEN(disposition_filename) == 0) disposition_filename = NULL; + } + EM_DEBUG_LOG("Disposition[%s]", disposition_str); + EM_DEBUG_LOG_SEC("Disposition-Filename[%s]", disposition_filename); + /*Content Disposition - END*/ + + /*Content ID*/ + content_id = (char *)g_mime_object_get_content_id(mobject); + EM_DEBUG_LOG_SEC("Content-ID:%s", content_id); + + /*Content Location*/ + content_location = (char *)g_mime_part_get_content_location(leaf_part); + EM_DEBUG_LOG_SEC("Content-Location:%s", content_location); + + + /*Figure out TEXT or ATTACHMENT(INLINE) ?*/ + int result = false; + if (disposition_str && g_ascii_strcasecmp(disposition_str, GMIME_DISPOSITION_ATTACHMENT) == 0) { + content_disposition_type = ATTACHMENT; + EM_DEBUG_LOG("ATTACHMENT"); + } else if ((content_id || content_location) && (ctype_name || disposition_filename)) { + if (cnt_info->attachment_only) { + content_disposition_type = ATTACHMENT; + EM_DEBUG_LOG("ATTACHMENT"); + } else { + content_disposition_type = INLINE_ATTACHMENT; + EM_DEBUG_LOG("INLINE_ATTACHMENT"); + } + } else { + if (content_id && + (emcore_search_string_from_file(cnt_info->text.html, content_id, NULL, &result) == EMAIL_ERROR_NONE && result)) { + content_disposition_type = INLINE_ATTACHMENT; + EM_DEBUG_LOG("INLINE_ATTACHMENT"); + } else if (content_id || content_location) { + if (g_ascii_strcasecmp(ctype_type, "text") == 0 && + (g_ascii_strcasecmp(ctype_subtype, "plain") == 0 || g_ascii_strcasecmp(ctype_subtype, "html") == 0)) { + EM_DEBUG_LOG("TEXT"); + } else { + if (cnt_info->attachment_only) { + content_disposition_type = ATTACHMENT; + EM_DEBUG_LOG("ATTACHMENT"); + } else { + content_disposition_type = INLINE_ATTACHMENT; + EM_DEBUG_LOG("INLINE_ATTACHMENT"); + } + } + } else { + if (g_ascii_strcasecmp(ctype_type, "text") == 0 && + (g_ascii_strcasecmp(ctype_subtype, "plain") == 0 || g_ascii_strcasecmp(ctype_subtype, "html") == 0)) { + EM_DEBUG_LOG("TEXT"); + } else { + content_disposition_type = ATTACHMENT; + EM_DEBUG_LOG("ATTACHMENT"); + } + } + } + + /*if (content_id && (emcore_search_string_from_file(cnt_info->text.html, content_id, NULL, &result) == EMAIL_ERROR_NONE && result)) { + content_disposition_type = INLINE_ATTACHMENT; + EM_DEBUG_LOG("INLINE_ATTACHMENT"); + } else if ((disposition_str && g_ascii_strcasecmp(disposition_str, GMIME_DISPOSITION_ATTACHMENT) == 0) || disposition_filename || ctype_name) { + content_disposition_type = ATTACHMENT; + EM_DEBUG_LOG("ATTACHMENT"); + }*/ + + /*Content*/ + if (!emcore_get_temp_file_name(&content_path, &error)) { + EM_DEBUG_EXCEPTION("emcore_get_temp_file_name failed [%d]", error); + goto FINISH_OFF; + } + EM_DEBUG_LOG_SEC("Temporary Content Path[%s]", content_path); + + GMimeContentEncoding enc = g_mime_part_get_content_encoding(leaf_part); + switch(enc) { + case GMIME_CONTENT_ENCODING_DEFAULT: + EM_DEBUG_LOG("Encoding:ENCODING_DEFAULT"); + break; + case GMIME_CONTENT_ENCODING_7BIT: + EM_DEBUG_LOG("Encoding:ENCODING_7BIT"); + break; + case GMIME_CONTENT_ENCODING_8BIT: + EM_DEBUG_LOG("Encoding:ENCODING_8BIT"); + break; + case GMIME_CONTENT_ENCODING_BINARY: + EM_DEBUG_LOG("Encoding:ENCODING_BINARY"); + break; + case GMIME_CONTENT_ENCODING_BASE64: + EM_DEBUG_LOG("Encoding:ENCODING_BASE64"); + break; + case GMIME_CONTENT_ENCODING_QUOTEDPRINTABLE: + EM_DEBUG_LOG("Encoding:ENCODING_QUOTEDPRINTABLE"); + break; + case GMIME_CONTENT_ENCODING_UUENCODE: + EM_DEBUG_LOG("Encoding:ENCODING_UUENCODE"); + break; + + default: + break; + } + + GMimeDataWrapper *data = g_mime_part_get_content_object(leaf_part); + if (data) { + int fd = 0; + GMimeStream *out_stream = NULL; + GMimeStream *src_stream = NULL; + + fd = open(content_path, 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; + } + + out_stream = g_mime_stream_fs_new(fd); + src_stream = g_mime_data_wrapper_get_stream(data); + + if (src_stream) + EM_DEBUG_LOG_DEV("Data length [%d]", g_mime_stream_length(src_stream)); + + /*g_mime_data_wrapper_set_stream(data, out_stream); + g_mime_data_wrapper_set_encoding(data, enc);*/ + + g_mime_data_wrapper_write_to_stream(data, out_stream); + if (out_stream) g_object_unref(out_stream); + emcore_get_file_size(content_path, &real_size, NULL); + } + else + { + int fd = 0; + fd = open(content_path, 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; + } + close(fd); + } + /*Content - END*/ + + ctype = g_mime_object_get_content_type(mobject); + tmp_path = (char *)g_mime_content_type_get_parameter(ctype, "tmp_content_path"); + if (tmp_path) { + g_remove(tmp_path); + } + + if (content_disposition_type != ATTACHMENT && content_disposition_type != INLINE_ATTACHMENT) { + /*TEXT*/ + EM_DEBUG_LOG("TEXT"); + + if (ctype_type && g_ascii_strcasecmp(ctype_type, "text") == 0) { + if (!ctype_charset || g_ascii_strcasecmp(ctype_charset, "X-UNKNOWN") == 0) { + ctype_charset = "UTF-8"; + } + + if (ctype_subtype && g_ascii_strcasecmp(ctype_subtype, "plain") == 0) { + EM_DEBUG_LOG("TEXT/PLAIN"); + + char *file_content = NULL; + int content_size = 0; + + if (emcore_get_content_from_file(content_path, &file_content, &content_size) != EMAIL_ERROR_NONE) { + EM_DEBUG_EXCEPTION("emcore_get_content_from_file failed"); + } + + if (file_content && content_size > 0) { + char escape = 0x1b; + char detector[25] = {0,}; + snprintf(detector, sizeof(detector), "%c$B", escape); + if (g_strrstr(ctype_charset, "UTF-8") && g_strrstr(file_content, detector)) { + ctype_charset = "ISO-2022-JP"; + } + } + + EM_SAFE_FREE(file_content); + EM_SAFE_FREE(cnt_info->text.plain_charset); + EM_SAFE_FREE(cnt_info->text.plain); + + cnt_info->text.plain_charset = g_strdup(ctype_charset); + cnt_info->text.plain = g_strdup(content_path); + } else if (ctype_subtype && g_ascii_strcasecmp(ctype_subtype, "html") == 0) { + EM_DEBUG_LOG("TEXT/HTML"); + + EM_SAFE_FREE(cnt_info->text.html_charset); + EM_SAFE_FREE(cnt_info->text.html); + + cnt_info->text.html_charset = g_strdup(ctype_charset); + cnt_info->text.html = g_strdup(content_path); + } + } + } else if (content_disposition_type == INLINE_ATTACHMENT) { + + struct attachment_info *file = NULL; + struct attachment_info *temp_file = cnt_info->inline_file; + char *utf8_text = NULL; + char *file_content = NULL; + int file_size = 0; + int err = EMAIL_ERROR_NONE; + + file = em_malloc(sizeof(struct attachment_info)); + if (file == NULL) { + EM_DEBUG_EXCEPTION("em_malloc failed..."); + goto FINISH_OFF; + } + + file->type = content_disposition_type; + if (disposition_filename) file->name = g_strdup(disposition_filename); + else if (ctype_name) file->name = g_strdup(ctype_name); + else if (content_id) file->name = g_strdup(content_id); + file->content_id = g_strdup(content_id); + + if (file->name && g_strrstr(file->name, "/") != NULL) { + char *tmp_ptr = file->name; + int tmp_len = EM_SAFE_STRLEN(file->name); + int tmpi = 0; + for (tmpi=0; tmpiname[%s]", file->name); + } + + if (!(utf8_text = g_mime_utils_header_decode_text(file->name))) { + EM_DEBUG_EXCEPTION("g_mime_utils_header_decode_text failed [%d]", err); + } + EM_DEBUG_LOG_SEC("utf8_text : [%s]", utf8_text); + + if (utf8_text) { + EM_SAFE_FREE(file->name); + file->name = EM_SAFE_STRDUP(utf8_text); + } + EM_SAFE_FREE(utf8_text); + + /* check inline name duplication */ + char *modified_name= NULL; + if (emcore_gmime_check_filename_duplication(file->name, cnt_info)) { + modified_name = emcore_gmime_get_modified_filename_in_duplication(file->name); + EM_SAFE_FREE(file->name); + file->name = modified_name; + } + + char *modified_name2 = NULL; + emcore_unescape_from_url(file->name, &modified_name2); + EM_DEBUG_LOG_SEC("file->name[%s] modified_name[%s]", file->name, modified_name2); + EM_SAFE_FREE(file->name); + file->name = modified_name2; + + /* cid replacement for inline attachment */ + if (emcore_get_content_from_file(cnt_info->text.html, &file_content, &file_size) != EMAIL_ERROR_NONE) { + EM_DEBUG_EXCEPTION("emcore_get_content_from_file failed"); + } + + if (file_content && file_size > 0) { + EM_DEBUG_LOG_SEC("content_id[%s] name[%s]", file->content_id, file->name); + em_replace_string_ex(&file_content, "cid:", ""); + em_replace_string_ex(&file_content, file->content_id, file->name); + + file_size = EM_SAFE_STRLEN(file_content); + if (emcore_set_content_to_file(file_content, cnt_info->text.html, file_size) != EMAIL_ERROR_NONE) { + EM_DEBUG_EXCEPTION("emcore_set_content_to_file failed"); + } + } + g_free(file_content); /* prevent 39110 */ + + if(ctype_type && ctype_subtype) { + char mime_type_buffer[128] = {0,}; + snprintf(mime_type_buffer, sizeof(mime_type_buffer), "%s/%s", ctype_type, ctype_subtype); + file->attachment_mime_type = g_strdup(mime_type_buffer); + } + + file->save = g_strdup(content_path); + file->size = real_size; + file->save_status = 1; + + while (temp_file && temp_file->next) + temp_file = temp_file->next; + + if (temp_file == NULL) + cnt_info->inline_file = file; + else + temp_file->next = file; + } else if (content_disposition_type == ATTACHMENT) { + + struct attachment_info *file = NULL; + struct attachment_info *temp_file = cnt_info->file; + char *utf8_text = NULL; + int err = EMAIL_ERROR_NONE; + + file = em_malloc(sizeof(struct attachment_info)); + if (file == NULL) { + EM_DEBUG_EXCEPTION("em_malloc failed..."); + goto FINISH_OFF; + } + + file->type = content_disposition_type; + if (disposition_filename) file->name = g_strdup(disposition_filename); + else if (ctype_name) file->name = g_strdup(ctype_name); + else if (content_id) file->name = g_strdup(content_id); + else file->name = g_strdup("unknown-attachment"); + + file->content_id = g_strdup(content_id); + + if (!(utf8_text = g_mime_utils_header_decode_text(file->name))) { + EM_DEBUG_EXCEPTION("g_mime_utils_header_decode_text failed [%d]", err); + } + EM_DEBUG_LOG_SEC("utf8_text : [%s]", utf8_text); + + if (utf8_text) { + EM_SAFE_FREE(file->name); + file->name = EM_SAFE_STRDUP(utf8_text); + } + EM_SAFE_FREE(utf8_text); + + if(ctype_type && ctype_subtype) { + char mime_type_buffer[128] = {0,}; + snprintf(mime_type_buffer, sizeof(mime_type_buffer), "%s/%s", ctype_type, ctype_subtype); + file->attachment_mime_type = g_strdup(mime_type_buffer); + } + + file->save = g_strdup(content_path); + if (real_size == 0 && ctype_size) + file->size = atoi(ctype_size); + else + file->size = real_size; + file->save_status = 1; + + if (ctype_type && g_ascii_strcasecmp(ctype_type, "APPLICATION") == 0) { + if (ctype_subtype && g_ascii_strcasecmp(ctype_subtype, MIME_SUBTYPE_DRM_OBJECT) == 0) + file->drm = EMAIL_ATTACHMENT_DRM_OBJECT; + else if (ctype_subtype && g_ascii_strcasecmp(ctype_subtype, MIME_SUBTYPE_DRM_RIGHTS) == 0) + file->drm = EMAIL_ATTACHMENT_DRM_RIGHTS; + else if (ctype_subtype && g_ascii_strcasecmp(ctype_subtype, MIME_SUBTYPE_DRM_DCF) == 0) + file->drm = EMAIL_ATTACHMENT_DRM_DCF; + } + + while (temp_file && temp_file->next) + temp_file = temp_file->next; + + if (temp_file == NULL) + cnt_info->file = file; + else + temp_file->next = file; + } + + EM_SAFE_FREE(content_path); + } + +FINISH_OFF: + + EM_SAFE_FREE(content_path); + EM_DEBUG_FUNC_END(); +} + +INTERNAL_FUNC void emcore_gmime_imap_parse_bodystructure_foreach_cb(GMimeObject *parent, GMimeObject *part, gpointer user_data) +{ + EM_DEBUG_FUNC_BEGIN("parent[%p], part[%p], user_data[%p]", parent, part, user_data); + + int error = EMAIL_ERROR_NONE; + struct _m_content_info *cnt_info = (struct _m_content_info *)user_data; + + if (GMIME_IS_MESSAGE_PART(part)) { + GMimeMessage *message = NULL; + GMimeContentType *msg_ctype = NULL; + GMimeContentDisposition *msg_disposition = NULL; + char *msg_ctype_type = NULL; + char *msg_ctype_subtype = NULL; + char *msg_ctype_size = NULL; + char *msg_disposition_str = NULL; + unsigned long msg_content_size = 0; + EM_DEBUG_LOG("Message Part"); + + message = g_mime_message_part_get_message((GMimeMessagePart *)part); + if (!message) { + EM_DEBUG_EXCEPTION("Message is NULL"); + //goto FINISH_OFF; + } + + /*Content Type*/ + msg_ctype = g_mime_object_get_content_type(part); + msg_ctype_type = (char *)g_mime_content_type_get_media_type(msg_ctype); + msg_ctype_subtype = (char *)g_mime_content_type_get_media_subtype(msg_ctype); + msg_ctype_size = (char *)g_mime_content_type_get_parameter(msg_ctype, "message_size"); + EM_DEBUG_LOG("Content-Type[%s/%s]", msg_ctype_type, msg_ctype_subtype); + EM_DEBUG_LOG("Part.size.bytes[%s]", msg_ctype_size); + + if (msg_ctype_size) msg_content_size = atol(msg_ctype_size); + cnt_info->total_mail_size += msg_content_size; + /*Content Type - END*/ + + /*Content Disposition*/ + msg_disposition = g_mime_object_get_content_disposition(part); + if (msg_disposition) { + msg_disposition_str = (char *)g_mime_content_disposition_get_disposition(msg_disposition); + } + EM_DEBUG_LOG("RFC822/Message Disposition[%s]", msg_disposition_str); + /*Content Disposition - END*/ + + if (msg_disposition_str && g_ascii_strcasecmp(msg_disposition_str, GMIME_DISPOSITION_ATTACHMENT) == 0) { + EM_DEBUG_LOG("RFC822/Message is ATTACHMENT"); + cnt_info->total_attachment_size += msg_content_size; + } + + //g_mime_message_foreach(message, emcore_gmime_imap_parse_bodystructure_foreach_cb, user_data); + } else if (GMIME_IS_MESSAGE_PARTIAL(part)) { + EM_DEBUG_LOG("Partial Part"); + //TODO + } else if (GMIME_IS_MULTIPART_SIGNED(part)) { + EM_DEBUG_LOG("Multi Part Signed"); + } else if (GMIME_IS_MULTIPART(part)) { + EM_DEBUG_LOG("Multi Part"); + GMimeMultipart *multi_part = NULL; + multi_part = (GMimeMultipart *)part; + + int multi_count = g_mime_multipart_get_count(multi_part); + EM_DEBUG_LOG("Multi Part Count:%d", multi_count); + EM_DEBUG_LOG("Boundary:%s\n\n", g_mime_multipart_get_boundary(multi_part)); + + } else if (GMIME_IS_PART(part)) { + EM_DEBUG_LOG("Part"); + int content_disposition_type = 0; + char *content_id = NULL; + char *content_location = NULL; + char *disposition_str = NULL; + char *disposition_filename = NULL; + char *ctype_type = NULL; + char *ctype_subtype = NULL; + char *ctype_charset = NULL; + char *ctype_name = NULL; + char *ctype_size = NULL; + unsigned long content_size = 0; + + GMimeContentType *ctype = NULL; + GMimeContentDisposition *disposition = NULL; + GMimePart *leaf_part = NULL; + GMimeObject *mobject = (GMimeObject *)part; + leaf_part = (GMimePart *)part; + + /*Content Type*/ + ctype = g_mime_object_get_content_type(mobject); + ctype_type = (char *)g_mime_content_type_get_media_type(ctype); + ctype_subtype = (char *)g_mime_content_type_get_media_subtype(ctype); + ctype_charset = (char *)g_mime_content_type_get_parameter(ctype, "charset"); + ctype_name = (char *)g_mime_content_type_get_parameter(ctype, "name"); + ctype_size = (char *)g_mime_content_type_get_parameter(ctype, "part_size"); + if (EM_SAFE_STRLEN(ctype_name) == 0) ctype_name = NULL; + EM_DEBUG_LOG("Content-Type[%s/%s]", ctype_type, ctype_subtype); + EM_DEBUG_LOG("Content-Type-Charset[%s]", ctype_charset); + EM_DEBUG_LOG("Content-Type-Name[%s]", ctype_name); + EM_DEBUG_LOG("Part.size.bytes[%s]", ctype_size); + + if (ctype_size) content_size = atol(ctype_size); + cnt_info->total_mail_size += content_size; + /*Content Type - END*/ + + /*Content Disposition*/ + disposition = g_mime_object_get_content_disposition(mobject); + if (disposition) { + disposition_str = (char *)g_mime_content_disposition_get_disposition(disposition); + disposition_filename = (char *)g_mime_content_disposition_get_parameter(disposition, "filename"); + if (EM_SAFE_STRLEN(disposition_filename) == 0) disposition_filename = NULL; + } + EM_DEBUG_LOG("Disposition[%s]", disposition_str); + EM_DEBUG_LOG_SEC("Disposition-Filename[%s]", disposition_filename); + /*Content Disposition - END*/ + + /*Content ID*/ + content_id = (char *)g_mime_object_get_content_id(mobject); + EM_DEBUG_LOG_SEC("Content-ID:%s", content_id); + + /*Content Location*/ + content_location = (char *)g_mime_part_get_content_location(leaf_part); + EM_DEBUG_LOG_SEC("Content-Location:%s", content_location); + + /*Figure out TEXT or ATTACHMENT(INLINE) */ + if (disposition_str && g_ascii_strcasecmp(disposition_str, GMIME_DISPOSITION_ATTACHMENT) == 0) { + content_disposition_type = ATTACHMENT; + cnt_info->total_attachment_size += content_size; + EM_DEBUG_LOG("ATTACHMENT"); + } else if ((content_id || content_location) && (ctype_name || disposition_filename)) { + if (cnt_info->attachment_only) { + content_disposition_type = ATTACHMENT; + cnt_info->total_attachment_size += content_size; + EM_DEBUG_LOG("ATTACHMENT"); + } else { + content_disposition_type = INLINE_ATTACHMENT; + cnt_info->total_body_size += content_size; + EM_DEBUG_LOG("INLINE_ATTACHMENT"); + } + } else { + if (content_id || content_location) { + if (g_ascii_strcasecmp(ctype_type, "text") == 0 && + (g_ascii_strcasecmp(ctype_subtype, "plain") == 0 || + g_ascii_strcasecmp(ctype_subtype, "html") == 0)) { + cnt_info->total_body_size += content_size; + EM_DEBUG_LOG("TEXT"); + } else { + if (cnt_info->attachment_only) { + content_disposition_type = ATTACHMENT; + cnt_info->total_attachment_size += content_size; + EM_DEBUG_LOG("ATTACHMENT"); + } else { + content_disposition_type = INLINE_ATTACHMENT; + cnt_info->total_body_size += content_size; + EM_DEBUG_LOG("INLINE_ATTACHMENT"); + } + } + } else { + if (g_ascii_strcasecmp(ctype_type, "text") == 0 && + (g_ascii_strcasecmp(ctype_subtype, "plain") == 0 || + g_ascii_strcasecmp(ctype_subtype, "html") == 0)) { + cnt_info->total_body_size += content_size; + EM_DEBUG_LOG("TEXT"); + } else { + content_disposition_type = ATTACHMENT; + cnt_info->total_attachment_size += content_size; + EM_DEBUG_LOG("ATTACHMENT"); + } + } + } + + if (content_disposition_type != ATTACHMENT && content_disposition_type != INLINE_ATTACHMENT) { + /*TEXT*/ + EM_DEBUG_LOG("TEXT"); + + if (ctype_type && g_ascii_strcasecmp(ctype_type, "text") == 0) { + char *tmp_file = NULL; + + if (!ctype_charset || g_ascii_strcasecmp(ctype_charset, "X-UNKNOWN") == 0) { + ctype_charset = "UTF-8"; + } + + if (!emcore_get_temp_file_name(&tmp_file, &error) || !tmp_file) { + EM_DEBUG_EXCEPTION("emcore_get_temp_file_name failed [%d]", error); + EM_SAFE_FREE(tmp_file); + goto FINISH_OFF; + } + + if (ctype_subtype && g_ascii_strcasecmp(ctype_subtype, "plain") == 0) { + EM_DEBUG_LOG("TEXT/PLAIN"); + cnt_info->text.plain_charset = g_strdup(ctype_charset); + cnt_info->text.plain = tmp_file; + } + else if (ctype_subtype && g_ascii_strcasecmp(ctype_subtype, "html") == 0) { + EM_DEBUG_LOG("TEXT/HTML"); + cnt_info->text.html_charset = g_strdup(ctype_charset); + cnt_info->text.html = tmp_file; + } + } + } + } + +FINISH_OFF: + + EM_DEBUG_FUNC_END(); +} + + +INTERNAL_FUNC void emcore_gmime_get_body_sections_foreach_cb(GMimeObject *parent, + GMimeObject *part, + gpointer user_data) +{ + EM_DEBUG_FUNC_BEGIN("parent[%p], part[%p], user_data[%p]", parent, part, user_data); + + struct _m_content_info *cnt_info = (struct _m_content_info *)user_data; + char sections[IMAP_MAX_COMMAND_LENGTH] = {0,}; + + if (GMIME_IS_MESSAGE_PART(part)) { + EM_DEBUG_LOG("Message Part"); + + if (cnt_info->grab_type != (GRAB_TYPE_TEXT|GRAB_TYPE_ATTACHMENT)) { + EM_DEBUG_LOG("grab_type is not GRAB_TYPE_TEXT|GRAB_TYPE_ATTACHMENT"); + goto FINISH_OFF; + } + + GMimeMessage *message = NULL; + GMimeContentDisposition *msg_disposition = NULL; + GMimeContentType *msg_ctype = NULL; + char *msg_disposition_str = NULL; + char *msg_ctype_section = NULL; + + message = g_mime_message_part_get_message((GMimeMessagePart *)part); + if (!message) { + EM_DEBUG_EXCEPTION("Message is NULL"); + //goto FINISH_OFF; + } + + /*Content Disposition*/ + msg_disposition = g_mime_object_get_content_disposition(part); + if (msg_disposition) { + msg_disposition_str = (char *)g_mime_content_disposition_get_disposition(msg_disposition); + } + EM_DEBUG_LOG("RFC822/Message Disposition[%s]", msg_disposition_str); + /*Content Disposition - END*/ + + if (!msg_disposition_str || g_ascii_strcasecmp(msg_disposition_str, GMIME_DISPOSITION_ATTACHMENT) != 0) { + goto FINISH_OFF; + } + + msg_ctype = g_mime_object_get_content_type(part); + msg_ctype_section = (char *)g_mime_content_type_get_parameter(msg_ctype, "section"); + EM_DEBUG_LOG("section[%s]", msg_ctype_section); + + if (!msg_ctype_section) { + EM_DEBUG_LOG("section is NULL"); + goto FINISH_OFF; + } + + snprintf(sections, sizeof(sections), "BODY.PEEK[%s]", msg_ctype_section); + + EM_DEBUG_LOG("sections <%s>", sections); + + if (cnt_info->sections) { + char *tmp_str = NULL; + tmp_str = g_strconcat(cnt_info->sections, " ", sections, NULL); + + if (tmp_str) { + EM_SAFE_FREE(cnt_info->sections); + cnt_info->sections = tmp_str; + } + } + else { + cnt_info->sections = EM_SAFE_STRDUP(sections); + } + + EM_DEBUG_LOG("sections <%s>", cnt_info->sections); + } else if (GMIME_IS_MESSAGE_PARTIAL(part)) { + EM_DEBUG_LOG("Partial Part"); + } else if (GMIME_IS_MULTIPART_SIGNED(part)) { + EM_DEBUG_LOG("Multi Part Signed"); + snprintf(sections, sizeof(sections), "BODY.PEEK[1.mime] BODY.PEEK[1]"); + + if (cnt_info->sections) { + char *tmp_str = NULL; + tmp_str = g_strconcat(cnt_info->sections, " ", sections, NULL); + + if (tmp_str) { + EM_SAFE_FREE(cnt_info->sections); + cnt_info->sections = tmp_str; + } + } + else { + cnt_info->sections = EM_SAFE_STRDUP(sections); + } + + EM_DEBUG_LOG("sections <%s>", cnt_info->sections); + + } else if (GMIME_IS_MULTIPART(part)) { + EM_DEBUG_LOG("Multi Part"); + } else if (GMIME_IS_PART(part)) { + EM_DEBUG_LOG("Part"); + int content_disposition_type = 0; + char *content_id = NULL; + char *content_location = NULL; + char *disposition_str = NULL; + char *disposition_filename = NULL; + char *ctype_type = NULL; + char *ctype_subtype = NULL; + char *ctype_name = NULL; + char *ctype_section = NULL; + + GMimeContentType *ctype = NULL; + GMimeContentDisposition *disposition = NULL; + GMimePart *leaf_part = NULL; + GMimeObject *mobject = (GMimeObject *)part; + leaf_part = (GMimePart *)part; + + /*Content Type*/ + ctype = g_mime_object_get_content_type(mobject); + ctype_type = (char *)g_mime_content_type_get_media_type(ctype); + ctype_subtype = (char *)g_mime_content_type_get_media_subtype(ctype); + ctype_name = (char *)g_mime_content_type_get_parameter(ctype, "name"); + if (EM_SAFE_STRLEN(ctype_name) == 0) ctype_name = NULL; + ctype_section = (char *)g_mime_content_type_get_parameter(ctype, "section"); + EM_DEBUG_LOG("Content-Type-Name[%s]", ctype_name); + EM_DEBUG_LOG("Content-Type-Section[%s]", ctype_section); + + if (!ctype_section) { + EM_DEBUG_LOG("section is NULL"); + goto FINISH_OFF; + } + /*Content Type - END*/ + + /*Content Disposition*/ + disposition = g_mime_object_get_content_disposition(mobject); + if (disposition) { + disposition_str = (char *)g_mime_content_disposition_get_disposition(disposition); + disposition_filename = (char *)g_mime_content_disposition_get_parameter(disposition, "filename"); + if (EM_SAFE_STRLEN(disposition_filename) == 0) disposition_filename = NULL; + } + EM_DEBUG_LOG("Disposition[%s]", disposition_str); + EM_DEBUG_LOG_SEC("Disposition-Filename[%s]", disposition_filename); + /*Content Disposition - END*/ + + /*Content ID*/ + content_id = (char *)g_mime_object_get_content_id(mobject); + EM_DEBUG_LOG_SEC("Content-ID:%s", content_id); + + /*Content Location*/ + content_location = (char *)g_mime_part_get_content_location(leaf_part); + EM_DEBUG_LOG_SEC("Content-Location:%s", content_location); + + /*Figure out TEXT or ATTACHMENT(INLINE) */ + if (disposition_str && g_ascii_strcasecmp(disposition_str, GMIME_DISPOSITION_ATTACHMENT) == 0) { + content_disposition_type = ATTACHMENT; + EM_DEBUG_LOG("ATTACHMENT"); + } else if ((content_id || content_location) && (ctype_name || disposition_filename)) { + if (cnt_info->attachment_only) { + content_disposition_type = ATTACHMENT; + EM_DEBUG_LOG("ATTACHMENT"); + } else { + content_disposition_type = INLINE_ATTACHMENT; + EM_DEBUG_LOG("INLINE_ATTACHMENT"); + } + } else { + if (content_id || content_location) { + if (g_ascii_strcasecmp(ctype_type, "text") == 0 && + (g_ascii_strcasecmp(ctype_subtype, "plain") == 0 || + g_ascii_strcasecmp(ctype_subtype, "html") == 0)) { + EM_DEBUG_LOG("TEXT"); + } else { + if (cnt_info->attachment_only) { + content_disposition_type = ATTACHMENT; + EM_DEBUG_LOG("ATTACHMENT"); + } else { + content_disposition_type = INLINE_ATTACHMENT; + EM_DEBUG_LOG("INLINE_ATTACHMENT"); + } + } + } else { + if (g_ascii_strcasecmp(ctype_type, "text") == 0 && + (g_ascii_strcasecmp(ctype_subtype, "plain") == 0 || + g_ascii_strcasecmp(ctype_subtype, "html") == 0)) { + EM_DEBUG_LOG("TEXT"); + } else { + content_disposition_type = ATTACHMENT; + EM_DEBUG_LOG("ATTACHMENT"); + } + } + } + + if (content_disposition_type == ATTACHMENT) { + EM_DEBUG_LOG("ATTACHMENT"); + + if (cnt_info->grab_type != (GRAB_TYPE_TEXT|GRAB_TYPE_ATTACHMENT)) + goto FINISH_OFF; + } + else { + snprintf(sections, sizeof(sections), "BODY.PEEK[%s.MIME] BODY.PEEK[%s]", ctype_section, ctype_section); + + if (cnt_info->sections) { + + if (strcasestr(cnt_info->sections, "BODY.PEEK[1.MIME] BODY.PEEK[1]")) { + if (strcasestr(sections, "1.")) + goto FINISH_OFF; + } + + char *tmp_str = NULL; + tmp_str = g_strconcat(cnt_info->sections, " ", sections, NULL); + + if (tmp_str) { + EM_SAFE_FREE(cnt_info->sections); + cnt_info->sections = tmp_str; + } + } + else { + cnt_info->sections = EM_SAFE_STRDUP(sections); + } + + EM_DEBUG_LOG("sections <%s>", cnt_info->sections); + } + } + +FINISH_OFF: + + EM_DEBUG_FUNC_END(); +} + + +INTERNAL_FUNC void emcore_gmime_get_attachment_section_foreach_cb(GMimeObject *parent, + GMimeObject *part, + gpointer user_data) +{ + EM_DEBUG_FUNC_BEGIN("parent[%p], part[%p], user_data[%p]", parent, part, user_data); + + struct _m_content_info *cnt_info = (struct _m_content_info *)user_data; + char sections[IMAP_MAX_COMMAND_LENGTH] = {0,}; + + if (GMIME_IS_MESSAGE_PART(part)) { + EM_DEBUG_LOG("Message Part"); + + if (cnt_info->grab_type != GRAB_TYPE_ATTACHMENT) { + EM_DEBUG_LOG("grab_type is not GRAB_TYPE_ATTACHMENT"); + goto FINISH_OFF; + } + + GMimeMessage *message = NULL; + GMimeContentDisposition *msg_disposition = NULL; + GMimeContentType *msg_ctype = NULL; + char *msg_disposition_str = NULL; + char *msg_ctype_section = NULL; + + message = g_mime_message_part_get_message((GMimeMessagePart *)part); + if (!message) { + EM_DEBUG_EXCEPTION("Message is NULL"); + //goto FINISH_OFF; + } + + /*Content Disposition*/ + msg_disposition = g_mime_object_get_content_disposition(part); + if (msg_disposition) { + msg_disposition_str = (char *)g_mime_content_disposition_get_disposition(msg_disposition); + } + EM_DEBUG_LOG("RFC822/Message Disposition[%s]", msg_disposition_str); + /*Content Disposition - END*/ + + if (!msg_disposition_str || g_ascii_strcasecmp(msg_disposition_str, GMIME_DISPOSITION_ATTACHMENT) != 0) { + goto FINISH_OFF; + } + + if (--cnt_info->file_no != 0) + goto FINISH_OFF; + + msg_ctype = g_mime_object_get_content_type(part); + msg_ctype_section = (char *)g_mime_content_type_get_parameter(msg_ctype, "section"); + EM_DEBUG_LOG("section[%s]", msg_ctype_section); + + if (!msg_ctype_section) { + EM_DEBUG_LOG("section is NULL"); + goto FINISH_OFF; + } + + snprintf(sections, sizeof(sections), "%s", msg_ctype_section); + + EM_DEBUG_LOG("sections <%s>", sections); + + if (!cnt_info->sections) { + cnt_info->sections = EM_SAFE_STRDUP(sections); + } + + EM_DEBUG_LOG("sections <%s>", cnt_info->sections); + } else if (GMIME_IS_MESSAGE_PARTIAL(part)) { + EM_DEBUG_LOG("Partial Part"); + } else if (GMIME_IS_MULTIPART(part)) { + EM_DEBUG_LOG("Multi Part"); + } else if (GMIME_IS_PART(part)) { + EM_DEBUG_LOG("Part"); + int content_disposition_type = 0; + char *content_id = NULL; + char *content_location = NULL; + char *disposition_str = NULL; + char *disposition_filename = NULL; + char *ctype_type = NULL; + char *ctype_subtype = NULL; + char *ctype_name = NULL; + char *ctype_section = NULL; + + GMimeContentType *ctype = NULL; + GMimeContentDisposition *disposition = NULL; + GMimePart *leaf_part = NULL; + GMimeObject *mobject = (GMimeObject *)part; + leaf_part = (GMimePart *)part; + + if (cnt_info->grab_type != GRAB_TYPE_ATTACHMENT) { + EM_DEBUG_LOG("grab_type is not GRAB_TYPE_ATTACHMENT"); + goto FINISH_OFF; + } + + /*Content Type*/ + ctype = g_mime_object_get_content_type(mobject); + ctype_type = (char *)g_mime_content_type_get_media_type(ctype); + ctype_subtype = (char *)g_mime_content_type_get_media_subtype(ctype); + ctype_name = (char *)g_mime_content_type_get_parameter(ctype, "name"); + if (EM_SAFE_STRLEN(ctype_name) == 0) ctype_name = NULL; + ctype_section = (char *)g_mime_content_type_get_parameter(ctype, "section"); + EM_DEBUG_LOG("Content-Type-Name[%s]", ctype_name); + EM_DEBUG_LOG("Content-Type-Section[%s]", ctype_section); + + if (!ctype_section) { + EM_DEBUG_LOG("section is NULL"); + goto FINISH_OFF; + } + /*Content Type - END*/ + + /*Content Disposition*/ + disposition = g_mime_object_get_content_disposition(mobject); + if (disposition) { + disposition_str = (char *)g_mime_content_disposition_get_disposition(disposition); + disposition_filename = (char *)g_mime_content_disposition_get_parameter(disposition, "filename"); + if (EM_SAFE_STRLEN(disposition_filename) == 0) disposition_filename = NULL; + } + EM_DEBUG_LOG("Disposition[%s]", disposition_str); + EM_DEBUG_LOG("Disposition-Filename[%s]", disposition_filename); + /*Content Disposition - END*/ + + /*Content ID*/ + content_id = (char *)g_mime_object_get_content_id(mobject); + EM_DEBUG_LOG_SEC("Content-ID:%s", content_id); + + /*Content Location*/ + content_location = (char *)g_mime_part_get_content_location(leaf_part); + EM_DEBUG_LOG_SEC("Content-Location:%s", content_location); + + /*Figure out TEXT or ATTACHMENT(INLINE) */ + if (disposition_str && g_ascii_strcasecmp(disposition_str, GMIME_DISPOSITION_ATTACHMENT) == 0) { + content_disposition_type = ATTACHMENT; + EM_DEBUG_LOG("ATTACHMENT"); + } else if ((content_id || content_location) && (ctype_name || disposition_filename)) { + if (cnt_info->attachment_only) { + content_disposition_type = ATTACHMENT; + EM_DEBUG_LOG("ATTACHMENT"); + } else { + content_disposition_type = INLINE_ATTACHMENT; + EM_DEBUG_LOG("INLINE_ATTACHMENT"); + } + } else { + if (content_id || content_location) { + if (g_ascii_strcasecmp(ctype_type, "text") == 0 && + (g_ascii_strcasecmp(ctype_subtype, "plain") == 0 || + g_ascii_strcasecmp(ctype_subtype, "html") == 0)) { + EM_DEBUG_LOG("TEXT"); + } else { + if (cnt_info->attachment_only) { + content_disposition_type = ATTACHMENT; + EM_DEBUG_LOG("ATTACHMENT"); + } else { + content_disposition_type = INLINE_ATTACHMENT; + EM_DEBUG_LOG("INLINE_ATTACHMENT"); + } + } + } else { + if (g_ascii_strcasecmp(ctype_type, "text") == 0 && + (g_ascii_strcasecmp(ctype_subtype, "plain") == 0 || + g_ascii_strcasecmp(ctype_subtype, "html") == 0)) { + EM_DEBUG_LOG("TEXT"); + } else { + content_disposition_type = ATTACHMENT; + EM_DEBUG_LOG("ATTACHMENT"); + } + } + } + + if (content_disposition_type == ATTACHMENT) { + EM_DEBUG_LOG("ATTACHMENT"); + + if (--cnt_info->file_no != 0) + goto FINISH_OFF; + + snprintf(sections, sizeof(sections), "%s", ctype_section); + + if (!cnt_info->sections) { + cnt_info->sections = EM_SAFE_STRDUP(sections); + } + + EM_DEBUG_LOG("sections <%s>", cnt_info->sections); + } + } + +FINISH_OFF: + + EM_DEBUG_FUNC_END(); +} + +INTERNAL_FUNC void emcore_gmime_search_section_foreach_cb(GMimeObject *parent, GMimeObject *part, gpointer user_data) +{ + EM_DEBUG_FUNC_BEGIN(); + + search_section *search_info = (search_section *)user_data; + GMimeContentType *ctype = NULL; + char buf[255] = {0}; + char *ctype_section = NULL; + + if (!search_info) { + EM_DEBUG_LOG("search_info is NULL"); + goto FINISH_OFF; + } + + if (!part) { + EM_DEBUG_LOG("part is NULL"); + goto FINISH_OFF; + } + + if (GMIME_IS_MESSAGE_PART(part)) { + EM_DEBUG_LOG("Message Part"); + } else if (GMIME_IS_MESSAGE_PARTIAL(part)) { + EM_DEBUG_LOG("Partial Part"); + } else if (GMIME_IS_MULTIPART(part)) { + EM_DEBUG_LOG("Multi Part"); + } else if (GMIME_IS_PART(part)) { + EM_DEBUG_LOG("Part"); + } + + ctype = g_mime_object_get_content_type(part); + ctype_section = (char *)g_mime_content_type_get_parameter(ctype, "section"); + EM_DEBUG_LOG("section[%s]", ctype_section); + + if (!ctype_section) { + EM_DEBUG_LOG("section is NULL"); + goto FINISH_OFF; + } + + SNPRINTF(buf, sizeof(buf), "%s.MIME", ctype_section); + + if (g_ascii_strcasecmp(ctype_section, search_info->section) == 0) { + EM_DEBUG_LOG("found section"); + if (!(search_info->section_object)) search_info->section_object = part; + } else if (g_ascii_strcasecmp(search_info->section, buf) == 0) { + EM_DEBUG_LOG("Mime header"); + if (!(search_info->section_object)) search_info->section_object = part; + } + +FINISH_OFF: + + EM_DEBUG_FUNC_END(); +} + +INTERNAL_FUNC void emcore_gmime_get_mime_entity_cb(GMimeObject *parent, GMimeObject *part, gpointer user_data) +{ + EM_DEBUG_FUNC_BEGIN(); + + struct _m_content_info *cnt_info = (struct _m_content_info *)user_data; + + if (GMIME_IS_MESSAGE_PART(part)) { + EM_DEBUG_LOG("Message Part"); + } else if (GMIME_IS_MESSAGE_PARTIAL(part)) { + EM_DEBUG_LOG("Partial Part"); + } else if (GMIME_IS_MULTIPART_SIGNED(part)) { + EM_DEBUG_LOG("Multi Part Signed"); + cnt_info->text.mime_entity = emcore_gmime_get_mime_entity_signed_message(part); + } else if (GMIME_IS_MULTIPART(part)) { + EM_DEBUG_LOG("Multi Part"); + } else if (GMIME_IS_PART(part)) { + EM_DEBUG_LOG("Part"); + } + + EM_DEBUG_FUNC_END(); +} + +INTERNAL_FUNC void emcore_gmime_construct_multipart (GMimeMultipart *multipart, + BODY *body, + const char *spec, + int *total_mail_size) +{ + EM_DEBUG_FUNC_BEGIN(); + PART *part = NULL; + GMimeObject *subpart = NULL; + GMimeMultipart *sub_multipart = NULL; + GMimeMessagePart *sub_messagepart = NULL; + GMimeMessage *sub_message = NULL; + GMimePart *sub_part = NULL; + char *subspec = NULL; + char *id = NULL; + char *section = NULL; + int i = 1; + + if (!body || !multipart || !spec) { + EM_DEBUG_EXCEPTION("body[%p], multipart[%p], spec[%p]", body, multipart, spec); + return; + } + + subspec = g_alloca (strlen(spec) + 14); + id = g_stpcpy(subspec, spec); + *id++ = '.'; + + EM_DEBUG_LOG("constructing a %s/%s part (%s)", body_types[body->type], + body->subtype, spec); + + /* checkout boundary */ + if (body->parameter) { + PARAMETER *param = body->parameter; + while(param) { + EM_DEBUG_LOG("Content-Type Parameter: attribute[%s], value[%s]", param->attribute, param->value); + param = param->next; + } + } + + part = body->nested.part; + + while (part != NULL) { + sprintf (id, "%d", i++); + + if (EM_SAFE_STRLEN(subspec) > 2) + section = EM_SAFE_STRDUP(subspec+2); + + EM_DEBUG_LOG("constructing a %s/%s part (%s/%s)", body_types[part->body.type], part->body.subtype, + subspec, section); + + if (part->body.type == TYPEMULTIPART) { + /*multipart*/ + char *subtype = g_ascii_strdown(part->body.subtype, -1); + sub_multipart = g_mime_multipart_new_with_subtype(subtype); + EM_SAFE_FREE(subtype); + emcore_gmime_construct_multipart(sub_multipart, &(part->body), subspec, total_mail_size); + + subpart = GMIME_OBJECT(sub_multipart); + } else if (part->body.type == TYPEMESSAGE) { + /*message/rfc822 or message/news*/ + BODY *nested_body = NULL; + MESSAGE *nested_message = NULL; + char *subtype = g_ascii_strdown(part->body.subtype, -1); + sub_messagepart = g_mime_message_part_new(subtype); + EM_SAFE_FREE(subtype); + + subpart = GMIME_OBJECT(sub_messagepart); + + if (part->body.size.bytes > 0) { + char size_str[sizeof(unsigned long)*8+1] = {0,}; + snprintf(size_str, sizeof(size_str), "%lu", part->body.size.bytes); + g_mime_object_set_content_type_parameter(subpart, "message_size", size_str); + } + + nested_message = part->body.nested.msg; + if (nested_message) nested_body = nested_message->body; + + if (!emcore_gmime_construct_mime_part_with_bodystructure(nested_body, &sub_message, subspec, NULL)) { + EM_DEBUG_EXCEPTION("emcore_gmime_construct_mime_part_with_bodystructure failed"); + } else { + g_mime_message_part_set_message(sub_messagepart, sub_message); + if (sub_message) g_object_unref(sub_message); + } + } else { + /*other parts*/ + char *type = g_ascii_strdown(body_types[part->body.type], -1); + char *subtype = g_ascii_strdown(part->body.subtype, -1); + sub_part = g_mime_part_new_with_type(type, subtype); + EM_SAFE_FREE(type); + EM_SAFE_FREE(subtype); + subpart = GMIME_OBJECT(sub_part); + + if (total_mail_size != NULL) { + *total_mail_size = *total_mail_size + (int)part->body.size.bytes; + EM_DEBUG_LOG("body.size.bytes [%d]", part->body.size.bytes); + EM_DEBUG_LOG("total_mail_size [%d]", *total_mail_size); + } + + /* encoding */ + if (part->body.encoding <= 5) { + EM_DEBUG_LOG("Content Encoding: %s", body_encodings[part->body.encoding]); + GMimeContentEncoding encoding = GMIME_CONTENT_ENCODING_DEFAULT; + switch(part->body.encoding) { + case ENC7BIT: + encoding = GMIME_CONTENT_ENCODING_7BIT; + break; + case ENC8BIT: + encoding = GMIME_CONTENT_ENCODING_8BIT; + break; + case ENCBINARY: + encoding = GMIME_CONTENT_ENCODING_BINARY; + break; + case ENCBASE64: + encoding = GMIME_CONTENT_ENCODING_BASE64; + break; + case ENCQUOTEDPRINTABLE: + encoding = GMIME_CONTENT_ENCODING_QUOTEDPRINTABLE; + break; + case ENCOTHER: + encoding = GMIME_CONTENT_ENCODING_DEFAULT; + break; + + default: + break; + } + g_mime_part_set_content_encoding(sub_part, encoding); + } + + /* content description */ + if (part->body.description) { + EM_DEBUG_LOG("Content-Description: %s", part->body.description); + g_mime_part_set_content_description(sub_part, part->body.description); + } + + /* content location */ + if (part->body.location) { + EM_DEBUG_LOG_SEC("Content-Location: %s", part->body.location); + g_mime_part_set_content_location(sub_part, part->body.location); + } + + /* md5 */ + if (part->body.md5) { + EM_DEBUG_LOG("Content-MD5: %s", part->body.md5); + g_mime_part_set_content_md5(sub_part, part->body.md5); + } + + if (part->body.size.bytes > 0) { + char size_str[sizeof(unsigned long)*8+1] = {0,}; + snprintf(size_str, sizeof(size_str), "%lu", part->body.size.bytes); + g_mime_object_set_content_type_parameter(subpart, "part_size", size_str); + } + } + + /* content type */ + if (part->body.parameter) { + PARAMETER *param = part->body.parameter; + while(param) { + EM_DEBUG_LOG("Content-Type Parameter: attribute[%s], value[%s]", param->attribute, param->value); + if (param->attribute || param->value) + g_mime_object_set_content_type_parameter(subpart, param->attribute, param->value); + param = param->next; + } + } + g_mime_object_set_content_type_parameter(subpart, "section", section); + + /* content disposition */ + if (part->body.disposition.type) { + EM_DEBUG_LOG("Content-Disposition: %s", part->body.disposition.type); + char *disposition_type = g_ascii_strdown(part->body.disposition.type, -1); + g_mime_object_set_disposition(subpart, disposition_type); + g_free(disposition_type); + } + + if (part->body.disposition.parameter) { + PARAMETER *param = part->body.disposition.parameter; + while(param) { + EM_DEBUG_LOG_SEC("Content-Disposition Parameter: attribute[%s], value[%s]", param->attribute, param->value); + if (param->attribute || param->value) + g_mime_object_set_content_disposition_parameter(subpart, param->attribute, param->value); + param = param->next; + } + } + + /* content id */ + if (part->body.id) { + EM_DEBUG_LOG_SEC("Content-ID: %s", part->body.id); + int i = 0; + char *cid = EM_SAFE_STRDUP(part->body.id); + g_strstrip(cid); + + while (EM_SAFE_STRLEN(cid) > 0 && cid[i] != '\0') { + if (cid[i] == '<' || cid[i] == '>') + cid[i] = ' '; + i++; + } + + g_strstrip(cid); + EM_DEBUG_LOG_DEV("Content-ID stripped: %s", cid); + g_mime_object_set_content_id(subpart, cid); + EM_SAFE_FREE(cid); + } + + g_mime_multipart_add (multipart, subpart); + + if (subpart) { + g_object_unref (subpart); + subpart = NULL; + } + + EM_SAFE_FREE(section); + + part = part->next; + } + + EM_DEBUG_FUNC_END(); +} + +INTERNAL_FUNC void emcore_gmime_construct_part (GMimePart *part, + BODY *body, + const char *spec, + int *total_mail_size) +{ + EM_DEBUG_FUNC_BEGIN(); + GMimeObject *part_object = NULL; + + if (!body || !part || !spec) { + EM_DEBUG_EXCEPTION("body[%p], part[%p] spec[%p]", body, part, spec); + return; + } + + part_object = GMIME_OBJECT(part); + + if (total_mail_size != NULL) { + *total_mail_size = (int)(body->size.bytes); + EM_DEBUG_LOG("total_mail_size [%d]", *total_mail_size); + } + + GMimeContentType *ctype = NULL; + char *ctype_type = NULL; + char *ctype_subtype = NULL; + ctype = g_mime_object_get_content_type(GMIME_OBJECT(part)); + ctype_type = (char *)g_mime_content_type_get_media_type(ctype); + ctype_subtype = (char *)g_mime_content_type_get_media_subtype(ctype); + + /* Type-Subtype */ + if (g_strcmp0(ctype_type, "text") == 0 && g_strcmp0(ctype_subtype, "plain") == 0 && + body->type >= (unsigned int)0 && body->subtype) { + GMimeContentType *content_type = NULL; + char *type = g_ascii_strdown(body_types[body->type], -1); + char *subtype = g_ascii_strdown(body->subtype, -1); + EM_DEBUG_LOG("Content Type: [%s/%s]", type, subtype); + + content_type = g_mime_content_type_new(type, subtype); + g_mime_object_set_content_type(GMIME_OBJECT(part), content_type); + g_object_unref(content_type); + + EM_SAFE_FREE(type); + EM_SAFE_FREE(subtype); + } + + /* encoding */ + if (body->encoding <= 5) { + EM_DEBUG_LOG("Content Encoding: %s", body_encodings[body->encoding]); + GMimeContentEncoding encoding = GMIME_CONTENT_ENCODING_DEFAULT; + switch(body->encoding) { + case ENC7BIT: + encoding = GMIME_CONTENT_ENCODING_7BIT; + break; + case ENC8BIT: + encoding = GMIME_CONTENT_ENCODING_8BIT; + break; + case ENCBINARY: + encoding = GMIME_CONTENT_ENCODING_BINARY; + break; + case ENCBASE64: + encoding = GMIME_CONTENT_ENCODING_BASE64; + break; + case ENCQUOTEDPRINTABLE: + encoding = GMIME_CONTENT_ENCODING_QUOTEDPRINTABLE; + break; + case ENCOTHER: + encoding = GMIME_CONTENT_ENCODING_DEFAULT; + break; + + default: + break; + } + g_mime_part_set_content_encoding(part, encoding); + } + + /* content description */ + if (body->description) { + EM_DEBUG_LOG("Content-Description: %s", body->description); + g_mime_part_set_content_description(part, body->description); + } + + /* content location */ + if (body->location) { + EM_DEBUG_LOG_SEC("Content-Location: %s", body->location); + g_mime_part_set_content_location(part, body->location); + } + + /* md5 */ + if (body->md5) { + EM_DEBUG_LOG("Content-MD5: %s", body->md5); + g_mime_part_set_content_md5(part, body->md5); + } + + /* content type */ + if (body->parameter) { + PARAMETER *param = body->parameter; + while(param) { + EM_DEBUG_LOG("Content-Type Parameter: attribute[%s], value[%s]", param->attribute, param->value); + if (param->attribute || param->value) + g_mime_object_set_content_type_parameter(part_object, param->attribute, param->value); + param = param->next; + } + } + + if (body->size.bytes > 0) { + char size_str[sizeof(unsigned long)*8+1] = {0,}; + snprintf(size_str, sizeof(size_str), "%lu", body->size.bytes); + g_mime_object_set_content_type_parameter(part_object, "part_size", size_str); + } + + if (g_strcmp0(spec, "1") == 0) + g_mime_object_set_content_type_parameter(part_object, "section", spec); + else { + if (EM_SAFE_STRLEN(spec) > 2) { + char *tmp = EM_SAFE_STRDUP(spec+2); + g_mime_object_set_content_type_parameter(part_object, "section", tmp); + EM_SAFE_FREE(tmp); + } + } + + /* content disposition */ + if (body->disposition.type) { + EM_DEBUG_LOG("Content-Disposition: %s", body->disposition.type); + char *disposition_type = g_ascii_strdown(body->disposition.type, -1); + g_mime_object_set_disposition(part_object, disposition_type); + g_free(disposition_type); + } + + if (body->disposition.parameter) { + PARAMETER *param = body->disposition.parameter; + while(param) { + EM_DEBUG_LOG("Content-Disposition Parameter: attribute[%s], value[%s]", param->attribute, param->value); + if (param->attribute || param->value) + g_mime_object_set_content_disposition_parameter(part_object, param->attribute, param->value); + param = param->next; + } + } + + /* content id */ + if (body->id) { + EM_DEBUG_LOG("Content-ID: %s", body->id); + int i = 0; + char *cid = EM_SAFE_STRDUP(body->id); + if (cid) g_strstrip(cid); + + while (strlen(cid) > 0 && cid[i] != '\0') { + if (cid[i] == '<' || cid[i] == '>') + cid[i] = ' '; + i++; + } + + g_strstrip(cid); + EM_DEBUG_LOG_DEV("Content-ID stripped: %s", cid); + g_mime_object_set_content_id(part_object, cid); + EM_SAFE_FREE(cid); + } + + EM_DEBUG_FUNC_END(); +} + +INTERNAL_FUNC int emcore_gmime_construct_mime_part_with_bodystructure(BODY *mbody, + GMimeMessage **message, const char *spec, int *total_mail_size) +{ + EM_DEBUG_FUNC_BEGIN(); + + GMimeMessage *message1 = NULL; + GMimeObject *mime_part = NULL; + GMimeMultipart *multipart = NULL; + GMimePart *singlepart = NULL; + int total_size = 0; + int ret = FALSE; + + if (!mbody || !message) { + EM_DEBUG_EXCEPTION("body[%p], message[%p]", mbody, message); + return ret; + } + + message1 = g_mime_message_new(FALSE); + + /* Construct mime_part of GMimeMessage */ + if (g_ascii_strcasecmp(body_types[mbody->type], "multipart") == 0) { + /* checkout boundary */ + int boundary_ok = 0; + if (mbody->parameter) { + PARAMETER *param = mbody->parameter; + while(param) { + if (g_ascii_strcasecmp(param->attribute, "boundary") == 0 && param->value) + boundary_ok = 1; + param = param->next; + } + } + + if (!boundary_ok) { + EM_DEBUG_EXCEPTION("boundary is not exist in bodystructure"); + goto FINISH_OFF; + } + + char *subtype = g_ascii_strdown(mbody->subtype, -1); + EM_DEBUG_LOG("Constructing a MULTIPART/%s", subtype); + if (g_ascii_strcasecmp(subtype, "signed") == 0) { + multipart = (GMimeMultipart *)g_mime_multipart_signed_new(); + } else { + multipart = g_mime_multipart_new_with_subtype(subtype); + } + + /* Fill up mime part of message1 using bodystructure info */ + emcore_gmime_construct_multipart(multipart, mbody, spec, &total_size); + + mime_part = GMIME_OBJECT(multipart); + EM_SAFE_FREE(subtype); + + if (mbody->parameter) { + PARAMETER *param = mbody->parameter; + while(param) { + EM_DEBUG_LOG("Content-Type Parameter: attribute[%s], value[%s]", param->attribute, param->value); + if (param->attribute || param->value) + g_mime_object_set_content_type_parameter(mime_part, param->attribute, param->value); + param = param->next; + } + } + } + else { + char *type = g_ascii_strdown(body_types[mbody->type], -1); + char *subtype = g_ascii_strdown(mbody->subtype, -1); + singlepart = g_mime_part_new_with_type(type, subtype); + + emcore_gmime_construct_part(singlepart, mbody, spec, &total_size); + + mime_part = GMIME_OBJECT(singlepart); + EM_SAFE_FREE(type); + EM_SAFE_FREE(subtype); + } + + g_mime_message_set_mime_part(message1, mime_part); + if (mime_part) g_object_unref(mime_part); + + ret = TRUE; + +FINISH_OFF: + + if (total_mail_size) + *total_mail_size = total_size; + + if (message) + *message = message1; + + EM_DEBUG_FUNC_END(); + + return ret; +} + +INTERNAL_FUNC int emcore_gmime_get_body_sections_from_message(GMimeMessage *message, + struct _m_content_info *cnt_info, + char **sections_to_fetch) +{ + EM_DEBUG_FUNC_BEGIN(); + + int ret = FALSE; + GMimePartIter *iter1 = NULL; + GMimeObject *part_tmp = NULL; + char *part_path = NULL; + char sections[IMAP_MAX_COMMAND_LENGTH] = {0,}; + + iter1 = g_mime_part_iter_new((GMimeObject *)message); + + if (!g_mime_part_iter_is_valid(iter1)) { + EM_DEBUG_EXCEPTION("Part iterator is not valid"); + goto FINISH_OFF; + } + + do { + part_tmp = g_mime_part_iter_get_current(iter1); + if (part_tmp && GMIME_IS_PART(part_tmp)) { + GMimeObject *mobject = (GMimeObject *)part_tmp; + GMimeContentDisposition *disposition = NULL; + char *disposition_str = NULL; + + /*Content Disposition*/ + disposition = g_mime_object_get_content_disposition(mobject); + if (disposition) { + disposition_str = (char *)g_mime_content_disposition_get_disposition(disposition); + } + EM_DEBUG_LOG("Disposition[%s]", disposition_str); + /*Content Disposition - END*/ + + part_path = g_mime_part_iter_get_path(iter1); + + if (cnt_info->grab_type == (GRAB_TYPE_TEXT | GRAB_TYPE_ATTACHMENT)) { + char t[100] = {0,}; + snprintf(t, sizeof(t), "BODY.PEEK[%s] ", part_path); + if (EM_SAFE_STRLEN(sections) + EM_SAFE_STRLEN(t) < sizeof(sections) - 1) { + strcat(sections, t); + } + else { + EM_DEBUG_EXCEPTION("Too many body parts. IMAP command may cross 2000bytes."); + goto FINISH_OFF; + } + } + else if (cnt_info->grab_type == GRAB_TYPE_TEXT) { + if (disposition_str && g_ascii_strcasecmp(disposition_str, GMIME_DISPOSITION_ATTACHMENT) == 0) { + EM_DEBUG_LOG("ATTACHMENT"); + } else { + char t[100] = {0,}; + snprintf(t, sizeof(t), "BODY.PEEK[%s] ", part_path); + if (EM_SAFE_STRLEN(sections) + EM_SAFE_STRLEN(t) < sizeof(sections) - 1) { + strcat(sections, t); + } + else { + EM_DEBUG_EXCEPTION("Too many body parts. IMAP command may cross 2000bytes."); + goto FINISH_OFF; + } + } + } + + EM_SAFE_FREE(part_path); + } + } while (g_mime_part_iter_next(iter1)); + + if (iter1) { + g_mime_part_iter_free(iter1); + iter1 = NULL; + } + + if (EM_SAFE_STRLEN(sections) <= 0 || EM_SAFE_STRLEN(sections) >= IMAP_MAX_COMMAND_LENGTH-1) { + EM_DEBUG_EXCEPTION("Too many body parts. IMAP command may cross 2000bytes."); + goto FINISH_OFF; + } + + if (sections[EM_SAFE_STRLEN(sections)-1] == ' ') + sections[EM_SAFE_STRLEN(sections)-1] = '\0'; + + EM_DEBUG_LOG("sections <%s>", sections); + + if (g_strlcpy(*sections_to_fetch, sections, IMAP_MAX_COMMAND_LENGTH) > 0) + ret = TRUE; + +FINISH_OFF: + + if (iter1) { + g_mime_part_iter_free(iter1); + iter1 = NULL; + } + + EM_SAFE_FREE(part_path); + + EM_DEBUG_FUNC_END(); + + return ret; +} + +INTERNAL_FUNC int emcore_gmime_get_attachment_section_from_message(GMimeMessage *message, + struct _m_content_info *cnt_info, + int nth, + char **section_to_fetch) +{ + EM_DEBUG_FUNC_BEGIN(); + + int ret = FALSE; + int count = nth; + GMimePartIter *iter1 = NULL; + GMimeObject *part_tmp = NULL; + char *part_path = NULL; + char sections[IMAP_MAX_COMMAND_LENGTH] = {0,}; + + if (nth <= 0) { + EM_DEBUG_EXCEPTION("parameter nth is not valid"); + goto FINISH_OFF; + } + + iter1 = g_mime_part_iter_new((GMimeObject *)message); + + if (!g_mime_part_iter_is_valid(iter1)) { + EM_DEBUG_EXCEPTION("Part iterator is not valid"); + goto FINISH_OFF; + } + + do { + part_tmp = g_mime_part_iter_get_current(iter1); + if (part_tmp && GMIME_IS_PART(part_tmp)) { + GMimeObject *mobject = (GMimeObject *)part_tmp; + GMimeContentDisposition *disposition = NULL; + char *disposition_str = NULL; + + /*Content Disposition*/ + disposition = g_mime_object_get_content_disposition(mobject); + if (disposition) { + disposition_str = (char *)g_mime_content_disposition_get_disposition(disposition); + } + EM_DEBUG_LOG("Disposition[%s]", disposition_str); + /*Content Disposition - END*/ + + part_path = g_mime_part_iter_get_path(iter1); + + if (disposition_str && g_ascii_strcasecmp(disposition_str, GMIME_DISPOSITION_ATTACHMENT) == 0) { + EM_DEBUG_LOG("ATTACHMENT"); + count--; + + if (count == 0) { + char t[100] = {0,}; + snprintf(t, sizeof(t), "%s", part_path); + if (EM_SAFE_STRLEN(sections) + EM_SAFE_STRLEN(t) < sizeof(sections) - 1) { + strcat(sections, t); + } + else { + EM_DEBUG_EXCEPTION("Too many body parts. IMAP command may cross 2000bytes."); + goto FINISH_OFF; + } + } + } + + EM_SAFE_FREE(part_path); + } + } while (g_mime_part_iter_next(iter1)); + + if (iter1) { + g_mime_part_iter_free(iter1); + iter1 = NULL; + } + + EM_DEBUG_LOG("sections <%s>", sections); + + if (g_strlcpy(*section_to_fetch, sections, IMAP_MAX_COMMAND_LENGTH) > 0) + ret = TRUE; + +FINISH_OFF: + + if (iter1) { + g_mime_part_iter_free(iter1); + iter1 = NULL; + } + + EM_SAFE_FREE(part_path); + + EM_DEBUG_FUNC_END(); + + return ret; +} + +static int emcore_gmime_get_section_n_bodysize(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 = EMAIL_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 FALSE; + } + } else { + return FALSE; + } + + return TRUE; +} + +INTERNAL_FUNC int emcore_gmime_fetch_imap_body_sections(MAILSTREAM *stream, int msg_uid, int mail_id, + struct _m_content_info *cnt_info, + GMimeMessage *message, int event_handle, + int auto_download, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("stream[%p], msg_uid[%d], cnt_info[%p], err_code[%p]", + stream, msg_uid, cnt_info, err_code); + + int err = EMAIL_ERROR_NONE; + int ret = FALSE; + + IMAPLOCAL *imaplocal = NULL; + + char tag[16] = {0,}; + char command[IMAP_MAX_COMMAND_LENGTH+100] = {0,}; + char section[16] = {0,}; + char *response = NULL; + + int server_response_yn = 0; + int body_size = 0; + + char *buf = NULL; + + unsigned char encoded[DOWNLOAD_MAX_BUFFER_SIZE] = {0,}; + unsigned char test_buffer[LOCAL_MAX_BUFFER_SIZE] = {0,}; + + int total = 0; + int flag_first_write = 1; + char *tag_position = NULL; + + int part_header = 0; + int signed_message = 0; + int download_interval = 0; + int download_total_size = 0; + int downloaded_size = 0; + int download_progress = 0; + int last_notified_download_size = 0; + + char *full_text = NULL; + char *body_string = NULL; + char *header_string = NULL; + GMimeObject *entity_part = NULL; + GMimeParser *entity_parser = NULL; + + GMimeDataWrapper *content = NULL; + GMimeStream *content_stream = NULL; + GMimeObject *mime_object = NULL; + GMimePart *mime_part = NULL; + GMimeMessagePart *mime_message_part = NULL; + //GMimePartIter *mime_iter = NULL; + search_section *search_info = NULL; + + imaplocal = stream->local; + + if (!imaplocal || !imaplocal->netstream) { + EM_DEBUG_EXCEPTION("invalid IMAP4 stream detected..."); + err = EMAIL_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + if (!cnt_info || !cnt_info->sections) { + EM_DEBUG_LOG("invalid parameter detected..."); + /* Encrypted message did not have a text body So did not have a body section */ + ret = TRUE; + goto FINISH_OFF; + } + + SNPRINTF(tag, sizeof(tag), "%08lx", 0xffffffff & (stream->gensym++)); + SNPRINTF(command, sizeof(command), "%s UID FETCH %d (%s)\015\012", tag, msg_uid, cnt_info->sections); + EM_DEBUG_LOG("command <%s>", command); + + /* send command : get msgno/uid for all message */ + if (!net_sout(imaplocal->netstream, command, (int)EM_SAFE_STRLEN(command))) { + EM_DEBUG_EXCEPTION("net_sout failed..."); + err = EMAIL_ERROR_CONNECTION_BROKEN; + goto FINISH_OFF; + } + + if (GMIME_IS_MULTIPART_SIGNED(message->mime_part)) { + EM_DEBUG_LOG("Multi Part Signed"); + signed_message = 1; + } + + while (imaplocal->netstream) { + + /* receive response */ + if (!(response = net_getline(imaplocal->netstream))) { + EM_DEBUG_EXCEPTION("net_getline failed..."); + err = EMAIL_ERROR_INVALID_RESPONSE; + goto FINISH_OFF; + } + + EM_DEBUG_LOG("response :%s", response); + + if (strstr(response, "BODY[")) { + + if (!server_response_yn) { /* start of response */ + if (response[0] != '*') { + err = EMAIL_ERROR_INVALID_RESPONSE; + EM_DEBUG_EXCEPTION("Start of response doesn't contain *"); + goto FINISH_OFF; + } + server_response_yn = 1; + } + + part_header = 0; + flag_first_write = 1; + total = 0; + memset(encoded, 0x00, sizeof(encoded)); + + if (!emcore_gmime_get_section_n_bodysize(response, section, &body_size)) { + EM_DEBUG_EXCEPTION("emcore_gmime_get_section_body_size failed [%d]", err); + err = EMAIL_ERROR_INVALID_RESPONSE; + goto FINISH_OFF; + } + EM_DEBUG_LOG("section :%s, body_size :%d", section, body_size); + + /*if (GMIME_IS_MULTIPART (message->mime_part)) { + mime_iter = g_mime_part_iter_new((GMimeObject *)message); + + if (!g_mime_part_iter_is_valid(mime_iter)) { + EM_DEBUG_EXCEPTION("Part iterator is not valid"); + goto FINISH_OFF; + } + + if (g_mime_part_iter_jump_to(mime_iter, section)) { + EM_DEBUG_LOG("g_mime_part_iter_jump_to: %s", section); + mime_object = g_mime_part_iter_get_current(mime_iter); + if (!mime_object) { + EM_DEBUG_EXCEPTION("g_mime_part_iter_get_current failed"); + goto FINISH_OFF; + } + mime_part = GMIME_PART(mime_object); + } else { + EM_DEBUG_LOG("g_mime_part_iter_jump_to: failed to jump to %s", section); + goto FINISH_OFF; + } + + if (mime_iter) { + g_mime_part_iter_free(mime_iter); + mime_iter = NULL; + } + } else if (GMIME_IS_PART (message->mime_part)) { + mime_object = message->mime_part; + mime_part = GMIME_PART(mime_object); + }*/ + + if (search_info) { + EM_SAFE_FREE(search_info->section); + EM_SAFE_FREE(search_info); + } + + if (!(search_info = em_malloc(sizeof(search_section)))) { /* prevent */ + EM_DEBUG_EXCEPTION("em_malloc failed..."); + err = EMAIL_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + search_info->section = EM_SAFE_STRDUP(section); + g_mime_message_foreach(message, emcore_gmime_search_section_foreach_cb, (gpointer)search_info); + + if (!(search_info->section_object)) { + EM_DEBUG_EXCEPTION("section search failed"); + goto FINISH_OFF; + } + + mime_message_part = NULL; + mime_part = NULL; + mime_object = search_info->section_object; + if (GMIME_IS_MESSAGE_PART(mime_object)) { + if (strcasestr(section, "MIME")) + part_header = 1; + + mime_message_part = GMIME_MESSAGE_PART(mime_object); + } else if (GMIME_IS_PART(mime_object)) { + if (strcasestr(section, "MIME")) + part_header = 1; + + mime_part = GMIME_PART(mime_object); + } else if (signed_message) { + if (strcasestr(section, "MIME")) + part_header = 1; + } else { + EM_DEBUG_EXCEPTION("invalid mime part type"); + goto FINISH_OFF; + } + + if (!part_header) { + if (!emcore_get_temp_file_name(&buf, &err) || !buf) { + EM_DEBUG_EXCEPTION("emcore_get_temp_file_name failed [%d]", err); + goto FINISH_OFF; + } + + EM_DEBUG_LOG("TMP name : [%s]", buf); + g_mime_object_set_content_type_parameter(mime_object, "tmp_content_path", buf); + + if (event_handle > 0) + FINISH_OFF_IF_EVENT_CANCELED (err, event_handle); + + if (cnt_info->grab_type == GRAB_TYPE_TEXT) { + if (cnt_info->total_body_size > body_size) { + EM_DEBUG_LOG("Multipart body size is [%d]", cnt_info->total_body_size); + if (!auto_download) { + if (!emcore_notify_network_event(NOTI_DOWNLOAD_MULTIPART_BODY, + mail_id, + buf, + cnt_info->total_body_size, + 0)) + EM_DEBUG_EXCEPTION(" emcore_notify_network_event [ NOTI_DOWNLOAD_BODY_START] Failed >>>> "); + } + + download_interval = cnt_info->total_body_size * DOWNLOAD_NOTI_INTERVAL_PERCENT / 100; + download_total_size = cnt_info->total_body_size; + } + else { + if (!auto_download) { + if (!emcore_notify_network_event(NOTI_DOWNLOAD_BODY_START, mail_id, buf, body_size, 0)) + EM_DEBUG_EXCEPTION(" emcore_notify_network_event [ NOTI_DOWNLOAD_BODY_START] Failed >>>> "); + } + + download_interval = body_size * DOWNLOAD_NOTI_INTERVAL_PERCENT / 100; + download_total_size = body_size; + } + } + + if (cnt_info->grab_type == (GRAB_TYPE_TEXT | GRAB_TYPE_ATTACHMENT)) { + if (!auto_download) { + if (!emcore_notify_network_event(NOTI_DOWNLOAD_MULTIPART_BODY, + mail_id, + buf, + cnt_info->total_mail_size, + 0)) + EM_DEBUG_EXCEPTION(" emcore_notify_network_event [ NOTI_DOWNLOAD_BODY_START] Failed >>>> "); + } + + download_interval = cnt_info->total_mail_size * DOWNLOAD_NOTI_INTERVAL_PERCENT / 100; + download_total_size = cnt_info->total_mail_size; + } + + if (download_interval > DOWNLOAD_NOTI_INTERVAL_SIZE) { + download_interval = 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 = EMAIL_ERROR_NO_RESPONSE; + goto FINISH_OFF; + } + + if (signed_message) { + content_stream = g_mime_stream_mem_new_with_buffer((const char *)encoded, + EM_SAFE_STRLEN(encoded)); + entity_parser = g_mime_parser_new_with_stream(content_stream); + if (content_stream) g_object_unref(content_stream); + + entity_part = g_mime_parser_construct_part(entity_parser); + if (entity_parser) g_object_unref(entity_parser); + } + else if (GMIME_IS_PART(mime_object) && mime_part) { + content_stream = g_mime_stream_mem_new_with_buffer((const char *)encoded, + EM_SAFE_STRLEN(encoded)); + //parser = g_mime_parser_new_with_stream(content_stream); + content = g_mime_data_wrapper_new_with_stream(content_stream, mime_part->encoding); + if (content_stream) g_object_unref (content_stream); + g_mime_part_set_content_object(mime_part, content); + if (content) g_object_unref(content); + } + else if (GMIME_IS_MESSAGE_PART(mime_object) && mime_message_part) { + FILE *fp = NULL; + int encoded_len = EM_SAFE_STRLEN((char *)encoded); + + err = em_fopen(buf, "wb+", &fp); + if (err != EMAIL_ERROR_NONE) { + EM_DEBUG_EXCEPTION_SEC("em_fopen failed - %s", buf); + goto FINISH_OFF; + } + + if (encoded_len > 0 && fwrite(encoded, encoded_len, 1, fp) == 0) { + EM_DEBUG_EXCEPTION("Error Occured while writing. fwrite() failed"); + err = EMAIL_ERROR_SYSTEM_FAILURE; + fclose(fp); + goto FINISH_OFF; + } + + if (fp != NULL) + fclose(fp); + } + + downloaded_size += EM_SAFE_STRLEN((char *)encoded); + EM_DEBUG_LOG("IMAP4 downloaded body size [%d]", downloaded_size); + EM_DEBUG_LOG("IMAP4 total body size [%d]", download_total_size); + EM_DEBUG_LOG("IMAP4 download interval [%d]", download_interval); + + /* In some situation, total_encoded_len includes the length of dummy bytes. + * So it might be greater than body_size */ + + download_progress = 100 * downloaded_size / download_total_size; + + EM_DEBUG_LOG("DOWNLOADING STATUS NOTIFY:Total[%d]/[%d] = %d %% Completed", + downloaded_size, download_total_size, download_progress); + + if (cnt_info->grab_type == GRAB_TYPE_TEXT && !auto_download) { + if (cnt_info->total_body_size > body_size) { + if (!emcore_notify_network_event(NOTI_DOWNLOAD_MULTIPART_BODY, mail_id, buf, download_total_size, downloaded_size)) + EM_DEBUG_EXCEPTION(" emcore_notify_network_event [NOTI_DOWNLOAD_MULTIPART_BODY] Failed >>>>"); + } + else { + if (!emcore_notify_network_event(NOTI_DOWNLOAD_BODY_START, mail_id, buf, download_total_size, downloaded_size)) + EM_DEBUG_EXCEPTION(" emcore_notify_network_event [NOTI_DOWNLOAD_BODY_START] Failed >>>>"); + } + } + } else { + int remain_body_size = body_size; + int x = 0; + int nsize = 0; + int fd = 0; + total = 0; + + if (mime_part && mime_part->encoding == GMIME_CONTENT_ENCODING_BASE64) + x = (sizeof(encoded)/78)*78; /* to solve base64 decoding pro */ + else + x = sizeof(encoded)-1; + + memset(test_buffer, 0x00, sizeof(test_buffer)); + while (remain_body_size && (total netstream, (long)x, (char *)encoded) <= 0) { + EM_DEBUG_EXCEPTION("net_getbuffer failed..."); + err = EMAIL_ERROR_NO_RESPONSE; + goto FINISH_OFF; + } + + nsize = EM_SAFE_STRLEN((char *)encoded); + remain_body_size = remain_body_size - nsize; + strncat((char *)test_buffer, (char *)encoded, nsize); + total = total + nsize; + downloaded_size += nsize; + + EM_DEBUG_LOG("total/body_size [%d/%d]", total, body_size); + + if (!(remain_body_size/x) && remain_body_size%x) + x = remain_body_size%x; + + //EM_DEBUG_LOG("IMAP4 - %d ", _imap4_last_notified_body_size); + EM_DEBUG_LOG("IMAP4 download interval [%d]", download_interval); + EM_DEBUG_LOG("IMAP4 downloaded size [%d]", downloaded_size); + EM_DEBUG_LOG("IMAP4 total body size [%d]", download_total_size); + + if (((last_notified_download_size + download_interval) <= downloaded_size) + || (downloaded_size >= download_total_size)) { + + /* In some situation, total_encoded_len includes the length of dummy bytes. + * So it might be greater than body_size */ + + if (downloaded_size > download_total_size) + downloaded_size = download_total_size; + + last_notified_download_size = downloaded_size; + + if (download_total_size != 0) download_progress = 100*downloaded_size/download_total_size; + EM_DEBUG_LOG("DOWNLOADING STATUS NOTIFY :Total[%d] / [%d] = %d %% Completed.", + downloaded_size, download_total_size, download_progress); + + if (!auto_download) { + if (cnt_info->total_body_size > body_size) { + if (!emcore_notify_network_event(NOTI_DOWNLOAD_MULTIPART_BODY, mail_id, buf, download_total_size, downloaded_size)) + EM_DEBUG_EXCEPTION("emcore_notify_network_event [NOTI_DOWNLOAD_MULTIPART_BODY] Failed >>>>"); + } else { + if (!emcore_notify_network_event(NOTI_DOWNLOAD_BODY_START, mail_id, buf, download_total_size, downloaded_size)) + EM_DEBUG_EXCEPTION("emcore_notify_network_event [NOTI_DOWNLOAD_BODY_START] Failed >>>>"); + } + } + } + } + + if (flag_first_write == 1) { + FILE *fp = NULL; + int encoded_len = EM_SAFE_STRLEN((char *)test_buffer); + + err = em_fopen(buf, "wb+", &fp); + if (err != EMAIL_ERROR_NONE) { + EM_DEBUG_EXCEPTION_SEC("em_fopen failed - %s", buf); + goto FINISH_OFF; + } + + if (encoded_len > 0 && fwrite(test_buffer, encoded_len, 1, fp) == 0) { + EM_DEBUG_EXCEPTION("Error Occured while writing. fwrite(\"%s\") failed", test_buffer); + err = EMAIL_ERROR_SYSTEM_FAILURE; + fclose (fp); /* prevent */ + goto FINISH_OFF; + } + + if (fp != NULL) + fclose(fp); + + flag_first_write = 0; + } else { + FILE *fp = NULL; + int encoded_len = EM_SAFE_STRLEN((char *)test_buffer); + + err = em_fopen(buf, "ab+", &fp); + if (err != EMAIL_ERROR_NONE) { + EM_DEBUG_EXCEPTION_SEC("em_fopen failed - %s", buf); + goto FINISH_OFF; + } + + if (encoded_len > 0 && fwrite(test_buffer, encoded_len, 1, fp) == 0) { + EM_DEBUG_EXCEPTION("Error Occured while writing. fwrite(\"%s\") failed", test_buffer); + err = EMAIL_ERROR_SYSTEM_FAILURE; + fclose (fp); /* prevent */ + goto FINISH_OFF; + } + + if (fp != NULL) + fclose(fp); + } + EM_DEBUG_LOG("%d has been written", EM_SAFE_STRLEN((char *)test_buffer)); + } + + if (signed_message) { + err = em_open(buf, O_RDONLY, 0, &fd); + if (err != EMAIL_ERROR_NONE) { + EM_DEBUG_EXCEPTION("holder open failed : holder is a filename that will be saved."); + goto FINISH_OFF; + } + + content_stream = g_mime_stream_fs_new(fd); + + entity_parser = g_mime_parser_new_with_stream(content_stream); + if (content_stream) g_object_unref(content_stream); + + entity_part = g_mime_parser_construct_part(entity_parser); + if (entity_parser) g_object_unref(entity_parser); + } + else if (GMIME_IS_PART(mime_object) && mime_part) { + err = em_open(buf, O_RDONLY, 0, &fd); + if (err != EMAIL_ERROR_NONE) { + EM_DEBUG_EXCEPTION("holder open failed : holder is a filename that will be saved."); + goto FINISH_OFF; + } + + content_stream = g_mime_stream_fs_new(fd); + //parser = g_mime_parser_new_with_stream(content_stream); + content = g_mime_data_wrapper_new_with_stream(content_stream, mime_part->encoding); + if (content_stream) g_object_unref (content_stream); + g_mime_part_set_content_object(mime_part, content); + if (content) g_object_unref(content); + } + } + } else { + EM_DEBUG_LOG("MIME header"); + + char *file_name = NULL; + + GMimeObject *object_header = NULL; + GMimeParser *parser_header = NULL; + GMimeContentType *ctype_header = NULL; + GMimeContentDisposition *disposition_header = NULL; + + if (net_getbuffer(imaplocal->netstream, (long)body_size, (char *)encoded) <= 0) { + EM_DEBUG_EXCEPTION("net_getbuffer failed..."); + err = EMAIL_ERROR_NO_RESPONSE; + goto FINISH_OFF; + } + + EM_DEBUG_LOG_DEV("Data : [%s]", encoded); + + if (signed_message) { + header_string = g_strdup((const gchar *)encoded); + } else { + content_stream = g_mime_stream_mem_new_with_buffer((const char *)encoded, EM_SAFE_STRLEN(encoded)); + parser_header = g_mime_parser_new_with_stream(content_stream); + if (content_stream) g_object_unref(content_stream); + + object_header = g_mime_parser_construct_part(parser_header); + if (parser_header) g_object_unref(parser_header); + + /* Content type */ + ctype_header = g_mime_object_get_content_type(object_header); + file_name = (char *)g_mime_content_type_get_parameter(ctype_header, "name"); + EM_DEBUG_LOG_DEV("Content name : [%s]", file_name); + + if (file_name == NULL) { + /* Content Disposition */ + disposition_header = g_mime_object_get_content_disposition(object_header); + file_name = (char *)g_mime_content_disposition_get_parameter(disposition_header, "filename"); + EM_DEBUG_LOG_DEV("Disposition name : [%s]", file_name); + } + + /* Replace the file name (Becase the server sometimes send the invalid name in bodystructure) */ + if (mime_part && file_name) g_mime_part_set_filename(mime_part, file_name); + } + + if (object_header) g_object_unref(object_header); + if (ctype_header) g_object_unref(ctype_header); + if (disposition_header) g_object_unref(disposition_header); + } + + if (buf) g_remove(buf); + EM_SAFE_FREE(buf); + } + else if ((tag_position = g_strrstr(response, tag))) /* end of response */ { + if (!strncmp(tag_position + EM_SAFE_STRLEN(tag) + 1, "OK", 2)) { + EM_SAFE_FREE(response); + } + else { /* 'NO' or 'BAD */ + err = EMAIL_ERROR_IMAP4_FETCH_UID_FAILURE; + goto FINISH_OFF; + } + break; + } + else if (!strcmp(response, ")")) { + } + + EM_SAFE_FREE (response); + } + + if (signed_message) { + int part_index = -1; + + GMimeStream *tmp_stream = NULL; + GMimeParser *tmp_parser = NULL; + GMimeMessage *tmp_message = NULL; + + body_string = g_mime_object_to_string(entity_part); + if (entity_part) g_object_unref(entity_part); + + full_text = g_strconcat(header_string, body_string, NULL); + tmp_stream = g_mime_stream_mem_new_with_buffer(full_text, EM_SAFE_STRLEN(full_text)); + + tmp_parser = g_mime_parser_new_with_stream(tmp_stream); + if (tmp_stream) g_object_unref(tmp_stream); + + tmp_message = g_mime_parser_construct_message(tmp_parser); + if (tmp_parser) g_object_unref(tmp_parser); + + /* Search get index of multipart for replacing */ + part_index = g_mime_multipart_index_of(GMIME_MULTIPART(message->mime_part), mime_object); + if (part_index == -1) { + EM_DEBUG_EXCEPTION("g_mime_multipart_index_of failed"); + if (tmp_message) g_object_unref(tmp_message); + goto FINISH_OFF; + } + + /* replace the entity part */ + if (g_mime_multipart_replace(GMIME_MULTIPART(message->mime_part), part_index, tmp_message->mime_part) == NULL) { + EM_DEBUG_EXCEPTION("g_mime_multipart_replaced failed"); + if (tmp_message) g_object_unref(tmp_message); + goto FINISH_OFF; + } + + if (tmp_message) g_object_unref(tmp_message); + } + + ret = TRUE; + +FINISH_OFF: + + /*if (mime_iter) { + g_mime_part_iter_free(mime_iter); + mime_iter = NULL; + }*/ + + EM_SAFE_FREE(header_string); + EM_SAFE_FREE(body_string); + EM_SAFE_FREE(full_text); + + if (entity_part) g_object_unref(entity_part); + if (entity_parser) g_object_unref(entity_parser); + + if (search_info) { + EM_SAFE_FREE(search_info->section); + EM_SAFE_FREE(search_info); + } + + if (buf) g_remove(buf); + EM_SAFE_FREE(buf); + + EM_SAFE_FREE(response); + + if (err_code) + *err_code = err; + + EM_DEBUG_FUNC_END(); + + return ret; +} + +INTERNAL_FUNC int emcore_gmime_fetch_imap_attachment_section(MAILSTREAM *stream, + int mail_id, int uid, int nth, struct _m_content_info *cnt_info, + GMimeMessage *message, int auto_download, int event_handle, int *err_code) +{ + EM_DEBUG_FUNC_BEGIN("stream[%p], uid[%d], err_code[%p]", stream, uid, err_code); + + int ret = FALSE; + int err = EMAIL_ERROR_NONE; + + IMAPLOCAL *imaplocal = NULL; + + char tag[16] = {0,}; + char command[64] = {0,}; + char *response = NULL; + unsigned char encoded[DOWNLOAD_MAX_BUFFER_SIZE] = {0, }; + unsigned char test_buffer[LOCAL_MAX_BUFFER_SIZE] = {0, }; + + int flag_first_write = TRUE; + int preline_len = 0; + int nskip = 0; + char *concat_encoded = NULL; + char *new_response = NULL; + char *tag_position = NULL; + char *tmp_file = NULL; + + int body_size = 0; + int total = 0; + int server_response_yn = 0; + int download_noti_interval = 0; + int download_total_size = 0; + int downloaded_size = 0; + int download_progress = 0; + int last_notified_download_size = 0; + + GMimeDataWrapper *content = NULL; + GMimeStream *content_stream = NULL; + GMimeObject *mime_object = NULL; + GMimePart *mime_part = NULL; + //GMimePartIter *mime_iter = NULL; + GMimeMessagePart *mime_message_part = NULL; + search_section *search_info = NULL; + + if (!stream || !cnt_info || !message) { + EM_DEBUG_EXCEPTION_SEC("stream[%p], section[%s], cnt_info[%p], message[%p]", + stream, cnt_info, message); + err = EMAIL_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + if (!cnt_info->sections) { + EM_DEBUG_EXCEPTION("section is NULL"); + err = EMAIL_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + imaplocal = stream->local; + + if (!imaplocal->netstream) { + EM_DEBUG_EXCEPTION("invalid IMAP4 stream detected... %p", imaplocal->netstream); + err = EMAIL_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 UID FETCH %d BODY.PEEK[%s]\015\012", tag, uid, cnt_info->sections); + EM_DEBUG_LOG("[IMAP4] >>> [%s]", command); + + /* send command : get msgno/uid for all message */ + if (!net_sout(imaplocal->netstream, command, (int)EM_SAFE_STRLEN(command))) { + EM_DEBUG_EXCEPTION("net_sout failed..."); + err = EMAIL_ERROR_CONNECTION_BROKEN; + goto FINISH_OFF; + } + + char *p_stream = NULL; + char *p_content = NULL; + + while (imaplocal->netstream) { + + /*don't delete the comment. several threads including event thread call this func + if (!emcore_check_thread_status()) { + EM_DEBUG_LOG("Canceled..."); + imaplocal->netstream = NULL; + err = EMAIL_ERROR_CANCELLED; + goto FINISH_OFF; + }*/ + + /* receive response */ + if (!(response = net_getline(imaplocal->netstream))) { + EM_DEBUG_EXCEPTION("net_getline failed..."); + err = EMAIL_ERROR_INVALID_RESPONSE; + goto FINISH_OFF; + } + +#ifdef FEATURE_CORE_DEBUG + EM_DEBUG_LOG("recv[%s]", response); +#endif + + /* start of response */ + if (response[0] == '*' && !server_response_yn) { + + p_stream = strstr(response, "BODY["); + + if (!p_stream) { + err = EMAIL_ERROR_INVALID_RESPONSE; + goto FINISH_OFF; + } + + server_response_yn = 1; + p_stream += strlen("BODY["); + p_content = p_stream; + + while (*p_content != ']') + p_content++; + + *p_content = '\0'; + + /* check correct section */ + if (g_strcmp0(cnt_info->sections, p_stream) != 0) { + EM_DEBUG_LOG("Invalid response of section"); + err = EMAIL_ERROR_INVALID_RESPONSE; + goto FINISH_OFF; + } + + /* get body size */ + p_stream = strstr(p_content+1, " {"); + if (p_stream) { + p_stream += strlen(" {"); + p_content = p_stream; + + while (isdigit(*p_content)) + p_content++; + + *p_content = '\0'; + + body_size = atoi(p_stream); + } else { /* no body length is replied */ + /* seek the termination of double quot */ + p_stream = strstr(p_content+1, " \""); + if (p_stream) { + char *t = NULL; + p_stream += strlen(" \""); + t = strstr(p_stream, "\""); + if (t) { + body_size = t - p_stream; + *t = '\0'; + EM_DEBUG_LOG("Body : start[%p] end[%p] : body[%s]", p_stream, t, p_stream); + /* need to decode */ + EM_SAFE_FREE(response); + response = EM_SAFE_STRDUP(p_stream); + } else { + err = EMAIL_ERROR_INVALID_RESPONSE; + goto FINISH_OFF; + } + } else { + err = EMAIL_ERROR_INVALID_RESPONSE; + goto FINISH_OFF; + } + } + + /*if (GMIME_IS_MULTIPART (message->mime_part)) { + mime_iter = g_mime_part_iter_new((GMimeObject *)message); + + if (!g_mime_part_iter_is_valid(mime_iter)) { + EM_DEBUG_EXCEPTION("Part iterator is not valid"); + goto FINISH_OFF; + } + + if (g_mime_part_iter_jump_to (mime_iter, section)) { + EM_DEBUG_LOG("g_mime_part_iter_jump_to: %s", section); + mime_object = g_mime_part_iter_get_current (mime_iter); + if (!mime_object) { + EM_DEBUG_EXCEPTION("g_mime_part_iter_get_current failed"); + goto FINISH_OFF; + } + mime_part = GMIME_PART(mime_object); + } else { + EM_DEBUG_LOG("g_mime_part_iter_jump_to: failed to jump to %s", section); + goto FINISH_OFF; + } + + if (mime_iter) { + g_mime_part_iter_free(mime_iter); + mime_iter = NULL; + } + } else if (GMIME_IS_PART (message->mime_part)) { + mime_object = message->mime_part; + mime_part = GMIME_PART(mime_object); + }*/ + + if (search_info) { + EM_SAFE_FREE(search_info->section); + EM_SAFE_FREE(search_info); + } + + if (!(search_info = em_malloc(sizeof(search_section)))) { /* prevent */ + EM_DEBUG_EXCEPTION("em_malloc failed..."); + err = EMAIL_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + search_info->section = EM_SAFE_STRDUP(cnt_info->sections); + g_mime_message_foreach(message, emcore_gmime_search_section_foreach_cb, (gpointer)search_info); + + if (!(search_info->section_object)) { + EM_DEBUG_EXCEPTION("section search failed"); + goto FINISH_OFF; + } + + mime_message_part = NULL; + mime_part = NULL; + mime_object = search_info->section_object; + if (GMIME_IS_MESSAGE_PART(mime_object)) { + mime_message_part = GMIME_MESSAGE_PART(mime_object); + } else if (GMIME_IS_PART(mime_object)) { + mime_part = GMIME_PART(mime_object); + } else { + EM_DEBUG_EXCEPTION("invalid mime part type"); + goto FINISH_OFF; + } + + if (!emcore_get_temp_file_name(&tmp_file, &err) || !tmp_file) { + EM_DEBUG_EXCEPTION("emcore_get_temp_file_name failed [%d]", err); + goto FINISH_OFF; + } + + g_mime_object_set_content_type_parameter(mime_object, "tmp_content_path", tmp_file); + + EM_DEBUG_LOG("Attachment number [%d]", nth); + if (!auto_download) { + if (!emcore_notify_network_event(NOTI_DOWNLOAD_ATTACH_START, mail_id, tmp_file, nth, 0)) + EM_DEBUG_EXCEPTION("emcore_notify_network_event [ NOTI_DOWNLOAD_ATTACH_START] Failed >>>>"); + } + + download_noti_interval = body_size * DOWNLOAD_NOTI_INTERVAL_PERCENT / 100; + download_total_size = body_size; + + if (download_noti_interval > DOWNLOAD_NOTI_INTERVAL_SIZE) { + download_noti_interval = DOWNLOAD_NOTI_INTERVAL_SIZE; + } + + /* remove new lines */ + do { + EM_SAFE_FREE(response); + if (!(response = net_getline(imaplocal->netstream))) { + EM_DEBUG_EXCEPTION("net_getline failed..."); + err = EMAIL_ERROR_INVALID_RESPONSE; + goto FINISH_OFF; + } + + EM_DEBUG_LOG("response:%s", response); + if (EM_SAFE_STRLEN(response) == 0) { + EM_DEBUG_LOG("Skip newline !!"); + nskip++; + } else { + EM_SAFE_FREE(new_response); /* detected by valgrind */ + new_response = g_strconcat(response, "\r\n", NULL); + EM_SAFE_FREE(response); + break; + } + } while(1); + + preline_len = EM_SAFE_STRLEN(new_response); + EM_DEBUG_LOG("preline_len : %d", preline_len); + + if (body_size <= 0 || preline_len <= 0) + continue; + + if ((body_size - preline_len - nskip*2) <= 0) { + /* 1 line content */ + + if (GMIME_IS_PART(mime_object) && mime_part) { + char *tmp_str = NULL; + tmp_str = g_strndup(new_response, body_size); + if (tmp_str == NULL) tmp_str = g_strdup(new_response); + + content_stream = g_mime_stream_mem_new_with_buffer((const char *)tmp_str, EM_SAFE_STRLEN(tmp_str)); + //parser = g_mime_parser_new_with_stream(content_stream); + content = g_mime_data_wrapper_new_with_stream(content_stream, mime_part->encoding); + if (content_stream) g_object_unref (content_stream); + g_mime_part_set_content_object(mime_part, content); + if (content) g_object_unref(content); + EM_SAFE_FREE(tmp_str); + } + else if (GMIME_IS_MESSAGE_PART(mime_object) && mime_message_part) { + FILE *fp = NULL; + int response_len = 0; + char *tmp_str = NULL; + + tmp_str = g_strndup(new_response, body_size); + if (tmp_str == NULL) tmp_str = g_strdup(new_response); + + response_len = EM_SAFE_STRLEN((char *)tmp_str); + + err = em_fopen(tmp_file, "wb+", &fp); + if (err != EMAIL_ERROR_NONE) { + EM_DEBUG_EXCEPTION_SEC("em_fopen failed - %s", tmp_file); + EM_SAFE_FREE(tmp_str); + goto FINISH_OFF; + } + + if (response_len > 0 && fwrite(tmp_str, response_len, 1, fp) == 0) { + EM_DEBUG_EXCEPTION("Error Occured while writing. fwrite() failed"); + err = EMAIL_ERROR_SYSTEM_FAILURE; + fclose(fp); + EM_SAFE_FREE(tmp_str); + goto FINISH_OFF; + } + + if (fp != NULL) + fclose(fp); + + EM_SAFE_FREE(tmp_str); + } + + EM_SAFE_FREE(new_response); + + total = body_size; + EM_DEBUG_LOG("current total = %d", total); + downloaded_size += total; + + EM_DEBUG_LOG("DOWNLOADING STATUS NOTIFY : received[%d] / total_size[%d] = %d %% Completed", + downloaded_size, download_total_size, (int)((float)downloaded_size / (float)download_total_size * 100.0)); + + if (((last_notified_download_size + download_noti_interval) <= downloaded_size) || (downloaded_size >= download_total_size)) { + + if (downloaded_size > download_total_size) + downloaded_size = download_total_size; + + last_notified_download_size = downloaded_size; + + download_progress = (int)((float)downloaded_size / (float)download_total_size * 100.0); + + if (!auto_download) { + if (download_total_size && !emcore_notify_network_event(NOTI_DOWNLOAD_ATTACH_START, mail_id, tmp_file, nth, download_progress)) + EM_DEBUG_EXCEPTION("emcore_notify_network_event [ NOTI_DOWNLOAD_ATTACH_START] Failed >>>>"); + } + } + } + else if ((body_size < DOWNLOAD_MAX_BUFFER_SIZE) && (body_size - preline_len - nskip*2 < DOWNLOAD_MAX_BUFFER_SIZE)) { + memset(encoded, 0x00, sizeof(encoded)); + if (net_getbuffer(imaplocal->netstream, body_size - preline_len - nskip*2, (char *)encoded) <= 0) { + EM_DEBUG_EXCEPTION("net_getbuffer failed..."); + err = EMAIL_ERROR_NO_RESPONSE; + goto FINISH_OFF; + } + + concat_encoded = g_strconcat(new_response, encoded, NULL); + memset(encoded, 0x00, sizeof(encoded)); + memcpy(encoded, concat_encoded, EM_SAFE_STRLEN(concat_encoded)); + EM_SAFE_FREE(concat_encoded); + EM_SAFE_FREE(new_response); + + if (GMIME_IS_PART(mime_object) && mime_part) { + content_stream = g_mime_stream_mem_new_with_buffer((const char *)encoded, EM_SAFE_STRLEN(encoded)); + //parser = g_mime_parser_new_with_stream(content_stream); + content = g_mime_data_wrapper_new_with_stream(content_stream, mime_part->encoding); + if (content_stream) g_object_unref (content_stream); + g_mime_part_set_content_object(mime_part, content); + if (content) g_object_unref(content); + } + else if (GMIME_IS_MESSAGE_PART(mime_object) && mime_message_part) { + FILE *fp = NULL; + int encoded_len = EM_SAFE_STRLEN((char *)encoded); + + err = em_fopen(tmp_file, "wb+", &fp); + if (err != EMAIL_ERROR_NONE) { + EM_DEBUG_EXCEPTION_SEC("em_fopen failed - %s", tmp_file); + goto FINISH_OFF; + } + + if (encoded_len > 0 && fwrite(encoded, encoded_len, 1, fp) == 0) { + EM_DEBUG_EXCEPTION("Error Occured while writing. fwrite() failed"); + err = EMAIL_ERROR_SYSTEM_FAILURE; + fclose(fp); + goto FINISH_OFF; + } + + if (fp != NULL) + fclose(fp); + } + + total = EM_SAFE_STRLEN((char *)encoded); + EM_DEBUG_LOG("total = %d", total); + downloaded_size += total; + + EM_DEBUG_LOG("DOWNLOADING STATUS NOTIFY : received[%d] / total_size[%d] = %d %% Completed", + downloaded_size, download_total_size, (int)((float)downloaded_size / (float)download_total_size * 100.0)); + + if (((last_notified_download_size + download_noti_interval) <= downloaded_size) || (downloaded_size >= download_total_size)) { + + if (downloaded_size > download_total_size) + downloaded_size = download_total_size; + + last_notified_download_size = downloaded_size; + + download_progress = (int)((float)downloaded_size / (float)download_total_size * 100.0); + + if (!auto_download) { + if (download_total_size && !emcore_notify_network_event(NOTI_DOWNLOAD_ATTACH_START, mail_id, tmp_file, nth, download_progress)) + EM_DEBUG_EXCEPTION("emcore_notify_network_event [ NOTI_DOWNLOAD_ATTACH_START] Failed >>>>"); + } + } + } + else { + int remain_body_size = body_size - preline_len - nskip*2; + int x = 0; + int nsize = 0; + int fd = 0; + total += preline_len + nskip*2; + downloaded_size += preline_len + nskip*2; + + memset(test_buffer, 0x00, sizeof(test_buffer)); + + while (remain_body_size > 0 && (total < body_size)) { + + memset(test_buffer, 0x00, sizeof(test_buffer)); + + if (remain_body_size < DOWNLOAD_MAX_BUFFER_SIZE) + x = remain_body_size; + else if (mime_part && mime_part->encoding == GMIME_CONTENT_ENCODING_BASE64) + x = (sizeof(encoded)/preline_len)*preline_len; /* to solve base64 decoding pro */ + else + x = sizeof(encoded)-1; + + if (new_response) { + strncat((char *)test_buffer, (char *)new_response, preline_len); + EM_SAFE_FREE(new_response); + } + + while (remain_body_size > 0 && (total < body_size) && ((EM_SAFE_STRLEN((char *)test_buffer) + x) < sizeof(test_buffer))) { + if (event_handle > 0) + FINISH_OFF_IF_EVENT_CANCELED (err, event_handle); + + memset(encoded, 0x00, sizeof(encoded)); + + if (net_getbuffer(imaplocal->netstream, (long)x, (char *)encoded) <= 0) { + EM_DEBUG_EXCEPTION("net_getbuffer failed..."); + err = EMAIL_ERROR_NO_RESPONSE; + goto FINISH_OFF; + } + + nsize = EM_SAFE_STRLEN((char *)encoded); + remain_body_size = remain_body_size - nsize; + strncat((char *)test_buffer, (char *)encoded, nsize); + total = total + nsize; + downloaded_size += nsize; + EM_DEBUG_LOG("nsize : %d", nsize); + EM_DEBUG_LOG("remain_body_size : %d", remain_body_size); + EM_DEBUG_LOG("total : %d", total); + EM_DEBUG_LOG("imap_received_body_size : %d", downloaded_size); + + if (!(remain_body_size/x) && remain_body_size%x) + x = remain_body_size%x; + + EM_DEBUG_LOG("DOWNLOADING STATUS NOTIFY : received[%d] / total_size[%d] = %d %% Completed", + downloaded_size, download_total_size, (int)((float)downloaded_size / (float)download_total_size * 100.0)); + + if (((last_notified_download_size + download_noti_interval) <= downloaded_size) || (downloaded_size >= download_total_size)) { + + if (downloaded_size > download_total_size) + downloaded_size = download_total_size; + + last_notified_download_size = downloaded_size; + + download_progress = (int)((float)downloaded_size / (float)download_total_size * 100.0); + + if (!auto_download) { + if (download_total_size && !emcore_notify_network_event(NOTI_DOWNLOAD_ATTACH_START, mail_id, tmp_file, nth, download_progress)) + EM_DEBUG_EXCEPTION("emcore_notify_network_event [ NOTI_DOWNLOAD_ATTACH_START] Failed >>>>"); + } + } + } + + if (flag_first_write == true) { + + FILE *fp = NULL; + int encoded_len = EM_SAFE_STRLEN((char *)test_buffer); + + err = em_fopen(tmp_file, "wb+", &fp); + if (err != EMAIL_ERROR_NONE) { + EM_DEBUG_EXCEPTION_SEC("em_fopen failed - %s", tmp_file); + goto FINISH_OFF; + } + + if (encoded_len > 0 && fwrite(test_buffer, encoded_len, 1, fp) == 0) { + EM_DEBUG_EXCEPTION("Error Occured while writing. fwrite(\"%s\") failed", test_buffer); + err = EMAIL_ERROR_SYSTEM_FAILURE; + fclose(fp); /* prevent */ + goto FINISH_OFF; + } + + if (fp != NULL) + fclose(fp); + + flag_first_write = false; + } else { + FILE *fp = NULL; + int encoded_len = EM_SAFE_STRLEN((char *)test_buffer); + + err = em_fopen(tmp_file, "ab+", &fp); + if (err != EMAIL_ERROR_NONE) { + EM_DEBUG_EXCEPTION_SEC("em_fopen failed - %s", tmp_file); + goto FINISH_OFF; + } + + if (encoded_len > 0 && fwrite(test_buffer, encoded_len, 1, fp) == 0) { + EM_DEBUG_EXCEPTION("Error Occured while writing. fwrite(\"%s\") failed", test_buffer); + err = EMAIL_ERROR_SYSTEM_FAILURE; + fclose(fp); /* prevent */ + goto FINISH_OFF; + } + + if (fp != NULL) + fclose(fp); + } + EM_DEBUG_LOG("%d has been written", EM_SAFE_STRLEN((char *)test_buffer)); + } + + if (GMIME_IS_PART(mime_object) && mime_part) { + err = em_open(tmp_file, O_RDONLY, 0, &fd); + if (err != EMAIL_ERROR_NONE) { + EM_DEBUG_EXCEPTION("holder open failed : holder is a filename that will be saved."); + if (fd) close(fd); + goto FINISH_OFF; + } + + content_stream = g_mime_stream_fs_new(fd); + //parser = g_mime_parser_new_with_stream(content_stream); + content = g_mime_data_wrapper_new_with_stream(content_stream, mime_part->encoding); + if (content_stream) g_object_unref (content_stream); + g_mime_part_set_content_object(mime_part, content); + if (content) g_object_unref(content); + } + } + + EM_SAFE_FREE(tmp_file); + } + else if ((tag_position = g_strrstr(response, tag))) /* end of response */ { + if (!strncmp(tag_position + EM_SAFE_STRLEN(tag) + 1, "OK", 2)) { + EM_SAFE_FREE(response); + } else { /* 'NO' or 'BAD */ + err = EMAIL_ERROR_IMAP4_FETCH_UID_FAILURE; + goto FINISH_OFF; + } + break; + } + else if (!strcmp(response, ")")) { + /* The end of response which contains body information */ + } + } /* while (imaplocal->netstream) */ + + ret = TRUE; + +FINISH_OFF: + + EM_SAFE_FREE(tmp_file); + EM_SAFE_FREE(response); + EM_SAFE_FREE (new_response); + + if (search_info) { + EM_SAFE_FREE(search_info->section); + EM_SAFE_FREE(search_info); + } + + /*if (mime_iter) { + g_mime_part_iter_free(mime_iter); + mime_iter = NULL; + }*/ + + if (err_code != NULL) + *err_code = err; + + EM_DEBUG_FUNC_END(); + + return ret; +} + +INTERNAL_FUNC int emcore_gmime_check_filename_duplication(char *source_filename, struct _m_content_info *cnt_info) +{ + EM_DEBUG_FUNC_BEGIN("source_file_name [%s], content_info [%p]", source_filename, cnt_info); + + if (!source_filename || !cnt_info || strlen(source_filename) <= 0) { + EM_DEBUG_EXCEPTION("Invalid parameter"); + return FALSE; + } + + struct attachment_info *cur_attachment_info = NULL; + int ret = FALSE; + + cur_attachment_info = cnt_info->inline_file; + + while (cur_attachment_info) { + + if(g_strcmp0(source_filename, cur_attachment_info->name) == 0) { + ret = TRUE; + break; + } + + cur_attachment_info = cur_attachment_info->next; + } + + EM_DEBUG_FUNC_END(); + return ret; +} + +INTERNAL_FUNC char *emcore_gmime_get_modified_filename_in_duplication(char *source_filename) +{ + EM_DEBUG_FUNC_BEGIN(); + + struct timeval tv; + char temp_filename[MAX_PATH] = {0,}; + //char *filename = NULL; + //char *extension = NULL; + + if (!source_filename) { + EM_DEBUG_EXCEPTION("Invalid parameter"); + return NULL; + } + + /*if ((err = em_get_file_name_and_extension_from_file_path(source_filename, &filename, &extension)) != EMAIL_ERROR_NONE) { + EM_DEBUG_EXCEPTION("em_get_file_name_and_extension_from_file_path failed [%d]", err); + return NULL; + }*/ + + gettimeofday(&tv, NULL); + srand(tv.tv_usec); + + snprintf(temp_filename, MAX_PATH, "%d_%s", rand(), source_filename); + EM_DEBUG_LOG_SEC("temp_file_name [%s]", temp_filename); + + EM_DEBUG_FUNC_END(); + return EM_SAFE_STRDUP(temp_filename); +} + +INTERNAL_FUNC char *emcore_gmime_get_encoding_to_utf8(const char *text) +{ + EM_DEBUG_FUNC_BEGIN(); + + if (text == NULL) { + EM_DEBUG_EXCEPTION("Invalid parameter"); + return NULL; + } + + char *encoded_text = NULL; + + encoded_text = g_mime_utils_header_encode_text(text); + if (encoded_text == NULL) { + EM_DEBUG_EXCEPTION("g_mime_utils_header_encode_text failed : [%s]", text); + return NULL; + } + + EM_DEBUG_LOG_SEC("encoded_text : [%s]", encoded_text); + + return encoded_text; +} + +INTERNAL_FUNC char *emcore_gmime_get_decoding_text(const char *text) +{ + EM_DEBUG_FUNC_BEGIN(); + + if (text == NULL) { + EM_DEBUG_EXCEPTION("Invalid parameter"); + return NULL; + } + + char *decoded_text = NULL; + + decoded_text = g_mime_utils_header_decode_text(text); + if (decoded_text == NULL) { + EM_DEBUG_EXCEPTION("g_mime_utils_header_encode_text failed : [%s]", text); + return NULL; + } + + EM_DEBUG_LOG("decoded_text : [%s]", decoded_text); + + return decoded_text; +} + +INTERNAL_FUNC char *emcore_gmime_get_mime_entity_signed_message(GMimeObject *multipart) +{ + EM_DEBUG_FUNC_BEGIN(); + + int entity_fd = 0; + int real_size = 0; + int error = EMAIL_ERROR_NONE; + char *mime_entity_path = NULL; + + GMimeObject *mime_entity = NULL; + GMimeStream *out_stream = NULL; + + if (!GMIME_IS_MULTIPART_SIGNED(multipart)) { + EM_DEBUG_EXCEPTION("Invalid param"); + error = EMAIL_ERROR_INVALID_PARAM; + goto FINISH_OFF; + } + + if (!emcore_get_temp_file_name(&mime_entity_path, &error)) { + EM_DEBUG_EXCEPTION("emcore_get_temp_file_name failed : [%d]", error); + goto FINISH_OFF; + } + + entity_fd = open(mime_entity_path, O_WRONLY|O_CREAT, 0644); + if (entity_fd < 0) { + EM_DEBUG_EXCEPTION("open failed"); + error = EMAIL_ERROR_SYSTEM_FAILURE; + goto FINISH_OFF; + } + + mime_entity = g_mime_multipart_get_part((GMimeMultipart *)multipart, 0); + out_stream = g_mime_stream_fs_new(entity_fd); + real_size = g_mime_object_write_to_stream(mime_entity, out_stream); + if (out_stream) g_object_unref(out_stream); + + if (real_size <= 0) { + EM_DEBUG_EXCEPTION("g_mime_object_write_to_stream failed"); + error = EMAIL_ERROR_FILE; + goto FINISH_OFF; + } + +FINISH_OFF: + + if (out_stream) g_object_unref(out_stream); + + if (error != EMAIL_ERROR_NONE) { + EM_SAFE_FREE(mime_entity_path); + return NULL; + } else { + return mime_entity_path; + } +} + +INTERNAL_FUNC char *emcore_gmime_get_mime_entity(int fd) +{ + EM_DEBUG_FUNC_BEGIN(); + char *output_path = NULL; + + GMimeStream *stream = NULL; + GMimeParser *parser = NULL; + GMimeObject *part = NULL; + + stream = g_mime_stream_fs_new(fd); + + parser = g_mime_parser_new_with_stream(stream); + if (stream) g_object_unref(stream); + + part = g_mime_parser_construct_part(parser); + if (parser) g_object_unref(parser); + if (part == NULL) { + EM_DEBUG_EXCEPTION("Data is invalid"); + return NULL; + } + + output_path = emcore_gmime_get_mime_entity_signed_message(part); + + if (part) g_object_unref(part); + + EM_DEBUG_FUNC_END(); + return output_path; +} diff --git a/email-core/email-core-pgp.c b/email-core/email-core-pgp.c new file mode 100644 index 0000000..17afa56 --- /dev/null +++ b/email-core/email-core-pgp.c @@ -0,0 +1,797 @@ +/* +* email-service +* +* Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved. +* +* Contact: Kyuho Jo , Sunghyun Kwon +* +* 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 : email-core-smime.c + *Desc : MIME Operation + * + *Auth : + * + *History : + * 2011.04.14 : created + ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ***/ +#undef close + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "email-utilities.h" +#include "email-core-global.h" +#include "email-core-utils.h" +#include "email-core-mail.h" +#include "email-core-smtp.h" +#include "email-storage.h" +#include "email-core-cert.h" +#include "email-debug-log.h" + +#define PGP_SIGNED_FILE "signature.asc" +#define PGP_ENCRYPTED_FILE "encrypted.asc" +#define DECRYPTED_TEMP_FILE "decrypted_temp_file.eml" + +static char *passphrase = NULL; + +static gboolean request_passwd(GMimeCryptoContext *ctx, const char *user_id, + const char *prompt_ctx, gboolean reprompt, + GMimeStream *response, GError **err) +{ + EM_DEBUG_FUNC_BEGIN(); + EM_DEBUG_LOG("passpharse : [%s]", passphrase); + if (g_mime_stream_write_string (response, passphrase) == -1 || + g_mime_stream_write (response, "\n", 1) == -1) { + g_set_error (err, GMIME_ERROR, errno, "%s", g_strerror (errno)); + return false; + } + + EM_SAFE_FREE(passphrase); + + EM_DEBUG_FUNC_END(); + return true; +} + +static int emcore_pgp_get_gmime_digest_algo(email_digest_type digest_type) +{ + EM_DEBUG_FUNC_BEGIN(); + int gmime_digest_algo = GMIME_DIGEST_ALGO_DEFAULT; + + switch (digest_type) { + case DIGEST_TYPE_SHA1: + gmime_digest_algo = GMIME_DIGEST_ALGO_SHA1; + break; + case DIGEST_TYPE_MD5: + gmime_digest_algo = GMIME_DIGEST_ALGO_MD5; + break; + case DIGEST_TYPE_RIPEMD160: + gmime_digest_algo = GMIME_DIGEST_ALGO_RIPEMD160; + break; + case DIGEST_TYPE_MD2: + gmime_digest_algo = GMIME_DIGEST_ALGO_MD2; + break; + case DIGEST_TYPE_TIGER192: + gmime_digest_algo = GMIME_DIGEST_ALGO_TIGER192; + break; + case DIGEST_TYPE_HAVAL5160: + gmime_digest_algo = GMIME_DIGEST_ALGO_HAVAL5160; + break; + case DIGEST_TYPE_SHA256: + gmime_digest_algo = GMIME_DIGEST_ALGO_SHA256; + break; + case DIGEST_TYPE_SHA384: + gmime_digest_algo = GMIME_DIGEST_ALGO_SHA384; + break; + case DIGEST_TYPE_SHA512: + gmime_digest_algo = GMIME_DIGEST_ALGO_SHA512; + break; + case DIGEST_TYPE_SHA224: + gmime_digest_algo = GMIME_DIGEST_ALGO_SHA224; + break; + case DIGEST_TYPE_MD4: + gmime_digest_algo = GMIME_DIGEST_ALGO_MD4; + break; + default: + gmime_digest_algo = GMIME_DIGEST_ALGO_DEFAULT; + break; + } + + EM_DEBUG_FUNC_END(); + return gmime_digest_algo; +} + +static int get_stack_of_recipients(char *recipients, GPtrArray **output_recipients_array) { + EM_DEBUG_FUNC_BEGIN(); + int err = EMAIL_ERROR_NONE; + char *temp_key = NULL; + char *keys = NULL; + GPtrArray *p_recipients_array = NULL; + gchar **strings = NULL; + gchar **ptr = NULL; + + p_recipients_array = g_ptr_array_new(); + if (p_recipients_array == NULL) { + EM_DEBUG_EXCEPTION("g_ptr_array_new failed"); + err = EMAIL_ERROR_OUT_OF_MEMORY; + goto FINISH_OFF; + } + + keys = EM_SAFE_STRDUP(recipients); + strings = g_strsplit(keys, ",", -1); + + for (ptr = strings; *ptr; ptr++){ + temp_key = NULL; + temp_key = g_strdup_printf("0x%s",*(ptr)); + g_ptr_array_add(p_recipients_array, temp_key); + } + +FINISH_OFF: + g_strfreev(strings); + EM_SAFE_FREE(keys); + if (err != EMAIL_ERROR_NONE) + g_ptr_array_free(p_recipients_array, true); + else + *output_recipients_array = p_recipients_array; + + EM_DEBUG_FUNC_END(); + return err; +} + +static GMimeSignatureStatus get_signature_status(GMimeSignatureList *signatures) +{ + EM_DEBUG_FUNC_BEGIN(); + + int i = 0; + + GMimeSignature *sig = NULL; + GMimeSignatureStatus status = GMIME_SIGNATURE_STATUS_GOOD; + + if (!signatures || signatures->array->len == 0) + return GMIME_SIGNATURE_STATUS_ERROR; + + for (i = 0; i < g_mime_signature_list_length(signatures); i++) { + sig = g_mime_signature_list_get_signature(signatures, i); + if (sig) status = MAX(status, sig->status); + } + + EM_DEBUG_FUNC_END(); + + return status; +} + +INTERNAL_FUNC int emcore_pgp_set_signed_message(char *certificate, + char *password, + char *mime_entity, + char *user_id, + email_digest_type digest_type, + char **file_path) +{ + EM_DEBUG_FUNC_BEGIN_SEC("Certificate path : [%s], mime_entity : [%s]", certificate, mime_entity); + +#ifdef __FEATURE_SECURE_PGP__ + int err = EMAIL_ERROR_NONE; + int clear_fd = 0; + int gpg_fd = 0; + int p_digest_type = 0; + char temp_pgp_filepath[512] = {0, }; + + GMimeCryptoContext *ctx = NULL; + GMimeStream *clear_text = NULL; + GMimeStream *signed_text = NULL; + GError *g_err = NULL; + + if (!password || !mime_entity || !user_id) { + EM_DEBUG_EXCEPTION("Invalid param"); + err = EMAIL_ERROR_INVALID_PARAM; + return err; + } + + /* Initialized the output stream (signed stream) */ + EM_SAFE_FREE(passphrase); + passphrase = EM_SAFE_STRDUP(password); + +#if !GLIB_CHECK_VERSION(2, 31, 0) + g_thread_init(NULL); +#endif + g_mime_init(0); + + SNPRINTF(temp_pgp_filepath, sizeof(temp_pgp_filepath), "%s%s%s", MAILTEMP, DIR_SEPERATOR, PGP_SIGNED_FILE); + EM_DEBUG_LOG_SEC("attachment file path of pgp : [%s]", temp_pgp_filepath); + + err = em_open(temp_pgp_filepath, O_CREAT|O_TRUNC|O_RDWR, S_IRUSR|S_IWUSR|S_IWGRP|S_IRGRP|S_IROTH, &gpg_fd); + if (err != EMAIL_ERROR_NONE) { + EM_DEBUG_EXCEPTION("em_open failed : [%s] [%d]", temp_pgp_filepath, err); + goto FINISH_OFF; + } + + signed_text = g_mime_stream_fs_new(gpg_fd); + if (g_mime_stream_reset(signed_text) == -1) { + EM_DEBUG_EXCEPTION("g_mime_stream_reset signed_text failed"); + err = EMAIL_ERROR_SYSTEM_FAILURE; + goto FINISH_OFF; + } + + ctx = g_mime_gpg_context_new(request_passwd, "/usr/bin/gpg"); + g_mime_gpg_context_set_always_trust ((GMimeGpgContext *)ctx, true); + + /* Initialized the input stream (clear text stream) */ + EM_DEBUG_LOG("mime_entity : [%s]", mime_entity); + err = em_open(mime_entity, O_RDONLY, 0, &clear_fd); + if (err != EMAIL_ERROR_NONE) { + EM_DEBUG_EXCEPTION("em_open failed : [%s] [%d]", mime_entity, err); + goto FINISH_OFF; + } + + clear_text = g_mime_stream_fs_new(clear_fd); + if (g_mime_stream_reset(clear_text) == -1) { + EM_DEBUG_EXCEPTION("g_mime_stream_reset clear_text failed"); + err = EMAIL_ERROR_SYSTEM_FAILURE; + goto FINISH_OFF; + } + + /* Get the digest type of gmime */ + p_digest_type = emcore_pgp_get_gmime_digest_algo(digest_type); + + /* Set the signed message */ + if ((g_mime_crypto_context_sign(ctx, + user_id, + p_digest_type, + clear_text, + signed_text, + &g_err) < 0) && (g_err != NULL)) { + EM_DEBUG_EXCEPTION("g_mime_crypto_context_sign failed : [%s]", g_err->message); + err = EMAIL_ERROR_SYSTEM_FAILURE; + goto FINISH_OFF; + } + +FINISH_OFF: + + if (g_err) + g_error_free(g_err); + + if (clear_text) + g_object_unref(clear_text); + + if (signed_text) + g_object_unref(signed_text); + + if (ctx) + g_object_unref(ctx); + + g_mime_shutdown(); + + close(clear_fd); + close(gpg_fd); + + if (file_path) + *file_path = EM_SAFE_STRDUP(temp_pgp_filepath); + + return err; +#else /* __FEATURE_SECURE_PGP__ */ + + return EMAIL_ERROR_NOT_SUPPORTED; + +#endif +} + +INTERNAL_FUNC int emcore_pgp_set_encrypted_message(char *recipient_list, + char *certificate, + char *password, + char *mime_entity, + char *user_id, + email_digest_type digest_type, + char **file_path) +{ + EM_DEBUG_FUNC_BEGIN_SEC("Certificate path : [%s], mime_entity : [%s]", certificate, mime_entity); + +#ifdef __FEATURE_SECURE_PGP__ + int err = EMAIL_ERROR_NONE; + int clear_fd = 0; + int gpg_fd = 0; + int p_digest_type = 0; + char temp_pgp_filepath[512] = {0, }; + + GPtrArray *recipients = NULL; + + GMimeCryptoContext *ctx = NULL; + GMimeStream *clear_text = NULL; + GMimeStream *encrypted_text = NULL; + GError *g_err = NULL; + + if (!recipient_list || !mime_entity || !user_id) { + EM_DEBUG_EXCEPTION("Invalid param"); + err = EMAIL_ERROR_INVALID_PARAM; + return err; + } + + /* Initialized the output stream (signed stream) */ +#if !GLIB_CHECK_VERSION(2, 31, 0) + g_thread_init(NULL); +#endif + g_mime_init(0); + + SNPRINTF(temp_pgp_filepath, sizeof(temp_pgp_filepath), "%s%s%s", MAILTEMP, DIR_SEPERATOR, PGP_ENCRYPTED_FILE); + EM_DEBUG_LOG_SEC("attachment file path of pgp : [%s]", temp_pgp_filepath); + + err = em_open(temp_pgp_filepath, O_CREAT|O_TRUNC|O_RDWR, S_IRUSR|S_IWUSR|S_IWGRP|S_IRGRP|S_IROTH, &gpg_fd); + if (err != EMAIL_ERROR_NONE) { + EM_DEBUG_EXCEPTION("em_open failed : [%s] [%d]", temp_pgp_filepath, err); + goto FINISH_OFF; + } + + encrypted_text = g_mime_stream_fs_new(gpg_fd); + if (g_mime_stream_reset(encrypted_text) == -1) { + EM_DEBUG_EXCEPTION("g_mime_stream_reset encrypted_text failed"); + err = EMAIL_ERROR_SYSTEM_FAILURE; + goto FINISH_OFF; + } + + ctx = g_mime_gpg_context_new(request_passwd, "/usr/bin/gpg"); + g_mime_gpg_context_set_always_trust ((GMimeGpgContext *)ctx, true); + + /* Initialized the input stream (clear text stream) */ + EM_DEBUG_LOG("mime_entity : [%s]", mime_entity); + err = em_open(mime_entity, O_RDONLY, 0, &clear_fd); + if (err != EMAIL_ERROR_NONE) { + EM_DEBUG_EXCEPTION("em_open failed : [%s] [%d]", mime_entity, err); + goto FINISH_OFF; + } + + clear_text = g_mime_stream_fs_new(clear_fd); + if (g_mime_stream_reset(clear_text) == -1) { + EM_DEBUG_EXCEPTION("g_mime_stream_reset clear_text failed"); + err = EMAIL_ERROR_SYSTEM_FAILURE; + goto FINISH_OFF; + } + + /* Get the digest type of gmime */ + p_digest_type = emcore_pgp_get_gmime_digest_algo(digest_type); + + /* Set the recipients list */ + if ((err = get_stack_of_recipients(recipient_list, &recipients)) != EMAIL_ERROR_NONE) { + EM_DEBUG_EXCEPTION("get_stack_of_recipients failed : [%d]", err); + goto FINISH_OFF; + } + + /* Set the signed message */ + if ((g_mime_crypto_context_encrypt(ctx, + false, + user_id, + p_digest_type, + recipients, + clear_text, + encrypted_text, + &g_err) < 0) && (g_err != NULL)) { + EM_DEBUG_EXCEPTION("NO signature : g_mime_crypto_context_encrypt failed : [%s]", g_err->message); + err = EMAIL_ERROR_SYSTEM_FAILURE; + goto FINISH_OFF; + } + +FINISH_OFF: + + g_ptr_array_free(recipients, true); + + if (g_err) + g_error_free(g_err); + + if (clear_text) + g_object_unref(clear_text); + + if (encrypted_text) + g_object_unref(encrypted_text); + + if (ctx) + g_object_unref(ctx); + + g_mime_shutdown(); + + close(clear_fd); + close(gpg_fd); + + if (file_path) + *file_path = EM_SAFE_STRDUP(temp_pgp_filepath); + + return err; +#else /* __FEATURE_SECURE_PGP__ */ + + return EMAIL_ERROR_NOT_SUPPORTED; + +#endif + +} + +INTERNAL_FUNC int emcore_pgp_set_signed_and_encrypted_message(char *recipient_list, + char *certificate, + char *password, + char *mime_entity, + char *user_id, + email_digest_type digest_type, + char **file_path) +{ + EM_DEBUG_FUNC_BEGIN_SEC("mime_entity : [%s]", mime_entity); + +#ifdef __FEATURE_SECURE_PGP__ + int err = EMAIL_ERROR_NONE; + int clear_fd = 0; + int gpg_fd = 0; + int p_digest_type = 0; + char temp_pgp_filepath[512] = {0, }; + + GPtrArray *recipients = NULL; + GMimeCryptoContext *ctx = NULL; + GMimeStream *clear_text = NULL; + GMimeStream *encrypted_text = NULL; + GError *g_err = NULL; + + if (!recipient_list || !password || !mime_entity || !user_id) { + EM_DEBUG_EXCEPTION("Invalid param"); + err = EMAIL_ERROR_INVALID_PARAM; + return err; + } + + /* Initialized the output stream (signed stream) */ + EM_SAFE_FREE(passphrase); + passphrase = strdup(password); + +#if !GLIB_CHECK_VERSION(2, 31, 0) + g_thread_init(NULL); +#endif + g_mime_init(0); + + SNPRINTF(temp_pgp_filepath, sizeof(temp_pgp_filepath), "%s%s%s", MAILTEMP, DIR_SEPERATOR, PGP_ENCRYPTED_FILE); + EM_DEBUG_LOG_SEC("attachment file path of pgp : [%s]", temp_pgp_filepath); + + err = em_open(temp_pgp_filepath, O_CREAT|O_TRUNC|O_RDWR, S_IRUSR|S_IWUSR|S_IWGRP|S_IRGRP|S_IROTH, &gpg_fd); + if (err != EMAIL_ERROR_NONE) { + EM_DEBUG_EXCEPTION("em_open failed : [%s], [%d]", temp_pgp_filepath, err); + goto FINISH_OFF; + } + + encrypted_text = g_mime_stream_fs_new(gpg_fd); + if (g_mime_stream_reset(encrypted_text) == -1) { + EM_DEBUG_EXCEPTION("g_mime_stream_reset encrypted_text failed"); + err = EMAIL_ERROR_SYSTEM_FAILURE; + goto FINISH_OFF; + } + + ctx = g_mime_gpg_context_new(request_passwd, "/usr/bin/gpg"); + g_mime_gpg_context_set_always_trust ((GMimeGpgContext *)ctx, true); + + /* Initialized the input stream (clear text stream) */ + EM_DEBUG_LOG("mime_entity : [%s]", mime_entity); + err = em_open(mime_entity, O_RDONLY, 0, &clear_fd); + if (err != EMAIL_ERROR_NONE) { + EM_DEBUG_EXCEPTION("em_open failed : [%s] [%d]", mime_entity, err); + goto FINISH_OFF; + } + + clear_text = g_mime_stream_fs_new(clear_fd); + if (g_mime_stream_reset(clear_text) == -1) { + EM_DEBUG_EXCEPTION("g_mime_stream_reset clear_text failed"); + err = EMAIL_ERROR_SYSTEM_FAILURE; + goto FINISH_OFF; + } + + /* Get the digest type of gmime */ + p_digest_type = emcore_pgp_get_gmime_digest_algo(digest_type); + + /* Set the recipients list */ + if ((err = get_stack_of_recipients(recipient_list, &recipients)) != EMAIL_ERROR_NONE) { + EM_DEBUG_EXCEPTION("get_stack_of_recipients failed : [%d]", err); + goto FINISH_OFF; + } + + /* Set the signed message */ + if ((g_mime_crypto_context_encrypt(ctx, + true, + user_id, + p_digest_type, + recipients, + clear_text, + encrypted_text, + &g_err) < 0) && (g_err != NULL)) { + EM_DEBUG_EXCEPTION("Signature : g_mime_crypto_context_encrypt failed : [%s]", g_err->message); + err = EMAIL_ERROR_SYSTEM_FAILURE; + goto FINISH_OFF; + } + +FINISH_OFF: + + g_ptr_array_free(recipients, true); + + if (g_err) + g_error_free(g_err); + + if (clear_text) + g_object_unref(clear_text); + + if (encrypted_text) + g_object_unref(encrypted_text); + + if (ctx) + g_object_unref(ctx); + + g_mime_shutdown(); + + close(clear_fd); + close(gpg_fd); + + if (file_path) + *file_path = EM_SAFE_STRDUP(temp_pgp_filepath); + + return err; +#else /* __FEATURE_SECURE_PGP__ */ + + return EMAIL_ERROR_NOT_SUPPORTED; + +#endif + +} + +INTERNAL_FUNC int emcore_pgp_get_verify_signature(char *signature_path, + char *mime_entity, + email_digest_type digest_type, + int *verify) +{ + EM_DEBUG_FUNC_BEGIN_SEC("signature path : [%s], mime_entity : [%s]", signature_path, mime_entity); + +#ifdef __FEATURE_SECURE_PGP__ + int err = EMAIL_ERROR_NONE; + int clear_fd = 0; + int signed_fd = 0; + int p_digest_type = 0; + int p_verify = false; + + GMimeCryptoContext *ctx = NULL; + GMimeStream *clear_text = NULL; + GMimeStream *signed_text = NULL; + GMimeSignatureList *signatures = NULL; + GError *g_err = NULL; + + if (!signature_path || !mime_entity) { + EM_DEBUG_EXCEPTION("Invalid param"); + err = EMAIL_ERROR_INVALID_PARAM; + return err; + } + + /* Initialized the Context */ +#if !GLIB_CHECK_VERSION(2, 31, 0) + g_thread_init(NULL); +#endif + g_mime_init(0); + + ctx = g_mime_gpg_context_new(request_passwd, "/usr/bin/gpg"); + g_mime_gpg_context_set_always_trust ((GMimeGpgContext *)ctx, true); + + /* Initialized the input stream (clear text stream) */ + EM_DEBUG_LOG("mime_entity : [%s]", mime_entity); + err = em_open(mime_entity, O_RDONLY, 0, &clear_fd); + if (err != EMAIL_ERROR_NONE) { + EM_DEBUG_EXCEPTION("em_open failed : [%s] [%d]", mime_entity, err); + goto FINISH_OFF; + } + + clear_text = g_mime_stream_fs_new(clear_fd); + if (g_mime_stream_reset(clear_text) == -1) { + EM_DEBUG_EXCEPTION("g_mime_stream_reset clear_text failed"); + err = EMAIL_ERROR_SYSTEM_FAILURE; + goto FINISH_OFF; + } + + /* Initialized the output stream (signed stream) */ + EM_DEBUG_LOG("signature_path : [%s]", signature_path); + err = em_open(signature_path, O_RDONLY, 0, &signed_fd); + if (err != EMAIL_ERROR_NONE) { + EM_DEBUG_EXCEPTION("em_open failed : [%s] [%d]", signature_path, err); + goto FINISH_OFF; + } + + signed_text = g_mime_stream_fs_new(signed_fd); + if (g_mime_stream_reset(signed_text) == -1) { + EM_DEBUG_EXCEPTION("g_mime_stream_reset signed_text failed"); + err = EMAIL_ERROR_SYSTEM_FAILURE; + goto FINISH_OFF; + } + + /* Get the digest type of gmime */ + p_digest_type = emcore_pgp_get_gmime_digest_algo(digest_type); + + /* Verify the signature */ + signatures = g_mime_crypto_context_verify(ctx, p_digest_type, clear_text, signed_text, &g_err); + if (signatures == NULL) { + EM_DEBUG_EXCEPTION("g_mime_crypto_context_verify failed : [%s]", g_err->message); + err = EMAIL_ERROR_SYSTEM_FAILURE; + goto FINISH_OFF; + } + + if (get_signature_status(signatures) != GMIME_SIGNATURE_STATUS_GOOD) { + EM_DEBUG_LOG("Invalid the signature"); + goto FINISH_OFF; + } + + p_verify = true; + +FINISH_OFF: + + if (g_err) + g_error_free(g_err); + + if (signatures) + g_object_unref(signatures); + + if (clear_text) + g_object_unref(clear_text); + + if (signed_text) + g_object_unref(signed_text); + + if (ctx) + g_object_unref(ctx); + + g_mime_shutdown(); + + close(clear_fd); + close(signed_fd); + + if (verify) + *verify = p_verify; + + return err; +#else /* __FEATURE_SECURE_PGP__ */ + + return EMAIL_ERROR_NOT_SUPPORTED; + +#endif + +} + +INTERNAL_FUNC int emcore_pgp_get_decrypted_message(char *encrypted_message, + char *password, + int sign, + char **decrypted_file, + int *verify) +{ + EM_DEBUG_FUNC_BEGIN_SEC("Encrypted message : [%s], password : [%s]", encrypted_message, password); + +#ifdef __FEATURE_SECURE_PGP__ + int err = EMAIL_ERROR_NONE; + int p_verify = false; + int decrypted_fd = 0; + int encrypted_fd = 0; + char temp_decrypt_filepath[512] = {0, }; + + GError *g_err = NULL; + GMimeCryptoContext *ctx = NULL; + GMimeDecryptResult *result = NULL; + GMimeStream *encrypted_text = NULL; + GMimeStream *decrypted_text = NULL; + + if (!encrypted_message && !password) { + EM_DEBUG_EXCEPTION("Invalid parameter"); + err = EMAIL_ERROR_INVALID_PARAM; + return err; + } + + EM_SAFE_FREE(passphrase); + passphrase = EM_SAFE_STRDUP(password); + +#if !GLIB_CHECK_VERSION(2, 31, 0) + g_thread_init(NULL); +#endif + g_mime_init(0); + + /* Initialized the context */ + ctx = g_mime_gpg_context_new(request_passwd, "/usr/bin/gpg"); + g_mime_gpg_context_set_always_trust ((GMimeGpgContext *)ctx, true); + + /* Initialized the input stream (clear text stream) */ + err = em_open(encrypted_message, O_RDONLY, 0, &encrypted_fd); + if (err != EMAIL_ERROR_NONE) { + EM_DEBUG_EXCEPTION("em_open failed : [%s] [%d]", encrypted_message, err); + goto FINISH_OFF; + } + + encrypted_text = g_mime_stream_fs_new(encrypted_fd); + if (g_mime_stream_reset(encrypted_text) == -1) { + EM_DEBUG_EXCEPTION("g_mime_stream_reset encrypted_text failed"); + err = EMAIL_ERROR_SYSTEM_FAILURE; + goto FINISH_OFF; + } + + /* Initialized the output stream (signed stream) */ + SNPRINTF(temp_decrypt_filepath, sizeof(temp_decrypt_filepath), "%s%s%s", MAILTEMP, DIR_SEPERATOR, DECRYPTED_TEMP_FILE); + EM_DEBUG_LOG_SEC("tmp decrypt file path : [%s]", temp_decrypt_filepath); + + err = em_open(temp_decrypt_filepath, O_CREAT|O_TRUNC|O_RDWR, S_IRUSR|S_IWUSR|S_IWGRP|S_IRGRP|S_IROTH, &decrypted_fd); + if (err != EMAIL_ERROR_NONE) { + EM_DEBUG_EXCEPTION("em_open failed : [%s] [%d]", temp_decrypt_filepath, err); + goto FINISH_OFF; + } + + decrypted_text = g_mime_stream_fs_new(decrypted_fd); + if (g_mime_stream_reset(decrypted_text) == -1) { + EM_DEBUG_EXCEPTION("g_mime_stream_reset decrypted_text failed"); + err = EMAIL_ERROR_SYSTEM_FAILURE; + goto FINISH_OFF; + } + + /* Get the decrypt message */ + result = g_mime_crypto_context_decrypt(ctx, encrypted_text, decrypted_text, &g_err); + if (result == NULL) { + EM_DEBUG_EXCEPTION("g_mime_crypto_context_decrypt failed : [%s]", g_err->message); + err = EMAIL_ERROR_DECRYPT_FAILED; + goto FINISH_OFF; + } + + if (result->signatures) { + if (get_signature_status(result->signatures) != GMIME_SIGNATURE_STATUS_GOOD) + p_verify = false; + else + p_verify = true; + } else { + p_verify = -1; + } + +FINISH_OFF: + + if (g_err) + g_error_free(g_err); + + if (ctx) + g_object_unref(ctx); + + if (encrypted_text) + g_object_unref(encrypted_text); + + if (decrypted_text) + g_object_unref(decrypted_text); + + if (result) + g_object_unref(result); + + g_mime_shutdown(); + + close(encrypted_fd); + close(decrypted_fd); + + if (verify) + *verify = p_verify; + + if (decrypted_file) + *decrypted_file = EM_SAFE_STRDUP(temp_decrypt_filepath); + + return err; +#else /* __FEATURE_SECURE_PGP__ */ + + return EMAIL_ERROR_NOT_SUPPORTED; + +#endif +} + diff --git a/email-core/include/email-core-auto-download.h b/email-core/include/email-core-auto-download.h new file mode 100755 index 0000000..d4b863d --- /dev/null +++ b/email-core/include/email-core-auto-download.h @@ -0,0 +1,59 @@ +/* +* email-service +* +* Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved. +* +* Contact: Minsoo Kim , Kyuho Jo , +* Sunghyun Kwon +* +* 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. +* +*/ + +#ifndef __EMAIL_CORE_AUTO_DOWNLOAD_H__ +#define __EMAIL_CORE_AUTO_DOWNLOAD_H__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +typedef struct auto_download_t +{ + int activity_id; + int status; + int account_id; + int mail_id; + unsigned long server_mail_id; + int mailbox_id; + char *multi_user_name; +} email_event_auto_download; + +INTERNAL_FUNC int emcore_start_auto_download_loop(int *err_code); +INTERNAL_FUNC int emcore_auto_download_loop_continue(void); +INTERNAL_FUNC int emcore_stop_auto_download_loop(int *err_code); +INTERNAL_FUNC int emcore_insert_auto_download_event(email_event_auto_download *event_data, int *err_code); +INTERNAL_FUNC int emcore_retrieve_auto_download_event(email_event_auto_download **event_data, int *err_code); +INTERNAL_FUNC int emcore_is_auto_download_queue_empty(void); +INTERNAL_FUNC int emcore_is_auto_download_queue_full(void); +INTERNAL_FUNC int emcore_clear_auto_download_queue(void); + +INTERNAL_FUNC int emcore_insert_auto_download_job(char *multi_user_name, int account_id, int mailbox_id, int mail_id, int auto_download_on, char *uid, int *err_code); +INTERNAL_FUNC int emcore_insert_auto_download_activity(email_event_auto_download *local_activity, int *activity_id, int *err_code); +INTERNAL_FUNC int emcore_delete_auto_download_activity(char *multi_user_name, int account_id, int mail_id, int activity_id, int *err_code); +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +/* EOF */ diff --git a/email-core/include/email-core-container.h b/email-core/include/email-core-container.h new file mode 100644 index 0000000..663b1f6 --- /dev/null +++ b/email-core/include/email-core-container.h @@ -0,0 +1,45 @@ +/* +* email-service +* +* Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved. +* +* Contact: Kyuho Jo , Sunghyun Kwon +* +* 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 functionality related to KNOX + * to interact with email-service. + * @file email-core-container.c + * @author + * @version 0.1 + * @brief This file contains functionality to provide KNOX support in email-service. + */ + +#include +#include "email-internal-types.h" + +INTERNAL_FUNC void emcore_create_container(); +INTERNAL_FUNC void emcore_destroy_container(); +INTERNAL_FUNC void emcore_bind_vsm_context(); +INTERNAL_FUNC int emcore_get_container_path(char *multi_user_name, char **container_path); +INTERNAL_FUNC int emcore_get_user_name(int pid, char **multi_user_name); +INTERNAL_FUNC int emcore_lookup_zone_by_name(char *user_name); +INTERNAL_FUNC void emcore_set_declare_link(const char *file_path); +INTERNAL_FUNC int emcore_get_zone_name_list(GList **output_name_list); +INTERNAL_FUNC int emcore_get_canonicalize_path(char *db_path, char **output_path); +INTERNAL_FUNC int emcore_set_join_zone(char *multi_user_name, void **join_zone); +INTERNAL_FUNC void emcore_unset_join_zone(void *join_zone); diff --git a/email-core/include/email-core-gmime.h b/email-core/include/email-core-gmime.h new file mode 100644 index 0000000..bb0a130 --- /dev/null +++ b/email-core/include/email-core-gmime.h @@ -0,0 +1,84 @@ +/* +* email-service +* +* Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved. +* +* Contact: Kyuho Jo , Sunghyun Kwon +* +* 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. +* +*/ + +#ifndef __EMAIL_CORE_GMIME_H__ +#define __EMAIL_CORE_GMIME_H__ + +#include "email-core-mail.h" +#include + +#include "c-client.h" +#include "lnx_inc.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +typedef struct _search_section { + GMimeObject *section_object; + char *section; +} search_section; + +INTERNAL_FUNC void emcore_gmime_init(void); +INTERNAL_FUNC void emcore_gmime_shutdown(void); + +INTERNAL_FUNC int emcore_gmime_pop3_parse_mime(char *eml_path, struct _m_content_info *cnt_info, int *err_code); +INTERNAL_FUNC int emcore_gmime_imap_parse_mime_partial(char *rfc822header_str, char *bodytext_str, struct _m_content_info *cnt_info); +INTERNAL_FUNC int emcore_gmime_eml_parse_mime(char *eml_path, struct _rfc822header *rfc822_header, struct _m_content_info *cnt_info, int *err_code); + +INTERNAL_FUNC void emcore_gmime_imap_parse_foreach_cb(GMimeObject *parent, GMimeObject *part, gpointer user_data); +INTERNAL_FUNC void emcore_gmime_imap_parse_full_foreach_cb(GMimeObject *parent, GMimeObject *part, gpointer user_data); +INTERNAL_FUNC void emcore_gmime_imap_parse_bodystructure_foreach_cb(GMimeObject *parent, GMimeObject *part, gpointer user_data); + +INTERNAL_FUNC void emcore_gmime_get_body_sections_foreach_cb(GMimeObject *parent, GMimeObject *part, gpointer user_data); +INTERNAL_FUNC void emcore_gmime_get_attachment_section_foreach_cb(GMimeObject *parent, GMimeObject *part, gpointer user_data); +INTERNAL_FUNC void emcore_gmime_search_section_foreach_cb(GMimeObject *parent, GMimeObject *part, gpointer user_data); + +INTERNAL_FUNC void emcore_gmime_construct_multipart (GMimeMultipart *multipart, BODY *body, const char *spec, int *total_mail_size); +INTERNAL_FUNC void emcore_gmime_construct_part (GMimePart *part, BODY *body, const char *spec, int *total_mail_size); +INTERNAL_FUNC int emcore_gmime_construct_mime_part_with_bodystructure(BODY *mbody, GMimeMessage **message, const char *spec, int *total_mail_size); + +INTERNAL_FUNC int emcore_gmime_get_body_sections_from_message(GMimeMessage *message, struct _m_content_info *cnt_info, char **sections_to_fetch); +INTERNAL_FUNC int emcore_gmime_get_attachment_section_from_message(GMimeMessage *message, + struct _m_content_info *cnt_info, int nth, char **section_to_fetch); + +INTERNAL_FUNC int emcore_gmime_fetch_imap_body_sections(MAILSTREAM *stream, int msg_uid, int mail_id, + struct _m_content_info *cnt_info, GMimeMessage *message, int event_handle, int auto_download, int *err_code); + +INTERNAL_FUNC int emcore_gmime_fetch_imap_attachment_section(MAILSTREAM *stream, + int mail_id, int uid, int nth, struct _m_content_info *cnt_info, + GMimeMessage *message, int auto_download, int event_handle, int *err_code); + +INTERNAL_FUNC int emcore_gmime_check_filename_duplication(char *source_filename, struct _m_content_info *cnt_info); +INTERNAL_FUNC char *emcore_gmime_get_modified_filename_in_duplication(char *source_filename); +INTERNAL_FUNC char *emcore_gmime_get_encoding_to_utf8(const char *text); +INTERNAL_FUNC char *emcore_gmime_get_decoding_text(const char *text); +INTERNAL_FUNC void emcore_gmime_get_mime_entity_cb(GMimeObject *parent, GMimeObject *part, gpointer user_data); +INTERNAL_FUNC char *emcore_gmime_get_mime_entity_signed_message(GMimeObject *multipart); +INTERNAL_FUNC char *emcore_gmime_get_mime_entity(int fd); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif +/* EOF */ diff --git a/email-core/include/email-core-pgp.h b/email-core/include/email-core-pgp.h new file mode 100644 index 0000000..b7d2288 --- /dev/null +++ b/email-core/include/email-core-pgp.h @@ -0,0 +1,50 @@ +/* +* email-service +* +* Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved. +* +* Contact: Kyuho Jo , Sunghyun Kwon +* +* 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 : email-core-smime.h + * Desc : Mail Operation Header + * + * Auth : + * + * History : + * 2006.08.16 : created + *****************************************************************************/ + +#ifndef EM_CORE_GPG_H_ +#define EM_CORE_GPG_H_ + +#include + +#include "email-types.h" + +INTERNAL_FUNC int emcore_pgp_set_signed_message(char *certificate, char *password, char *mime_entity, char *user_id, email_digest_type digest_type, char **file_path); + +INTERNAL_FUNC int emcore_pgp_set_encrypted_message(char *recipient_list, char *certificate, char *password, char *mime_entity, char *user_id, email_digest_type digest_type, char **file_path); + +INTERNAL_FUNC int emcore_pgp_set_signed_and_encrypted_message(char *recipient_list, char *certificate, char *password, char *mime_entity, char *user_id, email_digest_type digest_type, char **file_path); + +INTERNAL_FUNC int emcore_pgp_get_verify_signature(char *signature_path, char *mime_entity, email_digest_type digest_type, int *verify); + +INTERNAL_FUNC int emcore_pgp_get_decrypted_message(char *encrypted_message, char *password, int sign, char **decrypted_file, int *verify); + +#endif /* EM_CORE_GPG_H_ */ diff --git a/utilities/test-application/include/testapp-gmime.h b/utilities/test-application/include/testapp-gmime.h new file mode 100755 index 0000000..0aeafee --- /dev/null +++ b/utilities/test-application/include/testapp-gmime.h @@ -0,0 +1,31 @@ +/* +* email-service +* +* Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved. +* +* Contact: Kyuho Jo , Sunghyun Kwon +* +* 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. +* +*/ + + + +#ifndef EMAIL_TEST_GMIME_H +#define EMAIL_TEST_GMIME_H + +/* export API */ +void testapp_gmime_main(void); + +#endif + diff --git a/utilities/test-application/testapp-gmime.c b/utilities/test-application/testapp-gmime.c new file mode 100644 index 0000000..dfed596 --- /dev/null +++ b/utilities/test-application/testapp-gmime.c @@ -0,0 +1,189 @@ +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "testapp-utility.h" +#include "testapp-gmime.h" + + +#define TEST_EML_PATH "/tmp/test.eml" + +static void print_depth(int depth) +{ + int i; + for (i = 0; i < depth; i++) + testapp_print(" \n"); +} + +static void print_mime_struct(GMimeObject *part, int depth) +{ + const GMimeContentType *type; + GMimeMultipart *multipart; + GMimeObject *subpart; + int i, n; + + print_depth(depth); + type = g_mime_object_get_content_type(part); + testapp_print("Content-Type: %s/%s\n", type->type, type->subtype); + + if (GMIME_IS_MULTIPART(part)) { + multipart = (GMimeMultipart *)part; + + n = g_mime_multipart_get_count(multipart); + for (i = 0; i < n; i++) { + subpart = g_mime_multipart_get_part(multipart, i); + print_mime_struct(subpart, depth + 1); + g_object_unref(subpart); + } + } +} + +static void +test_eml_parsing_foreach_callback(GMimeObject *parent, GMimeObject *part, gpointer user_data) +{ + int *cnt= user_data; + + (*cnt)++; + + if (GMIME_IS_PART(part)) { + testapp_print ("Part\n"); + GMimePart *leaf_part = NULL; + leaf_part = (GMimePart *)part; + + testapp_print("Content ID:%s\n", g_mime_part_get_content_id(leaf_part)); + testapp_print("Description:%s\n", g_mime_part_get_content_description(leaf_part)); + testapp_print("MD5:%s\n", g_mime_part_get_content_md5(leaf_part)); + testapp_print("Location:%s\n", g_mime_part_get_content_location(leaf_part)); + + GMimeContentEncoding enc = g_mime_part_get_content_encoding(leaf_part); + switch(enc) { + case GMIME_CONTENT_ENCODING_DEFAULT: + testapp_print("Encoding:ENCODING_DEFAULT\n"); + break; + case GMIME_CONTENT_ENCODING_7BIT: + testapp_print("Encoding:ENCODING_7BIT\n"); + break; + case GMIME_CONTENT_ENCODING_8BIT: + testapp_print("Encoding:ENCODING_8BIT\n"); + break; + case GMIME_CONTENT_ENCODING_BINARY: + testapp_print("Encoding:ENCODING_BINARY\n"); + break; + case GMIME_CONTENT_ENCODING_BASE64: + testapp_print("Encoding:ENCODING_BASE64\n"); + break; + case GMIME_CONTENT_ENCODING_QUOTEDPRINTABLE: + testapp_print("Encoding:ENCODING_QUOTEDPRINTABLE\n"); + break; + case GMIME_CONTENT_ENCODING_UUENCODE: + testapp_print("Encoding:ENCODING_UUENCODE\n"); + break; + + default: + break; + } + + testapp_print("File name:%s\n\n\n", g_mime_part_get_filename(leaf_part)); + GMimeDataWrapper *data = g_mime_part_get_content_object(leaf_part); + + if (data) { + char tmp_path[50] = {0,}; + snprintf(tmp_path, sizeof(tmp_path), "/tmp/gmime_content%d", *cnt); + + int fd; + if ((fd = open(tmp_path, O_RDWR|O_CREAT, 0)) == -1) { + testapp_print ("open fail\n"); + } + GMimeStream *out_stream; + out_stream = g_mime_stream_fs_new(fd); + g_mime_data_wrapper_write_to_stream(data, out_stream); + g_object_unref(out_stream); + } + } +} + +static gboolean testapp_test_gmime_eml_parsing(void) +{ + GMimeMessage *message; + GMimeParser *parser; + GMimeStream *stream; + int fd; + int count = 0; + + if ((fd = open(TEST_EML_PATH, O_RDONLY, 0)) == -1) { + testapp_print ("open fail\n"); + return 0; + } + + /* init the gmime library */ + g_mime_init(0); + + /* create a stream to read from the file descriptor */ + stream = g_mime_stream_fs_new(fd); + + /* create a new parser object to parse the stream */ + parser = g_mime_parser_new_with_stream(stream); + + /* unref the stream (parser owns a ref, so this object does not actually get free'd until we destroy the parser) */ + g_object_unref(stream); + + /* parse the message from the stream */ + message = g_mime_parser_construct_message(parser); + + /* free the parser (and the stream) */ + g_object_unref(parser); + + testapp_print("Sender:%s\n", g_mime_message_get_sender(message)); + testapp_print("Reply To:%s\n", g_mime_message_get_reply_to(message)); + testapp_print("Subject:%s\n", g_mime_message_get_subject(message)); + testapp_print("Date:%s\n", g_mime_message_get_date_as_string(message)); + testapp_print("Message ID:%s\n", g_mime_message_get_message_id(message)); + + GMimeObject *po = (GMimeObject *)message; + testapp_print("Header String:%s\n\n\n\n", g_mime_header_list_to_string(po->headers)); + + g_mime_message_foreach(message, test_eml_parsing_foreach_callback, &count); +} + +static gboolean testapp_test_interpret_command (int menu_number) +{ + gboolean go_to_loop = TRUE; + + switch (menu_number) { + case 1: + testapp_test_gmime_eml_parsing(); + break; + + case 0: + go_to_loop = FALSE; + break; + default: + break; + } + + return go_to_loop; +} + +void testapp_gmime_main() +{ + gboolean go_to_loop = TRUE; + int menu_number = 0; + int result_from_scanf = 0; + + while (go_to_loop) { + testapp_show_menu (EMAIL_GMIME_MENU); + testapp_show_prompt (EMAIL_GMIME_MENU); + + result_from_scanf = scanf ("%d", &menu_number); + + go_to_loop = testapp_test_interpret_command (menu_number); + } +} -- 2.7.4