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