tizen beta release
[framework/messaging/email-service.git] / email-engine / emf-emn.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 #include <stdio.h>
24 #include <string.h>
25 #include <stdlib.h>
26 #include <time.h>
27 #include <stdarg.h>     /*  Needed for the definition of va_list */
28 #include <glib.h>
29
30 #include "emflib.h"
31
32 /* #include "emf-emn-storage.h" */
33 #include "emf-emn.h"
34
35 /* --------------------------------------------------------------------------------*/
36 /* ----- WBXML Parsing (2007.06.09) --------------------------------------------------*/
37 /* --------------------------------------------------------------------------------*/
38 #ifdef USE_OMA_EMN
39
40 #include <wbxml.h>
41 #include <wbxml_errors.h>
42 #include "emf-dbglog.h"
43 #include <vconf.h>
44 #include "emf-global.h"
45
46 typedef struct
47 {
48         int account_id;
49         emf_emn_noti_cb callback;
50         void* user_data;
51
52 emf_emn_noti_pack_t;
53
54
55 char*
56 __emn_get_username(char *account_username);
57 static void 
58 _cb_parser_start_document(void* ctx, WB_LONG charset, const WBXMLLangEntry* lang)
59 {
60     EM_DEBUG_LOG("_cb_parser_start_document\n");
61     EM_DEBUG_LOG("Parsing Document:\n\tRoot Element: %s\n\tPublic ID: %s\n\tDTD: %s\n",
62                  lang->publicID->xmlRootElt,
63                  lang->publicID->xmlPublicID,
64                  lang->publicID->xmlDTD);
65 }
66
67 static void 
68 _cb_parser_end_document(void* ctx)
69 {
70     EM_DEBUG_LOG("_cb_parser_end_document\n");
71 }
72
73 static void 
74 _cb_parser_start_element(void* ctx, WBXMLTag* element, WBXMLAttribute** atts, WB_BOOL empty)
75 {
76     WB_UTINY* p, **pp = ctx;
77     WB_ULONG j = 0, len = 0;
78     EM_DEBUG_LOG("parse_clb_start_element\n");
79
80     if (strcasecmp((char *)wbxml_tag_get_xml_name(element), "emn") != 0)
81     {
82         EM_DEBUG_LOG("not email notification\n");
83         return ;
84     }
85
86     if (atts == NULL)
87     {
88         EM_DEBUG_LOG("no emn attributes\n");
89         return ;
90     }
91
92     len = strlen((char *)wbxml_tag_get_xml_name(element)) + 1;
93     while (atts[j] != NULL)
94     {
95         len += (strlen((char *)wbxml_attribute_get_xml_name(atts[j])) + strlen((char *)wbxml_attribute_get_xml_value(atts[j])) + 7);
96         j++;
97     }
98     len += 3;
99
100     if (!(p = malloc(sizeof(WB_UTINY) * len + 1)))
101     {
102         return ;
103     }
104
105     EM_DEBUG_LOG("<%s", (char *)wbxml_tag_get_xml_name(element));
106     sprintf((char *)p, "<%s", (char *)wbxml_tag_get_xml_name(element));
107
108     j = 0;
109     while (atts[j] != NULL)
110     {
111         EM_DEBUG_LOG(" %s=\"%s\"", (char *)wbxml_attribute_get_xml_name(atts[j]), (char *)wbxml_attribute_get_xml_value(atts[j]));
112         strcat((char *)p, " ");
113         strcat((char *)p, (char *)wbxml_attribute_get_xml_name(atts[j]));
114         strcat((char *)p, "=");
115         strcat((char *)p, "\"");
116         strcat((char *)p, (char *)wbxml_attribute_get_xml_value(atts[j]));
117         strcat((char *)p, "\"");
118         j++;
119     }
120
121     if (empty)
122     {
123         EM_DEBUG_LOG("/>\n");
124         strcat((char *)p, "/>");
125     }
126     else
127     {
128         EM_DEBUG_LOG(">\n");
129         strcat((char *)p, ">");
130     }
131
132     *pp = p;
133 }
134
135 static void 
136 _cb_parser_end_element(void* ctx, WBXMLTag* element, WB_BOOL empty)
137 {
138     EM_DEBUG_LOG("parse_clb_end_element\n");
139 }
140
141 static void 
142 _cb_parser_characters(void* ctx, WB_UTINY* ch, WB_ULONG start, WB_ULONG length)
143 {
144     EM_DEBUG_LOG("_cb_parser_characters\n");
145 }
146
147 static int _get_addr_from_element(unsigned char* elm,
148                                                 int* type,
149                                                 unsigned char** user_name,
150                                                 unsigned char** host_addr,
151                                                 unsigned char** mbox_name,
152                                                 unsigned char** auth_type)
153 {
154     unsigned char*      p;
155     unsigned char*      s;
156     unsigned char*      user = NULL;
157     unsigned char*      host = NULL;
158     unsigned char*      mbox = NULL;
159     unsigned char*      auth = NULL;
160     
161      EM_DEBUG_FUNC_BEGIN();
162          
163     if (!(p = (unsigned char*)strstr((char *)elm, "mailbox")))  /*  add acetrack.20080331.K8.4043 */
164     {
165         EM_DEBUG_EXCEPTION("invalid notification data\n");
166         return 0;
167     }
168
169     p += 9;
170     s = (unsigned char*)strchr((char *)p, '\"');
171     /*  2007-05-08 by acetrack */
172     if (s)
173       *s = '\0';
174         
175     switch (p[0])
176     {
177     case 'm':/*  mailat (RFC2234) */
178         *type = 1;
179         p += 7;
180         if (!(s = (unsigned char*)strchr((char *)p, '@'))) return 0;
181         *s = '\0';
182         user = (unsigned char*)EM_SAFE_STRDUP((char *)p);
183         s++;
184         host = (unsigned char*)EM_SAFE_STRDUP((char *)s);
185           mbox = NULL;
186         auth = NULL;
187         break;
188
189     case 'p':/*  pop3 (RFC2384) */
190         *type = 2;
191         p += 6;
192         if ((s = (unsigned char*)strchr((char *)p, ';')))
193         {
194             *s = '\0';
195             if (strlen((char *)p)) user = (unsigned char*)EM_SAFE_STRDUP((char *)p);
196             p = s + 1;
197         }
198         if ((s = (unsigned char*)strchr((char *)p, '@')))
199         {
200             *s = '\0';
201             if (user || *(p - 3) == '/')
202             {
203                 if (strncmp((char *)p, "AUTH=", 5) == 0) auth = (unsigned char*)EM_SAFE_STRDUP((char *)p + 5);
204             }
205             else
206                 user = (unsigned char*)EM_SAFE_STRDUP((char *)p);
207             p = s + 1;
208         }
209         if ((s = (unsigned char*)strchr((char *)p, ':')))
210         {
211             *s = '\0';
212             s++;
213             EM_DEBUG_LOG("PORT:%s\n", s);
214         }
215         host = (unsigned char*)EM_SAFE_STRDUP((char *)p);
216         mbox = NULL;
217         break;
218
219     case 'i':/*  imap (RFC2192) */
220         *type = 3;
221         p += 7;
222         if ((s = (unsigned char*)strchr((char *)p, ';')))
223         {
224             *s = '\0';
225             if (strlen((char *)p)) user = (unsigned char*)EM_SAFE_STRDUP((char *)p);
226             p = s + 1;
227         }
228         if ((s = (unsigned char*)strchr((char *)p, '@')))
229         {
230             *s = '\0';
231             if (user || *(p - 3) == '/')
232             {
233                 if (strncmp((char *)p, "AUTH=", 5) == 0) auth = (unsigned char*)EM_SAFE_STRDUP((char *)p + 5);
234             }
235             else
236                 user = (unsigned char*)EM_SAFE_STRDUP((char *)p);
237             p = s + 1;
238         }
239
240         if ((s = (unsigned char *)strchr((char *)p, '/'))) * s = '\0';
241         host = (unsigned char *)EM_SAFE_STRDUP((char *)p);
242         p = s + 1;
243
244         if ((s = (unsigned char*)strchr((char *)p, '?'))) * s = '\0';
245         else if ((s = (unsigned char*)strchr((char *)p, ';'))) * s = '\0';
246         else s = p + strlen((char *)p);
247         if (*(s - 1) == '/') *(s - 1) = '\0';
248
249         if (strlen((char *)p)) mbox =(unsigned char*) EM_SAFE_STRDUP((char *)p);
250         break;
251
252     case 'h': /*  not supported */
253         EM_DEBUG_LOG("Http URI is not yet supported\n");
254         return 0;
255         
256     default:
257         return 0;
258     }
259
260     *user_name = user;
261     *host_addr = host;
262     *mbox_name = mbox;
263     *auth_type = auth;
264
265     return 1;
266 }
267
268 static int      
269 _get_time_from_element(unsigned char* elm,
270                           unsigned char** time_stamp)
271 {
272     EM_DEBUG_FUNC_BEGIN();
273
274     unsigned char* p, *s, *stamp = NULL;
275     if (!(p = (unsigned char*)strstr((char *)elm, "timestamp")))
276     {
277         EM_DEBUG_EXCEPTION("invalid notification data\n");
278         return 0;
279     }
280
281     p += 11;
282     s = (unsigned char*)strchr((char *)p, '\"');
283     /*  2007-05-08 by acetrack */
284     if (s)
285         *s = '\0';
286
287     stamp = malloc(15);
288     if (!stamp) /*  added acetrack.20080331.K8.4045 */
289     {
290         EM_DEBUG_EXCEPTION("malloc failed");
291         return 0;
292     }
293     memcpy(stamp, p, 4);
294     memcpy(stamp + 4, p + 5, 2);
295     memcpy(stamp + 6, p + 8, 2);
296     memcpy(stamp + 8, p + 11, 2);
297     memcpy(stamp + 10, p + 14, 2);
298     memcpy(stamp + 12, p + 17, 2);
299     stamp[14] = '\0';
300
301     *time_stamp = stamp;
302
303     return 1;
304 }
305
306 /*  <emn mailbox="mailat:user@wapforum.org" timestamp="2002-04-16T06:40:00Z"/> */
307 static int _get_data_from_element(unsigned char* elm,
308                           int* type,
309                           unsigned char** user_name,
310                           unsigned char** host_addr,
311                           unsigned char** mbox_name,
312                           unsigned char** auth_type,
313                           unsigned char** time_stamp)
314 {
315
316     EM_DEBUG_FUNC_BEGIN();
317     if (!_get_time_from_element(elm, time_stamp))
318     {
319         return 0;
320         }
321
322     /*  must call get_addr_from_element after calling _get_time_from_element */
323     if (!_get_addr_from_element(elm, type, user_name, host_addr, mbox_name, auth_type))
324     {
325             EM_SAFE_FREE*time_stamp)    /*  added acetrack.20080331.K8.4046 */
326             return 0;
327     }
328
329     return 1;
330 }
331
332 /* Parse the Email address to Get the user Name for the account [deepam.p@samsung.com] */
333 char*
334 __emn_get_username(char *account_username)
335 {
336
337         EM_IF_NULL_RETURN_VALUE(account_username, NULL);
338
339         int index = 0;
340         char **token_list = NULL;
341         char *username = NULL, *name = NULL;
342
343         username = g_strdup(account_username);
344         token_list = g_strsplit_set(username, "@", -1);
345
346         if (username) {
347                 g_free(username);
348         }
349
350         if (token_list[index] != NULL)
351     {
352                 name = g_strdup(token_list[index]);
353                 g_strfreev(token_list); /*  MUST BE. */
354                 EM_DEBUG_LOG("ACCOUNT USER NAME [%s] \n", name);
355                 return name;
356         }
357         else
358                 return NULL;
359         
360 }
361
362 /* description
363  *    get account from OMA EMN data
364  * arguments
365  *    wbxml_b64 : BASE64 encoded data
366  *    account_id: id of account to be retrieved from EMN data
367  *    mailbox   : if mail-box information exists in EMN data, mailbox holds the name of mailbox.
368  *    err_code  : hold error code
369  * return
370  *    succeed : 1
371  *    fail : 0
372  */
373 static int
374 _get_emn_account(unsigned char* wbxml_b64, emf_account_t* account, char** mailbox, int* err_code)
375 {
376         EM_DEBUG_LOG("_get_emn_account Enter");
377     WBXMLContentHandler parse_handler = {
378                                             (WBXMLStartDocumentHandler) _cb_parser_start_document,
379                                             (WBXMLEndDocumentHandler) _cb_parser_end_document,
380                                             (WBXMLStartElementHandler) _cb_parser_start_element,
381                                             (WBXMLEndElementHandler) _cb_parser_end_element,
382                                             (WBXMLCharactersHandler) _cb_parser_characters,
383                                             NULL
384                                         };
385
386     WBXMLParser*        wbxml_parser = NULL;
387     WB_UTINY*           wbxml = NULL;
388     WB_UTINY*           elm = NULL;
389     WB_ULONG            wbxml_len = 0;
390     WB_ULONG            err_idx = 0;
391     WBXMLError          ret = WBXML_OK;
392     emf_account_t*      accounts = NULL;
393     unsigned char*      user_name = NULL;
394     unsigned char*      host_addr = NULL;
395     unsigned char*      mbox_name = NULL;
396     unsigned char*      auth_type = NULL;
397     unsigned char*      time_stamp = NULL;
398     int                         type = 0;
399     int                         i = 0;
400     int                         count = 0;
401     int                         retr = false;
402     int                         err = EMF_ERROR_NONE;
403
404     EM_DEBUG_LOG("");
405
406     if (!wbxml_b64 || !account)
407     {
408          EM_DEBUG_EXCEPTION(">>>> Invalid Parameter >>>> \n");
409         err = EMF_ERROR_INVALID_PARAM;
410         goto FINISH_OFF;
411     }
412
413     wbxml = g_base64_decode((const char*)wbxml_b64, (unsigned int*)&wbxml_len);
414     EM_DEBUG_LOG("wbxml = %p\n", wbxml);
415     EM_DEBUG_LOG("wbxml_len = %d\n", wbxml_len);
416
417     /*  create wbxml parser */
418     if (!(wbxml_parser = wbxml_parser_create()))
419     {
420         err = EMF_ERROR_OUT_OF_MEMORY;          
421         goto FINISH_OFF;
422     }
423
424     /*  initialize wbxml parser */
425     wbxml_parser_set_user_data(wbxml_parser, (void*)&elm);
426     wbxml_parser_set_content_handler(wbxml_parser, &parse_handler);
427
428     /*  parsing wbxml */
429     if ((ret = wbxml_parser_parse(wbxml_parser, wbxml, wbxml_len)) != WBXML_OK)
430     {
431         err_idx = wbxml_parser_get_current_byte_index(wbxml_parser);
432         EM_DEBUG_LOG("Parsing failed at %u - Token %x - %s", err_idx, wbxml[err_idx], wbxml_errors_string(ret));
433                 
434         err = EMF_ERROR_XML_PARSER_FAILURE;             
435         goto FINISH_OFF;
436     }
437     else
438     {
439         EM_DEBUG_LOG("Parsing OK !\n");
440     }
441
442     /*  destroy parser */
443     wbxml_parser_destroy(wbxml_parser);
444     wbxml_parser = NULL;
445
446     /*  free buffer */
447     wbxml_free(wbxml);
448     wbxml = NULL;
449
450     if (!elm)
451     {
452         EM_DEBUG_EXCEPTION("invalid elements\n");
453                 
454         err = EMF_ERROR_XML_PARSER_FAILURE;             
455         goto FINISH_OFF;
456     }
457
458     EM_DEBUG_LOG("elements = [%s]\n", elm);
459     _get_data_from_element(elm, &type, &user_name, &host_addr, &mbox_name, &auth_type, &time_stamp);
460
461     EM_SAFE_FREE(elm);
462
463     EM_DEBUG_LOG("user_type = [%d]\n", type);
464     EM_DEBUG_LOG("user_name = [%s]\n", (char *)user_name ? (char*)user_name : "NIL");
465     EM_DEBUG_LOG("host_addr = [%s]\n", (char *)host_addr ? (char*)host_addr : "NIL");
466     EM_DEBUG_LOG("mbox_name = [%s]\n", (char *)mbox_name ? (char*)mbox_name : "NIL");
467     EM_DEBUG_LOG("auth_type = [%s]\n", (char *)auth_type ? (char*)auth_type : "NIL");
468     EM_DEBUG_LOG("time_stamp= [%s]\n", (char *)time_stamp? (char*)time_stamp: "NIL");
469
470      if (!emf_account_get_list(&accounts, &count, &err))
471     {
472         EM_DEBUG_EXCEPTION("   emf_account_get_list error");
473         err = EMF_ERROR_DB_FAILURE;
474         goto FINISH_OFF;
475     }
476         
477     for (i = 0; i < count; i++)
478     {
479         /* sowmya.kr, 201009, Fix for EMN */
480         char* temp_account_name = NULL;
481                 char *s = NULL;
482             /*  EM_DEBUG_LOG(">>>> Account Information UserName [ %s ] Email Addr [ %s], Account ID [ %d] >>> \n",accounts[i].user_name,accounts[i].email_addr, accounts[i].account_id); */
483                 temp_account_name =(char*) EM_SAFE_STRDUP((char *)accounts[i].user_name);
484
485                 if ((s = (char*)strchr((char *)temp_account_name, '@')))  {
486                         *s = '\0';
487                         EM_SAFE_FREE(accounts[i].user_name);                    
488                         accounts[i].user_name  = (char*)EM_SAFE_STRDUP((char *)temp_account_name);                      
489                 }
490                 EM_SAFE_FREE(temp_account_name);
491                 if (user_name)  {       
492                         if (strcmp(accounts[i].user_name, (char *)user_name) == 0 &&
493                                 strstr(accounts[i].email_addr, (char *)host_addr)) {
494                                 EM_DEBUG_LOG(">>>> Account Match >>> \n");
495                                 if ((type == 1) ||
496                                         (type == 2 && accounts[i].receiving_server_type == EMF_SERVER_TYPE_POP3) ||
497                                         (type == 3 && accounts[i].receiving_server_type == EMF_SERVER_TYPE_IMAP4)) {
498                                         accounts[i].flag2 = type;
499                                         EM_DEBUG_LOG("found target account id[%d] name[%s]", accounts[i].account_id, accounts[i].user_name);
500                                         break;
501                                 }
502                         }
503                 }
504         }
505
506         if (i >= count) {
507                 EM_DEBUG_EXCEPTION("no account was found");
508                 err = EMF_ERROR_ACCOUNT_NOT_FOUND;
509                 goto FINISH_OFF;
510         }
511         if (account) {
512                 account->account_bind_type = accounts[i].account_bind_type;
513                 account->account_id = accounts[i].account_id;
514                 account->flag2 = accounts[i].flag2;
515         }
516     
517     if (mailbox)
518     {
519         *mailbox = mbox_name ? (char *)mbox_name : NULL;
520         mbox_name = NULL;
521     }
522     emf_account_free(&accounts, count, NULL);
523     accounts = NULL;
524
525     retr = true;
526
527 FINISH_OFF:
528     if (wbxml) wbxml_free(wbxml);
529     if (wbxml_parser) wbxml_parser_destroy(wbxml_parser);
530     EM_SAFE_FREE(elm);
531     if (accounts) emf_account_free(&accounts, count, NULL);
532     EM_SAFE_FREE(user_name);
533     EM_SAFE_FREE(mbox_name);
534     EM_SAFE_FREE(auth_type);
535     EM_SAFE_FREE(time_stamp);
536     if (err_code) *err_code = err;
537     return retr;
538 }
539
540 EXPORT_API int emf_emn_handler(unsigned char* wbxml_b64, emf_emn_noti_cb callback, int* err_code)
541 {
542         EM_DEBUG_FUNC_BEGIN("wbxml_b64[%p], callback[%p], err_code[%p]", wbxml_b64, callback, err_code);
543         
544         int ret = false;
545         int err = EMF_ERROR_NONE;;
546         char* mailbox_name = NULL;
547         emf_mailbox_t mailbox = { 0 };
548         emf_account_t account = { 0 };
549         emf_emn_noti_pack_t* pack = NULL;
550         char* pmailbox = NULL;
551         
552         if (!wbxml_b64) {
553                 EM_DEBUG_EXCEPTION("EMF_ERROR_INVALID_PARAM");
554                 err = EMF_ERROR_INVALID_PARAM;
555                 goto FINISH_OFF;
556         }
557         
558         pack = (emf_emn_noti_pack_t*)em_core_malloc(sizeof(emf_emn_noti_pack_t));
559         if (!pack) {
560                 EM_DEBUG_EXCEPTION("em_core_malloc failed");
561                 err = EMF_ERROR_OUT_OF_MEMORY;
562                 goto FINISH_OFF;
563         }
564         
565         if (!_get_emn_account(wbxml_b64, &account, &mailbox_name, &err)) {
566                 EM_DEBUG_EXCEPTION("_get_emn_account failed [%d]", err);
567                 goto FINISH_OFF;
568         }
569
570         mailbox.account_id = account.account_id;
571
572         if (!em_storage_get_mailboxname_by_mailbox_type(mailbox.account_id,EMF_MAILBOX_TYPE_INBOX,&pmailbox, false, &err))  {
573                 EM_DEBUG_EXCEPTION("em_storage_get_mailboxname_by_mailbox_type failed [%d", err);               
574                 err = em_storage_get_emf_error_from_em_storage_error(err);
575                 goto FINISH_OFF;
576         }
577
578         if ((account.receiving_server_type == EMF_SERVER_TYPE_IMAP4) && (account.flag2 == 3))  {
579
580                 if (!mailbox_name || strncmp(pmailbox, mailbox_name, strlen(pmailbox)) != 0)  {
581                         EM_DEBUG_EXCEPTION("invalid inbox name [%p]", mailbox_name);
582                         err = EMF_ERROR_INVALID_MAILBOX;
583                         goto FINISH_OFF;
584                 }
585         }
586         
587         /* sync header with mail server */
588         mailbox.name = mailbox_tbl->mailbox_name;
589         
590         if (!emf_mailbox_sync_header(&mailbox, NULL, &err))  {
591                 EM_DEBUG_EXCEPTION("emf_mailbox_sync_header falied [%d]", err);
592                 goto FINISH_OFF;
593         }
594         
595         ret = true;
596         
597 FINISH_OFF:
598         if (ret == false) 
599                 EM_SAFE_FREE(pack);
600
601         EM_SAFE_FREE(pmailbox);
602
603         if (err_code != NULL)
604                 *err_code = err;
605         
606         return ret;
607 }
608
609
610 #endif /*  USE_OMA_EMN */
611
612 /* EOF */