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