Coverity issue fixes for email service
[platform/core/messaging/email-service.git] / email-core / email-core-auto-download.c
1 /*
2 *  email-service
3 *
4 * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
5 *
6 * Contact: Minsoo Kim <minnsoo.kim@samsung.com>, Kyuho Jo <kyuho.jo@samsung.com>,
7 * Sunghyun Kwon <sh0701.kwon@samsung.com>
8 *
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
12 *
13 * http://www.apache.org/licenses/LICENSE-2.0
14 *
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
20 *
21 */
22
23
24 #include <stdio.h>
25 #include <glib.h>
26 #include <malloc.h>
27 #include <pthread.h>
28 #include <vconf.h>
29 #include "email-storage.h"
30 #include "email-utilities.h"
31 #include "email-daemon.h"
32 #include "email-network.h"
33 #include "email-core-global.h"
34 #include "email-core-account.h"
35 #include "email-core-event.h"
36 #include "email-core-utils.h"
37 #include "email-core-mailbox.h"
38 #include "email-core-imap-mailbox.h"
39 #include "email-core-mail.h"
40 #include "email-core-mailbox-sync.h"
41 #include "email-core-smtp.h"
42 #include "email-core-utils.h"
43 #include "email-debug-log.h"
44 #include "email-types.h"
45 #include "email-internal-types.h"
46 #include "email-core-auto-download.h"
47
48 /*-----------------------------------------------------------------------------
49  * Auto Download Event Queue
50  *---------------------------------------------------------------------------*/
51 INTERNAL_FUNC thread_t g_auto_download_thread;
52 INTERNAL_FUNC pthread_cond_t  _auto_downalod_available_signal = PTHREAD_COND_INITIALIZER;
53 INTERNAL_FUNC pthread_mutex_t *_auto_download_queue_lock = NULL;
54
55 INTERNAL_FUNC GQueue *g_auto_download_que = NULL;
56 INTERNAL_FUNC int g_auto_download_loop = 1;
57 INTERNAL_FUNC int auto_download_thread_run = 0;
58
59 #define AUTO_DOWNLOAD_QUEUE_MAX 100
60
61 static void* worker_auto_download_queue(void *arg);
62 static gint __auto_download_compare_func(gconstpointer a, gconstpointer b, gpointer user_data);
63
64 INTERNAL_FUNC int emcore_start_auto_download_loop(int *err_code)
65 {
66         EM_DEBUG_FUNC_BEGIN();
67         int thread_error;
68
69         if (err_code != NULL)
70                 *err_code = EMAIL_ERROR_NONE;
71
72         if (g_auto_download_thread) {
73                 EM_DEBUG_EXCEPTION("auto downlaod thread is already running...");
74                 if (err_code != NULL)
75                         *err_code = EMAIL_ERROR_UNKNOWN;
76                 return true;
77         }
78
79         g_auto_download_que = g_queue_new();
80         g_queue_init(g_auto_download_que);
81         g_auto_download_loop = 1;
82
83         /* initialize lock */
84         INITIALIZE_RECURSIVE_CRITICAL_SECTION(_auto_download_queue_lock);
85
86         /* create thread */
87         THREAD_CREATE(g_auto_download_thread, worker_auto_download_queue, NULL, thread_error);
88
89         if (thread_error != 0) {
90                 EM_DEBUG_EXCEPTION("cannot create thread");
91                 g_auto_download_loop = 0;
92                 if (err_code != NULL)
93                         *err_code = EMAIL_ERROR_SYSTEM_FAILURE;
94                 return false;
95         }
96
97         if (err_code != NULL)
98                 *err_code = EMAIL_ERROR_NONE;
99
100         return true;
101 }
102
103
104 INTERNAL_FUNC int emcore_auto_download_loop_continue(void)
105 {
106         return g_auto_download_loop;
107 }
108
109
110 INTERNAL_FUNC int emcore_stop_auto_download_loop(int *err_code)
111 {
112         EM_DEBUG_FUNC_BEGIN();
113
114         if (err_code != NULL)
115                 *err_code = EMAIL_ERROR_NONE;
116
117         if (!g_auto_download_thread) {
118                 if (err_code != NULL)
119                         *err_code = EMAIL_ERROR_UNKNOWN;
120                 return false;
121         }
122
123         /* stop event_data loop */
124         g_auto_download_loop = 0;
125
126         WAKE_CONDITION_VARIABLE(_auto_downalod_available_signal);
127
128         /* wait for thread finished */
129         THREAD_JOIN(g_auto_download_thread);
130
131         g_queue_free(g_auto_download_que);
132
133         g_auto_download_thread = 0;
134
135         DELETE_RECURSIVE_CRITICAL_SECTION(_auto_download_queue_lock);
136         DELETE_CONDITION_VARIABLE(_auto_downalod_available_signal);
137
138         if (err_code != NULL)
139                 *err_code = EMAIL_ERROR_NONE;
140         EM_DEBUG_FUNC_END();
141         return true;
142 }
143
144
145 INTERNAL_FUNC int emcore_insert_auto_download_event(email_event_auto_download *event_data, int *err_code)
146 {
147         EM_DEBUG_FUNC_BEGIN("event_data[%p], err_code[%p]", event_data, err_code);
148
149         if (!event_data) {
150                 EM_DEBUG_EXCEPTION("Invalid Parameter");
151                 if (err_code != NULL)
152                         *err_code = EMAIL_ERROR_INVALID_PARAM;
153                 return false;
154         }
155
156         if (!g_auto_download_thread) {
157                 EM_DEBUG_EXCEPTION("g_auto_download_thread is not ready");
158                 if (err_code != NULL)
159                         *err_code = EMAIL_ERROR_LOAD_ENGINE_FAILURE;
160                 return false;
161         }
162
163         int ret = false;
164         int error = EMAIL_ERROR_NONE;
165         int q_length = 0;
166
167         ENTER_RECURSIVE_CRITICAL_SECTION(_auto_download_queue_lock);
168
169         if (g_auto_download_que)
170                 q_length = g_queue_get_length(g_auto_download_que);
171         EM_DEBUG_LOG("Q Length : [%d]", q_length);
172
173         EM_DEBUG_LOG("event_data->status : [%d]", event_data->status);
174
175         if (q_length > AUTO_DOWNLOAD_QUEUE_MAX) {
176                 EM_DEBUG_EXCEPTION("auto download que is full...");
177                 error = EMAIL_ERROR_EVENT_QUEUE_FULL;
178                 ret = false;
179         } else {
180                 event_data->status = EMAIL_EVENT_STATUS_WAIT;
181                 g_queue_insert_sorted(g_auto_download_que, event_data, __auto_download_compare_func, event_data);
182                 //WAKE_CONDITION_VARIABLE(_auto_downalod_available_signal);
183                 ret = true;
184         }
185
186         LEAVE_RECURSIVE_CRITICAL_SECTION(_auto_download_queue_lock);
187
188         if (err_code) {
189                 EM_DEBUG_LOG("ERR [%d]", error);
190                 *err_code = error;
191         }
192
193         return ret;
194 }
195
196
197 INTERNAL_FUNC int emcore_retrieve_auto_download_event(email_event_auto_download **event_data, int *err_code)
198 {
199         EM_DEBUG_FUNC_BEGIN("event_data[%p], err_code[%p]", event_data, err_code);
200
201         int ret = false;
202         int error = EMAIL_ERROR_NONE;
203         int q_length = 0;
204         //email_event_auto_download *poped = NULL;
205         email_event_auto_download *head_event = NULL;
206
207         if (g_auto_download_que)
208                 q_length = g_queue_get_length(g_auto_download_que);
209         EM_DEBUG_LOG("Q Length : [%d]", q_length);
210
211         if (!q_length) {
212                 error = EMAIL_ERROR_EVENT_QUEUE_EMPTY;
213                 EM_DEBUG_LOG("QUEUE is empty");
214                 goto FINISH_OFF;
215         }
216
217         while (1) {
218                 head_event = (email_event_auto_download *)g_queue_peek_head(g_auto_download_que);
219                 if (!head_event) {
220                         error = EMAIL_ERROR_EVENT_QUEUE_EMPTY;
221                         EM_DEBUG_LOG_DEV("QUEUE is empty");
222                         break;
223                 }
224
225                 /*if (head_event->status != EMAIL_EVENT_STATUS_WAIT) {
226                         EM_DEBUG_LOG("EVENT STATUS [%d]", head_event->status);
227                         poped = g_queue_pop_head(g_auto_download_que);
228                         if (poped) {
229                                 EM_SAFE_FREE(poped);
230                         } else {
231                                 error = EMAIL_ERROR_EVENT_QUEUE_EMPTY;
232                                 EM_DEBUG_LOG("QUEUE is empty");
233                                 break;
234                         }
235                 } else*/
236                 {
237                         head_event->status = EMAIL_EVENT_STATUS_STARTED;
238                         *event_data = head_event;
239                         ret = true;
240                         break;
241                 }
242         }
243
244 FINISH_OFF:
245
246         if (err_code != NULL)
247                 *err_code = error;
248
249         EM_DEBUG_FUNC_END("ret [%d]", ret);
250         return ret;
251 }
252
253
254 INTERNAL_FUNC int emcore_is_auto_download_queue_empty(void)
255 {
256         EM_DEBUG_FUNC_BEGIN();
257
258         int ret = false;
259         int q_length = 0;
260
261         ENTER_RECURSIVE_CRITICAL_SECTION(_auto_download_queue_lock);
262
263         if (g_auto_download_que)
264                 q_length = g_queue_get_length(g_auto_download_que);
265
266         EM_DEBUG_LOG("Q Length : [%d]", q_length);
267
268         if (q_length <= 0) {
269                 EM_DEBUG_LOG("auto downlaod que is empty...");
270                 ret = true;
271         }
272
273         LEAVE_RECURSIVE_CRITICAL_SECTION(_auto_download_queue_lock);
274         EM_DEBUG_FUNC_END("ret [%d]", ret);
275         return ret;
276 }
277
278
279 INTERNAL_FUNC int emcore_is_auto_download_queue_full(void)
280 {
281         EM_DEBUG_FUNC_BEGIN();
282
283         int ret = false;
284         int q_length = 0;
285
286         ENTER_RECURSIVE_CRITICAL_SECTION(_auto_download_queue_lock);
287
288         if (g_auto_download_que)
289                 q_length = g_queue_get_length(g_auto_download_que);
290
291         EM_DEBUG_LOG("Q Length : [%d]", q_length);
292
293         if (q_length > AUTO_DOWNLOAD_QUEUE_MAX) {
294                 EM_DEBUG_LOG("auto downlaod que is full...");
295                 ret = true;
296         }
297
298         LEAVE_RECURSIVE_CRITICAL_SECTION(_auto_download_queue_lock);
299         EM_DEBUG_FUNC_END();
300         return ret;
301 }
302
303
304 INTERNAL_FUNC int emcore_clear_auto_download_queue(void)
305 {
306         EM_DEBUG_FUNC_BEGIN();
307         int ret = false;
308         int i = 0;
309         int q_length = 0;
310         email_event_auto_download *pop_elm = NULL;
311
312         ENTER_RECURSIVE_CRITICAL_SECTION(_auto_download_queue_lock);
313
314         q_length = g_auto_download_que ? g_queue_get_length(g_auto_download_que) : 0;
315
316         for (i = 0; i < q_length; i++) {
317                 pop_elm = (email_event_auto_download *)g_queue_peek_nth(g_auto_download_que, i);
318
319                 if (pop_elm) {
320                         EM_SAFE_FREE(pop_elm);
321                 }
322         }
323
324         g_queue_clear(g_auto_download_que);
325         ret = true;
326
327         LEAVE_RECURSIVE_CRITICAL_SECTION(_auto_download_queue_lock);
328         EM_DEBUG_FUNC_END();
329         return ret;
330 }
331
332
333 static void* worker_auto_download_queue(void *arg)
334 {
335         EM_DEBUG_FUNC_BEGIN();
336         int err = EMAIL_ERROR_NONE;
337
338         int ai = 0;
339         int mi = 0;
340         int di = 0;
341         int account_count = 0;
342         int mailbox_count = 0;
343         int activity_count = 0;
344         int activity_list_count = 0;
345         int *account_list = NULL;
346         int *mailbox_list = NULL;
347         email_event_auto_download *event_data = NULL;
348         email_event_auto_download *started_event = NULL;
349         email_event_auto_download *activity_list = NULL;
350
351
352         if (!emstorage_open(NULL, &err)) {
353                 EM_DEBUG_EXCEPTION("emstorage_open falied [%d]", err);
354                 return false;
355         }
356
357         /* check that event_data loop is continuous */
358         while (emcore_auto_download_loop_continue()) {
359
360                 ENTER_RECURSIVE_CRITICAL_SECTION(_auto_download_queue_lock);
361
362                 if (!emcore_retrieve_auto_download_event(&event_data, &err)) {
363                         /* no event_data pending */
364                         if (err != EMAIL_ERROR_EVENT_QUEUE_EMPTY) {
365                                 LEAVE_RECURSIVE_CRITICAL_SECTION(_auto_download_queue_lock);
366                                 continue;
367                         }
368
369                         activity_count = 0;
370                         if (!emstorage_get_auto_download_activity_count(NULL, &activity_count, false, &err)) {
371                                 EM_DEBUG_LOG("emstorage_get_auto_download_activity_count failed [%d]", err);
372                                 goto CHECK_CONTINUE;
373                         }
374
375                         if (activity_count <= 0) {
376                                 EM_DEBUG_LOG("auto download activity count is 0");
377                                 goto CHECK_CONTINUE;
378                         }
379
380                         account_count = 0;
381                         EM_SAFE_FREE(account_list);
382                         if (!emstorage_get_auto_download_account_list(NULL, &account_list, &account_count, false, &err)) {
383                                 EM_DEBUG_EXCEPTION(" emstorage_get_auto_download_account_list failed.. [%d]", err);
384                                 goto CHECK_CONTINUE;
385                         }
386
387                         if (account_count <= 0 || !account_list) {
388                                 EM_DEBUG_LOG("auto download account count is 0");
389                                 goto CHECK_CONTINUE;
390                         }
391
392                         for (ai = 0; ai < account_count; ai++) {
393
394                                 email_account_t *account_ref = NULL;
395                                 if (!(account_ref = emcore_get_account_reference(NULL, account_list[ai], false))) {
396                                         EM_DEBUG_EXCEPTION("emcore_get_account_reference failed [%d]", account_list[ai]);
397                                         err = EMAIL_ERROR_INVALID_ACCOUNT;
398                                         continue;
399                                 }
400
401                                 if (!(account_ref->wifi_auto_download)) {
402                                         EM_DEBUG_LOG("ACCOUNT[%d] AUTO DOWNLOAD MODE OFF", account_ref->account_id);
403                                         emcore_free_account(account_ref);
404                                         EM_SAFE_FREE(account_ref);
405                                         continue;
406                                 }
407
408                                 emcore_free_account(account_ref);
409                                 EM_SAFE_FREE(account_ref);
410
411                                 mailbox_count = 0;
412                                 EM_SAFE_FREE(mailbox_list);
413                                 if (!emstorage_get_auto_download_mailbox_list(NULL, account_list[ai], &mailbox_list, &mailbox_count, false, &err)) {
414                                         EM_DEBUG_EXCEPTION(" emstorage_get_auto_download_mailbox_list failed.. [%d]", err);
415                                         goto CHECK_CONTINUE;
416                                 }
417
418                                 if (mailbox_count <= 0 || !mailbox_list) {
419                                         EM_DEBUG_LOG("auto download mailbox count is 0");
420                                         goto CHECK_CONTINUE;
421                                 }
422
423                                 for (mi = 0; mi < mailbox_count; mi++) {
424                                         emstorage_mailbox_tbl_t *target_mailbox = NULL;
425
426                                         activity_list_count = 0;
427                                         EM_SAFE_FREE(activity_list);
428
429                                         if ((err = emstorage_get_mailbox_by_id(NULL, mailbox_list[mi], &target_mailbox)) != EMAIL_ERROR_NONE) {
430                                                 EM_DEBUG_EXCEPTION("emstorage_get_mailbox_by_id failed. [%d]", err);
431                                         }
432
433                                         if (target_mailbox) {
434                                                 if (target_mailbox->mailbox_type != EMAIL_MAILBOX_TYPE_INBOX) {
435                                                         EM_DEBUG_LOG("Not INBOX mail, skip to next");
436                                                         emstorage_free_mailbox(&target_mailbox, 1, NULL);
437                                                         continue;
438                                                 }
439                                                 emstorage_free_mailbox(&target_mailbox, 1, NULL);
440                                         }
441
442                                         if (!emstorage_get_auto_download_activity(NULL, account_list[ai], mailbox_list[mi], &activity_list, &activity_list_count, false, &err)) {
443                                                 EM_DEBUG_EXCEPTION(" emstorage_get_auto_download_activity failed.. [%d]", err);
444                                                 goto CHECK_CONTINUE;
445                                         }
446
447                                         if (activity_list_count <= 0 || !activity_list) {
448                                                 EM_DEBUG_LOG("auto download activity count is 0");
449                                                 goto CHECK_CONTINUE;
450                                         }
451
452                                         for (di = 0; di < activity_list_count; di++) {
453                                                 email_event_auto_download *activity = NULL;
454                                                 activity = (email_event_auto_download *)em_malloc(sizeof(email_event_auto_download));
455                                                 if (!activity) {
456                                                         EM_DEBUG_EXCEPTION("Malloc failed");
457                                                         err = EMAIL_ERROR_OUT_OF_MEMORY;
458                                                         goto CHECK_CONTINUE;
459                                                 }
460
461                                                 activity->activity_id = activity_list[di].activity_id;
462                                                 activity->status = EMAIL_EVENT_STATUS_DIRECT;
463                                                 activity->account_id = activity_list[di].account_id;
464                                                 activity->mail_id = activity_list[di].mail_id;
465                                                 activity->server_mail_id = activity_list[di].server_mail_id;
466                                                 activity->mailbox_id = activity_list[di].mailbox_id;
467
468                                                 if (!emcore_insert_auto_download_event(activity, &err)) {
469                                                         EM_DEBUG_EXCEPTION("emcore_insert_auto_download_event is failed [%d]", err);
470                                                         EM_SAFE_FREE(activity);
471                                                         if (err == EMAIL_ERROR_EVENT_QUEUE_FULL) goto CHECK_CONTINUE;
472                                                 }
473                                         }
474                                 }
475                         }
476
477 CHECK_CONTINUE:
478
479                         EM_SAFE_FREE(account_list);
480                         EM_SAFE_FREE(mailbox_list);
481                         EM_SAFE_FREE(activity_list);
482
483                         if (!emcore_is_auto_download_queue_empty()) {
484                                 LEAVE_RECURSIVE_CRITICAL_SECTION(_auto_download_queue_lock);
485                                 continue;
486                         }
487
488                         auto_download_thread_run = 0;
489                         //go to sleep when queue is empty
490                         SLEEP_CONDITION_VARIABLE(_auto_downalod_available_signal, *_auto_download_queue_lock);
491                         EM_DEBUG_LOG("Wake up by _auto_downalod_available_signal");
492                         LEAVE_RECURSIVE_CRITICAL_SECTION(_auto_download_queue_lock);
493                 } else {
494                         LEAVE_RECURSIVE_CRITICAL_SECTION(_auto_download_queue_lock);
495                         EM_DEBUG_LOG_DEV(">>>>>>>>>>>>>>> Got auto download event_data !!! <<<<<<<<<<<<<<<");
496                         int state1 = 0, state2 = 0, state3 = 0, wifi_status = 0;
497                         emstorage_mail_tbl_t *mail = NULL;
498                         emstorage_mailbox_tbl_t *target_mailbox = NULL;
499                         email_account_t *account_ref = NULL;
500                         auto_download_thread_run = 1;
501
502                         if ((err = emnetwork_get_wifi_status(&wifi_status)) != EMAIL_ERROR_NONE) {
503                                 EM_DEBUG_EXCEPTION("emnetwork_get_wifi_status failed [%d]", err);
504                         }
505
506                         EM_DEBUG_LOG("WIFI Status [%d]", wifi_status);
507
508                         if ((state1 = emcore_get_pbd_thd_state()) == true ||
509                                         (state2 = emcore_is_event_queue_empty()) == false ||
510                                         (state3 = emcore_is_send_event_queue_empty()) == false ||
511                                         (wifi_status <= 1)) {
512
513                                 EM_DEBUG_LOG("Auto Download Thread going to SLEEP");
514
515                                 ENTER_RECURSIVE_CRITICAL_SECTION(_auto_download_queue_lock);
516                                 auto_download_thread_run = 0;
517                                 SLEEP_CONDITION_VARIABLE(_auto_downalod_available_signal, *_auto_download_queue_lock);
518                                 EM_DEBUG_LOG("Wake up by _auto_downalod_available_signal");
519                                 LEAVE_RECURSIVE_CRITICAL_SECTION(_auto_download_queue_lock);
520
521                                 auto_download_thread_run = 1;
522                         }
523
524                         if (!(account_ref = emcore_get_account_reference(event_data->multi_user_name, event_data->account_id, false))) {
525                                 EM_DEBUG_EXCEPTION("emcore_get_account_reference failed [%d]", event_data->account_id);
526                                 err = EMAIL_ERROR_INVALID_ACCOUNT;
527                                 goto POP_HEAD;
528                         }
529
530                         if (!(account_ref->wifi_auto_download)) {
531                                 EM_DEBUG_LOG("ACCOUNT[%d] AUTO DOWNLOAD MODE OFF", event_data->account_id);
532                                 goto POP_HEAD;
533                         }
534
535                         if ((err = emstorage_get_mailbox_by_id(event_data->multi_user_name, event_data->mailbox_id, &target_mailbox)) != EMAIL_ERROR_NONE) {
536                                 EM_DEBUG_EXCEPTION("emstorage_get_mailbox_by_id failed. [%d]", err);
537                         }
538
539                         if (target_mailbox) {
540                                 if (target_mailbox->mailbox_type != EMAIL_MAILBOX_TYPE_INBOX) {
541                                         EM_DEBUG_LOG("Not INBOX mail, skip to next");
542                                         emstorage_free_mailbox(&target_mailbox, 1, NULL);
543                                         goto DELETE_ACTIVITY;
544                                 }
545
546                                 emstorage_free_mailbox(&target_mailbox, 1, NULL);
547                         }
548
549                         /* Handling storage full */
550                         if ((err = emcore_is_storage_full()) == EMAIL_ERROR_MAIL_MEMORY_FULL) {
551                                 EM_DEBUG_EXCEPTION("Storage is full");
552                                 ENTER_RECURSIVE_CRITICAL_SECTION(_auto_download_queue_lock);
553                                 auto_download_thread_run = 0;
554                                 SLEEP_CONDITION_VARIABLE(_auto_downalod_available_signal, *_auto_download_queue_lock);
555                                 EM_DEBUG_LOG("Wake up by _auto_downalod_available_signal");
556                                 LEAVE_RECURSIVE_CRITICAL_SECTION(_auto_download_queue_lock);
557
558                                 if (account_ref) {
559                                         emcore_free_account(account_ref);
560                                         EM_SAFE_FREE(account_ref);
561                                 }
562
563                                 continue;
564                         }
565
566                         // POP3's UID is string, not integer type. So event_data->server_mail_id is invalid in this time.
567                         // emstorage_get_mail_data_by_servermailid() is always fail if it is POP3 event.
568                         if (!emstorage_get_mail_by_id(event_data->multi_user_name,
569                                                                                 event_data->mail_id,
570                                                                                 &mail,
571                                                                                 true,
572                                                                                 &err) || !mail) {
573                                 EM_DEBUG_EXCEPTION("emstorage_get_mail_by_id failed : [%d]", err);
574                         }
575                         else {
576                                 if (mail->body_download_status & EMAIL_BODY_DOWNLOAD_STATUS_FULLY_DOWNLOADED) {
577                                         EM_DEBUG_LOG("fully downloaded mail");
578                                 }
579                                 else {
580                                         EM_DEBUG_LOG("partially downloaded mail");
581                                         if (account_ref->incoming_server_type == EMAIL_SERVER_TYPE_POP3) {
582                                                 EM_DEBUG_LOG("#####AUTO DOWNLOAD BODY: ACCOUNT_ID[%d] MAILBOX_ID[%d] MAIL_ID[%d] UID[%lu] ACTIVITY[%d]#####",
583                                                                 event_data->account_id, event_data->mailbox_id,
584                                                                 event_data->mail_id, event_data->server_mail_id, event_data->activity_id);
585                                                 if (!emcore_gmime_download_body_sections(event_data->multi_user_name,
586                                                                         NULL,
587                                                                         event_data->account_id,
588                                                                         event_data->mail_id,
589                                                                         0,
590                                                                         NO_LIMITATION,
591                                                                         -1,
592                                                                         0,
593                                                                         1,
594                                                                         &err))
595                                                         EM_DEBUG_EXCEPTION("emcore_gmime_download_body_sections failed - %d", err);
596                                         }
597                                 }
598
599                                 if (mail->attachment_count > 0) {
600                                         int i = 0;
601                                         int j = 0;
602                                         int attachment_count = 0;
603                                         emstorage_attachment_tbl_t *attachment_list = NULL;
604
605                                         if ((err = emstorage_get_attachment_list(event_data->multi_user_name,
606                                                                                                                                 event_data->mail_id,
607                                                                                                                                 true,
608                                                                                                                                 &attachment_list,
609                                                                                                                                 &attachment_count)) != EMAIL_ERROR_NONE) {
610                                                 EM_DEBUG_EXCEPTION("emstorage_get_attachment_list failed [%d]", err);
611                                         } else {
612                                                 for (i = 0; i < attachment_count; i++) {
613                                                         if (attachment_list[i].attachment_inline_content_status)
614                                                                 continue;
615
616                                                         j++;
617
618                                                         if (attachment_list[i].attachment_save_status)
619                                                                 continue;
620
621                                                         EM_DEBUG_LOG("#####AUTO DOWNLOAD ATTACHMENT[%d]: ACCOUNT_ID[%d] "
622                                                                                 "MAILBOX_ID[%d] MAIL_ID[%d] UID[%lu] ACTIVITY[%d]#####",
623                                                                                 j, event_data->account_id, event_data->mailbox_id,
624                                                                                 event_data->mail_id, event_data->server_mail_id, event_data->activity_id);
625
626                                                         if (!emcore_gmime_download_attachment(event_data->multi_user_name,
627                                                                                                                                         event_data->mail_id,
628                                                                                                                                         j,
629                                                                                                                                         0,
630                                                                                                                                         -1,
631                                                                                                                                         1,
632                                                                                                                                         &err)) {
633                                                                 EM_DEBUG_EXCEPTION("emcore_gmime_download_attachment failed [%d]", err);
634                                                                 EM_DEBUG_LOG("Retry again");
635                                                                 if (!emcore_gmime_download_attachment(event_data->multi_user_name,
636                                                                                                                                                 event_data->mail_id,
637                                                                                                                                                 j,
638                                                                                                                                                 0,
639                                                                                                                                                 -1,
640                                                                                                                                                 1,
641                                                                                                                                                 &err))
642                                                                         EM_DEBUG_EXCEPTION("emcore_gmime_download_attachment failed [%d]", err);
643                                                         }
644                                                 }
645
646                                                 if (attachment_list)
647                                                         emstorage_free_attachment(&attachment_list, attachment_count, NULL);
648                                         }
649                                 }
650
651                                 if (mail)
652                                         emstorage_free_mail(&mail, 1, NULL);
653                         }
654
655 DELETE_ACTIVITY:
656                         if (!emcore_delete_auto_download_activity(event_data->multi_user_name,
657                                                                                                                 event_data->account_id,
658                                                                                                                 event_data->mail_id,
659                                                                                                                 event_data->activity_id,
660                                                                                                                 &err)) {
661                                 EM_DEBUG_EXCEPTION("emcore_delete_auto_download_activity failed [%d]", err);
662                         }
663
664
665 POP_HEAD:
666                         /* free event itself */
667                         ENTER_RECURSIVE_CRITICAL_SECTION(_auto_download_queue_lock);
668                         started_event = g_queue_pop_head(g_auto_download_que);
669                         LEAVE_RECURSIVE_CRITICAL_SECTION(_auto_download_queue_lock);
670                         if (!started_event) {
671                                 EM_DEBUG_EXCEPTION("Failed to g_queue_pop_head");
672                         } else {
673                                 EM_SAFE_FREE(started_event->multi_user_name);
674                                 EM_SAFE_FREE(started_event);
675                         }
676
677                         if (account_ref) {
678                                 emcore_free_account(account_ref);
679                                 EM_SAFE_FREE(account_ref);
680                         }
681                 }
682         }
683
684         if (!emstorage_close(&err))
685                 EM_DEBUG_EXCEPTION("emstorage_close falied [%d]", err);
686
687         emcore_close_recv_stream_list();
688
689         EM_DEBUG_FUNC_END();
690         return SUCCESS;
691 }
692
693
694 INTERNAL_FUNC int emcore_insert_auto_download_job(char *multi_user_name,
695                                                                                                         int account_id,
696                                                                                                         int mailbox_id,
697                                                                                                         int mail_id,
698                                                                                                         int auto_download_on,
699                                                                                                         char *uid,
700                                                                                                         int *err_code)
701 {
702         EM_DEBUG_FUNC_BEGIN("account_id [%d], maibox_id[%d], mail_id[%d], uid[%p]", account_id, mailbox_id, mail_id, uid);
703
704         int ret = false;
705         int err = EMAIL_ERROR_NONE;
706         int event_pushed = 0;
707         email_event_auto_download *ad_event = NULL;
708
709         if (account_id < FIRST_ACCOUNT_ID || mailbox_id <= 0 || mail_id < 0 || !uid) {
710                 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
711                 err = EMAIL_ERROR_INVALID_PARAM;
712                 goto FINISH_OFF;
713         }
714
715         ad_event = (email_event_auto_download *)em_malloc(sizeof(email_event_auto_download));
716
717         if (!ad_event) {
718                 EM_DEBUG_EXCEPTION("em_mallocfailed...");
719                 err = EMAIL_ERROR_OUT_OF_MEMORY;
720                 goto FINISH_OFF;
721         }
722
723         ad_event->status = 0;
724         ad_event->account_id = account_id;
725         ad_event->mail_id = mail_id;
726         ad_event->server_mail_id = strtoul(uid, NULL, 0);
727         ad_event->mailbox_id = mailbox_id;
728         ad_event->multi_user_name = EM_SAFE_STRDUP(multi_user_name);
729
730         if (!emcore_insert_auto_download_activity(ad_event, &(ad_event->activity_id), &err)) {
731                 EM_DEBUG_EXCEPTION("Inserting auto download activity failed with error[%d]", err);
732                 goto FINISH_OFF;
733         } else {
734                 ret = true;
735
736                 if (!auto_download_on) {
737                         goto FINISH_OFF;
738                 }
739
740                 if (emcore_is_auto_download_queue_full()) {
741                         EM_DEBUG_LOG("Activity inserted only in DB .. Queue is Full");
742                 } else {
743                         ad_event->status = EMAIL_EVENT_STATUS_DIRECT;
744
745                         if (!emcore_insert_auto_download_event(ad_event, &err)) {
746                                 EM_DEBUG_EXCEPTION("emcore_insert_auto_download_event is failed [%d]", err);
747                                 goto FINISH_OFF;
748                         }
749                         event_pushed = 1;
750                 }
751         }
752
753 FINISH_OFF:
754
755         if (!event_pushed) {
756                 if (ad_event) {
757                         EM_SAFE_FREE(ad_event->multi_user_name);
758                         free(ad_event);
759                 }
760         }
761
762         EM_DEBUG_FUNC_END();
763         return ret;
764 }
765
766 INTERNAL_FUNC int emcore_insert_auto_download_activity(email_event_auto_download *local_activity, int *activity_id, int *err_code)
767 {
768         EM_DEBUG_FUNC_BEGIN("local_activity[%p], activity_id[%p], err_code[%p]", local_activity, activity_id, err_code);
769
770         if (!local_activity || !activity_id) {
771                 EM_DEBUG_EXCEPTION("local_activity[%p], activity_id[%p] err_code[%p]", local_activity, activity_id, err_code);
772                 if (err_code != NULL)
773                         *err_code = EMAIL_ERROR_INVALID_PARAM;
774                 return false;
775         }
776
777         int ret = false;
778         int err = EMAIL_ERROR_NONE;
779         int before_tr_begin = 0;
780
781         if (!emstorage_begin_transaction(local_activity->multi_user_name, NULL, NULL, &err)) {
782                 EM_DEBUG_EXCEPTION("emstorage_begin_transaction failed [%d]", err);
783                 before_tr_begin = 1;
784                 goto FINISH_OFF;
785         }
786
787         if (!emstorage_add_auto_download_activity(local_activity->multi_user_name, local_activity, activity_id, false, &err)) {
788                 EM_DEBUG_EXCEPTION("emstorage_add_auto_download_activity failed [%d]", err);
789                 goto FINISH_OFF;
790         }
791
792         ret = true;
793
794 FINISH_OFF:
795         if (ret == true) {      /*  COMMIT TRANSACTION; */
796                 if (emstorage_commit_transaction(local_activity->multi_user_name, NULL, NULL, NULL) == false) {
797                         err = EMAIL_ERROR_DB_FAILURE;
798                         ret = false;
799                 }
800         } else {        /*  ROLLBACK TRANSACTION; */
801                 if (!before_tr_begin && emstorage_rollback_transaction(local_activity->multi_user_name, NULL, NULL, NULL) == false)
802                         err = EMAIL_ERROR_DB_FAILURE;
803         }
804
805         if (err_code != NULL)
806                 *err_code = err;
807         EM_DEBUG_FUNC_END();
808         return ret;
809 }
810
811
812 INTERNAL_FUNC int emcore_delete_auto_download_activity(char *multi_user_name, int account_id, int mail_id, int activity_id, int *err_code)
813 {
814         EM_DEBUG_FUNC_BEGIN("account_id[%d], mail_id[%d], err_code[%p]", account_id, mail_id, err_code);
815
816         if (account_id < FIRST_ACCOUNT_ID || mail_id < 0) {
817                 EM_DEBUG_EXCEPTION("account_id[%d], mail_id[%d], err_code[%p]", account_id, mail_id, err_code);
818                 if (err_code != NULL)
819                         *err_code = EMAIL_ERROR_INVALID_PARAM;
820                 return false;
821         }
822
823         int ret = false;
824         int err = EMAIL_ERROR_NONE;
825         int before_tr_begin = 0;
826
827         if (!emstorage_begin_transaction(multi_user_name, NULL, NULL, &err)) {
828                 EM_DEBUG_EXCEPTION("emstorage_begin_transaction failed [%d]", err);
829                 before_tr_begin = 1;
830                 goto FINISH_OFF;
831         }
832
833         if (!emstorage_delete_auto_download_activity(multi_user_name, account_id, mail_id, activity_id, false, &err)) {
834                 EM_DEBUG_EXCEPTION("emstorage_delete_auto_download_activity failed [%d]", err);
835                 goto FINISH_OFF;
836         } else if (err == EMAIL_ERROR_DATA_NOT_FOUND)
837                 err = EMAIL_ERROR_NONE;
838
839         ret = true;
840
841 FINISH_OFF:
842
843         if (ret == true) {      /*  COMMIT TRANSACTION; */
844                 if (emstorage_commit_transaction(multi_user_name, NULL, NULL, NULL) == false) {
845                         err = EMAIL_ERROR_DB_FAILURE;
846                         ret = false;
847                 }
848         } else {        /*  ROLLBACK TRANSACTION; */
849                 if (!before_tr_begin && emstorage_rollback_transaction(multi_user_name, NULL, NULL, NULL) == false)
850                         err = EMAIL_ERROR_DB_FAILURE;
851         }
852
853         if (err_code != NULL)
854                 *err_code = err;
855         EM_DEBUG_FUNC_END();
856         return ret;
857 }
858
859 static gint __auto_download_compare_func(gconstpointer a, gconstpointer b, gpointer user_data)
860 {
861         email_event_auto_download *first = (email_event_auto_download*)a;
862         email_event_auto_download *second = (email_event_auto_download*)b;
863         if (first->account_id == second->account_id) {
864                 if (first->server_mail_id == second->server_mail_id) return 0;
865                 else if (first->server_mail_id > second->server_mail_id) return -1;
866                 else return 1;
867         } else {
868                 if (first->account_id < second->account_id) return -1;
869                 else return 1;
870         }
871         return 1;
872 }