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