4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Kyuho Jo <kyuho.jo@samsung.com>, Sunghyun Kwon <sh0701.kwon@samsung.com>
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
12 * http://www.apache.org/licenses/LICENSE-2.0
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.
24 /* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ***
25 *File : email-core-mime.c
26 *Desc : MIME Operation
31 * 2011.04.14 : created
32 ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ***/
42 #include "email-internal-types.h"
44 #include "email-utilities.h"
45 #include "email-core-global.h"
46 #include "email-core-utils.h"
47 #include "email-core-mail.h"
48 #include "email-core-mime.h"
49 #include "email-storage.h"
50 #include "email-core-event.h"
51 #include "email-core-account.h"
52 #include "email-debug-log.h"
54 #define MIME_MESG_IS_SOCKET
56 #define MIME_LINE_LEN 1024
57 #define BOUNDARY_LEN 256
63 #define TYPE_APPLICATION 5
64 #define TYPE_MULTIPART 6
65 #define TYPE_MESSAGE 7
66 #define TYPE_UNKNOWN 8
68 #define TEXT_STR "TEXT"
69 #define IMAGE_STR "IMAGE"
70 #define AUDIO_STR "AUDIO"
71 #define VIDEO_STR "VIDEO"
72 #define APPLICATION_STR "APPLICATION"
73 #define MULTIPART_STR "MULTIPART"
74 #define MESSAGE_STR "MESSAGE"
76 #define CONTENT_TYPE 1
77 #define CONTENT_SUBTYPE 2
78 #define CONTENT_ENCODING 3
79 #define CONTENT_CHARSET 4
80 #define CONTENT_DISPOSITION 5
81 #define CONTENT_NAME 6
82 #define CONTENT_FILENAME 7
83 #define CONTENT_BOUNDARY 8
84 #define CONTENT_REPORT_TYPE 9
86 #define CONTENT_LOCATION 11
88 #define GRAB_TYPE_TEXT 1 /* retrieve text and attachment name */
89 #define GRAB_TYPE_ATTACHMENT 2 /* retrieve only attachmen */
91 #define SAVE_TYPE_SIZE 1 /* only get content siz */
92 #define SAVE_TYPE_BUFFER 2 /* save content to buffe */
93 #define SAVE_TYPE_FILE 3 /* save content to temporary fil */
95 #define EML_FOLDER 20 /* save eml content to temporary folder */
98 MIME Structure Example
100 (part 0) multipart/mixed
101 (part 1) multipart/alternative
102 (part 1.1) text/plain <- text message
103 (part 1.2) text/html <- html message
104 (part 2) text/plain <- text attachment
107 (part 0) multipart/related
108 (part 1) multipart/alternative
109 (part 1.1) text/plain <- text message
110 (part 1.2) text/html <- html message
111 (part 2) image/png <- inline image
112 (part 2) image/png <- inline image
115 (part 0) multipart/mixed
116 (part 1.1) multipart/related
117 (part 2.1) multipart/alternative
118 (part 3.1) text/plain(body) <- text message
119 (part 3.2) text/html(body) <- html message
120 (part 2.2) image/png(related) <- inline image
121 (part 1.2) image/png(attachment) <- image attachment
124 /* Text and Attachment Holde */
125 /* struct _m_content_info */
126 /* int grab_type; */ /* 1 : text and attachment list */
128 /* int file_no; */ /* attachment sequence to be downloaded (min : 1 */
129 /* struct text_data */
130 /* char *plain; */ /* body plain tex */
131 /* char *plain_charset */ /* charset of plai */
132 /* char *html; */ /* body html tex */
135 /* struct attachment_info */
136 /* int type; */ /* 1 : inline 2 : attachmen */
137 /* char *name; */ /* attachment filenam */
138 /* int size; */ /* attachment siz */
139 /* char *save; */ /* content saving filenam */
140 /* struct attachment_info *next */
144 /* --------------------- MIME Structure --------------------------------- */
145 /* MIME Header Parameter (Content-Type, Content-Disposition, ... */
147 char *name; /* parameter name */
148 char *value; /* parameter valu */
149 struct _parameter *next; /* next paramete */
152 /* Content-Dispositio */
153 struct _disposition {
154 char *type; /* "inline" "attachment */
155 struct _parameter *parameter; /* "filename", .. */
159 struct _rfc822header {
160 char *return_path; /* error return pat */
176 /* MIME Part Header */
177 struct _m_part_header {
178 char *type; /* text, image, audio, video, application, multipart, message */
179 char *subtype; /* plain, html, jpeg, .. */
180 char *encoding; /* encoding typ */
181 struct _parameter *parameter; /* content-type parameter : "boundary" "charset" .. */
182 char *desc; /* descriptio */
183 char *disp_type; /* disposition type : "inline" "attachment", */
184 struct _parameter *disp_parameter; /* disposition parameter : "filename", .. */
185 char *content_id; /* content id : it is inline */
186 char *content_location; /* content location : "inline" location */
189 /* MIME Message Header */
190 struct _m_mesg_header {
191 char *version; /* MIME Versio */
192 struct _m_part_header *part_header; /* MIME Part Heade */
195 /* MIME Multipart Body linked list */
196 typedef struct _m_body _m_body_t;
198 _m_body_t *body; /* part bod */
199 struct _m_part *next; /* the next found par */
202 /* MIME Multipart Body */
204 struct _m_part_header *part_header; /* MIME Part Heade */
205 struct _m_part nested; /* nested structure if contain multipar */
206 char *text; /* text if not contain multipar */
207 int size; /* text size if not contain multipar */
213 struct _rfc822header *rfc822header; /* RFC822 Heade */
214 struct _m_mesg_header *header; /* MIME Message Heade */
215 struct _m_part nested; /* nested structure if contain multipar */
216 char *text; /* text if not contain multipar */
217 int size; /* text size if not contain multipar */
219 /* ---------------------------------------------------------------------- */
220 /* Global variable */
221 static bool next_decode_string = false;
222 static int eml_data_count = 0;
224 /* ---------------------------------------------------------------------- */
225 /* External variable */
226 extern int _pop3_receiving_mail_id;
227 extern int _pop3_received_body_size;
228 extern int _pop3_last_notified_body_size;
229 extern int _pop3_total_body_size;
231 extern int _imap4_received_body_size;
232 extern int _imap4_last_notified_body_size;
233 extern int _imap4_total_body_size;
234 extern int _imap4_download_noti_interval_value;
236 extern int multi_part_body_size;
237 extern bool only_body_download;
239 extern BODY **g_inline_list;
240 extern int g_inline_count;
242 /* ---------------------------------------------------------------------- */
243 /* Function Declaration */
245 /* parsing the first header (RFC822 Header and Message Header and Etc... */
246 static int emcore_mime_parse_header(void *stream, int is_file, struct _rfc822header **rfcheader, struct _m_mesg_header **header, int *err_code);
248 /* parsing the first bod */
249 static int emcore_mime_parse_body(void *stream, int is_file, struct _m_mesg *mmsg, struct _m_content_info *cnt_info, void *callback, int *err_code);
251 /* parsing the message part header (CONTENT-... header */
252 static int emcore_mime_parse_part_header(void *stream, int is_file, struct _m_part_header **header, int *err_code);
254 /* parsing the message part by boundar */
255 static int emcore_mime_parse_part(void *stream, int is_file, struct _m_part_header *parent_header, struct _m_part *nested, struct _m_content_info *cnt_info, int *end_of_parsing, int *err_code);
257 /* set RFC822 Header valu */
258 static int emcore_mime_set_rfc822_header_value(struct _rfc822header **rfc822header, char *name, char *value, int *err_code);
260 /* set Message Part Header (Content-... Header */
261 static int emcore_mime_set_part_header_value(struct _m_part_header **header, char *name, char *value, int *err_code);
263 static int emcore_mime_get_param_from_str(char *str, struct _parameter **param, int *err_code);
265 static int emcore_mime_add_param_to_list(struct _parameter **param_list, struct _parameter *param, int *err_code);
267 char *emcore_mime_get_header_value(struct _m_part_header *header, int type, int *err_code);
269 void emcore_mime_free_param(struct _parameter *param);
270 void emcore_mime_free_part_header(struct _m_part_header *header);
271 void emcore_mime_free_message_header(struct _m_mesg_header *header);
272 void emcore_mime_free_rfc822_header(struct _rfc822header *rfc822header);
273 void emcore_mime_free_part(struct _m_part *part);
274 void emcore_mime_free_part_body(struct _m_body *body);
275 void emcore_mime_free_mime(struct _m_mesg *mmsg);
276 char *emcore_mime_get_line_from_sock(void *stream, char *buf, int size, int *err_code);
277 char *emcore_mime_get_save_file_name(int *err_code);
279 /* get content data and save buffer or fil */
280 /* mode - 1 : get the only siz */
281 /* 2 : save content to buffer (holder is buffer */
282 /* 3 : save content to file (holder is file name */
283 static int emcore_mime_get_content_data(void *stream,
287 char *content_encoding,
294 /* skip content data to boundary_str or end of fil */
295 int emcore_mime_skip_content_data(void *stream,
303 static int emcore_get_file_pointer(BODY *body, bool input_check_duplicated_file_name, char *buf, struct _m_content_info *cnt_info , int *err);
304 static PARTLIST *emcore_get_body_full(MAILSTREAM *stream, int msg_uid, BODY *body, struct _m_content_info *cnt_info, int *err_code, PARTLIST *section_list);
305 static int emcore_get_body_part_imap_full(MAILSTREAM *stream, int msg_uid, int account_id, int mail_id, PARTLIST *section_list, struct _m_content_info *cnt_info, int *err_code, int event_handle);
306 static PARTLIST *emcore_add_node(PARTLIST *section_list, BODY *body);
307 static void emcore_free_section_list(PARTLIST *section_list);
308 static int emcore_get_section_body_size(char *response, char *section, int *body_size);
309 static void parse_file_path_to_filename(char *src_string, char **out_string);
310 extern long pop3_reply (MAILSTREAM *stream);
311 /* ------------------------------------------------------------------------------------------------- */
314 /* Fix for issue junk characters in mail body */
315 char *em_split_file_path(char *str)
317 EM_DEBUG_FUNC_BEGIN("str [%s]", str);
319 EM_IF_NULL_RETURN_VALUE(str, NULL);
324 char *temp_str = NULL;
325 char *content_id = NULL;
327 char *temp_cid_data = NULL;
328 char *temp_cid = NULL;
329 temp_str = EM_SAFE_STRDUP(str);
330 buf_length = strlen(str) + 1024;
331 buf = em_malloc(buf_length);
332 content_id = temp_str;
333 temp_cid = strstr(temp_str, "\"");
335 if (temp_cid == NULL) {
336 EM_DEBUG_EXCEPTION(">>>> File Path Doesnot contain end line for CID ");
337 next_decode_string = true;
341 temp_cid_data = em_malloc((temp_cid-temp_str)+1);
342 memcpy(temp_cid_data, temp_str, (temp_cid-temp_str));
344 if (!strstr(temp_cid_data, delims)) {
345 EM_DEBUG_EXCEPTION(">>>> File Path Doesnot contain @ ");
346 next_decode_string = true;
348 EM_SAFE_FREE(temp_cid_data);
352 result = strstr(temp_str, delims);
353 if (result != NULL) {
354 next_decode_string = false;
357 EM_DEBUG_LOG("content_id is [ %s ]", content_id);
359 if (strcasestr(content_id, ".bmp") || strcasestr(content_id, ".jpeg") || strcasestr(content_id, ".png") ||
360 strcasestr(content_id, ".jpg") || strcasestr(content_id, ".gif"))
361 snprintf(buf+strlen(buf), buf_length - strlen(buf), "%s\"", content_id);
363 snprintf(buf+strlen(buf), buf_length - strlen(buf), "%s%s", content_id, ".jpeg\"");
366 EM_DEBUG_EXCEPTION(">>>> File Path Doesnot contain end line for CID ");
367 next_decode_string = true;
369 EM_SAFE_FREE(temp_cid_data);
372 result = strstr(result, "\"");
373 if (result != NULL) {
375 snprintf(buf+strlen(buf), buf_length - strlen(buf), "%s", result);
378 EM_SAFE_FREE(temp_str);
379 EM_SAFE_FREE(temp_cid_data);
384 static char *em_replace_string_with_split_file_path(char *source_string, char *old_string, char *new_string)
386 EM_DEBUG_FUNC_BEGIN();
388 char *split_str = NULL;
393 EM_IF_NULL_RETURN_VALUE(source_string, NULL);
394 EM_IF_NULL_RETURN_VALUE(old_string, NULL);
395 EM_IF_NULL_RETURN_VALUE(new_string, NULL);
397 EM_DEBUG_LOG("source_string [%s] ", source_string);
398 EM_DEBUG_LOG("old_string [%s] ", old_string);
399 EM_DEBUG_LOG("new_string [%s] ", new_string);
401 p = strstr(source_string, old_string);
404 EM_DEBUG_EXCEPTION("Orig not found in source_string");
408 buf_len = strlen(source_string) + 1024;
409 buffer = (char *)em_malloc(buf_len);
411 if(p - source_string < strlen(source_string) + 1024 + 1) {
412 strncpy(buffer, source_string, p - source_string);
414 EM_DEBUG_LOG("BUFFER [%s]", buffer);
416 split_str = em_split_file_path(p);
419 EM_DEBUG_EXCEPTION(">> SPLIT STRING IS NULL ");
423 q = strstr(split_str, old_string);
425 EM_DEBUG_LOG("Split string [%s]", split_str);
426 snprintf(buffer + strlen(buffer), buf_len - strlen(buffer), "%s%s", new_string, q+strlen(old_string));
427 EM_DEBUG_LOG("BUFFER 1 [%s]", buffer);
428 EM_SAFE_FREE(split_str);
429 EM_DEBUG_FUNC_END("Suceeded");
434 EM_DEBUG_EXCEPTION("Buffer is too small.");
435 EM_SAFE_FREE(buffer);
440 EM_SAFE_FREE(split_str);
441 EM_SAFE_FREE(buffer);
443 EM_DEBUG_FUNC_END("Failed");
449 int emcore_mime_flush_receiving_buffer(void *stream, int is_file, char *boundary_string, char *boundary_end_string, int *end_of_parsing, int *err_code)
451 EM_DEBUG_FUNC_BEGIN("stream[%p], is_file[%d], boundary_string[%s], boundary_end_string[%s], end_of_parsing[%p], err_code[%p]", stream, is_file, boundary_string, boundary_end_string, end_of_parsing, err_code);
452 char buf[MIME_LINE_LEN] = {0, };
453 int local_end_of_parsing = 0;
457 *err_code = EMAIL_ERROR_INVALID_PARAM;
458 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
463 if (!emcore_check_thread_status()) {
464 if (err_code != NULL)
465 *err_code = EMAIL_ERROR_CANCELLED;
466 EM_DEBUG_FUNC_END("EMAIL_ERROR_CANCELLED");
470 if ((is_file == 0 && !emcore_mime_get_line_from_sock(stream, buf, MIME_LINE_LEN, err_code)) ||
471 (is_file == 1 && !emcore_get_line_from_file(stream, buf, MIME_LINE_LEN, err_code))) {
472 EM_DEBUG_EXCEPTION("emcore_mime_get_line_from_sock failed");
473 local_end_of_parsing = 0;
477 if (boundary_string && boundary_end_string) {
478 if (!strcmp(buf, boundary_string)) {
479 EM_DEBUG_LOG("found boundary");
480 local_end_of_parsing = 0;
483 else if (!strcmp(buf, boundary_end_string)) {
484 EM_DEBUG_LOG("found boundary_end");
485 local_end_of_parsing = 1;
492 *end_of_parsing = local_end_of_parsing;
498 int emcore_parse_mime(void *stream, int is_file, struct _m_content_info *cnt_info, int *err_code)
500 EM_DEBUG_FUNC_BEGIN("stream[%p], is_file[%d], cnt_info[%p], err_code[%p]", stream, is_file, cnt_info, err_code);
502 struct _m_mesg *mmsg = em_malloc(sizeof(struct _m_mesg));
504 if (!mmsg) return false;
506 memset(mmsg, 0x00, sizeof(struct _m_mesg));
508 /* 1. parse the first found heade */
509 EM_DEBUG_LOG(">>>>>> 1. parse the first found header");
510 if (!emcore_mime_parse_header(stream, is_file, &mmsg->rfc822header, &mmsg->header, err_code)) {
515 if (!emcore_check_thread_status()) {
516 if (err_code != NULL)
517 *err_code = EMAIL_ERROR_CANCELLED;
522 EM_DEBUG_LOG(">>>>>> 2. parse body");
523 if (mmsg && mmsg->header && mmsg->header->part_header && mmsg->header->part_header->parameter) {
524 EM_DEBUG_LOG("name[%s]", mmsg->header->part_header->parameter->name);
525 EM_DEBUG_LOG("value[%s]", mmsg->header->part_header->parameter->value);
526 EM_DEBUG_LOG("next : %p", mmsg->header->part_header->parameter->next);
529 if (emcore_mime_parse_body(stream, is_file, mmsg, cnt_info, NULL, err_code)<0) {
535 EM_DEBUG_LOG(">>>>>> 3. free memory");
536 if (mmsg && mmsg->header && mmsg->header->part_header && mmsg->header->part_header->parameter) {
537 EM_DEBUG_LOG("name[%s]", mmsg->header->part_header->parameter->name);
538 EM_DEBUG_LOG("value[%s]", mmsg->header->part_header->parameter->value);
539 EM_DEBUG_LOG("next : %p", mmsg->header->part_header->parameter->next);
541 emcore_mime_free_mime(mmsg);
546 int emcore_mime_parse_header(void *stream, int is_file, struct _rfc822header **rfc822header, struct _m_mesg_header **header, int *err_code)
548 EM_DEBUG_FUNC_BEGIN("stream[%p], is_file[%d], rfc822header[%p], header[%p], err_code[%p]", stream, is_file, rfc822header, header, err_code);
550 struct _m_mesg_header *tmp_header = NULL;
551 struct _rfc822header *tmp_rfc822header = NULL;
552 char buf[MIME_LINE_LEN] = {0, };
558 if (!emcore_check_thread_status()) {
559 if (err_code != NULL)
560 *err_code = EMAIL_ERROR_CANCELLED;
565 if ((is_file == 0 && !emcore_mime_get_line_from_sock(stream, buf, MIME_LINE_LEN, err_code)) ||
566 (is_file == 1 && !emcore_get_line_from_file(stream, buf, MIME_LINE_LEN, err_code))) {
570 if (!(tmp_header = em_malloc(sizeof(struct _m_mesg_header)))) {
571 EM_DEBUG_EXCEPTION("malloc failed...");
572 if (err_code != NULL)
573 *err_code = EMAIL_ERROR_OUT_OF_MEMORY;
577 if (!emcore_check_thread_status()) {
578 if (err_code != NULL)
579 *err_code = EMAIL_ERROR_CANCELLED;
584 EM_DEBUG_LOG("buf[%s]", buf);
586 if (!strncmp(buf, CRLF_STRING, 2))
589 is_longheader = (buf[0] == ' ' || buf[0] == '\t') ? TRUE : FALSE;
592 if (!is_longheader) { /* Normal header (format : "Name : Value" or "Name : Value; Parameters" */
597 /* EM_DEBUG_FUNC_BEGIN() */
598 if ((pTemp = strtok(buf, ":")) == NULL)
601 name = EM_SAFE_STRDUP(pTemp);
603 value = strtok(NULL, CRLF_STRING);
605 /* --> 2007-05-16, cy */
610 em_upper_string(name);
612 else { /* Long header */
613 value = strtok(buf, CRLF_STRING);
617 /* --> 2007-05-08 by cy */
621 EM_DEBUG_LOG("> name[%s]", name);
622 EM_DEBUG_LOG("> value[%s]", value);
624 /* MIME Part Heade */
625 if (memcmp(name, "CONTENT-", 8) == 0 && value) {
627 emcore_mime_set_part_header_value(&tmp_header->part_header, name, value, err_code);
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);
635 /* MIME Version Heade */
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) */
645 /* in socket stream case, ignored because we need only contents information */
647 emcore_mime_set_rfc822_header_value(&tmp_rfc822header, name, value, err_code);
650 if (!emcore_check_thread_status()) {
651 if (err_code != NULL)
652 *err_code = EMAIL_ERROR_CANCELLED;
655 if ((is_file == 0 && !emcore_mime_get_line_from_sock(stream, buf, MIME_LINE_LEN, err_code)) ||
656 (is_file == 1 && !emcore_get_line_from_file(stream, buf, MIME_LINE_LEN, err_code))) {
658 if (tmp_rfc822header)
659 emcore_mime_free_rfc822_header(tmp_rfc822header);
663 emcore_mime_free_part_header(tmp_header->part_header);
665 EM_SAFE_FREE(tmp_header->version);
666 EM_SAFE_FREE(tmp_header);
672 *header = tmp_header;
673 *rfc822header = tmp_rfc822header;
680 int emcore_mime_parse_part_header(void *stream, int is_file, struct _m_part_header **header, int *err_code)
682 EM_DEBUG_FUNC_BEGIN("stream[%p], is_file[%d], header[%p], err_code[%p]", stream, is_file, header, err_code);
684 struct _m_part_header *tmp_header = NULL;
685 char buf[MIME_LINE_LEN] = {0x00};
689 int is_longheader = false;
691 if (!emcore_check_thread_status()) {
692 if (err_code != NULL)
693 *err_code = EMAIL_ERROR_CANCELLED;
697 if ((is_file == 0 && !emcore_mime_get_line_from_sock(stream, buf, MIME_LINE_LEN, err_code)) ||
698 (is_file == 1 && !emcore_get_line_from_file(stream, buf, MIME_LINE_LEN, err_code)))
701 tmp_header = em_malloc(sizeof(struct _m_part_header));
704 EM_DEBUG_EXCEPTION("em_malloc failed");
708 memset(tmp_header, 0, sizeof(struct _m_part_header));
711 if (!strncmp(buf, CRLF_STRING, strlen(CRLF_STRING))) break;
713 is_longheader = (buf[0] == ' ' || buf[0] == TAB);
715 if (!is_longheader) { /* Normal header (format : "Name : Value" or "Name : Value; Parameters" */
717 p = strtok(buf , ":");
720 name = EM_SAFE_STRDUP(p);
721 value = strtok(NULL, CRLF_STRING);
722 em_upper_string(name);
725 else /* Long header */
726 value = strtok(buf, CRLF_STRING);
731 emcore_mime_set_part_header_value(&tmp_header, name, value, err_code);
733 if (!emcore_check_thread_status()) {
734 if (err_code != NULL)
735 *err_code = EMAIL_ERROR_CANCELLED;
739 if ((is_file == 0 && !emcore_mime_get_line_from_sock(stream, buf, MIME_LINE_LEN, err_code)) ||
740 (is_file == 1 && !emcore_get_line_from_file(stream, buf, MIME_LINE_LEN, err_code))) {
742 EM_SAFE_FREE(tmp_header);
748 *header = tmp_header;
756 int emcore_mime_parse_body(void *stream, int is_file, struct _m_mesg *mmsg, struct _m_content_info *cnt_info, void *callback, int *err_code)
758 EM_DEBUG_FUNC_BEGIN("stream[%p], is_file[%d], mmsg[%p], cnt_info[%p], callback[%p], err_code[%p]", stream, is_file, mmsg, cnt_info, callback, err_code);
760 char *content_type = NULL, *content_encoding = NULL, *holder = NULL, *attachment_name, *t = NULL;
761 int type = 0, end_of_parsing = 0, size, local_err_code = EMAIL_ERROR_NONE;
763 if (!emcore_check_thread_status()) {
764 if (err_code != NULL)
765 *err_code = EMAIL_ERROR_CANCELLED;
770 content_type = emcore_mime_get_header_value(mmsg->header->part_header, CONTENT_TYPE, err_code);
772 content_type = "TEXT/PLAIN";
775 content_encoding = emcore_mime_get_header_value(mmsg->header->part_header, CONTENT_ENCODING, err_code);
776 if (!content_encoding)
777 content_encoding = "7BIT";
779 if (strstr(content_type, TEXT_STR)) type = TYPE_TEXT;
780 else if (strstr(content_type, IMAGE_STR)) type = TYPE_IMAGE;
781 else if (strstr(content_type, AUDIO_STR)) type = TYPE_AUDIO;
782 else if (strstr(content_type, VIDEO_STR)) type = TYPE_VIDEO;
783 else if (strstr(content_type, APPLICATION_STR)) type = TYPE_APPLICATION;
784 else if (strstr(content_type, MULTIPART_STR)) type = TYPE_MULTIPART;
785 else if (strstr(content_type, MESSAGE_STR)) type = TYPE_MESSAGE;
786 else type = TYPE_UNKNOWN;
790 if (mmsg->header && !emcore_mime_get_header_value(mmsg->header->part_header, CONTENT_BOUNDARY, err_code)) {
791 EM_DEBUG_FUNC_END("false");
795 if (mmsg->header && !emcore_mime_parse_part(stream, is_file, mmsg->header->part_header, &mmsg->nested, cnt_info, &end_of_parsing, &local_err_code)) {
796 EM_DEBUG_FUNC_END("false");
800 /* after finishing body parsing, make stream empty to get next mail. (get line from sock or file until '.' is read */
801 if (end_of_parsing == true && local_err_code != EMAIL_ERROR_NO_MORE_DATA)
802 emcore_mime_flush_receiving_buffer(stream, is_file, NULL, NULL, NULL, err_code);
805 *err_code = local_err_code;
810 attachment_name = NULL;
812 if (mmsg->header && emcore_mime_get_header_value(mmsg->header->part_header, CONTENT_DISPOSITION, err_code)) {
813 attachment_name = emcore_mime_get_header_value(mmsg->header->part_header, CONTENT_FILENAME, err_code);
814 /* if (!attachment_name) attachment_name = "unknown" */
815 if (attachment_name) EM_DEBUG_LOG(" attachment = [%s]", attachment_name);
818 if (strstr(content_type, "PKCS7-MIME")) {
819 EM_DEBUG_LOG("Encrypted mail do not include the body");
820 cnt_info->file = em_malloc(sizeof(struct attachment_info));
821 if (cnt_info->file) {
822 cnt_info->file->type = 2;
823 cnt_info->file->name = EM_SAFE_STRDUP(attachment_name);
824 emcore_mime_get_content_data(stream, is_file, false, NULL, content_encoding, &end_of_parsing, SAVE_TYPE_FILE, &holder, &size, NULL, err_code);
825 cnt_info->file->save = holder;
826 cnt_info->file->size = size;
831 if (cnt_info->grab_type & GRAB_TYPE_TEXT) {
833 /* get content data. content data is saved in file */
834 emcore_mime_get_content_data(stream, is_file, true, NULL, content_encoding, &end_of_parsing, SAVE_TYPE_FILE, &holder, &size, NULL, err_code);
836 EM_DEBUG_LOG("After emcore_mime_get_content_data");
838 if (mmsg->header && mmsg->header->part_header && strstr((t = emcore_mime_get_header_value(mmsg->header->part_header, CONTENT_TYPE, err_code)) ? t : "", "HTML"))
839 cnt_info->text.html = holder;
840 else if (mmsg->header) {
841 char *charset = emcore_mime_get_header_value(mmsg->header->part_header, CONTENT_CHARSET, err_code);
843 EM_DEBUG_LOG(">>>> charset [%s]", charset);
845 if (!charset || !strncmp(charset, "X-UNKNOWN", strlen("X-UNKNOWN")))
846 cnt_info->text.plain_charset = EM_SAFE_STRDUP("UTF-8");
848 cnt_info->text.plain_charset = EM_SAFE_STRDUP(charset);
850 EM_DEBUG_LOG(">>>> cnt_info->text.plain_charset [%s]", cnt_info->text.plain_charset);
852 cnt_info->text.plain = holder;
854 EM_DEBUG_LOG(">>>> cnt_info->text.plain [%s]", cnt_info->text.plain);
864 int emcore_mime_parse_part(void *stream, int is_file, struct _m_part_header *parent_header, struct _m_part *nested, struct _m_content_info *cnt_info, int *eop, int *err_code)
866 EM_DEBUG_FUNC_BEGIN("stream[%p], is_file[%d], parent_header[%p], nested[%p], cnt_info[%p], eop[%p], err_code[%p]", stream, is_file, parent_header, nested, cnt_info, eop, err_code);
868 struct _m_body *tmp_body = NULL;
869 struct _m_part **p = NULL;
870 char buf[MIME_LINE_LEN] = {0x00, };
871 char boundary[BOUNDARY_LEN] = {0x00, };
872 char boundary_end[BOUNDARY_LEN] = {0x00, };
873 char mime_type_buffer[128] = { 0, };
874 char *boundary_str = NULL;
875 char *content_type = NULL;
876 char *content_encoding = NULL;
878 char *attachment_name = NULL;
879 char *content_disposition = NULL;
883 int content_disposition_type = 0;
884 int end_of_parsing = 0;
885 int size = 0, local_err_code = EMAIL_ERROR_NONE;
888 boundary_str = emcore_mime_get_header_value(parent_header, CONTENT_BOUNDARY, err_code);
890 SNPRINTF(boundary, BOUNDARY_LEN, "--%s%s", boundary_str, CRLF_STRING);
891 SNPRINTF(boundary_end, BOUNDARY_LEN, "--%s%s", boundary_str, "--\r\n");
896 /* goto the first found useful mime dat */
897 EM_DEBUG_LOG("Before first loop");
899 if (!emcore_check_thread_status()) {
900 if (err_code != NULL)
901 *err_code = EMAIL_ERROR_CANCELLED;
904 if ((is_file == 0 && !emcore_mime_get_line_from_sock(stream, buf, MIME_LINE_LEN, err_code)) ||
905 (is_file == 1 && !emcore_get_line_from_file(stream, buf, MIME_LINE_LEN, err_code))) {
906 EM_DEBUG_EXCEPTION("emcore_mime_get_line_from_sock failed.");
909 EM_DEBUG_FUNC_END("false");
913 if (!strcmp(buf, boundary))
917 EM_DEBUG_LOG("Before second loop");
919 if (!(tmp_body = em_malloc(sizeof(struct _m_body)))) {
920 EM_DEBUG_EXCEPTION("em_malloc failed.");
922 emcore_mime_free_part_body(nested->body);
924 emcore_mime_free_part(nested->next);
925 EM_DEBUG_FUNC_END("false");
929 memset(tmp_body, 0, sizeof(struct _m_body));
931 /* parsing MIME Header */
932 if (!emcore_mime_parse_part_header(stream, is_file, &tmp_body->part_header, err_code)) {
933 EM_DEBUG_EXCEPTION("emcore_mime_parse_part_header failed.");
935 emcore_mime_free_part_body(nested->body);
937 emcore_mime_free_part(nested->next);
939 emcore_mime_free_part_body(tmp_body);
943 content_type = emcore_mime_get_header_value(tmp_body->part_header, CONTENT_TYPE, err_code);
946 content_type = "TEXT/PLAIN";
948 content_encoding = emcore_mime_get_header_value(tmp_body->part_header, CONTENT_ENCODING, err_code);
949 if (!content_encoding)
950 content_encoding = "7BIT";
952 if (strstr(content_type, TEXT_STR)) type = TYPE_TEXT;
953 else if (strstr(content_type, IMAGE_STR)) type = TYPE_IMAGE;
954 else if (strstr(content_type, AUDIO_STR)) type = TYPE_AUDIO;
955 else if (strstr(content_type, VIDEO_STR)) type = TYPE_VIDEO;
956 else if (strstr(content_type, APPLICATION_STR)) type = TYPE_APPLICATION;
957 else if (strstr(content_type, MULTIPART_STR)) type = TYPE_MULTIPART;
958 else if (strstr(content_type, MESSAGE_STR)) type = TYPE_MESSAGE;
959 else type = TYPE_UNKNOWN;
963 EM_DEBUG_LOG("TYPE_MULTIPART");
964 if (!emcore_mime_get_header_value(tmp_body->part_header, CONTENT_BOUNDARY, err_code)) {
965 EM_DEBUG_EXCEPTION("emcore_mime_get_header_value failed.");
966 emcore_mime_free_part_body(tmp_body);
967 EM_DEBUG_FUNC_END("false");
971 emcore_mime_parse_part(stream, is_file, tmp_body->part_header, &tmp_body->nested, cnt_info, &end_of_parsing, &local_err_code);
974 nested->body = tmp_body;
978 while (*p && (*p)->next)
984 if (!(*p = em_malloc(sizeof(struct _m_part)))) {
985 EM_DEBUG_EXCEPTION("em_malloc failed");
986 if (nested->body) emcore_mime_free_part_body(nested->body);
987 if (nested->next) emcore_mime_free_part(nested->next);
988 emcore_mime_free_part_body(tmp_body);
989 EM_DEBUG_FUNC_END("false");
993 (*p)->body = tmp_body;
998 *err_code = local_err_code;
1000 if (end_of_parsing && local_err_code != EMAIL_ERROR_NO_MORE_DATA) /* working with imap */
1001 /* if (!end_of_parsing) */ /* working with pop */ {
1002 EM_DEBUG_LOG("Enter flushing socket buffer.");
1003 emcore_mime_flush_receiving_buffer(stream, is_file, boundary, boundary_end, &end_of_parsing, err_code);
1009 EM_DEBUG_LOG("default");
1010 attachment_name = NULL;
1011 content_disposition = NULL;
1013 if (type == TYPE_MESSAGE)
1016 if (is_skip == true) {
1017 if (!emcore_mime_skip_content_data(stream, is_file, boundary_str, &end_of_parsing, &size, NULL, err_code))
1018 EM_DEBUG_EXCEPTION("emcore_mime_skip_content_data failed...");
1020 emcore_mime_free_part_body(tmp_body);
1021 EM_DEBUG_LOG_MIME("break");
1025 /* first check inline content */
1026 /* if the content id or content location exis */
1027 content_disposition = emcore_mime_get_header_value(tmp_body->part_header, CONTENT_DISPOSITION, err_code);
1028 EM_DEBUG_LOG("content_disposition : [%s]", content_disposition);
1029 if (content_disposition) {
1030 if (!strcasecmp(content_disposition, "inline")) {
1031 if (!attachment_name)
1032 attachment_name = emcore_mime_get_header_value(tmp_body->part_header, CONTENT_ID, err_code);
1033 if (!attachment_name)
1034 attachment_name = emcore_mime_get_header_value(tmp_body->part_header, CONTENT_LOCATION, err_code);
1036 content_disposition_type = 1;
1037 } else if (!strcasecmp(content_disposition, "attachment")) {
1038 if (!attachment_name) {
1039 attachment_name = emcore_mime_get_header_value(tmp_body->part_header, CONTENT_FILENAME, err_code);
1040 EM_DEBUG_LOG_MIME(">> attachment = [%s]", attachment_name ? attachment_name : NIL);
1042 content_disposition_type = 2;
1044 } else if (strstr(content_type, "PKCS7")) {
1045 attachment_name = emcore_mime_get_header_value(tmp_body->part_header, CONTENT_NAME, err_code);
1046 EM_DEBUG_LOG_MIME(">> attachment = [%s]", attachment_name ? attachment_name : NIL);
1049 if (!emcore_check_thread_status()) {
1050 if (err_code != NULL)
1051 *err_code = EMAIL_ERROR_CANCELLED;
1052 EM_DEBUG_EXCEPTION("EMAIL_ERROR_CANCELLED");
1053 EM_DEBUG_FUNC_END("false");
1057 /* get content and content information */
1058 if (!attachment_name) { /* text */
1059 /* get content by buffe */
1060 EM_DEBUG_LOG_MIME("attachment_name is NULL. It's a text message");
1061 emcore_mime_get_content_data(stream, is_file, true, boundary_str, content_encoding, &end_of_parsing, SAVE_TYPE_FILE, &holder, &size, NULL, err_code);
1063 EM_DEBUG_LOG("After emcore_mime_get_content_data");
1065 if (cnt_info->grab_type & GRAB_TYPE_TEXT) {
1066 if (tmp_body->part_header && strstr((t = emcore_mime_get_header_value(tmp_body->part_header, CONTENT_TYPE, err_code)) ? t : "", "HTML")) {
1067 cnt_info->text.html = holder;
1069 EM_DEBUG_LOG(" cnt_info->text.html [%s]", cnt_info->text.html);
1072 char *charset = emcore_mime_get_header_value(tmp_body->part_header, CONTENT_CHARSET, err_code);
1073 EM_DEBUG_LOG(" charset [%s]", charset);
1075 if (!charset || !strncmp(charset, "X-UNKNOWN", strlen("X-UNKNOWN")))
1076 cnt_info->text.plain_charset = EM_SAFE_STRDUP("UTF-8");
1078 cnt_info->text.plain_charset = EM_SAFE_STRDUP(charset);
1080 EM_DEBUG_LOG(" cnt_info->text.plain_charset [%s]", cnt_info->text.plain_charset);
1082 cnt_info->text.plain = holder;
1084 EM_DEBUG_LOG(" cnt_info->text.plain [%s]", cnt_info->text.plain);
1094 else { /* attachment */
1095 EM_DEBUG_LOG_MIME("attachment_name is not NULL. It's a attachment");
1096 struct attachment_info **file = &cnt_info->file;
1099 while (*file && (*file)->next) {
1100 file = &(*file)->next;
1105 file = &(*file)->next;
1109 *file = em_malloc(sizeof(struct attachment_info));
1111 (*file)->type = content_disposition_type;
1113 EM_DEBUG_LOG_MIME("file->type : %d", (*file)->type);
1115 (*file)->name = EM_SAFE_STRDUP(attachment_name);
1116 (*file)->content_id = EM_SAFE_STRDUP(tmp_body->part_header->content_id);
1117 if(tmp_body->part_header->type && tmp_body->part_header->subtype) {
1118 SNPRINTF(mime_type_buffer, 128, "%s/%s", tmp_body->part_header->type, tmp_body->part_header->subtype);
1119 (*file)->attachment_mime_type = EM_SAFE_STRDUP(mime_type_buffer);
1122 /* check if the current file is target file */
1123 if ( (cnt_info->grab_type & GRAB_TYPE_ATTACHMENT) || (*file)->type == 1) {
1124 /* get content by file */
1125 EM_DEBUG_LOG_MIME("Trying to get content");
1126 emcore_mime_get_content_data(stream, is_file, false, boundary_str, content_encoding, &end_of_parsing, SAVE_TYPE_FILE, &holder, &size, NULL, err_code);
1127 (*file)->save = holder;
1130 /* only get content size */
1131 EM_DEBUG_LOG_MIME("Pass downloading");
1132 emcore_mime_get_content_data(stream, is_file, false, boundary_str, content_encoding, &end_of_parsing, SAVE_TYPE_SIZE, NULL, &size, NULL, err_code);
1133 (*file)->save = NULL;
1137 EM_DEBUG_LOG("end_of_parsing [%d], err_code [%d]", end_of_parsing, *err_code);
1139 (*file)->size = size;
1141 if (strstr(content_type, APPLICATION_STR)) {
1142 pTemp = content_type + strlen(APPLICATION_STR);
1144 if (strcasecmp(pTemp, MIME_SUBTYPE_DRM_OBJECT) == 0)
1145 (*file)->drm = EMAIL_ATTACHMENT_DRM_OBJECT;
1146 else if (strcasecmp(pTemp, MIME_SUBTYPE_DRM_RIGHTS) == 0)
1147 (*file)->drm = EMAIL_ATTACHMENT_DRM_RIGHTS;
1148 else if (strcasecmp(pTemp, MIME_SUBTYPE_DRM_DCF) == 0)
1149 (*file)->drm = EMAIL_ATTACHMENT_DRM_DCF;
1153 EM_DEBUG_EXCEPTION("em_malloc failed...");
1154 emcore_mime_free_part_body(tmp_body);
1155 EM_DEBUG_FUNC_END("false");
1160 if (!emcore_check_thread_status()) {
1161 if (err_code != NULL)
1162 *err_code = EMAIL_ERROR_CANCELLED;
1163 EM_DEBUG_EXCEPTION("EMAIL_ERROR_CANCELLED");
1164 EM_DEBUG_FUNC_END("false");
1169 nested->body = tmp_body;
1173 while (*p && (*p)->next)
1179 if (!(*p = em_malloc(sizeof(struct _m_part)))) {
1180 EM_DEBUG_EXCEPTION("em_malloc failed");
1181 if (nested->body) emcore_mime_free_part_body(nested->body);
1182 if (nested->next) emcore_mime_free_part(nested->next);
1184 emcore_mime_free_part_body(tmp_body);
1185 EM_DEBUG_FUNC_END("false");
1189 (*p)->body = tmp_body;
1202 *eop = end_of_parsing;
1204 EM_DEBUG_FUNC_END("end_of_parsing [%d]", end_of_parsing);
1208 /* set RFC822 Heade */
1209 int emcore_mime_set_rfc822_header_value(struct _rfc822header **header, char *name, char *value, int *err_code)
1211 EM_DEBUG_FUNC_BEGIN("header[%p], name[%s], value[%s], err_code[%p]", header, name, value, err_code);
1216 /* ? ? ? why return value is 1 */
1217 if (!value || !*value) return true;
1220 *header = em_malloc(sizeof(struct _rfc822header));
1222 EM_DEBUG_EXCEPTION("em_malloc failed");
1228 em_upper_string(name);
1230 if (strncmp(name, "RETURN-PATH", strlen("RETURN-PATH")) == 0)
1231 p = &(*header)->return_path;/* Return-Rat */
1232 else if (strncmp(name, "RECEIVED", strlen("RECEIVED")) == 0)
1233 p = &(*header)->received; /* Receive */
1234 else if (strncmp(name, "REPLY-TO", strlen("REPLY-TO")) == 0)
1235 p = &(*header)->reply_to; /* Reply-T */
1236 else if (strncmp(name, "DATE", strlen("DATE")) == 0)
1237 p = &(*header)->date; /* Dat */
1238 else if (strncmp(name, "FROM", strlen("FROM")) == 0)
1239 p = &(*header)->from; /* Fro */
1240 else if (strncmp(name, "SUBJECT", strlen("SUBJECT")) == 0)
1241 p = &(*header)->subject; /* Subjec */
1242 else if (strncmp(name, "SENDER", strlen("SENDER")) == 0)
1243 p = &(*header)->sender; /* Sende */
1244 else if (strncmp(name, "TO", strlen("TO")) == 0)
1245 p = &(*header)->to; /* T */
1246 else if (strncmp(name, "CC", strlen("CC")) == 0)
1247 p = &(*header)->cc; /* C */
1248 else if (strncmp(name, "BCC", strlen("BCC")) == 0)
1249 p = &(*header)->bcc; /* Bc */
1250 else if (strncmp(name, "X-PRIORITY", strlen("X-PRIORITY")) == 0)
1251 p = &(*header)->priority; /* Prorit */
1252 else if (strncmp(name, "X-MSMAIL-PRIORITY", strlen("X-MSMAIL-PRIORITY")) == 0)
1253 p = &(*header)->ms_priority;/* Prorit */
1254 else if (strncmp(name, "DISPOSITION-NOTIFICATION-TO", strlen("DISPOSITION-NOTIFICATION-TO")) == 0)
1255 p = &(*header)->dsp_noti_to;/* Disposition-Notification-T */
1263 *p = EM_SAFE_STRDUP(value);
1264 else { /* Long Heade */
1265 if (!(t = realloc(*p, strlen(*p) + strlen(value)+1)))
1268 strncat(t, value, strlen(value));
1276 /* set MIME Part Heade */
1277 int emcore_mime_set_part_header_value(struct _m_part_header **header, char *name, char *value, int *err_code)
1279 EM_DEBUG_FUNC_BEGIN("header[%p], name[%s], value[%s], err_code[%p]", header, name, value, err_code);
1281 if (!name || !value) {
1282 EM_DEBUG_EXCEPTION("Invalid parameter");
1283 if (err_code != NULL)
1284 *err_code = EMAIL_ERROR_INVALID_PARAM;
1288 struct _parameter *p = NULL;
1292 *header = em_malloc(sizeof(struct _m_part_header));
1294 EM_DEBUG_EXCEPTION("em_malloc failed...");
1299 em_upper_string(name);
1300 em_trim_left(value);
1301 em_trim_right(value);
1303 if (!emcore_check_thread_status()) {
1304 if (err_code != NULL)
1305 *err_code = EMAIL_ERROR_CANCELLED;
1310 if (strncmp(name, "CONTENT-TYPE", strlen("CONTENT-TYPE")) == 0) {
1311 p_val = strtok(value, ";");
1314 if (!(*header)->type) { /* Content-Type */
1315 em_upper_string(p_val);
1316 (*header)->type = EM_SAFE_STRDUP(p_val);
1318 else { /* Content-Type Parameter (format : "name =value" */
1319 if (emcore_mime_get_param_from_str(p_val, &p, err_code))
1320 emcore_mime_add_param_to_list(&((*header)->parameter), p, err_code);
1323 /* repeatedly get paramete */
1324 while ((p_val = strtok(NULL, ";"))) {
1325 if (emcore_mime_get_param_from_str(p_val, &p, err_code))
1326 emcore_mime_add_param_to_list(&((*header)->parameter), p, err_code);
1330 else if (strncmp(name, "CONTENT-TRANSFER-ENCODING", strlen("CONTENT-TRANSFER-ENCODING")) == 0) {
1331 em_upper_string(value);
1332 (*header)->encoding = EM_SAFE_STRDUP(value);
1334 else if (strncmp(name, "CONTENT-DESCRPTION", strlen("CONTENT-DESCRPTION")) == 0) {
1335 em_upper_string(value);
1336 (*header)->desc = EM_SAFE_STRDUP(value);
1338 else if (strncmp(name, "CONTENT-DISPOSITION", strlen("CONTENT-DISPOSITION")) == 0) {
1339 p_val = strtok(value, ";");
1342 if (!(*header)->disp_type) { /* Content-Dispositio */
1343 em_upper_string(p_val);
1344 (*header)->disp_type = EM_SAFE_STRDUP(p_val);
1346 else { /* Content-Disposition parameter (format : "name =value" */
1347 if (emcore_mime_get_param_from_str(p_val, &p, err_code))
1348 emcore_mime_add_param_to_list(&((*header)->disp_parameter), p, err_code);
1351 /* repeatedly get paramete */
1352 while ((p_val = strtok(NULL, ";"))) {
1353 if (emcore_mime_get_param_from_str(p_val, &p, err_code))
1354 emcore_mime_add_param_to_list(&((*header)->disp_parameter), p, err_code);
1358 else if (strncmp(name, "CONTENT-ID", strlen("CONTENT-ID")) == 0) {
1360 len = strlen(value);
1361 /* em_upper_string(value) */
1363 if ((len) && (value[0] == '<')) {
1368 if ((len > 1) && (value[len-1] == '>'))
1369 value[len-1] = '\0';
1371 (*header)->content_id = EM_SAFE_STRDUP(value);
1373 else if (strncmp(name, "CONTENT-LOCATION", strlen("CONTENT-LOCATION")) == 0)
1374 (*header)->content_location = EM_SAFE_STRDUP(value);
1376 EM_DEBUG_FUNC_END();
1380 /* get header parameter from strin */
1381 int emcore_mime_get_param_from_str(char *str, struct _parameter **param, int *err_code)
1383 EM_DEBUG_FUNC_BEGIN("str[%s], param[%p], err_code[%p]", str, param, err_code);
1385 char *p_name, *p_val, *p;
1389 /* Parameter Chec */
1390 if (!(p = strchr(str, '='))) return false;
1397 em_trim_left(p_name);
1398 em_trim_right(p_name);
1400 if (!*p_name) return false;
1402 em_trim_left(p_val);
1403 em_trim_right(p_val);
1405 if (!*p_val) return false;
1407 if (!(*param = em_malloc(sizeof(struct _parameter)))) return false;
1409 (*param)->next = NULL;
1412 /* check string lengt */
1413 if (strlen(p_name) > 0) {
1414 em_upper_string(p_name);
1415 (*param)->name = EM_SAFE_STRDUP(p_name);
1418 if (strlen(p_val) > 0) {
1419 if ((p = strchr(p_val, '\"'))) {
1421 if (!*p_val) return false;
1423 if ((p = strchr(p_val, '\"')))
1426 if (strncmp(p_name, "BOUNDARY", strlen("BOUNDARY")) != 0 && !strstr(p_name, "NAME"))
1427 em_upper_string(p_val);
1429 /* = ? ENCODING_TYPE ? B(Q) ? ENCODED_STRING ? */
1430 int err = EMAIL_ERROR_NONE;
1431 char *utf8_text = NULL;
1433 if (!(utf8_text = emcore_decode_rfc2047_text(p_val, &err)))
1434 EM_DEBUG_EXCEPTION("emcore_decode_rfc2047_text failed [%d]", err);
1435 (*param)->value = utf8_text;
1437 EM_DEBUG_FUNC_END();
1441 /* add a parameter to parameter lis */
1442 int emcore_mime_add_param_to_list(struct _parameter **param_list, struct _parameter *param, int *err_code)
1444 struct _parameter **t = param_list;
1446 while (*t && (*t)->next)
1457 /* get header value from MIME Part Heade */
1458 char *emcore_mime_get_header_value(struct _m_part_header *header, int type, int *err_code)
1460 EM_DEBUG_FUNC_BEGIN("header[%p], type[%d], err_code[%p]", header, type, err_code);
1462 struct _parameter *p = NULL;
1466 EM_DEBUG_EXCEPTION("header[%p], type[%d]", header, type);
1468 if (err_code != NULL)
1469 *err_code = EMAIL_ERROR_INVALID_PARAM;
1475 return header->type;
1477 case CONTENT_SUBTYPE:
1478 return header->subtype;
1480 case CONTENT_ENCODING:
1481 return header->encoding;
1483 case CONTENT_CHARSET:
1485 p = header->parameter;
1488 case CONTENT_DISPOSITION:
1489 return header->disp_type;
1493 p = header->parameter;
1496 case CONTENT_FILENAME:
1498 p = header->disp_parameter;
1501 case CONTENT_BOUNDARY:
1503 p = header->parameter;
1506 case CONTENT_REPORT_TYPE:
1507 name = "REPORT-TYPE";
1508 p = header->parameter;
1512 return header->content_id;
1514 case CONTENT_LOCATION:
1515 return header->content_location;
1521 for (; p; p = p->next) {
1522 if (strcmp(p->name, name) == 0)
1528 EM_DEBUG_FUNC_END();
1533 * decode body text (quoted-printable, base64)
1534 * enc_type : encoding type (base64/quotedprintable)
1536 INTERNAL_FUNC int emcore_decode_body_text(char *enc_buf, int enc_len, int enc_type, int *dec_len, int *err_code)
1538 EM_DEBUG_FUNC_BEGIN("enc_buf[%p], enc_len[%d], enc_type[%d], dec_len[%p]", enc_buf, enc_len, enc_type, dec_len);
1539 unsigned char *content = NULL;
1541 /* too many called */
1545 case ENCQUOTEDPRINTABLE:
1546 EM_DEBUG_LOG("ENCQUOTEDPRINTABLE");
1547 content = rfc822_qprint((unsigned char *)enc_buf, (unsigned long)enc_len, (unsigned long *)dec_len);
1551 EM_DEBUG_LOG("ENCBASE64");
1552 content = rfc822_base64((unsigned char *)enc_buf, (unsigned long)enc_len, (unsigned long *)dec_len);
1564 if (enc_len < *dec_len) {
1565 EM_DEBUG_EXCEPTION("Decoded length is too big to store it");
1568 memcpy(enc_buf, content, *dec_len);
1569 enc_buf[*dec_len] = '\0';
1570 EM_SAFE_FREE(content);
1572 EM_DEBUG_FUNC_END();
1576 /* 1. if boundary is NULL, contnent has not multipart */
1577 /* 2. if boundary isn't NULL, content is from current line to the next found boundary */
1578 /* if next found boundary is the other part boundary ("--boundary"), return and set end_of_parsing to 1 */
1579 /* if next found boundary is the multipart ending boundary ("--boundary--"), return and set end_of_parsing to 0 */
1580 /* mode - SAVE_TYPE_SIZE : no saving (only hold content size */
1581 /* SAVE_TYPE_BUFFER : content is saved to buffer (holder is buffer */
1582 /* SAVE_TYPE_FILE : content is saved to temporary file (holder is file name */
1583 int emcore_mime_get_content_data(void *stream, int is_file, int is_text, char *boundary_str, char *content_encoding, int *end_of_parsing, int mode, char **holder, int *size, void *callback, int *err_code)
1585 EM_DEBUG_FUNC_BEGIN("stream[%p], is_file[%d], boundary_str[%s], content_encoding[%s], end_of_parsing[%p], mode[%d], holder[%p], size[%p], callback[%p], err_code[%p]", stream, is_file, boundary_str, content_encoding, end_of_parsing, mode, holder, size, callback, err_code);
1587 char buf[MIME_LINE_LEN] = {0x00, };
1588 char boundary[BOUNDARY_LEN] = {0x00, };
1589 char boundary_end[BOUNDARY_LEN] = {0x00, };
1590 char *result_buffer = NULL;
1591 int sz = 0, fd = 0, result_buffer_size = 0;;
1592 int encoding = ENC7BIT;
1594 int error = EMAIL_ERROR_NONE, ret = false;
1597 if ((mode == SAVE_TYPE_FILE || mode == SAVE_TYPE_BUFFER) && !holder)
1606 EM_DEBUG_LOG("get content");
1608 if (content_encoding) {
1609 switch (content_encoding[0]) {
1611 encoding = ENCQUOTEDPRINTABLE;
1612 break; /* qutoed-printabl */
1614 if (content_encoding[1] == 'A') {
1615 encoding = ENCBASE64;
1618 if (content_encoding[1] == 'I') {
1619 encoding = ENCBINARY;
1631 encoding = ENCOTHER;
1636 /* saving type is file */
1637 if (mode == SAVE_TYPE_FILE) {
1638 *holder = emcore_mime_get_save_file_name(err_code);
1640 EM_DEBUG_LOG("holder[%s]", *holder);
1642 fd = open(*holder, O_WRONLY|O_CREAT, 0644);
1644 EM_DEBUG_EXCEPTION("holder open failed : holder is a filename that will be saved.");
1650 /* if there boundary, this content is from current line to ending boundary */
1651 memset(boundary, 0x00, BOUNDARY_LEN);
1652 memset(boundary_end, 0x00, BOUNDARY_LEN);
1654 SNPRINTF(boundary, BOUNDARY_LEN, "--%s%s", boundary_str, CRLF_STRING);
1655 SNPRINTF(boundary_end, BOUNDARY_LEN, "--%s%s", boundary_str, "--\r\n");
1659 if (!emcore_check_thread_status()) {
1660 EM_DEBUG_EXCEPTION("EMAIL_ERROR_CANCELLED");
1661 error = EMAIL_ERROR_CANCELLED;
1665 if ((is_file == 0 && !emcore_mime_get_line_from_sock(stream, buf, MIME_LINE_LEN, &error)) ||
1666 (is_file == 1 && !emcore_get_line_from_file(stream, buf, MIME_LINE_LEN, &error))) {
1667 if (error == EMAIL_ERROR_NO_MORE_DATA)
1668 EM_DEBUG_EXCEPTION("End of data");
1670 EM_DEBUG_EXCEPTION("emcore_mime_get_line_from_sock failed");
1671 *end_of_parsing = 1;
1678 if (!strcmp(buf, boundary)) { /* the other part started. the parsing of other part will be started */
1679 *end_of_parsing = 0;
1683 else if (!strcmp(buf, boundary_end)) { /* if ending boundary, the parsing of other multipart will be started */
1684 *end_of_parsing = 1;
1690 /* parsing string started by '.' in POP3 */
1691 if ((buf[0] == '.' && buf[1] == '.') && (encoding == ENCQUOTEDPRINTABLE || encoding == ENC7BIT)) {
1692 strncpy(buf, buf+1, MIME_LINE_LEN-1);
1693 buf[strlen(buf)] = NULL_CHAR;
1696 if (encoding == ENCBASE64) {
1697 if (strlen(buf) >= 2)
1698 buf[strlen(buf)-2] = NULL_CHAR;
1699 } else if (encoding == ENCQUOTEDPRINTABLE) {
1700 /* if (strcmp(buf, CRLF_STRING) == 0 */
1704 dec_len = strlen(buf);
1706 if (mode > SAVE_TYPE_SIZE) { /* decode content */
1707 emcore_decode_body_text(buf, dec_len, encoding, &dec_len, err_code);
1708 EM_DEBUG_LOG("decode buf : [%s]", buf);
1711 result_buffer = em_replace_string(buf, "cid:", "");
1713 result_buffer_size = strlen(result_buffer);
1716 if (result_buffer == NULL) {
1717 result_buffer = buf;
1718 result_buffer_size = dec_len;
1721 if (mode == SAVE_TYPE_BUFFER) { /* save content to buffer */
1722 pTemp = realloc(*holder, sz + result_buffer_size + 2);
1724 EM_DEBUG_EXCEPTION("realloc failed...");
1725 error = EMAIL_ERROR_OUT_OF_MEMORY;
1727 EM_SAFE_FREE(*holder);
1728 EM_SAFE_FREE(result_buffer);
1734 memcpy(*holder + sz, result_buffer, result_buffer_size);
1735 (*holder)[sz + strlen(result_buffer) + 1] = NULL_CHAR;
1736 } else if (mode == SAVE_TYPE_FILE) { /* save content to file */
1737 if (write(fd, result_buffer, result_buffer_size) != result_buffer_size) {
1738 if (is_text && (result_buffer != buf))
1739 EM_SAFE_FREE(result_buffer);
1740 EM_DEBUG_EXCEPTION("write failed");
1741 error = EMAIL_ERROR_SYSTEM_FAILURE;
1746 if (is_text && (result_buffer != buf))
1747 EM_SAFE_FREE(result_buffer);
1748 result_buffer = NULL;
1755 if (err_code != NULL)
1766 EM_DEBUG_FUNC_END("ret [%d], sz [%d]", ret, sz);
1770 int emcore_mime_skip_content_data(void *stream,
1773 int *end_of_parsing,
1778 EM_DEBUG_FUNC_BEGIN("stream[%p], is_file[%d], boundary_str[%s], end_of_parsing[%p], size[%p], callback[%p], err_code[%p]", stream, is_file, boundary_str, end_of_parsing, size, callback, err_code);
1780 char buf[MIME_LINE_LEN] = {0x00}, boundary[BOUNDARY_LEN], boundary_end[BOUNDARY_LEN];
1786 EM_DEBUG_LOG(">>> skip content <<<<<<<<<<<<<");
1788 if (!boundary_str) { /* if no boundary, this content is from current line to end of all multipart */
1791 if (!emcore_check_thread_status()) {
1792 if (err_code != NULL)
1793 *err_code = EMAIL_ERROR_CANCELLED;
1796 if ((is_file == 0 && !emcore_mime_get_line_from_sock(stream, buf, MIME_LINE_LEN, err_code)) ||
1797 (is_file == 1 && !emcore_get_line_from_file(stream, buf, MIME_LINE_LEN, err_code))) {
1798 *end_of_parsing = 1;
1806 else { /* if there boundary, this content is from current line to ending boundary */
1807 memset(boundary, 0x00, BOUNDARY_LEN);
1808 memset(boundary_end, 0x00, BOUNDARY_LEN);
1810 SNPRINTF(boundary, BOUNDARY_LEN, "--%s%s", boundary_str, CRLF_STRING);
1811 SNPRINTF(boundary_end, BOUNDARY_LEN, "--%s%s", boundary_str, "--\r\n");
1815 if (!emcore_check_thread_status()) {
1816 if (err_code != NULL)
1817 *err_code = EMAIL_ERROR_CANCELLED;
1820 if ((is_file == 0 && !emcore_mime_get_line_from_sock(stream, buf, MIME_LINE_LEN, err_code)) ||
1821 (is_file == 1 && !emcore_get_line_from_file(stream, buf, MIME_LINE_LEN, err_code))) {
1823 *end_of_parsing = 1;
1829 if (!strcmp(buf, boundary)) { /* the other part started. the parsing of other part will be started */
1830 *end_of_parsing = 0;
1835 else if (!strcmp(buf, boundary_end)) { /* if ending boundary, the parsing of other multipart will be started */
1836 *end_of_parsing = 1;
1848 EM_DEBUG_FUNC_END();
1852 /* get temporary file nam */
1853 char *emcore_mime_get_save_file_name(int *err_code)
1855 EM_DEBUG_FUNC_BEGIN();
1859 gettimeofday(&tv, NULL);
1862 memset(tempname, 0x00, sizeof(tempname));
1864 SNPRINTF(tempname, sizeof(tempname), "%s%s%s%s%d", MAILHOME, DIR_SEPERATOR, MAILTEMP, DIR_SEPERATOR, rand());
1865 EM_DEBUG_FUNC_END();
1866 return EM_SAFE_STRDUP(tempname);
1869 /* get a line from file pointer */
1870 char *emcore_get_line_from_file(void *stream, char *buf, int size, int *err_code)
1872 if (!fgets(buf, size, (FILE *)stream)) {
1873 if (feof((FILE *)stream))
1881 /* get a line from POP3 mail stream */
1882 /* emcore_mail_cmd_read_mail_pop3 must be called before this function */
1883 char *emcore_mime_get_line_from_sock(void *stream, char *buf, int size, int *err_code)
1885 EM_DEBUG_FUNC_BEGIN("stream[%p], buf[%p]", stream, buf);
1886 POP3LOCAL *p_pop3local = NULL;
1888 if (!stream || !buf) {
1889 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
1890 if (err_code != NULL)
1891 *err_code = EMAIL_ERROR_INVALID_PARAM;
1895 memset(buf, 0x00, size);
1897 p_pop3local = (POP3LOCAL *)(((MAILSTREAM *)stream)->local);
1899 EM_DEBUG_EXCEPTION("stream->local[%p]", p_pop3local);
1900 if (err_code != NULL)
1901 *err_code = EMAIL_ERROR_INVALID_PARAM;
1905 if (!pop3_reply((MAILSTREAM *)stream)) { /* if TRUE, check respons */
1906 EM_DEBUG_LOG("p_pop3local->response 1[%s]", p_pop3local->response);
1907 if (p_pop3local->response) {
1908 if (*p_pop3local->response == '.' && strlen(p_pop3local->response) == 1) {
1909 free(p_pop3local->response);
1910 p_pop3local->response = NULL;
1911 if (err_code != NULL)
1912 *err_code = EMAIL_ERROR_NO_MORE_DATA;
1913 EM_DEBUG_FUNC_END("end of response");
1916 EM_DEBUG_LOG("Not end of response");
1917 strncpy(buf, p_pop3local->response, size-1);
1918 strncat(buf, CRLF_STRING, size-(strlen(buf) + 1));
1920 free(p_pop3local->response);
1921 p_pop3local->response = NULL;
1927 EM_DEBUG_LOG("p_pop3local->response 2[%s]", p_pop3local->response);
1928 if (p_pop3local->response)
1930 /* if response isn't NULL, check whether this response start with '+' */
1931 /* if the first character is '+', return error because this response is normal data */
1932 strncpy(buf, p_pop3local->response, size-1);
1933 strncat(buf, CRLF_STRING, size-(strlen(buf)+1));
1934 free(p_pop3local->response); p_pop3local->response = NULL;
1938 EM_DEBUG_EXCEPTION("p_pop3local->response is null. network error... ");
1939 if (err_code != NULL)
1940 *err_code = EMAIL_ERROR_INVALID_RESPONSE;
1941 EM_DEBUG_FUNC_END();
1947 int received_percentage, last_notified_percentage;
1948 _pop3_received_body_size += strlen(buf);
1950 last_notified_percentage = (double)_pop3_last_notified_body_size / (double)_pop3_total_body_size *100.0;
1951 received_percentage = (double)_pop3_received_body_size / (double)_pop3_total_body_size *100.0;
1953 EM_DEBUG_LOG("_pop3_received_body_size = %d, _pop3_total_body_size = %d", _pop3_received_body_size, _pop3_total_body_size);
1954 EM_DEBUG_LOG("received_percentage = %d, last_notified_percentage = %d", received_percentage, last_notified_percentage);
1956 if (received_percentage > last_notified_percentage + 5) {
1957 if (!emstorage_notify_network_event(NOTI_DOWNLOAD_BODY_START, _pop3_receiving_mail_id, "dummy-file", _pop3_total_body_size, _pop3_received_body_size))
1958 EM_DEBUG_EXCEPTION(" emstorage_notify_network_event [NOTI_DOWNLOAD_BODY_START] Failed >>>> ");
1960 EM_DEBUG_LOG("NOTI_DOWNLOAD_BODY_START notified (%d / %d)", _pop3_received_body_size, _pop3_total_body_size);
1961 _pop3_last_notified_body_size = _pop3_received_body_size;
1964 EM_DEBUG_FUNC_END();
1968 void emcore_mime_free_param(struct _parameter *param)
1970 struct _parameter *t, *p = param;
1971 EM_DEBUG_FUNC_BEGIN();
1974 EM_SAFE_FREE(p->name);
1975 EM_SAFE_FREE(p->value);
1979 EM_DEBUG_FUNC_END();
1982 void emcore_mime_free_part_header(struct _m_part_header *header)
1984 EM_DEBUG_FUNC_BEGIN();
1985 if (!header) return ;
1986 EM_SAFE_FREE(header->type);
1987 if (header->parameter) emcore_mime_free_param(header->parameter);
1988 EM_SAFE_FREE(header->subtype);
1989 EM_SAFE_FREE(header->encoding);
1990 EM_SAFE_FREE(header->desc);
1991 EM_SAFE_FREE(header->disp_type);
1992 if (header->disp_parameter) emcore_mime_free_param(header->disp_parameter);
1993 free(header); header = NULL;
1994 EM_DEBUG_FUNC_END();
1997 void emcore_mime_free_message_header(struct _m_mesg_header *header)
1999 EM_DEBUG_FUNC_BEGIN();
2000 if (!header) return ;
2001 EM_SAFE_FREE(header->version);
2002 if (header->part_header) emcore_mime_free_part_header(header->part_header);
2003 free(header); header = NULL;
2004 EM_DEBUG_FUNC_END();
2007 void emcore_mime_free_rfc822_header(struct _rfc822header *header)
2009 EM_DEBUG_FUNC_BEGIN();
2010 if (!header) return ;
2011 EM_SAFE_FREE(header->return_path);
2012 EM_SAFE_FREE(header->received);
2013 EM_SAFE_FREE(header->reply_to);
2014 EM_SAFE_FREE(header->date);
2015 EM_SAFE_FREE(header->from);
2016 EM_SAFE_FREE(header->subject);
2017 EM_SAFE_FREE(header->sender);
2018 EM_SAFE_FREE(header->to);
2019 EM_SAFE_FREE(header->cc);
2020 EM_SAFE_FREE(header->bcc);
2021 free(header); header = NULL;
2022 EM_DEBUG_FUNC_END();
2025 void emcore_mime_free_part_body(struct _m_body *body)
2027 EM_DEBUG_FUNC_BEGIN();
2029 if (body->part_header) emcore_mime_free_part_header(body->part_header);
2030 EM_SAFE_FREE(body->text);
2031 if (body->nested.body) emcore_mime_free_part_body(body->nested.body);
2032 if (body->nested.next) emcore_mime_free_part(body->nested.next);
2033 free(body); body = NULL;
2034 EM_DEBUG_FUNC_END();
2037 void emcore_mime_free_part(struct _m_part *part)
2039 EM_DEBUG_FUNC_BEGIN();
2041 if (part->body) emcore_mime_free_part_body(part->body);
2042 if (part->next) emcore_mime_free_part(part->next);
2043 free(part);part = NULL;
2044 EM_DEBUG_FUNC_END();
2047 void emcore_mime_free_mime(struct _m_mesg *mmsg)
2049 EM_DEBUG_FUNC_BEGIN();
2052 if (mmsg->header) emcore_mime_free_message_header(mmsg->header);
2053 if (mmsg->rfc822header) emcore_mime_free_rfc822_header(mmsg->rfc822header);
2054 if (mmsg->nested.body) emcore_mime_free_part_body(mmsg->nested.body);
2055 if (mmsg->nested.next) emcore_mime_free_part(mmsg->nested.next);
2056 EM_SAFE_FREE(mmsg->text);
2057 free(mmsg); mmsg = NULL;
2058 EM_DEBUG_FUNC_END();
2061 void emcore_free_content_info(struct _m_content_info *cnt_info)
2063 EM_DEBUG_FUNC_BEGIN();
2064 struct attachment_info *p;
2066 if (!cnt_info) return ;
2067 EM_SAFE_FREE(cnt_info->text.plain);
2068 EM_SAFE_FREE(cnt_info->text.plain_charset);
2069 EM_SAFE_FREE(cnt_info->text.html);
2070 while (cnt_info->file) {
2071 p = cnt_info->file->next;
2072 EM_SAFE_FREE(cnt_info->file->name);
2073 EM_SAFE_FREE(cnt_info->file->save);
2074 EM_SAFE_FREE(cnt_info->file->attachment_mime_type);
2075 EM_SAFE_FREE(cnt_info->file->content_id);
2076 free(cnt_info->file); cnt_info->file = NULL;
2079 free(cnt_info);cnt_info = NULL;
2080 EM_DEBUG_FUNC_END();
2083 /* get body-part in nested part */
2084 static PARTLIST *emcore_get_allnested_part_full(MAILSTREAM *stream, int msg_uid, BODY *body, struct _m_content_info *cnt_info, int *err_code, PARTLIST *section_list)
2086 EM_DEBUG_FUNC_BEGIN("stream[%p], msg_uid[%d], body[%p], cnt_info[%p], err_code[%p]", stream, msg_uid, body, cnt_info, err_code);
2088 PART *part_child = body->nested.part;
2090 while (part_child) {
2091 section_list = emcore_get_body_full(stream, msg_uid, &part_child->body, cnt_info, err_code, section_list);
2092 part_child = part_child->next;
2095 return section_list;
2098 /* get body-part in alternative multiple part */
2099 static PARTLIST *emcore_get_alternative_multi_part_full(MAILSTREAM *stream, int msg_uid, BODY *body, struct _m_content_info *cnt_info, int *err_code, PARTLIST *section_list)
2101 EM_DEBUG_FUNC_BEGIN("stream[%p], msg_uid[%d], body[%p], cnt_info[%p], err_code[%p]", stream, msg_uid, body, cnt_info, err_code);
2103 PART *part_child = body->nested.part;
2105 /* find the best sub part we can show */
2106 while (part_child) {
2107 section_list = emcore_get_body_full(stream, msg_uid, &part_child->body, cnt_info, err_code, section_list);
2108 part_child = part_child->next;
2111 return section_list;
2114 /* get body part in signed multiple part */
2115 static PARTLIST *emcore_get_signed_multi_part_full(MAILSTREAM *stream, int msg_uid, BODY *body, struct _m_content_info *cnt_info, int *err_code, PARTLIST *section_list)
2117 EM_DEBUG_FUNC_BEGIN("stream[%p], msg_uid[%d], body[%p], cnt_info[%p], err_code[%p]", stream, msg_uid, body, cnt_info, err_code);
2119 PART *part_child = body->nested.part;
2121 /* find the best sub part we can show */
2122 while (part_child) {
2123 section_list = emcore_get_body_full(stream, msg_uid, &part_child->body, cnt_info, err_code, section_list);
2124 part_child = part_child->next;
2127 return section_list;
2130 /* get body part in encrypted multiple part */
2131 static PARTLIST *emcore_get_encrypted_multi_part_full(MAILSTREAM *stream, int msg_uid, BODY *body, struct _m_content_info *cnt_info, int *err_code, PARTLIST *section_list)
2133 EM_DEBUG_FUNC_BEGIN("stream[%p], msg_uid[%d], body[%p], cnt_info[%p], err_code[%p]", stream, msg_uid, body, cnt_info, err_code);
2135 /* "protocol" = "application/pgp-encrypted */
2136 return section_list;
2139 /* get body part in multiple part */
2140 static PARTLIST *emcore_get_multi_part_full(MAILSTREAM *stream, int msg_uid, BODY *body, struct _m_content_info *cnt_info, int *err_code, PARTLIST *section_list)
2142 EM_DEBUG_FUNC_BEGIN("stream[%p], msg_uid[%d], body[%p], cnt_info[%p], err_code[%p]", stream, msg_uid, body, cnt_info, err_code);
2144 switch (body->subtype[0]) {
2145 case 'A': /* ALTERNATIV */
2146 return section_list = emcore_get_alternative_multi_part_full(stream, msg_uid, body, cnt_info, err_code, section_list);
2148 case 'S': /* SIGNE */
2149 return section_list = emcore_get_signed_multi_part_full(stream, msg_uid, body, cnt_info, err_code, section_list);
2151 case 'E': /* ENCRYPTE */
2152 return section_list = emcore_get_encrypted_multi_part_full(stream, msg_uid, body, cnt_info, err_code, section_list);
2154 default: /* process all unknown as MIXED (according to the RFC 2047 */
2155 return section_list = emcore_get_allnested_part_full(stream, msg_uid, body, cnt_info, err_code, section_list);
2160 PARTLIST* emcore_get_body_full(MAILSTREAM *stream, int msg_uid, BODY *body, struct _m_content_info *cnt_info, int *err_code, PARTLIST *section_list)
2162 EM_DEBUG_FUNC_BEGIN("stream[%p], msg_uid[%d], body[%p], cnt_info[%p], err_code[%p]", stream, msg_uid, body, cnt_info, err_code);
2163 char content_type_buffer[512] = { 0, };
2165 if (!stream || !body || !cnt_info) {
2166 EM_DEBUG_EXCEPTION("stream[%p], msg_uid[%d], body[%p], cnt_info[%p]", stream, msg_uid, body, cnt_info);
2168 if (err_code != NULL)
2169 *err_code = EMAIL_ERROR_INVALID_PARAM;
2173 switch (body->type) {
2175 return section_list = emcore_get_multi_part_full(stream, msg_uid, body, cnt_info, err_code, section_list);
2181 case TYPEAPPLICATION:
2188 /* Form list of attachment followed by list of inline images */
2189 if (body->id || body->location || body->disposition.type) {
2191 char filename[512] = {0, };
2192 struct attachment_info **ai = NULL;
2193 struct attachment_info *prev_ai = NULL;
2194 struct attachment_info *next_ai = NULL;
2197 if (emcore_get_file_pointer(body, true, filename, cnt_info, (int*)NULL) < 0)
2198 EM_DEBUG_EXCEPTION("emcore_get_file_pointer failed");
2200 /* To form list of attachment info - Attachment list followed by inline attachment list */
2203 ai = &cnt_info->file;
2205 EM_DEBUG_LOG(" ai - %p ", (*ai));
2208 /* if ((body->id) || (body->location) */
2209 if ((body->id) || (body->location) || ((body->disposition.type != NULL) && ((body->disposition.type[0] == 'i') || (body->disposition.type[0] == 'I')))) {
2210 /* For Inline content append to the end */
2211 for (i = 1; *ai; ai = &(*ai)->next)
2215 /* For attachment - search till Inline content found and insert before inline */
2216 for (i = 1; *ai; ai = &(*ai)->next) {
2217 if ((*ai)->type == 1) {
2218 /* Means inline image */
2219 EM_DEBUG_LOG("Found Inline Content ");
2228 if (!(*ai = em_malloc(sizeof(struct attachment_info)))) {
2229 EM_DEBUG_EXCEPTION("em_malloc failed...");
2233 cnt_info->file = (*ai);
2235 if ((body->id) || (body->location) || ((body->disposition.type != NULL) && ((body->disposition.type[0] == 'i') || (body->disposition.type[0] == 'I'))))
2236 (*ai)->type = 1; /* inline contents */
2238 (*ai)->type = 2; /* attachment */
2240 (*ai)->name = EM_SAFE_STRDUP(filename);
2241 (*ai)->size = body->size.bytes;
2242 (*ai)->content_id = EM_SAFE_STRDUP(body->id);
2243 if ( emcore_get_content_type_from_mail_bodystruct(body, 512, content_type_buffer) == EMAIL_ERROR_NONE)
2244 (*ai)->attachment_mime_type = EM_SAFE_STRDUP(content_type_buffer);
2246 #ifdef __ATTACHMENT_OPTI__
2247 (*ai)->encoding = body->encoding;
2249 (*ai)->section = EM_SAFE_STRDUP(body->sparep);
2251 EM_DEBUG_LOG(" Encoding - %d Section No - %s ", (*ai)->encoding, (*ai)->section);
2254 EM_DEBUG_LOG("Type[%d], Name[%s], Path[%s] ", (*ai)->type, (*ai)->name, (*ai)->save);
2255 if (body->type == TYPEAPPLICATION) {
2256 if (!strcasecmp(body->subtype, MIME_SUBTYPE_DRM_OBJECT))
2257 (*ai)->drm = EMAIL_ATTACHMENT_DRM_OBJECT;
2258 else if (!strcasecmp(body->subtype, MIME_SUBTYPE_DRM_RIGHTS))
2259 (*ai)->drm = EMAIL_ATTACHMENT_DRM_RIGHTS;
2260 else if (!strcasecmp(body->subtype, MIME_SUBTYPE_DRM_DCF))
2261 (*ai)->drm = EMAIL_ATTACHMENT_DRM_DCF;
2262 else if (!strcasecmp(body->subtype, "pkcs7-mime"))
2263 cnt_info->grab_type = cnt_info->grab_type | GRAB_TYPE_ATTACHMENT;
2266 if ((*ai)->type != 1 && next_ai != NULL) {
2267 /* Means next_ai points to the inline attachment info structure */
2268 if (prev_ai == NULL) {
2269 /* First node is inline attachment */
2270 (*ai)->next = next_ai;
2271 cnt_info->file = (*ai);
2274 prev_ai->next = (*ai);
2275 (*ai)->next = next_ai;
2284 /* if (cnt_info->grab_type == GRAB_TYPE_ATTACHMENT */
2285 if (cnt_info->grab_type & GRAB_TYPE_ATTACHMENT) {
2286 if (((body->disposition.type != NULL) && ((body->disposition.type[0] == 'a') || (body->disposition.type[0] == 'A'))) && (cnt_info->file != NULL)) {
2287 PARAMETER *param = NULL;
2290 param = body->parameter;
2293 if (!strcasecmp(param->attribute, "NAME")) {
2294 fn = EM_SAFE_STRDUP(param->value);
2297 if (!strcasecmp(param->attribute, "FILENAME")) {
2298 fn = EM_SAFE_STRDUP(param->value);
2301 param = param->next;
2303 if ((fn != NULL)&& (!strcmp(fn, cnt_info->file->name)) && (body->size.bytes == cnt_info->file->size)) /* checks to zero in on particular attachmen */ {
2304 section_list = emcore_add_node(section_list, body);
2305 if (section_list == NULL) {
2306 EM_DEBUG_EXCEPTION("adding node to section list failed");
2312 return section_list; /* single attachment download, so if a match found break the recursio */
2319 /* get a section list which has only plain, html and inline */
2320 if (!((body->disposition.type != NULL) && ((body->disposition.type[0] == 'a') || (body->disposition.type[0] == 'A'))))/* if the body not an attachmen */ {
2321 section_list = emcore_add_node(section_list, body);
2322 if (section_list == NULL) {
2323 EM_DEBUG_EXCEPTION("adding node to section list failed");
2335 return section_list;
2338 INTERNAL_FUNC int emcore_get_body_part_list_full(MAILSTREAM *stream, int msg_uid, int account_id, int mail_id, BODY *body, struct _m_content_info *cnt_info, int *err_code, PARTLIST *section_list, int event_handle)
2340 EM_DEBUG_FUNC_BEGIN("stream[%p], msg_uid[%d], body[%p], cnt_info[%p], err_code[%p]", stream, msg_uid, body, cnt_info, err_code);
2342 if (!stream || !body || !cnt_info) {
2343 EM_DEBUG_EXCEPTION("stream[%p], msg_uid[%d], body[%p], cnt_info[%p]", stream, msg_uid, body, cnt_info);
2345 if (err_code != NULL)
2346 *err_code = EMAIL_ERROR_INVALID_PARAM;
2349 section_list = emcore_get_body_full(stream, msg_uid, body, cnt_info, err_code, section_list);
2351 if (section_list == NULL) {
2352 /* assumed at least one body part exist */
2353 EM_DEBUG_EXCEPTION("emcore_get_body_full failed");
2357 if (emcore_get_body_part_imap_full(stream, msg_uid, account_id, mail_id, section_list, cnt_info, err_code, event_handle) < 0) {
2358 EM_DEBUG_EXCEPTION("emcore_get_body_part_imap_full failed");
2359 emcore_free_section_list(section_list);
2362 emcore_free_section_list(section_list);
2366 static int emcore_write_response_into_file(char *filename, char *write_mode, char *encoded, int encoding_type, char *subtype, int account_id, int mail_id, int *err)
2368 EM_DEBUG_FUNC_BEGIN();
2369 int temp_decoded_len = 0;
2370 int inline_support = 0;
2372 int error = EMAIL_ERROR_NONE;
2373 int not_found = true;
2374 int encoded_len = 0;
2375 int written_bytes = 0;
2376 unsigned long decoded_len = 0;
2377 char *decoded = NULL;
2378 char *decoded_temp = NULL;
2379 char save_file_name[MAX_PATH+1] = {0, };
2380 char html_cid_path[MAX_PATH+1] = {0, };
2382 PARAMETER *param = NULL;
2383 PARAMETER *param1 = NULL;
2386 if (!encoded || !filename || !write_mode) {
2387 EM_DEBUG_EXCEPTION("Invalid Param ");
2388 error = EMAIL_ERROR_INVALID_PARAM;
2393 EM_DEBUG_LOG("Encoded buffer length [%d]", strlen(encoded));
2394 encoded_len = strlen(encoded);
2396 EM_DEBUG_LOG("encoding_type [%d]", encoding_type);
2397 switch (encoding_type) {
2398 case ENCQUOTEDPRINTABLE: {
2399 unsigned char *orignal = (unsigned char *)g_strdup_printf("%s\r\n", encoded);
2400 decoded = (char *)rfc822_qprint(orignal, encoded_len + 2, &decoded_len);
2406 decoded = (char *)rfc822_base64((unsigned char *)encoded, encoded_len, &decoded_len);
2410 unsigned char *orignal = (unsigned char *)g_strdup_printf("%s\r\n", encoded);
2411 memcpy(decoded = malloc(encoded_len + 3), orignal, encoded_len + 3);
2412 decoded_len = encoded_len + 2;
2418 if (decoded != NULL) {
2419 EM_DEBUG_LOG("Decoded Length [%d] " , decoded_len);
2420 EM_DEBUG_LOG("filename [%s] " , filename);
2422 if (!(fp = fopen(filename, write_mode))) {
2423 EM_DEBUG_EXCEPTION("fopen failed - %s", filename);
2424 error = EMAIL_ERROR_SYSTEM_FAILURE;
2428 if (subtype && subtype[0] == 'H') {
2429 char body_inline_id[512] = {0};
2431 while (strstr(decoded, "cid:")) {
2432 EM_DEBUG_LOG("Found cid:");
2434 if (g_inline_count) {
2435 BODY *body_inline = NULL;
2436 int inline_count = 0;
2437 char *decoded_content_id = NULL;
2438 while (inline_count < g_inline_count && g_inline_list[inline_count]) {
2439 EM_DEBUG_LOG("inline_count [%d], g_inline_count [%d]", inline_count, g_inline_count);
2440 body_inline = g_inline_list[inline_count];
2441 param = body_inline->disposition.parameter;
2442 param1 = body_inline->parameter;
2444 memset(body_inline_id, 0x00, 512);
2446 if (body_inline && body_inline->id && strlen(body_inline->id) > 0) {
2447 EM_DEBUG_LOG("body_inline->id - %s", body_inline->id);
2448 EM_DEBUG_LOG("param - %p param1 - %p", param, param1);
2449 decoded_content_id = strstr(decoded, "cid:");
2451 if (body_inline->id[0] == '<')
2452 memcpy(body_inline_id, body_inline->id + 1, strlen(body_inline->id) - 2);
2454 memcpy(body_inline_id, body_inline->id , strlen(body_inline->id));
2456 EM_DEBUG_LOG("Inline body_inline_id [%s] ", body_inline_id);
2458 if ((param || param1) && 0 == strncmp(body_inline_id , decoded_content_id + strlen("cid:"), strlen(body_inline_id))) {
2459 EM_DEBUG_LOG(" Inline CID Found ");
2461 memset(save_file_name, 0x00, MAX_PATH);
2462 memset(html_cid_path, 0x00, MAX_PATH);
2464 /* Finding 'filename' attribute from content inf */
2465 emcore_get_file_pointer(body_inline, true, save_file_name, NULL, &error);
2467 if (strlen(save_file_name) > 0) {
2468 /* Content ID will be replaced with its file name in html */
2469 memcpy(html_cid_path, decoded_content_id , strlen("cid:") + strlen(body_inline_id));
2471 EM_DEBUG_LOG("Replacing %s with %s ", html_cid_path, save_file_name);
2472 if ((decoded_temp = em_replace_string(decoded, html_cid_path, save_file_name))) {
2473 EM_SAFE_FREE(decoded);
2474 decoded = decoded_temp;
2475 decoded_len = strlen(decoded);
2476 EM_DEBUG_LOG("Decoded Length [%d] ", decoded_len);
2479 /* only_body_download = false */
2492 EM_DEBUG_LOG("not_found is true");
2493 memset(body_inline_id, 0x00, sizeof(body_inline_id));
2494 decoded_temp = em_replace_string_with_split_file_path(decoded, "cid:", body_inline_id);
2496 /* only_body_download = false */
2497 /* EM_DEBUG_LOG(">>>> decoded_temp 2 [ %s ] ", decoded_temp) */
2498 EM_SAFE_FREE(decoded);
2499 decoded = decoded_temp;
2500 temp_decoded_len = strlen(body_inline_id);
2501 decoded_len = strlen(decoded);
2502 EM_DEBUG_LOG("Decoded Length [%d] ", decoded_len);
2509 EM_DEBUG_LOG("Trying to fwrite. decoded_len [%d]", decoded_len);
2511 if (decoded_len > 0 && fwrite(decoded, decoded_len, 1, fp) < 0) {
2512 EM_DEBUG_EXCEPTION("Error Occured while writing. fwrite(\"%s\") failed. decoded_len [%d], written_bytes [%d] ", decoded, decoded_len, written_bytes);
2513 error = EMAIL_ERROR_SYSTEM_FAILURE;
2517 EM_DEBUG_LOG("fwrite succeed");
2520 EM_DEBUG_EXCEPTION("Error Occured while decoding ");
2530 EM_SAFE_FREE(decoded);
2535 EM_DEBUG_FUNC_END();
2541 static BODY *emcore_select_body_structure_from_section_list(PARTLIST *section_list, char *section)
2543 PARTLIST *temp = section_list;
2546 while (temp != NULL) {
2548 if (!strcmp(section, body->sparep))
2550 temp = (PARTLIST *)temp->next;
2558 static int imap_mail_write_body_to_file(MAILSTREAM *stream, int account_id, int mail_id, int is_attachment, char *filepath, int uid, char *section, int encoding, int *decoded_total, char *section_subtype, int *err_code)
2560 EM_PROFILE_BEGIN(imapMailWriteBodyToFile);
2561 EM_DEBUG_FUNC_BEGIN("stream[%p], filepath[%s], uid[%d], section[%s], encoding[%d], decoded_total[%p], err_code[%p]", stream, filepath, uid, section, encoding, decoded_total, err_code);
2564 int err = EMAIL_ERROR_NONE;
2567 IMAPLOCAL *imaplocal = NULL;
2568 char tag[16], command[64];
2569 char *response = NULL;
2570 char *decoded = NULL;
2571 int body_size = 0, total = 0;
2572 char *file_id = NULL;
2573 char server_uid[129];
2574 char *filename = NULL;
2575 int server_response_yn = 0;
2576 int write_flag = false;
2577 char *write_buffer = NULL;
2578 unsigned char encoded[DOWNLOAD_MAX_BUFFER_SIZE] = {0, };
2579 unsigned char test_buffer[LOCAL_MAX_BUFFER_SIZE] = {0};
2580 int flag_first_write = true;
2582 if (!stream || !filepath || !section) {
2583 EM_DEBUG_EXCEPTION("stream[%p], filepath[%s], uid[%d], section[%s], encoding[%d], decoded_total[%p]", stream, filepath, uid, section, encoding, decoded_total);
2584 err = EMAIL_ERROR_INVALID_PARAM;
2588 int max_write_buffer_size = 0;
2589 if (vconf_get_int("db/email/write_buffer_mode", &max_write_buffer_size) != 0) {
2590 EM_DEBUG_EXCEPTION("vconf_get_int failed. So set direct file writing");
2591 /* set as default profile typ */
2592 max_write_buffer_size = 0;
2595 EM_DEBUG_LOG(">>> WRITE BUFFER SIZE : %d KB", max_write_buffer_size);
2596 if (max_write_buffer_size > 0) {
2597 max_write_buffer_size *= 1024; /* KB -> byte */
2598 if (!(write_buffer = em_malloc(sizeof(char) *max_write_buffer_size))) {
2599 EM_DEBUG_EXCEPTION("em_malloc failed...");
2600 err = EMAIL_ERROR_OUT_OF_MEMORY;
2605 FINISH_OFF_IF_CANCELED;
2607 if (!(fp = fopen(filepath, "wb+"))) {
2608 EM_DEBUG_EXCEPTION("fopen failed - %s", filepath);
2609 err = EMAIL_ERROR_SYSTEM_FAILURE; /* EMAIL_ERROR_UNKNOWN */
2613 imaplocal = stream->local;
2615 if (!imaplocal->netstream) {
2616 EM_DEBUG_EXCEPTION("invalid IMAP4 stream detected... %p", imaplocal->netstream);
2618 err = EMAIL_ERROR_INVALID_STREAM;
2622 EM_DEBUG_LOG(" next_decode_string = false ");
2623 next_decode_string = false;
2625 memset(tag, 0x00, sizeof(tag));
2626 memset(command, 0x00, sizeof(command));
2628 SNPRINTF(tag, sizeof(tag), "%08lx", 0xffffffff & (stream->gensym++));
2629 SNPRINTF(command, sizeof(command), "%s UID FETCH %d BODY.PEEK[%s]\015\012", tag, uid, section);
2631 EM_DEBUG_LOG("[IMAP4] >>> [%s]", command);
2633 /* send command : get msgno/uid for all messag */
2634 if (!net_sout(imaplocal->netstream, command, (int)strlen(command))) {
2635 EM_DEBUG_EXCEPTION("net_sout failed...");
2636 err = EMAIL_ERROR_CONNECTION_BROKEN;
2640 while (imaplocal->netstream) {
2644 if (!emcore_check_thread_status()) {
2645 EM_DEBUG_LOG("Canceled...");
2646 /* Is it realy required ? It might cause crashes.
2647 if (imaplocal->netstream)
2648 net_close (imaplocal->netstream);
2650 imaplocal->netstream = NULL;
2651 err = EMAIL_ERROR_CANCELLED;
2655 /* receive respons */
2656 if (!(response = net_getline(imaplocal->netstream))) {
2657 EM_DEBUG_EXCEPTION("net_getline failed...");
2658 err = EMAIL_ERROR_INVALID_RESPONSE;
2661 #ifdef FEATURE_CORE_DEBUG
2662 EM_DEBUG_LOG("recv[%s]", response);
2666 if (response[0] == '*' && !server_response_yn) { /* start of respons */
2668 if ((p = strstr(response, "BODY[")) /* || (p = strstr(s + 1, "BODY["))*/) {
2669 server_response_yn = 1;
2670 p += strlen("BODY[");
2678 if (strcmp(section, p)) {
2679 err = EMAIL_ERROR_INVALID_RESPONSE;
2683 if ((p = strstr(s+1, " {"))) {
2692 body_size = atoi(p);
2694 else { /* no body length is replied */
2695 if ((p = strstr(s+1, " \""))) { /* seek the termination of double quot */
2698 if ((t = strstr(p, "\""))) {
2701 EM_DEBUG_LOG("Body : start[%p] end[%p] : body[%s]", p, t, p);
2703 EM_SAFE_FREE(response);
2704 response = EM_SAFE_STRDUP(p);
2708 err = EMAIL_ERROR_INVALID_RESPONSE;
2713 err = EMAIL_ERROR_INVALID_RESPONSE;
2718 /* sending progress noti to application.
2723 parse_file_path_to_filename(filepath, &file_id);
2726 sprintf(server_uid, "%d", uid);
2728 EM_DEBUG_LOG("file_id [%s]", file_id);
2729 EM_DEBUG_LOG("filename [%p]-[%s]", filename, filename);
2730 EM_DEBUG_LOG("body_size [%d]", body_size);
2731 EM_DEBUG_LOG("server_uid [%s]", server_uid);
2732 EM_DEBUG_LOG("mail_id [%d]", mail_id);
2734 if (is_attachment) {
2735 EM_DEBUG_LOG("Attachment number [%d]", is_attachment);
2736 if (!emstorage_notify_network_event(NOTI_DOWNLOAD_ATTACH_START, mail_id, filename, is_attachment, 0))
2737 EM_DEBUG_EXCEPTION(" emstorage_notify_network_event [ NOTI_DOWNLOAD_ATTACH_START] Failed >>>> ");
2738 _imap4_download_noti_interval_value = body_size *DOWNLOAD_NOTI_INTERVAL_PERCENT / 100;
2739 _imap4_total_body_size = body_size;
2742 if (multi_part_body_size) {
2743 EM_DEBUG_LOG("Multipart body size is [%d]", multi_part_body_size);
2744 if (!emstorage_notify_network_event(NOTI_DOWNLOAD_MULTIPART_BODY, mail_id, filename, multi_part_body_size, 0))
2745 EM_DEBUG_EXCEPTION(" emstorage_notify_network_event [ NOTI_DOWNLOAD_BODY_START] Failed >>>> ");
2746 _imap4_download_noti_interval_value = multi_part_body_size *DOWNLOAD_NOTI_INTERVAL_PERCENT / 100;
2747 /* _imap4_total_body_size should be set before calling this functio */
2748 /* _imap4_total_body_size */
2751 if (!emstorage_notify_network_event(NOTI_DOWNLOAD_BODY_START, mail_id, filename, body_size, 0))
2752 EM_DEBUG_EXCEPTION(" emstorage_notify_network_event [ NOTI_DOWNLOAD_BODY_START] Failed >>>>");
2753 _imap4_download_noti_interval_value = body_size *DOWNLOAD_NOTI_INTERVAL_PERCENT / 100;
2754 _imap4_total_body_size = body_size;
2757 if (_imap4_download_noti_interval_value > DOWNLOAD_NOTI_INTERVAL_SIZE) {
2758 _imap4_download_noti_interval_value = DOWNLOAD_NOTI_INTERVAL_SIZE;
2760 if (body_size < DOWNLOAD_MAX_BUFFER_SIZE) {
2761 if (net_getbuffer (imaplocal->netstream, (long)body_size, (char *)encoded) <= 0) {
2762 EM_DEBUG_EXCEPTION("net_getbuffer failed...");
2763 err = EMAIL_ERROR_NO_RESPONSE;
2767 if (!emcore_write_response_into_file(filepath, "wb+", (char *)encoded, encoding, section_subtype, account_id, mail_id, &err)) {
2768 EM_DEBUG_EXCEPTION("write_response_into_file failed [%d]", err);
2772 total = strlen((char *)encoded);
2773 EM_DEBUG_LOG("total = %d", total);
2774 EM_DEBUG_LOG("write_response_into_file successful %s.....", filename);
2776 if (((_imap4_last_notified_body_size + _imap4_download_noti_interval_value) <= _imap4_received_body_size)
2777 || (_imap4_received_body_size >= _imap4_total_body_size)) /* 100 */ {
2778 /* In some situation, total_encoded_len includes the length of dummy bytes. So it might be greater than body_size */
2780 if (total > body_size)
2781 gap = total - body_size;
2782 _imap4_received_body_size -= gap;
2783 _imap4_last_notified_body_size = _imap4_received_body_size;
2786 EM_DEBUG_LOG("DOWNLOADING STATUS NOTIFY : Encoded[%d] / [%d] = %d %% Completed. -- Total Decoded[%d]", total, body_size, 100*total/body_size, total);
2788 if(_imap4_total_body_size > 0)
2789 EM_DEBUG_LOG("DOWNLOADING STATUS NOTIFY : Total[%d] / [%d] = %d %% Completed.", _imap4_received_body_size, _imap4_total_body_size, 100*_imap4_received_body_size/_imap4_total_body_size);
2791 if (is_attachment) {
2792 if (_imap4_total_body_size && !emstorage_notify_network_event(NOTI_DOWNLOAD_ATTACH_START, mail_id, filename, is_attachment, 100 *_imap4_received_body_size / _imap4_total_body_size))
2793 EM_DEBUG_EXCEPTION(" emstorage_notify_network_event [ NOTI_DOWNLOAD_ATTACH_START] Failed >>>> ");
2796 if (multi_part_body_size) {
2797 if (!emstorage_notify_network_event(NOTI_DOWNLOAD_MULTIPART_BODY, mail_id, filename, _imap4_total_body_size, _imap4_received_body_size))
2798 EM_DEBUG_EXCEPTION(" emstorage_notify_network_event [ NOTI_DOWNLOAD_BODY_START] Failed >>>> ");
2801 if (!emstorage_notify_network_event(NOTI_DOWNLOAD_BODY_START, mail_id, filename, _imap4_total_body_size, _imap4_received_body_size))
2802 EM_DEBUG_EXCEPTION(" emstorage_notify_network_event [ NOTI_DOWNLOAD_BODY_START] Failed >>>>");
2804 } /* if (is_attachment) .. else .. */
2808 int temp_body_size = body_size;
2811 if (encoding == ENCBASE64)
2812 x = (sizeof(encoded)/78) *78; /* to solve base64 decoding pro */
2814 x = sizeof(encoded)-1;
2816 memset(test_buffer, 0x00, sizeof(test_buffer));
2817 while (temp_body_size && (total <body_size)) {
2819 memset(test_buffer, 0x00, sizeof(test_buffer));
2820 while ((total != body_size) && temp_body_size && ((strlen((char *)test_buffer) + x) < sizeof(test_buffer))) {
2821 memset(encoded, 0x00, sizeof(encoded));
2823 if (net_getbuffer (imaplocal->netstream, (long)x, (char *)encoded) <= 0) {
2824 EM_DEBUG_EXCEPTION("net_getbuffer failed...");
2825 err = EMAIL_ERROR_NO_RESPONSE;
2829 temp_body_size = temp_body_size - x;
2830 strncat((char *)test_buffer, (char *)encoded, strlen((char *)encoded));
2832 _imap4_received_body_size += strlen((char *)encoded);
2834 if ( !(temp_body_size/x) && temp_body_size%x)
2835 x = temp_body_size%x;
2837 if (((_imap4_last_notified_body_size + _imap4_download_noti_interval_value) <= _imap4_received_body_size)
2838 || (_imap4_received_body_size >= _imap4_total_body_size)) /* 100 */ {
2839 /* In some situation, total_encoded_len includes the length of dummy bytes. So it might be greater than body_size */
2841 if (total > body_size)
2842 gap = total - body_size;
2843 _imap4_received_body_size -= gap;
2844 _imap4_last_notified_body_size = _imap4_received_body_size;
2846 /* EM_DEBUG_LOG("DOWNLOADING STATUS NOTIFY : Encoded[%d] / [%d] = %d %% Completed. -- Total Decoded[%d]", total, body_size, 100*total/body_size, total) */
2847 EM_DEBUG_LOG("DOWNLOADING STATUS NOTIFY : Total[%d] / [%d] = %d %% Completed.", _imap4_received_body_size, _imap4_total_body_size, 100*_imap4_received_body_size/_imap4_total_body_size);
2849 if (is_attachment) {
2850 if (!emstorage_notify_network_event(NOTI_DOWNLOAD_ATTACH_START, mail_id, filename, is_attachment, 100 *_imap4_received_body_size / _imap4_total_body_size))
2851 EM_DEBUG_EXCEPTION(" emstorage_notify_network_event [ NOTI_DOWNLOAD_ATTACH_START] Failed >>>> ");
2854 if (multi_part_body_size) {
2855 /* EM_DEBUG_LOG("DOWNLOADING.......... : Multipart body size is [%d]", multi_part_body_size) */
2856 if (!emstorage_notify_network_event(NOTI_DOWNLOAD_MULTIPART_BODY, mail_id, filename, _imap4_total_body_size, _imap4_received_body_size))
2857 EM_DEBUG_EXCEPTION(" emstorage_notify_network_event [ NOTI_DOWNLOAD_BODY_START] Failed >>>> ");
2860 if (!emstorage_notify_network_event(NOTI_DOWNLOAD_BODY_START, mail_id, filename, _imap4_total_body_size, _imap4_received_body_size))
2861 EM_DEBUG_EXCEPTION(" emstorage_notify_network_event [ NOTI_DOWNLOAD_BODY_START] Failed >>>>");
2863 } /* if (is_attachment) .. else .. */
2869 if (flag_first_write == true) {
2870 if (!emcore_write_response_into_file(filepath, "wb+", (char *)test_buffer, encoding, section_subtype, account_id, mail_id, &err)) {
2871 EM_DEBUG_EXCEPTION("write_response_into_file %s failed [%d]", filepath, err);
2874 flag_first_write = false;
2877 if (!emcore_write_response_into_file(filepath, "ab+", (char *)test_buffer, encoding, section_subtype, account_id, mail_id, &err)) /* append */ {
2878 EM_DEBUG_EXCEPTION("write_response_into_file %s failed [%d]", filepath, err);
2882 EM_DEBUG_LOG("%d has been written", strlen((char *)test_buffer));
2889 err = EMAIL_ERROR_INVALID_RESPONSE;
2894 else if (!strncmp(response, tag, strlen(tag))) { /* end of respons */
2895 if (!strncmp(response + strlen(tag) + 1, "OK", 2)) {
2896 EM_SAFE_FREE(response);
2898 else { /* 'NO' or 'BAD */
2899 err = EMAIL_ERROR_IMAP4_FETCH_UID_FAILURE;
2905 else if (!strcmp(response, ")")) {
2906 /* The end of response which contains body informatio */
2910 } /* while (imaplocal->netstream) */
2912 if (decoded_total != NULL)
2913 *decoded_total = total;
2918 EM_SAFE_FREE(decoded);
2919 EM_SAFE_FREE(response);
2924 EM_SAFE_FREE(write_buffer);
2926 if (ret == false) { /* delete temp fil */
2927 struct stat temp_file_stat;
2928 if (filepath && stat(filepath, &temp_file_stat) == 0)
2932 if (err_code != NULL)
2935 EM_PROFILE_END(imapMailWriteBodyToFile);
2940 static int emcore_get_body_part_imap_full(MAILSTREAM *stream, int msg_uid, int account_id, int mail_id, PARTLIST *section_list, struct _m_content_info *cnt_info, int *err_code, int event_handle)
2942 EM_DEBUG_FUNC_BEGIN("stream[%p], msg_uid[%d], body[%p], cnt_info[%p], err_code[%p]", stream, msg_uid, section_list, cnt_info, err_code);
2944 int err = EMAIL_ERROR_NONE;
2945 char sections[IMAP_MAX_COMMAND_LENGTH] = { 0, };
2946 IMAPLOCAL *imaplocal = NULL;
2947 char tag[16] = { 0, }, command[IMAP_MAX_COMMAND_LENGTH] = { 0, };
2948 char section[16] = {0};
2949 char *response = NULL;
2951 int server_response_yn = 0;
2954 char filename[512] = {0, };
2955 int return_value = 0 ;
2957 unsigned char encoded[DOWNLOAD_MAX_BUFFER_SIZE] = {0};
2958 unsigned char test_buffer[LOCAL_MAX_BUFFER_SIZE] = {0};
2959 struct attachment_info *ai = NULL;
2962 int flag_first_write = 1;
2963 int imap4_total_body_download_progress = 0, progress = 0;
2965 if (!(imaplocal = stream->local) || !imaplocal->netstream || !section_list || !cnt_info) {
2966 EM_DEBUG_EXCEPTION("invalid IMAP4 stream detected...");
2967 err = EMAIL_ERROR_INVALID_PARAM;
2972 if (section_list != NULL) {
2973 PARTLIST *temp = section_list;
2975 if (cnt_info->grab_type == GRAB_TYPE_ATTACHMENT) {
2976 /* to download attachment */
2978 if (body->sparep != NULL) {
2979 snprintf(sections, sizeof(sections), "BODY.PEEK[%s]", (char *)body->sparep);
2982 EM_DEBUG_EXCEPTION("body->sparep can not be null. ");
2989 while (temp != NULL) {
2993 if ((body->type == TYPETEXT) || (body->id != NULL) || ((body->disposition.type != NULL) && ((body->disposition.type[0] == 'i') || (body->disposition.type[0] == 'I')))) {
2994 snprintf(t, sizeof(t), "BODY.PEEK[%s] ", (char *)body->sparep); /* body parts seperated by period */
2995 strcat(sections, t);
2997 temp = (PARTLIST *)temp->next;
3002 if ((strlen(sections) == (sizeof(sections)-1)) || (strlen(sections) == 0)) {
3003 EM_DEBUG_EXCEPTION(" Too many body parts or nil. IMAP command may cross 1000bytes.");
3008 if (sections[strlen(sections)-1] == ' ') {
3009 sections[strlen(sections)-1] = '\0';
3012 EM_DEBUG_LOG("sections <%s>", sections);
3014 SNPRINTF(tag, sizeof(tag), "%08lx", 0xffffffff & (stream->gensym++));
3015 SNPRINTF(command, sizeof(command), "%s UID FETCH %d (%s)\015\012", tag, msg_uid, sections);
3016 EM_DEBUG_LOG("command %s", command);
3018 if (strlen(command) == (sizeof(command)-1)) {
3019 EM_DEBUG_EXCEPTION("Too many body parts. IMAP command will fail.");
3024 /* send command : get msgno/uid for all message */
3025 if (!net_sout(imaplocal->netstream, command, (int)strlen(command))) {
3026 EM_DEBUG_EXCEPTION("net_sout failed...");
3027 err = EMAIL_ERROR_CONNECTION_BROKEN;
3031 while (imaplocal->netstream) {
3033 /* receive respons */
3034 if (!(response = net_getline(imaplocal->netstream))) {
3035 EM_DEBUG_EXCEPTION("net_getline failed...");
3036 err = EMAIL_ERROR_INVALID_RESPONSE;
3041 if (strstr(response, "BODY[")) {
3043 if (!server_response_yn) /* start of response */ {
3044 if (response[0] != '*') {
3045 err = EMAIL_ERROR_INVALID_RESPONSE;
3046 EM_DEBUG_EXCEPTION("Start of response doesn't contain *");
3050 server_response_yn = 1;
3053 flag_first_write = 1;
3055 memset(encoded, 0x00, sizeof(encoded));
3057 if (emcore_get_section_body_size(response, section, &body_size)<0) {
3058 EM_DEBUG_EXCEPTION("emcore_get_section_body_size failed [%d]", err);
3059 err = EMAIL_ERROR_INVALID_RESPONSE;
3063 EM_DEBUG_LOG("body_size-%d", body_size);
3065 /* get body from seciton_list */
3066 if ((body = emcore_select_body_structure_from_section_list(section_list, section)) == NULL) {
3067 EM_DEBUG_EXCEPTION("emcore_select_body_structure_from_section_list failed [%d]", err);
3068 err = EMAIL_ERROR_INVALID_RESPONSE;
3072 encoding = body->encoding;
3074 /* if (emcore_get_file_pointer(account_id, mail_id, body, buf, cnt_info , err)<0) {
3075 EM_DEBUG_EXCEPTION("emcore_get_file_pointer failed [%d]", err);
3079 if (!emcore_get_temp_file_name(&buf, &err)) {
3080 EM_DEBUG_EXCEPTION("emcore_get_temp_file_name failed [%d]", err);
3084 EM_DEBUG_LOG("buf : %s", buf);
3086 /* notifying UI start */
3087 /* parse_file_path_to_filename(buf, &file_id); */
3088 /* EM_DEBUG_LOG(">>>> filename - %p >>>>>>", file_id) */
3090 if (body->type == TYPETEXT && body->subtype && (!body->disposition.type || (body->disposition.type && (body->disposition.type[0] == 'i' || body->disposition.type[0] == 'I')))) {
3091 if (body->subtype[0] == 'H')
3092 cnt_info->text.html = buf;
3094 cnt_info->text.plain = buf;
3096 PARAMETER *param = NULL;
3098 param = body->parameter;
3101 if (!strcasecmp(param->attribute, "CHARSET")) {
3102 cnt_info->text.plain_charset = EM_SAFE_STRDUP(param->value);
3105 param = param->next;
3108 else if (body->id || body->location || body->disposition.type) {
3110 if (emcore_get_file_pointer(body, false, filename, cnt_info , &err)<0) {
3111 EM_DEBUG_EXCEPTION("emcore_get_file_pointer failed [%d]", err);
3115 /* Search info from attachment list followed by inline attachment list */
3117 ai = cnt_info->file;
3118 EM_DEBUG_LOG("ai - %p ", (ai));
3120 /* For Inline content append to the end */
3121 for (i = 1; ai; ai = ai->next, i++) {
3122 if (ai->save == NULL && (ai->content_id != NULL && !strcmp(ai->content_id, body->id))) {
3123 EM_DEBUG_LOG("Found matching details ");
3130 FINISH_OFF_IF_CANCELED;
3132 if (cnt_info->grab_type == GRAB_TYPE_ATTACHMENT) {
3133 if (!emstorage_notify_network_event(NOTI_DOWNLOAD_ATTACH_START, mail_id, buf, cnt_info->file_no, 0))
3134 EM_DEBUG_EXCEPTION(" emstorage_notify_network_event [ NOTI_DOWNLOAD_ATTACH_START] Failed >>>> ");
3136 _imap4_download_noti_interval_value = body_size *DOWNLOAD_NOTI_INTERVAL_PERCENT / 100;
3137 _imap4_total_body_size = body_size;
3140 if (multi_part_body_size) {
3141 EM_DEBUG_LOG("Multipart body size is [%d]", multi_part_body_size);
3142 if (!emstorage_notify_network_event(NOTI_DOWNLOAD_MULTIPART_BODY, mail_id, buf, multi_part_body_size, 0))
3143 EM_DEBUG_EXCEPTION(" emstorage_notify_network_event [ NOTI_DOWNLOAD_BODY_START] Failed >>>> ");
3145 _imap4_download_noti_interval_value = multi_part_body_size *DOWNLOAD_NOTI_INTERVAL_PERCENT / 100;
3148 if (!emstorage_notify_network_event(NOTI_DOWNLOAD_BODY_START, mail_id, buf, body_size, 0))
3149 EM_DEBUG_EXCEPTION(" emstorage_notify_network_event [ NOTI_DOWNLOAD_BODY_START] Failed >>>> ");
3151 _imap4_download_noti_interval_value = body_size *DOWNLOAD_NOTI_INTERVAL_PERCENT / 100;
3152 _imap4_total_body_size = body_size;
3157 if (_imap4_download_noti_interval_value > DOWNLOAD_NOTI_INTERVAL_SIZE) {
3158 _imap4_download_noti_interval_value = DOWNLOAD_NOTI_INTERVAL_SIZE;
3161 /* EM_SAFE_FREE(file_id) */
3162 /* notifying UI end */
3164 if (body_size < DOWNLOAD_MAX_BUFFER_SIZE) {
3165 if (net_getbuffer (imaplocal->netstream, (long)body_size, (char *)encoded) <= 0) {
3166 EM_DEBUG_EXCEPTION("net_getbuffer failed...");
3167 err = EMAIL_ERROR_NO_RESPONSE;
3171 if (!emcore_write_response_into_file(buf, "wb+", (char *)encoded, encoding, body->subtype, account_id, mail_id, &err)) {
3172 EM_DEBUG_EXCEPTION("write_response_into_file failed [%d]", err);
3177 EM_DEBUG_LOG("total = %d", total);
3178 EM_DEBUG_LOG("write_response_into_file successful %s.....", buf);
3180 total = _imap4_received_body_size = strlen((char *)encoded);
3182 EM_DEBUG_LOG("_imap4_last_notified_body_size [%d]", _imap4_last_notified_body_size);
3183 EM_DEBUG_LOG("_imap4_download_noti_interval_value [%d]", _imap4_download_noti_interval_value);
3184 EM_DEBUG_LOG("_imap4_received_body_size [%d]", _imap4_received_body_size);
3185 EM_DEBUG_LOG("_imap4_total_body_size [%d] ", _imap4_total_body_size);
3187 if (((_imap4_last_notified_body_size + _imap4_download_noti_interval_value) <= _imap4_received_body_size)
3188 || (_imap4_received_body_size >= _imap4_total_body_size)) /* 100 */ {
3189 /* In some situation, total_encoded_len includes the length of dummy bytes. So it might be greater than body_size */
3192 if (total > body_size)
3193 gap = total - body_size;
3194 _imap4_received_body_size -= gap;
3195 _imap4_last_notified_body_size = _imap4_received_body_size;
3196 if (_imap4_total_body_size)
3197 imap4_total_body_download_progress = 100*_imap4_received_body_size/_imap4_total_body_size;
3199 imap4_total_body_download_progress = _imap4_received_body_size;
3201 EM_DEBUG_LOG("3 : body_size %d", body_size);
3204 progress = 100*total/body_size;
3206 progress = body_size;
3208 EM_DEBUG_LOG("DOWNLOADING STATUS NOTIFY : Encoded[%d] / [%d] = %d %% Completed. -- Total Decoded[%d]", total, body_size, progress, total);
3209 EM_DEBUG_LOG("DOWNLOADING STATUS NOTIFY : Total[%d] / [%d] = %d %% Completed.", _imap4_received_body_size, _imap4_total_body_size, imap4_total_body_download_progress);
3211 if (cnt_info->grab_type == GRAB_TYPE_ATTACHMENT) {
3212 if (!emstorage_notify_network_event(NOTI_DOWNLOAD_ATTACH_START, mail_id, buf, cnt_info->file_no, imap4_total_body_download_progress))
3213 EM_DEBUG_EXCEPTION(" emstorage_notify_network_event [ NOTI_DOWNLOAD_ATTACH_START] Failed >>>> ");
3216 if (multi_part_body_size) {
3217 /* EM_DEBUG_LOG("DOWNLOADING.......... : Multipart body size is [%d]", multi_part_body_size) */
3218 if (!emstorage_notify_network_event(NOTI_DOWNLOAD_MULTIPART_BODY, mail_id, buf, _imap4_total_body_size, _imap4_received_body_size))
3219 EM_DEBUG_EXCEPTION(" emstorage_notify_network_event [ NOTI_DOWNLOAD_BODY_START] Failed >>>> ");
3222 if (!emstorage_notify_network_event(NOTI_DOWNLOAD_BODY_START, mail_id, buf, _imap4_total_body_size, _imap4_received_body_size))
3223 EM_DEBUG_EXCEPTION(" emstorage_notify_network_event [ NOTI_DOWNLOAD_BODY_START] Failed >>>>");
3225 } /* if (is_attachment) .. else .. */
3232 int temp_body_size = body_size;
3235 if (encoding == ENCBASE64)
3236 x = (sizeof(encoded)/78) *78; /* to solve base64 decoding pro */
3238 x = sizeof(encoded)-1;
3240 memset(test_buffer, 0x00, sizeof(test_buffer));
3241 while (temp_body_size && (total <body_size)) {
3243 memset(test_buffer, 0x00, sizeof(test_buffer));
3244 while ((total != body_size) && temp_body_size && ((strlen((char *)test_buffer) + x) < sizeof(test_buffer))) {
3245 memset(encoded, 0x00, sizeof(encoded));
3247 if (net_getbuffer (imaplocal->netstream, (long)x, (char *)encoded) <= 0) {
3248 EM_DEBUG_EXCEPTION("net_getbuffer failed...");
3249 err = EMAIL_ERROR_NO_RESPONSE;
3254 temp_body_size = temp_body_size - x;
3255 strncat((char *)test_buffer, (char *)encoded, strlen((char *)encoded));
3257 _imap4_received_body_size += strlen((char *)encoded);
3259 EM_DEBUG_LOG("total = %d", total);
3261 if ( !(temp_body_size/x) && temp_body_size%x)
3262 x = temp_body_size%x;
3264 EM_DEBUG_LOG(" _imap4_last_notified_body_size - %d ", _imap4_last_notified_body_size);
3265 EM_DEBUG_LOG(" _imap4_download_noti_interval_value - %d ", _imap4_download_noti_interval_value);
3266 EM_DEBUG_LOG(" _imap4_received_body_size - %d ", _imap4_received_body_size);
3267 EM_DEBUG_LOG(" _imap4_received_body_size - %d ", _imap4_received_body_size);
3268 EM_DEBUG_LOG(" _imap4_total_body_size - %d ", _imap4_total_body_size);
3270 if (_imap4_total_body_size)
3271 imap4_total_body_download_progress = 100*_imap4_received_body_size/_imap4_total_body_size;
3273 imap4_total_body_download_progress = _imap4_received_body_size;
3275 if (((_imap4_last_notified_body_size + _imap4_download_noti_interval_value) <= _imap4_received_body_size)
3276 || (_imap4_received_body_size >= _imap4_total_body_size)) /* 100 */ {
3277 /* In some situation, total_encoded_len includes the length of dummy bytes. So it might be greater than body_size */
3279 if (total > body_size)
3280 gap = total - body_size;
3281 _imap4_received_body_size -= gap;
3282 _imap4_last_notified_body_size = _imap4_received_body_size;
3285 progress = 100*total/body_size;
3287 progress = body_size;
3289 EM_DEBUG_LOG("DOWNLOADING STATUS NOTIFY : Encoded[%d] / [%d] = %d %% Completed. -- Total Decoded[%d]", total, body_size, progress, total);
3290 EM_DEBUG_LOG("DOWNLOADING STATUS NOTIFY : Total[%d] / [%d] = %d %% Completed.", _imap4_received_body_size, _imap4_total_body_size, imap4_total_body_download_progress);
3292 if (cnt_info->grab_type == GRAB_TYPE_ATTACHMENT) {
3293 if (!emstorage_notify_network_event(NOTI_DOWNLOAD_ATTACH_START, mail_id, buf, cnt_info->file_no, imap4_total_body_download_progress))
3294 EM_DEBUG_EXCEPTION(" emstorage_notify_network_event [ NOTI_DOWNLOAD_ATTACH_START] Failed >>>> ");
3297 if (multi_part_body_size) {
3298 /* EM_DEBUG_LOG("DOWNLOADING.......... : Multipart body size is [%d]", multi_part_body_size) */
3299 if (!emstorage_notify_network_event(NOTI_DOWNLOAD_MULTIPART_BODY, mail_id, buf, _imap4_total_body_size, _imap4_received_body_size))
3300 EM_DEBUG_EXCEPTION(" emstorage_notify_network_event [ NOTI_DOWNLOAD_BODY_START] Failed >>>> ");
3303 if (!emstorage_notify_network_event(NOTI_DOWNLOAD_BODY_START, mail_id, buf, _imap4_total_body_size, _imap4_received_body_size))
3304 EM_DEBUG_EXCEPTION(" emstorage_notify_network_event [ NOTI_DOWNLOAD_BODY_START] Failed >>>>");
3306 } /* if (is_attachment) .. else .. */
3310 if (flag_first_write == 1) {
3311 if (!emcore_write_response_into_file(buf, "wb+", (char *)test_buffer, encoding, body->subtype, account_id, mail_id, &err)) {
3312 EM_DEBUG_EXCEPTION("write_response_into_file %s failed [%d]", buf, err);
3316 flag_first_write = 0;
3319 if (!emcore_write_response_into_file(buf, "ab+", (char *)test_buffer, encoding, body->subtype, account_id, mail_id, &err)) /* append */ {
3320 EM_DEBUG_EXCEPTION("write_response_into_file %s failed [%d]", buf, err);
3325 EM_DEBUG_LOG("%d has been written", strlen((char *)test_buffer));
3329 else if (!strncmp(response, tag, strlen(tag))) /* end of respons */ {
3330 if (!strncmp(response + strlen(tag) + 1, "OK", 2))
3331 EM_SAFE_FREE(response);
3332 else /* 'NO' or 'BAD */ {
3333 err = EMAIL_ERROR_IMAP4_FETCH_UID_FAILURE;
3340 else if (!strcmp(response, ")")) {
3355 EM_SAFE_FREE(response);
3357 return return_value;
3360 static int _find_duplicated_inline_content_file(char *input_source_file_name, struct _m_content_info *input_content_info, bool *output_result)
3362 EM_DEBUG_FUNC_BEGIN("input_source_file_name [%p], input_content_info [%p], output_result [%p]", input_source_file_name,input_content_info, output_result);
3363 struct attachment_info *cur_attachment_info = NULL;
3364 int err = EMAIL_ERROR_NONE;
3365 bool result = false;
3367 if(!input_source_file_name || !input_content_info || !output_result) {
3368 EM_DEBUG_EXCEPTION("Invalid parameter");
3369 return EMAIL_ERROR_INVALID_PARAM;
3372 cur_attachment_info = input_content_info->file;
3374 while(cur_attachment_info) {
3375 if(strcmp(input_source_file_name, cur_attachment_info->name) == 0) {
3379 cur_attachment_info = cur_attachment_info->next;
3382 *output_result = result;
3384 EM_DEBUG_FUNC_END("err [%d], result [%d]", err, result);
3388 static int _modify_file_name_string_for_duplicated_inline_content(char *input_source_file_name, struct _m_content_info *input_content_info)
3390 EM_DEBUG_FUNC_BEGIN("input_source_file_name [%p], input_content_info [%p]", input_source_file_name,input_content_info);
3391 int err = EMAIL_ERROR_NONE;
3392 char temp_file_name[MAX_PATH] = { 0, };
3393 char *file_name = NULL;
3394 char *extension = NULL;
3396 if(!input_source_file_name || !input_content_info) {
3397 EM_DEBUG_EXCEPTION("Invalid parameter");
3398 return EMAIL_ERROR_INVALID_PARAM;
3401 if ( (err = em_get_file_name_and_extension_from_file_path(input_source_file_name, &file_name, &extension)) != EMAIL_ERROR_NONE) {
3402 EM_DEBUG_EXCEPTION("em_get_file_name_and_extension_from_file_path failed [%d]", err);
3406 if(file_name && extension)
3407 SNPRINTF(temp_file_name, MAX_PATH, "%s_.%s", file_name, extension);
3409 SNPRINTF(temp_file_name, MAX_PATH, "%s_", file_name);
3411 EM_SAFE_STRCPY(input_source_file_name, temp_file_name);
3415 EM_SAFE_FREE(file_name);
3416 EM_SAFE_FREE(extension);
3418 EM_DEBUG_FUNC_END("err [%d], temp_file_name [%s]", err, temp_file_name);
3422 static int emcore_get_file_pointer(BODY *body, bool input_check_duplicated_file_name, char *output_file_name_string, struct _m_content_info *cnt_info , int *err)
3424 EM_DEBUG_FUNC_BEGIN();
3426 char *decoded_filename = NULL;
3427 char attachment_file_name[MAX_PATH] = { 0, };
3428 char attachment_file_name_source[MAX_PATH] = {0, };
3429 int error = EMAIL_ERROR_NONE;
3430 bool file_name_duplicated = false;
3432 if ((body->type == TYPETEXT) && (body->disposition.type == NULL)) {
3433 EM_DEBUG_LOG("body->type == TYPETEXT");
3435 EM_DEBUG_EXCEPTION("But, cnt_info is null");
3436 error = EMAIL_ERROR_INVALID_PARAM;
3439 if (body->subtype[0] == 'H') {
3440 if (cnt_info->text.plain_charset != NULL) {
3441 memcpy(output_file_name_string, cnt_info->text.plain_charset, strlen(cnt_info->text.plain_charset));
3442 strcat(output_file_name_string, HTML_EXTENSION_STRING);
3445 memcpy(output_file_name_string, "UTF-8.htm", strlen("UTF-8.htm"));
3447 cnt_info->text.html = EM_SAFE_STRDUP(output_file_name_string);
3450 PARAMETER *param = body->parameter;
3451 char charset_string[512];
3453 if (emcore_get_attribute_value_of_body_part(param, "CHARSET", charset_string, 512, false, &error)) {
3454 cnt_info->text.plain_charset = EM_SAFE_STRDUP(charset_string);
3455 memcpy(output_file_name_string, cnt_info->text.plain_charset, strlen(cnt_info->text.plain_charset));
3458 memcpy(output_file_name_string, "UTF-8", strlen("UTF-8"));
3460 cnt_info->text.plain = EM_SAFE_STRDUP(output_file_name_string);
3464 else if ((body->id != NULL) || ((body->disposition.type != NULL) && ((body->disposition.type[0] == 'i') || (body->disposition.type[0] == 'I')))) {
3465 /* body id is exising or disposition type is inline */
3467 if (body->parameter) /* Get actual name of file */ {
3468 PARAMETER *param_body = body->parameter;
3469 if (!emcore_get_attribute_value_of_body_part(param_body, "NAME", attachment_file_name_source, MAX_PATH, true, &error))
3470 emcore_get_attribute_value_of_body_part(param_body, "CHARSET", attachment_file_name_source, MAX_PATH, true, &error);
3471 if (!emcore_make_attachment_file_name_with_extension(attachment_file_name_source, body->subtype, attachment_file_name, MAX_PATH, &error)) {
3472 EM_DEBUG_EXCEPTION("emcore_make_attachment_file_name_with_extension failed [%d]", error);
3476 else if (body->disposition.type) {
3477 PARAMETER *param_disposition = body->disposition.parameter;
3478 EM_DEBUG_LOG("body->disposition.type exist");
3479 emcore_get_attribute_value_of_body_part(param_disposition, "filename", attachment_file_name_source, MAX_PATH, true, &error);
3480 if (!emcore_make_attachment_file_name_with_extension(attachment_file_name_source, body->subtype, attachment_file_name, MAX_PATH, &error)) {
3481 EM_DEBUG_EXCEPTION("emcore_make_attachment_file_name_with_extension failed [%d]", error);
3485 else { /* body id is not null but disposition type is null */
3486 if ((body->id[0] == '<'))
3487 SNPRINTF(attachment_file_name, MAX_PATH, "%s", body->id+1); /* fname = em_parse_filename(body->id + 1 */
3489 SNPRINTF(attachment_file_name, MAX_PATH, "%s", body->id); /* fname = em_parse_filename(body->id */
3491 len = strlen(attachment_file_name);
3493 if ((len > 1) && (attachment_file_name[len-1] == '>'))
3494 attachment_file_name[len - 1] = '\0';
3495 decoded_filename = emcore_decode_rfc2047_text(attachment_file_name, &error);
3497 EM_DEBUG_LOG("attachment_file_name [%s]", attachment_file_name);
3498 if (decoded_filename != NULL)
3499 memcpy(output_file_name_string, decoded_filename, strlen(decoded_filename));
3501 memcpy(output_file_name_string, attachment_file_name, strlen(attachment_file_name));
3504 else if (body->disposition.type != NULL) { /* disposition type is existing and not inline and body_id is nul */
3505 PARAMETER *param = body->parameter;
3506 if (!emcore_get_attribute_value_of_body_part(param, "NAME", attachment_file_name, MAX_PATH, true, &error))
3507 emcore_get_attribute_value_of_body_part(param, "FILENAME", attachment_file_name, MAX_PATH, true, &error);
3508 memcpy(output_file_name_string, attachment_file_name, strlen(attachment_file_name));
3511 if(input_check_duplicated_file_name) {
3512 if ( (error = _find_duplicated_inline_content_file(output_file_name_string, cnt_info, &file_name_duplicated)) != EMAIL_ERROR_NONE) {
3513 EM_DEBUG_EXCEPTION("_find_duplicated_inline_content_file failed [%d]", error);
3517 if (file_name_duplicated == true) {
3518 if ( ( error = _modify_file_name_string_for_duplicated_inline_content(output_file_name_string, cnt_info)) != EMAIL_ERROR_NONE) {
3519 EM_DEBUG_EXCEPTION("_modify_file_name_string_for_duplicated_inline_content failed [%d]", error);
3527 EM_SAFE_FREE(decoded_filename);
3532 EM_DEBUG_FUNC_END("output_file_name_string[%s], error [%d]", output_file_name_string, error);
3537 static PARTLIST *emcore_add_node(PARTLIST *section_list, BODY *body)
3539 PARTLIST *temp = (PARTLIST *)malloc(sizeof(PARTLIST));
3542 EM_DEBUG_EXCEPTION("PARTLIST node creation failed");
3548 if (section_list == NULL)/* first node in lis */ {
3549 section_list = temp;
3551 else/* has min 1 nod */ {
3552 PARTLIST *t = section_list;
3553 while (t->next != NULL) /* go to last nod */ {
3554 t = (PARTLIST *) t->next;
3556 t->next = (PART *)temp;/* I think this should be PARTLIST, but why this is PART */
3558 in imap-2007e/c-client/mail.h
3565 return section_list;
3569 static void emcore_free_section_list(PARTLIST *section_list)
3571 PARTLIST *temp = NULL;
3573 while (section_list != NULL) {
3574 temp = (PARTLIST *)section_list->next;
3575 EM_SAFE_FREE(section_list);
3576 section_list = temp;
3580 static int emcore_get_section_body_size(char *response, char *section, int *body_size)
3585 if ((p = strstr(response, "BODY[")) /* || (p = strstr(s + 1, "BODY["))*/) {
3587 p += strlen("BODY[");
3597 /* if (strcmp(section, p)) {
3598 err = EMAIL_ERROR_INVALID_RESPONSE;
3601 p = strstr(s+1, " {");
3614 /* sending progress noti to application.
3632 static char *em_parse_filename(char *filename)
3634 EM_DEBUG_FUNC_BEGIN("filename [%p] ", filename);
3636 EM_DEBUG_EXCEPTION("filename is NULL ");
3640 char delims[] = "@";
3641 char *result = NULL;
3642 static char parsed_filename[512] = {0, };
3644 memset(parsed_filename, 0x00, 512);
3646 if (!strstr(filename, delims)) {
3647 EM_DEBUG_EXCEPTION("FileName doesnot contain @ ");
3651 result = strtok(filename, delims);
3653 if (strcasestr(result, ".bmp") || strcasestr(result, ".jpeg") || strcasestr(result, ".png") || strcasestr(result, ".jpg"))
3654 sprintf(parsed_filename + strlen(parsed_filename), "%s", result);
3656 sprintf(parsed_filename + strlen(parsed_filename), "%s%s", result, ".jpeg");
3658 EM_DEBUG_LOG(">>> FileName [ %s ] ", result);
3660 EM_DEBUG_FUNC_END("parsed_filename [%s] ", parsed_filename);
3661 return parsed_filename;
3664 #define CONTENT_TYPE_STRING_IN_MIME_HEAEDER "Content-Type:"
3666 INTERNAL_FUNC int emcore_get_content_type_from_mime_string(char *input_mime_string, char **output_content_type)
3668 EM_DEBUG_FUNC_BEGIN("input_mime_string [%p], output_content_type [%p]", input_mime_string, output_content_type);
3670 int err = EMAIL_ERROR_NONE;
3671 int temp_mime_header_string_length = 0;
3672 char result_content_type[256] = { 0, };
3673 char *temp_mime_header_string = NULL;
3674 char *temp_content_type_start = NULL;
3675 char *temp_content_type_end = NULL;
3677 if(input_mime_string == NULL || output_content_type == NULL) {
3678 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
3679 err = EMAIL_ERROR_INVALID_PARAM;
3683 temp_mime_header_string_length = EM_SAFE_STRLEN(input_mime_string);
3684 temp_mime_header_string = input_mime_string;
3686 EM_DEBUG_LOG("temp_mime_header_string [%s]", temp_mime_header_string);
3688 temp_content_type_start = strcasestr(temp_mime_header_string, CONTENT_TYPE_STRING_IN_MIME_HEAEDER);
3690 if(temp_content_type_start == NULL) {
3691 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_DATA");
3692 err = EMAIL_ERROR_INVALID_DATA;
3696 temp_content_type_start += EM_SAFE_STRLEN(CONTENT_TYPE_STRING_IN_MIME_HEAEDER);
3697 temp_content_type_end = temp_content_type_start;
3699 while(temp_content_type_end && temp_content_type_end < (temp_mime_header_string + temp_mime_header_string_length) && *temp_content_type_end != ';')
3700 temp_content_type_end++;
3702 if(temp_content_type_end && *temp_content_type_end == ';') {
3703 if(temp_content_type_end - temp_content_type_start < 256) {
3704 memcpy(result_content_type, temp_content_type_start, temp_content_type_end - temp_content_type_start);
3705 EM_DEBUG_LOG("result_content_type [%s]", result_content_type);
3706 *output_content_type = EM_SAFE_STRDUP(result_content_type);
3707 em_trim_left(*output_content_type);
3711 EM_DEBUG_EXCEPTION("temp_content_type_end - temp_content_type_start [%d]", temp_content_type_end - temp_content_type_start);
3712 err = EMAIL_ERROR_DATA_TOO_LONG;
3720 EM_DEBUG_FUNC_END("err [%d]", err);
3724 #define SUBTYPE_STRING_LENGTH 128
3726 INTERNAL_FUNC int emcore_get_content_type_from_mail_bodystruct(BODY *input_body, int input_buffer_length, char *output_content_type)
3728 EM_DEBUG_FUNC_BEGIN("input_body [%p], input_buffer_length [%d], output_content_type [%p]", input_body, input_buffer_length, output_content_type);
3729 int err = EMAIL_ERROR_NONE;
3730 char subtype_string[SUBTYPE_STRING_LENGTH] = { 0 , };
3732 if(input_body == NULL || output_content_type == NULL || input_buffer_length == 0) {
3733 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
3734 err = EMAIL_ERROR_INVALID_PARAM;
3738 EM_SAFE_STRNCPY(subtype_string, input_body->subtype, SUBTYPE_STRING_LENGTH);
3739 em_lower_string(subtype_string);
3741 switch(input_body->type) {
3743 SNPRINTF(output_content_type, input_buffer_length, "text/%s", subtype_string);
3745 case TYPEMULTIPART :
3746 SNPRINTF(output_content_type, input_buffer_length, "multipart/%s", subtype_string);
3749 SNPRINTF(output_content_type, input_buffer_length, "message/%s", subtype_string);
3751 case TYPEAPPLICATION :
3752 SNPRINTF(output_content_type, input_buffer_length, "application/%s", subtype_string);
3755 SNPRINTF(output_content_type, input_buffer_length, "audio/%s", subtype_string);
3758 SNPRINTF(output_content_type, input_buffer_length, "image/%s", subtype_string);
3761 SNPRINTF(output_content_type, input_buffer_length, "video/%s", subtype_string);
3764 SNPRINTF(output_content_type, input_buffer_length, "model/%s", subtype_string);
3767 SNPRINTF(output_content_type, input_buffer_length, "other/%s", subtype_string);
3770 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
3771 err = EMAIL_ERROR_INVALID_PARAM;
3776 EM_DEBUG_LOG("output_content_type [%s]", output_content_type);
3780 EM_DEBUG_FUNC_END("err [%d]", err);
3784 INTERNAL_FUNC int emcore_get_attribute_value_of_body_part(PARAMETER *input_param, char *atribute_name, char *output_value, int output_buffer_length, int with_rfc2047_text, int *err_code)
3786 EM_DEBUG_FUNC_BEGIN("input_param [%p], atribute_name [%s], output_buffer_length [%d], with_rfc2047_text [%d]", input_param, atribute_name, output_buffer_length, with_rfc2047_text);
3787 PARAMETER *temp_param = input_param;
3788 char *decoded_value = NULL, *result_value = NULL;
3789 int ret = false, err = EMAIL_ERROR_NONE;
3792 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
3793 err = EMAIL_ERROR_INVALID_PARAM;
3797 memset(output_value, 0, output_buffer_length);
3799 while (temp_param) {
3800 EM_DEBUG_LOG("temp_param->attribute [%s]", temp_param->attribute);
3801 if (!strcasecmp(temp_param->attribute, atribute_name)) {
3802 EM_DEBUG_LOG("temp_param->value [%s]", temp_param->value);
3803 if (temp_param->value) {
3804 if (with_rfc2047_text) {
3805 decoded_value = emcore_decode_rfc2047_text(temp_param->value, &err);
3807 result_value = decoded_value;
3809 result_value = decoded_value;
3812 result_value = temp_param->value;
3815 EM_DEBUG_EXCEPTION("EMAIL_ERROR_DATA_NOT_FOUND");
3816 err = EMAIL_ERROR_DATA_NOT_FOUND;
3819 EM_DEBUG_LOG("result_value [%s]", result_value);
3821 if(output_buffer_length > strlen(result_value)) {
3822 strncpy(output_value, result_value, output_buffer_length);
3823 output_value[strlen(result_value)] = NULL_CHAR;
3827 EM_DEBUG_EXCEPTION("buffer is too short");
3828 err = EMAIL_ERROR_DATA_TOO_LONG;
3835 temp_param = temp_param->next;
3839 EM_SAFE_FREE(decoded_value);
3844 EM_DEBUG_FUNC_END("ret [%d]", ret);
3850 *download body part of imap mail (body-text and attachment)
3852 static int emcore_get_body_part_imap(MAILSTREAM *stream, int account_id, int mail_id, int msg_uid, BODY *body, struct _m_content_info *cnt_info, int *err_code)
3854 EM_DEBUG_FUNC_BEGIN("stream[%p], msg_uid[%d], body[%p], cnt_info[%p], err_code[%p]", stream, msg_uid, body, cnt_info, err_code);
3856 int err = EMAIL_ERROR_NONE, ret = -1;
3857 struct attachment_info **ai;
3858 struct attachment_info *prev_ai = NULL;
3859 struct attachment_info *next_ai = NULL;
3860 char *savefile = NULL;
3861 char *o_data = NULL;
3862 char filename[MAX_PATH + 1] = { 0, };
3863 char *decoded_filename = NULL;
3864 int is_attachment = 0;
3866 char *filename_temp = NULL;
3867 char charset_value_buffer[512] = { 0, };
3868 char content_type_buffer[512] = { 0, };
3873 char *sparep = NULL;
3874 unsigned short encode = 0;
3875 int section_plain = 0;
3876 int section_html = 0;
3877 int is_pbd = (account_id == 0 && mail_id == 0) ? true : false;
3880 EM_DEBUG_LOG("Grab Type [ %d ] ", cnt_info->grab_type);
3883 if (body->type > TYPEOTHER) { /* unknown type */
3884 EM_DEBUG_EXCEPTION("Unknown type.");
3885 err = EMAIL_ERROR_NOT_SUPPORTED;
3889 if (NULL == body->subtype) {
3890 EM_DEBUG_LOG("body->subtype is null. "); /* not exceptional case */
3891 if (err_code != NULL)
3892 *err_code = EMAIL_ERROR_INVALID_PARAM;
3897 if (!emcore_get_temp_file_name(&o_data, &err) || !o_data) {
3898 EM_DEBUG_EXCEPTION("emcore_get_temp_file_name failed [%d]", err);
3899 if (err_code != NULL)
3905 if (body->subtype[0] == 'P') { /* Sub type is PLAIN_TEX */
3906 if (cnt_info->text.plain != NULL)
3907 EM_SAFE_FREE(o_data);
3910 if (body->type == TYPETEXT && body->subtype &&
3911 (!body->disposition.type || (body->disposition.type && (body->disposition.type[0] == 'i' || body->disposition.type[0] == 'I')))) {
3912 if (body->subtype[0] == 'H') /* HTM */
3913 cnt_info->text.html = o_data;
3915 cnt_info->text.plain = o_data;
3917 memset(charset_value_buffer, 0, 512);
3919 if (emcore_get_attribute_value_of_body_part(body->parameter, "CHARSET", charset_value_buffer, 512, true, &err)) {
3920 cnt_info->text.plain_charset = EM_SAFE_STRDUP(charset_value_buffer);
3921 EM_DEBUG_LOG(">>>>> CHARSET [%s] ", filename);
3926 if ((body->id) && strlen(body->id) > 1) { /* if Content-ID or Content-Location exists, it is inline contents */
3927 EM_DEBUG_LOG("body->id exist");
3929 /* Get actual name of file - fix for inline images to be stored with actual names and not .jpeg */
3930 if (body->parameter) {
3931 PARAMETER *param1 = body->parameter;
3933 EM_DEBUG_LOG("param1->attribute - %s ", param1->attribute);
3934 if (!strcasecmp(param1->attribute, "NAME")) { /* attribute is "NAME" */
3935 char *extcheck = NULL;
3937 if (param1->value) {
3938 decoded_filename = emcore_decode_rfc2047_text(param1->value, &err);
3939 strncpy(filename, decoded_filename, MAX_PATH);
3940 EM_SAFE_FREE(decoded_filename);
3942 EM_DEBUG_LOG(">>>>> FILENAME [%s] ", filename);
3943 extcheck = strchr(filename, '.');
3946 EM_DEBUG_LOG(">>>> Extension Exist in the Attachment [ %s ] ", extcheck);
3947 else /* No extension attached , So add the Extension based on the subtyp */ {
3948 if (body->subtype) {
3949 strcat(filename, ".");
3950 strcat(filename, body->subtype);
3951 EM_DEBUG_LOG(">>>>> FILENAME Identified the Extension [%s] ", filename);
3954 EM_DEBUG_EXCEPTION("UnKnown Extesnsion : _ (");
3960 param1 = param1->next;
3964 else if (body->disposition.type) {
3965 PARAMETER *param = body->disposition.parameter;
3968 EM_DEBUG_LOG(">>>>> body->disposition.parameter->attribute [ %s ] ", param->attribute);
3969 EM_DEBUG_LOG(">>>>> body->disposition.parameter->value [ %s ] ", param->value);
3971 /* attribute is "filename" */
3972 if (!strcasecmp(param->attribute, "filename")) {
3973 decoded_filename = emcore_decode_rfc2047_text(param->value, &err);
3974 strncpy(filename, decoded_filename, MAX_PATH);
3975 EM_SAFE_FREE(decoded_filename);
3976 EM_DEBUG_LOG(">>>>> FILENAME [%s] ", filename);
3980 param = param->next;
3984 if ((body->id[0] == '<'))
3985 SNPRINTF(filename, MAX_PATH, "%s", body->id+1);
3987 SNPRINTF(filename, MAX_PATH, "%s", body->id);
3989 len = strlen(filename);
3991 if ((len > 1) && (filename[len-1] == '>'))
3992 filename[len-1] = '\0';
3994 /* is_attachment = 1; */
3997 else if (body->location) {
3998 EM_DEBUG_LOG("body->location exist");
4000 decoded_filename = emcore_decode_rfc2047_text(body->location, &err);
4001 strncpy(filename, decoded_filename, MAX_PATH);
4002 EM_SAFE_FREE(decoded_filename);
4003 EM_DEBUG_LOG("body->location [%s]", body->location);
4005 else if (is_pbd && (strncmp(body->subtype, "RFC822", strlen("RFC822")) == 0) && (cnt_info->grab_type == 0 || (cnt_info->grab_type & GRAB_TYPE_ATTACHMENT))) {
4006 EM_DEBUG_LOG("Beause subtype is RFC822. This is ttachment");
4009 if (cnt_info->grab_type == 0) {
4010 if ((body->nested.msg != NULL) && (body->nested.msg->env != NULL) && (body->nested.msg->env->subject != NULL)) {
4011 decoded_filename = emcore_decode_rfc2047_text(body->nested.msg->env->subject, &err);
4012 strncpy(filename, decoded_filename, MAX_PATH);
4013 EM_SAFE_FREE(decoded_filename);
4016 strncpy(filename, "Unknown <message/rfc822>", MAX_PATH);
4018 else if (cnt_info->grab_type & GRAB_TYPE_ATTACHMENT) {
4019 BODY *temp_body = NULL;
4020 if (body->nested.msg->env->subject != NULL) {
4022 int subject_count = 0;
4023 if (g_str_has_prefix(body->nested.msg->env->subject, "= ? ") && g_str_has_suffix(body->nested.msg->env->subject, " ? = "))
4024 strncpy(filename, "unknown", MAX_PATH);
4026 for (subject_count = 0; body->nested.msg->env->subject[subject_count] != '\0' ; subject_count++) {
4027 if (body->nested.msg->env->subject[subject_count] != ':' &&
4028 body->nested.msg->env->subject[subject_count] != ';' &&
4029 body->nested.msg->env->subject[subject_count] != '*' &&
4030 body->nested.msg->env->subject[subject_count] != '?' &&
4031 body->nested.msg->env->subject[subject_count] != '\"' &&
4032 body->nested.msg->env->subject[subject_count] != '<' &&
4033 body->nested.msg->env->subject[subject_count] != '>' &&
4034 body->nested.msg->env->subject[subject_count] != '|' &&
4035 body->nested.msg->env->subject[subject_count] != '/') {
4036 filename[i] = body->nested.msg->env->subject[subject_count];
4045 strncpy(filename, "Unknown", MAX_PATH);
4047 body = ((MESSAGE *)body->nested.msg)->body;
4048 part = body->nested.part;
4050 if ((body->subtype[0] == 'P') || (body->subtype[0] == 'H'))
4052 else if (part != NULL) {
4053 temp_body = &(part->body);
4054 if ((temp_body->subtype[0] == 'P' || temp_body->subtype[0] == 'H') && part->next != NULL) {
4056 temp_body = &(part->body);
4061 if (temp_body->subtype[0] == 'P')
4063 else if (temp_body->subtype[0] == 'H')
4066 sparep = temp_body->sparep;
4067 encode = temp_body->encoding;
4072 else if (body->disposition.type) /* if disposition exists, get filename from disposition parameter */ { /* "attachment" or "inline" or etc.. */
4073 EM_DEBUG_LOG("body->disposition.type exist");
4076 if (emcore_get_attribute_value_of_body_part(body->disposition.parameter, "filename", filename, MAX_PATH, true, &err))
4077 EM_DEBUG_LOG(">>>>> FILENAME [%s] ", filename);
4079 if (!*filename) { /* If the part has no filename, it may be report ms */
4080 if ((body->disposition.type[0] == 'i' || body->disposition.type[0] == 'I') && body->parameter && body->parameter->attribute && strcasecmp(body->parameter->attribute, "NAME"))
4082 else if (body->parameter) /* Fix for the MMS attachment File name as unknown */ {
4083 char *extcheck = NULL;
4085 if (emcore_get_attribute_value_of_body_part(body->parameter, "NAME", filename, MAX_PATH, true, &err))
4086 EM_DEBUG_LOG("NAME [%s] ", filename);
4088 extcheck = strchr(filename, '.');
4091 EM_DEBUG_LOG(">>>> Extension Exist in the Attachment [ %s ] ", extcheck);
4092 else { /* No extension attached , So add the Extension based on the subtype */
4093 if (body->subtype) {
4094 if (strlen(filename) + strlen(body->subtype) + 1 < MAX_PATH) {
4095 strcat(filename, ".");
4096 strcat(filename, body->subtype);
4098 EM_DEBUG_LOG(">>>>> FILENAME Identified the Extension [%s] ", filename);
4101 EM_DEBUG_EXCEPTION("UnKnown Extesnsion : _ (");
4106 strncpy(filename, "unknown", MAX_PATH);
4109 if ((body->disposition.type[0] == 'i' || body->disposition.type[0] == 'I'))
4114 /* if (!is_pbd) */ {
4115 EM_DEBUG_LOG("filename [%s]", filename);
4117 decoded_filename = emcore_decode_rfc2047_text(filename, &err);
4118 strncpy(filename, decoded_filename, MAX_PATH);
4119 EM_SAFE_FREE(decoded_filename);
4120 filename_temp = em_parse_filename(filename);
4121 if (filename_temp) {
4122 strncpy(filename, filename_temp, MAX_PATH);
4123 EM_DEBUG_LOG("filename [%s]", filename);
4127 EM_DEBUG_LOG("is_attachment [%d]", is_attachment);
4129 if (!is_attachment) { /* Text or RFC822 Message */
4130 EM_DEBUG_LOG("Multipart is not attachment, body->type = %d", body->type);
4131 if ((cnt_info->grab_type & GRAB_TYPE_TEXT) && (body->type == TYPEMESSAGE || body->type == TYPETEXT || body->type == TYPEIMAGE)) {
4134 else { /* fetch body */
4135 if (!emcore_get_temp_file_name(&o_data, &err)) {
4136 EM_DEBUG_EXCEPTION("emcore_get_temp_file_name failed [%d]", err);
4140 if (!imap_mail_write_body_to_file(stream, account_id, mail_id, 0, o_data, msg_uid, body->sparep, body->encoding, &o_data_len, body->subtype, &err)) {
4141 EM_DEBUG_EXCEPTION("imap_mail_write_body_to_file failed [%d]", err);
4147 switch (body->type) {
4149 EM_DEBUG_LOG("TYPETEXT");
4150 if (body->subtype[0] == 'H')
4151 cnt_info->text.html = o_data;
4153 cnt_info->text.plain = o_data;
4154 memset(charset_value_buffer, 0, 512);
4155 if (emcore_get_attribute_value_of_body_part(body->parameter, "CHARSET", charset_value_buffer, 512, true, &err))
4156 cnt_info->text.plain_charset = EM_SAFE_STRDUP(charset_value_buffer);
4160 case TYPEAPPLICATION:
4163 /* Inline Content - suspect of crash on partial body download */
4165 EM_DEBUG_LOG("TYPEIMAGE or TYPEAPPLICATION : inline content");
4166 ai = &(cnt_info->file);
4168 dec_len = body->size.bytes;
4169 if ((cnt_info->grab_type & GRAB_TYPE_ATTACHMENT) &&
4170 (cnt_info->grab_type & GRAB_TYPE_TEXT)) { /* it is 'download all */
4171 only_body_download = false;
4172 cnt_info->file_no = 1;
4175 /* add attachment info to content info */
4176 if (!(*ai = em_malloc(sizeof(struct attachment_info)))) {
4177 EM_DEBUG_EXCEPTION("em_malloc failed...");
4178 if (err_code != NULL)
4179 *err_code = EMAIL_ERROR_OUT_OF_MEMORY;
4183 if (((body->id) || (body->location)) && body->type == TYPEIMAGE)
4184 (*ai)->type = 1; /* inline */
4186 (*ai)->type = 2; /* attachment */
4188 (*ai)->name = EM_SAFE_STRDUP(filename);
4189 (*ai)->size = body->size.bytes;
4190 (*ai)->save = o_data;
4191 (*ai)->content_id = EM_SAFE_STRDUP(body->id);
4193 memset(content_type_buffer, 0, 512);
4194 if ( (err = emcore_get_content_type_from_mail_bodystruct(body, 512, content_type_buffer) ) == EMAIL_ERROR_NONE)
4195 (*ai)->attachment_mime_type = EM_SAFE_STRDUP(content_type_buffer);
4197 EM_DEBUG_LOG("name[%s], size[%d], save[%s], content_id[%s], content_type_buffer [%s]", cnt_info->file->name, cnt_info->file->size, cnt_info->file->save, content_type_buffer);
4198 #ifdef __ATTACHMENT_OPTI__
4199 (*ai)->encoding = body->encoding;
4201 (*ai)->section = EM_SAFE_STRDUP(body->sparep);
4202 EM_DEBUG_LOG(" Encoding - %d Section No - %s ", (*ai)->encoding, (*ai)->section);
4207 case TYPEMESSAGE: /* RFC822 Message */
4208 EM_DEBUG_EXCEPTION("MESSAGE/RFC822");
4209 err = EMAIL_ERROR_NOT_SUPPORTED;
4213 EM_DEBUG_EXCEPTION("Unknown type. body->type [%d]", body->type);
4214 err = EMAIL_ERROR_NOT_SUPPORTED;
4218 stream->text.data = NULL; /* ? ? ? ? ? ? ? ? */
4220 else { /* Attachment */
4223 ai = &cnt_info->file;
4224 EM_DEBUG_LOG(" ai - %p ", (*ai));
4226 if ((body->id) || (body->location)) {
4227 /* For Inline content append to the end */
4228 for (i = 1; *ai; ai = &(*ai)->next)
4231 else { /* For attachment - search till Inline content found and insert before inline */
4232 for (i = 1; *ai; ai = &(*ai)->next) {
4233 if ((*ai)->type == 1) {
4234 /* Means inline image */
4235 EM_DEBUG_LOG("Found Inline Content ");
4244 EM_DEBUG_LOG("i - %d next_ai - %p prev_ai - %p", i, next_ai, prev_ai);
4246 if ((cnt_info->grab_type & GRAB_TYPE_ATTACHMENT) &&
4247 (cnt_info->grab_type & GRAB_TYPE_TEXT)) { /* it is 'download all */
4248 EM_DEBUG_LOG("Download All");
4249 only_body_download = false;
4250 cnt_info->file_no = 1;
4253 /* meaningless code */
4254 dec_len = body->size.bytes;
4257 EM_DEBUG_LOG("BODY ID [ %s ]", body->id);
4259 EM_DEBUG_LOG("BODY ID IS NULL");
4261 EM_DEBUG_LOG("i : %d, cnt_info->file_no : %d", i, cnt_info->file_no);
4264 ((cnt_info->grab_type & GRAB_TYPE_ATTACHMENT) && i == cnt_info->file_no) || /* Is it correct attachment */
4265 (((body->id) || (body->location)) && (cnt_info->grab_type & GRAB_TYPE_TEXT)) /* Is it inline contents */
4267 /* fetch attachment */
4268 EM_DEBUG_LOG("attachment (enc) : %s %ld bytes", filename, body->size.bytes);
4269 EM_DEBUG_LOG(">>>>> ONLY BODY DOWNLOAD [ %d ] ", only_body_download);
4271 if (only_body_download == false) {
4272 if (!emcore_get_temp_file_name(&savefile, &err)) {
4273 EM_DEBUG_EXCEPTION("emcore_get_temp_file_name failed [%d]", err);
4278 if (!imap_mail_write_body_to_file(stream, account_id, mail_id, cnt_info->file_no, savefile, msg_uid, body->sparep, body->encoding, &dec_len, body->subtype, &err)) {
4279 EM_DEBUG_EXCEPTION("imap_mail_write_body_to_file failed [%d]", err);
4286 EM_DEBUG_LOG("attachment (dec) : %s %d bytes", filename, dec_len);
4288 /* add attachment info to content inf */
4289 if (!(*ai = em_malloc(sizeof(struct attachment_info)))) {
4290 EM_DEBUG_EXCEPTION("em_malloc failed...");
4291 err = EMAIL_ERROR_OUT_OF_MEMORY;
4295 if ((body->id) || (body->location))
4301 if (savefile != NULL) {
4302 if (section_plain == 1)
4303 strcat(filename, ".txt");
4304 if (section_html == 1)
4305 strcat(filename, ".html");
4310 (*ai)->name = EM_SAFE_STRDUP(filename);
4311 (*ai)->size = dec_len;
4312 (*ai)->save = savefile;
4313 (*ai)->content_id = EM_SAFE_STRDUP(body->id);
4315 memset(content_type_buffer, 0, 512);
4316 if ( (err = emcore_get_content_type_from_mail_bodystruct(body, 512, content_type_buffer) ) == EMAIL_ERROR_NONE)
4317 (*ai)->attachment_mime_type = EM_SAFE_STRDUP(content_type_buffer);
4318 #ifdef __ATTACHMENT_OPTI__
4319 (*ai)->encoding = body->encoding;
4321 (*ai)->section = EM_SAFE_STRDUP(body->sparep);
4323 EM_DEBUG_LOG(" Encoding - %d Section No - %s ", (*ai)->encoding, (*ai)->section);
4325 if (body->type == TYPEAPPLICATION) {
4326 if (!strcasecmp(body->subtype, MIME_SUBTYPE_DRM_OBJECT))
4327 (*ai)->drm = EMAIL_ATTACHMENT_DRM_OBJECT;
4328 else if (!strcasecmp(body->subtype, MIME_SUBTYPE_DRM_RIGHTS))
4329 (*ai)->drm = EMAIL_ATTACHMENT_DRM_RIGHTS;
4330 else if (!strcasecmp(body->subtype, MIME_SUBTYPE_DRM_DCF))
4331 (*ai)->drm = EMAIL_ATTACHMENT_DRM_DCF;
4334 /* All inline images information are stored at the end of list */
4335 if ((*ai)->type != 1 && next_ai != NULL) {
4336 /* Means next_ai points to the inline attachment info structure */
4337 if (prev_ai == NULL) {
4338 /* First node is inline attachment */
4339 (*ai)->next = next_ai;
4340 cnt_info->file = (*ai);
4343 prev_ai->next = (*ai);
4344 (*ai)->next = next_ai;
4353 EM_DEBUG_FUNC_END("ret [%d]", ret);
4356 /* get body-part in nested part */
4358 static int emcore_get_allnested_part(MAILSTREAM *stream, int account_id, int mail_id, int msg_uid, BODY *body, struct _m_content_info *cnt_info, int *err_code)
4360 EM_DEBUG_FUNC_BEGIN("stream[%p], msg_uid[%d], body[%p], cnt_info[%p], err_code[%p]", stream, msg_uid, body, cnt_info, err_code);
4361 PART *part_child = body->nested.part;
4363 while (part_child) {
4364 if (emcore_get_body(stream, account_id, mail_id, msg_uid, &part_child->body, cnt_info, err_code) < 0)
4367 part_child = part_child->next;
4370 EM_DEBUG_FUNC_END();
4374 /* get body-part in alternative multiple part */
4375 static int emcore_get_alternative_multi_part(MAILSTREAM *stream, int account_id, int mail_id, int msg_uid, BODY *body, struct _m_content_info *cnt_info, int *err_code)
4377 EM_DEBUG_FUNC_BEGIN("stream[%p], msg_uid[%d], body[%p], cnt_info[%p], err_code[%p]", stream, msg_uid, body, cnt_info, err_code);
4379 PART *part_child = body->nested.part;
4381 /* find the best sub part we can show */
4382 while (part_child) {
4383 if (emcore_get_body(stream, account_id, mail_id, msg_uid, &part_child->body, cnt_info, err_code) < 0)
4386 part_child = part_child->next;
4388 EM_DEBUG_FUNC_END();
4392 /* get body part in signed multiple part */
4393 static int emcore_get_signed_multi_part(MAILSTREAM *stream, int account_id, int mail_id, int msg_uid, BODY *body, struct _m_content_info *cnt_info, int *err_code)
4395 EM_DEBUG_FUNC_BEGIN("stream[%p], msg_uid[%d], body[%p], cnt_info[%p], err_code[%p]", stream, msg_uid, body, cnt_info, err_code);
4397 PART *part_child = body->nested.part;
4399 /* find the best sub part we can show */
4400 while (part_child) {
4401 if (emcore_get_body(stream, account_id, mail_id, msg_uid, &part_child->body, cnt_info, err_code) < 0)
4404 part_child = part_child->next;
4407 EM_DEBUG_FUNC_END();
4411 /* get body part in encrypted multiple part */
4412 static int emcore_get_encrypted_multi_part(MAILSTREAM *stream, int account_id, int mail_id, int msg_uid, BODY *body, struct _m_content_info *cnt_info, int *err_code)
4414 EM_DEBUG_FUNC_BEGIN("stream[%p], msg_uid[%d], body[%p], cnt_info[%p], err_code[%p]", stream, msg_uid, body, cnt_info, err_code);
4415 EM_DEBUG_FUNC_END();
4419 /* get body part in multiple part */
4420 static int emcore_get_multi_part(MAILSTREAM *stream, int account_id, int mail_id, int msg_uid, BODY *body, struct _m_content_info *cnt_info, int *err_code)
4422 EM_DEBUG_FUNC_BEGIN("stream[%p], msg_uid[%d], body[%p], cnt_info[%p], err_code[%p]", stream, msg_uid, body, cnt_info, err_code);
4425 EM_DEBUG_EXCEPTION("Invalid Parameter.");
4427 *err_code = EMAIL_ERROR_INVALID_PARAM;
4431 switch (body->subtype[0]) {
4432 case 'A': /* ALTERNATIVE */
4433 EM_DEBUG_LOG("body->subtype[0] = ALTERNATIVE");
4434 return emcore_get_alternative_multi_part(stream, account_id, mail_id, msg_uid, body, cnt_info, err_code);
4436 case 'S': /* SIGNED */
4437 EM_DEBUG_LOG("body->subtype[0] = SIGNED");
4438 return emcore_get_signed_multi_part(stream, account_id, mail_id, msg_uid, body, cnt_info, err_code);
4440 case 'E': /* ENCRYPTED */
4441 EM_DEBUG_LOG("body->subtype[0] = ENCRYPTED");
4442 return emcore_get_encrypted_multi_part(stream, account_id, mail_id, msg_uid, body, cnt_info, err_code);
4444 default: /* process all unknown as MIXED (according to the RFC 2047) */
4445 EM_DEBUG_LOG("body->subtype[0] = [%c].", body->subtype[0]);
4446 return emcore_get_allnested_part(stream, account_id, mail_id, msg_uid, body, cnt_info, err_code);
4450 EM_DEBUG_LOG("emcore_get_multi_part BODY ID [%s].", body->id);
4452 EM_DEBUG_LOG("emcore_get_multi_part BODY ID NULL.");
4453 EM_DEBUG_FUNC_END();
4457 /* get body data by body structure */
4458 /* if POP3, ignored */
4459 INTERNAL_FUNC int emcore_get_body(MAILSTREAM *stream, int account_id, int mail_id, int msg_uid, BODY *body, struct _m_content_info *cnt_info, int *err_code)
4461 EM_DEBUG_FUNC_BEGIN("stream[%p], msg_uid[%d], body[%p], cnt_info[%p], err_code[%p]", stream, msg_uid, body, cnt_info, err_code);
4463 if (!stream || !body || !cnt_info) {
4464 EM_DEBUG_EXCEPTION("Invalid parameter");
4466 if (err_code != NULL)
4467 *err_code = EMAIL_ERROR_INVALID_PARAM;
4471 EM_DEBUG_LOG("body->type [%d]", body->type);
4473 switch (body->type) {
4475 return emcore_get_multi_part(stream, account_id, mail_id, msg_uid, body, cnt_info, err_code);
4477 case TYPEMESSAGE: /* not support */
4478 if (strcasecmp(body->subtype, "RFC822") == 0)
4479 return emcore_get_body_part_imap(stream, account_id, mail_id, msg_uid, body, cnt_info, err_code);
4483 case TYPEAPPLICATION:
4489 /* exactly, get a pure body part (text and attachment */
4490 return emcore_get_body_part_imap(stream, account_id, mail_id, msg_uid, body, cnt_info, err_code);
4495 EM_DEBUG_FUNC_END();
4499 /* get body structure */
4500 INTERNAL_FUNC int emcore_get_body_structure(MAILSTREAM *stream, int msg_uid, BODY **body, int *err_code)
4502 EM_DEBUG_FUNC_BEGIN("stream[%p], msg_uid[%d], body[%p], err_code[%p]", stream, msg_uid, body, err_code);
4504 EM_IF_NULL_RETURN_VALUE(stream, false);
4505 EM_IF_NULL_RETURN_VALUE(body, false);
4507 #ifdef __FEATURE_HEADER_OPTIMIZATION__
4508 ENVELOPE *env = mail_fetch_structure(stream, msg_uid, body, FT_UID | FT_PEEK | FT_NOLOOKAHEAD, 1);
4510 ENVELOPE *env = mail_fetch_structure(stream, msg_uid, body, FT_UID | FT_PEEK | FT_NOLOOKAHEAD);
4514 *err_code = EMAIL_ERROR_MAIL_NOT_FOUND_ON_SERVER;
4515 EM_DEBUG_EXCEPTION("mail_fetch_structure failed");
4519 #ifdef FEATURE_CORE_DEBUG
4520 _print_body(*body, true); /* shasikala.p@partner.samsung.com */
4522 EM_DEBUG_FUNC_END();
4526 int emcore_set_fetch_part_section(BODY *body, char *section_pfx, int section_subno, int enable_inline_list, int *total_mail_size, int *err_code);
4528 /* set body section to be fetched */
4529 INTERNAL_FUNC int emcore_set_fetch_body_section(BODY *body, int enable_inline_list, int *total_mail_size, int *err_code)
4531 EM_DEBUG_FUNC_BEGIN("body[%p], err_code[%p]", body, err_code);
4534 EM_DEBUG_EXCEPTION("body [%p]", body);
4535 if (err_code != NULL)
4536 *err_code = EMAIL_ERROR_INVALID_PARAM;
4540 body->id = cpystr("1"); /* top level body */
4543 EM_SAFE_FREE(g_inline_list);
4544 emcore_set_fetch_part_section(body, (char *)NULL, 0, enable_inline_list, total_mail_size, err_code);
4546 if (body->id && body)
4547 EM_DEBUG_LOG(">>>>> FILE NAME [ %s ] ", body->id);
4549 EM_DEBUG_LOG(">>>>> BODY NULL ", body->id);
4551 EM_DEBUG_FUNC_END();
4555 /* set part section of body to be fetched */
4556 int emcore_set_fetch_part_section(BODY *body, char *section_pfx, int section_subno, int enable_inline_list, int *total_mail_size, int *err_code)
4558 EM_DEBUG_FUNC_BEGIN("body[%p], section_pfx[%s], section_subno[%d], err_code[%p]", body, section_pfx, section_subno, err_code);
4561 char section[64] = {0x00, };
4563 /* multipart doesn't have a row to itself */
4564 if (body->type == TYPEMULTIPART) {
4565 /* if not first time, extend prefix */
4567 SNPRINTF(section, sizeof(section), "%s%d.", section_pfx, ++section_subno);
4573 for (section_subno = 0, part = body->nested.part; part; part = part->next)
4574 emcore_set_fetch_part_section(&part->body, section, section_subno++, enable_inline_list, total_mail_size, err_code);
4577 if (!section_pfx) /* dummy prefix if top level */
4580 SNPRINTF(section, sizeof(section), "%s%d", section_pfx, ++section_subno);
4582 if (enable_inline_list && ((body->disposition.type && (body->disposition.type[0] == 'i' || body->disposition.type[0] == 'I')) ||
4583 (!body->disposition.type && body->id))) {
4585 temp = realloc(g_inline_list, sizeof(BODY *) *(g_inline_count + 1));
4587 memset(temp+g_inline_count, 0x00, sizeof(BODY *));
4588 g_inline_list = temp;
4589 g_inline_list[g_inline_count] = body;
4594 EM_DEBUG_EXCEPTION("realloc fails");
4597 EM_DEBUG_LOG("Update g_inline_list with inline count [%d]", g_inline_count);
4600 /* if ((total_mail_size != NULL) && !(body->disposition.type && (body->disposition.type[0] == 'a' || body->disposition.type[0] == 'A')) */
4601 if (total_mail_size != NULL) {
4602 *total_mail_size = *total_mail_size + (int)body->size.bytes;
4603 EM_DEBUG_LOG("body->size.bytes [%d]", body->size.bytes);
4606 /* encapsulated message ? */
4607 if ((body->type == TYPEMESSAGE) && !strcasecmp(body->subtype, "RFC822") && (body = ((MESSAGE *)body->nested.msg)->body)) {
4608 if (body->type == TYPEMULTIPART) {
4610 emcore_set_fetch_part_section(body, section, section_subno-1, enable_inline_list, total_mail_size, err_code);
4612 else { /* build encapsulation prefi */
4613 SNPRINTF(section, sizeof(section), "%s%d.", section_pfx, section_subno);
4614 emcore_set_fetch_part_section(body, section, 0, enable_inline_list, total_mail_size, err_code);
4618 /* set body section */
4620 body->sparep = cpystr(section);
4623 EM_DEBUG_FUNC_END();
4628 static void parse_file_path_to_filename(char *src_string, char **out_string)
4631 char *filepath = NULL;
4636 filepath = EM_SAFE_STRDUP(src_string);
4637 token = strtok_r(filepath, "/", &str);
4642 } while ((token = strtok_r(NULL , "/", &str)));
4644 *out_string = EM_SAFE_STRDUP(prev1);
4645 EM_SAFE_FREE(filepath);
4648 static char *emcore_decode_rfc2047_word(char *encoded_word, int *err_code)
4650 EM_DEBUG_FUNC_BEGIN("encoded_word[%s], err_code[%p]", encoded_word, err_code);
4652 int err = EMAIL_ERROR_NONE;
4653 int base64_encoded = false, length = 0;
4654 SIZEDTEXT src = { NULL, 0 };
4655 SIZEDTEXT dst = { NULL, 0 };
4656 gchar *charset = NULL, *encoded_text = NULL;
4657 char *decoded_text = NULL, *decoded_word = NULL;
4658 char *current = NULL, *start = NULL, *end = NULL;
4659 char *buffer = (char*) em_malloc(strlen(encoded_word) * 2 + 1);
4661 if (buffer == NULL) {
4662 EM_DEBUG_EXCEPTION("Memory allocation fail");
4663 err = EMAIL_ERROR_OUT_OF_MEMORY;
4669 /* encoding format : =?charset?encoding?encoded-text ?= */
4670 /* charset : UTF-8, EUC-KR, ... */
4671 /* encoding : b/B (BASE64), q/Q (QUOTED-PRINTABLE) */
4672 current = encoded_word;
4674 while (*current != NULL_CHAR) {
4676 start = strstr(current, "=?"); /* start of encoding */
4677 end = strstr(current, "?="); /* end of encoding */
4679 #ifdef FEATURE_CORE_DEBUG
4680 EM_DEBUG_LOG("current[%p][%s], start[%p][%s], end[%p][%s]", current, current, start, start, end, end);
4682 if (start != NULL) {
4683 if (current != start) { /* copy the string between current and start to buffer */
4684 strncat(buffer, current, start - current);
4686 #ifdef FEATURE_CORE_DEBUG
4687 EM_DEBUG_LOG("1 - Buffer[%s]", buffer);
4691 if (end) { /* decode text between start and end */
4692 char *p = strstr(start, "?b?");
4694 if (p || (p = strstr(start, "?B?"))) /* BASE64 */
4695 base64_encoded = true;
4697 p = strstr(start, "?q?");
4699 if (p || (p = strstr(start, "?Q?"))) /* QUOTED-PRINTABLE */
4700 base64_encoded = false;
4702 EM_DEBUG_EXCEPTION("unknown encoding found...");
4704 err = EMAIL_ERROR_UNKNOWN;
4709 if (base64_encoded) { /* BASE64 */
4710 charset = g_strndup(start + 2, p - (start + 2));
4711 encoded_text = g_strndup(p + 3, end - (p + 3));
4713 else { /* QUOTED-PRINTABLE */
4714 charset = g_strndup(start + 2, p - (start + 2));
4715 if (*(p+3) == '=') { /* encoded text might start with '='. ex) '?Q?=E0' */
4716 end = strstr(p+3, "?="); /* find new end flag */
4718 encoded_text = g_strndup(p + 3, end - (p + 3));
4720 else { /* end flag is not found */
4721 EM_DEBUG_EXCEPTION("emcore_decode_rfc2047_word decoding error : '?=' is not found...");
4723 err = EMAIL_ERROR_UNKNOWN;
4728 encoded_text = g_strndup(p + 3, end - (p + 3));
4732 #ifdef FEATURE_CORE_DEBUG
4733 EM_DEBUG_LOG("\t >>>>>>>>>>>>>>> CHARSET[%s]", charset);
4734 EM_DEBUG_LOG("\t >>>>>>>>>>>>>>> ENCODED_TEXT[%s]", encoded_text);
4737 unsigned long len = 0;
4738 if (encoded_text != NULL) {
4739 if (base64_encoded == true) {
4740 if (!(decoded_text = (char *)rfc822_base64((unsigned char *)encoded_text, strlen(encoded_text), &len))) {
4741 EM_DEBUG_EXCEPTION("rfc822_base64 falied...");
4746 g_strdelimit(encoded_text, "_", ' ');
4748 if (!(decoded_text = (char *)rfc822_qprint((unsigned char *)encoded_text, strlen(encoded_text), &len))) {
4749 EM_DEBUG_EXCEPTION("rfc822_base64 falied...");
4754 src.data = (unsigned char *)decoded_text;
4755 src.size = strlen(decoded_text);
4757 if (!utf8_text(&src, charset, &dst, 0)) {
4758 EM_DEBUG_EXCEPTION("utf8_text falied...");
4759 strncat(buffer, (char *)src.data, src.size); /* Eventhough failed to decode, downloading should go on. Kyuho Jo */
4762 strncat(buffer, (char *)dst.data, dst.size);
4763 #ifdef FEATURE_CORE_DEBUG
4764 EM_DEBUG_LOG("2 - Buffer[%s]", buffer);
4767 /* free all of the temp variables */
4768 if (dst.data != NULL && dst.data != src.data)
4769 EM_SAFE_FREE(dst.data);
4771 EM_SAFE_FREE(decoded_text);
4773 g_free(encoded_text);
4774 encoded_text = NULL;
4776 if (charset != NULL) {
4781 current = end + 2; /* skip '?=' */
4784 /* unencoded text */
4785 length = strlen(start);
4786 strncat(buffer, start, length);
4787 current = start + length;
4788 #ifdef FEATURE_CORE_DEBUG
4789 EM_DEBUG_LOG("3 - Buffer[%s]", buffer);
4794 /* unencoded text */
4795 length = strlen(current);
4796 strncat(buffer, current, length);
4797 current = current + length;
4798 #ifdef FEATURE_CORE_DEBUG
4799 EM_DEBUG_LOG("4 - Buffer[%s]", buffer);
4804 decoded_word = EM_SAFE_STRDUP(buffer);
4806 #ifdef FEATURE_CORE_DEBUG
4807 EM_DEBUG_LOG(">>>>>>>>>>>>>>> DECODED_WORD[%s]", decoded_word);
4811 if (dst.data != NULL && dst.data != src.data)
4812 EM_SAFE_FREE(dst.data);
4813 EM_SAFE_FREE(decoded_text);
4814 EM_SAFE_FREE(buffer);
4816 if (encoded_text != NULL)
4817 g_free(encoded_text);
4818 if (charset != NULL)
4821 if (err_code != NULL)
4824 EM_DEBUG_FUNC_END();
4825 return decoded_word;
4828 INTERNAL_FUNC char *emcore_decode_rfc2047_text(char *rfc2047_text, int *err_code)
4830 EM_DEBUG_FUNC_BEGIN("rfc2047_text[%s], err_code[%p]", rfc2047_text, err_code);
4833 int err = EMAIL_ERROR_NONE;
4835 if (!rfc2047_text) {
4836 EM_DEBUG_EXCEPTION("rfc2047_text[%p]", rfc2047_text);
4837 if (err_code != NULL)
4838 *err_code = EMAIL_ERROR_INVALID_PARAM;
4844 gchar **encoded_words = g_strsplit_set(rfc2047_text, " \t\r\n", -1);
4845 gchar **decoded_words = g_new0(char *, g_strv_length(encoded_words) + 1);
4847 /* EM_DEBUG_LOG("g_strv_length(encoded_words) [%d]", g_strv_length(encoded_words)); */
4849 if (encoded_words != NULL) {
4852 while (encoded_words[i] != NULL) {
4853 if (!(decoded_words[i] = emcore_decode_rfc2047_word(encoded_words[i], &err))) {
4854 EM_DEBUG_EXCEPTION("emcore_decode_rfc2047_word falied [%d]", err);
4860 text = g_strjoinv(" ", decoded_words);
4863 text = EM_SAFE_STRDUP(rfc2047_text);
4865 #ifdef FEATURE_CORE_DEBUG
4866 EM_DEBUG_LOG(">>>>>>>>>>>>>>>>> TEXT[%s]", text);
4867 #endif /* FEATURE_CORE_DEBUG */
4872 g_strfreev(decoded_words);
4873 g_strfreev(encoded_words);
4875 if (err_code != NULL)
4877 EM_DEBUG_FUNC_END();
4881 INTERNAL_FUNC int emcore_make_mail_data_from_mime_data(struct _m_mesg *mmsg, struct _m_content_info *cnt_info, email_mail_data_t **output_mail_data, email_attachment_data_t **output_attachment_data, int *output_attachment_count, int *err_code)
4883 EM_DEBUG_FUNC_BEGIN();
4885 int err = EMAIL_ERROR_NONE;
4886 int local_attachment_count = 0;
4887 int local_inline_content_count = 0;
4888 int attachment_num = 0;
4890 int eml_mail_id = 0;
4892 char html_body[MAX_PATH] = {0, };
4893 struct tm temp_time_info;
4895 struct attachment_info *ai = NULL;
4896 email_attachment_data_t *attachment = NULL;
4897 email_mail_data_t *p_mail_data = NULL;
4898 MESSAGECACHE mail_cache_element = {0, };
4900 if (!mmsg || !cnt_info || !output_mail_data || !output_attachment_data) {
4901 EM_DEBUG_EXCEPTION("Invalid parameter");
4902 err = EMAIL_ERROR_INVALID_PARAM;
4906 p_mail_data = (email_mail_data_t *)em_malloc(sizeof(email_mail_data_t));
4907 if (p_mail_data == NULL) {
4908 EM_DEBUG_EXCEPTION("em_malloc failed");
4909 err = EMAIL_ERROR_OUT_OF_MEMORY;
4913 memset(&mail_cache_element, 0x00, sizeof(MESSAGECACHE));
4914 memset((void *)&temp_time_info, 0, sizeof(struct tm));
4916 /* Create rand mail id of eml */
4917 gettimeofday(&tv, NULL);
4919 eml_mail_id = rand();
4921 p_mail_data->mail_id = eml_mail_id;
4922 p_mail_data->account_id = EML_FOLDER;
4924 if (mmsg->rfc822header->date)
4925 mail_parse_date(&mail_cache_element, (unsigned char *)mmsg->rfc822header->date);
4927 temp_time_info.tm_sec = mail_cache_element.seconds;
4928 temp_time_info.tm_min = mail_cache_element.minutes - mail_cache_element.zminutes;
4929 temp_time_info.tm_hour = mail_cache_element.hours - mail_cache_element.zhours;
4931 if (mail_cache_element.hours - mail_cache_element.zhours < 0) {
4932 temp_time_info.tm_mday = mail_cache_element.day - 1;
4933 temp_time_info.tm_hour += 24;
4935 temp_time_info.tm_mday = mail_cache_element.day;
4937 temp_time_info.tm_mon = mail_cache_element.month - 1;
4938 temp_time_info.tm_year = mail_cache_element.year + 70;
4940 p_mail_data->date_time = timegm(&temp_time_info);
4941 p_mail_data->full_address_return = EM_SAFE_STRDUP(mmsg->rfc822header->return_path);
4942 p_mail_data->email_address_recipient = EM_SAFE_STRDUP(mmsg->rfc822header->received);
4943 p_mail_data->full_address_from = EM_SAFE_STRDUP(mmsg->rfc822header->from);
4944 p_mail_data->subject = EM_SAFE_STRDUP(mmsg->rfc822header->subject);
4945 p_mail_data->email_address_sender = EM_SAFE_STRDUP(mmsg->rfc822header->sender);
4946 p_mail_data->full_address_to = EM_SAFE_STRDUP(mmsg->rfc822header->to);
4947 p_mail_data->full_address_cc = EM_SAFE_STRDUP(mmsg->rfc822header->cc);
4948 p_mail_data->full_address_bcc = EM_SAFE_STRDUP(mmsg->rfc822header->bcc);
4949 p_mail_data->full_address_reply = EM_SAFE_STRDUP(mmsg->rfc822header->reply_to);
4950 p_mail_data->body_download_status = EMAIL_BODY_DOWNLOAD_STATUS_FULLY_DOWNLOADED;
4952 EM_DEBUG_LOG("cnt_info->text.plain [%s], cnt_info->text.html [%s]", cnt_info->text.plain, cnt_info->text.html);
4954 if (cnt_info->text.plain) {
4955 EM_DEBUG_LOG("cnt_info->text.plain [%s]", cnt_info->text.plain);
4956 if (!emstorage_create_dir(EML_FOLDER, eml_mail_id, 0, &err)) {
4957 EM_DEBUG_EXCEPTION("emstorage_create_dir failed [%d]", err);
4961 if (!emstorage_get_save_name(EML_FOLDER, eml_mail_id, 0, cnt_info->text.plain_charset ? cnt_info->text.plain_charset : "UTF-8", buf, &err)) {
4962 EM_DEBUG_EXCEPTION("emstorage_get_save_name failed [%d]", err);
4966 if (!emstorage_move_file(cnt_info->text.plain, buf, false, &err)) {
4967 EM_DEBUG_EXCEPTION("emstorage_move_file failed [%d]", err);
4971 p_mail_data->file_path_plain = EM_SAFE_STRDUP(buf);
4972 EM_DEBUG_LOG("mail_data->file_path_plain [%s]", p_mail_data->file_path_plain);
4975 if (cnt_info->text.html) {
4976 if (!emstorage_create_dir(EML_FOLDER, eml_mail_id, 0, &err)) {
4977 EM_DEBUG_EXCEPTION("emstorage_create_dir failed [%d]", err);
4981 if (cnt_info->text.plain_charset != NULL) {
4982 memcpy(html_body, cnt_info->text.plain_charset, strlen(cnt_info->text.plain_charset));
4983 strcat(html_body, HTML_EXTENSION_STRING);
4986 memcpy(html_body, "UTF-8.htm", strlen("UTF-8.htm"));
4988 if (!emstorage_get_save_name(EML_FOLDER, eml_mail_id, 0, html_body, buf, &err)) {
4989 EM_DEBUG_EXCEPTION("emstorage_get_save_name failed [%d]", err);
4993 if (!emstorage_move_file(cnt_info->text.html, buf, false, &err)) {
4994 EM_DEBUG_EXCEPTION("emstorage_move_file failed [%d]", err);
4997 p_mail_data->file_path_html = EM_SAFE_STRDUP(buf);
5001 for (ai = cnt_info->file; ai; ai = ai->next, attachment_num++) {}
5002 EM_DEBUG_LOG("attachment_num : [%d]", attachment_num);
5004 if (attachment_num > 0) {
5005 attachment = (email_attachment_data_t *)em_malloc(sizeof(email_attachment_data_t) * attachment_num);
5006 if (attachment == NULL) {
5007 EM_DEBUG_EXCEPTION("em_malloc failed");
5008 err = EMAIL_ERROR_OUT_OF_MEMORY;
5012 for (ai = cnt_info->file; ai; ai = ai->next, i++) {
5013 attachment[i].attachment_id = i;
5014 attachment[i].attachment_size = ai->size;
5015 attachment[i].attachment_name = EM_SAFE_STRDUP(ai->name);
5016 attachment[i].drm_status = ai->drm;
5017 attachment[i].save_status = 0;
5018 attachment[i].inline_content_status = ai->type == 1;
5019 attachment[i].attachment_mime_type = ai->attachment_mime_type;
5020 #ifdef __ATTACHMENT_OPTI__
5021 attachment[i].encoding = ai->encoding;
5022 attachment[i].section = ai->section;
5024 EM_DEBUG_LOG("attachment[%d].attachment_id[%d]", i, attachment[i].attachment_id);
5025 EM_DEBUG_LOG("attachment[%d].attachment_size[%d]", i, attachment[i].attachment_size);
5026 EM_DEBUG_LOG("attachment[%d].attachment_name[%s]", i, attachment[i].attachment_name);
5027 EM_DEBUG_LOG("attachment[%d].drm_status[%d]", i, attachment[i].drm_status);
5028 EM_DEBUG_LOG("attachment[%d].inline_content_status[%d]", i, attachment[i].inline_content_status);
5031 local_inline_content_count ++;
5032 local_attachment_count++;
5035 attachment[i].save_status = 1;
5036 if (ai->type == 1) { /* it is inline content */
5037 if (!emstorage_create_dir(EML_FOLDER, eml_mail_id, 0, &err)) {
5038 EM_DEBUG_EXCEPTION("emstorage_create_dir failed [%d]", err);
5041 if (!emstorage_get_save_name(EML_FOLDER, eml_mail_id, 0, attachment[i].attachment_name, buf, &err)) {
5042 EM_DEBUG_EXCEPTION("emstorage_get_save_name failed [%d]", err);
5047 if (!emstorage_create_dir(EML_FOLDER, eml_mail_id, i, &err)) {
5048 EM_DEBUG_EXCEPTION("emstorage_create_dir failed [%d]", err);
5052 if (!emstorage_get_save_name(EML_FOLDER, eml_mail_id, i, attachment[i].attachment_name, buf, &err)) {
5053 EM_DEBUG_EXCEPTION("emstorage_get_save_name failed [%d]", err);
5058 if (!emstorage_move_file(ai->save, buf, false, &err)) {
5059 EM_DEBUG_EXCEPTION("emstorage_move_file failed [%d]", err);
5061 /* delete all created files. */
5062 if (!emstorage_get_save_name(EML_FOLDER, eml_mail_id, 0, NULL, buf, NULL)) {
5063 EM_DEBUG_EXCEPTION("emstorage_get_save_name failed...");
5064 /* goto FINISH_OFF; */
5067 if (!emstorage_delete_dir(buf, NULL)) {
5068 EM_DEBUG_EXCEPTION("emstorage_delete_dir failed...");
5069 /* goto FINISH_OFF; */
5076 attachment[i].attachment_path = EM_SAFE_STRDUP(buf);
5080 EM_DEBUG_LOG("attachment[%d].attachment_path[%s]", i, attachment[i].attachment_path);
5083 EM_DEBUG_LOG("Check #1");
5085 p_mail_data->attachment_count = local_attachment_count;
5086 p_mail_data->inline_content_count = local_inline_content_count;
5088 eml_data_count += 1;
5094 if (output_mail_data)
5095 *output_mail_data = p_mail_data;
5097 if (output_attachment_data)
5098 *output_attachment_data = attachment;
5100 if (output_attachment_count)
5101 *output_attachment_count = local_attachment_count;
5104 emcore_free_mail_data(p_mail_data);
5107 emcore_free_attachment_data(&attachment, attachment_num, NULL);
5116 INTERNAL_FUNC int emcore_load_eml_file_to_mail(char *eml_file_path, email_mail_data_t **output_mail_data, email_attachment_data_t **output_attachment_data, int *output_attachment_count, int *err_code)
5118 EM_DEBUG_FUNC_BEGIN("eml_file_path : [%s], output_mail_data : [%p]", eml_file_path, output_mail_data);
5120 int err = EMAIL_ERROR_NONE;
5123 FILE *eml_fp = NULL;
5124 struct _m_content_info *cnt_info = NULL;
5125 struct _m_mesg *mmsg = NULL;
5128 if (!eml_file_path || !output_mail_data || !output_attachment_data || !output_attachment_count) {
5129 EM_DEBUG_EXCEPTION("Invalid paramter");
5130 err = EMAIL_ERROR_INVALID_PARAM;
5134 cnt_info = (struct _m_content_info *)em_malloc(sizeof(struct _m_content_info));
5135 if (cnt_info == NULL) {
5136 EM_DEBUG_EXCEPTION("em_malloc failed...");
5137 err = EMAIL_ERROR_OUT_OF_MEMORY;
5141 cnt_info->grab_type = GRAB_TYPE_TEXT | GRAB_TYPE_ATTACHMENT;
5143 mmsg = (struct _m_mesg *)em_malloc(sizeof(struct _m_mesg));
5145 EM_DEBUG_EXCEPTION("em_malloc failed");
5146 err = EMAIL_ERROR_OUT_OF_MEMORY;
5150 eml_fp = fopen(eml_file_path, "r");
5151 if (eml_fp == NULL) {
5152 EM_DEBUG_EXCEPTION("file open failed");
5153 err = EMAIL_ERROR_ON_PARSING;
5157 if (!emcore_mime_parse_header(eml_fp, is_file, &mmsg->rfc822header, &mmsg->header, &err)) {
5158 EM_DEBUG_EXCEPTION("emcore_mime_parse_header failed : [%d]", err);
5162 if (emcore_mime_parse_body(eml_fp, is_file, mmsg, cnt_info, NULL, &err) < 0) {
5163 EM_DEBUG_EXCEPTION("emcore_mime_parse_body failed : [%d]", err);
5167 if (!emcore_make_mail_data_from_mime_data(mmsg, cnt_info, output_mail_data, output_attachment_data, output_attachment_count, &err)) {
5168 EM_DEBUG_EXCEPTION("emcore_make_mail_tbl_data_from_mime failed : [%d]", err);
5181 emcore_mime_free_mime(mmsg);
5184 emcore_free_content_info(cnt_info);
5189 EM_DEBUG_FUNC_END("err : %d", err);
5193 INTERNAL_FUNC int emcore_delete_eml_data(email_mail_data_t *input_mail_data, int *err_code)
5195 EM_DEBUG_FUNC_BEGIN("input_mail_data : [%p]", input_mail_data);
5196 int err = EMAIL_ERROR_NONE;
5200 if (!input_mail_data) {
5201 EM_DEBUG_EXCEPTION("Invliad parameter");
5202 err = EMAIL_ERROR_INVALID_PARAM;
5206 if ((input_mail_data->account_id != EML_FOLDER) && (!input_mail_data->mail_id)) {
5207 EM_DEBUG_EXCEPTION("Invliad parameter: account_id[%d], mail_id[%d]", input_mail_data->account_id, input_mail_data->mail_id);
5208 err = EMAIL_ERROR_INVALID_PARAM;
5212 eml_data_count = eml_data_count - 1;
5214 if (eml_data_count == 0) {
5215 SNPRINTF(buf, sizeof(buf), "%s%s%d", MAILHOME, DIR_SEPERATOR, input_mail_data->account_id);
5217 SNPRINTF(buf, sizeof(buf), "%s%s%d%s%d", MAILHOME, DIR_SEPERATOR, input_mail_data->account_id, DIR_SEPERATOR, input_mail_data->mail_id);
5220 EM_DEBUG_LOG("Directory : [%s]", buf);
5222 if (!emstorage_delete_dir(buf, &err)) {
5223 EM_DEBUG_EXCEPTION("emstorage_delete_dir failed");
5237 INTERNAL_FUNC int emcore_get_mime_entity(char *mime_path, char **output_path, int *err_code)
5239 EM_DEBUG_FUNC_BEGIN("mime_path : [%s], output_path : [%p]", mime_path, *output_path);
5241 int err = EMAIL_ERROR_NONE;
5244 char buf[MIME_LINE_LEN] = {0x00, };
5245 char *mime_entity_path = NULL;
5246 char *content_type = NULL;
5247 char boundary[BOUNDARY_LEN] = {0x00,};
5248 char *boundary_string = NULL;
5249 FILE *fp_read = NULL;
5250 FILE *fp_write = NULL;
5251 struct _m_mesg *mmsg = NULL;
5254 EM_DEBUG_EXCEPTION("Invalid parameter");
5255 err = EMAIL_ERROR_INVALID_PARAM;
5259 /* Get the header info */
5260 mmsg = (struct _m_mesg *)em_malloc(sizeof(struct _m_mesg));
5262 EM_DEBUG_EXCEPTION("em_malloc failed");
5263 err = EMAIL_ERROR_OUT_OF_MEMORY;
5267 fp_read = fopen(mime_path, "r");
5268 if (fp_read == NULL) {
5269 EM_DEBUG_EXCEPTION("File open(read) is failed : filename [%s]", mime_path);
5270 err = EMAIL_ERROR_SYSTEM_FAILURE;
5274 if (!emcore_mime_parse_header(fp_read, is_file, &mmsg->rfc822header, &mmsg->header, &err)) {
5275 EM_DEBUG_EXCEPTION("emcore_mime_parse_header failed : [%d]", err);
5279 /* Parsing the mime header */
5280 content_type = emcore_mime_get_header_value(mmsg->header->part_header, CONTENT_TYPE, NULL);
5281 EM_DEBUG_LOG("Content_type : [%s]", content_type);
5282 if (strcasestr(content_type, "signed") == NULL) {
5283 EM_DEBUG_EXCEPTION("Invalid parameter : No signed mail");
5284 err = EMAIL_ERROR_INVALID_PARAM;
5288 /* Create mime_entity file */
5289 if (!emcore_get_temp_file_name(&mime_entity_path, &err)) {
5290 EM_DEBUG_EXCEPTION("emcore_get_temp_file_name failed[%d]", err);
5293 EM_DEBUG_LOG("mime_entity_path = %s", mime_entity_path);
5295 fp_write = fopen(mime_entity_path, "w");
5296 if (fp_write == NULL) {
5297 EM_DEBUG_EXCEPTION("File open(write) is failed : filename [%s]", mime_entity_path);
5298 err = EMAIL_ERROR_SYSTEM_FAILURE;
5302 boundary_string = emcore_mime_get_header_value(mmsg->header->part_header, CONTENT_BOUNDARY, NULL);
5303 SNPRINTF(boundary, BOUNDARY_LEN, "--%s%s", boundary_string, CRLF_STRING);
5306 if (!emcore_get_line_from_file((void *)fp_read, buf, MIME_LINE_LEN, &err)) {
5307 EM_DEBUG_EXCEPTION("emcore_mime_get_line_from_file failed [%d]", err);
5311 if (!strcmp(buf, boundary)) {
5313 } else if (search == 1) {
5314 EM_DEBUG_LOG("Buf : [%s]", buf);
5315 fprintf(fp_write, "%s", buf);
5316 } else if (search == 2) {
5332 emcore_mime_free_mime(mmsg);
5335 *output_path = mime_entity_path;
5340 EM_DEBUG_FUNC_END();