4 * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Kyuho Jo <kyuho.jo@samsung.com>, Sunghyun Kwon <sh0701.kwon@samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
23 /******************************************************************************
24 * File : email-core-mailbox.c
25 * Desc : Local Mailbox Management
29 *****************************************************************************/
34 #include <sys/types.h>
35 #include "email-types.h"
36 #include "email-utilities.h"
37 #include "email-convert.h"
38 #include "email-debug-log.h"
39 #include "email-core-global.h"
40 #include "email-core-utils.h"
41 #include "email-core-mailbox.h"
42 #include "email-core-event.h"
43 #include "email-network.h"
44 #include "email-core-mail.h"
45 #include "email-core-imap-mailbox.h"
46 #include "email-storage.h"
47 #include "email-core-account.h"
49 #ifdef __FEATURE_KEEP_CONNECTION__
50 static void *g_receiving_thd_stream = NULL; /* Stores the recv thd stream for next time reuse */
51 static int prev_acc_id_recv_thd = 0; /* Stores the account id for which recv thd stream is open */
52 extern int recv_thread_run;
54 static void *g_partial_body_thd_stream = NULL; /* Stores the pb thd stream for next time reuse */
55 static int prev_acc_id_pb_thd = 0; /* Stores the account id for which pb thd stream is open */
57 __thread email_connection_info_t *g_connection_info_list = NULL;
59 static pthread_mutex_t _close_stream_lock = PTHREAD_MUTEX_INITIALIZER; /* Mutex to protect closing stream */
60 #endif /* __FEATURE_KEEP_CONNECTION__ */
63 /* Binding IMAP mailbox with its function */
64 static email_mailbox_type_item_t g_mailbox_type[MAX_MAILBOX_TYPE] = {
65 {EMAIL_MAILBOX_TYPE_INBOX, "INBOX" },
67 {EMAIL_MAILBOX_TYPE_INBOX, "Inbox" },
68 {EMAIL_MAILBOX_TYPE_SENTBOX, "Sent Messages"} ,
69 {EMAIL_MAILBOX_TYPE_SPAMBOX, "&wqTTOLpUx3zVaA-"} ,
70 {EMAIL_MAILBOX_TYPE_DRAFT, "Drafts"} ,
71 {EMAIL_MAILBOX_TYPE_TRASH, "Deleted Messages" } ,
73 {EMAIL_MAILBOX_TYPE_SENTBOX, "Sent"} ,
74 {EMAIL_MAILBOX_TYPE_SPAMBOX, "Spam" },
75 {EMAIL_MAILBOX_TYPE_DRAFT, "Drafts"} ,
76 {EMAIL_MAILBOX_TYPE_TRASH, "Trash"},
78 {EMAIL_MAILBOX_TYPE_SPAMBOX, "&wqTTONO4ycDVaA-"},
80 {EMAIL_MAILBOX_TYPE_SENTBOX, "mail/sent-mail"},
81 {EMAIL_MAILBOX_TYPE_SPAMBOX, "mail/spam-mail" },
82 {EMAIL_MAILBOX_TYPE_DRAFT, "mail/saved-drafts"} ,
83 {EMAIL_MAILBOX_TYPE_TRASH, "mail/mail-trash"},
86 #ifdef __FEATURE_KEEP_CONNECTION__
87 email_connection_info_t* emcore_get_connection_info_by_account_id(int account_id)
89 EM_DEBUG_FUNC_BEGIN("account_id [%d]", account_id);
90 email_connection_info_t *connection_info = g_connection_info_list;
92 while(connection_info) {
93 if(connection_info->account_id == account_id)
95 connection_info = connection_info->next;
98 EM_DEBUG_FUNC_END("connection_info [%p]", connection_info);
99 return connection_info;
102 int emcore_append_connection_info(email_connection_info_t *new_connection_info)
104 EM_DEBUG_FUNC_BEGIN("new_connection_info [%p]", new_connection_info);
105 email_connection_info_t *connection_info = g_connection_info_list;
107 if(!new_connection_info) {
108 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
109 return EMAIL_ERROR_INVALID_PARAM;
112 if(emcore_get_connection_info_by_account_id(new_connection_info->account_id)) {
113 EM_DEBUG_EXCEPTION("EMAIL_ERROR_ALREADY_EXISTS");
114 return EMAIL_ERROR_ALREADY_EXISTS;
117 if(connection_info) {
118 while(connection_info) {
119 if(connection_info->next == NULL) {
120 connection_info->next = new_connection_info;
121 new_connection_info->next = NULL;
123 connection_info = connection_info->next;
127 new_connection_info->next = NULL;
128 g_connection_info_list = new_connection_info;
131 EM_DEBUG_FUNC_END("EMAIL_ERROR_NONE");
132 return EMAIL_ERROR_NONE;
135 INTERNAL_FUNC int emcore_remove_connection_info(int account_id)
137 EM_DEBUG_FUNC_BEGIN("account_id [%d]", account_id);
138 email_connection_info_t *connection_info = g_connection_info_list, *prev_connection_info = NULL;
140 while(connection_info) {
141 if(connection_info->account_id == account_id) {
142 if(prev_connection_info) {
143 prev_connection_info->next = connection_info->next;
146 g_connection_info_list = connection_info->next;
148 EM_SAFE_FREE(connection_info);
151 prev_connection_info = connection_info;
152 connection_info = connection_info->next;
155 EM_DEBUG_FUNC_END("");
156 return EMAIL_ERROR_NONE;
159 #endif /* __FEATURE_KEEP_CONNECTION__ */
163 * get local mailbox list
165 INTERNAL_FUNC int emcore_get_mailbox_list(int account_id, email_mailbox_t **mailbox_list, int *p_count, int *err_code)
167 EM_DEBUG_FUNC_BEGIN("account_id[%d], mailbox_list[%p], p_count[%p], err_code[%p]", account_id, mailbox_list, p_count, err_code);
169 if (account_id <= 0 || !mailbox_list || !p_count) {
170 EM_DEBUG_EXCEPTION("PARAM Failed account_id[%d], mailbox_list[%p], p_count[%p]", account_id, mailbox_list, p_count);
171 if (err_code != NULL)
172 *err_code = EMAIL_ERROR_INVALID_PARAM;
177 int error = EMAIL_ERROR_NONE;
178 emstorage_mailbox_tbl_t *local_mailbox_list = NULL;
179 email_account_t *ref_account = NULL;
182 /* get mailbox list from mailbox table */
184 if (!(ref_account = emcore_get_account_reference(account_id))) {
185 EM_DEBUG_EXCEPTION(" emcore_get_account_reference failed - %d", account_id);
186 error = EMAIL_ERROR_INVALID_ACCOUNT;
190 if (!emstorage_get_mailbox_list(ref_account->account_id, EMAIL_MAILBOX_ALL, EMAIL_MAILBOX_SORT_BY_NAME_ASC, &count, &local_mailbox_list, true, &error)) {
191 EM_DEBUG_EXCEPTION(" emstorage_get_mailbox failed - %d", error);
197 if (!(*mailbox_list = em_malloc(sizeof(email_mailbox_t) * count))) {
198 EM_DEBUG_EXCEPTION(" mailloc failed...");
199 error = EMAIL_ERROR_OUT_OF_MEMORY;
203 memset(*mailbox_list, 0x00, (sizeof(email_mailbox_t) * count));
205 for (i = 0; i < count; i++) {
206 em_convert_mailbox_tbl_to_mailbox(local_mailbox_list + i, (*mailbox_list) + i);
217 if (local_mailbox_list != NULL)
218 emstorage_free_mailbox(&local_mailbox_list, count, NULL);
221 emcore_free_account(ref_account);
222 EM_SAFE_FREE(ref_account);
225 if (err_code != NULL)
233 * get imap sync mailbox list
235 int emcore_get_mailbox_list_to_be_sync(int account_id, email_mailbox_t **mailbox_list, int *p_count, int *err_code)
237 EM_DEBUG_FUNC_BEGIN("account_id[%d], mailbox_list[%p], p_count[%p], err_code[%p]", account_id, mailbox_list, p_count, err_code);
239 if (account_id <= 0 || !mailbox_list || !p_count) {
240 EM_DEBUG_EXCEPTION(" account_id[%d], mailbox_list[%p], p_count[%p]", account_id, mailbox_list, p_count);
241 if (err_code != NULL)
242 *err_code = EMAIL_ERROR_INVALID_PARAM;
247 int error = EMAIL_ERROR_NONE;
248 email_mailbox_t *tmp_mailbox_list = NULL;
249 emstorage_mailbox_tbl_t *mailbox_tbl_list = NULL;
250 email_account_t *ref_account = NULL;
253 /* get mailbox list from mailbox table */
254 if (!(ref_account = emcore_get_account_reference(account_id))) {
255 EM_DEBUG_EXCEPTION("emcore_get_account_reference failed - %d", account_id);
256 error = EMAIL_ERROR_INVALID_ACCOUNT;
260 if (!emstorage_get_mailbox_list(ref_account->account_id, 0, EMAIL_MAILBOX_SORT_BY_TYPE_ASC, &count, &mailbox_tbl_list, true, &error)) {
261 EM_DEBUG_EXCEPTION("emstorage_get_mailbox failed - %d", error);
267 if (!(tmp_mailbox_list = em_malloc(sizeof(email_mailbox_t) * count))) {
268 EM_DEBUG_EXCEPTION("malloc failed...");
269 error = EMAIL_ERROR_OUT_OF_MEMORY;
273 memset(tmp_mailbox_list, 0x00, (sizeof(email_mailbox_t) * count));
275 for (i = 0; i < count; i++) {
276 em_convert_mailbox_tbl_to_mailbox(mailbox_tbl_list + i, tmp_mailbox_list + i);
280 tmp_mailbox_list = NULL;
286 *mailbox_list = tmp_mailbox_list;
289 emcore_free_account(ref_account);
290 EM_SAFE_FREE(ref_account);
293 if (mailbox_tbl_list != NULL)
294 emstorage_free_mailbox(&mailbox_tbl_list, count, NULL);
296 if (err_code != NULL)
298 EM_DEBUG_FUNC_END("error [%d]", error);
302 INTERNAL_FUNC int emcore_get_mail_count(email_mailbox_t *mailbox, int *total, int *unseen, int *err_code)
304 EM_DEBUG_FUNC_BEGIN("mailbox[%p], total[%p], unseen[%p], err_code[%p]", mailbox, total, unseen, err_code);
307 int err = EMAIL_ERROR_NONE;
310 EM_DEBUG_EXCEPTION(" mailbox[%p], total[%p], unseen[%p]", mailbox, total, unseen);
311 err = EMAIL_ERROR_INVALID_PARAM;
315 if (!emstorage_get_mail_count(mailbox->account_id, mailbox->mailbox_id, total, unseen, true, &err)) {
316 EM_DEBUG_EXCEPTION(" emstorage_get_mail_count failed - %d", err);
325 if (err_code != NULL)
331 INTERNAL_FUNC int emcore_create_mailbox(email_mailbox_t *new_mailbox, int on_server, int *err_code)
333 EM_DEBUG_FUNC_BEGIN("new_mailbox[%p], err_code[%p]", new_mailbox, err_code);
335 int err = EMAIL_ERROR_NONE;
336 emstorage_mailbox_tbl_t local_mailbox;
338 if (new_mailbox == NULL || new_mailbox->mailbox_name == NULL) {
339 err = EMAIL_ERROR_INVALID_PARAM;
344 /* Create a mailbox from Sever */
345 if (!emcore_create_imap_mailbox(new_mailbox, &err)) {
346 EM_DEBUG_EXCEPTION(">>>>> mailbox Creation in Server FAILED >>> ");
350 EM_DEBUG_LOG(">>>>> mailbox Creation in Server SUCCESS >>> ");
353 memset(&local_mailbox, 0x00, sizeof(emstorage_mailbox_tbl_t));
354 EM_DEBUG_LOG("box name[%s] local yn[%d] mailbox_type[%d]", new_mailbox->mailbox_name, local_mailbox.local_yn, new_mailbox->mailbox_type);
356 /* add local mailbox into local mailbox table */
357 local_mailbox.mailbox_id = new_mailbox->mailbox_id;
358 local_mailbox.account_id = new_mailbox->account_id;
359 local_mailbox.local_yn = new_mailbox->local;
360 local_mailbox.mailbox_name = new_mailbox->mailbox_name;
361 local_mailbox.alias = new_mailbox->alias;
362 local_mailbox.mailbox_type = new_mailbox->mailbox_type;
363 local_mailbox.unread_count = 0;
364 local_mailbox.total_mail_count_on_local = 0;
365 local_mailbox.total_mail_count_on_server = 0;
366 emcore_get_default_mail_slot_count(local_mailbox.account_id, &local_mailbox.mail_slot_size);
368 if (strncmp(new_mailbox->mailbox_name, EMAIL_INBOX_NAME, EM_SAFE_STRLEN(EMAIL_INBOX_NAME)) == 0 ||
369 strncmp(new_mailbox->mailbox_name, EMAIL_DRAFTBOX_NAME, EM_SAFE_STRLEN(EMAIL_DRAFTBOX_NAME)) == 0 ||
370 strncmp(new_mailbox->mailbox_name, EMAIL_OUTBOX_NAME, EM_SAFE_STRLEN(EMAIL_OUTBOX_NAME)) == 0 ||
371 strncmp(new_mailbox->mailbox_name, EMAIL_SENTBOX_NAME, EM_SAFE_STRLEN(EMAIL_SENTBOX_NAME)) == 0)
372 local_mailbox.modifiable_yn = 0; /* can be deleted/modified */
374 local_mailbox.modifiable_yn = 1;
377 if (!emstorage_add_mailbox(&local_mailbox, true, &err)) {
378 EM_DEBUG_EXCEPTION("emstorage_add_mailbox failed [%d]", err);
382 new_mailbox->mailbox_id = local_mailbox.mailbox_id;
392 INTERNAL_FUNC int emcore_delete_mailbox(int input_mailbox_id, int input_on_server, int input_recursive)
394 EM_DEBUG_FUNC_BEGIN("input_mailbox_id[%d] input_on_server[%d] input_recursive[%d]", input_mailbox_id, input_on_server, input_recursive);
396 int err = EMAIL_ERROR_NONE;
398 int mailbox_count = 0;
399 emstorage_mailbox_tbl_t *target_mailbox = NULL;
400 emstorage_mailbox_tbl_t *target_mailbox_array = NULL;
402 if (input_mailbox_id <= 0) {
403 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
404 err = EMAIL_ERROR_INVALID_PARAM;
408 if ((err = emstorage_get_mailbox_by_id(input_mailbox_id, &target_mailbox)) != EMAIL_ERROR_NONE || !target_mailbox) {
409 EM_DEBUG_EXCEPTION("emstorage_get_mailbox_by_id failed. [%d]", err);
413 #ifdef __FEATURE_DELETE_MAILBOX_RECURSIVELY__
414 if(input_recursive) {
415 /* Getting children mailbox list */
416 if(!emstorage_get_child_mailbox_list(target_mailbox->account_id, target_mailbox->mailbox_name, &mailbox_count, &target_mailbox_array, false,&err)) {
417 EM_DEBUG_EXCEPTION("emstorage_get_child_mailbox_list failed. [%d]", err);
422 emstorage_free_mailbox(&target_mailbox, 1, NULL);
423 target_mailbox = NULL;
426 #endif /* __FEATURE_DELETE_MAILBOX_RECURSIVELY__ */
428 target_mailbox_array = target_mailbox;
430 target_mailbox = NULL;
433 /* Remove mailboxes */
434 for(i = 0; i < mailbox_count ; i++) {
435 EM_DEBUG_LOG("Deleting mailbox_id [%d]", target_mailbox_array[i].mailbox_id);
436 if (input_on_server) {
437 EM_DEBUG_LOG("Delete the mailbox in Sever >>> ");
438 if (!emcore_delete_imap_mailbox(target_mailbox_array[i].mailbox_id, &err))
439 EM_DEBUG_EXCEPTION("Delete the mailbox in server : failed [%d]", err);
441 EM_DEBUG_LOG("Delete the mailbox in server : success");
444 if (!emcore_delete_all_mails_of_mailbox(target_mailbox_array[i].account_id, target_mailbox_array[i].mailbox_id, false, &err)) {
445 EM_DEBUG_EXCEPTION("emcore_delete_all_mails_of_mailbox failed [%d]", err);
449 if (!emstorage_delete_mailbox(target_mailbox_array[i].account_id, -1, target_mailbox_array[i].mailbox_id, true, &err)) {
450 EM_DEBUG_EXCEPTION("emstorage_delete_mailbox failed [%d]", err);
457 emstorage_free_mailbox(&target_mailbox, 1, NULL);
459 if (target_mailbox_array)
460 emstorage_free_mailbox(&target_mailbox_array, mailbox_count, NULL);
462 EM_DEBUG_FUNC_END("err[%d]", err);
467 INTERNAL_FUNC int emcore_delete_mailbox_ex(int input_account_id, int *input_mailbox_id_array, int input_mailbox_id_count, int input_on_server, int input_recursive)
469 EM_DEBUG_FUNC_BEGIN("input_account_id [%d] input_mailbox_id_array[%p] input_mailbox_id_count[%d] input_on_server[%d] input_recursive[%d]", input_mailbox_id_array, input_mailbox_id_array, input_mailbox_id_count, input_on_server, input_recursive);
470 int err = EMAIL_ERROR_NONE;
473 if(input_account_id == 0 || input_mailbox_id_count <= 0 || input_mailbox_id_array == NULL) {
474 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
475 err = EMAIL_ERROR_INVALID_PARAM;
479 if((err = emstorage_set_field_of_mailbox_with_integer_value(input_account_id, input_mailbox_id_array, input_mailbox_id_count, "deleted_flag", 1, true)) != EMAIL_ERROR_NONE) {
480 EM_DEBUG_EXCEPTION("emstorage_set_field_of_mailbox_with_integer_value failed[%d]", err);
484 for(i = 0; i < input_mailbox_id_count; i++) {
485 if((err = emcore_delete_mailbox(input_mailbox_id_array[i] , input_on_server, input_recursive)) != EMAIL_ERROR_NONE) {
486 EM_DEBUG_EXCEPTION("emcore_delete_mailbox failed [%d]", err);
492 EM_DEBUG_FUNC_END("err[%d]", err);
496 INTERNAL_FUNC int emcore_delete_mailbox_all(email_mailbox_t *mailbox, int *err_code)
498 EM_DEBUG_FUNC_BEGIN(" mailbox[%p], err_code[%p]", mailbox, err_code);
501 int err = EMAIL_ERROR_NONE;
503 if (mailbox == NULL) {
504 EM_DEBUG_EXCEPTION(" mailbox[%p]", mailbox);
505 err = EMAIL_ERROR_INVALID_PARAM;
509 if (!emcore_delete_all_mails_of_mailbox(mailbox->account_id, mailbox->mailbox_id, 0, /*NULL, */ &err)) {
510 EM_DEBUG_EXCEPTION(" emcore_delete_all_mails_of_mailbox failed - %d", err);
515 if (!emstorage_delete_mailbox(mailbox->account_id, -1, mailbox->mailbox_id, true, &err)) {
516 EM_DEBUG_EXCEPTION(" emstorage_delete_mailbox failed - %d", err);
525 if (err_code != NULL)
527 EM_DEBUG_FUNC_END("err[%d]", err);
531 INTERNAL_FUNC int emcore_rename_mailbox(int input_mailbox_id, char *input_new_mailbox_name, char *input_new_mailbox_alias, int input_on_server, int input_recursive, int handle_to_be_published)
533 EM_DEBUG_FUNC_BEGIN("input_mailbox_id[%d] input_new_mailbox_name[%p] input_new_mailbox_alias[%p] input_on_server[%d] input_recursive[%d] handle_to_be_published[%d]", input_mailbox_id, input_new_mailbox_name, input_new_mailbox_alias, input_on_server, input_recursive, handle_to_be_published);
535 int err = EMAIL_ERROR_NONE;
537 int mailbox_count = 0;
538 emstorage_mailbox_tbl_t *target_mailbox = NULL;
539 emstorage_mailbox_tbl_t *target_mailbox_array = NULL;
540 char *renamed_mailbox_name = NULL;
541 char *old_mailbox_name = NULL;
543 if (input_mailbox_id == 0 || input_new_mailbox_name == NULL || input_new_mailbox_alias == NULL) {
544 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
545 err = EMAIL_ERROR_INVALID_PARAM;
549 if ((err = emstorage_get_mailbox_by_id(input_mailbox_id, &target_mailbox)) != EMAIL_ERROR_NONE || !target_mailbox) {
550 EM_DEBUG_EXCEPTION("emstorage_get_mailbox_by_id failed. [%d]", err);
554 EM_DEBUG_LOG("target_mailbox->mailbox_name [%s]", target_mailbox->mailbox_name);
555 old_mailbox_name = EM_SAFE_STRDUP(target_mailbox->mailbox_name);
557 if (input_on_server) {
558 EM_DEBUG_LOG("Rename the mailbox in Sever >>> ");
560 if ((err = emcore_rename_mailbox_on_imap_server(target_mailbox->account_id, target_mailbox->mailbox_id, target_mailbox->mailbox_name, input_new_mailbox_name, handle_to_be_published)) != EMAIL_ERROR_NONE) {
561 EM_DEBUG_EXCEPTION("emcore_rename_mailbox_on_imap_server failed [%d]", err);
565 EM_DEBUG_LOG("Rename the mailbox on server : success");
568 #ifdef __FEATURE_RENAME_MAILBOX_RECURSIVELY__
569 if(input_recursive) {
570 /* Getting children mailbox list */
571 if(!emstorage_get_child_mailbox_list(target_mailbox->account_id, target_mailbox->mailbox_name, &mailbox_count, &target_mailbox_array, false,&err)) {
572 EM_DEBUG_EXCEPTION("emstorage_get_child_mailbox_list failed. [%d]", err);
577 emstorage_free_mailbox(&target_mailbox, 1, NULL);
578 target_mailbox = NULL;
581 #endif /* __FEATURE_RENAME_MAILBOX_RECURSIVELY__ */
583 target_mailbox_array = target_mailbox;
585 target_mailbox = NULL;
588 /* Remove mailboxes */
589 for(i = 0; i < mailbox_count ; i++) {
590 EM_DEBUG_LOG("Rename mailbox_id [%d] mailbox_name [%s]", target_mailbox_array[i].mailbox_id, target_mailbox_array[i].mailbox_name);
592 if(input_mailbox_id == target_mailbox_array[i].mailbox_id) {
593 if ((err = emstorage_rename_mailbox(target_mailbox_array[i].mailbox_id, input_new_mailbox_name, input_new_mailbox_alias, true)) != EMAIL_ERROR_NONE) {
594 EM_DEBUG_EXCEPTION("emstorage_rename_mailbox failed [%d]", err);
599 EM_DEBUG_LOG("target_mailbox_array[i].mailbox_name[%s] old_mailbox_name[%s] input_new_mailbox_name [%s]", target_mailbox_array[i].mailbox_name, old_mailbox_name, input_new_mailbox_name);
600 renamed_mailbox_name = em_replace_string(target_mailbox_array[i].mailbox_name, old_mailbox_name, input_new_mailbox_name);
601 EM_DEBUG_LOG("renamed_mailbox_name[%s]", renamed_mailbox_name);
603 if ((err = emstorage_rename_mailbox(target_mailbox_array[i].mailbox_id, renamed_mailbox_name, target_mailbox_array[i].alias, true)) != EMAIL_ERROR_NONE) {
604 EM_DEBUG_EXCEPTION("emstorage_rename_mailbox failed [%d]", err);
608 EM_SAFE_FREE(renamed_mailbox_name);
613 EM_SAFE_FREE(renamed_mailbox_name);
614 EM_SAFE_FREE(old_mailbox_name);
617 emstorage_free_mailbox(&target_mailbox, 1, NULL);
619 if (target_mailbox_array)
620 emstorage_free_mailbox(&target_mailbox_array, mailbox_count, NULL);
626 extern int try_auth_smtp;
628 #ifdef __FEATURE_KEEP_CONNECTION__
629 extern long smtp_send(SENDSTREAM *stream, char *command, char *args);
630 #endif /* __FEATURE_KEEP_CONNECTION__ */
632 INTERNAL_FUNC int emcore_connect_to_remote_mailbox_with_account_info(email_account_t *account, int input_mailbox_id, void **result_stream, int *err_code)
634 EM_PROFILE_BEGIN(emCoreMailboxOpen);
635 EM_DEBUG_FUNC_BEGIN("account[%p], input_mailbox_id[%d], mail_stream[%p], err_code[%p]", account, input_mailbox_id, result_stream, err_code);
638 int error = EMAIL_ERROR_NONE;
639 email_session_t *session = NULL;
640 char *mbox_path = NULL;
641 void *reusable_stream = NULL;
642 int is_connection_for = _SERVICE_THREAD_TYPE_NONE;
643 emstorage_mailbox_tbl_t* mailbox = NULL;
644 char *mailbox_name = NULL;
646 if (account == NULL) {
647 EM_DEBUG_EXCEPTION("Invalid Parameter.");
648 error = EMAIL_ERROR_INVALID_PARAM;
652 if (!emcore_get_current_session(&session)) {
653 EM_DEBUG_EXCEPTION("emcore_get_current_session failed...");
654 error = EMAIL_ERROR_SESSION_NOT_FOUND;
658 if (input_mailbox_id == 0 || input_mailbox_id != EMAIL_CONNECT_FOR_SENDING)
659 is_connection_for = _SERVICE_THREAD_TYPE_RECEIVING;
661 is_connection_for = _SERVICE_THREAD_TYPE_SENDING;
663 #ifdef __FEATURE_KEEP_CONNECTION__
664 email_connection_info_t *connection_info = emcore_get_connection_info_by_account_id(account->account_id);
666 if(connection_info) {
667 if (is_connection_for == _SERVICE_THREAD_TYPE_RECEIVING) {
668 if(connection_info->receiving_server_stream_status == EMAIL_STREAM_STATUS_CONNECTED)
669 reusable_stream = connection_info->receiving_server_stream;
672 if(connection_info->sending_server_stream_status == EMAIL_STREAM_STATUS_CONNECTED)
673 reusable_stream = connection_info->sending_server_stream;
677 if (reusable_stream != NULL)
678 EM_DEBUG_LOG("Stream reuse desired");
680 reusable_stream = *result_stream;
683 session->error = EMAIL_ERROR_NONE;
684 emcore_set_network_error(EMAIL_ERROR_NONE); /* set current network error as EMAIL_ERROR_NONE before network operation */
686 if (input_mailbox_id == EMAIL_CONNECT_FOR_SENDING) {
687 mailbox_name = EM_SAFE_STRDUP(ENCODED_PATH_SMTP);
689 else if (input_mailbox_id == 0) {
692 if ( (error = emstorage_get_mailbox_by_id(input_mailbox_id, &mailbox)) != EMAIL_ERROR_NONE || !mailbox) {
693 EM_DEBUG_EXCEPTION("emstorage_get_mailbox_by_id failed [%d]", error);
696 mailbox_name = EM_SAFE_STRDUP(mailbox->mailbox_name);
699 if (is_connection_for == _SERVICE_THREAD_TYPE_RECEIVING) {
700 /* open pop3/imap server */
701 MAILSTREAM *mail_stream = NULL;
703 if (!emcore_get_long_encoded_path_with_account_info(account, mailbox_name, '/', &mbox_path, &error)) {
704 EM_DEBUG_EXCEPTION("emcore_get_long_encoded_path failed - %d", error);
705 session->error = error;
709 EM_DEBUG_LOG("open mail connection to mbox_path [%s]", mbox_path);
711 try_auth = 0; /* ref_account->receiving_auth ? 1 : 0 */
712 session->auth = 0; /* ref_account->receiving_auth ? 1 : 0 */
714 if (!(mail_stream = mail_open(reusable_stream, mbox_path, IMAP_2004_LOG))) {
715 EM_DEBUG_EXCEPTION("mail_open failed. session->error[%d], session->network[%d]", session->error, session->network);
717 if ((session->error == EMAIL_ERROR_UNKNOWN) || (session->error == EMAIL_ERROR_NONE))
718 session->error = EMAIL_ERROR_CONNECTION_FAILURE;
720 error = session->error;
722 #ifdef __FEATURE_KEEP_CONNECTION__
723 /* Since mail_open failed Reset the global stream pointer as it is a dangling pointer now */
724 #endif /* __FEATURE_KEEP_CONNECTION__ */
727 *result_stream = mail_stream;
730 /* open smtp server */
731 SENDSTREAM *send_stream = NULL;
732 char *host_list[2] = {NULL, NULL};
734 #ifdef __FEATURE_KEEP_CONNECTION__
735 if (reusable_stream != NULL) {
737 /* Check whether connection is avaiable */
738 send_stream = reusable_stream;
740 send_ret = smtp_send(send_stream, "RSET", 0);
742 if (send_ret != SMTP_RESPONSE_OK) {
743 EM_DEBUG_EXCEPTION("[SMTP] RSET --> [%s]", send_stream->reply);
750 if (!emcore_get_long_encoded_path_with_account_info(account, mailbox_name, 0, &mbox_path, &error)) {
751 EM_DEBUG_EXCEPTION(" emcore_get_long_encoded_path failed - %d", error);
752 session->error = error;
756 EM_DEBUG_LOG("open SMTP connection to mbox_path [%s]", mbox_path);
758 try_auth_smtp = account->outgoing_server_need_authentication ? 1 : 0;
759 session->auth = account->outgoing_server_need_authentication ? 1 : 0;
761 host_list[0] = mbox_path;
763 if (!(send_stream = smtp_open(host_list, 1))) {
764 EM_DEBUG_EXCEPTION("smtp_open failed... : current outgoing_server_secure_connection[%d] session->error[%d] session->network[%d]",
765 account->outgoing_server_secure_connection, session->error, session->network);
766 if (session->network != EMAIL_ERROR_NONE)
767 session->error = session->network;
768 if ((session->error == EMAIL_ERROR_UNKNOWN) || (session->error == EMAIL_ERROR_NONE))
769 session->error = EMAIL_ERROR_CONNECTION_FAILURE;
771 error = session->error;
775 *result_stream = send_stream;
782 #ifdef __FEATURE_KEEP_CONNECTION__
784 if(!connection_info) {
785 connection_info = em_malloc(sizeof(email_connection_info_t));
786 connection_info->account_id = account->account_id;
788 EM_DEBUG_EXCEPTION("em_malloc for connection_info failed.");
790 emcore_append_connection_info(connection_info);
793 if(connection_info) {
794 /* connection_info->account_id = account->account_id; */
795 if (is_connection_for == _SERVICE_THREAD_TYPE_RECEIVING) {
796 connection_info->receiving_server_stream = *result_stream;
797 connection_info->receiving_server_stream_status = EMAIL_STREAM_STATUS_CONNECTED;
800 connection_info->sending_server_stream = *result_stream;
801 connection_info->sending_server_stream_status = EMAIL_STREAM_STATUS_CONNECTED;
807 EM_SAFE_FREE(mbox_path);
809 EM_SAFE_FREE(mailbox_name);
812 emstorage_free_mailbox(&mailbox, 1, NULL);
815 if (err_code != NULL)
817 EM_PROFILE_END(emCoreMailboxOpen);
818 EM_DEBUG_FUNC_END("ret [%d]", ret);
822 #ifdef __FEATURE_KEEP_CONNECTION__
824 /*h.gahlaut@samsung.com : 20-oct-2010*/
825 /*Precaution : When Reuse Stream feature is enabled then stream should only be closed using emcore_close_mailbox from email-service code.
826 mail_close should not be used directly from anywhere in code.
827 emcore_close_mailbox uses mail_close inside it.
829 mail_close is only used in emcore_connect_to_remote_mailbox and emcore_reset_streams as an exception to above rule*/
831 INTERNAL_FUNC int emcore_connect_to_remote_mailbox(int account_id, char *mailbox, void **mail_stream, int *err_code)
833 EM_DEBUG_FUNC_BEGIN("account_id[%d], mailbox[%p], mail_stream[%p], err_code[%p]", account_id, mailbox, mail_stream, err_code);
836 int error = EMAIL_ERROR_NONE;
837 email_account_t *ref_account = NULL;
839 ref_account = emcore_get_account_reference(account_id);
842 EM_DEBUG_EXCEPTION("emcore_get_account_reference failed - account id[%d]", account_id);
843 error = EMAIL_ERROR_INVALID_ACCOUNT;
847 ret = emcore_connect_to_remote_mailbox_with_account_info(ref_account, mailbox, mail_stream, &error);
852 emcore_free_account(ref_account);
853 EM_SAFE_FREE(ref_account);
858 EM_DEBUG_FUNC_END("ret [%d]", ret);
862 INTERNAL_FUNC void emcore_close_mailbox_receiving_stream()
864 EM_DEBUG_FUNC_BEGIN("recv_thread_run [%d]", recv_thread_run);
865 if (!recv_thread_run) {
866 ENTER_CRITICAL_SECTION(_close_stream_lock);
867 mail_close(g_receiving_thd_stream);
868 g_receiving_thd_stream = NULL;
869 prev_acc_id_recv_thd = 0;
870 LEAVE_CRITICAL_SECTION(_close_stream_lock);
875 INTERNAL_FUNC void emcore_close_mailbox_partial_body_stream()
877 EM_DEBUG_FUNC_BEGIN();
878 if (false == emcore_get_pbd_thd_state()) {
879 EM_DEBUG_LOG("emcore_get_pbd_thd_state returned false");
880 mail_close(g_partial_body_thd_stream);
881 g_partial_body_thd_stream = NULL;
882 prev_acc_id_pb_thd = 0;
887 /* h.gahlaut@samsung.com : 21-10-2010 -
888 emcore_reset_stream() function is used to reset globally stored partial body thread and receiving thread streams
889 on account deletion and pdp deactivation */
891 INTERNAL_FUNC void emcore_reset_streams()
893 EM_DEBUG_FUNC_BEGIN();
895 emcore_close_mailbox_receiving_stream();
896 emcore_close_mailbox_partial_body_stream();
902 #else /* __FEATURE_KEEP_CONNECTION__ */
904 INTERNAL_FUNC int emcore_connect_to_remote_mailbox(int account_id, int input_mailbox_id, void **mail_stream, int *err_code)
906 EM_DEBUG_FUNC_BEGIN("account_id[%d], input_mailbox_id[%d], mail_stream[%p], err_code[%p]", account_id, input_mailbox_id, mail_stream, err_code);
909 int error = EMAIL_ERROR_NONE;
910 email_session_t *session = NULL;
911 email_account_t *ref_account = NULL;
913 ref_account = emcore_get_account_reference(account_id);
916 EM_DEBUG_EXCEPTION("emcore_get_account_reference failed - account id[%d]", account_id);
917 error = EMAIL_ERROR_INVALID_ACCOUNT;
921 if (!emcore_check_thread_status()) {
922 error = EMAIL_ERROR_CANCELLED;
926 if (!emnetwork_check_network_status(&error)) {
927 EM_DEBUG_EXCEPTION("emnetwork_check_network_status failed [%d]", error);
931 if (!emcore_get_empty_session(&session)) {
932 EM_DEBUG_EXCEPTION("emcore_get_empty_session failed...");
933 error = EMAIL_ERROR_SESSION_NOT_FOUND;
937 ret = emcore_connect_to_remote_mailbox_with_account_info(ref_account, input_mailbox_id, mail_stream, &error);
942 emcore_free_account(ref_account);
943 EM_SAFE_FREE(ref_account);
946 emcore_clear_session(session);
953 #endif /* __FEATURE_KEEP_CONNECTION__ */
955 INTERNAL_FUNC int emcore_close_mailbox(int account_id, void *mail_stream)
957 EM_DEBUG_FUNC_BEGIN("account_id[%d], mail_stream[%p]", account_id, mail_stream);
960 EM_DEBUG_EXCEPTION("Invalid parameter");
964 #ifdef __FEATURE_KEEP_CONNECTION__
965 thread_t thread_id = THREAD_SELF();
967 if (thread_id == (thread_t)emcore_get_receiving_thd_id()) {
968 /* Receiving thread - Dont' Free Reuse feature enabled */
970 else if (thread_id == (thread_t)emcore_get_partial_body_thd_id()) {
971 /* Partial Body Download thread - Dont' Free Reuse feature enabled */
974 /* Some other thread so free stream */
975 if (g_receiving_thd_stream != mail_stream && g_partial_body_thd_stream != mail_stream)
976 mail_close((MAILSTREAM *)mail_stream);
979 mail_close((MAILSTREAM *)mail_stream);
980 #endif /* __FEATURE_KEEP_CONNECTION__ */
985 INTERNAL_FUNC void emcore_free_mailbox_list(email_mailbox_t **mailbox_list, int count)
987 EM_DEBUG_FUNC_BEGIN("mailbox_list[%p], count[%d]", mailbox_list, count);
989 if (count <= 0 || !mailbox_list || !*mailbox_list) {
990 EM_DEBUG_EXCEPTION("INVALID_PARAM: mailbox_list[%p], count[%d]", mailbox_list, count);
994 email_mailbox_t *p = *mailbox_list;
997 for (i = 0; i < count; i++)
998 emcore_free_mailbox(p+i);
1001 *mailbox_list = NULL;
1003 EM_DEBUG_FUNC_END();
1007 INTERNAL_FUNC void emcore_free_mailbox(email_mailbox_t *mailbox)
1009 EM_DEBUG_FUNC_BEGIN();
1012 EM_DEBUG_EXCEPTION("INVALID_PARAM");
1016 EM_SAFE_FREE(mailbox->mailbox_name);
1017 EM_SAFE_FREE(mailbox->alias);
1019 EM_DEBUG_FUNC_END();
1023 INTERNAL_FUNC int emcore_free_internal_mailbox(email_internal_mailbox_t **mailbox_list, int count, int *err_code)
1025 EM_DEBUG_FUNC_BEGIN("mailbox_list[%p], count[%d], err_code[%p]", mailbox_list, count, err_code);
1027 /* default variable */
1029 int err = EMAIL_ERROR_NONE;
1032 if (!mailbox_list || !*mailbox_list) {
1033 EM_DEBUG_EXCEPTION(" mailbox_list[%p], count[%d]", mailbox_list, count);
1035 err = EMAIL_ERROR_INVALID_PARAM;
1039 email_internal_mailbox_t *p = *mailbox_list;
1042 /* EM_DEBUG_LOG("before loop"); */
1043 for (i = 0; i < count; i++) {
1044 EM_SAFE_FREE(p[i].mailbox_name);
1045 EM_SAFE_FREE(p[i].alias);
1047 /* EM_DEBUG_LOG("p [%p]", p); */
1049 *mailbox_list = NULL;
1057 EM_DEBUG_FUNC_END();
1061 INTERNAL_FUNC void emcore_bind_mailbox_type(email_internal_mailbox_t *mailbox_list)
1063 EM_DEBUG_FUNC_BEGIN("mailbox_list[%p]", mailbox_list);
1066 int bIsNotUserMailbox = false;
1067 email_mailbox_type_item_t *pMailboxType1 = NULL ;
1069 for (i = 0 ; i < MAX_MAILBOX_TYPE ; i++) {
1070 pMailboxType1 = g_mailbox_type + i;
1071 if (0 == EM_SAFE_STRCMP(pMailboxType1->mailbox_name, mailbox_list->mailbox_name)) { /*prevent 24662*/
1072 mailbox_list->mailbox_type = pMailboxType1->mailbox_type;
1073 EM_DEBUG_LOG("mailbox_list->mailbox_type[%d]", mailbox_list->mailbox_type);
1074 bIsNotUserMailbox = true;
1079 if (false == bIsNotUserMailbox)
1080 mailbox_list->mailbox_type = EMAIL_MAILBOX_TYPE_USER_DEFINED;
1082 EM_DEBUG_FUNC_END();
1085 INTERNAL_FUNC int emcore_send_mail_event(email_mailbox_t *mailbox, int mail_id , int *err_code)
1087 EM_DEBUG_FUNC_BEGIN();
1090 int err = EMAIL_ERROR_NONE;
1092 email_event_t event_data;
1094 if (!mailbox || mailbox->account_id <= 0) {
1095 EM_DEBUG_LOG(" mailbox[%p]", mailbox);
1097 err = EMAIL_ERROR_INVALID_PARAM;
1100 memset(&event_data, 0x00, sizeof(email_event_t));
1102 event_data.type = EMAIL_EVENT_SEND_MAIL;
1103 event_data.account_id = mailbox->account_id;
1104 event_data.event_param_data_4 = mail_id;
1105 event_data.event_param_data_1 = NULL;
1106 event_data.event_param_data_5 = mailbox->mailbox_id;
1108 if (!emcore_insert_event_for_sending_mails(&event_data, &handle, &err)) {
1109 EM_DEBUG_LOG(" emcore_insert_event failed - %d", err);
1112 emcore_add_transaction_info(mail_id , handle , &err);
1122 INTERNAL_FUNC int emcore_partial_body_thd_local_activity_sync(int *is_event_inserted, int *err_code)
1124 EM_DEBUG_FUNC_BEGIN();
1125 int activity_count = 0;
1127 int error = EMAIL_ERROR_NONE;
1129 if (false == emstorage_get_pbd_activity_count(&activity_count, false, &error)) {
1130 EM_DEBUG_LOG("emstorage_get_pbd_activity_count failed [%d]", error);
1134 if (activity_count > 0) {
1136 email_event_partial_body_thd pbd_event;
1138 /* Carefully initialise the event */
1139 memset(&pbd_event, 0x00, sizeof(email_event_partial_body_thd));
1141 pbd_event.event_type = EMAIL_EVENT_LOCAL_ACTIVITY_SYNC_BULK_PBD;
1142 pbd_event.activity_type = EMAIL_EVENT_LOCAL_ACTIVITY_SYNC_BULK_PBD;
1144 if (false == emcore_insert_partial_body_thread_event(&pbd_event, &error)) {
1145 EM_DEBUG_LOG(" emcore_insert_partial_body_thread_event failed [%d]", error);
1149 /*Not checking for NULL here because is_event_inserted is never NULL. */
1150 *is_event_inserted = true;
1155 *is_event_inserted = false;
1162 if (NULL != err_code) {
1169 INTERNAL_FUNC int emcore_get_mailbox_by_type(int account_id, email_mailbox_type_e mailbox_type, email_mailbox_t *result_mailbox, int *err_code)
1171 EM_DEBUG_FUNC_BEGIN("account_id [%d], result_mailbox [%p], err_code [%p]", account_id, result_mailbox, err_code);
1172 int ret = false, err = EMAIL_ERROR_NONE;
1173 emstorage_mailbox_tbl_t *mail_box_tbl_spam = NULL;
1175 if (result_mailbox == NULL) {
1176 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
1177 err = EMAIL_ERROR_INVALID_PARAM;
1181 if (!emstorage_get_mailbox_by_mailbox_type(account_id, mailbox_type, &mail_box_tbl_spam, false, &err)) {
1183 EM_DEBUG_LOG("emstorage_get_mailbox_by_mailbox_type failed - %d", err);
1186 if (mail_box_tbl_spam) {
1187 result_mailbox->mailbox_type = mail_box_tbl_spam->mailbox_type;
1188 result_mailbox->mailbox_name = EM_SAFE_STRDUP(mail_box_tbl_spam->mailbox_name);
1189 result_mailbox->account_id = mail_box_tbl_spam->account_id;
1190 result_mailbox->mail_slot_size = mail_box_tbl_spam->mail_slot_size;
1191 if (!emstorage_free_mailbox(&mail_box_tbl_spam, 1, &err))
1192 EM_DEBUG_EXCEPTION(" emstorage_free_mailbox Failed [%d]", err);
1200 EM_DEBUG_FUNC_END();
1204 #ifdef __FEATURE_LOCAL_ACTIVITY__
1205 INTERNAL_FUNC int emcore_local_activity_sync(int account_id, int *err_code)
1207 EM_DEBUG_FUNC_BEGIN();
1209 EM_DEBUG_LOG(">> account_id [%d], err_code [%p] ", account_id, err_code);
1211 int *activity_id_list = NULL;
1212 int activity_count = 0;
1216 email_event_t event_data;
1219 memset(&event_data, 0x00, sizeof(email_event_t));
1222 EM_IF_NULL_RETURN_VALUE(err_code, false);
1224 if (account_id <= 0) {
1225 EM_DEBUG_EXCEPTION(" Invalid Account ID [%d] ", account_id);
1228 EM_DEBUG_LOG(">>> emdaemon_sync_local_activity 3 ");
1230 if (!emstorage_get_activity_id_list(account_id, &activity_id_list, &activity_count, ACTIVITY_DELETEMAIL, ACTIVITY_COPYMAIL, true, &err)) {
1231 EM_DEBUG_LOG(">>> emdaemon_sync_local_activity 4 ");
1232 EM_DEBUG_EXCEPTION(" emstorage_get_activity_id_list failed [ %d] ", err);
1235 EM_DEBUG_LOG(">>> emdaemon_sync_local_activity 5 ");
1237 if (activity_count > 0) {
1238 event_data.type = EMAIL_EVENT_LOCAL_ACTIVITY;
1239 event_data.account_id = account_id;
1240 if (!emcore_insert_event(&event_data, &handle, &err)) {
1241 EM_DEBUG_LOG(" emcore_insert_event failed - %d", err);
1250 if (activity_id_list)
1251 emstorage_free_activity_id_list(activity_id_list, &err);
1253 if (err_code != NULL)
1260 INTERNAL_FUNC int emcore_save_local_activity_sync(int account_id, int *err_code)
1262 EM_DEBUG_FUNC_BEGIN();
1264 EM_DEBUG_LOG(">> account_id [%d], err_code [%p] ", account_id, err_code);
1266 emstorage_activity_tbl_t *local_activity = NULL;
1267 int *activity_id_list = NULL;
1268 int activity_count = 0;
1272 email_event_t event_data;
1274 memset(&event_data, 0x00, sizeof(email_event_t));
1276 EM_IF_NULL_RETURN_VALUE(err_code, false);
1278 if (account_id <= 0) {
1279 EM_DEBUG_EXCEPTION(" Invalid Account ID [%d] ", account_id);
1282 EM_DEBUG_LOG(">>> emdaemon_sync_local_activity 3 ");
1284 if (!emstorage_get_activity_id_list(account_id, &activity_id_list, &activity_count, ACTIVITY_SAVEMAIL, ACTIVITY_DELETEMAIL_SEND, true, &err)) {
1285 EM_DEBUG_EXCEPTION(" emstorage_get_activity_id_list [ %d] ", err);
1290 if (activity_count > 0) {
1291 event_data.type = EMAIL_EVENT_LOCAL_ACTIVITY;
1292 event_data.account_id = account_id;
1293 if (!emcore_insert_event_for_sending_mails(&event_data, &handle, &err)) {
1294 EM_DEBUG_LOG(" emcore_insert_event failed - %d", err);
1305 emstorage_free_local_activity(&local_activity, activity_count, NULL);
1307 if (activity_id_list)
1308 emstorage_free_activity_id_list(activity_id_list, &err);
1310 if (err_code != NULL)