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.
24 /******************************************************************************
26 * Desc: email-daemon Etc Implementations
31 * 2006.08.16 : created
32 *****************************************************************************/
37 #include <vconf-keys.h>
40 #include <glib-object.h>
41 #include <sys/smack.h>
42 #include <notification.h>
43 #include <notification_type.h>
45 #include "email-daemon.h"
46 #include "email-daemon-account.h"
47 #include "email-debug-log.h"
48 #include "email-internal-types.h"
49 #include "email-core-account.h"
50 #include "email-core-event.h"
51 #include "email-core-utils.h"
52 #include "email-core-alarm.h"
53 #include "email-core-smtp.h"
54 #include "email-utilities.h"
55 #include "email-storage.h"
56 #include "email-ipc.h"
57 #include "email-dbus-activation.h"
59 extern pthread_mutex_t sound_mutex;
60 extern pthread_cond_t sound_condition;
62 int emdaemon_register_event_callback(email_action_t action, email_event_callback callback, void* event_data)
64 return emcore_register_event_callback(action, callback, event_data);
67 int emdaemon_unregister_event_callback(email_action_t action, email_event_callback callback)
69 return emcore_unregister_event_callback(action, callback);
72 INTERNAL_FUNC int emdaemon_cancel_job(int account_id, int handle, int* err_code)
74 EM_DEBUG_FUNC_BEGIN("account_id[%d], handle[%d], err_code[%p]", account_id, handle, err_code);
77 int err = EMAIL_ERROR_NONE;
80 if (!emcore_cancel_thread(handle, NULL, &err)) {
81 EM_DEBUG_EXCEPTION("emcore_cancel_thread failed [%d]", err);
95 INTERNAL_FUNC int emdaemon_cancel_sending_mail_job(int account_id, int mail_id, int* err_code)
97 EM_DEBUG_FUNC_BEGIN("account_id[%d], mail_id[%d], err_code[%p]", account_id, mail_id, err_code);
100 int err = EMAIL_ERROR_NONE;
103 if (account_id <= 0) {
104 EM_DEBUG_EXCEPTION("account_id[%d], mail_id[%d]", account_id, mail_id);
105 err = EMAIL_ERROR_INVALID_PARAM;
109 #ifdef __FEATURE_PROGRESS_IN_OUTBOX__
111 /* Removed below code, as it is causing struck in composer */
113 /* h.gahlaut@samsung.com: Moved this code from email_cancel_sending_mail API to email-service engine
114 since this code has update DB operation which is failing in context of email application process
115 with an sqlite error -> sqlite3_step fail:8 */
117 /* which means #define SQLITE_READONLY 8 */ /* Attempt to write a readonly database */
118 emstorage_mail_tbl_t *mail_tbl_data = NULL;
120 if (!emstorage_get_mail_by_id(mail_id, &mail_tbl_data, false, &err)) {
121 EM_DEBUG_EXCEPTION("emcore_get_mail failed [%d]", err);
126 if (mail_tbl_data->save_status == EMAIL_MAIL_STATUS_SEND_CANCELED) {
127 EM_DEBUG_EXCEPTION(">>>> EMAIL_MAIL_STATUS_SEND_CANCELED Already set for Mail ID [ %d ]", mail_id);
131 mail_tbl_data->save_status = EMAIL_MAIL_STATUS_SEND_CANCELED;
133 if(!emstorage_set_field_of_mails_with_integer_value(multi_user_name, mail_tbl_data->account_id, &mail_id, 1, "save_status", EMAIL_MAIL_STATUS_SEND_CANCELED, true, &err)) {
134 EM_DEBUG_EXCEPTION("emstorage_set_field_of_mails_with_integer_value failed [%d]",err);
143 if ((err = emcore_delete_alram_data_by_reference_id(EMAIL_ALARM_CLASS_SCHEDULED_SENDING, mail_id)) != EMAIL_ERROR_NONE) {
144 EM_DEBUG_LOG("emcore_delete_alram_data_by_reference_id failed [%d]",err);
149 if(!emcore_get_handle_by_mailId_from_transaction_info(mail_id , &handle)) {
150 EM_DEBUG_EXCEPTION("emcore_get_handle_by_mailId_from_transaction_info failed for mail_id[%d]", mail_id);
155 if (!emcore_cancel_send_mail_thread(handle, NULL, &err)) {
156 EM_DEBUG_EXCEPTION("emcore_cancel_send_mail_thread failed [%d]", err);
159 if(!emcore_delete_transaction_info_by_mailId(mail_id))
160 EM_DEBUG_EXCEPTION("emcore_delete_transaction_info_by_mailId failed for mail_id[%d]", mail_id);
168 #ifdef __FEATURE_PROGRESS_IN_OUTBOX__
169 if(!emstorage_free_mail(&mail_tbl_data, 1, &err))
170 EM_DEBUG_EXCEPTION("emcore_free_mail Failed [%d ]", err);
177 INTERNAL_FUNC int emdaemon_search_mail_on_server(char *multi_user_name,
178 int input_account_id,
179 int input_mailbox_id,
180 email_search_filter_t *input_search_filter,
181 int input_search_filter_count,
182 unsigned int *output_handle,
185 EM_DEBUG_FUNC_BEGIN("input_account_id [%d], mailbox_id [%d], input_search_filter [%p], "
186 "input_search_filter_count [%d], output_handle [%p]",
187 input_account_id, input_mailbox_id, input_search_filter,
188 input_search_filter_count, output_handle);
189 int error = EMAIL_ERROR_NONE;
191 email_event_t *event_data = NULL;
193 if (input_mailbox_id == 0 || input_account_id < 0) {
194 EM_DEBUG_EXCEPTION("Invalid parameter");
195 error = EMAIL_ERROR_INVALID_PARAM;
199 event_data = em_malloc(sizeof(email_event_t));
200 if (event_data == NULL) {
201 EM_DEBUG_EXCEPTION("Out of memory");
202 error = EMAIL_ERROR_OUT_OF_MEMORY;
206 event_data->type = EMAIL_EVENT_SEARCH_ON_SERVER;
207 event_data->account_id = input_account_id;
208 event_data->event_param_data_1 = (void *)input_search_filter;
209 event_data->event_param_data_5 = input_search_filter_count;
210 event_data->event_param_data_4 = input_mailbox_id;
211 event_data->multi_user_name = EM_SAFE_STRDUP(multi_user_name);
213 if (!emcore_insert_event(event_data, (int *)output_handle, &error)) {
214 EM_DEBUG_EXCEPTION("emcore_insert_event failed [%d]", error);
215 error = EMAIL_ERROR_NONE;
223 if (ret == false && event_data) {
224 emcore_free_event(event_data);
228 if (err_code != NULL)
231 EM_DEBUG_FUNC_END("error [%d]", error);
236 INTERNAL_FUNC int emdaemon_reschedule_sending_mail()
238 EM_DEBUG_FUNC_BEGIN();
239 int err = EMAIL_ERROR_NONE;
240 char *conditional_clause_string = NULL;
241 email_list_filter_t filter_list[7];
242 email_mail_list_item_t *result_mail_list = NULL;
243 int filter_rule_count = 7;
244 int result_mail_count = 0;
247 memset(filter_list, 0 , sizeof(email_list_filter_t) * filter_rule_count);
249 filter_list[0].list_filter_item_type = EMAIL_LIST_FILTER_ITEM_RULE;
250 filter_list[0].list_filter_item.rule.target_attribute = EMAIL_MAIL_ATTRIBUTE_SCHEDULED_SENDING_TIME;
251 filter_list[0].list_filter_item.rule.rule_type = EMAIL_LIST_FILTER_RULE_NOT_EQUAL;
252 filter_list[0].list_filter_item.rule.key_value.integer_type_value = 0;
254 filter_list[1].list_filter_item_type = EMAIL_LIST_FILTER_ITEM_OPERATOR;
255 filter_list[1].list_filter_item.operator_type = EMAIL_LIST_FILTER_OPERATOR_AND;
257 filter_list[2].list_filter_item_type = EMAIL_LIST_FILTER_ITEM_OPERATOR;
258 filter_list[2].list_filter_item.operator_type = EMAIL_LIST_FILTER_OPERATOR_LEFT_PARENTHESIS;
260 filter_list[3].list_filter_item_type = EMAIL_LIST_FILTER_ITEM_RULE;
261 filter_list[3].list_filter_item.rule.target_attribute = EMAIL_MAIL_ATTRIBUTE_SAVE_STATUS;
262 filter_list[3].list_filter_item.rule.rule_type = EMAIL_LIST_FILTER_RULE_EQUAL;
263 filter_list[3].list_filter_item.rule.key_value.integer_type_value = EMAIL_MAIL_STATUS_SEND_SCHEDULED;
265 filter_list[4].list_filter_item_type = EMAIL_LIST_FILTER_ITEM_OPERATOR;
266 filter_list[4].list_filter_item.operator_type = EMAIL_LIST_FILTER_OPERATOR_OR;
268 filter_list[5].list_filter_item_type = EMAIL_LIST_FILTER_ITEM_RULE;
269 filter_list[5].list_filter_item.rule.target_attribute = EMAIL_MAIL_ATTRIBUTE_SAVE_STATUS;
270 filter_list[5].list_filter_item.rule.rule_type = EMAIL_LIST_FILTER_RULE_EQUAL;
271 filter_list[5].list_filter_item.rule.key_value.integer_type_value = EMAIL_MAIL_STATUS_SEND_DELAYED;
273 filter_list[6].list_filter_item_type = EMAIL_LIST_FILTER_ITEM_OPERATOR;
274 filter_list[6].list_filter_item.operator_type = EMAIL_LIST_FILTER_OPERATOR_RIGHT_PARENTHESIS;
276 /* Get scheduled mail list */
277 if( (err = emstorage_write_conditional_clause_for_getting_mail_list(multi_user_name, filter_list, filter_rule_count, NULL, 0, -1, -1, &conditional_clause_string)) != EMAIL_ERROR_NONE) {
278 EM_DEBUG_EXCEPTION("emstorage_write_conditional_clause_for_getting_mail_list failed[%d]", err);
282 EM_DEBUG_LOG("conditional_clause_string[%s].", conditional_clause_string);
284 if(!emstorage_query_mail_list(NULL, conditional_clause_string, true, &result_mail_list, &result_mail_count, &err) && !result_mail_list) {
285 EM_DEBUG_EXCEPTION("emstorage_query_mail_list [%d]", err);
289 /* Add alarm for scheduled mail */
290 for(i = 0; i < result_mail_count; i++) {
291 if((err = emcore_schedule_sending_mail(multi_user_name, result_mail_list[i].mail_id, result_mail_list[i].scheduled_sending_time)) != EMAIL_ERROR_NONE) {
292 EM_DEBUG_EXCEPTION("emcore_schedule_sending_mail failed [%d]", err);
298 EM_SAFE_FREE (conditional_clause_string); /* detected by valgrind */
299 EM_SAFE_FREE(result_mail_list);
301 EM_DEBUG_FUNC_END("err [%d]", err);
306 INTERNAL_FUNC int emdaemon_clear_all_mail_data(char *multi_user_name, int* err_code)
308 EM_DEBUG_FUNC_BEGIN();
311 int error = EMAIL_ERROR_NONE;
313 if (emdaemon_initialize(multi_user_name, &error)) {
314 if (!emstorage_clear_mail_data(multi_user_name, true, &error))
315 EM_DEBUG_EXCEPTION("emstorage_clear_mail_data failed [%d]", error);
318 EM_DEBUG_EXCEPTION("emdaemon_initialize failed [%d]", error);
324 emcore_display_unread_in_badge(multi_user_name);
328 if (!emstorage_create_table(multi_user_name, EMAIL_CREATE_DB_NORMAL, &error))
329 EM_DEBUG_EXCEPTION("emstorage_create_table failed [%d]", error);
331 emdaemon_finalize(&error);
340 INTERNAL_FUNC int emdaemon_check_smack_rule(int app_sockfd, char *file_path)
342 EM_DEBUG_FUNC_BEGIN_SEC("app_sockfd[%d], file_path[%s]", app_sockfd, file_path);
344 if (app_sockfd < 0 || !file_path) {
345 EM_DEBUG_LOG("Invalid parameter");
349 char *app_label = NULL;
350 char *file_label = NULL;
351 char *real_file_path = NULL;
352 char errno_buf[ERRNO_BUF_SIZE] = {0};
356 static int have_smack = -1;
358 if (-1 == have_smack) {
359 if (NULL == smack_smackfs_path()) {
367 EM_DEBUG_LOG("smack is disabled");
372 /* Smack is enabled */
374 ret = smack_new_label_from_socket(app_sockfd, &app_label);
376 EM_DEBUG_LOG("smack_new_label_from_socket failed");
381 real_file_path = realpath(file_path, NULL);
382 if (!real_file_path) {
383 EM_DEBUG_LOG("realpath failed [%d][%s]", errno, EM_STRERROR(errno_buf));
388 ret = smack_getlabel(real_file_path, &file_label, SMACK_LABEL_ACCESS);
390 EM_DEBUG_LOG("smack_getlabel failed");
395 EM_DEBUG_LOG("APP_LABEL[%s], FILE_LABEL[%s]", app_label, file_label);
397 ret = smack_have_access(app_label, file_label, "r");
409 EM_SAFE_FREE(app_label);
410 EM_SAFE_FREE(file_label);
411 EM_SAFE_FREE(real_file_path);
417 INTERNAL_FUNC int emdaemon_set_smack_label(char *file_path, char *label)
419 EM_DEBUG_FUNC_BEGIN();
423 if ((ret = smack_setlabel(file_path, label, SMACK_LABEL_ACCESS)) < 0) {
424 EM_DEBUG_LOG("smack_setlabel failed");
432 INTERNAL_FUNC int emdaemon_finalize_sync(char *multi_user_name, int account_id, int total_mail_count, int unread_mail_count, int vip_total_mail_count, int vip_unread_mail_count, int input_from_eas, int *error)
434 EM_DEBUG_FUNC_BEGIN("account_id [%d], total_mail_count [%d], unread_mail_count [%d], error [%p]", account_id, total_mail_count, unread_mail_count, error);
435 int err = EMAIL_ERROR_NONE, ret = true, result_sync_status = SYNC_STATUS_FINISHED;
438 if ((err = emcore_update_sync_status_of_account(multi_user_name, account_id, SET_TYPE_MINUS, SYNC_STATUS_SYNCING)) != EMAIL_ERROR_NONE)
439 EM_DEBUG_EXCEPTION("emcore_update_sync_status_of_account failed [%d]", err);
441 if (!emstorage_get_sync_status_of_account(multi_user_name, account_id, &result_sync_status, &err))
442 EM_DEBUG_EXCEPTION("emstorage_get_sync_status_of_account failed [%d]", err);
444 /* Check the topmost of email app */
445 if (input_from_eas) {
446 if (vconf_get_int(VCONF_KEY_TOPMOST_WINDOW, &topmost) != 0) {
447 EM_DEBUG_EXCEPTION("vconf_get_int failed");
451 if (result_sync_status == SYNC_STATUS_SYNCING) {
453 EM_DEBUG_LOG("The email app is topmost");
454 if (!emstorage_update_save_status(multi_user_name, account_id, &err)) {
455 EM_DEBUG_EXCEPTION("emstorage_update_save_status failed : [%d]", err);
458 if ((err = emcore_add_notification(multi_user_name, account_id, 0, unread_mail_count, vip_unread_mail_count, 0, EMAIL_ERROR_NONE, NOTIFICATION_DISPLAY_APP_ALL^NOTIFICATION_DISPLAY_APP_TICKER)) != EMAIL_ERROR_NONE)
459 EM_DEBUG_EXCEPTION("emcore_add_notification failed : [%d]", err);
461 } else*/ if (result_sync_status == SYNC_STATUS_HAVE_NEW_MAILS) {
463 EM_DEBUG_LOG("The email app is topmost");
467 // emcore_set_flash_noti();
469 if ((err = emcore_add_notification(multi_user_name, account_id, 0, unread_mail_count, vip_unread_mail_count, 1, EMAIL_ERROR_NONE, NOTIFICATION_DISPLAY_APP_ALL)) != EMAIL_ERROR_NONE)
470 EM_DEBUG_EXCEPTION("emcore_add_notification failed : [%d]", err);
472 #ifdef __FEATURE_BLOCKING_MODE__
473 emcore_set_blocking_mode_status(false);
474 #endif /* __FEATURE_BLOCKING_MODE__ */
477 if ((err = emcore_update_sync_status_of_account(multi_user_name, account_id, SET_TYPE_MINUS, SYNC_STATUS_HAVE_NEW_MAILS)) != EMAIL_ERROR_NONE)
478 EM_DEBUG_EXCEPTION("emcore_update_sync_status_of_account failed [%d]", err);
482 EM_DEBUG_LOG("sync status : [%d]", result_sync_status);
488 /* --------------------------------------------------------------------------------*/