2.0_alpha release commit
[framework/messaging/email-service.git] / email-core / email-core-imap-mailbox.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 /******************************************************************************
25  * File :  email-core-imap_folder.c
26  * Desc :  Mail IMAP mailbox
27  *
28  * Auth : 
29  *
30  * History : 
31  *    2006.08.01  :  created
32  *****************************************************************************/
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include <vconf.h>
37 #include "email-core-global.h"
38 #include "email-core-utils.h"
39 #include "c-client.h"
40 #include "email-storage.h"
41 #include "email-utilities.h"
42 #include "email-core-event.h"
43 #include "email-core-mailbox.h"
44 #include "email-core-imap-mailbox.h"
45 #include "email-core-mailbox-sync.h"
46 #include "email-core-account.h" 
47 #include "lnx_inc.h"
48
49 #include "email-debug-log.h"
50
51 INTERNAL_FUNC int emcore_get_default_mail_slot_count(int *output_count, int *err_code)
52 {       
53         EM_DEBUG_FUNC_BEGIN();
54         EM_DEBUG_LOG("output_count[%p], err_code[%p]", output_count, err_code);
55
56         int err = EMAIL_ERROR_NONE;
57         int mail_slot_count;
58         int ret = false, ret2;
59
60         if (output_count == NULL) {
61                 err = EMAIL_ERROR_INVALID_PARAM;
62                 goto FINISH_OFF;
63         }
64
65         ret2 = vconf_get_int(VCONF_KEY_DEFAULT_SLOT_SIZE, &mail_slot_count);
66
67         if (ret2 < 0) {
68                 EM_DEBUG_EXCEPTION("vconf_get_int() Failed(%d)", ret2);
69         mail_slot_count = 100;
70         }
71
72         ret = true;
73
74 FINISH_OFF: 
75         
76         if (output_count)
77                 *output_count = mail_slot_count;
78
79         if (err_code)
80                 *err_code = err;
81
82         return ret;
83         
84 }
85
86
87 INTERNAL_FUNC int emcore_remove_overflowed_mails(emstorage_mailbox_tbl_t *intput_mailbox_tbl, int *err_code)
88 {
89         EM_DEBUG_FUNC_BEGIN("intput_mailbox_tbl[%p], err_code[%p]", intput_mailbox_tbl, err_code);
90
91         int ret = false; 
92         int *mail_id_list = NULL, mail_id_list_count = 0;
93         int err = EMAIL_ERROR_NONE;
94         email_account_t *account_ref = NULL;
95         
96         if (!intput_mailbox_tbl || intput_mailbox_tbl->account_id < 1) {
97                 if (intput_mailbox_tbl)
98                 EM_DEBUG_EXCEPTION("Invalid Parameter. intput_mailbox_tbl->account_id [%d]", intput_mailbox_tbl->account_id);
99                 err = EMAIL_ERROR_INVALID_PARAM;
100                 goto FINISH_OFF;
101         }
102
103         account_ref = emcore_get_account_reference(intput_mailbox_tbl->account_id);
104         if (account_ref) {
105                 if (account_ref->incoming_server_type == EMAIL_SERVER_TYPE_ACTIVE_SYNC) {
106                         EM_DEBUG_LOG("ActiveSync Account didn't support mail slot");
107                         err = EMAIL_ERROR_NOT_SUPPORTED;
108                         goto FINISH_OFF;
109                 }
110         }
111         
112         if (!emstorage_get_overflowed_mail_id_list(intput_mailbox_tbl->account_id, intput_mailbox_tbl->mailbox_id, intput_mailbox_tbl->mail_slot_size, &mail_id_list, &mail_id_list_count, true, &err)) {
113                 if (err == EMAIL_ERROR_MAIL_NOT_FOUND) {
114                         EM_DEBUG_LOG("There are enough slot in intput_mailbox_tbl [%s]", intput_mailbox_tbl->mailbox_name);
115                         err = EMAIL_ERROR_NONE;
116                         ret = true;
117                 }
118                 else
119                         EM_DEBUG_EXCEPTION("emstorage_get_overflowed_mail_id_list failed [%d]", err);
120                 goto FINISH_OFF;
121         }
122
123         if (mail_id_list) {
124                 if (!emcore_delete_mail(intput_mailbox_tbl->account_id, mail_id_list, mail_id_list_count, EMAIL_DELETE_LOCALLY, EMAIL_DELETED_BY_OVERFLOW, false, &err)) {
125                         EM_DEBUG_EXCEPTION("emcore_delete_mail failed [%d]", err);
126                         goto FINISH_OFF;
127                 }
128         }
129         
130         ret = true;
131 FINISH_OFF: 
132         EM_SAFE_FREE(mail_id_list);
133
134         if (err_code)
135                 *err_code = err;
136
137         EM_DEBUG_FUNC_END("ret [%d]", ret);
138         return ret;
139 }
140
141
142 INTERNAL_FUNC int emcore_set_mail_slot_size(int account_id, int mailbox_id, int new_slot_size, int *err_code)
143 {
144         EM_DEBUG_FUNC_BEGIN("account_id [%d], mailbox_id[%d], err_code[%p]", account_id, mailbox_id, err_code);
145
146         int ret = false, err = EMAIL_ERROR_NONE; 
147         int i = 0;
148         int account_count = 100;
149         int mailbox_count = 0;
150         email_account_t *account_ref = NULL;
151         emstorage_account_tbl_t *account_tbl_list = NULL;
152         emstorage_mailbox_tbl_t *mailbox_tbl_list = NULL;
153
154         if (account_id > ALL_ACCOUNT) {
155                 account_ref = emcore_get_account_reference(account_id);
156                 if (account_ref && account_ref->incoming_server_type == EMAIL_SERVER_TYPE_ACTIVE_SYNC) {
157                         EM_DEBUG_LOG("ActiveSync account didn't support mail slot");
158                         ret = true;
159                         goto FINISH_OFF;
160                 }
161                 else if (!account_ref) {
162                         EM_DEBUG_EXCEPTION("emcore_get_account_reference failed");
163                         goto FINISH_OFF;
164                 }
165                 if (mailbox_id == 0) {
166                         if ( (err = emstorage_set_field_of_accounts_with_integer_value(account_id, "default_mail_slot_size", new_slot_size, true)) != EMAIL_ERROR_NONE) {
167                                 EM_DEBUG_EXCEPTION("emstorage_set_field_of_accounts_with_integer_value failed [%d]", err);
168                                 goto FINISH_OFF;
169                         }
170                 }
171         }
172         else {
173                 if (mailbox_id == 0) {
174                         if ( !emstorage_get_account_list(&account_count, &account_tbl_list, false, false, &err)) {
175                                 EM_DEBUG_EXCEPTION("emstorage_get_account_list failed [%d]", err);
176                                 goto FINISH_OFF;
177                         }
178                         for ( i = 0; i < account_count; i++) {
179                                 if ( (err = emstorage_set_field_of_accounts_with_integer_value(account_tbl_list[i].account_id, "default_mail_slot_size", new_slot_size, true)) != EMAIL_ERROR_NONE) {
180                                         EM_DEBUG_EXCEPTION("emstorage_set_field_of_accounts_with_integer_value failed [%d]", err);
181                                         goto FINISH_OFF;
182                                 }
183                         }
184                 }
185         }
186
187
188         if (!emstorage_set_mail_slot_size(account_id, mailbox_id, new_slot_size, true, &err)) {
189                 EM_DEBUG_EXCEPTION("emstorage_set_mail_slot_size failed [%d]", err);
190                 goto FINISH_OFF;
191         }
192
193         if (mailbox_id) {
194                 mailbox_count = 1;
195                 if (new_slot_size > 0) {
196                         mailbox_tbl_list = em_malloc(sizeof(emstorage_mailbox_tbl_t) * mailbox_count);
197                         if(!mailbox_tbl_list) {
198                                 EM_DEBUG_EXCEPTION("em_malloc failed");
199                                 goto FINISH_OFF;
200                         }
201                         mailbox_tbl_list->account_id = account_id;
202                         mailbox_tbl_list->mailbox_id = mailbox_id;
203                         mailbox_tbl_list->mail_slot_size = new_slot_size;     
204                 }
205                 else   {        /*  read information from DB */
206                         if ((err = emstorage_get_mailbox_by_id(mailbox_id, &mailbox_tbl_list)) != EMAIL_ERROR_NONE) {
207                                 EM_DEBUG_EXCEPTION("emstorage_get_mailbox_by_id failed [%d]", err);
208                                 goto FINISH_OFF;
209                         }
210                         
211                 }
212         }
213         else {
214                 if (!emstorage_get_mailbox_list(account_id, EMAIL_MAILBOX_ALL, EMAIL_MAILBOX_SORT_BY_NAME_ASC, &mailbox_count, &mailbox_tbl_list, true, &err)) {
215                         EM_DEBUG_EXCEPTION("emstorage_get_mailbox failed [%d]", err);
216                         goto FINISH_OFF;
217                 }
218         }
219
220         for (i = 0; i < mailbox_count; i++) {
221                 if (!emcore_remove_overflowed_mails(mailbox_tbl_list + i, &err)) {
222                         if (err == EMAIL_ERROR_MAIL_NOT_FOUND || err == EMAIL_ERROR_NOT_SUPPORTED)
223                                 err = EMAIL_ERROR_NONE;
224                         else
225                                 EM_DEBUG_EXCEPTION("emcore_remove_overflowed_mails failed [%d]", err);
226                 }
227         }
228
229         ret = true;
230         
231 FINISH_OFF: 
232
233         if (account_tbl_list)
234                 emstorage_free_account(&account_tbl_list, account_count, NULL);
235
236         if (mailbox_tbl_list)
237                 emstorage_free_mailbox(&mailbox_tbl_list, mailbox_count, NULL);
238
239
240         if (err_code)
241                 *err_code = err;
242         return ret;
243 }
244
245 static int emcore_get_mailbox_connection_path(int account_id, char *mailbox_name, char **path, int *err_code)
246 {
247     email_account_t *ref_account = NULL;
248         size_t path_len = 0;
249
250
251         ref_account = emcore_get_account_reference(account_id);
252         if (!ref_account)        {
253                 EM_DEBUG_EXCEPTION("emcore_get_account_reference failed");
254                 return 0;
255         }
256
257         path_len = strlen(ref_account->incoming_server_address) +
258                           (mailbox_name ? strlen(mailbox_name) : 0) + 50;
259
260     *path = em_malloc(path_len);/* strlen(ref_account->incoming_server_address) + */
261                           /* (mailbox_name ? strlen(mailbox_name) : 0) + 20); */
262     if (!*path)
263         return 0;
264         memset(*path, 0x00, path_len);
265     /* 1. server address / server type */
266
267     if (ref_account->incoming_server_type == EMAIL_SERVER_TYPE_POP3) {
268         SNPRINTF(*path + 1, path_len-1, "%s:%d/pop", ref_account->incoming_server_address, ref_account->incoming_server_port_number);
269     }
270     else {
271         SNPRINTF(*path + 1, path_len-1, "%s:%d/imap", ref_account->incoming_server_address, ref_account->incoming_server_port_number);
272     }
273
274     /* 2. set tls option if security connection */
275 /*     if (ref_account->incoming_server_secure_connection) strncat(*path + 1, "/tls", path_len-(strlen(*path)-1)); */
276         if (ref_account->incoming_server_secure_connection & 0x01) {
277                 strncat(*path + 1, "/ssl", path_len-(strlen(*path)-1));
278         }
279         if (ref_account->incoming_server_secure_connection & 0x02)
280                 strncat(*path + 1, "/tls", path_len-(strlen(*path)-1));
281         else
282                 strncat(*path + 1, "/notls", path_len-(strlen(*path)-1));
283
284     /*  3. re-format mailbox name (ex:"{mai.test.com:143/imap} or {mai.test.com:143/imap/tls}"} */
285     strncat(*path + 1, "}", path_len-strlen(*path)-1);
286     **path = '{';
287
288     if (mailbox_name) strncat(*path, mailbox_name, path_len-strlen(*path)-1);
289
290     return 1;
291 }
292
293 INTERNAL_FUNC int emcore_sync_mailbox_list(int account_id, char *mailbox_name, int *err_code)
294 {
295         EM_DEBUG_FUNC_BEGIN("account_id[%d], mailbox_name[%p], err_code[%p]", account_id, mailbox_name, err_code);
296         
297         int ret = false;
298         int err = EMAIL_ERROR_NONE;
299         int status = EMAIL_DOWNLOAD_FAIL;
300         
301         MAILSTREAM *stream = NULL;
302         email_internal_mailbox_t *mailbox_list = NULL;
303         email_account_t *ref_account = NULL;
304         void *tmp_stream = NULL;
305         char *mbox_path = NULL;
306         int i = 0, count = 0, counter = 0, mailbox_type_list[EMAIL_MAILBOX_TYPE_ALL_EMAILS + 1] = {-1, -1, -1, -1, -1, -1, -1, -1};
307         char *mailbox_name_for_mailbox_type = NULL;
308
309         
310         if (err_code) 
311                 *err_code = EMAIL_ERROR_NONE;
312         
313         if (!emcore_check_thread_status())  {
314                 err = EMAIL_ERROR_CANCELLED;
315                 goto FINISH_OFF;
316         }
317         
318         ref_account = emcore_get_account_reference(account_id);
319         if (!ref_account)  {
320                 EM_DEBUG_EXCEPTION("emcore_get_account_reference failed - %d", account_id);
321                 err = EMAIL_ERROR_INVALID_ACCOUNT;
322                 goto FINISH_OFF;
323         }
324         
325         /* if not imap4 mail, return */
326         if ( ref_account->incoming_server_type != EMAIL_SERVER_TYPE_IMAP4)  {
327                 EM_DEBUG_EXCEPTION("unsupported account...");
328                 err = EMAIL_ERROR_INVALID_ACCOUNT;
329                 goto FINISH_OFF;
330         }
331         
332         /*  get mail server path */
333         /*  mbox_path is not used. the below func might be unnecessary */
334         if (!emcore_get_mailbox_connection_path(account_id, NULL, &mbox_path, &err) || !mbox_path)  {
335                 EM_DEBUG_EXCEPTION("emcore_get_mailbox_connection_path - %d", err);
336                 goto FINISH_OFF;
337         }
338         
339         
340         if (!emcore_check_thread_status())  {
341                 err = EMAIL_ERROR_CANCELLED;
342                 goto FINISH_OFF;
343         }
344
345         stream = NULL;
346         if (!emcore_connect_to_remote_mailbox(account_id, 0, (void **)&tmp_stream, &err) || !tmp_stream)  {
347                 EM_DEBUG_EXCEPTION("emcore_connect_to_remote_mailbox failed - %d", err);
348                 
349                 if (err == EMAIL_ERROR_CONNECTION_BROKEN)
350                         err = EMAIL_ERROR_CANCELLED;
351                 else
352                         err = EMAIL_ERROR_CONNECTION_FAILURE;
353                 
354                 status = EMAIL_DOWNLOAD_CONNECTION_FAIL;
355                 goto FINISH_OFF;
356         }
357         
358         EM_SAFE_FREE(mbox_path);
359         
360         stream = (MAILSTREAM *)tmp_stream;
361         
362         if (!emcore_check_thread_status())  {
363                 err = EMAIL_ERROR_CANCELLED;
364                 goto FINISH_OFF;
365         }
366         
367         /*  download mailbox list */
368         if (!emcore_download_mailbox_list(stream, mailbox_name, &mailbox_list, &count, &err))  {
369                 EM_DEBUG_EXCEPTION("emcore_download_mailbox_list failed - %d", err);
370                 goto FINISH_OFF;
371         }
372
373         if (!emcore_check_thread_status())  {
374                 err = EMAIL_ERROR_CANCELLED;
375                 goto FINISH_OFF;
376         }
377         
378         for (i = 0; i < count; i++) {
379                 if (!emcore_check_thread_status())  {
380                         EM_DEBUG_LOG("emcore_check_thread_status - cancelled");
381                         err = EMAIL_ERROR_CANCELLED;
382                         goto FINISH_OFF;
383                 }
384                 if (mailbox_list[i].mailbox_name) {
385                         EM_DEBUG_LOG("mailbox name - %s", mailbox_list[i].mailbox_name);
386                         emcore_get_default_mail_slot_count(&(mailbox_list[i].mail_slot_size), NULL);
387
388                         if(mailbox_list[i].mailbox_type == EMAIL_MAILBOX_TYPE_NONE)
389                                 emcore_bind_mailbox_type(mailbox_list + i);
390
391                         if (mailbox_list[i].mailbox_type <= EMAIL_MAILBOX_TYPE_ALL_EMAILS) {    /* if result mailbox type is duplicated,  */
392                                 if (mailbox_type_list[mailbox_list[i].mailbox_type] != -1) {
393                                         EM_DEBUG_LOG("Mailbox type [%d] of [%s] is duplicated", mailbox_list[i].mailbox_type, mailbox_list[i].mailbox_name);
394                                         mailbox_list[i].mailbox_type = EMAIL_MAILBOX_TYPE_USER_DEFINED; /* ignore latest one  */
395                                 }
396                                 else
397                                         mailbox_type_list[mailbox_list[i].mailbox_type] = i;
398                         }
399
400                         EM_DEBUG_LOG("mailbox type [%d]", mailbox_list[i].mailbox_type);
401                         if(!emcore_set_sync_imap_mailbox(mailbox_list + i, 1, &err)) {
402                                 EM_DEBUG_EXCEPTION("emcore_set_sync_imap_mailbox failed [%d]", err);
403                                 goto FINISH_OFF;
404                         }
405
406                 }
407         }
408
409
410         for (counter = EMAIL_MAILBOX_TYPE_INBOX; counter <= EMAIL_MAILBOX_TYPE_OUTBOX; counter++) {
411                 /* if (!emstorage_get_mailbox_name_by_mailbox_type(account_id, counter, &mailbox_name_for_mailbox_type, false, &err))  */
412                 if (mailbox_type_list[counter] == -1) {
413                         /* EM_DEBUG_EXCEPTION("emstorage_get_mailbox_name_by_mailbox_type failed - %d", err); */
414                         /* if (EMAIL_ERROR_MAILBOX_NOT_FOUND == err)     */
415                         /* { */
416                                 emstorage_mailbox_tbl_t mailbox_tbl;
417                                 
418                                 memset(&mailbox_tbl, 0x00, sizeof(mailbox_tbl));
419                                 
420                                 mailbox_tbl.account_id = account_id;
421                                 mailbox_tbl.mailbox_id = 0;
422                                 mailbox_tbl.local_yn = 1; 
423                                 mailbox_tbl.mailbox_type = counter;
424                                 mailbox_tbl.sync_with_server_yn =  0;
425                                 mailbox_tbl.modifiable_yn = 1; 
426                                 mailbox_tbl.total_mail_count_on_server = 0;
427                                 emcore_get_default_mail_slot_count(&mailbox_tbl.mail_slot_size, NULL);
428                                 
429                                 switch (counter) {
430                                         case EMAIL_MAILBOX_TYPE_SENTBOX:
431                                                 mailbox_tbl.mailbox_name = EMAIL_SENTBOX_NAME;
432                                                 mailbox_tbl.alias = EMAIL_SENTBOX_DISPLAY_NAME;
433                                                 break;
434                                                 
435                                         case EMAIL_MAILBOX_TYPE_TRASH:
436                                                 mailbox_tbl.mailbox_name = EMAIL_TRASH_NAME;
437                                                 mailbox_tbl.alias = EMAIL_TRASH_DISPLAY_NAME;
438                                                 break;
439
440                                     case EMAIL_MAILBOX_TYPE_DRAFT:
441                                                 mailbox_tbl.mailbox_name = EMAIL_DRAFTBOX_NAME;
442                                                 mailbox_tbl.alias = EMAIL_DRAFTBOX_DISPLAY_NAME;
443                                                 break;
444                                                 
445                                         case EMAIL_MAILBOX_TYPE_SPAMBOX:
446                                                 mailbox_tbl.mailbox_name = EMAIL_SPAMBOX_NAME;
447                                                 mailbox_tbl.alias = EMAIL_SPAMBOX_DISPLAY_NAME;
448                                                 break;
449                                                 
450                                         case EMAIL_MAILBOX_TYPE_OUTBOX:
451                                                 mailbox_tbl.mailbox_name = EMAIL_OUTBOX_NAME;
452                                                 mailbox_tbl.alias = EMAIL_OUTBOX_DISPLAY_NAME;
453                                                 break;
454
455                                         default: 
456                                                 mailbox_tbl.mailbox_name = EMAIL_INBOX_NAME;
457                                                 mailbox_tbl.alias = EMAIL_INBOX_DISPLAY_NAME;
458                                                 break;
459                                 }
460
461                                 if (!emstorage_add_mailbox(&mailbox_tbl, true, &err)) {
462                                         EM_DEBUG_EXCEPTION("emstorage_add_mailbox failed - %d", err);
463                                         goto FINISH_OFF;
464                                 }
465                                 
466                         /* }     */
467                         /* else */
468                         /* { */
469                         /*  */
470                         /*      goto FINISH_OFF; */
471                         /* } */
472                         
473                 }
474                 EM_SAFE_FREE(mailbox_name_for_mailbox_type);
475         }
476
477         emstorage_mailbox_tbl_t *local_mailbox_list = NULL;
478         int select_num = 0;
479         i = 0;
480         email_mailbox_t mailbox;
481
482         if (emstorage_get_mailbox_by_modifiable_yn(account_id, 0 /* modifiable_yn */, &select_num, &local_mailbox_list, true, &err)) {
483                 if (select_num > 0) {
484                         for (i = 0; i < select_num; i++) {
485                                 EM_DEBUG_LOG(">>> MailBox needs to be Deleted[ %s ] ", local_mailbox_list[i].mailbox_name);
486                                 mailbox.account_id = local_mailbox_list[i].account_id;
487                                 mailbox.mailbox_name = local_mailbox_list[i].mailbox_name;
488                                 mailbox.mailbox_id = local_mailbox_list[i].mailbox_id;
489                                 if (!emcore_delete_mailbox_all(&mailbox, &err)) {
490                                         EM_DEBUG_EXCEPTION(" emcore_delete_all of Mailbox [%s] Failed ", mailbox.mailbox_name);
491                                         emstorage_free_mailbox(&local_mailbox_list, select_num, NULL); 
492                                         local_mailbox_list = NULL;
493                                         goto FINISH_OFF;
494                                 }
495                         }
496                         emstorage_free_mailbox(&local_mailbox_list, select_num, NULL); 
497                         local_mailbox_list = NULL;
498                 }
499         }
500
501         if (!emstorage_set_all_mailbox_modifiable_yn(account_id, 0, true, &err)) {
502                         EM_DEBUG_EXCEPTION(" >>>> emstorage_set_all_mailbox_modifiable_yn Failed [ %d ]", err);
503                         goto FINISH_OFF;
504         }
505         
506         if (!emcore_check_thread_status())  {
507                 err = EMAIL_ERROR_CANCELLED;
508                 goto FINISH_OFF;
509         }
510         
511         for (i = 0; i < count; i++)
512                 mailbox_list[i].account_id = account_id;
513         
514         
515         ret = true;
516         
517 FINISH_OFF: 
518         EM_SAFE_FREE(mailbox_name_for_mailbox_type);
519         EM_SAFE_FREE(mbox_path);
520
521         if (stream) 
522                 emcore_close_mailbox(account_id, stream);
523         
524         if (mailbox_list) 
525                 emcore_free_internal_mailbox(&mailbox_list, count, NULL);
526
527         if (err_code != NULL)
528                 *err_code = err;
529         EM_DEBUG_FUNC_END("ret [%d]", ret);
530         return ret;
531 }
532
533 int emcore_download_mailbox_list(void *mail_stream, 
534                                                                                 char *mailbox_name,
535                                                                                 email_internal_mailbox_t **mailbox_list,
536                                                                                 int *count, 
537                                                                                 int *err_code)
538 {
539         EM_DEBUG_FUNC_BEGIN("mail_stream [%p], mailbox_name [%p], mailbox_list [%p], count [%p], err_code [%p]", mail_stream, mailbox_name, mailbox_list, count, err_code);
540
541     MAILSTREAM *stream = mail_stream;
542     email_callback_holder_t holder;
543     char *pattern = NULL;
544     char *reference = NULL;
545     int   err = EMAIL_ERROR_NONE;
546     int   ret = false;
547
548         if (!stream || !mailbox_list || !count) {
549         err = EMAIL_ERROR_INVALID_PARAM;
550         goto FINISH_OFF;
551         }
552         
553         memset(&holder, 0x00, sizeof(holder));
554
555     /*  reference (ex : "{mail.test.com}", "{mail.test.com}inbox") */
556         if (mailbox_name)  {
557                 char *s = NULL;
558                 reference = em_malloc(strlen(stream->original_mailbox) + strlen(mailbox_name) + 1);
559                 if (reference) {
560                         strncpy(reference, stream->original_mailbox, (size_t)strlen(stream->original_mailbox));
561                         if ((s = strchr(reference, '}')))
562                                 *(++s) = '\0';
563                         strcat(reference, mailbox_name);
564                 }
565         }
566         else
567                 reference = EM_SAFE_STRDUP(stream->original_mailbox);
568
569         pattern        = "*";
570     stream->sparep = &holder;
571
572         /*  imap command : tag LIST reference * */
573     /*  see callback function mm_list */
574         mail_list(stream, reference, pattern);
575
576     stream->sparep = NULL;
577
578         EM_SAFE_FREE(reference);
579
580     *count        = holder.num;
581     *mailbox_list = (email_internal_mailbox_t*)holder.data;
582
583         ret = true;
584
585 FINISH_OFF: 
586         if (err_code)
587                 *err_code = err;
588
589         return ret;
590 }
591
592 /* description
593  *    check whether this imap mailbox is synchronous mailbox
594  * arguments
595  *    mailbox  :  imap mailbox to be checked
596  *    synchronous  :   boolean variable to be synchronous (1 : sync 0 : non-sync)
597  * return
598  *    succeed  :  1
599  *    fail  :  0
600  */
601 int emcore_check_sync_imap_mailbox(email_mailbox_t *mailbox, int *synchronous, int *err_code)
602 {
603         EM_DEBUG_FUNC_BEGIN();
604         
605         EM_DEBUG_LOG("\t mailbox[%p], synchronous[%p], err_code[%p]", mailbox, synchronous, err_code);
606         
607         if (err_code) {
608                 *err_code = EMAIL_ERROR_NONE;
609         }
610
611         if (!mailbox || !synchronous) {
612                 EM_DEBUG_EXCEPTION("\t mailbox[%p], synchronous[%p]", mailbox, synchronous);
613                 
614                 if (err_code != NULL)
615                         *err_code = EMAIL_ERROR_INVALID_PARAM;
616                 return false;
617         }
618         
619         int ret = false;
620         int err = EMAIL_ERROR_NONE;
621         emstorage_mailbox_tbl_t *imap_mailbox_tbl = NULL;
622
623         if (!emstorage_get_mailbox_by_name(mailbox->account_id, 0, mailbox->mailbox_name, &imap_mailbox_tbl, true, &err))  {
624                 EM_DEBUG_EXCEPTION("emstorage_get_mailbox_by_name failed - %d", err);
625                 goto FINISH_OFF;
626         }
627         
628         *synchronous = imap_mailbox_tbl ? 1  :  0;
629         
630         ret = true;
631         
632 FINISH_OFF: 
633         if (imap_mailbox_tbl != NULL)
634                 emstorage_free_mailbox(&imap_mailbox_tbl, 1, NULL);
635         
636         if (err_code != NULL)
637                 *err_code = err;
638         
639         return ret;
640 }
641
642
643 /* description
644  *    set sync imap mailbox
645  * arguments
646  *    mailbox_list  :  imap mailbox to be synced
647  *    syncronous  :  0-sync 1 : non-sync
648  * return
649  *    succeed  :  1
650  *    fail  :  0
651  */
652
653 INTERNAL_FUNC int emcore_set_sync_imap_mailbox(email_internal_mailbox_t *mailbox, int synchronous, int *err_code)
654 {
655         EM_DEBUG_FUNC_BEGIN("mailbox[%p], synchronous[%d], err_code[%p]", mailbox, synchronous, err_code);
656         
657         if (!mailbox)  {
658                 EM_DEBUG_EXCEPTION("mailbox[%p], synchronous[%d]", mailbox, synchronous);
659                 if (err_code != NULL)
660                         *err_code = EMAIL_ERROR_INVALID_PARAM;
661                 return false;
662         }
663         
664         int ret = false;
665         int err = EMAIL_ERROR_NONE;
666         emstorage_mailbox_tbl_t *imap_mailbox_tbl_item = NULL;
667         emcore_uid_list *uid_list = NULL;
668         emstorage_read_mail_uid_tbl_t *downloaded_uids = NULL;
669         MAILSTREAM *stream = mailbox->mail_stream;
670         int mailbox_renamed = 0;
671         int j = 0;
672         int i = 0;
673         int temp = 0;
674         IMAPLOCAL *imap_local = NULL;
675         char cmd[128] = { 0 , }, tag[32] = { 0 , }, *p = NULL;
676                 
677         if (synchronous) {              
678                 /* if synchcronous, insert imap mailbox to db */
679                 if (emstorage_get_mailbox_by_name(mailbox->account_id, 0, mailbox->mailbox_name, &imap_mailbox_tbl_item, true, &err))  {        
680                         /* mailbox already exists */
681                         /* mailbox Found, Do set the modifiable_yn = 1 */
682                         EM_DEBUG_LOG("mailbox already exists and setting modifiable_yn to 1");
683                         if (!emstorage_update_mailbox_modifiable_yn(mailbox->account_id, 0, mailbox->mailbox_name, 1, true, &err)) {
684                                 EM_DEBUG_EXCEPTION(" emstorage_update_mailbox_modifiable_yn Failed [ %d ] ", err);
685                                 goto JOB_ERROR;
686                         }
687                 }
688                 else {
689                         if (err != EMAIL_ERROR_MAILBOX_NOT_FOUND) {
690                                 EM_DEBUG_EXCEPTION(">>>>.>>>>>Getting mailbox failed>>>>>>>>>>>>>>");
691                                 /* This is error scenario so finish the job */
692                                 goto JOB_ERROR;
693                         }
694                         else {
695                                 /* This is not error scenario - mailbox is either new/renamed mailbox and needs to be added/modfied in DB */
696                                 /* Now check if mailbox is renamed */
697                                 EM_DEBUG_LOG(">>>>>>>>>>>>>>>>>>>>>>>MAILBOX NEW OR RENAMED");
698                                 if (stream) {
699                                         imap_local = ((MAILSTREAM *)stream)->local;
700                                         EM_DEBUG_LINE;
701                                         sprintf(tag, "%08lx", 0xffffffff & (((MAILSTREAM *)stream)->gensym++));
702                                         EM_DEBUG_LINE;
703                                         sprintf(cmd, "%s SELECT %s\015\012", tag, mailbox->mailbox_name);
704                                         EM_DEBUG_LINE;
705
706                                 }
707                                 
708                                 /* select the mailbox and get its UID */
709                                 if (!imap_local || !imap_local->netstream || !net_sout(imap_local->netstream, cmd, (int)strlen(cmd))) {
710                                         EM_DEBUG_EXCEPTION("network error - failed to IDLE on Mailbox [%s]", mailbox->mailbox_name);
711                                         /*
712                                         err = EMAIL_ERROR_CONNECTION_BROKEN;
713                                         if(imap_local)
714                                                 imap_local->netstream = NULL;
715                                         mailbox->mail_stream = NULL;
716                                         goto JOB_ERROR;
717                                         */
718                                 }
719                                 else {
720                                         EM_DEBUG_LOG("Get response for select call");
721                                         while (imap_local->netstream) {
722                                         p = net_getline(imap_local->netstream);
723                                                 EM_DEBUG_LOG("p =[%s]", p);
724                                                 if (!strncmp(p, "+", 1)) {
725                                                         ret = 1;
726                                                         break;
727                                                 }
728                                                 else if (!strncmp(p, "*", 1)) {
729                                                 EM_SAFE_FREE(p); 
730                                                 continue;
731                                                 }
732                                                 else {
733                                                         ret = 0;
734                                                         break;
735                                                 }
736                                 }
737                                         EM_SAFE_FREE(p); 
738                                         EM_DEBUG_LINE;
739                                         /* check if OK or BAD response comes. */
740                                         /* if response is OK the try getting UID list. */
741                                         if (!strncmp((char *)imap_local->reply.key, "OK", strlen("OK")))  {
742                                                 EM_DEBUG_LOG(">>>>>>>>>>Select success on %s mailbox", mailbox->mailbox_name);
743                                                 if (!imap4_mailbox_get_uids(stream, &uid_list, &err)) {
744                                                         EM_DEBUG_EXCEPTION("imap4_mailbox_get_uids failed - %d", err);
745                                                         EM_SAFE_FREE(uid_list);
746                                                 }
747                                                 else {
748                                                         if (!emstorage_get_downloaded_list(mailbox->account_id, 0, &downloaded_uids, &j, true, &err)) {
749                                                                 EM_DEBUG_EXCEPTION("emstorage_get_downloaded_list failed [%d]", err);
750                                                 
751                                                                 downloaded_uids = NULL;
752                                                         }
753                                                         else /* Prevent Defect - 28497 */ {
754                                                                 emcore_uid_list *uid_elem = uid_list;
755                                                                 emcore_uid_list *next_uid_elem = NULL;
756                                                                 if (uid_elem) {
757                                                                         for (i = j; (i > 0 && !mailbox_renamed); i--)  {
758                                                                                 if (uid_elem) {
759                                                                                         next_uid_elem = uid_elem->next;
760                                                                                         if (uid_elem->uid && downloaded_uids[i - 1].s_uid && !strcmp(uid_elem->uid, downloaded_uids[i - 1].s_uid)) {
761                                                                                                 temp = i-1;
762                                                                                                 mailbox_renamed = 1;
763                                                                                                 break;
764                                                                                         }
765                                                                                         EM_SAFE_FREE(uid_elem->uid);
766                                                                                         uid_elem = next_uid_elem;
767                                                                                 }
768                                                                         }
769                                                                 }
770                                                         }
771                                                 }
772                                         } /* mailbox selected */
773                                 }       
774
775                                 if (mailbox_renamed) /* renamed mailbox */ {
776                                         EM_DEBUG_LOG("downloaded_uids[temp].mailbox_name [%s]", downloaded_uids[temp].mailbox_name);
777                                         /* Do a mailbox rename in the DB */
778                                         if (!emstorage_modify_mailbox_of_mails(downloaded_uids[temp].mailbox_name, mailbox->mailbox_name, true, &err))
779                                                 EM_DEBUG_EXCEPTION(" emstorage_modify_mailbox_of_mails Failed [%d]", err);
780
781                                         mailbox_renamed = 0;
782
783                                         emstorage_mailbox_tbl_t mailbox_tbl;
784                                         mailbox_tbl.account_id = mailbox->account_id;
785                                         mailbox_tbl.local_yn = 0;
786                                         mailbox_tbl.mailbox_name = mailbox->mailbox_name;
787                                         mailbox_tbl.mailbox_type = mailbox->mailbox_type;
788
789                                         /* Get the Alias Name after parsing the Full mailbox Path */
790                                         if(mailbox->alias == NULL)
791                                                 mailbox->alias = emcore_get_alias_of_mailbox((const char *)mailbox->mailbox_name);
792                                         
793                                         mailbox_tbl.alias = mailbox->alias;
794                                         mailbox_tbl.sync_with_server_yn  = 1;
795                                         mailbox_tbl.modifiable_yn = 1;
796                                         mailbox_tbl.total_mail_count_on_server = 0;
797                                         
798                                         /* if non synchronous, delete imap mailbox from db */
799                                         if (!emstorage_update_mailbox(mailbox->account_id, 0, downloaded_uids[temp].mailbox_id, &mailbox_tbl, true, &err)) {
800                                                 EM_DEBUG_EXCEPTION(" emstorage_update_mailbox Failed [ %d ] ", err);
801                                                 goto JOB_ERROR;
802                                         }
803                                         
804                                 }
805                                 else /* Its a Fresh Mailbox */ {
806                                         emstorage_mailbox_tbl_t mailbox_tbl;
807                                         mailbox_tbl.mailbox_id = mailbox->mailbox_id;
808                                         mailbox_tbl.account_id = mailbox->account_id;
809                                         mailbox_tbl.local_yn = 0; 
810                                         mailbox_tbl.mailbox_type = mailbox->mailbox_type;
811                                         mailbox_tbl.mailbox_name = mailbox->mailbox_name;
812                                         mailbox_tbl.mail_slot_size = mailbox->mail_slot_size;
813
814                                         /* Get the Alias Name after Parsing the Full mailbox Path */
815                                         if(mailbox->alias == NULL)
816                                         mailbox->alias = emcore_get_alias_of_mailbox((const char *)mailbox->mailbox_name);
817
818                                         if (mailbox->alias) {
819                                                 EM_DEBUG_LOG("mailbox->alias [%s] ", mailbox->alias);
820
821                                                 mailbox_tbl.alias = mailbox->alias;
822                                                 mailbox_tbl.sync_with_server_yn = 1;
823                                                 mailbox_tbl.modifiable_yn = 1; 
824                                                 mailbox_tbl.total_mail_count_on_server = 0;
825                                                         
826                                                 EM_DEBUG_LOG("mailbox_tbl.mailbox_type - %d", mailbox_tbl.mailbox_type);
827
828                                                 if (!emstorage_add_mailbox(&mailbox_tbl, true, &err)) {
829                                                         EM_DEBUG_EXCEPTION("emstorage_add_mailbox failed - %d", err);
830                                                         goto JOB_ERROR;
831                                                 }
832                                         }
833                                 }
834                         }
835                 }
836         }
837
838         /* set sync db mailbox */
839         mailbox->synchronous = synchronous;
840         
841         ret = true;
842         
843 JOB_ERROR:
844
845         if (downloaded_uids) 
846                 emstorage_free_read_mail_uid(&downloaded_uids, j, NULL);
847
848         if (imap_mailbox_tbl_item)
849                 emstorage_free_mailbox(&imap_mailbox_tbl_item, 1, NULL);
850
851         if (err_code)
852                 *err_code = err;
853         
854         return ret;
855 }
856
857 /* description
858  *    create a new imap mailbox
859  * arguments
860  *    new_mailbox  :  imap mailbox to be created
861  * return
862  *    succeed  :  1
863  *    fail  :  0
864  */
865 INTERNAL_FUNC int emcore_create_imap_mailbox(email_mailbox_t *mailbox, int *err_code)
866 {
867     MAILSTREAM *stream = NULL;
868     char *long_enc_path = NULL;
869     void *tmp_stream = NULL;
870     int ret = false;
871     int err = EMAIL_ERROR_NONE;
872
873     EM_DEBUG_FUNC_BEGIN();
874
875         if (err_code) {
876                 *err_code = EMAIL_ERROR_NONE;
877         }
878
879     if (!mailbox)
880     {
881         err = EMAIL_ERROR_INVALID_PARAM;
882         goto JOB_ERROR;
883     }
884
885     /* connect mail server */
886     stream = NULL;
887     if (!emcore_connect_to_remote_mailbox(mailbox->account_id, 0, (void **)&tmp_stream, NULL))
888     {
889         err = EMAIL_ERROR_CONNECTION_FAILURE;
890         goto JOB_ERROR;
891     }
892
893     stream = (MAILSTREAM *)tmp_stream;
894
895     /* encode mailbox name by UTF7, and rename to full path (ex : {mail.test.com}child_mailbox) */
896     if (!emcore_get_long_encoded_path(mailbox->account_id, mailbox->mailbox_name, '/', &long_enc_path, err_code))
897     {
898         err = EMAIL_ERROR_UNKNOWN;
899         goto JOB_ERROR;
900     }
901
902     /* create mailbox */
903     if (!mail_create(stream, long_enc_path))
904     {
905         err = EMAIL_ERROR_UNKNOWN;
906         goto JOB_ERROR;
907     }
908
909         emcore_close_mailbox(0, stream);                                
910         stream = NULL;
911
912     EM_SAFE_FREE(long_enc_path);
913
914     ret = true;
915
916 JOB_ERROR:
917     if (stream)
918     {
919                 emcore_close_mailbox(0, stream);                                
920                 stream = NULL;
921     }
922
923     EM_SAFE_FREE(long_enc_path);
924
925     if (err_code)
926         *err_code = err;
927
928     return ret;
929 }
930
931
932 /* description
933  *    delete a imap mailbox
934  * arguments
935  *    input_mailbox_id  :  mailbox ID to be deleted
936  * return
937  *    succeed  :  1
938  *    fail  :  0
939  */
940 INTERNAL_FUNC int emcore_delete_imap_mailbox(int input_mailbox_id, int *err_code)
941 {
942     MAILSTREAM *stream = NULL;
943     char *long_enc_path = NULL;
944     email_account_t *ref_account = NULL;
945     void *tmp_stream = NULL;
946     int ret = false;
947     int err = EMAIL_ERROR_NONE;
948         emstorage_mailbox_tbl_t *mailbox_tbl = NULL;
949
950     EM_DEBUG_FUNC_BEGIN();
951
952         if (err_code) {
953                 *err_code = EMAIL_ERROR_NONE;
954         }
955
956         if ((err = emstorage_get_mailbox_by_id(input_mailbox_id, &mailbox_tbl)) != EMAIL_ERROR_NONE || !mailbox_tbl) {
957                 EM_DEBUG_EXCEPTION("emstorage_get_mailbox_by_id failed. [%d]", err);
958                 goto JOB_ERROR;
959         }
960
961     ref_account = emcore_get_account_reference(mailbox_tbl->account_id);
962     if (!ref_account)
963     {
964         err = EMAIL_ERROR_INVALID_PARAM;
965         goto JOB_ERROR;
966     }
967
968     /* if not imap4 mail, return */
969     if (ref_account->incoming_server_type != EMAIL_SERVER_TYPE_IMAP4) {
970         err = EMAIL_ERROR_INVALID_PARAM;
971         goto JOB_ERROR;
972     }
973
974     /* connect mail server */
975     stream = NULL;
976     if (!emcore_connect_to_remote_mailbox(ref_account->account_id, 0, (void **)&tmp_stream, NULL))
977     {
978         err = EMAIL_ERROR_CONNECTION_FAILURE;
979         goto JOB_ERROR;
980     }
981
982     stream = (MAILSTREAM *)tmp_stream;
983
984     /* encode mailbox name by UTF7, and rename to full path (ex : {mail.test.com}child_mailbox) */
985     if (!emcore_get_long_encoded_path(mailbox_tbl->account_id, mailbox_tbl->mailbox_name, '/', &long_enc_path, err_code))
986     {
987         err = EMAIL_ERROR_UNKNOWN;
988         goto JOB_ERROR;
989     }
990
991     /* delete mailbox */
992     if (!mail_delete(stream, long_enc_path))
993     {
994         err = EMAIL_ERROR_UNKNOWN;
995         goto JOB_ERROR;
996     }
997
998         emcore_close_mailbox(0, stream);                                
999         stream = NULL;
1000
1001     EM_SAFE_FREE(long_enc_path);
1002
1003     /* if deleted imap mailbox is synchronous mailbox, delete db imap mailbox from db */
1004     if (!emstorage_delete_mailbox(ref_account->account_id, 0, input_mailbox_id, true, &err)) {
1005                 EM_DEBUG_EXCEPTION("\t emstorage_delete_mailbox failed - %d", err);
1006         goto JOB_ERROR;
1007     }
1008
1009     ret = true;
1010
1011 JOB_ERROR:
1012     if (stream)
1013     {
1014                 emcore_close_mailbox(0, stream);                                
1015                 stream = NULL;
1016     }
1017
1018     EM_SAFE_FREE(long_enc_path);
1019
1020     if (mailbox_tbl)
1021                 emstorage_free_mailbox(&mailbox_tbl, 1, NULL);
1022
1023     if (err_code)
1024         *err_code = err;
1025
1026     return ret;
1027 }
1028
1029
1030 INTERNAL_FUNC int emcore_move_mailbox_on_imap_server(int input_account_id, char *input_old_mailbox_path, char *input_new_mailbox_path)
1031 {
1032         EM_DEBUG_FUNC_BEGIN("input_account_id [%d], input_old_mailbox_path [%p], input_new_mailbox_path [%p]", input_account_id, input_old_mailbox_path, input_new_mailbox_path);
1033     MAILSTREAM *stream = NULL;
1034     char *long_enc_path_old = NULL;
1035     char *long_enc_path_new = NULL;
1036     email_account_t *ref_account = NULL;
1037     void *tmp_stream = NULL;
1038     int err = EMAIL_ERROR_NONE;
1039
1040     if (!input_old_mailbox_path || !input_new_mailbox_path) {
1041         EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
1042         err = EMAIL_ERROR_INVALID_PARAM;
1043         goto FINISH_OFF;
1044     }
1045
1046     ref_account = emcore_get_account_reference(input_account_id);
1047
1048     if (!ref_account || ref_account->incoming_server_type != EMAIL_SERVER_TYPE_IMAP4) {
1049         EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_ACCOUNT");
1050         err = EMAIL_ERROR_INVALID_ACCOUNT;
1051         goto FINISH_OFF;
1052     }
1053
1054     /* connect mail server */
1055     stream = NULL;
1056     if (!emcore_connect_to_remote_mailbox(input_account_id, 0, (void **)&tmp_stream, &err)) {
1057         EM_DEBUG_EXCEPTION("emcore_connect_to_remote_mailbox failed. [%d]", err);
1058         goto FINISH_OFF;
1059     }
1060
1061     stream = (MAILSTREAM *)tmp_stream;
1062
1063     /* encode mailbox name by UTF7, and rename to full path (ex : {mail.test.com}child_mailbox) */
1064     if (!emcore_get_long_encoded_path(input_account_id, input_old_mailbox_path, '/', &long_enc_path_old, &err)) {
1065         EM_DEBUG_EXCEPTION("emcore_get_long_encoded_path failed. [%d]", err);
1066         goto FINISH_OFF;
1067     }
1068
1069     /* encode mailbox name by UTF7, and rename to full path (ex : {mail.test.com}child_mailbox) */
1070     if (!emcore_get_long_encoded_path(input_account_id, input_new_mailbox_path, '/', &long_enc_path_new, &err)) {
1071         EM_DEBUG_EXCEPTION("emcore_get_long_encoded_path failed. [%d]", err);
1072         goto FINISH_OFF;
1073     }
1074
1075     /* rename mailbox */
1076     if (!mail_rename(stream, long_enc_path_old, long_enc_path_new)) {
1077         err = EMAIL_ERROR_UNKNOWN;
1078         goto FINISH_OFF;
1079     }
1080
1081 FINISH_OFF:
1082     EM_SAFE_FREE(long_enc_path_old);
1083     EM_SAFE_FREE(long_enc_path_new);
1084
1085     if (stream) {
1086                 emcore_close_mailbox(0, stream);                                
1087                 stream = NULL;
1088     }
1089
1090     EM_DEBUG_FUNC_END("err [%d]", err);
1091     return err;
1092 }