2.0_alpha release commit
[framework/messaging/email-service.git] / email-core / email-core-account.c
1 /*
2 *  email-service
3 *
4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5 *
6 * Contact: Kyuho Jo <kyuho.jo@samsung.com>, Sunghyun Kwon <sh0701.kwon@samsung.com>
7 *
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
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
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.
19 *
20 */
21
22
23 /******************************************************************************
24  * File :  email-core-account.c
25  * Desc :  Account Management
26  *
27  * Auth :  Kyuho Jo
28  *
29  * History :
30  *    2010.08.25  :  created
31  *****************************************************************************/
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <time.h>
36 #include <sys/types.h>
37 #include <vconf.h>
38
39 #include "email-convert.h"
40 #include "email-types.h"
41 #include "email-daemon.h"
42 #include "email-debug-log.h"
43 #include "email-storage.h"
44 #include "email-network.h"
45 #include "email-utilities.h"
46 #include "email-core-utils.h"
47 #include "email-core-event.h"
48 #include "email-core-global.h"
49 #include "email-core-account.h"
50 #include "email-core-mailbox.h"
51 #include "email-core-imap-mailbox.h"
52
53 char *g_default_mbox_alias[MAILBOX_COUNT] =
54 {
55         EMAIL_INBOX_DISPLAY_NAME,
56         EMAIL_DRAFTBOX_DISPLAY_NAME,
57         EMAIL_OUTBOX_DISPLAY_NAME,
58         EMAIL_SENTBOX_DISPLAY_NAME,
59         EMAIL_TRASH_DISPLAY_NAME,
60         EMAIL_SPAMBOX_DISPLAY_NAME,
61 };
62
63 char *g_default_mbox_name[MAILBOX_COUNT]  =
64 {
65         EMAIL_INBOX_NAME,
66         EMAIL_DRAFTBOX_NAME,
67         EMAIL_OUTBOX_NAME,
68         EMAIL_SENTBOX_NAME,
69         EMAIL_TRASH_DISPLAY_NAME,
70         EMAIL_SPAMBOX_NAME,
71 };
72
73 email_mailbox_type_e g_default_mbox_type[MAILBOX_COUNT] =
74 {
75         EMAIL_MAILBOX_TYPE_INBOX,
76         EMAIL_MAILBOX_TYPE_DRAFT,
77         EMAIL_MAILBOX_TYPE_OUTBOX,
78         EMAIL_MAILBOX_TYPE_SENTBOX,
79         EMAIL_MAILBOX_TYPE_TRASH,
80         EMAIL_MAILBOX_TYPE_SPAMBOX,
81 };
82
83 INTERNAL_FUNC email_account_t* emcore_get_account_reference(int account_id)
84 {
85         EM_DEBUG_FUNC_BEGIN("account_id[%d]", account_id);
86         EM_PROFILE_BEGIN(profile_emcore_get_account_reference);
87         email_account_list_t **p;
88
89         if (account_id == NEW_ACCOUNT_ID)
90                 return emcore_get_new_account_reference();
91
92         if (account_id > 0)  {
93                 p = &g_account_list;
94                 while (*p)  {
95                         if ((*p)->account->account_id == account_id)
96                                 return ((*p)->account);
97                         p = &(*p)->next;
98                 }
99
100                 /*  refresh and check once agai */
101                 if (emcore_refresh_account_reference() == true) {
102                         p = &g_account_list;
103                         while (*p)  {
104                                 if ((*p)->account->account_id == account_id)
105                                         return ((*p)->account);
106
107                                 p = &(*p)->next;
108                         }
109                 }
110         }
111
112         EM_PROFILE_END(profile_emcore_get_account_reference);
113         EM_DEBUG_FUNC_END();
114         return NULL;
115 }
116
117
118 INTERNAL_FUNC int emcore_validate_account_with_account_info(email_account_t *account, int *err_code)
119 {
120         EM_DEBUG_FUNC_BEGIN("account[%p], err_code[%p], incoming_server_address [%s]", account, err_code, account->incoming_server_address);
121
122         int ret = false;
123         int err = EMAIL_ERROR_NONE;
124         email_session_t *session = NULL;
125         SENDSTREAM *stream = NULL;
126         MAILSTREAM *tmp_stream = NULL;
127
128         if (!emcore_check_thread_status())  {
129                 err = EMAIL_ERROR_CANCELLED;
130                 goto FINISH_OFF;
131         }
132
133         if (!emnetwork_check_network_status(&err))  {
134                 EM_DEBUG_EXCEPTION("emnetwork_check_network_status failed [%d]", err);
135                 goto FINISH_OFF;
136         }
137         EM_DEBUG_LOG("Network available");
138
139         if (!emcore_check_thread_status())  {
140                 err = EMAIL_ERROR_CANCELLED;
141                 goto FINISH_OFF;
142         }
143
144         if (!emcore_get_empty_session(&session))  {
145                 EM_DEBUG_EXCEPTION("emcore_get_empty_session failed...");
146                 err = EMAIL_ERROR_SESSION_NOT_FOUND;
147                 goto FINISH_OFF;
148         }
149
150 #ifdef _SMTP_ACCOUNT_VALIDATION_
151         /* validate connection for smt */
152         EM_DEBUG_LOG("Validate connection for SMTP");
153
154         if (!emcore_check_thread_status()) {
155                 err = EMAIL_ERROR_CANCELLED;
156                 goto FINISH_OFF;
157         }
158        if (!emcore_connect_to_remote_mailbox_with_account_info(account, (char *)ENCODED_PATH_SMTP, (void **)&stream, &err) || !stream)  {
159                 EM_DEBUG_EXCEPTION("emcore_connect_to_remote_mailbox failed 1 - %d", err);
160                 if (EMAIL_ERROR_AUTHENTICATE == err || EMAIL_ERROR_LOGIN_FAILURE == err) {      /*  wrong password or etc */
161                         EM_DEBUG_EXCEPTION("emcore_connect_to_remote_mailbox failed  :  Login or Authentication fail 1- %d", err);
162                         goto FINISH_OFF;
163                 }
164
165                 if (account->outgoing_server_secure_connection == 0x01) /*  0x01 == ss */ {
166                         /*  retry with tl */
167                         EM_DEBUG_LOG("Retry with TLS");
168                         account->outgoing_server_secure_connection = 0x02;      /*  0x02 == tl */
169                         if (!emcore_check_thread_status())  {
170                                 err = EMAIL_ERROR_CANCELLED;
171                                 goto FINISH_OFF;
172                         }
173
174                     if (!emcore_connect_to_remote_mailbox_with_account_info(account, (char *)ENCODED_PATH_SMTP, (void **)&stream, &err) || !stream)  {
175                                 EM_DEBUG_EXCEPTION("emcore_connect_to_remote_mailbox failed 2 - %d", err);
176                                 if (EMAIL_ERROR_AUTHENTICATE == err || EMAIL_ERROR_LOGIN_FAILURE == err) {      /*  wrong password or etc */
177                                         EM_DEBUG_EXCEPTION("emcore_connect_to_remote_mailbox failed  :  Login or Authentication fail 2 - %d", err);
178                                 }
179                                 else if (EMAIL_ERROR_CONNECTION_FAILURE != err) {
180                                         err = EMAIL_ERROR_VALIDATE_ACCOUNT;
181                                 }
182                                 account->outgoing_server_secure_connection = 0x01;      /*  restore to the previous value */
183                                 goto FINISH_OFF;
184                     }
185
186                         if (!emcore_check_thread_status())  {
187                                 err = EMAIL_ERROR_CANCELLED;
188                                 goto FINISH_OFF;
189                         }
190
191                         /*  save outgoing_server_secure_connection = 0x02 (tls) to the d */
192                         if (!emstorage_update_account(account_id, (emstorage_account_tbl_t  *)account, true, &err)) {
193                                 EM_DEBUG_EXCEPTION("emstorage_update_account failed - %d", err);
194                                 account->outgoing_server_secure_connection = 0x01;      /*  restore to the previous value */
195                                 err = EMAIL_ERROR_VALIDATE_ACCOUNT;
196                                 goto FINISH_OFF;
197                         }
198                 }
199                 else {
200                         if (EMAIL_ERROR_CONNECTION_FAILURE != err)
201                                 err = EMAIL_ERROR_VALIDATE_ACCOUNT;
202                         goto FINISH_OFF;
203                 }
204         }
205 #endif
206
207         /* validate connection for pop3/ima */
208         EM_DEBUG_LOG("Validate connection for POP3/IMAP4");
209         if (EMAIL_ERROR_NONE == err) {
210                 if (!emcore_check_thread_status())  {
211                         err = EMAIL_ERROR_CANCELLED;
212                         goto FINISH_OFF;
213                 }
214
215                  if (!emcore_connect_to_remote_mailbox_with_account_info(account, 0, (void **)&tmp_stream, &err) || !tmp_stream)
216                  {
217                         EM_DEBUG_EXCEPTION("emcore_connect_to_remote_mailbox failed - %d", err);
218                         if (EMAIL_ERROR_AUTHENTICATE == err || EMAIL_ERROR_LOGIN_FAILURE == err) {      /*  wrong password or etc */
219                                 EM_DEBUG_EXCEPTION("emcore_connect_to_remote_mailbox failed : Login or Authentication failed - %d", err);
220                         }
221                         else if (EMAIL_ERROR_CONNECTION_FAILURE != err) {
222                                 /* err = EMAIL_ERROR_VALIDATE_ACCOUNT */
223                         }
224                         goto FINISH_OFF;
225                 }
226         }
227
228         if (!emcore_check_thread_status())  {
229                 if (!emcore_delete_account(account->account_id, NULL))
230                         EM_DEBUG_EXCEPTION("emdaemon_delete_account failed [%d]", account->account_id);
231                 err = EMAIL_ERROR_CANCELLED;
232                 goto FINISH_OFF;
233         }
234
235         ret = true;
236
237 FINISH_OFF:
238         if (stream)
239                 smtp_close(stream);
240
241         if (tmp_stream)
242                 emcore_close_mailbox(0 , tmp_stream);
243
244         if (err_code != NULL)
245                 *err_code = err;
246
247         emcore_clear_session(session);
248
249         EM_DEBUG_FUNC_END();
250         return ret;
251 }
252
253
254 INTERNAL_FUNC int emcore_validate_account(int account_id, int *err_code)
255 {
256         EM_DEBUG_FUNC_BEGIN("account_id[%d], err_code[%p]", account_id, err_code);
257
258         int err = EMAIL_ERROR_NONE, ret = false;
259         email_account_t *ref_account = NULL;
260
261
262         if (account_id <= 0)
263     {
264                 EM_DEBUG_EXCEPTION("account_id[%p]", account_id);
265                 err = EMAIL_ERROR_INVALID_PARAM;
266                 goto FINISH_OFF;
267         }
268
269         ref_account = emcore_get_account_reference(account_id);
270
271         if (ref_account && emcore_validate_account_with_account_info(ref_account, &err) == false) {
272                 EM_DEBUG_EXCEPTION("emcore_validate_account_with_account_info failed (%d)", err);
273                 goto FINISH_OFF;
274         }
275
276         ret = true;
277
278 FINISH_OFF:
279
280         if (err_code)
281                 *err_code = err;
282
283         EM_DEBUG_FUNC_END();
284
285         return ret;
286 }
287
288 INTERNAL_FUNC int emcore_delete_account(int account_id, int *err_code)
289 {
290         EM_DEBUG_FUNC_BEGIN("account_id[%d], err_code[%p]", account_id, err_code);
291
292         /*  default variabl */
293         int ret = false;
294         int err = EMAIL_ERROR_NONE;
295
296         if (account_id < FIRST_ACCOUNT_ID)  {
297                 EM_DEBUG_EXCEPTION("account_id[%d]", account_id);
298                 err = EMAIL_ERROR_INVALID_PARAM;
299                 goto FINISH_OFF;
300         }
301 #ifdef __FEATURE_LOCAL_ACTIVITY__
302         /* Delete all local activities of previous account */
303         emstorage_activity_tbl_t activity;
304         memset(&activity, 0x00, sizeof(emstorage_activity_tbl_t));
305         activity.account_id = account_id;
306
307         if (!emcore_delete_activity(&activity, &err)) {
308                 EM_DEBUG_LOG("\t emcore_delete_activity failed - %d", err);
309
310                 goto FINISH_OFF;
311         }
312 #endif
313
314 #ifdef __FEATURE_PARTIAL_BODY_DOWNLOAD__
315         if (false == emcore_clear_partial_body_thd_event_que(&err))
316                 EM_DEBUG_EXCEPTION(" emcore_clear_partial_body_thd_event_que [%d]", err);
317
318         if (false == emstorage_delete_full_pbd_activity_data(account_id, true, &err))
319                 EM_DEBUG_EXCEPTION("emstorage_delete_full_pbd_activity_data failed [%d]", err);
320
321 #endif
322
323         if (emcore_cancel_all_threads_of_an_account(account_id) < EMAIL_ERROR_NONE) {
324                 EM_DEBUG_EXCEPTION("There are some remaining jobs. I couldn't stop them.");
325                 err = EMAIL_ERROR_CANNOT_STOP_THREAD;
326                 goto FINISH_OFF;
327         }
328
329         /*  BEGIN TRANSACTION;           */
330         emstorage_begin_transaction(NULL, NULL, NULL);
331         
332         if (!emstorage_delete_account(account_id, false, &err))  {
333                 EM_DEBUG_EXCEPTION("emstorage_delete_account failed [%d]", err);
334                 goto FINISH_OFF;
335         }
336
337 #ifdef __FEATURE_KEEP_CONNECTION__
338         /* emcore_reset_streams(); */
339         emcore_remove_connection_info(account_id);
340 #endif
341         
342         if ((err = emcore_delete_all_mails_of_acount(account_id)) != EMAIL_ERROR_NONE)  {
343                 EM_DEBUG_EXCEPTION("emcore_delete_all_mails_of_acount failed [%d]", err);
344                 goto FINISH_OFF;
345         }
346
347         /*  delete all mailboxe */
348         if (!emstorage_delete_mailbox(account_id, -1, 0, false, &err))  {
349                 EM_DEBUG_EXCEPTION("emstorage_delete_mailbox failed - %d", err);
350                 goto FINISH_OFF;
351         }
352
353         /*  delete local imap sync mailbox from imap mailbox tabl */
354         if (!emstorage_remove_downloaded_mail(account_id, NULL, NULL, false, &err))  {
355                 EM_DEBUG_EXCEPTION("emstorage_remove_downloaded_mail failed - %d", err);
356                 goto FINISH_OFF;
357         }
358
359         emcore_check_unread_mail();
360         emcore_delete_notification_by_account(account_id);
361         emcore_refresh_account_reference();
362
363         ret = true;
364
365 FINISH_OFF:
366         if (ret == true) {      /*  COMMIT TRANSACTION; */
367                 if (emstorage_commit_transaction(NULL, NULL, NULL) == false) {
368                         err = EMAIL_ERROR_DB_FAILURE;
369                         ret = false;
370                 }
371                 if (!emstorage_notify_storage_event(NOTI_ACCOUNT_DELETE, account_id, 0, NULL, 0))
372                         EM_DEBUG_EXCEPTION(" emstorage_notify_storage_event[ NOTI_ACCOUNT_DELETE] : Notification Failed >>> ");
373
374         }
375         else {  /*  ROLLBACK TRANSACTION; */
376                 if (emstorage_rollback_transaction(NULL, NULL, NULL) == false)
377                         err = EMAIL_ERROR_DB_FAILURE;
378                 if (!emstorage_notify_storage_event(NOTI_ACCOUNT_DELETE_FAIL, account_id, err, NULL, 0))
379                         EM_DEBUG_EXCEPTION(" emstorage_notify_storage_event[ NOTI_ACCOUNT_DELETE] : Notification Failed >>> ");
380         }
381
382         if (err_code)
383                 *err_code = err;
384
385         EM_DEBUG_FUNC_END();
386
387         return ret;
388 }
389
390 INTERNAL_FUNC int emcore_create_account(email_account_t *account, int *err_code)
391 {
392         EM_DEBUG_FUNC_BEGIN("account[%p], err_code[%p]", account, err_code);
393
394         int ret = false;
395         int err = EMAIL_ERROR_NONE;
396         int i, count = 0, is_preset_IMAP_account = false;
397         email_mailbox_t local_mailbox = {0};
398         emstorage_account_tbl_t *temp_account_tbl = NULL;
399
400         if (!account)  {
401                 EM_DEBUG_EXCEPTION("account[%p]", account);
402                 err = EMAIL_ERROR_INVALID_PARAM;
403                 goto FINISH_OFF;
404         }
405
406         if (!emstorage_get_account_count(&count, true, &err))  {
407                 EM_DEBUG_EXCEPTION("emstorage_get_account_count failed - %d", err);
408                 goto FINISH_OFF;
409         }
410
411
412         if (count >= EMAIL_ACCOUNT_MAX)  {
413                 EM_DEBUG_EXCEPTION("too many accounts...");
414                 err = EMAIL_ERROR_ACCOUNT_MAX_COUNT;
415                 goto FINISH_OFF;
416         }
417
418         account->account_id = 0;
419
420         /* Temporarily code - begin */
421         if (account->auto_download_size == 0) {
422                 account->auto_download_size = PARTIAL_BODY_SIZE_IN_BYTES;
423                 EM_DEBUG_LOG("account->auto_download_size [%d]", account->auto_download_size);
424         }
425
426         if (account->default_mail_slot_size == 0) {
427                 account->default_mail_slot_size = 50;
428                 EM_DEBUG_LOG("account->default_mail_slot_size [%d]", account->default_mail_slot_size);
429         }
430         /* Temporarily code - end */
431
432         /* check for email address validation */
433         EM_DEBUG_LOG("account->user_email_address[%s]", account->user_email_address);
434         if (account->user_email_address) {
435                 if (!em_verify_email_address(account->user_email_address, true, &err)) {
436                         err = EMAIL_ERROR_INVALID_ADDRESS;
437                         EM_DEBUG_EXCEPTION("Invalid Email Address");
438                         goto FINISH_OFF;
439                 }
440         }
441
442         temp_account_tbl = em_malloc(sizeof(emstorage_account_tbl_t));
443         if (!temp_account_tbl) {
444                 EM_DEBUG_EXCEPTION("allocation failed [%d]", err);
445                 goto FINISH_OFF;
446         }
447         em_convert_account_to_account_tbl(account, temp_account_tbl);
448
449         if (!emstorage_add_account(temp_account_tbl, true, &err))  {
450                 EM_DEBUG_EXCEPTION("emstorage_add_account failed - %d", err);
451                 goto FINISH_OFF;
452         }
453         account->account_id = temp_account_tbl->account_id;
454         is_preset_IMAP_account = ((account->incoming_server_type == EMAIL_SERVER_TYPE_IMAP4)) ? true : false;/*  && (account->is_preset_account)) ? true  :  false */
455
456         EM_DEBUG_LOG("is_preset_IMAP_account  :  %d", is_preset_IMAP_account);
457
458         if ((account->incoming_server_type != EMAIL_SERVER_TYPE_ACTIVE_SYNC)    && (!is_preset_IMAP_account)) {
459                 /* 1. create default local mailbox
460                 *    (Inbox, Draft, Outbox, Sentbox) */
461                 for (i = 0; i < MAILBOX_COUNT; i++) {
462                 EM_DEBUG_LOG("g_default_mbox_name [%d/%d] is [%s]", i, MAILBOX_COUNT, g_default_mbox_name[i]);
463                         local_mailbox.account_id = temp_account_tbl->account_id;
464                         local_mailbox.mailbox_name  = g_default_mbox_name[i];
465                         local_mailbox.mailbox_type      = g_default_mbox_type[i];
466                         if (local_mailbox.mailbox_type == EMAIL_MAILBOX_TYPE_INBOX) {
467                                 local_mailbox.local = EMAIL_MAILBOX_FROM_SERVER;
468                         }
469                         else {
470                                 local_mailbox.local = EMAIL_MAILBOX_FROM_LOCAL;
471                         }
472                         local_mailbox.alias = g_default_mbox_alias[i];
473                         emcore_get_default_mail_slot_count(&local_mailbox.mail_slot_size, NULL);
474
475                         if (!emcore_create_mailbox(&local_mailbox, 0, &err))  {
476                                 EM_DEBUG_EXCEPTION("emcore_create failed - %d", err);
477                                 goto FINISH_OFF;
478                         }
479                         
480                 }
481         }
482         
483         
484         
485         ret = true;
486         
487 FINISH_OFF: 
488         if (temp_account_tbl)
489                 emstorage_free_account(&temp_account_tbl, 1, NULL);
490         
491         if (ret == false && account != NULL)  {
492                 if (!emcore_delete_account(account->account_id, NULL))
493                         EM_DEBUG_EXCEPTION("emdaemon_delete_account Failed [%d]", account->account_id);
494         }
495         
496         if (err_code)
497                 *err_code = err;
498
499         EM_DEBUG_FUNC_END("Return value [%d]", ret);
500         return ret;
501 }
502
503
504 INTERNAL_FUNC int emcore_init_account_reference()
505 {
506         EM_DEBUG_FUNC_BEGIN();
507         
508         int err = EMAIL_ERROR_NONE;
509         
510         email_account_list_t *account_list = NULL;
511         email_account_list_t **p = NULL;
512         email_account_t *account = NULL;
513         emstorage_account_tbl_t *account_tbl_array = NULL;
514         int count = 0;          
515         int i = 0;
516         
517         if (!g_account_retrieved)  {
518                 count = 1000;
519                 if (!emstorage_get_account_list(&count, &account_tbl_array, true, true, &err))  {
520                         EM_DEBUG_EXCEPTION("emstorage_get_account_list failed [%d]", err);
521                         goto FINISH_OFF;
522                 }
523                 
524                 for (p = &account_list, i = 0; i < count; i++)  {
525                         account = em_malloc(sizeof(email_account_t));
526                         if (!account)  {        
527                                 EM_DEBUG_EXCEPTION("malloc failed...");
528                                 err = EMAIL_ERROR_OUT_OF_MEMORY;
529                                 goto FINISH_OFF;
530                         }
531                         
532                         em_convert_account_tbl_to_account(account_tbl_array + i, account);
533
534                         /* memcpy(account, accounts + i, sizeof(email_account_t)) */
535                         /* memset(accounts + i, 0x00, sizeof(email_account_t)) */
536                         
537                         *p = (email_account_list_t*) em_malloc(sizeof(email_account_list_t));
538                         if (!(*p))  {   
539                                 EM_DEBUG_EXCEPTION("malloc failed...");
540                                 err = EMAIL_ERROR_OUT_OF_MEMORY;
541                                 goto FINISH_OFF;
542                         }
543                         
544                         
545                         (*p)->account = account;
546                         
547                         p = &(*p)->next;
548                 }
549                 if (g_account_num)
550                         emcore_free_account_reference();
551                 g_account_retrieved = 1;
552                 g_account_num = count;
553                 g_account_list = account_list;
554         }
555         
556 FINISH_OFF: 
557         if (account_tbl_array)
558                 emstorage_free_account(&account_tbl_array, count, NULL);
559         
560         if (err != EMAIL_ERROR_NONE)  {
561                 g_account_list = account_list;
562                 emcore_free_account_reference();
563         }
564
565         EM_DEBUG_FUNC_END("err [%d]", err);
566         return err;
567 }
568
569 INTERNAL_FUNC int emcore_refresh_account_reference()
570 {
571         EM_DEBUG_FUNC_BEGIN();
572         
573         if (g_account_retrieved && g_account_num)
574                 emcore_free_account_reference();
575         
576         g_account_retrieved = 0;
577         g_account_num = 0;
578         g_account_list = NULL;
579         
580         if (emcore_init_account_reference() != EMAIL_ERROR_NONE)  {
581                 EM_DEBUG_EXCEPTION("emcore_init_account_reference failed...");
582                 return false;
583         }
584         EM_DEBUG_FUNC_END();
585         return true;
586 }
587
588 INTERNAL_FUNC int emcore_free_account_reference()
589 {
590         EM_DEBUG_FUNC_BEGIN();
591         
592         email_account_list_t *p = g_account_list;
593         email_account_list_t *p_next = NULL;
594         while (p)  {
595                 emcore_free_account(p->account);
596                 EM_SAFE_FREE(p->account);
597                 
598                 p_next = p->next;
599                 EM_SAFE_FREE(p);
600                 p = p_next;
601         }
602
603         g_account_retrieved = 0;
604         g_account_num = 0;
605         g_account_list = NULL;
606         EM_DEBUG_FUNC_END();
607         return true;
608 }
609
610 INTERNAL_FUNC int emcore_free_account_list(email_account_t **account_list, int count, int *err_code)
611 {
612         EM_DEBUG_FUNC_BEGIN("account_list[%p], count[%d], err_code[%p]", account_list, count, err_code);
613         
614         int ret = false;
615         int err = EMAIL_ERROR_NONE;
616         
617         if (count <= 0 || !account_list || !*account_list)  {
618                         err = EMAIL_ERROR_INVALID_PARAM;
619                         goto FINISH_OFF;
620         }
621                 
622         email_account_t *p = *account_list;
623         int i;
624         for (i = 0; i < count; i++)
625                 emcore_free_account(p+i);
626                 
627         EM_SAFE_FREE(p);
628         *account_list = NULL;
629         
630         ret = true;
631         
632 FINISH_OFF: 
633         if (err_code)
634                 *err_code = err;
635         EM_DEBUG_FUNC_END();
636         return ret;
637 }
638
639 INTERNAL_FUNC void emcore_free_option(email_option_t *option)
640 {
641         EM_SAFE_FREE(option->display_name_from);
642         EM_SAFE_FREE(option->signature);
643 }
644
645
646 INTERNAL_FUNC void emcore_free_account(email_account_t *account)
647 {
648         if(!account) return;
649
650         EM_SAFE_FREE(account->account_name);
651         EM_SAFE_FREE(account->incoming_server_address);
652         EM_SAFE_FREE(account->user_email_address);
653         EM_SAFE_FREE(account->incoming_server_user_name);
654         EM_SAFE_FREE(account->incoming_server_password);
655         EM_SAFE_FREE(account->outgoing_server_address);
656         EM_SAFE_FREE(account->outgoing_server_user_name);
657         EM_SAFE_FREE(account->outgoing_server_password);
658         EM_SAFE_FREE(account->user_display_name);
659         EM_SAFE_FREE(account->reply_to_address);
660         EM_SAFE_FREE(account->return_address);
661         EM_SAFE_FREE(account->logo_icon_path);
662         EM_SAFE_FREE(account->certificate_path);
663         EM_SAFE_FREE(account->user_data);
664         account->user_data_length = 0;
665         emcore_free_option(&account->options);
666
667
668         EM_DEBUG_FUNC_END();
669 }
670
671
672 INTERNAL_FUNC int emcore_get_account_reference_list(email_account_t **account_list, int *count, int *err_code)
673 {
674         EM_DEBUG_FUNC_BEGIN("account_list[%p], count[%p], err_code[%p]", account_list, count, err_code);
675         int i, countOfAccounts = 0;
676         int ret = false;
677         int err = EMAIL_ERROR_NONE;
678         email_account_t *accountRef;
679         email_account_list_t *p;
680
681         if (!account_list || !count)  {
682                 EM_DEBUG_EXCEPTION("account_list[%p], count[%p]", account_list, count);
683                 err = EMAIL_ERROR_INVALID_PARAM;
684                 goto FINISH_OFF;
685         }
686
687         p = g_account_list;
688
689         while (p) {
690                 countOfAccounts++;
691                 p = p->next;
692         }
693         
694         EM_DEBUG_LOG("Result count[%d]", countOfAccounts);
695         *count = countOfAccounts;
696
697         if (countOfAccounts > 0) {
698                 *account_list = malloc(sizeof(email_account_t) * countOfAccounts);
699                 if (!*account_list)  {          
700                         EM_DEBUG_LOG("malloc failed...");
701                         err = EMAIL_ERROR_OUT_OF_MEMORY;
702                         goto FINISH_OFF;
703                 }
704         }
705
706         p = g_account_list;
707         for (i = 0; i < countOfAccounts; i++)  {
708                 accountRef = (*account_list) + i;
709                 memcpy(accountRef, p->account , sizeof(email_account_t));
710                 p = p->next;
711         }
712
713         for (i = 0; i < countOfAccounts; i++)  {
714                 accountRef = (*account_list) + i;
715                 EM_DEBUG_LOG("Result account id[%d], name[%s]", accountRef->account_id, accountRef->account_name);
716         }
717
718         ret = true;
719
720 FINISH_OFF: 
721         if (ret == false) {
722                 if (account_list) /*  Warn! this is not *account_list. Just account_list */
723                         EM_SAFE_FREE(*account_list);
724         }
725
726         if (err_code != NULL)
727                 *err_code = err;
728         EM_DEBUG_FUNC_END();
729         return ret;
730 }
731         
732
733 #ifdef __FEATURE_BACKUP_ACCOUNT__
734 #include <ss_manager.h>
735
736 static int append_data_into_buffer(char **target_buffer, int *target_buffer_lenth, char *input_data, int input_data_length, int *error_code)
737 {
738         EM_DEBUG_FUNC_BEGIN("target_buffer [%p], target_buffer_lenth [%p], input_data [%p], input_data_length[%d]", target_buffer, target_buffer_lenth, input_data, input_data_length);
739         int local_error_code = EMAIL_ERROR_NONE, ret_code = false;
740
741         if (!target_buffer || !target_buffer_lenth || !input_data) {
742                 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
743                 local_error_code = EMAIL_ERROR_INVALID_PARAM;
744                 goto FINISH_OFF;
745         }
746
747         if (*target_buffer_lenth > 0 && input_data_length) {
748                 EM_DEBUG_LOG("*target_buffer_lenth [%d]", *target_buffer_lenth);
749                 *target_buffer = realloc(*target_buffer, (*target_buffer_lenth) + input_data_length);
750                 if (!*target_buffer) {
751                         EM_DEBUG_EXCEPTION("realloc failed");
752                         local_error_code = EMAIL_ERROR_OUT_OF_MEMORY;
753                         goto FINISH_OFF;
754                 }
755                 memcpy(*target_buffer + (*target_buffer_lenth), input_data, input_data_length);
756                 *target_buffer_lenth += input_data_length;
757                 EM_DEBUG_LOG("*target_buffer_lenth [%d] input_data_length [%d]", *target_buffer_lenth, input_data_length);
758         }
759         else {
760                 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
761                 local_error_code = EMAIL_ERROR_INVALID_PARAM;
762                 goto FINISH_OFF;
763         }
764
765         ret_code = true;
766
767 FINISH_OFF: 
768
769         if (error_code)
770                 *error_code = local_error_code;
771         EM_DEBUG_FUNC_END("ret_code [%d]", ret_code);
772
773         return ret_code;
774 }
775
776
777 static int emcore_write_account_into_buffer(char **target_buffer, int *target_buffer_lenth, emstorage_account_tbl_t *account_tbl_ptr, int *error_code)
778 {
779         EM_DEBUG_FUNC_BEGIN("target_buffer [%p], target_buffer_lenth [%p], account_tbl_ptr [%p], error_code [%p]", target_buffer, target_buffer_lenth, account_tbl_ptr, error_code);
780         int local_error_code = EMAIL_ERROR_NONE, ret_code = false, stream_length = 0;
781         email_account_t temp_account = {0};
782         char *byte_stream = NULL;
783
784         if (em_convert_account_tbl_to_account(account_tbl_ptr, &temp_account)) {
785                 byte_stream = em_convert_account_to_byte_stream(&temp_account, &stream_length);
786                 EM_DEBUG_LOG("stream_length [%d]", stream_length);
787                 /*  EM_DEBUG_LOG("incoming_server_password [%s]", temp_account->password) */
788
789                 if (byte_stream) {
790                         if (!append_data_into_buffer(target_buffer, target_buffer_lenth, (char *)&stream_length, sizeof(int), &local_error_code)) {
791                                 EM_DEBUG_EXCEPTION("append_data_into_buffer failed");
792                                 goto FINISH_OFF;
793                         }
794                         EM_DEBUG_LOG("append_data_into_buffer succeed for stream_length");
795
796                         if (!append_data_into_buffer(target_buffer, target_buffer_lenth, byte_stream, stream_length, &local_error_code)) {
797                                 EM_DEBUG_EXCEPTION("append_data_into_buffer failed");
798                                 goto FINISH_OFF;
799                         }
800                         EM_DEBUG_LOG("append_data_into_buffer succeed for byte_stream");
801                 }
802         }
803         else {
804                 EM_DEBUG_EXCEPTION("em_convert_account_tbl_to_account failed");
805                 local_error_code = EMAIL_ERROR_SYSTEM_FAILURE;
806                 goto FINISH_OFF;
807         }
808
809         ret_code = true;
810 FINISH_OFF: 
811         emcore_free_account(&temp_account);
812         if (error_code)
813                 *error_code = local_error_code;
814
815         EM_SAFE_FREE(byte_stream);
816
817         EM_DEBUG_FUNC_END("ret_code [%d]", ret_code);
818         return ret_code;
819 }
820
821 INTERNAL_FUNC int emcore_backup_accounts(const char *file_path, int *error_code)
822 {
823         EM_DEBUG_FUNC_BEGIN("file_path [%s], error_code [%p]", file_path, error_code);
824         int local_error_code = EMAIL_ERROR_NONE, local_error_code_2 = EMAIL_ERROR_NONE, ret_code = false;
825         int select_num, i, target_buff_length = 0;
826         char *target_buffer = NULL;
827         emstorage_account_tbl_t *account_list = NULL;
828
829         if (!file_path) {
830                 local_error_code = EMAIL_ERROR_INVALID_PARAM;
831                 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
832                 goto FINISH_OFF;        
833         }
834
835         select_num = 1000;
836         
837         if (!emstorage_get_account_list(&select_num, &account_list, true, true, &local_error_code)) {
838                 EM_DEBUG_EXCEPTION("emstorage_get_account_list failed [%d]", local_error_code);
839                 goto FINISH_OFF;        
840         }
841         
842         EM_DEBUG_LOG("select_num [%d]", select_num);
843         
844         if (account_list) {
845                 target_buffer = em_malloc(sizeof(int));
846                 if (!target_buffer)  {
847                         EM_DEBUG_EXCEPTION("malloc failed");
848                         local_error_code = EMAIL_ERROR_OUT_OF_MEMORY;
849                         goto FINISH_OFF;
850                 }
851
852                 memcpy(target_buffer, (char *)&select_num, sizeof(int));
853                 target_buff_length = sizeof(int);
854
855                 for (i = 0; i < select_num; i++) {
856                         if (!emcore_write_account_into_buffer(&target_buffer, &target_buff_length, account_list + i, &local_error_code)) {
857                                 EM_DEBUG_EXCEPTION("emcore_write_account_into_buffer failed [%d]", local_error_code);
858                                 goto FINISH_OFF;        
859                         }
860                 }
861
862                 EM_DEBUG_LOG("target_buff_length [%d]", target_buff_length);
863
864                 ssm_delete_file(file_path, SSM_FLAG_SECRET_OPERATION, NULL);
865                 
866                 if (ssm_write_buffer(target_buffer, target_buff_length, file_path, SSM_FLAG_SECRET_OPERATION, NULL) < 0) {
867                         EM_DEBUG_EXCEPTION("ssm_write_buffer failed [%d]", local_error_code);
868                         local_error_code = EMAIL_ERROR_SYSTEM_FAILURE;
869                         goto FINISH_OFF;        
870                 }
871                 
872         }
873
874         ret_code = true;        
875 FINISH_OFF: 
876
877         EM_SAFE_FREE(target_buffer);
878         if (account_list)
879                 emstorage_free_account(&account_list, select_num, &local_error_code_2);
880
881         if (error_code)
882                 *error_code = local_error_code;
883
884         EM_DEBUG_FUNC_END("ret_code [%d]", ret_code);
885         return ret_code;
886 }
887
888 INTERNAL_FUNC int emcore_restore_accounts(const char *file_path, int *error_code)
889 {
890         EM_DEBUG_FUNC_BEGIN("file_path [%s], error_code [%p]", file_path, error_code);
891         int local_error_code = EMAIL_ERROR_NONE, ret_code = false, buffer_length = 0, read_length = 0;
892         int account_count = 0, i = 0, account_stream_length = 0;
893         char *temp_buffer = NULL, *account_stream = NULL, *buffer_ptr = NULL;
894         email_account_t temp_account = {0};
895         email_account_t *account_list = NULL;
896
897         ssm_file_info_t sfi;
898
899         if (!file_path) {
900                 local_error_code = EMAIL_ERROR_INVALID_PARAM;
901                 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
902                 goto FINISH_OFF;        
903         }
904
905         if (emcore_get_account_reference_list(&account_list, &account_count, &ret_code)) {
906                 for (i = 0; i < account_count; i++) {
907                         if (account_list[i].incoming_server_type != EMAIL_SERVER_TYPE_ACTIVE_SYNC) {
908                                 if (!emcore_delete_account(account_list[i].account_id, &ret_code)) {
909                                         local_error_code = EMAIL_ERROR_INVALID_ACCOUNT;
910                                         EM_DEBUG_EXCEPTION("emcore_delete_account failed");
911                                         goto FINISH_OFF;
912                                 }
913                         }
914                 }
915         }
916
917         if (ssm_getinfo(file_path, &sfi, SSM_FLAG_SECRET_OPERATION, NULL) < 0) {
918                 EM_DEBUG_EXCEPTION("ssm_getinfo() failed.");
919                 ret_code = EMAIL_ERROR_SYSTEM_FAILURE;
920                 goto FINISH_OFF;
921         }
922
923         buffer_length = sfi.originSize;
924         EM_DEBUG_LOG("account buffer_length[%d]", buffer_length);
925         if ((temp_buffer = (char *)em_malloc(buffer_length + 1)) == NULL) {
926                 EM_DEBUG_EXCEPTION("em_malloc failed...");
927                 ret_code = EMAIL_ERROR_OUT_OF_MEMORY;
928                 goto FINISH_OFF;
929         }
930
931         if (ssm_read(file_path, temp_buffer, buffer_length, (size_t *)&read_length, SSM_FLAG_SECRET_OPERATION, NULL) < 0) {
932                 EM_DEBUG_EXCEPTION("ssm_read() failed.");
933                 ret_code = EMAIL_ERROR_SYSTEM_FAILURE;
934                 goto FINISH_OFF;
935         }
936
937         EM_DEBUG_LOG("read_length[%d]", read_length);
938
939         if (buffer_length == read_length) {
940                 memcpy((void *)&account_count, temp_buffer, sizeof(int));
941                 buffer_ptr = temp_buffer + sizeof(int);
942
943                 EM_DEBUG_LOG("account_count[%d]", account_count);               
944
945                 for (i = 0; i < account_count; i++) {
946                         memcpy((void *)&account_stream_length, buffer_ptr, sizeof(int));
947                         buffer_ptr += sizeof(int);
948                         EM_DEBUG_LOG("account_stream_length [%d]", account_stream_length);
949                         if (account_stream_length) {
950                                 account_stream = em_malloc(account_stream_length);
951                                 if (!account_stream) {
952                                         EM_DEBUG_EXCEPTION("em_malloc() failed.");
953                                         ret_code = EMAIL_ERROR_OUT_OF_MEMORY ;
954                                         goto FINISH_OFF;
955                                 }
956                                 memcpy(account_stream, buffer_ptr, account_stream_length);
957
958                                 em_convert_byte_stream_to_account(account_stream, account_stream_length, &temp_account);
959                                 EM_SAFE_FREE(account_stream);
960                         
961                                 if (!emcore_create_account(&temp_account, &ret_code)) {
962                                         EM_DEBUG_EXCEPTION("emcore_create_account() failed.");
963                                         goto FINISH_OFF;
964                                 }
965
966                                 emcore_free_account(&temp_account);
967                         }
968                         buffer_ptr += account_stream_length;
969                         account_stream_length = 0;
970                 }
971         } else {
972                 EM_DEBUG_EXCEPTION("ssm_read() failed.");
973                 ret_code = EMAIL_ERROR_SYSTEM_FAILURE;
974                 goto FINISH_OFF;
975         }
976         ret_code = true;        
977 FINISH_OFF: 
978         emcore_free_account(&temp_account);
979         EM_SAFE_FREE(account_stream);
980         EM_SAFE_FREE(temp_buffer);
981
982         EM_DEBUG_FUNC_END("ret_code [%d]", ret_code);
983         return ret_code;
984 }
985
986 #endif /*  __FEATURE_BACKUP_ACCOUNT_ */
987
988
989 INTERNAL_FUNC int emcore_query_server_info(const char* domain_name, email_server_info_t **result_server_info)
990 {
991         EM_DEBUG_FUNC_BEGIN("domain_name [%s], result_server_info [%p]", domain_name, result_server_info);
992         int ret_code = EMAIL_ERROR_NONE;
993         EM_DEBUG_FUNC_END("ret_code [%d]", ret_code);
994         return ret_code;
995 }
996
997
998 INTERNAL_FUNC int emcore_free_server_info(email_server_info_t **target_server_info)
999 {
1000         EM_DEBUG_FUNC_BEGIN("result_server_info [%p]", target_server_info);
1001         int i, ret_code = EMAIL_ERROR_NONE;
1002         email_server_info_t *server_info = NULL;
1003
1004         if(target_server_info && *target_server_info) {
1005                 server_info = *target_server_info;
1006                 EM_SAFE_FREE(server_info->service_name);
1007                 for(i = 0; i < server_info->protocol_conf_count; i++) {
1008                         EM_SAFE_FREE(server_info->protocol_config_array[i].server_addr);
1009                 }
1010                 EM_SAFE_FREE(server_info->protocol_config_array);
1011                 EM_SAFE_FREE(server_info);
1012         }
1013         EM_DEBUG_FUNC_END("ret_code [%d]", ret_code);
1014         return ret_code;        
1015 }
1016
1017 INTERNAL_FUNC int emcore_save_default_account_id(int input_account_id)
1018 {
1019         EM_DEBUG_FUNC_BEGIN("account_id [%d]", input_account_id);
1020         int ret_code = EMAIL_ERROR_NONE, result_value = 0;
1021
1022         result_value = vconf_set_int(VCONF_KEY_DEFAULT_ACCOUNT_ID, input_account_id);
1023         if (result_value < 0) {
1024                 EM_DEBUG_EXCEPTION("vconf_set_int failed [%d]", result_value);
1025                 ret_code = EMAIL_ERROR_SYSTEM_FAILURE;
1026         }
1027
1028         EM_DEBUG_FUNC_END("ret_code [%d]", ret_code);
1029         return ret_code;        
1030 }
1031
1032 static int _recover_from_invalid_default_account_id(int *output_account_id)
1033 {
1034         EM_DEBUG_FUNC_BEGIN("account_id [%p]", output_account_id);
1035         int ret_code = EMAIL_ERROR_NONE;
1036         int account_count = 100;
1037         emstorage_account_tbl_t *result_account_list = NULL;
1038
1039         if (output_account_id == NULL) {
1040                 ret_code = EMAIL_ERROR_INVALID_PARAM;
1041                 goto FINISH_OFF;
1042         }
1043
1044         if(!emstorage_get_account_list(&account_count, &result_account_list, false, false, &ret_code) || !result_account_list) {
1045                 EM_DEBUG_EXCEPTION("emstorage_get_account_list() failed [%d]", ret_code);
1046                 *output_account_id = 0;
1047                 goto FINISH_OFF;
1048         }
1049
1050         if (account_count > 0) {
1051                 *output_account_id = result_account_list[0].account_id;
1052         }
1053
1054         EM_DEBUG_LOG("output_account_id [%d]", *output_account_id);
1055
1056 FINISH_OFF:
1057
1058         if (result_account_list)
1059                 emstorage_free_account(&result_account_list, account_count, NULL);
1060
1061         EM_DEBUG_FUNC_END("ret_code [%d]", ret_code);
1062         return ret_code;
1063 }
1064
1065 INTERNAL_FUNC int emcore_load_default_account_id(int *output_account_id)
1066 {
1067         EM_DEBUG_FUNC_BEGIN("account_id [%p]", output_account_id);
1068         int ret_code = EMAIL_ERROR_NONE;
1069         int result_value = 0;
1070         emstorage_account_tbl_t *result_account = NULL;
1071         
1072         if (output_account_id == NULL) {
1073                 ret_code = EMAIL_ERROR_INVALID_PARAM;
1074                 goto FINISH_OFF;
1075         }
1076
1077         result_value = vconf_get_int(VCONF_KEY_DEFAULT_ACCOUNT_ID, output_account_id);
1078
1079         if (result_value < 0) {
1080                 EM_DEBUG_EXCEPTION("vconf_get_int() failed [%d]", result_value);
1081                 ret_code = EMAIL_ERROR_SYSTEM_FAILURE;
1082                 *output_account_id = 0;
1083         }
1084
1085         if (*output_account_id != 0) {
1086                 if (!emstorage_get_account_by_id(*output_account_id, EMAIL_ACC_GET_OPT_DEFAULT, &result_account, false, &ret_code)) {
1087                         EM_DEBUG_EXCEPTION("emstorage_get_account_by_id() failed [%d]", ret_code);
1088                         if(ret_code == EMAIL_ERROR_ACCOUNT_NOT_FOUND)
1089                                 *output_account_id = 0;
1090                         else
1091                                 goto FINISH_OFF;
1092                 }
1093         }
1094
1095         if (*output_account_id == 0) {
1096                 if ( (ret_code = _recover_from_invalid_default_account_id(output_account_id)) != EMAIL_ERROR_NONE) {
1097                         EM_DEBUG_EXCEPTION("_recover_from_invalid_default_account() failed [%d]", ret_code);
1098                         *output_account_id = 0;
1099                 }
1100         }
1101
1102 FINISH_OFF:
1103         if (result_account)
1104                 emstorage_free_account(&result_account, 1, NULL);
1105         
1106         EM_DEBUG_FUNC_END("ret_code [%d]", ret_code);
1107         return ret_code;        
1108 }
1109
1110 INTERNAL_FUNC int emcore_recover_from_secured_storage_failure()
1111 {
1112         EM_DEBUG_FUNC_BEGIN();
1113         int err = EMAIL_ERROR_NONE;
1114         int i = 0;
1115         int account_count = 50;
1116         emstorage_account_tbl_t *temp_account_tbl_list = NULL;
1117         emstorage_account_tbl_t *temp_account_tbl      = NULL;
1118
1119         if (!emstorage_get_account_list(&account_count, &temp_account_tbl_list, true, false, &err)) {
1120                 EM_DEBUG_EXCEPTION("emstorage_get_account_list failed [%d]", err);
1121                 goto FINISH_OFF;
1122         }
1123
1124         for (i = 0; i < account_count; i++) {
1125                 if(!emstorage_get_account_by_id(temp_account_tbl_list[i].account_id, EMAIL_ACC_GET_OPT_DEFAULT | EMAIL_ACC_GET_OPT_PASSWORD, &temp_account_tbl, true, &err)) {
1126                         if(err == EMAIL_ERROR_SECURED_STORAGE_FAILURE) {
1127                                 if(!emcore_delete_account(temp_account_tbl_list[i].account_id, &err)) {
1128                                         EM_DEBUG_EXCEPTION("emcore_delete_account failed [%d]", err);
1129                                         goto FINISH_OFF;
1130                                 }
1131                         }
1132                 }
1133         }
1134
1135 FINISH_OFF:
1136
1137         EM_DEBUG_FUNC_END("err [%d]", err);
1138         return err;
1139 }
1140
1141 INTERNAL_FUNC int emcore_update_sync_status_of_account(int input_account_id, email_set_type_t input_set_operator, int input_sync_status)
1142 {
1143         EM_DEBUG_FUNC_BEGIN("input_account_id [%d], input_set_operator [%d], input_sync_status [%d]", input_account_id, input_set_operator, input_sync_status);
1144         int err = EMAIL_ERROR_NONE;
1145
1146         if (!emstorage_update_sync_status_of_account(input_account_id, input_set_operator, input_sync_status, true, &err))
1147                 EM_DEBUG_EXCEPTION("emstorage_update_sync_status_of_account failed [%d]", err);
1148
1149         EM_DEBUG_FUNC_END("err [%d]", err);
1150         return err;
1151 }