2.0_alpha release commit
[framework/messaging/email-service.git] / email-core / email-core-mime.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-mime.c
26  *Desc :  MIME Operation
27  *
28  *Auth :
29  *
30  *History :
31  *   2011.04.14  :  created
32  ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ***/
33 #undef close
34
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <string.h>
38 #include <vconf.h>
39 #include <ctype.h>
40 #include <sys/stat.h>
41 #include <sys/time.h>
42 #include "email-internal-types.h"
43 #include "lnx_inc.h"
44 #include "email-utilities.h"
45 #include "email-core-global.h"
46 #include "email-core-utils.h"
47 #include "email-core-mail.h"
48 #include "email-core-mime.h"
49 #include "email-storage.h"
50 #include "email-core-event.h"
51 #include "email-core-account.h" 
52 #include "email-debug-log.h"
53
54 #define MIME_MESG_IS_SOCKET
55
56 #define MIME_LINE_LEN   1024
57 #define BOUNDARY_LEN    256
58
59 #define TYPE_TEXT            1
60 #define TYPE_IMAGE           2
61 #define TYPE_AUDIO           3
62 #define TYPE_VIDEO           4
63 #define TYPE_APPLICATION     5
64 #define TYPE_MULTIPART       6
65 #define TYPE_MESSAGE         7
66 #define TYPE_UNKNOWN         8
67
68 #define TEXT_STR             "TEXT"
69 #define IMAGE_STR            "IMAGE"
70 #define AUDIO_STR            "AUDIO"
71 #define VIDEO_STR            "VIDEO"
72 #define APPLICATION_STR      "APPLICATION"
73 #define MULTIPART_STR        "MULTIPART"
74 #define MESSAGE_STR          "MESSAGE"
75
76 #define CONTENT_TYPE         1
77 #define CONTENT_SUBTYPE      2
78 #define CONTENT_ENCODING     3
79 #define CONTENT_CHARSET      4
80 #define CONTENT_DISPOSITION  5
81 #define CONTENT_NAME         6
82 #define CONTENT_FILENAME     7
83 #define CONTENT_BOUNDARY     8
84 #define CONTENT_REPORT_TYPE  9
85 #define CONTENT_ID           10
86 #define CONTENT_LOCATION     11
87
88 #define GRAB_TYPE_TEXT       1  /*  retrieve text and attachment name */
89 #define GRAB_TYPE_ATTACHMENT 2  /*  retrieve only attachmen */
90
91 #define SAVE_TYPE_SIZE       1  /*  only get content siz */
92 #define SAVE_TYPE_BUFFER     2  /*  save content to buffe */
93 #define SAVE_TYPE_FILE       3  /*  save content to temporary fil */
94
95 #define EML_FOLDER           20 /*  save eml content to temporary folder */
96
97 /*
98         MIME Structure Example
99
100         (part 0)        multipart/mixed
101         (part 1)                multipart/alternative
102         (part 1.1)                      text/plain              <- text message
103         (part 1.2)                      text/html               <- html message
104         (part 2)                text/plain                      <- text attachment
105
106
107         (part 0)        multipart/related
108         (part 1)                multipart/alternative 
109         (part 1.1)                      text/plain                      <- text message  
110         (part 1.2)                      text/html                       <- html message  
111         (part 2)                image/png                               <- inline image
112         (part 2)                image/png                               <- inline image
113
114         
115         (part 0)        multipart/mixed
116         (part 1.1)              multipart/related   
117         (part 2.1)                      multipart/alternative 
118         (part 3.1)                              text/plain(body)  <- text message
119         (part 3.2)                              text/html(body) <- html message
120         (part 2.2)                      image/png(related)      <- inline image 
121         (part 1.2)              image/png(attachment)   <- image attachment
122 */
123
124 /*  Text and Attachment Holde */
125 /* struct _m_content_info  */
126 /*      int grab_type;  */              /*  1 :  text and attachment list */
127                                                 /*  2 :  attachmen */
128 /*      int file_no; */                 /*  attachment sequence to be downloaded (min : 1 */
129 /*      struct text_data  */
130 /*              char *plain;    */      /*  body plain tex */
131 /*              char *plain_charset */ /*  charset of plai */
132 /*              char *html; */ /*  body html tex */
133 /*      } text */
134
135 /*      struct attachment_info  */
136 /*              int   type;     */              /*  1 : inline 2 : attachmen */
137 /*              char *name;     */              /*  attachment filenam */
138 /*              int   size;             */      /*  attachment siz */
139 /*              char *save;     */              /*  content saving filenam */
140 /*              struct attachment_info *next */
141 /*      } *file */
142 /* } */
143
144 /* --------------------- MIME Structure --------------------------------- */
145 /*  MIME Header Parameter (Content-Type, Content-Disposition, ... */
146 struct _parameter {
147         char                            *name;                  /*  parameter name */
148         char                            *value;                 /*  parameter valu */
149         struct _parameter       *next;                  /*  next paramete */
150 };
151
152 /*  Content-Dispositio */
153 struct _disposition {
154         char                            *type;                  /*  "inline" "attachment */
155         struct _parameter       *parameter;             /*  "filename", .. */
156 };
157
158 /*  RFC822 Heade */
159 struct _rfc822header {
160         char                            *return_path;   /*  error return pat */
161         char                            *received;
162         char                            *date;
163         char                            *from;
164         char                            *subject;
165         char                            *sender;
166         char                            *to;
167         char                            *cc;
168         char                            *bcc;
169         char                            *reply_to;
170         char                            *priority;
171         char                            *ms_priority;
172         char                            *dsp_noti_to;
173         char                            *others;
174 };
175
176 /*  MIME Part Header */
177 struct _m_part_header {
178         char                            *type;                  /*  text, image, audio, video, application, multipart, message */
179         char                            *subtype;               /*  plain, html, jpeg, .. */
180         char                            *encoding;              /*  encoding typ */
181         struct _parameter       *parameter;             /*  content-type parameter  :  "boundary" "charset" .. */
182         char                            *desc;                  /*  descriptio */
183         char                            *disp_type;             /*  disposition type  :  "inline" "attachment", */
184         struct _parameter       *disp_parameter;    /*  disposition parameter  :  "filename", .. */
185         char                            *content_id;    /*  content id  :  it is inline  */
186         char                            *content_location;      /*  content location  :  "inline" location  */
187 }; 
188
189 /*  MIME Message Header */
190 struct _m_mesg_header {
191         char                            *version;               /*  MIME Versio */
192         struct _m_part_header  *part_header;    /*  MIME Part Heade */
193 }; 
194
195 /*  MIME Multipart Body linked list */
196 typedef struct _m_body _m_body_t;
197 struct _m_part{
198         _m_body_t                       *body;                  /*  part bod */
199         struct _m_part          *next;                  /*  the next found par */
200 };
201
202 /*  MIME Multipart Body */
203 struct _m_body {
204         struct _m_part_header *part_header;     /*  MIME Part Heade */
205         struct _m_part                  nested;                 /*  nested structure if contain multipar */
206         char                            *text;                  /*  text if not contain multipar */
207         int                                             size;                   /*  text size if not contain multipar */
208         char                            *holdingfile;
209 };
210
211 /*  MIME Message */
212 struct _m_mesg {
213         struct _rfc822header  *rfc822header;    /*  RFC822 Heade */
214         struct _m_mesg_header *header;                  /*  MIME Message Heade */
215         struct _m_part          nested;                 /*  nested structure if contain multipar */
216         char                            *text;                  /*  text if not contain multipar */
217         int                                             size;                   /*  text size if not contain multipar */
218 };
219 /* ---------------------------------------------------------------------- */
220 /*  Global variable */
221 static bool next_decode_string = false;
222 static int  eml_data_count = 0;
223
224 /* ---------------------------------------------------------------------- */
225 /*  External variable */
226 extern int _pop3_receiving_mail_id;
227 extern int _pop3_received_body_size;
228 extern int _pop3_last_notified_body_size;
229 extern int _pop3_total_body_size;
230
231 extern int _imap4_received_body_size;
232 extern int _imap4_last_notified_body_size;
233 extern int _imap4_total_body_size;
234 extern int _imap4_download_noti_interval_value;
235
236 extern int multi_part_body_size;
237 extern bool only_body_download;
238
239 extern BODY **g_inline_list;
240 extern int g_inline_count;
241
242 /* ---------------------------------------------------------------------- */
243 /*  Function Declaration */
244
245 /*  parsing the first header (RFC822 Header and Message Header and Etc... */
246 static int emcore_mime_parse_header(void *stream, int is_file, struct _rfc822header **rfcheader, struct _m_mesg_header **header, int *err_code);
247
248 /*  parsing the first bod */
249 static int emcore_mime_parse_body(void *stream, int is_file, struct _m_mesg *mmsg, struct _m_content_info *cnt_info, void *callback, int *err_code);
250
251 /*  parsing the message part header (CONTENT-... header */
252 static int emcore_mime_parse_part_header(void *stream, int is_file, struct _m_part_header **header, int *err_code);
253
254 /*  parsing the message part by boundar */
255 static int emcore_mime_parse_part(void *stream, int is_file, struct _m_part_header *parent_header, struct _m_part *nested, struct _m_content_info *cnt_info, int *end_of_parsing, int *err_code);
256
257 /*  set RFC822 Header valu */
258 static int emcore_mime_set_rfc822_header_value(struct _rfc822header **rfc822header, char *name, char *value, int *err_code);
259
260 /*  set Message Part Header (Content-... Header */
261 static int emcore_mime_set_part_header_value(struct _m_part_header **header, char *name, char *value, int *err_code);
262
263 static int emcore_mime_get_param_from_str(char *str, struct _parameter **param, int *err_code);
264
265 static int emcore_mime_add_param_to_list(struct _parameter **param_list, struct _parameter *param, int *err_code);
266
267 char *emcore_mime_get_header_value(struct _m_part_header *header, int type, int *err_code);
268
269 void emcore_mime_free_param(struct _parameter *param);
270 void emcore_mime_free_part_header(struct _m_part_header *header);
271 void emcore_mime_free_message_header(struct _m_mesg_header *header);
272 void emcore_mime_free_rfc822_header(struct _rfc822header *rfc822header);
273 void emcore_mime_free_part(struct _m_part *part);
274 void emcore_mime_free_part_body(struct _m_body *body);
275 void emcore_mime_free_mime(struct _m_mesg *mmsg);
276 char *emcore_mime_get_line_from_sock(void *stream, char *buf, int size, int *err_code); 
277 char *emcore_mime_get_save_file_name(int *err_code);
278
279 /*  get content data and save buffer or fil */
280 /*  mode - 1 :  get the only siz */
281 /*         2 :  save content to buffer (holder is buffer */
282 /*         3 :  save content to file (holder is file name */
283 static int emcore_mime_get_content_data(void *stream, 
284                                         int  is_file, 
285                        int   is_text, 
286                                         char *boundary_str, 
287                                         char *content_encoding, 
288                                         int *end_of_parsing,
289                                         int   mode,     
290                                         char **holder, 
291                                         int *size,
292                                         void *callback, 
293                                         int *err_code);
294 /*  skip content data to boundary_str or end of fil */
295 int emcore_mime_skip_content_data(void *stream, 
296                                                         int is_file, 
297                                                         char *boundary_str, 
298                                                         int *end_of_parsing, 
299                                                         int *size, 
300                                                         void *callback, 
301                                                         int *err_code);
302
303 static int emcore_get_file_pointer(BODY *body, bool input_check_duplicated_file_name, char *buf, struct _m_content_info *cnt_info , int *err);
304 static PARTLIST *emcore_get_body_full(MAILSTREAM *stream, int msg_uid, BODY *body, struct _m_content_info *cnt_info, int *err_code, PARTLIST *section_list);
305 static int emcore_get_body_part_imap_full(MAILSTREAM *stream, int msg_uid, int account_id, int mail_id, PARTLIST *section_list, struct _m_content_info *cnt_info, int *err_code, int event_handle);
306 static PARTLIST *emcore_add_node(PARTLIST *section_list, BODY *body);
307 static void emcore_free_section_list(PARTLIST *section_list);
308 static int emcore_get_section_body_size(char *response, char *section, int *body_size);
309 static void parse_file_path_to_filename(char *src_string, char **out_string);
310 extern long pop3_reply (MAILSTREAM *stream);
311 /* ------------------------------------------------------------------------------------------------- */
312
313
314 /* Fix for issue junk characters in mail body */
315 char *em_split_file_path(char *str)
316 {
317         EM_DEBUG_FUNC_BEGIN("str [%s]", str);
318
319         EM_IF_NULL_RETURN_VALUE(str, NULL);
320
321         char *buf = NULL;
322         char delims[] = "@";
323         char *result = NULL;
324         char *temp_str = NULL;
325         char *content_id = NULL;
326         int buf_length = 0;
327         char *temp_cid_data = NULL;
328         char *temp_cid = NULL;
329         temp_str = EM_SAFE_STRDUP(str);
330         buf_length = strlen(str) + 1024;
331         buf = em_malloc(buf_length);
332         content_id = temp_str;
333         temp_cid = strstr(temp_str, "\"");
334
335         if (temp_cid == NULL) {
336                 EM_DEBUG_EXCEPTION(">>>> File Path Doesnot contain end line for CID ");
337                 next_decode_string = true;
338                 EM_SAFE_FREE(buf); 
339                 return temp_str;
340         }
341         temp_cid_data = em_malloc((temp_cid-temp_str)+1);
342         memcpy(temp_cid_data, temp_str, (temp_cid-temp_str));
343
344         if (!strstr(temp_cid_data, delims)) {
345                 EM_DEBUG_EXCEPTION(">>>> File Path Doesnot contain @ ");
346                 next_decode_string = true;
347                 EM_SAFE_FREE(buf);
348                 EM_SAFE_FREE(temp_cid_data);
349                 return temp_str;
350         }
351         else            {
352                 result = strstr(temp_str, delims);
353                 if (result != NULL) {
354                         next_decode_string = false;
355                         *result = '\0';
356                         result++;
357                         EM_DEBUG_LOG("content_id is [ %s ]", content_id);
358
359                         if (strcasestr(content_id, ".bmp") || strcasestr(content_id, ".jpeg") || strcasestr(content_id, ".png") || 
360                                         strcasestr(content_id, ".jpg") || strcasestr(content_id, ".gif"))
361                                 snprintf(buf+strlen(buf), buf_length - strlen(buf), "%s\"", content_id);
362                         else
363                                 snprintf(buf+strlen(buf), buf_length - strlen(buf), "%s%s", content_id, ".jpeg\"");
364                 }
365                 else {
366                         EM_DEBUG_EXCEPTION(">>>> File Path Doesnot contain end line for CID ");
367                         next_decode_string = true;
368                         EM_SAFE_FREE(buf);
369                         EM_SAFE_FREE(temp_cid_data);
370                         return temp_str;
371                 }
372                 result = strstr(result, "\"");
373                 if (result != NULL) {
374                         result++;
375                         snprintf(buf+strlen(buf), buf_length - strlen(buf), "%s", result);
376                 }
377         }
378         EM_SAFE_FREE(temp_str);
379         EM_SAFE_FREE(temp_cid_data);
380         return buf;
381 }
382
383
384 static char *em_replace_string_with_split_file_path(char *source_string, char *old_string, char *new_string)
385 {
386         EM_DEBUG_FUNC_BEGIN();
387         char *buffer = NULL;
388         char *split_str = NULL;
389         char *p = NULL;
390         char *q = NULL;
391         int   buf_len = 0;
392
393         EM_IF_NULL_RETURN_VALUE(source_string, NULL);
394         EM_IF_NULL_RETURN_VALUE(old_string, NULL);
395         EM_IF_NULL_RETURN_VALUE(new_string, NULL);
396         
397         EM_DEBUG_LOG("source_string [%s] ", source_string);
398         EM_DEBUG_LOG("old_string    [%s] ", old_string);
399         EM_DEBUG_LOG("new_string    [%s] ", new_string);
400
401         p = strstr(source_string, old_string);
402
403         if (!p) {
404                 EM_DEBUG_EXCEPTION("Orig not found in source_string");
405                 return NULL;
406         }
407
408         buf_len = strlen(source_string) + 1024;
409         buffer = (char *)em_malloc(buf_len);
410
411         if(p - source_string < strlen(source_string) + 1024 + 1) {
412                 strncpy(buffer, source_string, p - source_string);
413
414                 EM_DEBUG_LOG("BUFFER [%s]", buffer);
415
416                 split_str = em_split_file_path(p);
417
418                 if (!split_str) {
419                         EM_DEBUG_EXCEPTION(">> SPLIT STRING IS NULL  ");
420                         goto FINISH_OFF;
421                 }
422
423                 q = strstr(split_str, old_string);
424                 if (q) {
425                         EM_DEBUG_LOG("Split string [%s]", split_str);
426                         snprintf(buffer + strlen(buffer), buf_len - strlen(buffer), "%s%s", new_string, q+strlen(old_string));
427                         EM_DEBUG_LOG("BUFFER 1 [%s]", buffer);
428                         EM_SAFE_FREE(split_str);
429                         EM_DEBUG_FUNC_END("Suceeded");
430                         return buffer;
431                 }
432         }
433         else  {
434                 EM_DEBUG_EXCEPTION("Buffer is too small.");
435                 EM_SAFE_FREE(buffer);
436                 return NULL;
437         }
438         
439 FINISH_OFF: 
440         EM_SAFE_FREE(split_str);
441         EM_SAFE_FREE(buffer);
442
443         EM_DEBUG_FUNC_END("Failed");
444         return NULL;
445                 
446 }
447
448
449 int emcore_mime_flush_receiving_buffer(void *stream, int is_file, char *boundary_string, char *boundary_end_string,  int *end_of_parsing, int *err_code)
450 {
451         EM_DEBUG_FUNC_BEGIN("stream[%p], is_file[%d], boundary_string[%s], boundary_end_string[%s], end_of_parsing[%p],  err_code[%p]", stream, is_file, boundary_string, boundary_end_string, end_of_parsing, err_code);
452         char buf[MIME_LINE_LEN] = {0, };
453         int local_end_of_parsing = 0;
454
455         if (!stream) {
456                 if (err_code)
457                         *err_code = EMAIL_ERROR_INVALID_PARAM;
458                 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
459                 return false;
460         }
461
462         while (TRUE)  {
463                 if (!emcore_check_thread_status())  {
464                         if (err_code != NULL)
465                                 *err_code = EMAIL_ERROR_CANCELLED;
466                         EM_DEBUG_FUNC_END("EMAIL_ERROR_CANCELLED");
467                         return false;
468                 }
469
470                 if ((is_file == 0 && !emcore_mime_get_line_from_sock(stream, buf, MIME_LINE_LEN, err_code)) || 
471                         (is_file == 1 && !emcore_get_line_from_file(stream, buf, MIME_LINE_LEN, err_code))) {
472                         EM_DEBUG_EXCEPTION("emcore_mime_get_line_from_sock failed");
473                         local_end_of_parsing = 0;
474                         break;
475                 }
476
477                 if (boundary_string && boundary_end_string) {
478                         if (!strcmp(buf, boundary_string))  {
479                                 EM_DEBUG_LOG("found boundary");
480                                 local_end_of_parsing = 0; 
481                                 break; 
482                         }
483                         else if (!strcmp(buf, boundary_end_string))  {
484                                 EM_DEBUG_LOG("found boundary_end");
485                                 local_end_of_parsing = 1; 
486                                 break; 
487                         }
488                 }
489         }
490         
491         if (end_of_parsing)
492                 *end_of_parsing = local_end_of_parsing;
493
494         EM_DEBUG_FUNC_END();
495         return true;
496 }
497
498 int emcore_parse_mime(void *stream, int is_file, struct _m_content_info *cnt_info, int *err_code)
499 {
500         EM_DEBUG_FUNC_BEGIN("stream[%p], is_file[%d], cnt_info[%p], err_code[%p]", stream, is_file, cnt_info, err_code);
501         
502         struct _m_mesg *mmsg = em_malloc(sizeof(struct _m_mesg));
503
504         if (!mmsg) return false;
505
506         memset(mmsg, 0x00, sizeof(struct _m_mesg));
507
508         /*  1. parse the first found heade */
509         EM_DEBUG_LOG(">>>>>> 1. parse the first found header");
510         if (!emcore_mime_parse_header(stream, is_file, &mmsg->rfc822header, &mmsg->header, err_code)) {
511                 EM_SAFE_FREE(mmsg);
512                 return false; 
513         }
514
515         if (!emcore_check_thread_status())  {
516                 if (err_code != NULL)
517                         *err_code = EMAIL_ERROR_CANCELLED;
518                 return false;
519         }
520         
521         /*  2. parse bod */
522         EM_DEBUG_LOG(">>>>>> 2. parse body");
523         if (mmsg && mmsg->header && mmsg->header->part_header && mmsg->header->part_header->parameter)  {
524                 EM_DEBUG_LOG("name[%s]", mmsg->header->part_header->parameter->name);
525                 EM_DEBUG_LOG("value[%s]", mmsg->header->part_header->parameter->value);
526                 EM_DEBUG_LOG("next  :  %p", mmsg->header->part_header->parameter->next);
527         }
528         
529         if (emcore_mime_parse_body(stream, is_file, mmsg, cnt_info, NULL, err_code)<0) {
530                 EM_SAFE_FREE(mmsg);
531                 return false; 
532         }
533
534         /*  3. free memor */
535         EM_DEBUG_LOG(">>>>>> 3. free memory");
536         if (mmsg && mmsg->header && mmsg->header->part_header && mmsg->header->part_header->parameter)  {
537                 EM_DEBUG_LOG("name[%s]", mmsg->header->part_header->parameter->name);
538                 EM_DEBUG_LOG("value[%s]", mmsg->header->part_header->parameter->value);
539                 EM_DEBUG_LOG("next  :  %p", mmsg->header->part_header->parameter->next);
540         }
541         emcore_mime_free_mime(mmsg);
542         EM_DEBUG_FUNC_END();
543         return true;
544 }
545
546 int emcore_mime_parse_header(void *stream, int is_file, struct _rfc822header **rfc822header, struct _m_mesg_header **header, int *err_code)
547
548         EM_DEBUG_FUNC_BEGIN("stream[%p], is_file[%d], rfc822header[%p], header[%p], err_code[%p]", stream, is_file, rfc822header, header, err_code);
549         
550         struct _m_mesg_header *tmp_header = NULL;
551         struct _rfc822header *tmp_rfc822header = NULL;
552         char buf[MIME_LINE_LEN] = {0, };
553         char *name = NULL;
554         char *value = NULL;
555         char *pTemp = NULL;
556         int  is_longheader; 
557         
558         if (!emcore_check_thread_status())  {
559                 if (err_code != NULL)
560                         *err_code = EMAIL_ERROR_CANCELLED;
561                         return false;
562                 }
563
564
565         if ((is_file == 0 && !emcore_mime_get_line_from_sock(stream, buf, MIME_LINE_LEN, err_code)) || 
566                 (is_file == 1 && !emcore_get_line_from_file(stream, buf, MIME_LINE_LEN, err_code)))  {
567                 return false;
568         }
569         
570         if (!(tmp_header = em_malloc(sizeof(struct _m_mesg_header))))  {
571                 EM_DEBUG_EXCEPTION("malloc failed...");
572                 if (err_code != NULL)
573                         *err_code = EMAIL_ERROR_OUT_OF_MEMORY;
574                 return false;
575         }
576         
577         if (!emcore_check_thread_status())  {
578                 if (err_code != NULL)
579                         *err_code = EMAIL_ERROR_CANCELLED;
580                         return false;
581                 }
582         
583         while (TRUE)  {
584                 EM_DEBUG_LOG("buf[%s]", buf);
585                 
586                 if (!strncmp(buf, CRLF_STRING, 2))
587                         break;
588                 
589                 is_longheader = (buf[0] == ' ' || buf[0] == '\t') ? TRUE  :  FALSE;
590                 
591                 
592                 if (!is_longheader)  { /*  Normal header (format :  "Name :  Value" or "Name :  Value; Parameters" */
593                         if (name)  {
594                                 EM_SAFE_FREE(name);
595                         }
596                         
597                         /* EM_DEBUG_FUNC_BEGIN() */
598                         if ((pTemp = strtok(buf, ":")) == NULL)
599                                 break;
600                         
601                         name = EM_SAFE_STRDUP(pTemp);
602                         
603                         value = strtok(NULL, CRLF_STRING);
604                         
605                         /* --> 2007-05-16, cy */
606                         if (value)
607                                 if (!*++value)
608                                         break;
609                                 
610                         em_upper_string(name);
611                 }
612                 else  { /*  Long header */
613                         value = strtok(buf, CRLF_STRING);
614                         em_trim_left(value);
615                 }
616                 
617                 /* --> 2007-05-08 by cy */
618                 if (!name)
619                         break;
620                 
621                 EM_DEBUG_LOG("> name[%s]", name);
622                 EM_DEBUG_LOG("> value[%s]", value);
623                 
624                 /*  MIME Part Heade */
625                 if (memcmp(name, "CONTENT-", 8) == 0 && value)  {
626                         EM_DEBUG_LINE;
627                         emcore_mime_set_part_header_value(&tmp_header->part_header, name, value, err_code);
628                         
629                         if (tmp_header->part_header && tmp_header->part_header->parameter)      {
630                                 EM_DEBUG_LOG("name[%s]", tmp_header->part_header->parameter->name);
631                                 EM_DEBUG_LOG("value[%s]", tmp_header->part_header->parameter->value);
632                                 EM_DEBUG_LOG("next  :  %p", tmp_header->part_header->parameter->next);
633                         }
634                         
635                         /*  MIME Version Heade */
636                 }
637                 else if (memcmp(name, "MIME-VERSION", 12) == 0)  {
638                         /* EM_DEBUG_FUNC_BEGIN() */
639                         /*  ignored because we need only contents information */
640                         /*  tmp_header->version = EM_SAFE_STRDUP(value) */
641                         
642                         /*  RFC822 Heade */
643                 }
644                 else  {
645                         /*  in socket stream case, ignored because we need only contents information */
646                         if (is_file == 1)
647                                 emcore_mime_set_rfc822_header_value(&tmp_rfc822header, name, value, err_code);
648                 }
649                 
650                 if (!emcore_check_thread_status())  {
651                         if (err_code != NULL)
652                                 *err_code = EMAIL_ERROR_CANCELLED;
653                         return false;
654                 }
655                 if ((is_file == 0 && !emcore_mime_get_line_from_sock(stream, buf, MIME_LINE_LEN, err_code)) || 
656                         (is_file == 1 && !emcore_get_line_from_file(stream, buf, MIME_LINE_LEN, err_code)))  {
657                         
658                         if (tmp_rfc822header)
659                                 emcore_mime_free_rfc822_header(tmp_rfc822header);
660                         
661                         
662                         if (tmp_header)  {
663                                 emcore_mime_free_part_header(tmp_header->part_header);
664                                 
665                                 EM_SAFE_FREE(tmp_header->version);
666                                 EM_SAFE_FREE(tmp_header);
667                         }
668                         return false; 
669                 }
670         }
671         
672         *header = tmp_header;
673         *rfc822header = tmp_rfc822header;
674         
675         EM_SAFE_FREE(name);
676         EM_DEBUG_FUNC_END();
677         return true;
678 }
679
680 int emcore_mime_parse_part_header(void *stream, int is_file, struct _m_part_header **header, int *err_code)
681
682         EM_DEBUG_FUNC_BEGIN("stream[%p], is_file[%d], header[%p], err_code[%p]", stream, is_file, header, err_code);
683         
684         struct _m_part_header *tmp_header = NULL;
685         char buf[MIME_LINE_LEN] = {0x00};
686         char *name = NULL;
687         char *value = NULL;     
688         char *p = NULL;         
689         int is_longheader = false; 
690         
691         if (!emcore_check_thread_status())  {
692                         if (err_code != NULL)
693                                 *err_code = EMAIL_ERROR_CANCELLED;
694                         return false;
695         }
696
697         if ((is_file == 0 && !emcore_mime_get_line_from_sock(stream, buf, MIME_LINE_LEN, err_code)) || 
698         (is_file == 1 && !emcore_get_line_from_file(stream, buf, MIME_LINE_LEN, err_code)))
699                 return false; 
700         
701         tmp_header = em_malloc(sizeof(struct _m_part_header));
702
703         if (!tmp_header)  {
704                 EM_DEBUG_EXCEPTION("em_malloc failed");
705                 return false;
706         }
707         
708         memset(tmp_header, 0, sizeof(struct _m_part_header));
709         
710         while (true)  {
711                 if (!strncmp(buf, CRLF_STRING, strlen(CRLF_STRING))) break; 
712                 
713                 is_longheader = (buf[0] == ' ' || buf[0] == TAB);
714                 
715                 if (!is_longheader)  {   /*  Normal header (format :  "Name :  Value" or "Name :  Value; Parameters" */
716                         EM_SAFE_FREE(name);
717                         p = strtok(buf , ":");
718                         
719                         if (p)  {                                               
720                                 name = EM_SAFE_STRDUP(p);
721                                 value = strtok(NULL, CRLF_STRING);
722                                 em_upper_string(name);
723                         }
724                 } 
725                 else            /*  Long header */
726                         value = strtok(buf, CRLF_STRING);
727                 
728                 if (!name)
729                         break;
730                 
731                 emcore_mime_set_part_header_value(&tmp_header, name, value, err_code);
732                 
733                 if (!emcore_check_thread_status())  {
734                         if (err_code != NULL)
735                                 *err_code = EMAIL_ERROR_CANCELLED;
736                         return false;
737                 }
738                 
739                 if ((is_file == 0 && !emcore_mime_get_line_from_sock(stream, buf, MIME_LINE_LEN, err_code)) || 
740                 (is_file == 1 && !emcore_get_line_from_file(stream, buf, MIME_LINE_LEN, err_code)))  {
741                         EM_SAFE_FREE(name);
742                         EM_SAFE_FREE(tmp_header);
743                         
744                         return false; 
745                 }
746         } 
747         
748         *header = tmp_header;
749         
750         EM_SAFE_FREE(name);
751         EM_DEBUG_FUNC_END();
752         return true;
753 }
754
755
756 int emcore_mime_parse_body(void *stream, int is_file, struct _m_mesg *mmsg, struct _m_content_info *cnt_info,  void *callback, int *err_code)
757
758         EM_DEBUG_FUNC_BEGIN("stream[%p], is_file[%d], mmsg[%p], cnt_info[%p], callback[%p], err_code[%p]", stream, is_file, mmsg, cnt_info, callback, err_code);
759         
760         char *content_type = NULL, *content_encoding = NULL, *holder = NULL, *attachment_name, *t = NULL;
761         int type = 0, end_of_parsing = 0, size, local_err_code = EMAIL_ERROR_NONE; 
762
763         if (!emcore_check_thread_status())  {
764                 if (err_code != NULL)
765                         *err_code = EMAIL_ERROR_CANCELLED;
766                 return false;
767         }
768         
769         if (mmsg->header)
770                 content_type = emcore_mime_get_header_value(mmsg->header->part_header, CONTENT_TYPE, err_code); 
771         if (!content_type) 
772                 content_type = "TEXT/PLAIN";
773         
774         if (mmsg->header)
775                 content_encoding = emcore_mime_get_header_value(mmsg->header->part_header, CONTENT_ENCODING, err_code);
776         if (!content_encoding) 
777                 content_encoding = "7BIT"; 
778         
779         if (strstr(content_type, TEXT_STR)) type = TYPE_TEXT; 
780         else if (strstr(content_type, IMAGE_STR)) type = TYPE_IMAGE; 
781         else if (strstr(content_type, AUDIO_STR)) type = TYPE_AUDIO; 
782         else if (strstr(content_type, VIDEO_STR)) type = TYPE_VIDEO; 
783         else if (strstr(content_type, APPLICATION_STR)) type = TYPE_APPLICATION; 
784         else if (strstr(content_type, MULTIPART_STR)) type = TYPE_MULTIPART; 
785         else if (strstr(content_type, MESSAGE_STR)) type = TYPE_MESSAGE; 
786         else type = TYPE_UNKNOWN; 
787         
788         switch (type)  {
789                 case TYPE_MULTIPART:
790                         if (mmsg->header && !emcore_mime_get_header_value(mmsg->header->part_header, CONTENT_BOUNDARY, err_code))  {
791                                 EM_DEBUG_FUNC_END("false");
792                                 return false;
793                         }
794                         
795                         if (mmsg->header && !emcore_mime_parse_part(stream, is_file, mmsg->header->part_header, &mmsg->nested, cnt_info, &end_of_parsing, &local_err_code)) {
796                                 EM_DEBUG_FUNC_END("false");
797                                 return false;
798                         }
799
800                         /*  after finishing body parsing, make stream empty to get next mail. (get line from sock or file until '.' is read */
801                         if (end_of_parsing == true && local_err_code != EMAIL_ERROR_NO_MORE_DATA) 
802                                 emcore_mime_flush_receiving_buffer(stream, is_file, NULL, NULL, NULL, err_code);
803
804                         if (err_code)   
805                                 *err_code = local_err_code;
806                         
807                         break; 
808                         
809                 default:        
810                         attachment_name = NULL;
811
812                         if (mmsg->header && emcore_mime_get_header_value(mmsg->header->part_header, CONTENT_DISPOSITION, err_code)) {
813                                 attachment_name = emcore_mime_get_header_value(mmsg->header->part_header, CONTENT_FILENAME, err_code);
814                                 /* if (!attachment_name) attachment_name = "unknown" */
815                                 if (attachment_name) EM_DEBUG_LOG(" attachment = [%s]", attachment_name);
816                         }
817
818                         if (strstr(content_type, "PKCS7-MIME")) {
819                                 EM_DEBUG_LOG("Encrypted mail do not include the body");
820                                 cnt_info->file = em_malloc(sizeof(struct attachment_info));
821                                 if (cnt_info->file) {
822                                         cnt_info->file->type = 2;
823                                         cnt_info->file->name = EM_SAFE_STRDUP(attachment_name);
824                                         emcore_mime_get_content_data(stream, is_file, false, NULL, content_encoding, &end_of_parsing, SAVE_TYPE_FILE, &holder, &size, NULL, err_code);
825                                         cnt_info->file->save = holder;
826                                         cnt_info->file->size = size;
827                                 }
828                                 break;
829                         }
830
831                         if (cnt_info->grab_type & GRAB_TYPE_TEXT)  {
832                                 /* EM_DEBUG_LINE */
833                                 /*  get content data. content data is saved in file */
834                                 emcore_mime_get_content_data(stream, is_file, true, NULL, content_encoding, &end_of_parsing, SAVE_TYPE_FILE, &holder, &size, NULL, err_code);
835                                 
836                                 EM_DEBUG_LOG("After emcore_mime_get_content_data");
837                                 
838                                 if (mmsg->header && mmsg->header->part_header && strstr((t = emcore_mime_get_header_value(mmsg->header->part_header, CONTENT_TYPE, err_code)) ? t  :  "", "HTML"))
839                                         cnt_info->text.html = holder;
840                                 else if (mmsg->header) {
841                                         char *charset = emcore_mime_get_header_value(mmsg->header->part_header, CONTENT_CHARSET, err_code);
842                                         
843                                         EM_DEBUG_LOG(">>>> charset [%s]", charset);
844                                         
845                                         if (!charset || !strncmp(charset, "X-UNKNOWN", strlen("X-UNKNOWN")))
846                                                 cnt_info->text.plain_charset = EM_SAFE_STRDUP("UTF-8");
847                                         else
848                                                 cnt_info->text.plain_charset = EM_SAFE_STRDUP(charset);
849                                         
850                                         EM_DEBUG_LOG(">>>> cnt_info->text.plain_charset [%s]", cnt_info->text.plain_charset);
851                                         
852                                         cnt_info->text.plain = holder;
853                                         
854                                         EM_DEBUG_LOG(">>>> cnt_info->text.plain [%s]", cnt_info->text.plain);
855                                 }
856                         }
857                         
858                         break; 
859         } 
860         EM_DEBUG_FUNC_END();
861         return true; 
862
863
864 int emcore_mime_parse_part(void *stream, int is_file, struct _m_part_header *parent_header, struct _m_part *nested, struct _m_content_info *cnt_info, int *eop, int *err_code)
865 {
866         EM_DEBUG_FUNC_BEGIN("stream[%p], is_file[%d], parent_header[%p], nested[%p], cnt_info[%p], eop[%p], err_code[%p]", stream, is_file, parent_header, nested, cnt_info, eop, err_code);
867         
868         struct _m_body *tmp_body = NULL;
869         struct _m_part **p = NULL;
870         char buf[MIME_LINE_LEN] = {0x00, };
871         char boundary[BOUNDARY_LEN] = {0x00, };
872         char boundary_end[BOUNDARY_LEN] = {0x00, }; 
873         char mime_type_buffer[128] = { 0, };
874         char *boundary_str = NULL;
875         char *content_type = NULL;
876         char *content_encoding = NULL;
877         char *holder = NULL;
878         char *attachment_name = NULL;
879         char *content_disposition = NULL;
880         char *t = NULL;
881         char *pTemp = NULL;
882         int type = 0;
883         int content_disposition_type = 0;
884         int end_of_parsing = 0;
885         int size = 0, local_err_code = EMAIL_ERROR_NONE;
886         int is_skip = false; 
887
888         boundary_str = emcore_mime_get_header_value(parent_header, CONTENT_BOUNDARY, err_code);
889
890         SNPRINTF(boundary, BOUNDARY_LEN, "--%s%s", boundary_str, CRLF_STRING); 
891         SNPRINTF(boundary_end, BOUNDARY_LEN, "--%s%s", boundary_str, "--\r\n");
892
893         nested->body = NULL;
894         nested->next = NULL;
895
896         /*  goto the first found useful mime dat */
897         EM_DEBUG_LOG("Before first loop");
898         while (true)  { 
899                 if (!emcore_check_thread_status())  {
900                         if (err_code != NULL)
901                                 *err_code = EMAIL_ERROR_CANCELLED;
902                         return false;
903                 }
904                 if ((is_file == 0 && !emcore_mime_get_line_from_sock(stream, buf, MIME_LINE_LEN, err_code)) || 
905                 (is_file == 1 && !emcore_get_line_from_file(stream, buf, MIME_LINE_LEN, err_code))) {
906                         EM_DEBUG_EXCEPTION("emcore_mime_get_line_from_sock failed.");
907                         if (eop)
908                                 *eop = true;
909                         EM_DEBUG_FUNC_END("false");
910                         return false;
911                 }
912                 
913                 if (!strcmp(buf, boundary))
914                         break; 
915         }
916
917         EM_DEBUG_LOG("Before second loop");
918         while (true)  {
919                 if (!(tmp_body = em_malloc(sizeof(struct _m_body))))  {
920                         EM_DEBUG_EXCEPTION("em_malloc failed.");
921                         if (nested->body) 
922                                 emcore_mime_free_part_body(nested->body);
923                         if (nested->next) 
924                                 emcore_mime_free_part(nested->next);
925                         EM_DEBUG_FUNC_END("false");
926                         return false;
927                 }
928                         
929                 memset(tmp_body, 0, sizeof(struct _m_body));
930                 
931                 /*  parsing MIME Header */
932                 if (!emcore_mime_parse_part_header(stream, is_file, &tmp_body->part_header, err_code))  {
933                         EM_DEBUG_EXCEPTION("emcore_mime_parse_part_header failed.");
934                         if (nested->body) 
935                                 emcore_mime_free_part_body(nested->body);
936                         if (nested->next) 
937                                 emcore_mime_free_part(nested->next);
938                         
939                         emcore_mime_free_part_body(tmp_body);
940                         return false;
941                 }
942                 
943                 content_type = emcore_mime_get_header_value(tmp_body->part_header, CONTENT_TYPE, err_code);
944
945                 if (!content_type) 
946                         content_type = "TEXT/PLAIN"; 
947
948                 content_encoding = emcore_mime_get_header_value(tmp_body->part_header, CONTENT_ENCODING, err_code);
949                 if (!content_encoding)
950                         content_encoding = "7BIT"; 
951                 
952                 if (strstr(content_type, TEXT_STR)) type = TYPE_TEXT; 
953                 else if (strstr(content_type, IMAGE_STR)) type = TYPE_IMAGE; 
954                 else if (strstr(content_type, AUDIO_STR)) type = TYPE_AUDIO; 
955                 else if (strstr(content_type, VIDEO_STR)) type = TYPE_VIDEO; 
956                 else if (strstr(content_type, APPLICATION_STR)) type = TYPE_APPLICATION; 
957                 else if (strstr(content_type, MULTIPART_STR)) type = TYPE_MULTIPART; 
958                 else if (strstr(content_type, MESSAGE_STR)) type = TYPE_MESSAGE; 
959                 else type = TYPE_UNKNOWN;
960
961                 switch (type)  {
962                         case TYPE_MULTIPART: 
963                                 EM_DEBUG_LOG("TYPE_MULTIPART");
964                                 if (!emcore_mime_get_header_value(tmp_body->part_header, CONTENT_BOUNDARY, err_code))  {
965                                         EM_DEBUG_EXCEPTION("emcore_mime_get_header_value failed.");
966                                         emcore_mime_free_part_body(tmp_body);
967                                         EM_DEBUG_FUNC_END("false");
968                                         return false;
969                                 }
970                                 
971                                 emcore_mime_parse_part(stream, is_file, tmp_body->part_header, &tmp_body->nested, cnt_info, &end_of_parsing, &local_err_code);
972                                 
973                                 if (!nested->body) 
974                                         nested->body = tmp_body;
975                                 else  {
976                                         p = &nested->next;
977                                         
978                                         while (*p && (*p)->next)
979                                                 *p = (*p)->next;
980                                         
981                                         if (*p)
982                                                 p = &(*p)->next;
983                                         
984                                         if (!(*p = em_malloc(sizeof(struct _m_part))))  {
985                                                 EM_DEBUG_EXCEPTION("em_malloc failed");
986                                                 if (nested->body) emcore_mime_free_part_body(nested->body);
987                                                 if (nested->next) emcore_mime_free_part(nested->next);
988                                                 emcore_mime_free_part_body(tmp_body);
989                                                 EM_DEBUG_FUNC_END("false");
990                                                 return false;
991                                         }
992                                         
993                                         (*p)->body = tmp_body;
994                                         (*p)->next = NULL;
995                                 }
996                                 
997                                 if (err_code)
998                                         *err_code = local_err_code;
999                                         
1000                                 if (end_of_parsing && local_err_code != EMAIL_ERROR_NO_MORE_DATA) /*  working with imap */
1001                                 /* if (!end_of_parsing) */ /*  working with pop */ {
1002                                         EM_DEBUG_LOG("Enter flushing socket buffer.");
1003                                         emcore_mime_flush_receiving_buffer(stream, is_file, boundary, boundary_end, &end_of_parsing, err_code);
1004                                 }
1005                                 
1006                                 break; 
1007                         
1008                         default: 
1009                                 EM_DEBUG_LOG("default");
1010                                 attachment_name = NULL;
1011                                 content_disposition = NULL;
1012                                 
1013                                 if (type == TYPE_MESSAGE) 
1014                                         is_skip = true;
1015                                 
1016                                 if (is_skip == true)  {
1017                                         if (!emcore_mime_skip_content_data(stream, is_file, boundary_str, &end_of_parsing, &size, NULL, err_code)) 
1018                                                 EM_DEBUG_EXCEPTION("emcore_mime_skip_content_data failed...");
1019                                         
1020                                         emcore_mime_free_part_body(tmp_body);
1021                                         EM_DEBUG_LOG_MIME("break");
1022                                         break;
1023                                 }
1024                                 
1025                                 /*  first check inline content */
1026                                 /*  if the content id or content location exis */
1027                                 content_disposition = emcore_mime_get_header_value(tmp_body->part_header, CONTENT_DISPOSITION, err_code);
1028                                 EM_DEBUG_LOG("content_disposition : [%s]", content_disposition);
1029                                 if (content_disposition) {
1030                                         if (!strcasecmp(content_disposition, "inline")) {
1031                                                 if (!attachment_name)
1032                                                         attachment_name = emcore_mime_get_header_value(tmp_body->part_header, CONTENT_ID, err_code);
1033                                                 if (!attachment_name)
1034                                                         attachment_name = emcore_mime_get_header_value(tmp_body->part_header, CONTENT_LOCATION, err_code);
1035
1036                                                 content_disposition_type = 1;
1037                                         } else if (!strcasecmp(content_disposition, "attachment")) {
1038                                                 if (!attachment_name)  {
1039                                                         attachment_name = emcore_mime_get_header_value(tmp_body->part_header, CONTENT_FILENAME, err_code);
1040                                                         EM_DEBUG_LOG_MIME(">> attachment = [%s]", attachment_name ? attachment_name  :  NIL);
1041                                                 }
1042                                                 content_disposition_type = 2;
1043                                         }
1044                                 } else if (strstr(content_type, "PKCS7")) {
1045                                         attachment_name = emcore_mime_get_header_value(tmp_body->part_header, CONTENT_NAME, err_code);
1046                                         EM_DEBUG_LOG_MIME(">> attachment = [%s]", attachment_name ? attachment_name  :  NIL);
1047                         }
1048
1049                                 if (!emcore_check_thread_status())  {
1050                                         if (err_code != NULL)
1051                                                 *err_code = EMAIL_ERROR_CANCELLED;
1052                                         EM_DEBUG_EXCEPTION("EMAIL_ERROR_CANCELLED");
1053                                         EM_DEBUG_FUNC_END("false");
1054                                         return false;
1055                                 }
1056
1057                                 /*  get content and content information */
1058                                 if (!attachment_name)  {        /*  text */
1059                                         /*  get content by buffe */
1060                                         EM_DEBUG_LOG_MIME("attachment_name is NULL. It's a text message"); 
1061                                         emcore_mime_get_content_data(stream, is_file, true, boundary_str, content_encoding, &end_of_parsing, SAVE_TYPE_FILE, &holder, &size, NULL, err_code);
1062
1063                                         EM_DEBUG_LOG("After emcore_mime_get_content_data");
1064                                         
1065                                         if (cnt_info->grab_type & GRAB_TYPE_TEXT)  {
1066                                                 if (tmp_body->part_header && strstr((t = emcore_mime_get_header_value(tmp_body->part_header, CONTENT_TYPE, err_code)) ? t  :  "", "HTML"))  {
1067                                                         cnt_info->text.html = holder;
1068                                                         
1069                                                         EM_DEBUG_LOG(" cnt_info->text.html [%s]", cnt_info->text.html);
1070                                                 }
1071                                                 else  {
1072                                                         char *charset = emcore_mime_get_header_value(tmp_body->part_header, CONTENT_CHARSET, err_code);
1073                                                         EM_DEBUG_LOG(" charset [%s]", charset);
1074                                                         
1075                                                         if (!charset || !strncmp(charset, "X-UNKNOWN", strlen("X-UNKNOWN")))
1076                                                                 cnt_info->text.plain_charset = EM_SAFE_STRDUP("UTF-8");
1077                                                         else
1078                                                                 cnt_info->text.plain_charset = EM_SAFE_STRDUP(charset);
1079                                                         
1080                                                         EM_DEBUG_LOG(" cnt_info->text.plain_charset [%s]", cnt_info->text.plain_charset);
1081                                                         
1082                                                         cnt_info->text.plain = holder;
1083                                                         
1084                                                         EM_DEBUG_LOG(" cnt_info->text.plain [%s]", cnt_info->text.plain);
1085                                                 }
1086                                         }
1087                                         else  {
1088                                                 if (holder)  {
1089                                                         free(holder);
1090                                                         holder = NULL;
1091                                                 }
1092                                         }
1093                                 }
1094                                 else  {         /*  attachment */
1095                                         EM_DEBUG_LOG_MIME("attachment_name is not NULL. It's a attachment"); 
1096                                         struct attachment_info **file = &cnt_info->file;
1097                                         int i = 1;
1098                                         
1099                                         while (*file && (*file)->next)  {
1100                                                 file = &(*file)->next;
1101                                                 i++;
1102                                         }
1103                                         
1104                                         if (*file)  {
1105                                                 file = &(*file)->next;
1106                                                 i++;
1107                                         }
1108                                         
1109                                         *file = em_malloc(sizeof(struct attachment_info));
1110                                         if (*file)  {           
1111                                                 (*file)->type = content_disposition_type;
1112
1113                                                 EM_DEBUG_LOG_MIME("file->type : %d", (*file)->type);
1114                                                 
1115                                                 (*file)->name                 = EM_SAFE_STRDUP(attachment_name);
1116                                                 (*file)->content_id           = EM_SAFE_STRDUP(tmp_body->part_header->content_id);
1117                                                 if(tmp_body->part_header->type && tmp_body->part_header->subtype) {
1118                                                         SNPRINTF(mime_type_buffer, 128, "%s/%s", tmp_body->part_header->type, tmp_body->part_header->subtype);
1119                                                         (*file)->attachment_mime_type = EM_SAFE_STRDUP(mime_type_buffer);
1120                                                 }
1121                                                 
1122                                                 /*  check if the current file is target file */
1123                                                 if ( (cnt_info->grab_type & GRAB_TYPE_ATTACHMENT) || (*file)->type == 1)  {
1124                                                         /*  get content by file */
1125                                                         EM_DEBUG_LOG_MIME("Trying to get content"); 
1126                                                         emcore_mime_get_content_data(stream, is_file, false, boundary_str, content_encoding, &end_of_parsing, SAVE_TYPE_FILE, &holder, &size, NULL, err_code);
1127                                                         (*file)->save = holder;
1128                                                 }
1129                                                 else  {
1130                                                         /*  only get content size */
1131                                                         EM_DEBUG_LOG_MIME("Pass downloading"); 
1132                                                         emcore_mime_get_content_data(stream, is_file, false, boundary_str, content_encoding, &end_of_parsing, SAVE_TYPE_SIZE, NULL, &size, NULL, err_code);
1133                                                         (*file)->save = NULL;
1134                                                 }
1135                                                 
1136                                                 if (err_code)
1137                                                         EM_DEBUG_LOG("end_of_parsing [%d], err_code [%d]", end_of_parsing, *err_code);
1138                                                 
1139                                                 (*file)->size = size;
1140                                                 
1141                                                 if (strstr(content_type, APPLICATION_STR))  {
1142                                                         pTemp = content_type + strlen(APPLICATION_STR); 
1143                                                         
1144                                                         if (strcasecmp(pTemp, MIME_SUBTYPE_DRM_OBJECT) == 0)
1145                                                                 (*file)->drm = EMAIL_ATTACHMENT_DRM_OBJECT;
1146                                                         else if (strcasecmp(pTemp, MIME_SUBTYPE_DRM_RIGHTS) == 0)
1147                                                                 (*file)->drm = EMAIL_ATTACHMENT_DRM_RIGHTS;
1148                                                         else if (strcasecmp(pTemp, MIME_SUBTYPE_DRM_DCF) == 0)
1149                                                                 (*file)->drm = EMAIL_ATTACHMENT_DRM_DCF;
1150                                                 }
1151                                         }
1152                                         else  {
1153                                                 EM_DEBUG_EXCEPTION("em_malloc failed...");
1154                                                 emcore_mime_free_part_body(tmp_body);
1155                                                 EM_DEBUG_FUNC_END("false");
1156                                                 return false;
1157                                         }
1158                                 }
1159
1160                                 if (!emcore_check_thread_status())  {
1161                         if (err_code != NULL)
1162                                 *err_code = EMAIL_ERROR_CANCELLED;
1163                                         EM_DEBUG_EXCEPTION("EMAIL_ERROR_CANCELLED");
1164                                         EM_DEBUG_FUNC_END("false");
1165                         return false;
1166                 }
1167
1168                                 if (!nested->body) 
1169                                         nested->body = tmp_body;
1170                                 else {
1171                                         p = &nested->next;
1172                                         
1173                                         while (*p && (*p)->next)
1174                                                 p = &(*p)->next;
1175                                         
1176                                         if (*p)
1177                                                 p = &(*p)->next;
1178                                         
1179                                         if (!(*p = em_malloc(sizeof(struct _m_part))))  {
1180                                                 EM_DEBUG_EXCEPTION("em_malloc failed");
1181                                                 if (nested->body) emcore_mime_free_part_body(nested->body);
1182                                                 if (nested->next) emcore_mime_free_part(nested->next);
1183                                                 
1184                                                 emcore_mime_free_part_body(tmp_body);
1185                                                 EM_DEBUG_FUNC_END("false");
1186                                                 return false;
1187                                         }
1188                                         
1189                                         (*p)->body = tmp_body;
1190                                         (*p)->next = NULL;
1191                                 }
1192                                 
1193                                 break; 
1194                 }
1195                 
1196                 /*  End of parsin */
1197                 if (end_of_parsing)
1198                         break; 
1199         }
1200         
1201         if (eop != NULL)
1202                 *eop = end_of_parsing;
1203
1204         EM_DEBUG_FUNC_END("end_of_parsing [%d]", end_of_parsing);
1205         return true; 
1206
1207
1208 /*  set RFC822 Heade */
1209 int emcore_mime_set_rfc822_header_value(struct _rfc822header **header, char *name, char *value, int *err_code)
1210 {
1211         EM_DEBUG_FUNC_BEGIN("header[%p], name[%s], value[%s], err_code[%p]", header, name, value, err_code);
1212         
1213         char **p = NULL;
1214         char *t = NULL;
1215
1216         /*  ? ? ? why return value is 1  */
1217         if (!value || !*value) return true;
1218
1219         if (!*header)  {
1220                 *header = em_malloc(sizeof(struct _rfc822header));
1221                 if (!*header)  {        
1222                         EM_DEBUG_EXCEPTION("em_malloc failed");
1223                         return false;
1224                 }
1225         }
1226
1227         if (name) {
1228         em_upper_string(name);
1229
1230                 if (strncmp(name, "RETURN-PATH", strlen("RETURN-PATH")) == 0)
1231                         p = &(*header)->return_path;/*  Return-Rat */
1232                 else if (strncmp(name, "RECEIVED", strlen("RECEIVED")) == 0)
1233                         p = &(*header)->received;       /*  Receive */
1234                 else if (strncmp(name, "REPLY-TO", strlen("REPLY-TO")) == 0)
1235                         p = &(*header)->reply_to;       /*  Reply-T */
1236                 else if (strncmp(name, "DATE", strlen("DATE")) == 0)
1237                         p = &(*header)->date;           /*  Dat */
1238                 else if (strncmp(name, "FROM", strlen("FROM")) == 0)
1239                         p = &(*header)->from;           /*  Fro */
1240                 else if (strncmp(name, "SUBJECT", strlen("SUBJECT")) == 0)
1241                         p = &(*header)->subject;        /*  Subjec */
1242                 else if (strncmp(name, "SENDER", strlen("SENDER")) == 0)
1243                         p = &(*header)->sender;         /*  Sende */
1244                 else if (strncmp(name, "TO", strlen("TO")) == 0)
1245                         p = &(*header)->to;                     /*  T */
1246                 else if (strncmp(name, "CC", strlen("CC")) == 0)
1247                         p = &(*header)->cc;                     /*  C */
1248                 else if (strncmp(name, "BCC", strlen("BCC")) == 0)
1249                         p = &(*header)->bcc;            /*  Bc */
1250                 else if (strncmp(name, "X-PRIORITY", strlen("X-PRIORITY")) == 0)
1251                         p = &(*header)->priority;       /*  Prorit */
1252                 else if (strncmp(name, "X-MSMAIL-PRIORITY", strlen("X-MSMAIL-PRIORITY")) == 0)
1253                         p = &(*header)->ms_priority;/*  Prorit */
1254                 else if (strncmp(name, "DISPOSITION-NOTIFICATION-TO", strlen("DISPOSITION-NOTIFICATION-TO")) == 0)
1255                         p = &(*header)->dsp_noti_to;/*  Disposition-Notification-T */
1256                 else {
1257                         return false;
1258                 }
1259         }
1260
1261         if (p) {
1262                 if (!*p) 
1263                         *p = EM_SAFE_STRDUP(value);
1264                 else  { /*  Long Heade */
1265                         if (!(t = realloc(*p, strlen(*p) + strlen(value)+1)))
1266                                 return false;
1267                         
1268                         strncat(t, value, strlen(value));
1269                         *p = t;
1270                 }
1271         }
1272         
1273         return true;
1274 }
1275
1276 /*  set MIME Part Heade */
1277 int emcore_mime_set_part_header_value(struct _m_part_header **header, char *name, char *value, int *err_code)
1278 {
1279         EM_DEBUG_FUNC_BEGIN("header[%p], name[%s], value[%s], err_code[%p]", header, name, value, err_code);
1280         
1281         if (!name || !value) {
1282                 EM_DEBUG_EXCEPTION("Invalid parameter");
1283                 if (err_code != NULL)
1284                         *err_code = EMAIL_ERROR_INVALID_PARAM;
1285                 return false;
1286         }
1287
1288         struct _parameter *p = NULL;
1289         char *p_val = NULL;
1290         
1291         if (!*header)  {
1292                 *header = em_malloc(sizeof(struct _m_part_header));
1293                 if (!(*header)) {       
1294                         EM_DEBUG_EXCEPTION("em_malloc failed...");
1295                         return false;
1296                 }
1297         }
1298         
1299         em_upper_string(name);
1300         em_trim_left(value);
1301         em_trim_right(value);
1302
1303         if (!emcore_check_thread_status())  {
1304                 if (err_code != NULL)
1305                         *err_code = EMAIL_ERROR_CANCELLED;
1306                 return false;
1307         }
1308
1309         if (name) {
1310                 if (strncmp(name, "CONTENT-TYPE", strlen("CONTENT-TYPE")) == 0)  {
1311                         p_val = strtok(value, ";");
1312                         
1313                         if (p_val)  {
1314                                 if (!(*header)->type)  {   /*  Content-Type */
1315                                         em_upper_string(p_val);
1316                                         (*header)->type = EM_SAFE_STRDUP(p_val); 
1317                                 } 
1318                                 else  {   /*  Content-Type Parameter (format :  "name =value" */
1319                                         if (emcore_mime_get_param_from_str(p_val, &p, err_code))        
1320                                                 emcore_mime_add_param_to_list(&((*header)->parameter), p, err_code);
1321                                 }
1322                                 
1323                                 /*  repeatedly get paramete */
1324                                 while ((p_val = strtok(NULL, ";")))  {
1325                                         if (emcore_mime_get_param_from_str(p_val, &p, err_code))        
1326                                                 emcore_mime_add_param_to_list(&((*header)->parameter), p, err_code);
1327                                 }
1328                         }
1329                 }
1330                 else if (strncmp(name, "CONTENT-TRANSFER-ENCODING", strlen("CONTENT-TRANSFER-ENCODING")) == 0)  {
1331                         em_upper_string(value);
1332                         (*header)->encoding = EM_SAFE_STRDUP(value);
1333                 } 
1334                 else if (strncmp(name, "CONTENT-DESCRPTION", strlen("CONTENT-DESCRPTION")) == 0)  {
1335                         em_upper_string(value);
1336                         (*header)->desc = EM_SAFE_STRDUP(value);
1337                 } 
1338                 else if (strncmp(name, "CONTENT-DISPOSITION", strlen("CONTENT-DISPOSITION")) == 0)  {
1339                         p_val = strtok(value, ";");
1340                         
1341                         if (p_val)  {
1342                                 if (!(*header)->disp_type)  {   /*  Content-Dispositio */
1343                                         em_upper_string(p_val);
1344                                         (*header)->disp_type = EM_SAFE_STRDUP(p_val); 
1345                                 } 
1346                                 else  { /*  Content-Disposition parameter (format :  "name =value" */
1347                                         if (emcore_mime_get_param_from_str(p_val, &p, err_code))        
1348                                                 emcore_mime_add_param_to_list(&((*header)->disp_parameter), p, err_code);
1349                                 }
1350                                 
1351                                 /*  repeatedly get paramete */
1352                                 while ((p_val = strtok(NULL, ";")))  {
1353                                         if (emcore_mime_get_param_from_str(p_val, &p, err_code))        
1354                                                 emcore_mime_add_param_to_list(&((*header)->disp_parameter), p, err_code);
1355                                 }
1356                         } 
1357                 } 
1358                 else if (strncmp(name, "CONTENT-ID", strlen("CONTENT-ID")) == 0)  {
1359                         size_t len = 0;
1360                         len = strlen(value);
1361                         /* em_upper_string(value) */
1362                         
1363                         if ((len) && (value[0] == '<'))  {
1364                                 ++value;
1365                                 --len;
1366                         }
1367                         
1368                         if ((len > 1) && (value[len-1] == '>')) 
1369                                 value[len-1] = '\0';
1370                         
1371                         (*header)->content_id = EM_SAFE_STRDUP(value);
1372                 }
1373                 else if (strncmp(name, "CONTENT-LOCATION", strlen("CONTENT-LOCATION")) == 0) 
1374                         (*header)->content_location = EM_SAFE_STRDUP(value);
1375         }       
1376         EM_DEBUG_FUNC_END();
1377         return true;
1378 }
1379  
1380 /*  get header parameter from strin */
1381 int emcore_mime_get_param_from_str(char *str, struct _parameter **param, int *err_code)
1382 {
1383         EM_DEBUG_FUNC_BEGIN("str[%s], param[%p], err_code[%p]", str, param, err_code);
1384         
1385         char *p_name, *p_val, *p;
1386
1387         *param = NULL;
1388
1389         /*  Parameter Chec */
1390         if (!(p = strchr(str, '=')))    return false;
1391         
1392         *p = '\0';
1393
1394         p_name = str;
1395         p_val = p+1;
1396
1397         em_trim_left(p_name);
1398         em_trim_right(p_name);
1399         
1400         if (!*p_name) return false;
1401
1402         em_trim_left(p_val);
1403         em_trim_right(p_val);
1404         
1405         if (!*p_val) return false;
1406
1407         if (!(*param = em_malloc(sizeof(struct _parameter)))) return false;
1408         
1409         (*param)->next = NULL;
1410
1411         /*  Name se */
1412         /*  check string lengt */
1413         if (strlen(p_name) > 0)  {
1414                 em_upper_string(p_name);
1415                 (*param)->name = EM_SAFE_STRDUP(p_name);
1416         }
1417
1418         if (strlen(p_val) > 0)  {
1419                 if ((p = strchr(p_val, '\"')))  {
1420                         p_val = p + 1;
1421                         if (!*p_val) return false;
1422                 }
1423                 if ((p = strchr(p_val, '\"')))
1424                         *p = '\0';
1425                 
1426                 if (strncmp(p_name, "BOUNDARY", strlen("BOUNDARY")) != 0 && !strstr(p_name, "NAME"))
1427                         em_upper_string(p_val);
1428                 
1429                 /*  = ? ENCODING_TYPE ? B(Q) ? ENCODED_STRING ? */
1430                 int err = EMAIL_ERROR_NONE;
1431                 char *utf8_text = NULL;
1432                 
1433                 if (!(utf8_text = emcore_decode_rfc2047_text(p_val, &err))) 
1434                         EM_DEBUG_EXCEPTION("emcore_decode_rfc2047_text failed [%d]", err);
1435                 (*param)->value = utf8_text;
1436         }
1437         EM_DEBUG_FUNC_END();
1438         return true;
1439 }
1440
1441 /*  add a parameter to parameter lis */
1442 int emcore_mime_add_param_to_list(struct _parameter **param_list, struct _parameter *param, int *err_code)
1443 {
1444         struct _parameter **t = param_list;
1445         
1446         while (*t && (*t)->next) 
1447                 *t = (*t)->next;
1448         
1449         if (*t) 
1450                 (*t)->next = param;
1451         else
1452                 *t = param;
1453
1454         return true;
1455 }
1456
1457 /*  get header value from MIME Part Heade */
1458 char *emcore_mime_get_header_value(struct _m_part_header *header, int type, int *err_code)
1459 {
1460         EM_DEBUG_FUNC_BEGIN("header[%p], type[%d], err_code[%p]", header, type, err_code);
1461         
1462         struct _parameter *p = NULL;
1463         char *name = NULL;
1464         
1465         if (!header)  {
1466                 EM_DEBUG_EXCEPTION("header[%p], type[%d]", header, type);
1467                 
1468                 if (err_code != NULL)
1469                         *err_code = EMAIL_ERROR_INVALID_PARAM;
1470                 return NULL;
1471         }
1472         
1473         switch (type)  {
1474                 case CONTENT_TYPE: 
1475                         return header->type;
1476                 
1477                 case CONTENT_SUBTYPE: 
1478                         return header->subtype;
1479                 
1480                 case CONTENT_ENCODING: 
1481                         return header->encoding;
1482                 
1483                 case CONTENT_CHARSET: 
1484                         name = "CHARSET";
1485                         p = header->parameter;
1486                         break;
1487                 
1488                 case CONTENT_DISPOSITION: 
1489                         return header->disp_type;
1490                 
1491                 case CONTENT_NAME: 
1492                         name = "NAME";
1493                         p = header->parameter;
1494                         break;
1495                 
1496                 case CONTENT_FILENAME: 
1497                         name = "FILENAME";
1498                         p = header->disp_parameter;
1499                         break;
1500                 
1501                 case CONTENT_BOUNDARY: 
1502                         name = "BOUNDARY";
1503                         p = header->parameter;
1504                         break;
1505                 
1506                 case CONTENT_REPORT_TYPE: 
1507                         name = "REPORT-TYPE";
1508                         p = header->parameter;
1509                         break;
1510                 
1511                 case CONTENT_ID: 
1512                         return header->content_id;
1513                 
1514                 case CONTENT_LOCATION: 
1515                         return header->content_location;
1516                 
1517                 default: 
1518                         return NULL;
1519         }
1520         
1521         for (; p; p = p->next)  {
1522                 if (strcmp(p->name, name) == 0)
1523                         break;
1524         }
1525         
1526         if (!p)
1527                 return NULL;
1528         EM_DEBUG_FUNC_END();
1529         return p->value;
1530 }
1531
1532 /*
1533  * decode body text (quoted-printable, base64) 
1534  * enc_type : encoding type (base64/quotedprintable)
1535  */
1536 INTERNAL_FUNC int emcore_decode_body_text(char *enc_buf, int enc_len, int enc_type, int *dec_len, int *err_code)
1537 {
1538         EM_DEBUG_FUNC_BEGIN("enc_buf[%p], enc_len[%d], enc_type[%d], dec_len[%p]", enc_buf, enc_len, enc_type, dec_len);
1539         unsigned char *content = NULL;
1540         
1541         /*  too many called */
1542         *dec_len = enc_len;
1543         
1544         switch (enc_type)  {
1545                 case ENCQUOTEDPRINTABLE:
1546                         EM_DEBUG_LOG("ENCQUOTEDPRINTABLE");
1547                         content = rfc822_qprint((unsigned char *)enc_buf, (unsigned long)enc_len, (unsigned long *)dec_len);
1548                         break;
1549                 
1550                 case ENCBASE64:
1551                         EM_DEBUG_LOG("ENCBASE64");
1552                         content = rfc822_base64((unsigned char *)enc_buf, (unsigned long)enc_len, (unsigned long *)dec_len);
1553                         break;
1554                 
1555                 case ENC7BIT:        
1556                 case ENC8BIT:        
1557                 case ENCBINARY:      
1558                 case ENCOTHER:       
1559                 default:
1560                         break;
1561         }
1562         
1563         if (content)  {
1564                 if (enc_len < *dec_len) {
1565                         EM_DEBUG_EXCEPTION("Decoded length is too big to store it");
1566                         return -1;
1567                 }
1568                 memcpy(enc_buf, content, *dec_len);
1569                 enc_buf[*dec_len] = '\0';
1570                 EM_SAFE_FREE(content);
1571         }
1572         EM_DEBUG_FUNC_END();
1573         return 0;
1574 }
1575
1576 /*  1. if boundary is NULL, contnent has not multipart */
1577 /*  2. if boundary isn't NULL, content is from current line to the next found boundary */
1578 /*     if next found boundary is the other part boundary ("--boundary"), return and set end_of_parsing to 1 */
1579 /*     if next found boundary is the multipart ending boundary ("--boundary--"), return and set end_of_parsing to 0 */
1580 /*  mode - SAVE_TYPE_SIZE   :  no saving (only hold content size */
1581 /*         SAVE_TYPE_BUFFER :  content is saved to buffer (holder is buffer */
1582 /*         SAVE_TYPE_FILE   :  content is saved to temporary file (holder is file name */
1583 int emcore_mime_get_content_data(void *stream, int is_file, int is_text, char *boundary_str, char *content_encoding, int *end_of_parsing, int mode, char **holder, int *size, void *callback, int *err_code) 
1584
1585         EM_DEBUG_FUNC_BEGIN("stream[%p], is_file[%d], boundary_str[%s], content_encoding[%s], end_of_parsing[%p], mode[%d], holder[%p], size[%p], callback[%p], err_code[%p]", stream, is_file, boundary_str, content_encoding, end_of_parsing, mode, holder, size, callback, err_code);
1586         
1587         char buf[MIME_LINE_LEN] = {0x00, };
1588         char boundary[BOUNDARY_LEN] = {0x00, };
1589         char boundary_end[BOUNDARY_LEN] = {0x00, };
1590         char *result_buffer = NULL;
1591         int sz = 0, fd = 0, result_buffer_size = 0;;
1592         int encoding = ENC7BIT;
1593         int dec_len = 0; 
1594         int error = EMAIL_ERROR_NONE, ret = false;
1595         char *pTemp = NULL;
1596
1597         if ((mode == SAVE_TYPE_FILE || mode == SAVE_TYPE_BUFFER) && !holder)
1598                 return false;
1599
1600         if (holder) 
1601                 *holder = NULL;
1602
1603         if (size) 
1604                 *size = 0;
1605
1606         EM_DEBUG_LOG("get content");
1607         
1608         if (content_encoding)  {
1609                 switch (content_encoding[0])  {
1610                         case 'Q': 
1611                                 encoding = ENCQUOTEDPRINTABLE;
1612                                 break;  /*  qutoed-printabl */
1613                         case 'B': 
1614                                 if (content_encoding[1] == 'A')  {
1615                                         encoding = ENCBASE64;
1616                                         break; /*  base6 */
1617                                 }
1618                                 if (content_encoding[1] == 'I')  {
1619                                         encoding = ENCBINARY;
1620                                         break; /*  binar */
1621                                 }
1622                                 encoding = ENC7BIT;
1623                                 break;
1624                         case '7': 
1625                                 encoding = ENC7BIT;
1626                                 break; /*  7bi */
1627                         case '8': 
1628                                 encoding = ENC8BIT;
1629                                 break; /*  8bi */
1630                         default: 
1631                                 encoding = ENCOTHER;
1632                                 break; /*  unknow */
1633                 }
1634         }
1635
1636         /*  saving type is file */
1637         if (mode == SAVE_TYPE_FILE)  {
1638                 *holder = emcore_mime_get_save_file_name(err_code);
1639                 
1640                 EM_DEBUG_LOG("holder[%s]", *holder);
1641                 
1642                 fd = open(*holder, O_WRONLY|O_CREAT, 0644);
1643                 if (fd <= 0)  {
1644                         EM_DEBUG_EXCEPTION("holder open failed :  holder is a filename that will be saved.");
1645                         goto FINISH_OFF;
1646                 }
1647         }
1648
1649         if (boundary_str) {
1650                 /*  if there boundary, this content is from current line to ending boundary */
1651                 memset(boundary, 0x00, BOUNDARY_LEN);
1652                 memset(boundary_end, 0x00, BOUNDARY_LEN);
1653                 
1654                 SNPRINTF(boundary, BOUNDARY_LEN, "--%s%s", boundary_str, CRLF_STRING); 
1655                 SNPRINTF(boundary_end, BOUNDARY_LEN, "--%s%s", boundary_str, "--\r\n");
1656         }
1657         
1658         while (TRUE) {
1659                 if (!emcore_check_thread_status())  {
1660                         EM_DEBUG_EXCEPTION("EMAIL_ERROR_CANCELLED");
1661                         error = EMAIL_ERROR_CANCELLED;
1662                         goto FINISH_OFF;
1663                 }
1664         
1665                 if ((is_file == 0 && !emcore_mime_get_line_from_sock(stream, buf, MIME_LINE_LEN, &error)) || 
1666                 (is_file == 1 && !emcore_get_line_from_file(stream, buf, MIME_LINE_LEN, &error)))  {
1667                         if (error == EMAIL_ERROR_NO_MORE_DATA)
1668                                 EM_DEBUG_EXCEPTION("End of data");
1669                         else
1670                                 EM_DEBUG_EXCEPTION("emcore_mime_get_line_from_sock failed");
1671                                 *end_of_parsing = 1;
1672                                 
1673                         ret = true;
1674                         goto FINISH_OFF; 
1675                 } 
1676                                 
1677                 if (boundary_str)  {
1678                         if (!strcmp(buf, boundary))  {  /*  the other part started. the parsing of other part will be started */
1679                                 *end_of_parsing = 0;
1680                                 ret = true; 
1681                                 goto FINISH_OFF; 
1682                         }
1683                         else if (!strcmp(buf, boundary_end))  { /*  if ending boundary, the parsing of other multipart will be started */
1684                                 *end_of_parsing = 1;
1685                                 ret = true;
1686                                 goto FINISH_OFF; 
1687                         } 
1688                 }
1689                         
1690                         /*  parsing string started by '.' in POP3 */
1691                 if ((buf[0] == '.' && buf[1] == '.') && (encoding == ENCQUOTEDPRINTABLE || encoding == ENC7BIT))  {
1692                                 strncpy(buf, buf+1, MIME_LINE_LEN-1);
1693                                 buf[strlen(buf)] = NULL_CHAR;
1694                 }
1695                         
1696                 if (encoding == ENCBASE64)  {
1697                                 if (strlen(buf) >= 2)
1698                                         buf[strlen(buf)-2] = NULL_CHAR;
1699                 } else if (encoding == ENCQUOTEDPRINTABLE)  {
1700 /*                      if (strcmp(buf, CRLF_STRING) == 0 */
1701 /*                                      continue */
1702                 }
1703                         
1704                 dec_len = strlen(buf);
1705                         
1706                 if (mode > SAVE_TYPE_SIZE) {    /*  decode content */
1707                         emcore_decode_body_text(buf, dec_len, encoding, &dec_len, err_code);
1708                         EM_DEBUG_LOG("decode buf : [%s]", buf);
1709
1710                         if (is_text) {
1711                                 result_buffer = em_replace_string(buf, "cid:", "");
1712                                 if (result_buffer)
1713                                         result_buffer_size = strlen(result_buffer);
1714                         }
1715
1716                         if (result_buffer == NULL) {
1717                                 result_buffer      = buf;
1718                                 result_buffer_size = dec_len;
1719                         }
1720
1721                         if (mode == SAVE_TYPE_BUFFER)  {   /*  save content to buffer */
1722                                 pTemp = realloc(*holder, sz + result_buffer_size + 2);
1723                                 if (!pTemp)  {
1724                                         EM_DEBUG_EXCEPTION("realloc failed...");
1725                                                 error = EMAIL_ERROR_OUT_OF_MEMORY;
1726
1727                                                 EM_SAFE_FREE(*holder);
1728                                                 EM_SAFE_FREE(result_buffer);
1729                                                 goto FINISH_OFF; 
1730                                 }
1731                                         else 
1732                                         *holder = pTemp;
1733                                 
1734                                         memcpy(*holder + sz, result_buffer, result_buffer_size);
1735                                         (*holder)[sz + strlen(result_buffer) + 1] = NULL_CHAR;
1736                         } else if (mode == SAVE_TYPE_FILE)  {   /*  save content to file */
1737                                 if (write(fd, result_buffer, result_buffer_size) != result_buffer_size)  {
1738                                         if (is_text && (result_buffer != buf))
1739                                                 EM_SAFE_FREE(result_buffer);
1740                                         EM_DEBUG_EXCEPTION("write failed");
1741                                         error = EMAIL_ERROR_SYSTEM_FAILURE;
1742                                         goto FINISH_OFF; 
1743                                 }
1744                         }
1745
1746                         if (is_text && (result_buffer != buf))
1747                                 EM_SAFE_FREE(result_buffer);    
1748                         result_buffer = NULL;
1749                 }
1750                 sz += dec_len;
1751         }
1752                 
1753         ret = true;
1754 FINISH_OFF: 
1755         if (err_code != NULL)
1756                 *err_code = error;
1757                                 
1758         if (fd > 0) 
1759                 close(fd);
1760
1761         if (ret) {
1762                 if (size)
1763                         *size = sz;
1764         } 
1765                         
1766         EM_DEBUG_FUNC_END("ret [%d], sz [%d]", ret, sz);
1767         return ret; 
1768
1769
1770 int emcore_mime_skip_content_data(void *stream, 
1771                                                         int is_file, 
1772                                                         char *boundary_str, 
1773                                                         int *end_of_parsing, 
1774                                                         int *size, 
1775                                                         void *callback, 
1776                                                         int *err_code) 
1777
1778         EM_DEBUG_FUNC_BEGIN("stream[%p], is_file[%d], boundary_str[%s], end_of_parsing[%p], size[%p], callback[%p], err_code[%p]", stream, is_file, boundary_str, end_of_parsing, size, callback, err_code);
1779         
1780         char buf[MIME_LINE_LEN] = {0x00}, boundary[BOUNDARY_LEN], boundary_end[BOUNDARY_LEN];
1781         int sz = 0; 
1782
1783         if (size) 
1784                 *size = 0;
1785
1786         EM_DEBUG_LOG(">>> skip content <<<<<<<<<<<<<");
1787
1788         if (!boundary_str)  {   /*  if no boundary, this content is from current line to end of all multipart */
1789                 while (TRUE)  {
1790                         
1791                         if (!emcore_check_thread_status())  {
1792                                 if (err_code != NULL)
1793                                         *err_code = EMAIL_ERROR_CANCELLED;
1794                                 return false;
1795                         }
1796                         if ((is_file == 0 && !emcore_mime_get_line_from_sock(stream, buf, MIME_LINE_LEN, err_code)) || 
1797                         (is_file == 1 && !emcore_get_line_from_file(stream, buf, MIME_LINE_LEN, err_code)))  {
1798                                 *end_of_parsing = 1; 
1799                                 if (size) 
1800                                         *size = sz;
1801                                 return false; 
1802                         }
1803                         sz += strlen(buf);
1804                 }
1805         } 
1806         else  {         /*  if there boundary, this content is from current line to ending boundary */
1807                 memset(boundary, 0x00, BOUNDARY_LEN);
1808                 memset(boundary_end, 0x00, BOUNDARY_LEN);
1809                 
1810                 SNPRINTF(boundary,  BOUNDARY_LEN, "--%s%s", boundary_str, CRLF_STRING); 
1811                 SNPRINTF(boundary_end, BOUNDARY_LEN, "--%s%s", boundary_str, "--\r\n");
1812                 
1813                 while (TRUE)  {
1814
1815                         if (!emcore_check_thread_status())  {
1816                                 if (err_code != NULL)
1817                                         *err_code = EMAIL_ERROR_CANCELLED;
1818                                 return false;
1819                         }
1820                         if ((is_file == 0 && !emcore_mime_get_line_from_sock(stream, buf, MIME_LINE_LEN, err_code)) || 
1821                         (is_file == 1 && !emcore_get_line_from_file(stream, buf, MIME_LINE_LEN, err_code)))  {
1822                                 /*  end of fil */
1823                                 *end_of_parsing = 1; 
1824                                 if (size) 
1825                                         *size = sz;
1826                                 return true; 
1827                         } 
1828                         
1829                         if (!strcmp(buf, boundary))  {          /*  the other part started. the parsing of other part will be started */
1830                                 *end_of_parsing = 0; 
1831                                 if (size) 
1832                                         *size = sz;
1833                                 return true; 
1834                         } 
1835                         else if (!strcmp(buf, boundary_end))  {         /*  if ending boundary, the parsing of other multipart will be started */
1836                                 *end_of_parsing = 1; 
1837                                 if (size) 
1838                                         *size = sz;
1839                                 return true; 
1840                         } 
1841                         
1842                         sz += strlen(buf);
1843                 } 
1844         } 
1845
1846         if (size) 
1847                 *size = sz;
1848         EM_DEBUG_FUNC_END();
1849         return true; 
1850
1851
1852 /*  get temporary file nam */
1853 char *emcore_mime_get_save_file_name(int *err_code) 
1854
1855         EM_DEBUG_FUNC_BEGIN();
1856         char tempname[512];
1857         struct timeval tv;
1858
1859         gettimeofday(&tv, NULL);
1860         srand(tv.tv_usec);
1861
1862         memset(tempname, 0x00, sizeof(tempname));
1863
1864         SNPRINTF(tempname, sizeof(tempname), "%s%s%s%s%d", MAILHOME, DIR_SEPERATOR, MAILTEMP, DIR_SEPERATOR, rand());
1865         EM_DEBUG_FUNC_END();
1866         return EM_SAFE_STRDUP(tempname);
1867
1868
1869 /*  get a line from file pointer */
1870 char *emcore_get_line_from_file(void *stream, char *buf, int size, int *err_code)
1871 {
1872         if (!fgets(buf, size, (FILE *)stream))  {
1873                 if (feof((FILE *)stream))
1874                         return NULL;
1875                 else
1876                         return NULL;
1877         }
1878         return buf;
1879 }
1880
1881 /*  get a line from POP3 mail stream */
1882 /*  emcore_mail_cmd_read_mail_pop3 must be called before this function */
1883 char *emcore_mime_get_line_from_sock(void *stream, char *buf, int size, int *err_code)
1884 {
1885         EM_DEBUG_FUNC_BEGIN("stream[%p], buf[%p]", stream, buf);
1886         POP3LOCAL *p_pop3local = NULL;
1887         
1888         if (!stream || !buf)  {
1889                 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
1890                 if (err_code != NULL)
1891                         *err_code = EMAIL_ERROR_INVALID_PARAM;
1892                 return NULL;
1893         }
1894         
1895         memset(buf, 0x00, size);
1896         
1897         p_pop3local = (POP3LOCAL *)(((MAILSTREAM *)stream)->local);
1898         if (!p_pop3local)  {
1899                 EM_DEBUG_EXCEPTION("stream->local[%p]", p_pop3local);
1900                 if (err_code != NULL)
1901                         *err_code = EMAIL_ERROR_INVALID_PARAM;
1902                 return NULL;
1903         }
1904         
1905         if (!pop3_reply((MAILSTREAM *)stream))  { /*  if TRUE, check respons */
1906                 EM_DEBUG_LOG("p_pop3local->response 1[%s]", p_pop3local->response);
1907                 if (p_pop3local->response) {
1908                         if (*p_pop3local->response == '.' && strlen(p_pop3local->response) == 1)  {
1909                                 free(p_pop3local->response); 
1910                                 p_pop3local->response = NULL;
1911                                 if (err_code != NULL)
1912                                         *err_code = EMAIL_ERROR_NO_MORE_DATA;
1913                                 EM_DEBUG_FUNC_END("end of response");
1914                                 return NULL;
1915                         }
1916                         EM_DEBUG_LOG("Not end of response");
1917                         strncpy(buf, p_pop3local->response, size-1);
1918                         strncat(buf, CRLF_STRING, size-(strlen(buf) + 1));
1919                 
1920                         free(p_pop3local->response); 
1921                         p_pop3local->response = NULL;
1922
1923                         goto FINISH_OFF;
1924                 }
1925         }
1926         
1927         EM_DEBUG_LOG("p_pop3local->response 2[%s]", p_pop3local->response);
1928         if (p_pop3local->response) 
1929        {
1930                 /*  if response isn't NULL, check whether this response start with '+' */
1931                 /*  if the first character is '+', return error because this response is normal data */
1932                 strncpy(buf, p_pop3local->response, size-1);
1933                 strncat(buf, CRLF_STRING, size-(strlen(buf)+1));
1934                 free(p_pop3local->response); p_pop3local->response = NULL;
1935                 goto FINISH_OFF;
1936        }
1937         else  {
1938                 EM_DEBUG_EXCEPTION("p_pop3local->response is null. network error... ");
1939                 if (err_code != NULL)
1940                         *err_code = EMAIL_ERROR_INVALID_RESPONSE;
1941                 EM_DEBUG_FUNC_END();
1942                 return NULL;
1943         }
1944
1945 FINISH_OFF: 
1946         if (buf) {
1947                 int received_percentage, last_notified_percentage;
1948                 _pop3_received_body_size += strlen(buf);
1949
1950                 last_notified_percentage = (double)_pop3_last_notified_body_size / (double)_pop3_total_body_size *100.0;
1951                 received_percentage      = (double)_pop3_received_body_size / (double)_pop3_total_body_size *100.0;
1952
1953                 EM_DEBUG_LOG("_pop3_received_body_size = %d, _pop3_total_body_size = %d", _pop3_received_body_size, _pop3_total_body_size);
1954                 EM_DEBUG_LOG("received_percentage = %d, last_notified_percentage = %d", received_percentage, last_notified_percentage);
1955                 
1956                 if (received_percentage > last_notified_percentage + 5) {
1957                         if (!emstorage_notify_network_event(NOTI_DOWNLOAD_BODY_START, _pop3_receiving_mail_id, "dummy-file", _pop3_total_body_size, _pop3_received_body_size))
1958                                 EM_DEBUG_EXCEPTION(" emstorage_notify_network_event [NOTI_DOWNLOAD_BODY_START] Failed >>>> ");
1959                         else
1960                                 EM_DEBUG_LOG("NOTI_DOWNLOAD_BODY_START notified (%d / %d)", _pop3_received_body_size, _pop3_total_body_size);
1961                         _pop3_last_notified_body_size = _pop3_received_body_size;
1962                 }
1963         }
1964         EM_DEBUG_FUNC_END();
1965         return buf;
1966 }
1967
1968 void emcore_mime_free_param(struct _parameter *param)
1969 {
1970         struct _parameter *t, *p = param;
1971         EM_DEBUG_FUNC_BEGIN();
1972         while (p) {
1973                 t = p->next;
1974                 EM_SAFE_FREE(p->name);
1975                 EM_SAFE_FREE(p->value);
1976                 free(p);p = NULL;
1977                 p = t;
1978         }
1979         EM_DEBUG_FUNC_END();
1980 }
1981
1982 void emcore_mime_free_part_header(struct _m_part_header *header)
1983 {
1984         EM_DEBUG_FUNC_BEGIN();
1985         if (!header) return ;
1986         EM_SAFE_FREE(header->type);
1987         if (header->parameter) emcore_mime_free_param(header->parameter);
1988         EM_SAFE_FREE(header->subtype);
1989         EM_SAFE_FREE(header->encoding);
1990         EM_SAFE_FREE(header->desc);
1991         EM_SAFE_FREE(header->disp_type);
1992         if (header->disp_parameter) emcore_mime_free_param(header->disp_parameter);
1993         free(header); header = NULL;
1994         EM_DEBUG_FUNC_END();
1995 }
1996
1997 void emcore_mime_free_message_header(struct _m_mesg_header *header)
1998 {
1999         EM_DEBUG_FUNC_BEGIN();
2000         if (!header) return ;
2001         EM_SAFE_FREE(header->version);
2002         if (header->part_header) emcore_mime_free_part_header(header->part_header);
2003         free(header); header = NULL;
2004         EM_DEBUG_FUNC_END();
2005 }
2006
2007 void emcore_mime_free_rfc822_header(struct _rfc822header *header)
2008 {
2009         EM_DEBUG_FUNC_BEGIN();
2010         if (!header) return ;
2011         EM_SAFE_FREE(header->return_path);
2012         EM_SAFE_FREE(header->received);
2013         EM_SAFE_FREE(header->reply_to);
2014         EM_SAFE_FREE(header->date);
2015         EM_SAFE_FREE(header->from);
2016         EM_SAFE_FREE(header->subject);
2017         EM_SAFE_FREE(header->sender);
2018         EM_SAFE_FREE(header->to);       
2019         EM_SAFE_FREE(header->cc);
2020         EM_SAFE_FREE(header->bcc);
2021         free(header); header = NULL;
2022         EM_DEBUG_FUNC_END();
2023 }
2024
2025 void emcore_mime_free_part_body(struct _m_body *body)
2026 {
2027         EM_DEBUG_FUNC_BEGIN();
2028         if (!body) return ;
2029         if (body->part_header) emcore_mime_free_part_header(body->part_header);
2030         EM_SAFE_FREE(body->text);
2031         if (body->nested.body) emcore_mime_free_part_body(body->nested.body);
2032         if (body->nested.next) emcore_mime_free_part(body->nested.next);
2033         free(body); body = NULL;
2034         EM_DEBUG_FUNC_END();
2035 }
2036
2037 void emcore_mime_free_part(struct _m_part *part)
2038 {
2039         EM_DEBUG_FUNC_BEGIN();
2040         if (!part) return ;
2041         if (part->body) emcore_mime_free_part_body(part->body);
2042         if (part->next) emcore_mime_free_part(part->next);
2043         free(part);part = NULL;
2044         EM_DEBUG_FUNC_END();
2045 }
2046
2047 void emcore_mime_free_mime(struct _m_mesg *mmsg)
2048 {
2049         EM_DEBUG_FUNC_BEGIN();
2050         
2051         if (!mmsg) return ;
2052         if (mmsg->header) emcore_mime_free_message_header(mmsg->header);
2053         if (mmsg->rfc822header) emcore_mime_free_rfc822_header(mmsg->rfc822header);
2054         if (mmsg->nested.body) emcore_mime_free_part_body(mmsg->nested.body);
2055         if (mmsg->nested.next) emcore_mime_free_part(mmsg->nested.next);
2056         EM_SAFE_FREE(mmsg->text);
2057         free(mmsg); mmsg = NULL;
2058         EM_DEBUG_FUNC_END();
2059 }
2060
2061 void emcore_free_content_info(struct _m_content_info *cnt_info)
2062 {
2063         EM_DEBUG_FUNC_BEGIN();
2064         struct attachment_info *p;
2065         
2066         if (!cnt_info) return ;
2067         EM_SAFE_FREE(cnt_info->text.plain);
2068         EM_SAFE_FREE(cnt_info->text.plain_charset);
2069         EM_SAFE_FREE(cnt_info->text.html);
2070         while (cnt_info->file) {
2071                 p = cnt_info->file->next;
2072                 EM_SAFE_FREE(cnt_info->file->name);
2073                 EM_SAFE_FREE(cnt_info->file->save);
2074                 EM_SAFE_FREE(cnt_info->file->attachment_mime_type);
2075                 EM_SAFE_FREE(cnt_info->file->content_id);
2076                 free(cnt_info->file); cnt_info->file = NULL;
2077                 cnt_info->file = p;
2078         }
2079         free(cnt_info);cnt_info = NULL;
2080         EM_DEBUG_FUNC_END();
2081 }
2082
2083 /* get body-part in nested part */
2084 static PARTLIST *emcore_get_allnested_part_full(MAILSTREAM *stream, int msg_uid, BODY *body, struct _m_content_info *cnt_info, int *err_code, PARTLIST *section_list)
2085 {
2086         EM_DEBUG_FUNC_BEGIN("stream[%p], msg_uid[%d], body[%p], cnt_info[%p], err_code[%p]", stream, msg_uid, body, cnt_info, err_code);
2087         
2088         PART *part_child = body->nested.part;
2089         
2090         while (part_child) {
2091                 section_list = emcore_get_body_full(stream, msg_uid, &part_child->body, cnt_info, err_code, section_list);              
2092                 part_child = part_child->next;
2093         }
2094
2095         return section_list;
2096 }
2097
2098 /* get body-part in alternative multiple part */
2099 static PARTLIST *emcore_get_alternative_multi_part_full(MAILSTREAM *stream, int msg_uid, BODY *body, struct _m_content_info *cnt_info, int *err_code, PARTLIST *section_list)
2100 {
2101         EM_DEBUG_FUNC_BEGIN("stream[%p], msg_uid[%d], body[%p], cnt_info[%p], err_code[%p]", stream, msg_uid, body, cnt_info, err_code);
2102         
2103         PART *part_child = body->nested.part;
2104
2105         /* find the best sub part we can show */
2106         while (part_child)  {
2107                 section_list = emcore_get_body_full(stream, msg_uid, &part_child->body, cnt_info, err_code, section_list);              
2108                 part_child = part_child->next;
2109         }
2110         
2111         return section_list;
2112 }
2113
2114 /* get body part in signed multiple part */
2115 static PARTLIST *emcore_get_signed_multi_part_full(MAILSTREAM *stream, int msg_uid, BODY *body, struct _m_content_info *cnt_info, int *err_code, PARTLIST *section_list)
2116 {
2117         EM_DEBUG_FUNC_BEGIN("stream[%p], msg_uid[%d], body[%p], cnt_info[%p], err_code[%p]", stream, msg_uid, body, cnt_info, err_code);
2118
2119         PART *part_child = body->nested.part;
2120
2121         /* find the best sub part we can show */
2122         while (part_child)  {
2123                 section_list = emcore_get_body_full(stream, msg_uid, &part_child->body, cnt_info, err_code, section_list);              
2124                 part_child = part_child->next;
2125         }
2126         
2127         return section_list;
2128 }
2129
2130 /* get body part in encrypted multiple part */
2131 static PARTLIST *emcore_get_encrypted_multi_part_full(MAILSTREAM *stream, int msg_uid, BODY *body, struct _m_content_info *cnt_info, int *err_code, PARTLIST *section_list)
2132 {
2133         EM_DEBUG_FUNC_BEGIN("stream[%p], msg_uid[%d], body[%p], cnt_info[%p], err_code[%p]", stream, msg_uid, body, cnt_info, err_code);
2134         
2135         /*  "protocol" = "application/pgp-encrypted */
2136         return section_list;
2137 }
2138
2139 /* get body part in multiple part */
2140 static PARTLIST *emcore_get_multi_part_full(MAILSTREAM *stream, int msg_uid, BODY *body, struct _m_content_info *cnt_info, int *err_code, PARTLIST *section_list)
2141 {
2142         EM_DEBUG_FUNC_BEGIN("stream[%p], msg_uid[%d], body[%p], cnt_info[%p], err_code[%p]", stream, msg_uid, body, cnt_info, err_code);
2143         
2144         switch (body->subtype[0])  {
2145                 case 'A':               /*  ALTERNATIV */
2146                         return section_list = emcore_get_alternative_multi_part_full(stream, msg_uid, body, cnt_info, err_code, section_list);
2147                 
2148                 case 'S':               /*  SIGNE */
2149                         return section_list = emcore_get_signed_multi_part_full(stream, msg_uid, body, cnt_info, err_code, section_list);
2150                 
2151                 case 'E':               /*  ENCRYPTE */
2152                         return section_list = emcore_get_encrypted_multi_part_full(stream, msg_uid, body, cnt_info, err_code, section_list);
2153                 
2154                 default:                /*  process all unknown as MIXED (according to the RFC 2047 */
2155                         return section_list = emcore_get_allnested_part_full(stream, msg_uid, body, cnt_info, err_code, section_list);
2156         }
2157 }
2158
2159
2160 PARTLIST* emcore_get_body_full(MAILSTREAM *stream, int msg_uid, BODY *body, struct _m_content_info *cnt_info, int *err_code, PARTLIST *section_list)
2161 {
2162         EM_DEBUG_FUNC_BEGIN("stream[%p], msg_uid[%d], body[%p], cnt_info[%p], err_code[%p]", stream, msg_uid, body, cnt_info, err_code);
2163         char content_type_buffer[512] = { 0, };
2164         
2165         if (!stream || !body || !cnt_info)  {
2166                 EM_DEBUG_EXCEPTION("stream[%p], msg_uid[%d], body[%p], cnt_info[%p]", stream, msg_uid, body, cnt_info);
2167                 
2168                 if (err_code != NULL)
2169                         *err_code = EMAIL_ERROR_INVALID_PARAM;
2170                 return NULL;
2171         }
2172         
2173         switch (body->type)  {
2174                 case TYPEMULTIPART: 
2175                         return section_list = emcore_get_multi_part_full(stream, msg_uid, body, cnt_info, err_code, section_list);
2176                 
2177                 case TYPEMESSAGE:
2178                         break;
2179                         
2180                 case TYPETEXT:
2181                 case TYPEAPPLICATION: 
2182                 case TYPEAUDIO:
2183                 case TYPEIMAGE:
2184                 case TYPEVIDEO:
2185                 case TYPEMODEL:
2186                 case TYPEOTHER:
2187
2188                         /* Form list of attachment followed by list of inline images */
2189                         if (body->id || body->location || body->disposition.type) {
2190
2191                                 char filename[512] = {0, };
2192                                 struct attachment_info **ai = NULL;
2193                                 struct attachment_info *prev_ai = NULL;
2194                                 struct attachment_info *next_ai = NULL;
2195                                 int i = 0;
2196                                 
2197                                 if (emcore_get_file_pointer(body, true, filename, cnt_info, (int*)NULL) < 0)
2198                                         EM_DEBUG_EXCEPTION("emcore_get_file_pointer failed");
2199                                 else {
2200                                         /* To form list of attachment info - Attachment list followed by inline attachment list */
2201                                         prev_ai = NULL;
2202                                         next_ai = NULL;
2203                                         ai      = &cnt_info->file;
2204                                         
2205                                         EM_DEBUG_LOG(" ai - %p ", (*ai));
2206
2207                                         if (ai != NULL) {
2208                                                 /* if ((body->id) || (body->location) */
2209                                                 if ((body->id) || (body->location) || ((body->disposition.type != NULL) && ((body->disposition.type[0] == 'i') || (body->disposition.type[0] == 'I')))) {
2210                                                         /* For Inline content append to the end */
2211                                                         for (i = 1; *ai; ai = &(*ai)->next)
2212                                                                 i++;
2213                                                 }
2214                                                 else {
2215                                                         /* For attachment - search till Inline content found and insert before inline */
2216                                                         for (i = 1; *ai; ai = &(*ai)->next) {
2217                                                                 if ((*ai)->type == 1)  {
2218                                                                         /* Means inline image */
2219                                                                         EM_DEBUG_LOG("Found Inline Content ");
2220                                                                         next_ai = (*ai);
2221                                                                         break;
2222                                                                 }
2223                                                                 i++;
2224                                                                 prev_ai = (*ai);
2225                                                         }
2226                                                 }
2227                                         }
2228                                         if (!(*ai = em_malloc(sizeof(struct attachment_info))))  {
2229                                                 EM_DEBUG_EXCEPTION("em_malloc failed...");
2230                                         }
2231                                         else {
2232                                                 if (ai == NULL)
2233                                                         cnt_info->file = (*ai);
2234
2235                                                 if ((body->id) || (body->location) || ((body->disposition.type != NULL) && ((body->disposition.type[0] == 'i') || (body->disposition.type[0] == 'I'))))
2236                                                         (*ai)->type = 1; /* inline contents */
2237                                                 else
2238                                                         (*ai)->type = 2; /* attachment */
2239                                                 
2240                                                 (*ai)->name                 = EM_SAFE_STRDUP(filename);
2241                                                 (*ai)->size                 = body->size.bytes;
2242                                                 (*ai)->content_id           = EM_SAFE_STRDUP(body->id);
2243                                                 if ( emcore_get_content_type_from_mail_bodystruct(body, 512, content_type_buffer) == EMAIL_ERROR_NONE)
2244                                                         (*ai)->attachment_mime_type = EM_SAFE_STRDUP(content_type_buffer);
2245                                                 
2246 #ifdef __ATTACHMENT_OPTI__
2247                                                 (*ai)->encoding = body->encoding;
2248                                                 if (body->sparep)
2249                                                         (*ai)->section = EM_SAFE_STRDUP(body->sparep);
2250
2251                                                 EM_DEBUG_LOG(" Encoding - %d  Section No - %s ", (*ai)->encoding, (*ai)->section);
2252 #endif
2253                                                 
2254                                                 EM_DEBUG_LOG("Type[%d], Name[%s],  Path[%s] ", (*ai)->type, (*ai)->name, (*ai)->save);
2255                                                 if (body->type == TYPEAPPLICATION)  {
2256                                                         if (!strcasecmp(body->subtype, MIME_SUBTYPE_DRM_OBJECT))
2257                                                                 (*ai)->drm = EMAIL_ATTACHMENT_DRM_OBJECT;
2258                                                         else if (!strcasecmp(body->subtype, MIME_SUBTYPE_DRM_RIGHTS))
2259                                                                 (*ai)->drm = EMAIL_ATTACHMENT_DRM_RIGHTS;
2260                                                         else if (!strcasecmp(body->subtype, MIME_SUBTYPE_DRM_DCF))
2261                                                                 (*ai)->drm = EMAIL_ATTACHMENT_DRM_DCF;
2262                                                         else if (!strcasecmp(body->subtype, "pkcs7-mime"))
2263                                                                 cnt_info->grab_type = cnt_info->grab_type | GRAB_TYPE_ATTACHMENT;
2264                                                 } 
2265                                         
2266                                                 if ((*ai)->type != 1 && next_ai != NULL) {
2267                                                         /* Means next_ai points to the inline attachment info structure */
2268                                                         if (prev_ai == NULL) {
2269                                                                 /* First node is inline attachment */
2270                                                                 (*ai)->next = next_ai;
2271                                                                 cnt_info->file = (*ai);
2272                                                         }
2273                                                         else {
2274                                                                 prev_ai->next = (*ai);
2275                                                                 (*ai)->next = next_ai;
2276                                                         }
2277                                                 }
2278                                         }
2279                                 }
2280
2281                         }
2282                                                         
2283                         
2284                         /* if (cnt_info->grab_type == GRAB_TYPE_ATTACHMENT */
2285                         if (cnt_info->grab_type & GRAB_TYPE_ATTACHMENT) {
2286                                 if (((body->disposition.type != NULL) && ((body->disposition.type[0] == 'a') || (body->disposition.type[0] == 'A'))) && (cnt_info->file != NULL)) {
2287                                         PARAMETER *param = NULL;        
2288                                         char *fn = NULL;
2289
2290                                         param = body->parameter;
2291                                                                                 
2292                                         while (param)  {
2293                                                 if (!strcasecmp(param->attribute, "NAME")) {
2294                                                         fn = EM_SAFE_STRDUP(param->value);                                                                      
2295                                                         break;
2296                                                 }
2297                                                 if (!strcasecmp(param->attribute, "FILENAME")) {
2298                                                         fn = EM_SAFE_STRDUP(param->value);                                                                      
2299                                                         break;
2300                                                 }
2301                                                 param = param->next;
2302                                         }
2303                                         if ((fn != NULL)&& (!strcmp(fn, cnt_info->file->name)) && (body->size.bytes == cnt_info->file->size)) /*  checks to zero in on particular attachmen */ {
2304                                                 section_list = emcore_add_node(section_list, body);
2305                                                 if (section_list == NULL) {
2306                                                         EM_DEBUG_EXCEPTION("adding  node to section list failed");
2307                                                         EM_SAFE_FREE(fn);       
2308                                                         return NULL;
2309                                                 }
2310                                                 else {
2311                                                         EM_SAFE_FREE(fn);
2312                                                         return section_list;    /* single attachment download, so if a match found break the recursio */
2313                                                 }
2314                                         }
2315                                         EM_SAFE_FREE(fn);
2316                                 }                                       
2317                         }
2318                         else {
2319                                 /* get a section list which has only plain, html and inline */
2320                                 if (!((body->disposition.type != NULL) && ((body->disposition.type[0] == 'a') || (body->disposition.type[0] == 'A'))))/*  if the body not an attachmen */ {
2321                                         section_list = emcore_add_node(section_list, body);
2322                                         if (section_list == NULL) {
2323                                                 EM_DEBUG_EXCEPTION("adding  node to section list failed");      
2324                                                 return NULL;
2325                                         }
2326                                 }
2327                         }
2328                                 
2329                         break;
2330                 
2331                 default: 
2332                         break;
2333         }
2334         
2335         return section_list;
2336 }
2337
2338 INTERNAL_FUNC int emcore_get_body_part_list_full(MAILSTREAM *stream, int msg_uid, int account_id, int mail_id, BODY *body, struct _m_content_info *cnt_info, int *err_code, PARTLIST *section_list, int event_handle)
2339 {
2340         EM_DEBUG_FUNC_BEGIN("stream[%p], msg_uid[%d], body[%p], cnt_info[%p], err_code[%p]", stream, msg_uid, body, cnt_info, err_code);
2341         
2342         if (!stream || !body || !cnt_info)  {
2343                 EM_DEBUG_EXCEPTION("stream[%p], msg_uid[%d], body[%p], cnt_info[%p]", stream, msg_uid, body, cnt_info);
2344                 
2345                 if (err_code != NULL)
2346                         *err_code = EMAIL_ERROR_INVALID_PARAM;
2347                 return FAILURE;
2348         }
2349         section_list = emcore_get_body_full(stream, msg_uid, body, cnt_info, err_code, section_list); 
2350
2351         if (section_list == NULL) {
2352                 /*  assumed at least one body part exist */
2353                 EM_DEBUG_EXCEPTION("emcore_get_body_full failed");
2354                 return FAILURE;
2355         }
2356
2357         if (emcore_get_body_part_imap_full(stream, msg_uid, account_id, mail_id, section_list, cnt_info, err_code, event_handle) < 0) {
2358                 EM_DEBUG_EXCEPTION("emcore_get_body_part_imap_full failed");
2359                 emcore_free_section_list(section_list);
2360                 return FAILURE;
2361         }
2362         emcore_free_section_list(section_list);
2363         return SUCCESS;
2364 }
2365
2366 static int emcore_write_response_into_file(char *filename, char *write_mode, char *encoded, int encoding_type, char *subtype, int account_id, int mail_id, int *err)
2367 {
2368         EM_DEBUG_FUNC_BEGIN();
2369         int temp_decoded_len = 0;
2370         int inline_support = 0;
2371         int ret = false;
2372         int error = EMAIL_ERROR_NONE;
2373         int not_found = true;
2374         int encoded_len = 0;
2375         int written_bytes = 0;
2376         unsigned long decoded_len = 0;
2377         char *decoded = NULL;
2378         char *decoded_temp = NULL;
2379         char save_file_name[MAX_PATH+1] = {0, };
2380         char html_cid_path[MAX_PATH+1] = {0, };
2381         FILE *fp = NULL;
2382         PARAMETER *param = NULL;
2383         PARAMETER *param1 = NULL;
2384
2385
2386         if (!encoded || !filename || !write_mode) {
2387                 EM_DEBUG_EXCEPTION("Invalid Param ");
2388                 error = EMAIL_ERROR_INVALID_PARAM;
2389                 goto FINISH_OFF;
2390         }
2391         
2392
2393         EM_DEBUG_LOG("Encoded buffer length [%d]", strlen(encoded));
2394         encoded_len = strlen(encoded);
2395         
2396         EM_DEBUG_LOG("encoding_type [%d]", encoding_type);
2397         switch (encoding_type)  {
2398                 case ENCQUOTEDPRINTABLE:   {
2399                         unsigned char *orignal = (unsigned char *)g_strdup_printf("%s\r\n", encoded);
2400                         decoded = (char *)rfc822_qprint(orignal, encoded_len + 2, &decoded_len);
2401                         g_free(orignal);
2402                         break;
2403                 }
2404         
2405                 case ENCBASE64:
2406                         decoded = (char *)rfc822_base64((unsigned char *)encoded, encoded_len, &decoded_len);
2407                         break;
2408         
2409                 default:  {
2410                         unsigned char *orignal = (unsigned char *)g_strdup_printf("%s\r\n", encoded);
2411                         memcpy(decoded = malloc(encoded_len + 3), orignal, encoded_len + 3);
2412                         decoded_len = encoded_len + 2;
2413                         g_free(orignal);
2414                 }
2415                 break;
2416         }
2417
2418         if (decoded != NULL)  {
2419                 EM_DEBUG_LOG("Decoded Length [%d] " , decoded_len);
2420                 EM_DEBUG_LOG("filename [%s] " , filename);
2421
2422                 if (!(fp = fopen(filename, write_mode)))  {
2423                         EM_DEBUG_EXCEPTION("fopen failed - %s", filename);
2424                         error = EMAIL_ERROR_SYSTEM_FAILURE;
2425                         return false;
2426                 }
2427
2428                 if (subtype && subtype[0] == 'H')  {
2429                         char body_inline_id[512] = {0};
2430
2431                         while (strstr(decoded, "cid:"))   {
2432                                 EM_DEBUG_LOG("Found cid:");
2433                                 not_found = true;
2434                                 if (g_inline_count) {
2435                                         BODY *body_inline = NULL;
2436                                         int   inline_count = 0;
2437                                         char *decoded_content_id = NULL;
2438                                         while (inline_count < g_inline_count && g_inline_list[inline_count]) {
2439                                                 EM_DEBUG_LOG("inline_count [%d], g_inline_count [%d]", inline_count, g_inline_count);
2440                                                 body_inline = g_inline_list[inline_count];
2441                                                 param = body_inline->disposition.parameter;
2442                                                 param1 = body_inline->parameter;                
2443
2444                                                 memset(body_inline_id, 0x00, 512);
2445
2446                                                 if (body_inline && body_inline->id && strlen(body_inline->id) > 0) {
2447                                                         EM_DEBUG_LOG("body_inline->id - %s", body_inline->id);
2448                                                         EM_DEBUG_LOG("param - %p param1 - %p", param, param1);
2449                                                         decoded_content_id = strstr(decoded, "cid:");
2450
2451                                                         if (body_inline->id[0] == '<')
2452                                                                 memcpy(body_inline_id, body_inline->id + 1, strlen(body_inline->id) - 2);
2453                                                         else
2454                                                                 memcpy(body_inline_id, body_inline->id , strlen(body_inline->id));
2455
2456                                                         EM_DEBUG_LOG("Inline body_inline_id [%s]  ", body_inline_id);
2457
2458                                                         if ((param || param1) && 0 == strncmp(body_inline_id , decoded_content_id + strlen("cid:"), strlen(body_inline_id))) {
2459                                                                 EM_DEBUG_LOG(" Inline CID Found ");
2460
2461                                                                 memset(save_file_name, 0x00, MAX_PATH);
2462                                                                 memset(html_cid_path, 0x00, MAX_PATH);
2463                         
2464                                                                 /*  Finding 'filename' attribute from content inf */
2465                                                                 emcore_get_file_pointer(body_inline, true, save_file_name, NULL, &error);
2466
2467                                                                 if (strlen(save_file_name) > 0) { 
2468                                                                         /*  Content ID will be replaced with its file name in html */
2469                                                                         memcpy(html_cid_path, decoded_content_id , strlen("cid:") + strlen(body_inline_id));
2470
2471                                                                         EM_DEBUG_LOG("Replacing %s with %s ", html_cid_path, save_file_name);
2472                                                                         if ((decoded_temp = em_replace_string(decoded, html_cid_path, save_file_name))) {
2473                                                                                 EM_SAFE_FREE(decoded);
2474                                                                                 decoded = decoded_temp;
2475                                                                                 decoded_len = strlen(decoded);
2476                                                                                 EM_DEBUG_LOG("Decoded Length [%d] ", decoded_len);
2477                                                                                 inline_support = 1;
2478                                                                                 not_found = false;
2479                                                                                 /* only_body_download = false */
2480                                                                                 break;
2481                                                                         }
2482                                                                 }
2483                                                         }
2484                                                 }
2485                                                 inline_count++;
2486                                         }
2487
2488                                 }
2489
2490
2491                                 if (not_found) {
2492                                         EM_DEBUG_LOG("not_found is true");
2493                                         memset(body_inline_id, 0x00, sizeof(body_inline_id));
2494                                         decoded_temp = em_replace_string_with_split_file_path(decoded, "cid:", body_inline_id);
2495                                         if (decoded_temp) {
2496                                                 /* only_body_download = false */
2497                                                 /* EM_DEBUG_LOG(">>>> decoded_temp 2 [ %s ] ", decoded_temp) */
2498                                                 EM_SAFE_FREE(decoded);
2499                                                 decoded = decoded_temp;
2500                                                 temp_decoded_len = strlen(body_inline_id);
2501                                                 decoded_len = strlen(decoded);
2502                                                 EM_DEBUG_LOG("Decoded Length [%d] ", decoded_len);
2503                                                 inline_support = 1;
2504                                         }
2505                                 }
2506                         }
2507                 }
2508
2509                 EM_DEBUG_LOG("Trying to fwrite. decoded_len [%d]", decoded_len);
2510
2511                 if (decoded_len > 0 && fwrite(decoded, decoded_len, 1, fp) < 0)  {
2512                         EM_DEBUG_EXCEPTION("Error Occured while writing. fwrite(\"%s\") failed. decoded_len [%d], written_bytes [%d] ", decoded, decoded_len, written_bytes);
2513                         error = EMAIL_ERROR_SYSTEM_FAILURE;
2514                         goto FINISH_OFF;
2515                 }
2516
2517                 EM_DEBUG_LOG("fwrite succeed");
2518         }
2519         else {
2520                 EM_DEBUG_EXCEPTION("Error Occured while decoding ");
2521                 goto FINISH_OFF;
2522         }
2523
2524         ret = true;
2525
2526 FINISH_OFF: 
2527         if (err)
2528                 *err = error;
2529         
2530         EM_SAFE_FREE(decoded);
2531
2532         if (fp != NULL)
2533                 fclose(fp);
2534
2535         EM_DEBUG_FUNC_END();
2536
2537         return ret;
2538 }
2539
2540
2541 static BODY *emcore_select_body_structure_from_section_list(PARTLIST *section_list,  char *section)
2542 {
2543         PARTLIST *temp = section_list;
2544         BODY *body = NULL;
2545
2546         while (temp != NULL) {
2547                 body = temp->body;      
2548                 if (!strcmp(section, body->sparep))
2549                         return body;
2550                 temp = (PARTLIST *)temp->next;
2551         }
2552         return body;
2553 }
2554
2555
2556
2557
2558 static int imap_mail_write_body_to_file(MAILSTREAM *stream, int account_id, int mail_id, int is_attachment, char *filepath, int uid, char *section, int encoding, int *decoded_total, char *section_subtype, int *err_code)
2559 {
2560         EM_PROFILE_BEGIN(imapMailWriteBodyToFile);
2561         EM_DEBUG_FUNC_BEGIN("stream[%p], filepath[%s], uid[%d], section[%s], encoding[%d], decoded_total[%p], err_code[%p]", stream, filepath, uid, section, encoding, decoded_total, err_code);
2562         
2563         int ret = false;
2564         int err = EMAIL_ERROR_NONE;
2565         
2566         FILE *fp = NULL;
2567         IMAPLOCAL *imaplocal = NULL;
2568         char tag[16], command[64];
2569         char *response = NULL;
2570         char *decoded = NULL;
2571         int body_size = 0, total = 0;
2572         char *file_id = NULL;
2573         char server_uid[129];
2574         char *filename = NULL;
2575         int server_response_yn = 0;
2576         int write_flag = false;
2577         char *write_buffer = NULL;
2578         unsigned char encoded[DOWNLOAD_MAX_BUFFER_SIZE] = {0, };
2579         unsigned char test_buffer[LOCAL_MAX_BUFFER_SIZE] = {0};
2580         int flag_first_write = true;    
2581         
2582         if (!stream || !filepath || !section)  {
2583                 EM_DEBUG_EXCEPTION("stream[%p], filepath[%s], uid[%d], section[%s], encoding[%d], decoded_total[%p]", stream, filepath, uid, section, encoding, decoded_total);
2584                 err = EMAIL_ERROR_INVALID_PARAM;
2585                 goto FINISH_OFF;
2586         }
2587
2588         int max_write_buffer_size = 0;
2589         if (vconf_get_int("db/email/write_buffer_mode", &max_write_buffer_size)  != 0) {
2590                 EM_DEBUG_EXCEPTION("vconf_get_int failed. So set direct file writing");
2591                 /*  set as default profile typ */
2592                 max_write_buffer_size = 0;
2593         }
2594
2595         EM_DEBUG_LOG(">>> WRITE BUFFER SIZE  :  %d KB", max_write_buffer_size);
2596         if (max_write_buffer_size > 0) {
2597                 max_write_buffer_size *= 1024;          /*  KB -> byte */
2598                 if (!(write_buffer = em_malloc(sizeof(char) *max_write_buffer_size))) {
2599                         EM_DEBUG_EXCEPTION("em_malloc failed...");                                              
2600                         err = EMAIL_ERROR_OUT_OF_MEMORY;                        
2601                         goto FINISH_OFF;
2602                 }
2603         }
2604
2605         FINISH_OFF_IF_CANCELED; 
2606         
2607         if (!(fp = fopen(filepath, "wb+")))  {
2608                 EM_DEBUG_EXCEPTION("fopen failed - %s", filepath);
2609                 err = EMAIL_ERROR_SYSTEM_FAILURE;               /* EMAIL_ERROR_UNKNOWN */
2610                 goto FINISH_OFF;
2611         }
2612         
2613         imaplocal = stream->local;
2614
2615         if (!imaplocal->netstream)  {
2616                 EM_DEBUG_EXCEPTION("invalid IMAP4 stream detected... %p", imaplocal->netstream);
2617                 
2618                 err = EMAIL_ERROR_INVALID_STREAM;               
2619                 goto FINISH_OFF;
2620         }
2621         
2622         EM_DEBUG_LOG(" next_decode_string = false  ");
2623         next_decode_string = false;
2624
2625         memset(tag, 0x00, sizeof(tag));
2626         memset(command, 0x00, sizeof(command));
2627         
2628         SNPRINTF(tag, sizeof(tag), "%08lx", 0xffffffff & (stream->gensym++));
2629         SNPRINTF(command, sizeof(command), "%s UID FETCH %d BODY.PEEK[%s]\015\012", tag, uid, section);
2630         
2631         EM_DEBUG_LOG("[IMAP4] >>> [%s]", command);
2632         
2633         /*  send command  :  get msgno/uid for all messag */
2634         if (!net_sout(imaplocal->netstream, command, (int)strlen(command)))  {
2635                 EM_DEBUG_EXCEPTION("net_sout failed...");
2636                 err = EMAIL_ERROR_CONNECTION_BROKEN;
2637                 goto FINISH_OFF;
2638         }
2639         
2640         while (imaplocal->netstream)  {
2641                 char *p = NULL;
2642                 char *s = NULL;
2643                 
2644                 if (!emcore_check_thread_status())  {
2645                         EM_DEBUG_LOG("Canceled...");
2646                         /*      Is it realy required ? It might cause crashes.
2647                         if (imaplocal->netstream) 
2648                                 net_close (imaplocal->netstream);
2649                         */
2650                         imaplocal->netstream = NULL;
2651                         err = EMAIL_ERROR_CANCELLED;
2652                         goto FINISH_OFF;
2653                 }       
2654
2655                 /*  receive respons */
2656                 if (!(response = net_getline(imaplocal->netstream)))  {
2657                         EM_DEBUG_EXCEPTION("net_getline failed...");
2658                         err = EMAIL_ERROR_INVALID_RESPONSE;
2659                         goto FINISH_OFF;
2660                 }
2661 #ifdef FEATURE_CORE_DEBUG
2662                 EM_DEBUG_LOG("recv[%s]", response);
2663 #endif
2664                 
2665                 write_flag = false;
2666                 if (response[0] == '*' && !server_response_yn)  {               /*  start of respons */
2667                                 
2668                         if ((p = strstr(response, "BODY[")) /* || (p = strstr(s + 1, "BODY["))*/) {
2669                                 server_response_yn = 1;
2670                                 p += strlen("BODY[");
2671                                 s = p;
2672                                 
2673                                 while (*s != ']')
2674                                         s++;
2675                                 
2676                                 *s = '\0';
2677
2678                                 if (strcmp(section, p))  {
2679                                         err = EMAIL_ERROR_INVALID_RESPONSE;
2680                                         goto FINISH_OFF;
2681                                 }
2682                                 
2683                                 if ((p = strstr(s+1, " {")))  { 
2684                                         p += strlen(" {");
2685                                         s = p;
2686                                         
2687                                         while (isdigit(*s))
2688                                                 s++;
2689                                         
2690                                         *s = '\0';
2691                                         
2692                                         body_size = atoi(p);
2693                                 }
2694                                 else {  /*  no body length is replied */
2695                                         if ((p = strstr(s+1, " \""))) { /*  seek the termination of double quot */
2696                                                 char *t = NULL;
2697                                                 p += strlen(" \"");
2698                                                 if ((t = strstr(p, "\""))) {
2699                                                         body_size = t - p;
2700                                                         *t = '\0';
2701                                                         EM_DEBUG_LOG("Body  :  start[%p] end[%p]  :  body[%s]", p, t, p);
2702                                                         /*  need to decod */
2703                                                         EM_SAFE_FREE(response);
2704                                                         response = EM_SAFE_STRDUP(p);
2705                                                         write_flag = true;
2706                                                 }
2707                                                 else {
2708                                                         err = EMAIL_ERROR_INVALID_RESPONSE;
2709                                                         goto FINISH_OFF;
2710                                                 }
2711                                         }
2712                                         else {
2713                                                 err = EMAIL_ERROR_INVALID_RESPONSE;
2714                                                 goto FINISH_OFF;
2715                                         }
2716                                 }
2717
2718                                 /* sending progress noti to application.
2719                                 1. mail_id
2720                                 2. file_id
2721                                 3. bodysize
2722                                 */
2723                                 parse_file_path_to_filename(filepath, &file_id);
2724                                 
2725                                 filename = file_id;
2726                                 sprintf(server_uid, "%d", uid);
2727                                 
2728                                 EM_DEBUG_LOG("file_id [%s]", file_id);
2729                                 EM_DEBUG_LOG("filename [%p]-[%s]", filename, filename);
2730                                 EM_DEBUG_LOG("body_size [%d]", body_size);
2731                                 EM_DEBUG_LOG("server_uid [%s]", server_uid);
2732                                 EM_DEBUG_LOG("mail_id [%d]", mail_id);
2733                                 
2734                                 if (is_attachment) {
2735                                         EM_DEBUG_LOG("Attachment number [%d]", is_attachment);
2736                                         if (!emstorage_notify_network_event(NOTI_DOWNLOAD_ATTACH_START, mail_id, filename, is_attachment, 0))
2737                                                 EM_DEBUG_EXCEPTION(" emstorage_notify_network_event [ NOTI_DOWNLOAD_ATTACH_START] Failed >>>> ");
2738                                         _imap4_download_noti_interval_value =  body_size *DOWNLOAD_NOTI_INTERVAL_PERCENT / 100;
2739                                         _imap4_total_body_size = body_size;
2740                                 }
2741                                 else {
2742                                         if (multi_part_body_size) {
2743                                                 EM_DEBUG_LOG("Multipart body size is [%d]", multi_part_body_size);
2744                                                 if (!emstorage_notify_network_event(NOTI_DOWNLOAD_MULTIPART_BODY, mail_id, filename, multi_part_body_size, 0))
2745                                                         EM_DEBUG_EXCEPTION(" emstorage_notify_network_event [ NOTI_DOWNLOAD_BODY_START] Failed >>>> ");
2746                                                 _imap4_download_noti_interval_value =  multi_part_body_size *DOWNLOAD_NOTI_INTERVAL_PERCENT / 100;
2747                                                 /*  _imap4_total_body_size should be set before calling this functio */
2748                                                 /* _imap4_total_body_size */
2749                                         }
2750                                         else {
2751                                                 if (!emstorage_notify_network_event(NOTI_DOWNLOAD_BODY_START, mail_id, filename, body_size, 0))
2752                                                         EM_DEBUG_EXCEPTION(" emstorage_notify_network_event [ NOTI_DOWNLOAD_BODY_START] Failed >>>>");
2753                                                 _imap4_download_noti_interval_value =  body_size *DOWNLOAD_NOTI_INTERVAL_PERCENT / 100;
2754                                                 _imap4_total_body_size = body_size;
2755                                         }
2756                                 }       
2757                                 if (_imap4_download_noti_interval_value > DOWNLOAD_NOTI_INTERVAL_SIZE) {        
2758                                         _imap4_download_noti_interval_value = DOWNLOAD_NOTI_INTERVAL_SIZE;
2759                                 }
2760                                 if (body_size < DOWNLOAD_MAX_BUFFER_SIZE) {
2761                                         if (net_getbuffer (imaplocal->netstream, (long)body_size, (char *)encoded) <= 0) {
2762                                                 EM_DEBUG_EXCEPTION("net_getbuffer failed...");
2763                                                 err = EMAIL_ERROR_NO_RESPONSE;
2764                                                 goto FINISH_OFF;
2765                                         }
2766
2767                                         if (!emcore_write_response_into_file(filepath, "wb+", (char *)encoded, encoding, section_subtype, account_id, mail_id, &err)) {
2768                                                 EM_DEBUG_EXCEPTION("write_response_into_file failed [%d]", err);
2769                                                 goto FINISH_OFF;
2770                                         }
2771
2772                                         total = strlen((char *)encoded);
2773                                         EM_DEBUG_LOG("total = %d", total);
2774                                         EM_DEBUG_LOG("write_response_into_file successful %s.....", filename);  
2775
2776                                         if (((_imap4_last_notified_body_size  + _imap4_download_noti_interval_value) <=  _imap4_received_body_size)
2777                                                                 || (_imap4_received_body_size >= _imap4_total_body_size))               /*  100  */ {
2778                                                 /*  In some situation, total_encoded_len includes the length of dummy bytes. So it might be greater than body_size */
2779                                                 int gap = 0;
2780                                                 if (total > body_size)
2781                                                         gap = total - body_size;
2782                                                 _imap4_received_body_size -= gap;
2783                                                 _imap4_last_notified_body_size = _imap4_received_body_size;
2784                                         
2785                                                 if(body_size > 0)
2786                                                         EM_DEBUG_LOG("DOWNLOADING STATUS NOTIFY  :  Encoded[%d] / [%d] = %d %% Completed. -- Total Decoded[%d]", total, body_size, 100*total/body_size, total);
2787
2788                                                 if(_imap4_total_body_size > 0)
2789                                                         EM_DEBUG_LOG("DOWNLOADING STATUS NOTIFY  :  Total[%d] / [%d] = %d %% Completed.", _imap4_received_body_size, _imap4_total_body_size, 100*_imap4_received_body_size/_imap4_total_body_size);
2790                                         
2791                                                 if (is_attachment) {
2792                                                         if (_imap4_total_body_size && !emstorage_notify_network_event(NOTI_DOWNLOAD_ATTACH_START, mail_id, filename, is_attachment, 100 *_imap4_received_body_size / _imap4_total_body_size))
2793                                                                 EM_DEBUG_EXCEPTION(" emstorage_notify_network_event [ NOTI_DOWNLOAD_ATTACH_START] Failed >>>> ");
2794                                                 }
2795                                                 else {
2796                                                         if (multi_part_body_size) {
2797                                                                 if (!emstorage_notify_network_event(NOTI_DOWNLOAD_MULTIPART_BODY, mail_id, filename, _imap4_total_body_size, _imap4_received_body_size))
2798                                                                         EM_DEBUG_EXCEPTION(" emstorage_notify_network_event [ NOTI_DOWNLOAD_BODY_START] Failed >>>> ");
2799                                                         }
2800                                                         else {
2801                                                                 if (!emstorage_notify_network_event(NOTI_DOWNLOAD_BODY_START, mail_id, filename, _imap4_total_body_size, _imap4_received_body_size))
2802                                                                         EM_DEBUG_EXCEPTION(" emstorage_notify_network_event [ NOTI_DOWNLOAD_BODY_START] Failed >>>>");
2803                                                         }
2804                                                 }       /*  if (is_attachment) .. else .. */
2805                                         }
2806                                 }
2807                                 else {
2808                                         int temp_body_size = body_size;
2809                                         int x = 0;
2810                                         
2811                                         if (encoding == ENCBASE64)
2812                                                 x = (sizeof(encoded)/78) *78; /*  to solve base64 decoding pro */
2813                                         else
2814                                                 x = sizeof(encoded)-1;
2815                                         
2816                                         memset(test_buffer, 0x00, sizeof(test_buffer));                                                                                 
2817                                         while (temp_body_size && (total <body_size)) {                                  
2818                                 
2819                                                 memset(test_buffer, 0x00, sizeof(test_buffer));
2820                                                 while ((total != body_size) && temp_body_size && ((strlen((char *)test_buffer) + x) < sizeof(test_buffer))) {
2821                                                         memset(encoded, 0x00, sizeof(encoded)); 
2822                                                 
2823                                                         if (net_getbuffer (imaplocal->netstream, (long)x, (char *)encoded) <= 0) {
2824                                                                 EM_DEBUG_EXCEPTION("net_getbuffer failed...");
2825                                                                 err = EMAIL_ERROR_NO_RESPONSE;          
2826                                                                 goto FINISH_OFF;
2827                                                         }
2828                                                 
2829                                                         temp_body_size = temp_body_size - x;
2830                                                         strncat((char *)test_buffer, (char *)encoded, strlen((char *)encoded));
2831                                                         total = total + x;
2832                                                         _imap4_received_body_size += strlen((char *)encoded);
2833                                                 
2834                                                         if ( !(temp_body_size/x) && temp_body_size%x)
2835                                                                 x = temp_body_size%x;
2836                                                         
2837                                                         if (((_imap4_last_notified_body_size  + _imap4_download_noti_interval_value) <=  _imap4_received_body_size)
2838                                                                 || (_imap4_received_body_size >= _imap4_total_body_size))               /*  100  */ {
2839                                                                 /*  In some situation, total_encoded_len includes the length of dummy bytes. So it might be greater than body_size */
2840                                                                 int gap = 0;
2841                                                                 if (total > body_size)
2842                                                                         gap = total - body_size;
2843                                                                 _imap4_received_body_size -= gap;
2844                                                                 _imap4_last_notified_body_size = _imap4_received_body_size;
2845                                                         
2846                                                                 /* EM_DEBUG_LOG("DOWNLOADING STATUS NOTIFY  :  Encoded[%d] / [%d] = %d %% Completed. -- Total Decoded[%d]", total, body_size, 100*total/body_size, total) */
2847                                                                 EM_DEBUG_LOG("DOWNLOADING STATUS NOTIFY  :  Total[%d] / [%d] = %d %% Completed.", _imap4_received_body_size, _imap4_total_body_size, 100*_imap4_received_body_size/_imap4_total_body_size);
2848                                                         
2849                                                                 if (is_attachment) {
2850                                                                         if (!emstorage_notify_network_event(NOTI_DOWNLOAD_ATTACH_START, mail_id, filename, is_attachment, 100 *_imap4_received_body_size / _imap4_total_body_size))
2851                                                                                 EM_DEBUG_EXCEPTION(" emstorage_notify_network_event [ NOTI_DOWNLOAD_ATTACH_START] Failed >>>> ");
2852                                                                 }
2853                                                                 else {
2854                                                                         if (multi_part_body_size) {
2855                                                                                 /* EM_DEBUG_LOG("DOWNLOADING..........  :  Multipart body size is [%d]", multi_part_body_size) */
2856                                                                         if (!emstorage_notify_network_event(NOTI_DOWNLOAD_MULTIPART_BODY, mail_id, filename, _imap4_total_body_size, _imap4_received_body_size))
2857                                                                                         EM_DEBUG_EXCEPTION(" emstorage_notify_network_event [ NOTI_DOWNLOAD_BODY_START] Failed >>>> ");
2858                                                                         }
2859                                                                         else {
2860                                                                                 if (!emstorage_notify_network_event(NOTI_DOWNLOAD_BODY_START, mail_id, filename, _imap4_total_body_size, _imap4_received_body_size))
2861                                                                                         EM_DEBUG_EXCEPTION(" emstorage_notify_network_event [ NOTI_DOWNLOAD_BODY_START] Failed >>>>");
2862                                                                         }
2863                                                                 }       /*  if (is_attachment) .. else .. */
2864                                                         }
2865
2866
2867                 }
2868                         
2869                                                         if (flag_first_write == true) {
2870                                                                 if (!emcore_write_response_into_file(filepath, "wb+", (char *)test_buffer, encoding, section_subtype, account_id, mail_id, &err)) {
2871                                                                         EM_DEBUG_EXCEPTION("write_response_into_file %s failed [%d]", filepath, err);
2872                                                                         goto FINISH_OFF;
2873                                                                 }
2874                                                                 flag_first_write = false;
2875                                                         }
2876                                                         else {
2877                                                                 if (!emcore_write_response_into_file(filepath, "ab+", (char *)test_buffer, encoding, section_subtype, account_id, mail_id, &err)) /*  append */ {
2878                                                                         EM_DEBUG_EXCEPTION("write_response_into_file %s failed [%d]", filepath, err);
2879                                                                         goto FINISH_OFF;
2880                                                                 }
2881                                                         }
2882                                                         EM_DEBUG_LOG("%d has been written", strlen((char *)test_buffer));       
2883                                                         /*  notif */
2884                                                 }
2885                                 }
2886
2887                         }
2888                         else  {
2889                                 err = EMAIL_ERROR_INVALID_RESPONSE;
2890                                 goto FINISH_OFF;
2891                         }
2892
2893                 }
2894                 else if (!strncmp(response, tag, strlen(tag)))  {               /*  end of respons */
2895                         if (!strncmp(response + strlen(tag) + 1, "OK", 2))  {
2896                                 EM_SAFE_FREE(response); 
2897                         }
2898                         else  {         /*  'NO' or 'BAD */
2899                                 err = EMAIL_ERROR_IMAP4_FETCH_UID_FAILURE;
2900                                 goto FINISH_OFF;
2901                         }
2902                         
2903                         break;
2904                 }
2905                 else if (!strcmp(response, ")"))  {
2906                         /*  The end of response which contains body informatio */
2907                         write_flag = false;
2908                 }
2909
2910         }       /*  while (imaplocal->netstream)  */
2911
2912         if (decoded_total != NULL)
2913                 *decoded_total = total;
2914         
2915         ret = true;
2916
2917 FINISH_OFF: 
2918         EM_SAFE_FREE(decoded);
2919         EM_SAFE_FREE(response);
2920         
2921         if (fp != NULL)
2922                 fclose(fp);
2923
2924         EM_SAFE_FREE(write_buffer);
2925
2926         if (ret == false) {     /*  delete temp fil */
2927                 struct stat temp_file_stat;
2928                 if (filepath &&  stat(filepath, &temp_file_stat) == 0)
2929                         remove(filepath);
2930         }
2931
2932         if (err_code != NULL)
2933                 *err_code = err;
2934
2935         EM_PROFILE_END(imapMailWriteBodyToFile);
2936         
2937         return ret;
2938 }
2939
2940 static int emcore_get_body_part_imap_full(MAILSTREAM *stream, int msg_uid, int account_id, int mail_id, PARTLIST *section_list, struct _m_content_info *cnt_info, int *err_code, int event_handle)
2941 {
2942         EM_DEBUG_FUNC_BEGIN("stream[%p], msg_uid[%d], body[%p], cnt_info[%p], err_code[%p]", stream, msg_uid, section_list, cnt_info, err_code);
2943         
2944         int err = EMAIL_ERROR_NONE;
2945         char sections[IMAP_MAX_COMMAND_LENGTH] = { 0, };
2946         IMAPLOCAL *imaplocal = NULL;
2947         char tag[16] = { 0, }, command[IMAP_MAX_COMMAND_LENGTH] = { 0, };
2948         char section[16] = {0};
2949         char *response = NULL;
2950         BODY *body = NULL;
2951         int server_response_yn = 0;
2952         int body_size = 0;
2953         char *buf = NULL;
2954         char filename[512] = {0, };
2955         int return_value = 0 ;
2956         int encoding = 0;
2957         unsigned char encoded[DOWNLOAD_MAX_BUFFER_SIZE] = {0};
2958         unsigned char test_buffer[LOCAL_MAX_BUFFER_SIZE] = {0};
2959         struct attachment_info *ai = NULL;
2960         int i = 0;
2961         int total = 0;
2962         int flag_first_write = 1;       
2963         int imap4_total_body_download_progress = 0, progress = 0;
2964         
2965         if (!(imaplocal = stream->local) || !imaplocal->netstream || !section_list || !cnt_info)  {
2966                 EM_DEBUG_EXCEPTION("invalid IMAP4 stream detected...");
2967                 err = EMAIL_ERROR_INVALID_PARAM;        
2968                 return_value = -1;
2969                 goto FINISH_OFF;
2970         }
2971         
2972         if (section_list != NULL) {
2973                 PARTLIST *temp = section_list;
2974
2975                 if (cnt_info->grab_type == GRAB_TYPE_ATTACHMENT) {
2976                         /*  to download attachment */
2977                         body = temp->body;
2978                         if (body->sparep != NULL)  {
2979                                 snprintf(sections, sizeof(sections), "BODY.PEEK[%s]", (char *)body->sparep);
2980                         }
2981                         else {
2982                                 EM_DEBUG_EXCEPTION("body->sparep can not be null. ");
2983                                 return_value = -1;
2984                                 goto FINISH_OFF;
2985
2986                         }
2987                 }
2988                 else {
2989                         while (temp != NULL) {
2990                                 char t[64] = {0};
2991                                 body = temp->body;
2992
2993                                 if ((body->type == TYPETEXT)  || (body->id != NULL) || ((body->disposition.type != NULL) && ((body->disposition.type[0] == 'i') || (body->disposition.type[0] == 'I')))) {
2994                                         snprintf(t, sizeof(t), "BODY.PEEK[%s] ", (char *)body->sparep);         /*  body parts seperated by period */
2995                                         strcat(sections, t);
2996                                 }
2997                                 temp = (PARTLIST *)temp->next;
2998                         }
2999                 }
3000         }
3001
3002         if ((strlen(sections) == (sizeof(sections)-1)) || (strlen(sections) == 0)) {
3003                         EM_DEBUG_EXCEPTION(" Too many body parts or nil. IMAP command may cross 1000bytes.");
3004                         return_value = -1;
3005                         goto FINISH_OFF;
3006                 }
3007
3008         if (sections[strlen(sections)-1] == ' ') {
3009                 sections[strlen(sections)-1] = '\0';
3010         }
3011         
3012         EM_DEBUG_LOG("sections <%s>", sections);
3013         
3014         SNPRINTF(tag, sizeof(tag), "%08lx", 0xffffffff & (stream->gensym++));
3015         SNPRINTF(command, sizeof(command), "%s UID FETCH %d (%s)\015\012", tag, msg_uid, sections);
3016         EM_DEBUG_LOG("command %s", command);
3017         
3018         if (strlen(command) == (sizeof(command)-1)) {
3019                 EM_DEBUG_EXCEPTION("Too many body parts. IMAP command will fail.");
3020                 return_value = -1;
3021                 goto FINISH_OFF;
3022         }
3023         
3024         /*  send command  :  get msgno/uid for all message */
3025         if (!net_sout(imaplocal->netstream, command, (int)strlen(command)))  {
3026                 EM_DEBUG_EXCEPTION("net_sout failed...");
3027                 err = EMAIL_ERROR_CONNECTION_BROKEN;    
3028                 return_value = -1;
3029                 goto FINISH_OFF;
3030         }
3031         while (imaplocal->netstream)  {
3032
3033                 /*  receive respons */
3034                 if (!(response = net_getline(imaplocal->netstream)))  {
3035                         EM_DEBUG_EXCEPTION("net_getline failed...");
3036                         err = EMAIL_ERROR_INVALID_RESPONSE;     
3037                         return_value = -1;
3038                         goto FINISH_OFF;
3039                 }
3040                 
3041                 if (strstr(response, "BODY[")) {
3042                                 
3043                         if (!server_response_yn)                /*  start of response */ {
3044                                 if (response[0] != '*') {
3045                                         err = EMAIL_ERROR_INVALID_RESPONSE;
3046                                         EM_DEBUG_EXCEPTION("Start of response doesn't contain *");
3047                                         return_value = -1;
3048                                         goto FINISH_OFF;
3049                                 }
3050                                 server_response_yn = 1;
3051                         }
3052                         
3053                         flag_first_write = 1;
3054                         total = 0;
3055                         memset(encoded, 0x00, sizeof(encoded));
3056                         
3057                         if (emcore_get_section_body_size(response, section, &body_size)<0) {
3058                                 EM_DEBUG_EXCEPTION("emcore_get_section_body_size failed [%d]", err);
3059                                 err = EMAIL_ERROR_INVALID_RESPONSE;
3060                                 return_value = -1;
3061                                 goto FINISH_OFF;
3062                         }
3063                         EM_DEBUG_LOG("body_size-%d", body_size);
3064
3065                         /*  get body from seciton_list */
3066                         if ((body = emcore_select_body_structure_from_section_list(section_list, section)) == NULL) {
3067                                 EM_DEBUG_EXCEPTION("emcore_select_body_structure_from_section_list failed [%d]", err);
3068                                 err = EMAIL_ERROR_INVALID_RESPONSE;
3069                                 return_value = -1;
3070                                 goto FINISH_OFF;
3071                         }                               
3072                         encoding = body->encoding;      
3073                                 
3074                         /* if (emcore_get_file_pointer(account_id, mail_id, body, buf, cnt_info , err)<0) {
3075                                 EM_DEBUG_EXCEPTION("emcore_get_file_pointer failed [%d]", err);
3076                                 goto FINISH_OFF;
3077                         }*/
3078
3079                         if (!emcore_get_temp_file_name(&buf, &err))  {
3080                                 EM_DEBUG_EXCEPTION("emcore_get_temp_file_name failed [%d]", err);                       
3081                                 goto FINISH_OFF;
3082                         }
3083                         
3084                         EM_DEBUG_LOG("buf :  %s", buf); 
3085
3086                         /*  notifying UI start */
3087                         /*  parse_file_path_to_filename(buf, &file_id);                 */
3088                         /*  EM_DEBUG_LOG(">>>> filename - %p >>>>>>", file_id) */
3089
3090                         if (body->type == TYPETEXT && body->subtype && (!body->disposition.type || (body->disposition.type && (body->disposition.type[0] == 'i' || body->disposition.type[0] == 'I')))) {
3091                                 if (body->subtype[0] == 'H')
3092                                         cnt_info->text.html = buf;
3093                                 else
3094                                         cnt_info->text.plain = buf;
3095
3096                                 PARAMETER *param = NULL;
3097                 
3098                                 param = body->parameter;
3099                                 
3100                                 while (param)  {
3101                                         if (!strcasecmp(param->attribute, "CHARSET"))  {
3102                                                 cnt_info->text.plain_charset = EM_SAFE_STRDUP(param->value);
3103                                                 break;
3104                                         }
3105                                         param = param->next;
3106                                 }
3107                         }
3108                         else if (body->id || body->location || body->disposition.type) {
3109
3110                                 if (emcore_get_file_pointer(body, false, filename, cnt_info , &err)<0) {
3111                                         EM_DEBUG_EXCEPTION("emcore_get_file_pointer failed [%d]", err);
3112                                         goto FINISH_OFF;
3113                                 }                               
3114                                 
3115                         /* Search info from attachment list followed by inline attachment list */
3116
3117                                 ai = cnt_info->file;
3118                                 EM_DEBUG_LOG("ai - %p ", (ai));
3119                                 
3120                                 /* For Inline content append to the end */
3121                                 for (i = 1; ai; ai = ai->next, i++) {
3122                                         if (ai->save == NULL && (ai->content_id != NULL && !strcmp(ai->content_id, body->id))) {
3123                                                 EM_DEBUG_LOG("Found matching details ");
3124                                                 ai->save = buf;
3125                                                 break;
3126                                         }
3127                                 }
3128                         }
3129                         
3130                         FINISH_OFF_IF_CANCELED;
3131                                 
3132                         if (cnt_info->grab_type == GRAB_TYPE_ATTACHMENT) {
3133                                 if (!emstorage_notify_network_event(NOTI_DOWNLOAD_ATTACH_START, mail_id, buf, cnt_info->file_no, 0))
3134                                         EM_DEBUG_EXCEPTION(" emstorage_notify_network_event [ NOTI_DOWNLOAD_ATTACH_START] Failed >>>> ");
3135                                 
3136                                 _imap4_download_noti_interval_value =  body_size *DOWNLOAD_NOTI_INTERVAL_PERCENT / 100;
3137                                 _imap4_total_body_size = body_size;
3138                         }
3139                         else {
3140                                 if (multi_part_body_size) {
3141                                         EM_DEBUG_LOG("Multipart body size is [%d]", multi_part_body_size);
3142                                         if (!emstorage_notify_network_event(NOTI_DOWNLOAD_MULTIPART_BODY, mail_id, buf, multi_part_body_size, 0))
3143                                                 EM_DEBUG_EXCEPTION(" emstorage_notify_network_event [ NOTI_DOWNLOAD_BODY_START] Failed >>>> ");
3144                                         
3145                                         _imap4_download_noti_interval_value =  multi_part_body_size *DOWNLOAD_NOTI_INTERVAL_PERCENT / 100;
3146                                 }
3147                                 else {
3148                                         if (!emstorage_notify_network_event(NOTI_DOWNLOAD_BODY_START, mail_id, buf, body_size, 0))
3149                                                 EM_DEBUG_EXCEPTION(" emstorage_notify_network_event [ NOTI_DOWNLOAD_BODY_START] Failed >>>> ");
3150                                         
3151                                         _imap4_download_noti_interval_value =  body_size *DOWNLOAD_NOTI_INTERVAL_PERCENT / 100;
3152                                         _imap4_total_body_size = body_size;
3153                                 }
3154
3155                         }
3156
3157                         if (_imap4_download_noti_interval_value > DOWNLOAD_NOTI_INTERVAL_SIZE) {        
3158                                 _imap4_download_noti_interval_value = DOWNLOAD_NOTI_INTERVAL_SIZE;
3159                         }                                       
3160                         
3161                         /* EM_SAFE_FREE(file_id) */
3162                         /* notifying UI end */
3163                         
3164                         if (body_size < DOWNLOAD_MAX_BUFFER_SIZE) {
3165                                 if (net_getbuffer (imaplocal->netstream, (long)body_size, (char *)encoded) <= 0) {
3166                                         EM_DEBUG_EXCEPTION("net_getbuffer failed...");
3167                                         err = EMAIL_ERROR_NO_RESPONSE;
3168                                         return_value = -1;
3169                                         goto FINISH_OFF;
3170                                 }
3171                                 if (!emcore_write_response_into_file(buf, "wb+", (char *)encoded, encoding, body->subtype, account_id, mail_id, &err)) {
3172                                         EM_DEBUG_EXCEPTION("write_response_into_file failed [%d]", err);
3173                                         return_value = -1;
3174                                         goto FINISH_OFF;
3175                                 }
3176                                 
3177                                 EM_DEBUG_LOG("total = %d", total);
3178                                 EM_DEBUG_LOG("write_response_into_file successful %s.....", buf);       
3179
3180                                 total = _imap4_received_body_size = strlen((char *)encoded);
3181                         
3182                                 EM_DEBUG_LOG("_imap4_last_notified_body_size [%d]", _imap4_last_notified_body_size);
3183                                 EM_DEBUG_LOG("_imap4_download_noti_interval_value [%d]", _imap4_download_noti_interval_value);
3184                                 EM_DEBUG_LOG("_imap4_received_body_size [%d]", _imap4_received_body_size);
3185                                 EM_DEBUG_LOG("_imap4_total_body_size [%d] ", _imap4_total_body_size);
3186                         
3187                                 if (((_imap4_last_notified_body_size  + _imap4_download_noti_interval_value) <=  _imap4_received_body_size)
3188                                         || (_imap4_received_body_size >= _imap4_total_body_size))               /*  100  */ {
3189                                         /*  In some situation, total_encoded_len includes the length of dummy bytes. So it might be greater than body_size */
3190                                         int gap = 0;
3191
3192                                         if (total > body_size)
3193                                                 gap = total - body_size;
3194                                         _imap4_received_body_size -= gap;
3195                                         _imap4_last_notified_body_size = _imap4_received_body_size;
3196                                         if (_imap4_total_body_size)
3197                                                 imap4_total_body_download_progress = 100*_imap4_received_body_size/_imap4_total_body_size;
3198                                         else
3199                                                 imap4_total_body_download_progress = _imap4_received_body_size;
3200
3201                                         EM_DEBUG_LOG("3  :  body_size %d", body_size);
3202                                 
3203                                         if (body_size)
3204                                                 progress = 100*total/body_size;
3205                                         else 
3206                                                 progress = body_size;
3207
3208                                         EM_DEBUG_LOG("DOWNLOADING STATUS NOTIFY  :  Encoded[%d] / [%d] = %d %% Completed. -- Total Decoded[%d]", total, body_size, progress, total);
3209                                         EM_DEBUG_LOG("DOWNLOADING STATUS NOTIFY  :  Total[%d] / [%d] = %d %% Completed.", _imap4_received_body_size, _imap4_total_body_size, imap4_total_body_download_progress);
3210                                 
3211                                         if (cnt_info->grab_type == GRAB_TYPE_ATTACHMENT) {
3212                                                 if (!emstorage_notify_network_event(NOTI_DOWNLOAD_ATTACH_START, mail_id, buf, cnt_info->file_no, imap4_total_body_download_progress))
3213                                                         EM_DEBUG_EXCEPTION(" emstorage_notify_network_event [ NOTI_DOWNLOAD_ATTACH_START] Failed >>>> ");
3214                                         }
3215                                         else {
3216                                                         if (multi_part_body_size) {
3217                                                                 /* EM_DEBUG_LOG("DOWNLOADING..........  :  Multipart body size is [%d]", multi_part_body_size) */
3218                                                         if (!emstorage_notify_network_event(NOTI_DOWNLOAD_MULTIPART_BODY, mail_id, buf, _imap4_total_body_size, _imap4_received_body_size))
3219                                                                         EM_DEBUG_EXCEPTION(" emstorage_notify_network_event [ NOTI_DOWNLOAD_BODY_START] Failed >>>> ");
3220                                                         }
3221                                                         else {
3222                                                         if (!emstorage_notify_network_event(NOTI_DOWNLOAD_BODY_START, mail_id, buf, _imap4_total_body_size, _imap4_received_body_size))
3223                                                                         EM_DEBUG_EXCEPTION(" emstorage_notify_network_event [ NOTI_DOWNLOAD_BODY_START] Failed >>>>");
3224                                                         }
3225                                         }       /*  if (is_attachment) .. else .. */
3226                                 }
3227
3228                                 EM_DEBUG_LOG("4");
3229
3230                         }
3231                         else {
3232                                 int temp_body_size = body_size;
3233                                 int x = 0;
3234                                 
3235                                 if (encoding == ENCBASE64)
3236                                         x = (sizeof(encoded)/78) *78; /*  to solve base64 decoding pro */
3237                                 else
3238                                         x = sizeof(encoded)-1;
3239                                 
3240                                 memset(test_buffer, 0x00, sizeof(test_buffer));                                                                                 
3241                                 while (temp_body_size && (total <body_size)) {                                  
3242                         
3243                                         memset(test_buffer, 0x00, sizeof(test_buffer));
3244                                         while ((total != body_size) && temp_body_size && ((strlen((char *)test_buffer) + x) < sizeof(test_buffer))) {
3245                                                 memset(encoded, 0x00, sizeof(encoded)); 
3246                                         
3247                                                 if (net_getbuffer (imaplocal->netstream, (long)x, (char *)encoded) <= 0) {
3248                                                         EM_DEBUG_EXCEPTION("net_getbuffer failed...");
3249                                                         err = EMAIL_ERROR_NO_RESPONSE;          
3250                                                         return_value = -1;
3251                                                         goto FINISH_OFF;
3252                                                 }
3253                                         
3254                                                 temp_body_size = temp_body_size - x;
3255                                                 strncat((char *)test_buffer, (char *)encoded, strlen((char *)encoded));
3256                                                 total = total + x;
3257                                                 _imap4_received_body_size += strlen((char *)encoded);
3258                                                 
3259                                                 EM_DEBUG_LOG("total = %d", total);
3260                                                 
3261                                                 if ( !(temp_body_size/x) && temp_body_size%x)
3262                                                         x = temp_body_size%x;
3263
3264                                                 EM_DEBUG_LOG(" _imap4_last_notified_body_size - %d ", _imap4_last_notified_body_size);
3265                                                 EM_DEBUG_LOG(" _imap4_download_noti_interval_value - %d ", _imap4_download_noti_interval_value);
3266                                                 EM_DEBUG_LOG(" _imap4_received_body_size - %d ", _imap4_received_body_size);
3267                                                 EM_DEBUG_LOG(" _imap4_received_body_size - %d ", _imap4_received_body_size);
3268                                                 EM_DEBUG_LOG(" _imap4_total_body_size - %d ", _imap4_total_body_size);
3269
3270                                                 if (_imap4_total_body_size)
3271                                                         imap4_total_body_download_progress = 100*_imap4_received_body_size/_imap4_total_body_size;
3272                                                 else
3273                                                         imap4_total_body_download_progress = _imap4_received_body_size;
3274
3275                                                 if (((_imap4_last_notified_body_size  + _imap4_download_noti_interval_value) <=  _imap4_received_body_size)
3276                                                         || (_imap4_received_body_size >= _imap4_total_body_size))               /*  100  */ {
3277                                                         /*  In some situation, total_encoded_len includes the length of dummy bytes. So it might be greater than body_size */
3278                                                         int gap = 0;
3279                                                         if (total > body_size)
3280                                                                 gap = total - body_size;
3281                                                         _imap4_received_body_size -= gap;
3282                                                         _imap4_last_notified_body_size = _imap4_received_body_size;
3283
3284                                                         if (body_size)
3285                                                                 progress = 100*total/body_size;
3286                                                         else 
3287                                                                 progress = body_size;
3288                                                 
3289                                                         EM_DEBUG_LOG("DOWNLOADING STATUS NOTIFY  :  Encoded[%d] / [%d] = %d %% Completed. -- Total Decoded[%d]", total, body_size, progress, total);
3290                                                         EM_DEBUG_LOG("DOWNLOADING STATUS NOTIFY  :  Total[%d] / [%d] = %d %% Completed.", _imap4_received_body_size, _imap4_total_body_size, imap4_total_body_download_progress);
3291                                                 
3292                                                         if (cnt_info->grab_type == GRAB_TYPE_ATTACHMENT) {
3293                                                                 if (!emstorage_notify_network_event(NOTI_DOWNLOAD_ATTACH_START, mail_id, buf, cnt_info->file_no, imap4_total_body_download_progress))
3294                                                                         EM_DEBUG_EXCEPTION(" emstorage_notify_network_event [ NOTI_DOWNLOAD_ATTACH_START] Failed >>>> ");
3295                                                         }
3296                                                         else {
3297                                                                 if (multi_part_body_size) {
3298                                                                         /* EM_DEBUG_LOG("DOWNLOADING..........  :  Multipart body size is [%d]", multi_part_body_size) */
3299                                                                         if (!emstorage_notify_network_event(NOTI_DOWNLOAD_MULTIPART_BODY, mail_id, buf, _imap4_total_body_size, _imap4_received_body_size))
3300                                                                                 EM_DEBUG_EXCEPTION(" emstorage_notify_network_event [ NOTI_DOWNLOAD_BODY_START] Failed >>>> ");
3301                                                                 }
3302                                                                 else {
3303                                                                         if (!emstorage_notify_network_event(NOTI_DOWNLOAD_BODY_START, mail_id, buf, _imap4_total_body_size, _imap4_received_body_size))
3304                                                                                 EM_DEBUG_EXCEPTION(" emstorage_notify_network_event [ NOTI_DOWNLOAD_BODY_START] Failed >>>>");
3305                                                                 }
3306                                                         }       /*  if (is_attachment) .. else .. */
3307                                                 }
3308                                         }
3309
3310                                         if (flag_first_write == 1) {
3311                                                 if (!emcore_write_response_into_file(buf, "wb+", (char *)test_buffer, encoding, body->subtype, account_id, mail_id, &err)) {
3312                                                         EM_DEBUG_EXCEPTION("write_response_into_file %s failed [%d]", buf, err);
3313                                                         return_value = -1;
3314                                                         goto FINISH_OFF;
3315                                                 }
3316                                                 flag_first_write = 0;
3317                                         }
3318                                         else {
3319                                                 if (!emcore_write_response_into_file(buf, "ab+", (char *)test_buffer, encoding, body->subtype, account_id, mail_id, &err)) /*  append */ {
3320                                                         EM_DEBUG_EXCEPTION("write_response_into_file %s failed [%d]", buf, err);
3321                                                         return_value = -1;
3322                                                         goto FINISH_OFF;
3323                                                 }
3324                                         }
3325                                         EM_DEBUG_LOG("%d has been written", strlen((char *)test_buffer));
3326                                 }
3327                         }
3328                 }
3329                 else if (!strncmp(response, tag, strlen(tag)))  /*  end of respons */ {         
3330                         if (!strncmp(response + strlen(tag) + 1, "OK", 2)) 
3331                                 EM_SAFE_FREE(response);
3332                         else                    /*  'NO' or 'BAD */ {
3333                                 err = EMAIL_ERROR_IMAP4_FETCH_UID_FAILURE;      
3334                                 return_value = -1;
3335                                 goto FINISH_OFF;
3336                         }
3337                         
3338                         break;
3339                 }
3340                 else if (!strcmp(response, ")"))  {
3341                         
3342                 }
3343                 
3344                 free(response); 
3345                 response = NULL;                
3346         }
3347
3348         return_value = 0;
3349         
3350         FINISH_OFF: 
3351
3352         if (err_code)
3353                 *err_code = err;
3354
3355         EM_SAFE_FREE(response);
3356
3357         return return_value;
3358 }
3359
3360 static int _find_duplicated_inline_content_file(char *input_source_file_name, struct _m_content_info *input_content_info, bool *output_result)
3361 {
3362         EM_DEBUG_FUNC_BEGIN("input_source_file_name [%p], input_content_info [%p], output_result [%p]", input_source_file_name,input_content_info, output_result);
3363         struct attachment_info *cur_attachment_info = NULL;
3364         int  err = EMAIL_ERROR_NONE;
3365         bool result = false;
3366
3367         if(!input_source_file_name || !input_content_info || !output_result) {
3368                 EM_DEBUG_EXCEPTION("Invalid parameter");
3369                 return EMAIL_ERROR_INVALID_PARAM;
3370         }
3371
3372         cur_attachment_info = input_content_info->file;
3373
3374         while(cur_attachment_info) {
3375                 if(strcmp(input_source_file_name, cur_attachment_info->name) == 0) {
3376                         result = true;
3377                         break;
3378                 }
3379                 cur_attachment_info = cur_attachment_info->next;
3380         }
3381
3382         *output_result = result;
3383
3384         EM_DEBUG_FUNC_END("err [%d], result [%d]", err, result);
3385         return err;
3386 }
3387
3388 static int _modify_file_name_string_for_duplicated_inline_content(char *input_source_file_name, struct _m_content_info *input_content_info)
3389 {
3390         EM_DEBUG_FUNC_BEGIN("input_source_file_name [%p], input_content_info [%p]", input_source_file_name,input_content_info);
3391         int   err = EMAIL_ERROR_NONE;
3392         char  temp_file_name[MAX_PATH] = { 0, };
3393         char *file_name = NULL;
3394         char *extension = NULL;
3395
3396         if(!input_source_file_name || !input_content_info) {
3397                 EM_DEBUG_EXCEPTION("Invalid parameter");
3398                 return EMAIL_ERROR_INVALID_PARAM;
3399         }
3400
3401         if ( (err = em_get_file_name_and_extension_from_file_path(input_source_file_name, &file_name, &extension)) != EMAIL_ERROR_NONE) {
3402                 EM_DEBUG_EXCEPTION("em_get_file_name_and_extension_from_file_path failed [%d]", err);
3403                 goto FINISH_OFF;
3404         }
3405
3406         if(file_name && extension)
3407                 SNPRINTF(temp_file_name, MAX_PATH, "%s_.%s", file_name, extension);
3408         else if(!extension)
3409                 SNPRINTF(temp_file_name, MAX_PATH, "%s_", file_name);
3410
3411         EM_SAFE_STRCPY(input_source_file_name, temp_file_name);
3412
3413 FINISH_OFF:
3414
3415         EM_SAFE_FREE(file_name);
3416         EM_SAFE_FREE(extension);
3417
3418         EM_DEBUG_FUNC_END("err [%d], temp_file_name [%s]", err, temp_file_name);
3419         return err;
3420 }
3421
3422 static int emcore_get_file_pointer(BODY *body, bool input_check_duplicated_file_name, char *output_file_name_string, struct _m_content_info *cnt_info , int *err)
3423 {
3424         EM_DEBUG_FUNC_BEGIN();
3425
3426         char *decoded_filename = NULL;
3427         char attachment_file_name[MAX_PATH] = { 0, };
3428         char attachment_file_name_source[MAX_PATH] = {0, };
3429         int error = EMAIL_ERROR_NONE;
3430         bool file_name_duplicated = false;
3431
3432         if ((body->type == TYPETEXT) && (body->disposition.type == NULL)) {
3433                 EM_DEBUG_LOG("body->type == TYPETEXT");
3434                 if (!cnt_info) {
3435                         EM_DEBUG_EXCEPTION("But, cnt_info is null");
3436                         error = EMAIL_ERROR_INVALID_PARAM;
3437                         goto FINISH_OFF;
3438                 }
3439                 if (body->subtype[0] == 'H') {
3440                         if (cnt_info->text.plain_charset != NULL) {
3441                                 memcpy(output_file_name_string, cnt_info->text.plain_charset, strlen(cnt_info->text.plain_charset));
3442                                 strcat(output_file_name_string, HTML_EXTENSION_STRING);
3443                         }
3444                         else {
3445                                 memcpy(output_file_name_string, "UTF-8.htm", strlen("UTF-8.htm"));
3446                         }
3447                         cnt_info->text.html = EM_SAFE_STRDUP(output_file_name_string);
3448                 }
3449                 else {                  
3450                         PARAMETER *param = body->parameter;
3451                         char charset_string[512];
3452
3453                         if (emcore_get_attribute_value_of_body_part(param, "CHARSET", charset_string, 512, false, &error)) {
3454                                 cnt_info->text.plain_charset = EM_SAFE_STRDUP(charset_string);
3455                                 memcpy(output_file_name_string, cnt_info->text.plain_charset, strlen(cnt_info->text.plain_charset));
3456                         }
3457                         else
3458                                 memcpy(output_file_name_string, "UTF-8", strlen("UTF-8"));
3459                         
3460                         cnt_info->text.plain = EM_SAFE_STRDUP(output_file_name_string);
3461                 }
3462                 
3463         }
3464         else if ((body->id != NULL) || ((body->disposition.type != NULL) && ((body->disposition.type[0] == 'i') || (body->disposition.type[0] == 'I')))) {
3465                 /*  body id is exising or disposition type is inline */
3466                 size_t len = 0;
3467                 if (body->parameter) /* Get actual name of file */ {
3468                         PARAMETER *param_body = body->parameter;
3469                         if (!emcore_get_attribute_value_of_body_part(param_body, "NAME", attachment_file_name_source, MAX_PATH, true, &error))
3470                                 emcore_get_attribute_value_of_body_part(param_body, "CHARSET", attachment_file_name_source, MAX_PATH, true, &error);
3471                         if (!emcore_make_attachment_file_name_with_extension(attachment_file_name_source, body->subtype, attachment_file_name, MAX_PATH, &error)) {
3472                                 EM_DEBUG_EXCEPTION("emcore_make_attachment_file_name_with_extension failed [%d]", error);
3473                                 goto FINISH_OFF;
3474                         }
3475                 }
3476                 else if (body->disposition.type)  {
3477                         PARAMETER *param_disposition = body->disposition.parameter;
3478                         EM_DEBUG_LOG("body->disposition.type exist");
3479                         emcore_get_attribute_value_of_body_part(param_disposition, "filename", attachment_file_name_source, MAX_PATH, true, &error);
3480                         if (!emcore_make_attachment_file_name_with_extension(attachment_file_name_source, body->subtype, attachment_file_name, MAX_PATH, &error)) {
3481                                 EM_DEBUG_EXCEPTION("emcore_make_attachment_file_name_with_extension failed [%d]", error);
3482                                 goto FINISH_OFF;
3483                         }
3484                 }
3485                 else {  /*  body id is not null but disposition type is null */
3486                         if ((body->id[0] == '<'))
3487                                 SNPRINTF(attachment_file_name, MAX_PATH, "%s", body->id+1); /*  fname = em_parse_filename(body->id + 1 */
3488                         else
3489                                 SNPRINTF(attachment_file_name, MAX_PATH, "%s", body->id); /*  fname = em_parse_filename(body->id */
3490                         
3491                         len = strlen(attachment_file_name);
3492                         
3493                         if ((len > 1) && (attachment_file_name[len-1] == '>'))
3494                                 attachment_file_name[len - 1] = '\0';
3495                         decoded_filename = emcore_decode_rfc2047_text(attachment_file_name, &error);
3496                 }
3497                 EM_DEBUG_LOG("attachment_file_name [%s]", attachment_file_name);
3498                 if (decoded_filename != NULL)
3499                         memcpy(output_file_name_string, decoded_filename, strlen(decoded_filename));
3500                 else
3501                         memcpy(output_file_name_string, attachment_file_name, strlen(attachment_file_name));
3502
3503         }
3504         else if (body->disposition.type != NULL) {      /*  disposition type is existing and not inline and body_id is nul */
3505                 PARAMETER *param = body->parameter;                                             
3506                 if (!emcore_get_attribute_value_of_body_part(param, "NAME", attachment_file_name, MAX_PATH, true, &error))
3507                         emcore_get_attribute_value_of_body_part(param, "FILENAME", attachment_file_name, MAX_PATH, true, &error);
3508                 memcpy(output_file_name_string, attachment_file_name, strlen(attachment_file_name));
3509         }
3510
3511         if(input_check_duplicated_file_name) {
3512                 if ( (error = _find_duplicated_inline_content_file(output_file_name_string, cnt_info, &file_name_duplicated)) != EMAIL_ERROR_NONE) {
3513                         EM_DEBUG_EXCEPTION("_find_duplicated_inline_content_file failed [%d]", error);
3514                         goto FINISH_OFF;
3515                 }
3516
3517                 if (file_name_duplicated == true) {
3518                         if ( ( error = _modify_file_name_string_for_duplicated_inline_content(output_file_name_string, cnt_info)) != EMAIL_ERROR_NONE) {
3519                                 EM_DEBUG_EXCEPTION("_modify_file_name_string_for_duplicated_inline_content failed [%d]", error);
3520                                 goto FINISH_OFF;
3521                         }
3522                 }
3523         }
3524
3525 FINISH_OFF: 
3526
3527         EM_SAFE_FREE(decoded_filename);
3528
3529         if (err)
3530                 *err = error;
3531
3532         EM_DEBUG_FUNC_END("output_file_name_string[%s], error [%d]", output_file_name_string, error);
3533         return SUCCESS;
3534 }
3535
3536
3537 static PARTLIST *emcore_add_node(PARTLIST *section_list, BODY *body)
3538 {
3539         PARTLIST *temp = (PARTLIST  *)malloc(sizeof(PARTLIST));
3540
3541         if (temp == NULL) {
3542                 EM_DEBUG_EXCEPTION("PARTLIST node creation failed");            
3543                 return NULL;
3544         }
3545         temp->body = body;
3546         temp->next = NULL;
3547         
3548         if (section_list == NULL)/*  first node in lis */ {                             
3549                 section_list = temp;
3550         }
3551         else/*  has min 1 nod */ {
3552                 PARTLIST *t = section_list;
3553                 while (t->next != NULL) /*  go to last nod */ {
3554                         t = (PARTLIST *) t->next;
3555                 }
3556                 t->next = (PART *)temp;/*  I think this should be PARTLIST, but why this is PART */
3557 /*
3558 in imap-2007e/c-client/mail.h
3559 PARTLIST{
3560   BODY *body;                   
3561   PART *next;                   
3562 };
3563 */
3564         }
3565         return section_list;
3566 }
3567
3568
3569 static void emcore_free_section_list(PARTLIST *section_list)
3570 {
3571         PARTLIST *temp = NULL;
3572
3573         while (section_list != NULL) {
3574                 temp = (PARTLIST *)section_list->next;
3575                 EM_SAFE_FREE(section_list);
3576                 section_list = temp;
3577         }
3578 }
3579
3580 static int emcore_get_section_body_size(char *response, char *section, int *body_size)
3581 {
3582         char *p = NULL;
3583         char *s = NULL;
3584         int size = 0;
3585         if ((p = strstr(response, "BODY[")) /* || (p = strstr(s + 1, "BODY["))*/) {
3586                                 
3587                                 p += strlen("BODY[");
3588                                 s = p;
3589                                 
3590                                 while (*s != ']')
3591                                         s++;
3592                                 
3593                                 *s = '\0';
3594                                 
3595                                 strcpy(section, p);
3596
3597                 /* if (strcmp(section, p)) {
3598                                         err = EMAIL_ERROR_INVALID_RESPONSE;
3599                                         goto FINISH_OFF;
3600                 }*/
3601                 p = strstr(s+1, " {");          
3602                 if (p)  {
3603                         p += strlen(" {");
3604                         s = p;
3605                         
3606                         while (isdigit(*s))
3607                                 s++;
3608                         
3609                         *s = '\0';
3610                         
3611                         size = atoi(p);
3612                         *body_size = size;
3613                         
3614                         /* sending progress noti to application.
3615                         1. mail_id
3616                         2. file_id
3617                         3. bodysize
3618                         */                      
3619                                 
3620                 }
3621                 else  {
3622                         return FAILURE;
3623                 }
3624         }
3625         else  {
3626                 return FAILURE;
3627         }
3628         return SUCCESS;
3629 }
3630
3631
3632 static char *em_parse_filename(char *filename)
3633 {
3634         EM_DEBUG_FUNC_BEGIN("filename [%p] ", filename);
3635         if (!filename) {
3636                 EM_DEBUG_EXCEPTION("filename is NULL ");
3637                 return NULL;
3638         }
3639         
3640         char delims[] = "@";
3641         char *result = NULL;
3642         static char parsed_filename[512] = {0, };
3643
3644         memset(parsed_filename, 0x00, 512);
3645         
3646         if (!strstr(filename, delims)) {
3647                 EM_DEBUG_EXCEPTION("FileName doesnot contain @ ");
3648                 return NULL;
3649         }
3650         
3651         result = strtok(filename, delims);
3652
3653         if (strcasestr(result, ".bmp") || strcasestr(result, ".jpeg") || strcasestr(result, ".png") || strcasestr(result, ".jpg"))
3654                 sprintf(parsed_filename + strlen(parsed_filename), "%s", result);
3655     else
3656                 sprintf(parsed_filename + strlen(parsed_filename), "%s%s", result, ".jpeg");
3657
3658         EM_DEBUG_LOG(">>> FileName [ %s ] ", result);
3659
3660         EM_DEBUG_FUNC_END("parsed_filename [%s] ", parsed_filename);
3661         return parsed_filename;
3662 }
3663
3664 #define CONTENT_TYPE_STRING_IN_MIME_HEAEDER "Content-Type:"
3665
3666 INTERNAL_FUNC int emcore_get_content_type_from_mime_string(char *input_mime_string, char **output_content_type)
3667 {
3668         EM_DEBUG_FUNC_BEGIN("input_mime_string [%p], output_content_type [%p]", input_mime_string, output_content_type);
3669
3670         int   err = EMAIL_ERROR_NONE;
3671         int   temp_mime_header_string_length = 0;
3672         char  result_content_type[256] = { 0, };
3673         char *temp_mime_header_string = NULL;
3674         char *temp_content_type_start = NULL;
3675         char *temp_content_type_end = NULL;
3676
3677         if(input_mime_string == NULL || output_content_type == NULL) {
3678                 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
3679                 err = EMAIL_ERROR_INVALID_PARAM;
3680                 goto FINISH_OFF;
3681         }
3682
3683         temp_mime_header_string_length = EM_SAFE_STRLEN(input_mime_string);
3684         temp_mime_header_string        = input_mime_string;
3685
3686         EM_DEBUG_LOG("temp_mime_header_string [%s]", temp_mime_header_string);
3687
3688         temp_content_type_start = strcasestr(temp_mime_header_string, CONTENT_TYPE_STRING_IN_MIME_HEAEDER);
3689
3690         if(temp_content_type_start == NULL) {
3691                 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_DATA");
3692                 err = EMAIL_ERROR_INVALID_DATA;
3693                 goto FINISH_OFF;
3694         }
3695         else {
3696                 temp_content_type_start += EM_SAFE_STRLEN(CONTENT_TYPE_STRING_IN_MIME_HEAEDER);
3697                 temp_content_type_end = temp_content_type_start;
3698
3699                 while(temp_content_type_end && temp_content_type_end < (temp_mime_header_string + temp_mime_header_string_length) && *temp_content_type_end != ';')
3700                         temp_content_type_end++;
3701
3702                 if(temp_content_type_end && *temp_content_type_end == ';') {
3703                         if(temp_content_type_end - temp_content_type_start < 256) {
3704                                 memcpy(result_content_type, temp_content_type_start, temp_content_type_end - temp_content_type_start);
3705                                 EM_DEBUG_LOG("result_content_type [%s]", result_content_type);
3706                                 *output_content_type = EM_SAFE_STRDUP(result_content_type);
3707                                 em_trim_left(*output_content_type);
3708
3709                         }
3710                         else {
3711                                 EM_DEBUG_EXCEPTION("temp_content_type_end - temp_content_type_start [%d]", temp_content_type_end - temp_content_type_start);
3712                                 err = EMAIL_ERROR_DATA_TOO_LONG;
3713                                 goto FINISH_OFF;
3714                         }
3715                 }
3716         }
3717
3718 FINISH_OFF:
3719
3720         EM_DEBUG_FUNC_END("err [%d]", err);
3721         return err;
3722 }
3723
3724 #define SUBTYPE_STRING_LENGTH 128
3725
3726 INTERNAL_FUNC int emcore_get_content_type_from_mail_bodystruct(BODY *input_body, int input_buffer_length, char *output_content_type)
3727 {
3728         EM_DEBUG_FUNC_BEGIN("input_body [%p], input_buffer_length [%d], output_content_type [%p]", input_body, input_buffer_length, output_content_type);
3729         int   err = EMAIL_ERROR_NONE;
3730         char  subtype_string[SUBTYPE_STRING_LENGTH] = { 0 , };
3731
3732         if(input_body == NULL || output_content_type == NULL || input_buffer_length == 0) {
3733                 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
3734                 err = EMAIL_ERROR_INVALID_PARAM;
3735                 goto FINISH_OFF;
3736         }
3737
3738         EM_SAFE_STRNCPY(subtype_string, input_body->subtype, SUBTYPE_STRING_LENGTH);
3739         em_lower_string(subtype_string);
3740
3741         switch(input_body->type) {
3742                 case TYPETEXT :
3743                         SNPRINTF(output_content_type, input_buffer_length, "text/%s", subtype_string);
3744                         break;
3745                 case TYPEMULTIPART :
3746                         SNPRINTF(output_content_type, input_buffer_length, "multipart/%s", subtype_string);
3747                         break;
3748                 case TYPEMESSAGE :
3749                         SNPRINTF(output_content_type, input_buffer_length, "message/%s", subtype_string);
3750                         break;
3751                 case TYPEAPPLICATION :
3752                         SNPRINTF(output_content_type, input_buffer_length, "application/%s", subtype_string);
3753                         break;
3754                 case TYPEAUDIO :
3755                         SNPRINTF(output_content_type, input_buffer_length, "audio/%s", subtype_string);
3756                         break;
3757                 case TYPEIMAGE :
3758                         SNPRINTF(output_content_type, input_buffer_length, "image/%s", subtype_string);
3759                         break;
3760                 case TYPEVIDEO :
3761                         SNPRINTF(output_content_type, input_buffer_length, "video/%s", subtype_string);
3762                         break;
3763                 case TYPEMODEL :
3764                         SNPRINTF(output_content_type, input_buffer_length, "model/%s", subtype_string);
3765                         break;
3766                 case TYPEOTHER :
3767                         SNPRINTF(output_content_type, input_buffer_length, "other/%s", subtype_string);
3768                         break;
3769                 default:
3770                         EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
3771                         err = EMAIL_ERROR_INVALID_PARAM;
3772                         goto FINISH_OFF;
3773                         break;
3774         }
3775
3776         EM_DEBUG_LOG("output_content_type [%s]", output_content_type);
3777
3778 FINISH_OFF:
3779
3780         EM_DEBUG_FUNC_END("err [%d]", err);
3781         return err;
3782 }
3783
3784 INTERNAL_FUNC int emcore_get_attribute_value_of_body_part(PARAMETER *input_param, char *atribute_name, char *output_value, int output_buffer_length, int with_rfc2047_text, int *err_code)
3785 {
3786         EM_DEBUG_FUNC_BEGIN("input_param [%p], atribute_name [%s], output_buffer_length [%d], with_rfc2047_text [%d]", input_param, atribute_name, output_buffer_length, with_rfc2047_text);
3787         PARAMETER *temp_param = input_param;
3788         char *decoded_value = NULL, *result_value = NULL;
3789         int ret = false, err = EMAIL_ERROR_NONE;
3790
3791         if(!output_value) {
3792                 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
3793                 err = EMAIL_ERROR_INVALID_PARAM;
3794                 goto FINISH_OFF;
3795         }
3796
3797         memset(output_value, 0, output_buffer_length);
3798         
3799         while (temp_param)  {
3800                 EM_DEBUG_LOG("temp_param->attribute [%s]", temp_param->attribute);
3801                 if (!strcasecmp(temp_param->attribute, atribute_name))  {       
3802                         EM_DEBUG_LOG("temp_param->value [%s]", temp_param->value);
3803                         if (temp_param->value) {
3804                                 if (with_rfc2047_text) {
3805                                         decoded_value = emcore_decode_rfc2047_text(temp_param->value, &err);
3806                                         if (decoded_value) 
3807                                                 result_value = decoded_value;
3808                                         else
3809                                                 result_value = decoded_value;
3810                                 }
3811                                 else
3812                                         result_value = temp_param->value;
3813                         }
3814                         else {
3815                                 EM_DEBUG_EXCEPTION("EMAIL_ERROR_DATA_NOT_FOUND");
3816                                 err = EMAIL_ERROR_DATA_NOT_FOUND;
3817                                 goto FINISH_OFF;
3818                         }
3819                         EM_DEBUG_LOG("result_value [%s]", result_value);
3820                         if(result_value) {
3821                                 if(output_buffer_length > strlen(result_value)) {
3822                                         strncpy(output_value, result_value, output_buffer_length);
3823                                         output_value[strlen(result_value)] = NULL_CHAR;
3824                                         ret = true;
3825                                 }
3826                                 else {
3827                                         EM_DEBUG_EXCEPTION("buffer is too short");
3828                                         err = EMAIL_ERROR_DATA_TOO_LONG;
3829                                         goto FINISH_OFF;
3830                                 }       
3831                         }
3832                         
3833                         break;
3834                 }
3835                 temp_param = temp_param->next;
3836         }
3837
3838 FINISH_OFF:
3839         EM_SAFE_FREE(decoded_value);
3840
3841         if(err_code)
3842                 *err_code = err;
3843
3844         EM_DEBUG_FUNC_END("ret [%d]", ret);
3845         return ret;
3846 }
3847
3848
3849 /*
3850  *download body part of imap mail (body-text and attachment)
3851  */
3852 static int emcore_get_body_part_imap(MAILSTREAM *stream, int account_id, int mail_id, int msg_uid, BODY *body, struct _m_content_info *cnt_info, int *err_code)
3853 {
3854         EM_DEBUG_FUNC_BEGIN("stream[%p], msg_uid[%d], body[%p], cnt_info[%p], err_code[%p]", stream, msg_uid, body, cnt_info, err_code);
3855         
3856         int err = EMAIL_ERROR_NONE, ret = -1;
3857         struct attachment_info **ai;
3858         struct attachment_info *prev_ai = NULL;
3859         struct attachment_info *next_ai = NULL; 
3860         char *savefile = NULL;
3861         char *o_data = NULL;
3862         char filename[MAX_PATH + 1] = { 0, };
3863         char *decoded_filename = NULL;
3864         int is_attachment = 0;
3865         int o_data_len = 0;
3866         char *filename_temp = NULL;
3867         char charset_value_buffer[512] = { 0, };
3868         char content_type_buffer[512] = { 0, };
3869 /*  { is_pb */
3870         PART *part = NULL;
3871         int dec_len;
3872         int i = 0;
3873         char *sparep = NULL;
3874         unsigned short encode = 0;
3875         int section_plain = 0;
3876         int section_html = 0;   
3877         int is_pbd = (account_id == 0 && mail_id == 0) ? true  :  false;
3878 /*   } is_pb */
3879
3880         EM_DEBUG_LOG("Grab Type [ %d ] ", cnt_info->grab_type);
3881
3882         /* unknown type */      
3883         if (body->type > TYPEOTHER)  {  /* unknown type */
3884                 EM_DEBUG_EXCEPTION("Unknown type.");
3885                 err = EMAIL_ERROR_NOT_SUPPORTED;
3886                 goto FINISH_OFF;
3887         }
3888
3889         if (NULL == body->subtype)      {
3890                 EM_DEBUG_LOG("body->subtype is null. "); /*  not exceptional case */
3891                 if (err_code != NULL)                   
3892                         *err_code = EMAIL_ERROR_INVALID_PARAM;
3893                 return FAILURE;
3894         }
3895
3896         if (is_pbd) {
3897                 if (!emcore_get_temp_file_name(&o_data, &err) || !o_data)  {
3898                         EM_DEBUG_EXCEPTION("emcore_get_temp_file_name failed [%d]", err);       
3899                         if (err_code != NULL) 
3900                                 *err_code = err;
3901                         return FAILURE;
3902                 }
3903
3904                 
3905                 if (body->subtype[0] == 'P')  { /*  Sub type is PLAIN_TEX */
3906                         if (cnt_info->text.plain != NULL)
3907                                 EM_SAFE_FREE(o_data);
3908                 }
3909
3910                 if (body->type == TYPETEXT && body->subtype && 
3911                         (!body->disposition.type || (body->disposition.type && (body->disposition.type[0] == 'i' || body->disposition.type[0] == 'I')))) {
3912                         if (body->subtype[0] == 'H')    /*  HTM */
3913                                 cnt_info->text.html = o_data;
3914                         else 
3915                                 cnt_info->text.plain = o_data;
3916
3917                         memset(charset_value_buffer, 0, 512);
3918
3919                         if (emcore_get_attribute_value_of_body_part(body->parameter, "CHARSET", charset_value_buffer, 512, true, &err)) {
3920                                 cnt_info->text.plain_charset = EM_SAFE_STRDUP(charset_value_buffer);
3921                                 EM_DEBUG_LOG(">>>>> CHARSET [%s] ", filename);
3922                         }
3923                 }
3924         } /*  is_pbd */
3925
3926         if ((body->id) && strlen(body->id) > 1) {       /* if Content-ID or Content-Location exists, it is inline contents */
3927                 EM_DEBUG_LOG("body->id exist");
3928                 size_t len = 0;
3929                 /*  Get actual name of file - fix for inline images to be stored with actual names and not .jpeg */
3930                 if (body->parameter)  {
3931                         PARAMETER *param1 = body->parameter;
3932                         while (param1)  {
3933                                 EM_DEBUG_LOG("param1->attribute - %s ", param1->attribute);
3934                                 if (!strcasecmp(param1->attribute, "NAME"))  {  /*  attribute is "NAME" */
3935                                         char *extcheck = NULL;
3936                                 
3937                                         if (param1->value) {
3938                                                 decoded_filename = emcore_decode_rfc2047_text(param1->value, &err);
3939                                                 strncpy(filename, decoded_filename, MAX_PATH);
3940                                                 EM_SAFE_FREE(decoded_filename);
3941                                         }
3942                                         EM_DEBUG_LOG(">>>>> FILENAME [%s] ", filename);
3943                                         extcheck = strchr(filename, '.');
3944
3945                                         if (extcheck)
3946                                                 EM_DEBUG_LOG(">>>> Extension Exist in the Attachment [ %s ] ", extcheck);
3947                                         else /*  No extension attached , So add the Extension based on the subtyp */ {
3948                                                 if (body->subtype) {
3949                                                         strcat(filename, ".");
3950                                                         strcat(filename, body->subtype);
3951                                                         EM_DEBUG_LOG(">>>>> FILENAME Identified the Extension [%s] ", filename);
3952                                                 }
3953                                                 else
3954                                                         EM_DEBUG_EXCEPTION("UnKnown Extesnsion  : _ (");
3955                         
3956                                         }
3957                                 
3958                                         break;
3959                                 }
3960                                 param1 = param1->next;
3961                         }
3962
3963                 }
3964                 else if (body->disposition.type)  {             
3965                         PARAMETER *param = body->disposition.parameter;
3966                         
3967                         while (param) {
3968                                 EM_DEBUG_LOG(">>>>> body->disposition.parameter->attribute [ %s ] ", param->attribute);
3969                                 EM_DEBUG_LOG(">>>>> body->disposition.parameter->value [ %s ] ", param->value);
3970
3971                                 /*  attribute is "filename" */
3972                                 if (!strcasecmp(param->attribute, "filename"))  {
3973                                         decoded_filename = emcore_decode_rfc2047_text(param->value, &err);
3974                                         strncpy(filename, decoded_filename, MAX_PATH);
3975                                         EM_SAFE_FREE(decoded_filename);
3976                                         EM_DEBUG_LOG(">>>>> FILENAME [%s] ", filename);
3977                                         break;
3978                                 }
3979                                 
3980                                 param = param->next;
3981                         }
3982                 }
3983                 else {
3984                         if ((body->id[0] == '<'))
3985                                 SNPRINTF(filename, MAX_PATH, "%s", body->id+1);
3986                         else
3987                                 SNPRINTF(filename, MAX_PATH, "%s", body->id);
3988                         
3989                         len = strlen(filename);
3990                         
3991                         if ((len > 1) && (filename[len-1] == '>'))
3992                                 filename[len-1] = '\0';
3993                 }
3994                 /* is_attachment = 1; */
3995                 is_attachment = 0; 
3996         }
3997         else if (body->location) {
3998                 EM_DEBUG_LOG("body->location exist");
3999                 is_attachment = 1;
4000                 decoded_filename = emcore_decode_rfc2047_text(body->location, &err);
4001                 strncpy(filename, decoded_filename, MAX_PATH);
4002                 EM_SAFE_FREE(decoded_filename);
4003                 EM_DEBUG_LOG("body->location [%s]", body->location);
4004         } 
4005         else if (is_pbd && (strncmp(body->subtype, "RFC822", strlen("RFC822")) == 0) && (cnt_info->grab_type == 0 || (cnt_info->grab_type & GRAB_TYPE_ATTACHMENT))) {
4006                 EM_DEBUG_LOG("Beause subtype is RFC822. This is ttachment");
4007                 is_attachment = 1;
4008
4009                 if (cnt_info->grab_type == 0) {
4010                         if ((body->nested.msg != NULL) && (body->nested.msg->env != NULL) && (body->nested.msg->env->subject != NULL)) {
4011                                 decoded_filename = emcore_decode_rfc2047_text(body->nested.msg->env->subject, &err);
4012                                 strncpy(filename, decoded_filename, MAX_PATH);
4013                                 EM_SAFE_FREE(decoded_filename);
4014                         }
4015                         else
4016                                 strncpy(filename, "Unknown <message/rfc822>", MAX_PATH);
4017                 }
4018                 else if (cnt_info->grab_type & GRAB_TYPE_ATTACHMENT) {
4019                         BODY *temp_body = NULL;
4020                         if (body->nested.msg->env->subject != NULL) {
4021                                 int i = 0;
4022                                 int subject_count = 0;
4023                                 if (g_str_has_prefix(body->nested.msg->env->subject, "= ? ") && g_str_has_suffix(body->nested.msg->env->subject, " ? = "))
4024                                         strncpy(filename, "unknown", MAX_PATH);
4025                                 else {
4026                                         for (subject_count = 0; body->nested.msg->env->subject[subject_count] != '\0' ; subject_count++) {
4027                                                 if (body->nested.msg->env->subject[subject_count] != ':'  &&
4028                                                         body->nested.msg->env->subject[subject_count] != ';'  &&
4029                                                         body->nested.msg->env->subject[subject_count] != '*'  &&
4030                                                         body->nested.msg->env->subject[subject_count] != '?'  &&
4031                                                         body->nested.msg->env->subject[subject_count] != '\"' &&
4032                                                         body->nested.msg->env->subject[subject_count] != '<'  &&
4033                                                         body->nested.msg->env->subject[subject_count] != '>'  &&
4034                                                         body->nested.msg->env->subject[subject_count] != '|'  &&
4035                                                         body->nested.msg->env->subject[subject_count] != '/') {
4036                                                         filename[i] = body->nested.msg->env->subject[subject_count];
4037                                                         i++;
4038                                                 }
4039                                                 else
4040                                                         continue;
4041                                         }
4042                                 }       
4043                         }
4044                         else
4045                                 strncpy(filename, "Unknown", MAX_PATH);
4046
4047                         body = ((MESSAGE *)body->nested.msg)->body;
4048                         part = body->nested.part;
4049
4050                         if ((body->subtype[0] == 'P') || (body->subtype[0] == 'H'))
4051                                 temp_body = body;
4052                         else if (part != NULL) {
4053                                 temp_body = &(part->body);
4054                                 if ((temp_body->subtype[0] == 'P' || temp_body->subtype[0] == 'H') && part->next != NULL) {
4055                                         part = part->next;
4056                                         temp_body = &(part->body);
4057                                 }
4058                         }
4059                         
4060                         if (temp_body) {
4061                                 if (temp_body->subtype[0] == 'P')                                                                       
4062                                         section_plain = 1;
4063                                 else if (temp_body->subtype[0] == 'H')
4064                                         section_html = 1;
4065                                 
4066                                 sparep = temp_body->sparep;
4067                                 encode = temp_body->encoding;
4068                         }
4069
4070                 } 
4071         }
4072         else if (body->disposition.type) /*  if disposition exists, get filename from disposition parameter */ {        /*  "attachment" or "inline" or etc.. */
4073                 EM_DEBUG_LOG("body->disposition.type exist");
4074                 is_attachment = 1;
4075                 
4076                 if (emcore_get_attribute_value_of_body_part(body->disposition.parameter, "filename", filename, MAX_PATH, true, &err))
4077                         EM_DEBUG_LOG(">>>>> FILENAME [%s] ", filename);
4078                 
4079                 if (!*filename)  {      /*  If the part has no filename, it may be report ms */
4080                         if ((body->disposition.type[0] == 'i' || body->disposition.type[0] == 'I') && body->parameter && body->parameter->attribute && strcasecmp(body->parameter->attribute, "NAME"))
4081                                 is_attachment = 0;
4082                         else if (body->parameter) /* Fix for the MMS attachment File name as unknown */ {
4083                                 char *extcheck = NULL;
4084                                 
4085                                 if (emcore_get_attribute_value_of_body_part(body->parameter, "NAME", filename, MAX_PATH, true, &err))
4086                                         EM_DEBUG_LOG("NAME [%s] ", filename);
4087
4088                                 extcheck = strchr(filename, '.');
4089
4090                                 if (extcheck)
4091                                         EM_DEBUG_LOG(">>>> Extension Exist in the Attachment [ %s ] ", extcheck);
4092                                 else  { /* No extension attached , So add the Extension based on the subtype */
4093                                         if (body->subtype) {
4094                                                 if (strlen(filename) + strlen(body->subtype) + 1 < MAX_PATH) {
4095                                                         strcat(filename, ".");
4096                                                         strcat(filename, body->subtype);
4097                                                 }
4098                                                 EM_DEBUG_LOG(">>>>> FILENAME Identified the Extension [%s] ", filename);
4099                                         }
4100                                         else
4101                                                 EM_DEBUG_EXCEPTION("UnKnown Extesnsion  : _ (");
4102                                 }
4103
4104                         }
4105                         else
4106                                 strncpy(filename, "unknown", MAX_PATH);
4107                 }
4108                 else {
4109                         if ((body->disposition.type[0] == 'i' || body->disposition.type[0] == 'I'))
4110                                 is_attachment = 0; 
4111                 }
4112         }
4113
4114         /* if (!is_pbd) */ {    
4115                 EM_DEBUG_LOG("filename [%s]", filename);
4116                 if (*filename)  {
4117                         decoded_filename = emcore_decode_rfc2047_text(filename, &err);
4118                         strncpy(filename, decoded_filename, MAX_PATH);
4119                         EM_SAFE_FREE(decoded_filename);
4120                         filename_temp = em_parse_filename(filename);
4121                         if (filename_temp) {
4122                                 strncpy(filename, filename_temp, MAX_PATH);
4123                                 EM_DEBUG_LOG("filename [%s]", filename);
4124                         }
4125                 }
4126         }
4127         EM_DEBUG_LOG("is_attachment [%d]", is_attachment);
4128
4129         if (!is_attachment)  {  /*  Text or RFC822 Message */
4130                 EM_DEBUG_LOG("Multipart is not attachment, body->type = %d", body->type);
4131                 if ((cnt_info->grab_type & GRAB_TYPE_TEXT) && (body->type == TYPEMESSAGE || body->type == TYPETEXT || body->type == TYPEIMAGE))  {
4132                         if (is_pbd)
4133                                 return SUCCESS;
4134                         else {  /*  fetch body */
4135                                 if (!emcore_get_temp_file_name(&o_data, &err))  {
4136                                         EM_DEBUG_EXCEPTION("emcore_get_temp_file_name failed [%d]", err);                       
4137                                         goto FINISH_OFF;
4138                                 }
4139                         
4140                                 if (!imap_mail_write_body_to_file(stream, account_id, mail_id, 0, o_data, msg_uid, body->sparep, body->encoding, &o_data_len, body->subtype, &err))  {
4141                                         EM_DEBUG_EXCEPTION("imap_mail_write_body_to_file failed [%d]", err);                    
4142                                         goto FINISH_OFF;
4143                                 }
4144                         }
4145                 }
4146
4147                 switch (body->type)  {
4148                         case TYPETEXT:
4149                                 EM_DEBUG_LOG("TYPETEXT");
4150                                 if (body->subtype[0] == 'H') 
4151                                         cnt_info->text.html = o_data;
4152                                 else  {
4153                                         cnt_info->text.plain = o_data;
4154                                         memset(charset_value_buffer, 0, 512);
4155                                         if (emcore_get_attribute_value_of_body_part(body->parameter, "CHARSET", charset_value_buffer, 512, true, &err))
4156                                                 cnt_info->text.plain_charset = EM_SAFE_STRDUP(charset_value_buffer);
4157                                 }
4158                                 break;
4159                         case TYPEIMAGE:
4160                         case TYPEAPPLICATION: 
4161                         case TYPEAUDIO:
4162                         case TYPEVIDEO:
4163                         /*  Inline Content - suspect of crash on partial body download */
4164                                 if (!is_pbd) {
4165                                         EM_DEBUG_LOG("TYPEIMAGE or TYPEAPPLICATION  :  inline content");
4166                                         ai = &(cnt_info->file);
4167                                         
4168                                         dec_len = body->size.bytes;
4169                                         if ((cnt_info->grab_type & GRAB_TYPE_ATTACHMENT) && 
4170                                                 (cnt_info->grab_type & GRAB_TYPE_TEXT))  {      /*  it is 'download all */
4171                                                 only_body_download = false;
4172                                                 cnt_info->file_no = 1;
4173                                         }
4174
4175                                         /*  add attachment info to content info */
4176                                         if (!(*ai = em_malloc(sizeof(struct attachment_info))))  {              
4177                                                 EM_DEBUG_EXCEPTION("em_malloc failed...");                                              
4178                                                 if (err_code != NULL) 
4179                                                         *err_code = EMAIL_ERROR_OUT_OF_MEMORY;                  
4180                                                 return FAILURE;         
4181                                         }       
4182                                 
4183                                         if (((body->id) || (body->location)) && body->type == TYPEIMAGE)
4184                                                 (*ai)->type = 1;                        /*  inline */
4185                                         else                    
4186                                                 (*ai)->type = 2;                        /*  attachment */
4187                                         
4188                                         (*ai)->name                 = EM_SAFE_STRDUP(filename);
4189                                         (*ai)->size                 = body->size.bytes;
4190                                         (*ai)->save                 = o_data;
4191                                         (*ai)->content_id           = EM_SAFE_STRDUP(body->id);
4192
4193                                         memset(content_type_buffer, 0, 512);
4194                                         if ( (err = emcore_get_content_type_from_mail_bodystruct(body, 512, content_type_buffer) ) == EMAIL_ERROR_NONE)
4195                                                 (*ai)->attachment_mime_type = EM_SAFE_STRDUP(content_type_buffer);
4196
4197                                         EM_DEBUG_LOG("name[%s], size[%d], save[%s], content_id[%s], content_type_buffer [%s]", cnt_info->file->name, cnt_info->file->size, cnt_info->file->save, content_type_buffer);
4198 #ifdef __ATTACHMENT_OPTI__
4199                                         (*ai)->encoding = body->encoding;
4200                                         if (body->sparep)
4201                                                 (*ai)->section = EM_SAFE_STRDUP(body->sparep);
4202                                         EM_DEBUG_LOG(" Encoding - %d  Section No - %s ", (*ai)->encoding, (*ai)->section);
4203 #endif                  
4204                                 }       
4205                                 break;
4206
4207                         case TYPEMESSAGE:  /*  RFC822 Message */
4208                                 EM_DEBUG_EXCEPTION("MESSAGE/RFC822");
4209                                 err = EMAIL_ERROR_NOT_SUPPORTED;
4210                                 goto FINISH_OFF;
4211                         
4212                         default: 
4213                                 EM_DEBUG_EXCEPTION("Unknown type. body->type [%d]", body->type);
4214                                 err = EMAIL_ERROR_NOT_SUPPORTED;
4215                                 goto FINISH_OFF;
4216                 }
4217                 
4218                 stream->text.data = NULL;  /*  ? ? ? ? ? ? ? ? */
4219         }
4220         else  { /*  Attachment */
4221                 prev_ai = NULL;
4222                 next_ai = NULL;
4223                 ai = &cnt_info->file;
4224                 EM_DEBUG_LOG(" ai - %p ", (*ai));
4225
4226                 if ((body->id) || (body->location)) {
4227                         /*  For Inline content append to the end */
4228                         for (i = 1; *ai; ai = &(*ai)->next)
4229                                 i++;
4230                         }
4231                 else {  /*  For attachment - search till Inline content found and insert before inline */
4232                         for (i = 1; *ai; ai = &(*ai)->next) {
4233                                 if ((*ai)->type == 1)  {
4234                                         /*  Means inline image */
4235                                         EM_DEBUG_LOG("Found Inline Content ");
4236                                         next_ai = (*ai);
4237                                         break;
4238                                 }
4239                                 i++;
4240                                 prev_ai = (*ai);
4241                         }
4242                 }
4243                 
4244                 EM_DEBUG_LOG("i - %d next_ai - %p  prev_ai - %p", i, next_ai, prev_ai);
4245                 
4246                 if ((cnt_info->grab_type & GRAB_TYPE_ATTACHMENT) && 
4247                 (cnt_info->grab_type & GRAB_TYPE_TEXT))  {      /*  it is 'download all */
4248                         EM_DEBUG_LOG("Download All");
4249                         only_body_download = false;
4250                         cnt_info->file_no = 1;
4251                         i = 1;
4252                 }
4253                 /*  meaningless code */
4254                 dec_len = body->size.bytes;
4255                 
4256                 if (body->id)
4257                         EM_DEBUG_LOG("BODY ID [ %s ]", body->id);
4258                 else
4259                         EM_DEBUG_LOG("BODY ID IS NULL");
4260                 
4261                 EM_DEBUG_LOG("i : %d, cnt_info->file_no : %d", i, cnt_info->file_no);
4262                 
4263                 if (
4264                         ((cnt_info->grab_type & GRAB_TYPE_ATTACHMENT) && i == cnt_info->file_no) ||   /*  Is it correct attachment  */
4265                         (((body->id) || (body->location)) && (cnt_info->grab_type & GRAB_TYPE_TEXT))  /*  Is it inline contents  */
4266                 )  {
4267                         /*  fetch attachment */
4268                         EM_DEBUG_LOG("attachment (enc)  :  %s %ld bytes", filename, body->size.bytes);
4269                         EM_DEBUG_LOG(">>>>> ONLY BODY DOWNLOAD [ %d ] ", only_body_download);
4270
4271                         if (only_body_download == false) {
4272                                 if (!emcore_get_temp_file_name(&savefile, &err))  {
4273                                         EM_DEBUG_EXCEPTION("emcore_get_temp_file_name failed [%d]", err);                       
4274                                         goto FINISH_OFF;
4275                                 }
4276
4277                                 if (!is_pbd) {
4278                                         if (!imap_mail_write_body_to_file(stream, account_id, mail_id, cnt_info->file_no, savefile, msg_uid, body->sparep, body->encoding, &dec_len, body->subtype, &err))  {
4279                                                 EM_DEBUG_EXCEPTION("imap_mail_write_body_to_file failed [%d]", err);
4280                                                 goto FINISH_OFF;
4281                                         }
4282                                 }
4283                         }
4284                 }
4285
4286                 EM_DEBUG_LOG("attachment (dec)  :  %s %d bytes", filename, dec_len);            
4287
4288                 /*  add attachment info to content inf */
4289                 if (!(*ai = em_malloc(sizeof(struct attachment_info))))  {
4290                         EM_DEBUG_EXCEPTION("em_malloc failed...");
4291                         err = EMAIL_ERROR_OUT_OF_MEMORY;
4292                         goto FINISH_OFF;
4293                 }
4294
4295                 if ((body->id) || (body->location))
4296                         (*ai)->type = 1;
4297                 else
4298                         (*ai)->type = 2;
4299
4300                 if (is_pbd) {
4301                         if (savefile != NULL) {
4302                                 if (section_plain == 1)
4303                                         strcat(filename, ".txt");
4304                                 if (section_html == 1)
4305                                         strcat(filename, ".html");
4306                                 section_plain = 0;
4307                                 section_html = 0;
4308                         }
4309                 } /*  is_pbd */
4310                 (*ai)->name                 = EM_SAFE_STRDUP(filename);
4311                 (*ai)->size                 = dec_len;
4312                 (*ai)->save                 = savefile;
4313                 (*ai)->content_id           = EM_SAFE_STRDUP(body->id);
4314                 
4315                 memset(content_type_buffer, 0, 512);
4316                 if ( (err = emcore_get_content_type_from_mail_bodystruct(body, 512, content_type_buffer) ) == EMAIL_ERROR_NONE)
4317                         (*ai)->attachment_mime_type = EM_SAFE_STRDUP(content_type_buffer);
4318 #ifdef __ATTACHMENT_OPTI__
4319                 (*ai)->encoding = body->encoding;
4320                 if (body->sparep)
4321                         (*ai)->section = EM_SAFE_STRDUP(body->sparep);
4322
4323                 EM_DEBUG_LOG(" Encoding - %d  Section No - %s ", (*ai)->encoding, (*ai)->section);
4324 #endif
4325                 if (body->type == TYPEAPPLICATION)  {
4326                         if (!strcasecmp(body->subtype, MIME_SUBTYPE_DRM_OBJECT))
4327                                 (*ai)->drm = EMAIL_ATTACHMENT_DRM_OBJECT;
4328                         else if (!strcasecmp(body->subtype, MIME_SUBTYPE_DRM_RIGHTS))
4329                                 (*ai)->drm = EMAIL_ATTACHMENT_DRM_RIGHTS;
4330                         else if (!strcasecmp(body->subtype, MIME_SUBTYPE_DRM_DCF))
4331                                 (*ai)->drm = EMAIL_ATTACHMENT_DRM_DCF;
4332                 }
4333                 
4334                 /*  All inline images information are stored at the end of list */
4335                 if ((*ai)->type != 1 && next_ai != NULL) {
4336                 /*  Means next_ai points to the inline attachment info structure */
4337                         if (prev_ai == NULL) {
4338                                 /*  First node is inline attachment */
4339                                 (*ai)->next = next_ai;
4340                                 cnt_info->file = (*ai);
4341                         }
4342                         else {
4343                                 prev_ai->next = (*ai);
4344                                 (*ai)->next = next_ai;
4345                         }
4346                 }
4347         }
4348
4349         ret = 0;
4350 FINISH_OFF: 
4351         if (err_code)
4352                 *err_code = err;
4353         EM_DEBUG_FUNC_END("ret [%d]", ret);
4354         return ret;
4355 }
4356 /*  get body-part in nested part */
4357
4358 static int emcore_get_allnested_part(MAILSTREAM *stream, int account_id, int mail_id, int msg_uid, BODY *body, struct _m_content_info *cnt_info, int *err_code)
4359 {
4360         EM_DEBUG_FUNC_BEGIN("stream[%p], msg_uid[%d], body[%p], cnt_info[%p], err_code[%p]", stream, msg_uid, body, cnt_info, err_code);
4361         PART *part_child = body->nested.part;
4362         
4363         while (part_child)  {
4364                 if (emcore_get_body(stream, account_id, mail_id, msg_uid, &part_child->body, cnt_info, err_code) < 0)
4365                         return FAILURE;
4366                 
4367                 part_child = part_child->next;
4368         }
4369
4370         EM_DEBUG_FUNC_END();
4371         return SUCCESS;
4372 }
4373
4374 /* get body-part in alternative multiple part */
4375 static int emcore_get_alternative_multi_part(MAILSTREAM *stream, int account_id, int mail_id, int msg_uid, BODY *body, struct _m_content_info *cnt_info, int *err_code)
4376 {
4377         EM_DEBUG_FUNC_BEGIN("stream[%p], msg_uid[%d], body[%p], cnt_info[%p], err_code[%p]", stream, msg_uid, body, cnt_info, err_code);
4378         
4379         PART *part_child = body->nested.part;
4380
4381         /* find the best sub part we can show */
4382         while (part_child)  {
4383                 if (emcore_get_body(stream, account_id, mail_id, msg_uid, &part_child->body, cnt_info, err_code) < 0)
4384                         return FAILURE;
4385                 
4386                 part_child = part_child->next;
4387         }
4388         EM_DEBUG_FUNC_END();
4389         return SUCCESS;
4390 }
4391
4392 /* get body part in signed multiple part */
4393 static int emcore_get_signed_multi_part(MAILSTREAM *stream, int account_id, int mail_id, int msg_uid, BODY *body, struct _m_content_info *cnt_info, int *err_code)
4394 {
4395         EM_DEBUG_FUNC_BEGIN("stream[%p], msg_uid[%d], body[%p], cnt_info[%p], err_code[%p]", stream, msg_uid, body, cnt_info, err_code);
4396
4397         PART *part_child = body->nested.part;
4398
4399         /* find the best sub part we can show */
4400         while (part_child)  {
4401                 if (emcore_get_body(stream, account_id, mail_id, msg_uid, &part_child->body, cnt_info, err_code) < 0)
4402                         return FAILURE;
4403
4404                 part_child = part_child->next;
4405         }
4406
4407         EM_DEBUG_FUNC_END();    
4408         return SUCCESS;
4409 }
4410
4411 /* get body part in encrypted multiple part */
4412 static int emcore_get_encrypted_multi_part(MAILSTREAM *stream, int account_id, int mail_id, int msg_uid, BODY *body, struct _m_content_info *cnt_info, int *err_code)
4413 {
4414         EM_DEBUG_FUNC_BEGIN("stream[%p], msg_uid[%d], body[%p], cnt_info[%p], err_code[%p]", stream, msg_uid, body, cnt_info, err_code);
4415         EM_DEBUG_FUNC_END();
4416         return SUCCESS;
4417 }
4418
4419 /* get body part in multiple part */
4420 static int emcore_get_multi_part(MAILSTREAM *stream, int account_id, int mail_id, int msg_uid, BODY *body, struct _m_content_info *cnt_info, int *err_code)
4421 {
4422         EM_DEBUG_FUNC_BEGIN("stream[%p], msg_uid[%d], body[%p], cnt_info[%p], err_code[%p]", stream, msg_uid, body, cnt_info, err_code);
4423
4424         if (!body) {
4425                 EM_DEBUG_EXCEPTION("Invalid Parameter.");
4426                 if (err_code)
4427                         *err_code = EMAIL_ERROR_INVALID_PARAM;
4428                 return FAILURE;
4429         }
4430
4431         switch (body->subtype[0])  {
4432                 case 'A':               /*  ALTERNATIVE */
4433                         EM_DEBUG_LOG("body->subtype[0] = ALTERNATIVE");
4434                         return emcore_get_alternative_multi_part(stream, account_id, mail_id, msg_uid, body, cnt_info, err_code);
4435                 
4436                 case 'S':               /*  SIGNED */
4437                         EM_DEBUG_LOG("body->subtype[0] = SIGNED");
4438                         return emcore_get_signed_multi_part(stream, account_id, mail_id, msg_uid, body, cnt_info, err_code);
4439                 
4440                 case 'E':               /*  ENCRYPTED */
4441                         EM_DEBUG_LOG("body->subtype[0] = ENCRYPTED");
4442                         return emcore_get_encrypted_multi_part(stream, account_id, mail_id, msg_uid, body, cnt_info, err_code);
4443                 
4444                 default:                /*  process all unknown as MIXED (according to the RFC 2047) */
4445                         EM_DEBUG_LOG("body->subtype[0] = [%c].", body->subtype[0]);
4446                         return emcore_get_allnested_part(stream, account_id, mail_id, msg_uid, body, cnt_info, err_code);
4447         }
4448
4449         if  (body->id)
4450                 EM_DEBUG_LOG("emcore_get_multi_part BODY ID [%s].", body->id);
4451         else
4452                 EM_DEBUG_LOG("emcore_get_multi_part BODY ID NULL.");
4453         EM_DEBUG_FUNC_END();
4454         return SUCCESS;
4455 }
4456
4457 /*  get body data by body structure */
4458 /*  if POP3, ignored */
4459 INTERNAL_FUNC int emcore_get_body(MAILSTREAM *stream, int account_id, int mail_id, int msg_uid, BODY *body, struct _m_content_info *cnt_info, int *err_code)
4460 {
4461         EM_DEBUG_FUNC_BEGIN("stream[%p], msg_uid[%d], body[%p], cnt_info[%p], err_code[%p]", stream, msg_uid, body, cnt_info, err_code);
4462         
4463         if (!stream || !body || !cnt_info)  {
4464                 EM_DEBUG_EXCEPTION("Invalid parameter");
4465                 
4466                 if (err_code != NULL)
4467                         *err_code = EMAIL_ERROR_INVALID_PARAM;
4468                 return FAILURE;
4469         }
4470
4471         EM_DEBUG_LOG("body->type [%d]", body->type);
4472         
4473         switch (body->type)  {
4474                 case TYPEMULTIPART: 
4475                         return emcore_get_multi_part(stream, account_id, mail_id, msg_uid, body, cnt_info, err_code);
4476                 
4477                 case TYPEMESSAGE:  /*  not support */
4478                         if (strcasecmp(body->subtype, "RFC822") == 0)
4479                                 return emcore_get_body_part_imap(stream, account_id, mail_id, msg_uid, body, cnt_info, err_code);
4480                         break;
4481                         
4482                 case TYPETEXT:
4483                 case TYPEAPPLICATION: 
4484                 case TYPEAUDIO:
4485                 case TYPEIMAGE:
4486                 case TYPEVIDEO:
4487                 case TYPEMODEL:
4488                 case TYPEOTHER:
4489                         /*  exactly, get a pure body part (text and attachment */
4490                         return emcore_get_body_part_imap(stream, account_id, mail_id, msg_uid, body, cnt_info, err_code);
4491                 
4492                 default: 
4493                         break;
4494         }
4495         EM_DEBUG_FUNC_END();
4496         return SUCCESS;
4497 }
4498
4499 /* get body structure */
4500 INTERNAL_FUNC int emcore_get_body_structure(MAILSTREAM *stream, int msg_uid, BODY **body, int *err_code)
4501 {
4502         EM_DEBUG_FUNC_BEGIN("stream[%p], msg_uid[%d], body[%p], err_code[%p]", stream, msg_uid, body, err_code);
4503         
4504         EM_IF_NULL_RETURN_VALUE(stream, false);
4505         EM_IF_NULL_RETURN_VALUE(body, false);
4506         
4507 #ifdef __FEATURE_HEADER_OPTIMIZATION__  
4508                 ENVELOPE *env = mail_fetch_structure(stream, msg_uid, body, FT_UID | FT_PEEK | FT_NOLOOKAHEAD, 1);
4509 #else
4510                 ENVELOPE *env = mail_fetch_structure(stream, msg_uid, body, FT_UID | FT_PEEK | FT_NOLOOKAHEAD);
4511 #endif
4512         if (!env) {
4513                 if (err_code)
4514                         *err_code = EMAIL_ERROR_MAIL_NOT_FOUND_ON_SERVER;
4515                 EM_DEBUG_EXCEPTION("mail_fetch_structure failed");
4516                 return FAILURE;
4517         }
4518         
4519 #ifdef FEATURE_CORE_DEBUG
4520         _print_body(*body, true); /* shasikala.p@partner.samsung.com */
4521 #endif
4522         EM_DEBUG_FUNC_END();
4523         return SUCCESS;
4524 }
4525
4526 int emcore_set_fetch_part_section(BODY *body, char *section_pfx, int section_subno, int enable_inline_list, int *total_mail_size, int *err_code);
4527
4528 /* set body section to be fetched */
4529 INTERNAL_FUNC int emcore_set_fetch_body_section(BODY *body, int enable_inline_list, int *total_mail_size, int *err_code)
4530 {
4531         EM_DEBUG_FUNC_BEGIN("body[%p], err_code[%p]", body, err_code);
4532
4533         if (!body)  {
4534                 EM_DEBUG_EXCEPTION("body [%p]", body);
4535                 if (err_code != NULL)
4536                         *err_code = EMAIL_ERROR_INVALID_PARAM;
4537                 return FAILURE;
4538         }
4539         
4540         body->id = cpystr("1"); /*  top level body */
4541         
4542         g_inline_count = 0;
4543         EM_SAFE_FREE(g_inline_list);
4544         emcore_set_fetch_part_section(body, (char *)NULL, 0, enable_inline_list, total_mail_size, err_code);
4545         
4546         if (body->id && body)
4547                 EM_DEBUG_LOG(">>>>> FILE NAME [ %s ] ", body->id);
4548         else
4549                 EM_DEBUG_LOG(">>>>> BODY NULL ", body->id);
4550
4551         EM_DEBUG_FUNC_END();
4552         return SUCCESS;
4553 }
4554
4555 /* set part section of body to be fetched */
4556 int emcore_set_fetch_part_section(BODY *body, char *section_pfx, int section_subno, int enable_inline_list, int *total_mail_size, int *err_code)
4557 {
4558         EM_DEBUG_FUNC_BEGIN("body[%p], section_pfx[%s], section_subno[%d], err_code[%p]", body, section_pfx, section_subno, err_code);
4559         
4560         PART *part = NULL;
4561         char section[64] = {0x00, };
4562         
4563         /* multipart doesn't have a row to itself */
4564         if (body->type == TYPEMULTIPART)  {
4565                 /* if not first time, extend prefix */
4566                 if (section_pfx) {
4567                         SNPRINTF(section, sizeof(section), "%s%d.", section_pfx, ++section_subno);
4568                 }
4569                 else {
4570                         section[0] = '\0';
4571                 }
4572
4573                 for (section_subno = 0, part = body->nested.part; part; part = part->next)
4574                         emcore_set_fetch_part_section(&part->body, section, section_subno++, enable_inline_list, total_mail_size, err_code);
4575         }
4576         else  {
4577                 if (!section_pfx) /* dummy prefix if top level */
4578                         section_pfx = "";               
4579
4580                 SNPRINTF(section, sizeof(section), "%s%d", section_pfx, ++section_subno);
4581
4582                 if (enable_inline_list && ((body->disposition.type && (body->disposition.type[0] == 'i' || body->disposition.type[0] == 'I')) || 
4583                         (!body->disposition.type && body->id))) {
4584                         BODY **temp = NULL;
4585                         temp =  realloc(g_inline_list, sizeof(BODY *) *(g_inline_count + 1));
4586                         if (NULL != temp) {
4587                                 memset(temp+g_inline_count, 0x00, sizeof(BODY *));
4588                                 g_inline_list = temp;
4589                                 g_inline_list[g_inline_count] = body;
4590                                 g_inline_count++;
4591                                 temp = NULL;
4592                         }
4593                         else {
4594                                 EM_DEBUG_EXCEPTION("realloc fails");
4595                         }
4596
4597                         EM_DEBUG_LOG("Update g_inline_list with inline count [%d]", g_inline_count);
4598                 }
4599                 
4600                 /*  if ((total_mail_size != NULL) && !(body->disposition.type && (body->disposition.type[0] == 'a' || body->disposition.type[0] == 'A')) */
4601                 if (total_mail_size != NULL) {
4602                         *total_mail_size = *total_mail_size + (int)body->size.bytes;
4603                         EM_DEBUG_LOG("body->size.bytes [%d]", body->size.bytes);
4604                 }
4605
4606                 /* encapsulated message ? */
4607                 if ((body->type == TYPEMESSAGE) && !strcasecmp(body->subtype, "RFC822") && (body = ((MESSAGE *)body->nested.msg)->body))  {
4608                         if (body->type == TYPEMULTIPART) {
4609                                 section[0] = '\0';
4610                                 emcore_set_fetch_part_section(body, section, section_subno-1, enable_inline_list, total_mail_size, err_code);
4611                         }
4612                         else  {         /*  build encapsulation prefi */
4613                                 SNPRINTF(section, sizeof(section), "%s%d.", section_pfx, section_subno);
4614                                 emcore_set_fetch_part_section(body, section, 0, enable_inline_list, total_mail_size, err_code);
4615                         }
4616                 }
4617                 else  {
4618                         /* set body section */
4619                         if (body) 
4620                                 body->sparep = cpystr(section);
4621                 }
4622         }
4623         EM_DEBUG_FUNC_END();
4624         return SUCCESS;
4625 }
4626
4627
4628 static void parse_file_path_to_filename(char *src_string, char **out_string)
4629 {
4630         char *token = NULL;
4631         char *filepath = NULL;
4632         char *str = NULL;
4633         char *prev1 = NULL;
4634         char *prev2 = NULL;
4635
4636         filepath = EM_SAFE_STRDUP(src_string);
4637         token = strtok_r(filepath, "/", &str);
4638
4639         do {
4640                 prev2 = prev1;
4641                 prev1 = token;
4642         } while ((token = strtok_r(NULL , "/", &str))); 
4643
4644         *out_string = EM_SAFE_STRDUP(prev1);
4645         EM_SAFE_FREE(filepath);
4646 }
4647
4648 static char *emcore_decode_rfc2047_word(char *encoded_word, int *err_code)
4649 {
4650         EM_DEBUG_FUNC_BEGIN("encoded_word[%s], err_code[%p]", encoded_word, err_code);
4651
4652         int err = EMAIL_ERROR_NONE;
4653         int base64_encoded = false, length = 0;
4654         SIZEDTEXT src = { NULL, 0 };
4655         SIZEDTEXT dst = { NULL, 0 };
4656         gchar *charset = NULL, *encoded_text = NULL;
4657         char *decoded_text = NULL, *decoded_word = NULL;
4658         char *current = NULL, *start = NULL, *end = NULL;
4659         char *buffer = (char*) em_malloc(strlen(encoded_word) * 2 + 1);
4660
4661         if (buffer == NULL) {
4662                 EM_DEBUG_EXCEPTION("Memory allocation fail");
4663                 err = EMAIL_ERROR_OUT_OF_MEMORY;
4664                 goto FINISH_OFF;
4665         }
4666
4667         strcpy(buffer, "");
4668                 
4669         /*  encoding format : =?charset?encoding?encoded-text ?=  */
4670         /*  charset : UTF-8, EUC-KR, ... */
4671         /*  encoding : b/B (BASE64), q/Q (QUOTED-PRINTABLE) */
4672         current = encoded_word;
4673
4674         while (*current != NULL_CHAR) {
4675                 /* search next */
4676                 start = strstr(current, "=?");          /*  start of encoding */
4677                 end = strstr(current, "?=");            /*  end of encoding */
4678
4679 #ifdef FEATURE_CORE_DEBUG       
4680                 EM_DEBUG_LOG("current[%p][%s], start[%p][%s], end[%p][%s]", current, current, start, start, end, end);
4681 #endif
4682                 if (start != NULL) {
4683                         if (current != start) { /*  copy the string between current and start to buffer */
4684                                 strncat(buffer, current, start - current);
4685                                 current = start;
4686 #ifdef FEATURE_CORE_DEBUG       
4687                                 EM_DEBUG_LOG("1 - Buffer[%s]", buffer);
4688 #endif
4689                         }
4690                         
4691                         if (end) {      /*  decode text between start and end */
4692                                 char *p = strstr(start, "?b?");
4693                                 
4694                                 if (p || (p = strstr(start, "?B?")))            /*  BASE64 */
4695                                         base64_encoded = true;
4696                                 else {
4697                                         p = strstr(start, "?q?");
4698                                         
4699                                         if (p || (p = strstr(start, "?Q?")))            /*  QUOTED-PRINTABLE */
4700                                                 base64_encoded = false;
4701                                         else {
4702                                                 EM_DEBUG_EXCEPTION("unknown encoding found...");
4703                                                 
4704                                                 err = EMAIL_ERROR_UNKNOWN;
4705                                                 goto FINISH_OFF;
4706                                         }
4707                                 }
4708
4709                                 if (base64_encoded) {   /*  BASE64 */
4710                                         charset = g_strndup(start + 2, p - (start + 2));
4711                                         encoded_text = g_strndup(p + 3, end - (p + 3));
4712                                 }
4713                                 else {  /*  QUOTED-PRINTABLE */
4714                                         charset = g_strndup(start + 2, p - (start + 2));
4715                                         if (*(p+3) == '=') {    /*  encoded text might start with '='. ex) '?Q?=E0' */
4716                                                 end = strstr(p+3, "?=");                /*  find new end flag */
4717                                                 if (end) {
4718                                                         encoded_text = g_strndup(p + 3, end - (p + 3));
4719                                                 }
4720                                                 else {  /*  end flag is not found */
4721                                                         EM_DEBUG_EXCEPTION("emcore_decode_rfc2047_word decoding error : '?=' is not found...");
4722                                                         
4723                                                         err = EMAIL_ERROR_UNKNOWN;
4724                                                         goto FINISH_OFF;
4725                                                 }
4726                                         }
4727                                         else {
4728                                                 encoded_text = g_strndup(p + 3, end - (p + 3));
4729                                         }
4730                                 }
4731                                 
4732 #ifdef FEATURE_CORE_DEBUG       
4733                                 EM_DEBUG_LOG("\t >>>>>>>>>>>>>>> CHARSET[%s]", charset);
4734                                 EM_DEBUG_LOG("\t >>>>>>>>>>>>>>> ENCODED_TEXT[%s]", encoded_text);
4735 #endif
4736
4737                                 unsigned long len = 0;
4738                                 if (encoded_text != NULL) {
4739                                 if (base64_encoded == true) {
4740                                         if (!(decoded_text = (char *)rfc822_base64((unsigned char *)encoded_text, strlen(encoded_text), &len))) {
4741                                                 EM_DEBUG_EXCEPTION("rfc822_base64 falied...");
4742                                                 goto FINISH_OFF;
4743                                         }
4744                                 }
4745                                 else  {
4746                                         g_strdelimit(encoded_text, "_", ' ');
4747                                         
4748                                         if (!(decoded_text = (char *)rfc822_qprint((unsigned char *)encoded_text, strlen(encoded_text), &len))) {
4749                                                 EM_DEBUG_EXCEPTION("rfc822_base64 falied...");
4750                                                 goto FINISH_OFF;
4751                                         }
4752                                 }
4753                                 
4754                                 src.data = (unsigned char *)decoded_text;
4755                                 src.size = strlen(decoded_text);
4756                                 
4757                                 if (!utf8_text(&src, charset, &dst, 0))  {
4758                                         EM_DEBUG_EXCEPTION("utf8_text falied...");
4759                                         strncat(buffer, (char *)src.data, src.size); /* Eventhough failed to decode, downloading should go on. Kyuho Jo */
4760                                 }
4761                                 else
4762                                         strncat(buffer, (char *)dst.data, dst.size);
4763 #ifdef FEATURE_CORE_DEBUG       
4764                                 EM_DEBUG_LOG("2 - Buffer[%s]", buffer);
4765 #endif
4766
4767                                 /*  free all of the temp variables */
4768                                 if (dst.data != NULL && dst.data != src.data)
4769                                         EM_SAFE_FREE(dst.data);
4770
4771                                 EM_SAFE_FREE(decoded_text);
4772                                 
4773                                         g_free(encoded_text);
4774                                         encoded_text = NULL;
4775                                 }
4776                                 if (charset != NULL) {
4777                                         g_free(charset);        
4778                                         charset = NULL;
4779                                 }
4780
4781                                 current = end + 2;      /*  skip '?=' */
4782                         }
4783                         else {
4784                                 /*  unencoded text      */
4785                                 length = strlen(start);
4786                                 strncat(buffer, start, length);
4787                                 current = start + length;
4788 #ifdef FEATURE_CORE_DEBUG       
4789                                 EM_DEBUG_LOG("3 - Buffer[%s]", buffer);
4790 #endif
4791                         }
4792                 }
4793                 else {
4794                         /*  unencoded text      */
4795                         length = strlen(current);
4796                         strncat(buffer, current, length);
4797                         current = current + length;
4798 #ifdef FEATURE_CORE_DEBUG       
4799                         EM_DEBUG_LOG("4 - Buffer[%s]", buffer);
4800 #endif
4801                 }
4802         }
4803
4804         decoded_word = EM_SAFE_STRDUP(buffer);
4805
4806 #ifdef FEATURE_CORE_DEBUG       
4807         EM_DEBUG_LOG(">>>>>>>>>>>>>>> DECODED_WORD[%s]", decoded_word);
4808 #endif
4809
4810 FINISH_OFF:
4811         if (dst.data != NULL && dst.data != src.data)
4812                 EM_SAFE_FREE(dst.data);
4813         EM_SAFE_FREE(decoded_text);
4814         EM_SAFE_FREE(buffer);
4815
4816         if (encoded_text != NULL)
4817                 g_free(encoded_text);
4818         if (charset != NULL)
4819                 g_free(charset);        
4820         
4821         if (err_code != NULL)
4822                 *err_code = err;
4823         
4824         EM_DEBUG_FUNC_END();
4825         return decoded_word;
4826 }
4827
4828 INTERNAL_FUNC char *emcore_decode_rfc2047_text(char *rfc2047_text, int *err_code)
4829 {
4830         EM_DEBUG_FUNC_BEGIN("rfc2047_text[%s], err_code[%p]", rfc2047_text, err_code);
4831         
4832         int ret = false;
4833         int err = EMAIL_ERROR_NONE;
4834         
4835         if (!rfc2047_text)  {
4836                 EM_DEBUG_EXCEPTION("rfc2047_text[%p]", rfc2047_text);
4837                 if (err_code != NULL)
4838                         *err_code = EMAIL_ERROR_INVALID_PARAM;
4839                 return NULL;
4840         }
4841         
4842         char *text = NULL;
4843         
4844         gchar **encoded_words = g_strsplit_set(rfc2047_text, " \t\r\n", -1);
4845         gchar **decoded_words = g_new0(char *, g_strv_length(encoded_words) + 1);
4846         
4847         /* EM_DEBUG_LOG("g_strv_length(encoded_words) [%d]", g_strv_length(encoded_words)); */
4848         
4849         if (encoded_words != NULL)  {
4850                 int i = 0;
4851                 
4852                 while (encoded_words[i] != NULL)  {
4853                         if (!(decoded_words[i] = emcore_decode_rfc2047_word(encoded_words[i], &err)))  {
4854                                 EM_DEBUG_EXCEPTION("emcore_decode_rfc2047_word falied [%d]", err);
4855                                 goto FINISH_OFF;
4856                         }
4857                         
4858                         i++;
4859                 }
4860                 text = g_strjoinv(" ", decoded_words);
4861         }
4862         else
4863                 text = EM_SAFE_STRDUP(rfc2047_text);
4864         
4865 #ifdef FEATURE_CORE_DEBUG
4866         EM_DEBUG_LOG(">>>>>>>>>>>>>>>>> TEXT[%s]", text);
4867 #endif  /*  FEATURE_CORE_DEBUG */
4868         
4869         ret = true;
4870         
4871 FINISH_OFF:
4872         g_strfreev(decoded_words);
4873         g_strfreev(encoded_words);
4874         
4875         if (err_code != NULL)
4876                 *err_code = err;
4877         EM_DEBUG_FUNC_END();
4878         return text;
4879 }
4880
4881 INTERNAL_FUNC int emcore_make_mail_data_from_mime_data(struct _m_mesg *mmsg, struct _m_content_info *cnt_info, email_mail_data_t **output_mail_data, email_attachment_data_t **output_attachment_data, int *output_attachment_count, int *err_code)
4882 {
4883         EM_DEBUG_FUNC_BEGIN();
4884         int ret = false;
4885         int err = EMAIL_ERROR_NONE;
4886         int local_attachment_count = 0;
4887         int local_inline_content_count = 0;
4888         int attachment_num = 0;
4889         int i = 0;
4890         int eml_mail_id = 0;
4891         char buf[512];
4892         char html_body[MAX_PATH] = {0, };
4893         struct tm temp_time_info;
4894         struct timeval tv;
4895         struct attachment_info *ai = NULL;
4896         email_attachment_data_t *attachment = NULL;
4897         email_mail_data_t *p_mail_data = NULL;
4898         MESSAGECACHE mail_cache_element = {0, };
4899
4900         if (!mmsg || !cnt_info || !output_mail_data || !output_attachment_data) {
4901                 EM_DEBUG_EXCEPTION("Invalid parameter");
4902                 err = EMAIL_ERROR_INVALID_PARAM;
4903                 goto FINISH_OFF;                
4904         }
4905
4906         p_mail_data = (email_mail_data_t *)em_malloc(sizeof(email_mail_data_t));
4907         if (p_mail_data == NULL) {
4908                 EM_DEBUG_EXCEPTION("em_malloc failed");
4909                 err = EMAIL_ERROR_OUT_OF_MEMORY;
4910                 goto FINISH_OFF;
4911         }
4912
4913         memset(&mail_cache_element, 0x00, sizeof(MESSAGECACHE));
4914         memset((void *)&temp_time_info, 0, sizeof(struct tm));
4915
4916         /* Create rand mail id of eml */
4917         gettimeofday(&tv, NULL);
4918         srand(tv.tv_usec);
4919         eml_mail_id = rand();
4920
4921         p_mail_data->mail_id = eml_mail_id;
4922         p_mail_data->account_id = EML_FOLDER;
4923
4924         if (mmsg->rfc822header->date)
4925                 mail_parse_date(&mail_cache_element, (unsigned char *)mmsg->rfc822header->date);
4926
4927         temp_time_info.tm_sec = mail_cache_element.seconds;
4928         temp_time_info.tm_min = mail_cache_element.minutes - mail_cache_element.zminutes;
4929         temp_time_info.tm_hour = mail_cache_element.hours - mail_cache_element.zhours;
4930
4931         if (mail_cache_element.hours - mail_cache_element.zhours < 0) {
4932                 temp_time_info.tm_mday = mail_cache_element.day - 1;
4933                 temp_time_info.tm_hour += 24;
4934         } else
4935                 temp_time_info.tm_mday = mail_cache_element.day;
4936
4937         temp_time_info.tm_mon = mail_cache_element.month - 1;
4938         temp_time_info.tm_year = mail_cache_element.year + 70;
4939
4940         p_mail_data->date_time                   = timegm(&temp_time_info);
4941         p_mail_data->full_address_return         = EM_SAFE_STRDUP(mmsg->rfc822header->return_path);
4942         p_mail_data->email_address_recipient     = EM_SAFE_STRDUP(mmsg->rfc822header->received);
4943         p_mail_data->full_address_from           = EM_SAFE_STRDUP(mmsg->rfc822header->from);
4944         p_mail_data->subject                     = EM_SAFE_STRDUP(mmsg->rfc822header->subject);
4945         p_mail_data->email_address_sender        = EM_SAFE_STRDUP(mmsg->rfc822header->sender);
4946         p_mail_data->full_address_to             = EM_SAFE_STRDUP(mmsg->rfc822header->to);
4947         p_mail_data->full_address_cc             = EM_SAFE_STRDUP(mmsg->rfc822header->cc);
4948         p_mail_data->full_address_bcc            = EM_SAFE_STRDUP(mmsg->rfc822header->bcc);
4949         p_mail_data->full_address_reply          = EM_SAFE_STRDUP(mmsg->rfc822header->reply_to);
4950         p_mail_data->body_download_status        = EMAIL_BODY_DOWNLOAD_STATUS_FULLY_DOWNLOADED;
4951
4952         EM_DEBUG_LOG("cnt_info->text.plain [%s], cnt_info->text.html [%s]", cnt_info->text.plain, cnt_info->text.html);
4953
4954         if (cnt_info->text.plain) {
4955                 EM_DEBUG_LOG("cnt_info->text.plain [%s]", cnt_info->text.plain);
4956                 if (!emstorage_create_dir(EML_FOLDER, eml_mail_id, 0, &err)) {
4957                         EM_DEBUG_EXCEPTION("emstorage_create_dir failed [%d]", err);
4958                         goto FINISH_OFF;
4959                 }
4960
4961                 if (!emstorage_get_save_name(EML_FOLDER, eml_mail_id, 0, cnt_info->text.plain_charset ? cnt_info->text.plain_charset : "UTF-8", buf, &err)) {
4962                         EM_DEBUG_EXCEPTION("emstorage_get_save_name failed [%d]", err);
4963                         goto FINISH_OFF;
4964                 }
4965
4966                 if (!emstorage_move_file(cnt_info->text.plain, buf, false, &err)) {
4967                         EM_DEBUG_EXCEPTION("emstorage_move_file failed [%d]", err);
4968                         goto FINISH_OFF;
4969                 }
4970
4971                 p_mail_data->file_path_plain = EM_SAFE_STRDUP(buf);
4972                 EM_DEBUG_LOG("mail_data->file_path_plain [%s]", p_mail_data->file_path_plain);  
4973         }
4974
4975         if (cnt_info->text.html)  {
4976                 if (!emstorage_create_dir(EML_FOLDER, eml_mail_id, 0, &err))  {
4977                         EM_DEBUG_EXCEPTION("emstorage_create_dir failed [%d]", err);
4978                         goto FINISH_OFF;
4979                 }
4980                 
4981                 if (cnt_info->text.plain_charset != NULL) {
4982                         memcpy(html_body, cnt_info->text.plain_charset, strlen(cnt_info->text.plain_charset));
4983                         strcat(html_body, HTML_EXTENSION_STRING);
4984                 }
4985                 else {
4986                         memcpy(html_body, "UTF-8.htm", strlen("UTF-8.htm"));
4987                 }
4988                 if (!emstorage_get_save_name(EML_FOLDER, eml_mail_id, 0, html_body, buf, &err))  {
4989                         EM_DEBUG_EXCEPTION("emstorage_get_save_name failed [%d]", err);
4990                         goto FINISH_OFF;
4991                 }
4992
4993                 if (!emstorage_move_file(cnt_info->text.html, buf, false, &err))  {
4994                         EM_DEBUG_EXCEPTION("emstorage_move_file failed [%d]", err);
4995                         goto FINISH_OFF;
4996                 }
4997                 p_mail_data->file_path_html = EM_SAFE_STRDUP(buf);
4998         }
4999
5000
5001         for (ai = cnt_info->file; ai; ai = ai->next, attachment_num++) {}
5002         EM_DEBUG_LOG("attachment_num : [%d]", attachment_num);
5003
5004         if (attachment_num > 0) { 
5005                 attachment = (email_attachment_data_t *)em_malloc(sizeof(email_attachment_data_t) * attachment_num);
5006                 if (attachment == NULL) {
5007                         EM_DEBUG_EXCEPTION("em_malloc failed");
5008                         err = EMAIL_ERROR_OUT_OF_MEMORY;
5009                         goto FINISH_OFF;
5010                 }
5011                 
5012                 for (ai = cnt_info->file; ai; ai = ai->next, i++) {
5013                         attachment[i].attachment_id          = i;
5014                         attachment[i].attachment_size        = ai->size;
5015                         attachment[i].attachment_name        = EM_SAFE_STRDUP(ai->name);
5016                         attachment[i].drm_status             = ai->drm;
5017                         attachment[i].save_status            = 0;
5018                         attachment[i].inline_content_status  = ai->type == 1;
5019                         attachment[i].attachment_mime_type   = ai->attachment_mime_type;
5020 #ifdef __ATTACHMENT_OPTI__
5021                         attachment[i].encoding               = ai->encoding;
5022                         attachment[i].section                = ai->section;
5023 #endif
5024                         EM_DEBUG_LOG("attachment[%d].attachment_id[%d]", i, attachment[i].attachment_id);
5025                         EM_DEBUG_LOG("attachment[%d].attachment_size[%d]", i, attachment[i].attachment_size);
5026                         EM_DEBUG_LOG("attachment[%d].attachment_name[%s]", i, attachment[i].attachment_name);
5027                         EM_DEBUG_LOG("attachment[%d].drm_status[%d]", i, attachment[i].drm_status);
5028                         EM_DEBUG_LOG("attachment[%d].inline_content_status[%d]", i, attachment[i].inline_content_status);
5029
5030                         if (ai->type == 1)
5031                                 local_inline_content_count ++;
5032                         local_attachment_count++;
5033
5034                         if (ai->save)  {
5035                                 attachment[i].save_status = 1;
5036                                 if (ai->type == 1)  {           /*  it is inline content */
5037                                         if (!emstorage_create_dir(EML_FOLDER, eml_mail_id, 0, &err))  {
5038                                                 EM_DEBUG_EXCEPTION("emstorage_create_dir failed [%d]", err);
5039                                                 goto FINISH_OFF;
5040                                         }
5041                                         if (!emstorage_get_save_name(EML_FOLDER, eml_mail_id, 0, attachment[i].attachment_name, buf, &err))  {
5042                                                 EM_DEBUG_EXCEPTION("emstorage_get_save_name failed [%d]", err);
5043                                                 goto FINISH_OFF;
5044                                         }
5045                                 }
5046                                 else  {
5047                                         if (!emstorage_create_dir(EML_FOLDER, eml_mail_id, i, &err)) {
5048                                                 EM_DEBUG_EXCEPTION("emstorage_create_dir failed [%d]", err);
5049                                                 goto FINISH_OFF;
5050                                         }
5051
5052                                         if (!emstorage_get_save_name(EML_FOLDER, eml_mail_id, i, attachment[i].attachment_name, buf, &err))  {
5053                                                 EM_DEBUG_EXCEPTION("emstorage_get_save_name failed [%d]", err);
5054                                                 goto FINISH_OFF;
5055                                         }
5056                                 }
5057
5058                                 if (!emstorage_move_file(ai->save, buf, false, &err))  {
5059                                         EM_DEBUG_EXCEPTION("emstorage_move_file failed [%d]", err);
5060
5061                                         /*  delete all created files. */
5062                                         if (!emstorage_get_save_name(EML_FOLDER, eml_mail_id, 0, NULL, buf, NULL)) {
5063                                                 EM_DEBUG_EXCEPTION("emstorage_get_save_name failed...");
5064                                                 /* goto FINISH_OFF; */
5065                                         }
5066
5067                                         if (!emstorage_delete_dir(buf, NULL)) {
5068                                                 EM_DEBUG_EXCEPTION("emstorage_delete_dir failed...");
5069                                                 /* goto FINISH_OFF; */
5070                                         }
5071
5072
5073                                         goto FINISH_OFF;
5074                                 }
5075
5076                                 attachment[i].attachment_path = EM_SAFE_STRDUP(buf);
5077
5078                         }
5079
5080                         EM_DEBUG_LOG("attachment[%d].attachment_path[%s]", i, attachment[i].attachment_path);
5081                 }
5082         }
5083         EM_DEBUG_LOG("Check #1");
5084
5085         p_mail_data->attachment_count = local_attachment_count;
5086         p_mail_data->inline_content_count = local_inline_content_count;
5087
5088         eml_data_count += 1;
5089         ret = true;
5090
5091 FINISH_OFF:
5092
5093         if (ret) {
5094                 if (output_mail_data) 
5095                         *output_mail_data = p_mail_data;
5096
5097                 if (output_attachment_data)
5098                         *output_attachment_data = attachment;
5099
5100                 if (output_attachment_count)
5101                         *output_attachment_count = local_attachment_count;
5102         } else {
5103                 if (p_mail_data)
5104                         emcore_free_mail_data(p_mail_data);
5105
5106                 if (attachment)
5107                         emcore_free_attachment_data(&attachment, attachment_num, NULL);
5108         }
5109
5110         if (err_code)
5111                 *err_code = err;
5112
5113         return ret;
5114 }
5115
5116 INTERNAL_FUNC int emcore_load_eml_file_to_mail(char *eml_file_path, email_mail_data_t **output_mail_data, email_attachment_data_t **output_attachment_data, int *output_attachment_count, int *err_code)
5117 {
5118         EM_DEBUG_FUNC_BEGIN("eml_file_path : [%s], output_mail_data : [%p]", eml_file_path, output_mail_data);
5119
5120         int err = EMAIL_ERROR_NONE;
5121         int ret = false;
5122         int is_file = 1;
5123         FILE *eml_fp = NULL;
5124         struct _m_content_info *cnt_info = NULL;
5125         struct _m_mesg *mmsg = NULL;
5126
5127
5128         if (!eml_file_path || !output_mail_data || !output_attachment_data || !output_attachment_count) {
5129                 EM_DEBUG_EXCEPTION("Invalid paramter");
5130                 err = EMAIL_ERROR_INVALID_PARAM;
5131                 goto FINISH_OFF;
5132         }
5133
5134         cnt_info = (struct _m_content_info *)em_malloc(sizeof(struct _m_content_info));
5135         if (cnt_info == NULL) {
5136                 EM_DEBUG_EXCEPTION("em_malloc failed...");
5137                 err = EMAIL_ERROR_OUT_OF_MEMORY;
5138                 goto FINISH_OFF;
5139         }
5140
5141         cnt_info->grab_type = GRAB_TYPE_TEXT | GRAB_TYPE_ATTACHMENT;
5142
5143         mmsg = (struct _m_mesg *)em_malloc(sizeof(struct _m_mesg));
5144         if (mmsg == NULL) {
5145                 EM_DEBUG_EXCEPTION("em_malloc failed");
5146                 err = EMAIL_ERROR_OUT_OF_MEMORY;        
5147                 goto FINISH_OFF;
5148         }
5149
5150         eml_fp = fopen(eml_file_path, "r");
5151         if (eml_fp == NULL) {
5152                 EM_DEBUG_EXCEPTION("file open failed");
5153                 err = EMAIL_ERROR_ON_PARSING;
5154                 goto FINISH_OFF;
5155         }
5156
5157         if (!emcore_mime_parse_header(eml_fp, is_file, &mmsg->rfc822header, &mmsg->header, &err)) {
5158                 EM_DEBUG_EXCEPTION("emcore_mime_parse_header failed : [%d]", err);
5159                 goto FINISH_OFF;
5160         }
5161
5162         if (emcore_mime_parse_body(eml_fp, is_file, mmsg, cnt_info, NULL, &err) < 0) {
5163                 EM_DEBUG_EXCEPTION("emcore_mime_parse_body failed : [%d]", err);
5164                 goto FINISH_OFF;
5165         }
5166
5167         if (!emcore_make_mail_data_from_mime_data(mmsg, cnt_info, output_mail_data, output_attachment_data, output_attachment_count, &err)) {
5168                 EM_DEBUG_EXCEPTION("emcore_make_mail_tbl_data_from_mime failed : [%d]", err);
5169                 goto FINISH_OFF;
5170
5171         }
5172
5173         ret = true;
5174         
5175 FINISH_OFF:
5176
5177         if (eml_fp)
5178                 fclose(eml_fp);
5179         
5180         if (mmsg)
5181                 emcore_mime_free_mime(mmsg);
5182
5183         if (cnt_info)
5184                 emcore_free_content_info(cnt_info);
5185
5186         if (err_code)
5187                 *err_code = err;
5188
5189         EM_DEBUG_FUNC_END("err : %d", err);
5190         return ret;
5191 }
5192
5193 INTERNAL_FUNC int emcore_delete_eml_data(email_mail_data_t *input_mail_data, int *err_code)
5194 {
5195         EM_DEBUG_FUNC_BEGIN("input_mail_data : [%p]", input_mail_data);
5196         int err = EMAIL_ERROR_NONE;
5197         int ret = false;
5198         char buf[512];
5199
5200         if (!input_mail_data) {
5201                 EM_DEBUG_EXCEPTION("Invliad parameter");
5202                 err = EMAIL_ERROR_INVALID_PARAM;
5203                 goto FINISH_OFF;
5204         }
5205
5206         if ((input_mail_data->account_id != EML_FOLDER) && (!input_mail_data->mail_id)) {
5207                 EM_DEBUG_EXCEPTION("Invliad parameter: account_id[%d], mail_id[%d]", input_mail_data->account_id, input_mail_data->mail_id);
5208                 err = EMAIL_ERROR_INVALID_PARAM;
5209                 goto FINISH_OFF;
5210         }
5211
5212         eml_data_count = eml_data_count - 1;
5213
5214         if (eml_data_count == 0) {
5215                 SNPRINTF(buf, sizeof(buf), "%s%s%d", MAILHOME, DIR_SEPERATOR, input_mail_data->account_id);
5216         } else {
5217                 SNPRINTF(buf, sizeof(buf), "%s%s%d%s%d", MAILHOME, DIR_SEPERATOR, input_mail_data->account_id, DIR_SEPERATOR, input_mail_data->mail_id);
5218         }
5219
5220         EM_DEBUG_LOG("Directory : [%s]", buf);
5221
5222         if (!emstorage_delete_dir(buf, &err)) {
5223                 EM_DEBUG_EXCEPTION("emstorage_delete_dir failed");
5224                 goto FINISH_OFF;
5225         }
5226
5227         ret = true;
5228
5229 FINISH_OFF:
5230         
5231         if (err_code)
5232                 *err_code = err;
5233         
5234         return ret;
5235 }
5236
5237 INTERNAL_FUNC int emcore_get_mime_entity(char *mime_path, char **output_path, int *err_code)
5238 {
5239         EM_DEBUG_FUNC_BEGIN("mime_path : [%s], output_path : [%p]", mime_path, *output_path);
5240         int ret = false;
5241         int err = EMAIL_ERROR_NONE;
5242         int is_file = 1;
5243         int search = 0;
5244         char buf[MIME_LINE_LEN] = {0x00, };
5245         char *mime_entity_path = NULL;
5246         char *content_type = NULL;
5247         char boundary[BOUNDARY_LEN] = {0x00,};
5248         char *boundary_string = NULL;
5249         FILE *fp_read = NULL;
5250         FILE *fp_write = NULL;
5251         struct _m_mesg *mmsg = NULL;
5252
5253         if (!mime_path) {
5254                 EM_DEBUG_EXCEPTION("Invalid parameter");
5255                 err = EMAIL_ERROR_INVALID_PARAM;
5256                 goto FINISH_OFF;
5257         }
5258
5259         /* Get the header info */
5260         mmsg = (struct _m_mesg *)em_malloc(sizeof(struct _m_mesg));
5261         if (mmsg == NULL) {
5262                 EM_DEBUG_EXCEPTION("em_malloc failed");
5263                 err = EMAIL_ERROR_OUT_OF_MEMORY;
5264                 goto FINISH_OFF;
5265         }
5266
5267         fp_read = fopen(mime_path, "r");
5268         if (fp_read == NULL) {
5269                 EM_DEBUG_EXCEPTION("File open(read) is failed : filename [%s]", mime_path);
5270                 err = EMAIL_ERROR_SYSTEM_FAILURE;
5271                 goto FINISH_OFF;
5272         }
5273
5274         if (!emcore_mime_parse_header(fp_read, is_file, &mmsg->rfc822header, &mmsg->header, &err)) {
5275                 EM_DEBUG_EXCEPTION("emcore_mime_parse_header failed : [%d]", err);
5276                 goto FINISH_OFF;
5277         }
5278
5279         /* Parsing the mime header */
5280         content_type = emcore_mime_get_header_value(mmsg->header->part_header, CONTENT_TYPE, NULL);
5281         EM_DEBUG_LOG("Content_type : [%s]", content_type);
5282         if (strcasestr(content_type, "signed") == NULL) {
5283                 EM_DEBUG_EXCEPTION("Invalid parameter : No signed mail");
5284                 err = EMAIL_ERROR_INVALID_PARAM;
5285                 goto FINISH_OFF;
5286         }
5287
5288         /* Create mime_entity file */
5289         if (!emcore_get_temp_file_name(&mime_entity_path, &err)) {
5290                 EM_DEBUG_EXCEPTION("emcore_get_temp_file_name failed[%d]", err);
5291                 goto FINISH_OFF;
5292         }
5293         EM_DEBUG_LOG("mime_entity_path = %s", mime_entity_path);        
5294
5295         fp_write = fopen(mime_entity_path, "w");
5296         if (fp_write == NULL) {
5297                 EM_DEBUG_EXCEPTION("File open(write) is failed : filename [%s]", mime_entity_path);
5298                 err = EMAIL_ERROR_SYSTEM_FAILURE;
5299                 goto FINISH_OFF;
5300         }
5301
5302         boundary_string = emcore_mime_get_header_value(mmsg->header->part_header, CONTENT_BOUNDARY, NULL);
5303         SNPRINTF(boundary, BOUNDARY_LEN, "--%s%s", boundary_string, CRLF_STRING);
5304
5305         while (TRUE) {
5306                 if (!emcore_get_line_from_file((void *)fp_read, buf, MIME_LINE_LEN, &err)) {
5307                         EM_DEBUG_EXCEPTION("emcore_mime_get_line_from_file failed [%d]", err);
5308                         break;
5309                 }
5310                 
5311                 if (!strcmp(buf, boundary)) {
5312                         search++;
5313                 } else if (search == 1) {
5314                         EM_DEBUG_LOG("Buf : [%s]", buf);
5315                         fprintf(fp_write, "%s", buf);   
5316                 } else if (search == 2) {
5317                         break;
5318                 }
5319         }
5320
5321         ret = true;
5322
5323 FINISH_OFF:
5324
5325         if (fp_read)
5326                 fclose(fp_read);
5327         
5328         if (fp_write)
5329                 fclose(fp_write);
5330         
5331         if (mmsg)
5332                 emcore_mime_free_mime(mmsg);
5333
5334         if (output_path)
5335                 *output_path = mime_entity_path;
5336
5337         if (err_code)
5338                 *err_code = err;
5339
5340         EM_DEBUG_FUNC_END();
5341         return ret;
5342 }