4 * Copyright (c) 2012 - 2013 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-core-signal.h"
53 #include "email-debug-log.h"
55 #define MIME_MESG_IS_SOCKET
57 #define MIME_LINE_LEN 1024
58 #define BOUNDARY_LEN 256
64 #define TYPE_APPLICATION 5
65 #define TYPE_MULTIPART 6
66 #define TYPE_MESSAGE 7
67 #define TYPE_UNKNOWN 8
69 #define TEXT_STR "TEXT"
70 #define IMAGE_STR "IMAGE"
71 #define AUDIO_STR "AUDIO"
72 #define VIDEO_STR "VIDEO"
73 #define APPLICATION_STR "APPLICATION"
74 #define MULTIPART_STR "MULTIPART"
75 #define MESSAGE_STR "MESSAGE"
77 #define CONTENT_TYPE 1
78 #define CONTENT_SUBTYPE 2
79 #define CONTENT_ENCODING 3
80 #define CONTENT_CHARSET 4
81 #define CONTENT_DISPOSITION 5
82 #define CONTENT_NAME 6
83 #define CONTENT_FILENAME 7
84 #define CONTENT_BOUNDARY 8
85 #define CONTENT_REPORT_TYPE 9
87 #define CONTENT_LOCATION 11
89 #define GRAB_TYPE_TEXT 1 /* retrieve text and attachment name */
90 #define GRAB_TYPE_ATTACHMENT 2 /* retrieve only attachmen */
92 #define SAVE_TYPE_SIZE 1 /* only get content siz */
93 #define SAVE_TYPE_BUFFER 2 /* save content to buffe */
94 #define SAVE_TYPE_FILE 3 /* save content to temporary fil */
96 #define EML_FOLDER 20 /* save eml content to temporary folder */
99 MIME Structure Example
101 (part 0) multipart/mixed
102 (part 1) multipart/alternative
103 (part 1.1) text/plain <- text message
104 (part 1.2) text/html <- html message
105 (part 2) text/plain <- text attachment
108 (part 0) multipart/related
109 (part 1) multipart/alternative
110 (part 1.1) text/plain <- text message
111 (part 1.2) text/html <- html message
112 (part 2) image/png <- inline image
113 (part 2) image/png <- inline image
116 (part 0) multipart/mixed
117 (part 1.1) multipart/related
118 (part 2.1) multipart/alternative
119 (part 3.1) text/plain(body) <- text message
120 (part 3.2) text/html(body) <- html message
121 (part 2.2) image/png(related) <- inline image
122 (part 1.2) image/png(attachment) <- image attachment
125 /* Text and Attachment Holde */
126 /* struct _m_content_info */
127 /* int grab_type; */ /* 1 : text and attachment list */
129 /* int file_no; */ /* attachment sequence to be downloaded (min : 1 */
130 /* struct text_data */
131 /* char *plain; */ /* body plain tex */
132 /* char *plain_charset */ /* charset of plai */
133 /* char *html; */ /* body html tex */
136 /* struct attachment_info */
137 /* int type; */ /* 1 : inline 2 : attachmen */
138 /* char *name; */ /* attachment filenam */
139 /* int size; */ /* attachment siz */
140 /* char *save; */ /* content saving filenam */
141 /* struct attachment_info *next */
145 /* --------------------- MIME Structure --------------------------------- */
146 /* MIME Header Parameter (Content-Type, Content-Disposition, ... */
148 char *name; /* parameter name */
149 char *value; /* parameter valu */
150 struct _parameter *next; /* next paramete */
153 /* Content-Dispositio */
154 struct _disposition {
155 char *type; /* "inline" "attachment */
156 struct _parameter *parameter; /* "filename", .. */
160 struct _rfc822header {
161 char *return_path; /* error return pat */
177 /* MIME Part Header */
178 struct _m_part_header {
179 char *type; /* text, image, audio, video, application, multipart, message */
180 char *subtype; /* plain, html, jpeg, .. */
181 char *encoding; /* encoding typ */
182 struct _parameter *parameter; /* content-type parameter : "boundary" "charset" .. */
183 char *desc; /* descriptio */
184 char *disp_type; /* disposition type : "inline" "attachment", */
185 struct _parameter *disp_parameter; /* disposition parameter : "filename", .. */
186 char *content_id; /* content id : it is inline */
187 char *content_location; /* content location : "inline" location */
190 /* MIME Message Header */
191 struct _m_mesg_header {
192 char *version; /* MIME Versio */
193 struct _m_part_header *part_header; /* MIME Part Heade */
196 /* MIME Multipart Body linked list */
197 typedef struct _m_body _m_body_t;
199 _m_body_t *body; /* part bod */
200 struct _m_part *next; /* the next found par */
203 /* MIME Multipart Body */
205 struct _m_part_header *part_header; /* MIME Part Heade */
206 struct _m_part nested; /* nested structure if contain multipar */
207 char *text; /* text if not contain multipar */
208 int size; /* text size if not contain multipar */
214 struct _rfc822header *rfc822header; /* RFC822 Heade */
215 struct _m_mesg_header *header; /* MIME Message Heade */
216 struct _m_part nested; /* nested structure if contain multipar */
217 char *text; /* text if not contain multipar */
218 int size; /* text size if not contain multipar */
220 /* ---------------------------------------------------------------------- */
221 /* Global variable */
222 static bool next_decode_string = false;
223 static int eml_data_count = 0;
225 /* ---------------------------------------------------------------------- */
226 /* External variable */
227 extern int _pop3_receiving_mail_id;
228 extern int _pop3_received_body_size;
229 extern int _pop3_last_notified_body_size;
230 extern int _pop3_total_body_size;
232 extern int _imap4_received_body_size;
233 extern int _imap4_last_notified_body_size;
234 extern int _imap4_total_body_size;
235 extern int _imap4_download_noti_interval_value;
237 extern int multi_part_body_size;
238 extern bool only_body_download;
240 extern BODY **g_inline_list;
241 extern int g_inline_count;
243 /* ---------------------------------------------------------------------- */
244 /* Function Declaration */
246 /* parsing the first header (RFC822 Header and Message Header and Etc... */
247 static int emcore_mime_parse_header(void *stream, int is_file, struct _rfc822header **rfcheader, struct _m_mesg_header **header, int *err_code);
249 /* parsing the first bod */
250 static int emcore_mime_parse_body(void *stream, int is_file, struct _m_mesg *mmsg, struct _m_content_info *cnt_info, void *callback, int *err_code);
252 /* parsing the message part header (CONTENT-... header */
253 static int emcore_mime_parse_part_header(void *stream, int is_file, struct _m_part_header **header, int *err_code);
255 /* parsing the message part by boundar */
256 static int emcore_mime_parse_part(void *stream, int is_file, struct _m_part_header *parent_header, struct _m_part *nested, struct _m_content_info *cnt_info, int *end_of_parsing, int *err_code);
258 /* set RFC822 Header valu */
259 static int emcore_mime_set_rfc822_header_value(struct _rfc822header **rfc822header, char *name, char *value, int *err_code);
261 /* set Message Part Header (Content-... Header */
262 static int emcore_mime_set_part_header_value(struct _m_part_header **header, char *name, char *value, int *err_code);
264 static int emcore_mime_get_param_from_str(char *str, struct _parameter **param, int *err_code);
266 static int emcore_mime_add_param_to_list(struct _parameter **param_list, struct _parameter *param, int *err_code);
268 char *emcore_mime_get_header_value(struct _m_part_header *header, int type, int *err_code);
270 void emcore_mime_free_param(struct _parameter *param);
271 void emcore_mime_free_part_header(struct _m_part_header *header);
272 void emcore_mime_free_message_header(struct _m_mesg_header *header);
273 void emcore_mime_free_rfc822_header(struct _rfc822header *rfc822header);
274 void emcore_mime_free_part(struct _m_part *part);
275 void emcore_mime_free_part_body(struct _m_body *body);
276 void emcore_mime_free_mime(struct _m_mesg *mmsg);
277 char *emcore_mime_get_line_from_sock(void *stream, char *buf, int size, int *err_code);
278 char *emcore_mime_get_save_file_name(int *err_code);
280 /* get content data and save buffer or fil */
281 /* mode - 1 : get the only siz */
282 /* 2 : save content to buffer (holder is buffer */
283 /* 3 : save content to file (holder is file name */
284 static int emcore_mime_get_content_data(void *stream,
288 char *content_encoding,
296 int emcore_decode_body_text_from_sock(void *stream, char *boundary_str, int encoding, int mode, int is_text, int fd, char **holder, int *end_of_parsing, int *size);
297 int emcore_decode_body_text_from_file(FILE *stream, char *boundary_str, int encoding, int mode, int is_text, int fd, char **holder, int *end_of_parsing, int *size);
298 /* skip content data to boundary_str or end of fil */
299 int emcore_mime_skip_content_data(void *stream,
307 static int emcore_get_file_pointer(BODY *body, bool input_check_duplicated_file_name, char *buf, struct _m_content_info *cnt_info , int *err);
308 static PARTLIST *emcore_get_body_full(MAILSTREAM *stream, int msg_uid, BODY *body, struct _m_content_info *cnt_info, int *err_code, PARTLIST *section_list);
309 static int emcore_get_body_part_imap_full(MAILSTREAM *stream, int msg_uid, int account_id, int mail_id, PARTLIST *section_list, struct _m_content_info *cnt_info, int *err_code, int event_handle);
310 static PARTLIST *emcore_add_node(PARTLIST *section_list, BODY *body);
311 static void emcore_free_section_list(PARTLIST *section_list);
312 static int emcore_get_section_body_size(char *response, char *section, int *body_size);
313 static void parse_file_path_to_filename(char *src_string, char **out_string);
314 extern long pop3_reply (MAILSTREAM *stream);
315 /* ------------------------------------------------------------------------------------------------- */
318 /* Fix for issue junk characters in mail body */
319 char *em_split_file_path(char *str)
321 EM_DEBUG_FUNC_BEGIN("str [%s]", str);
323 EM_IF_NULL_RETURN_VALUE(str, NULL);
328 char *temp_str = NULL;
329 char *content_id = NULL;
331 char *temp_cid_data = NULL;
332 char *temp_cid = NULL;
333 temp_str = EM_SAFE_STRDUP(str);
334 buf_length = EM_SAFE_STRLEN(str) + 1024;
335 buf = em_malloc(buf_length);
336 content_id = temp_str;
337 temp_cid = strstr(temp_str, "\"");
339 if (temp_cid == NULL) {
340 EM_DEBUG_EXCEPTION(">>>> File Path Doesnot contain end line for CID ");
341 next_decode_string = true;
345 temp_cid_data = em_malloc((temp_cid-temp_str)+1);
346 memcpy(temp_cid_data, temp_str, (temp_cid-temp_str));
348 if (!strstr(temp_cid_data, delims)) {
349 EM_DEBUG_EXCEPTION(">>>> File Path Doesnot contain @ ");
350 next_decode_string = true;
352 EM_SAFE_FREE(temp_cid_data);
356 result = strstr(temp_str, delims);
357 if (result != NULL) {
358 next_decode_string = false;
361 EM_DEBUG_LOG("content_id is [ %s ]", content_id);
363 if (strcasestr(content_id, ".bmp") || strcasestr(content_id, ".jpeg") || strcasestr(content_id, ".png") ||
364 strcasestr(content_id, ".jpg") || strcasestr(content_id, ".gif"))
365 snprintf(buf+EM_SAFE_STRLEN(buf), buf_length - EM_SAFE_STRLEN(buf), "%s\"", content_id);
367 snprintf(buf+EM_SAFE_STRLEN(buf), buf_length - EM_SAFE_STRLEN(buf), "%s%s", content_id, ".jpeg\"");
370 EM_DEBUG_EXCEPTION(">>>> File Path Doesnot contain end line for CID ");
371 next_decode_string = true;
373 EM_SAFE_FREE(temp_cid_data);
376 result = strstr(result, "\"");
377 if (result != NULL) {
379 snprintf(buf+EM_SAFE_STRLEN(buf), buf_length - EM_SAFE_STRLEN(buf), "%s", result);
382 EM_SAFE_FREE(temp_str);
383 EM_SAFE_FREE(temp_cid_data);
388 static char *em_replace_string_with_split_file_path(char *source_string, char *old_string, char *new_string)
390 EM_DEBUG_FUNC_BEGIN();
392 char *split_str = NULL;
397 EM_IF_NULL_RETURN_VALUE(source_string, NULL);
398 EM_IF_NULL_RETURN_VALUE(old_string, NULL);
399 EM_IF_NULL_RETURN_VALUE(new_string, NULL);
401 EM_DEBUG_LOG("source_string [%s] ", source_string);
402 EM_DEBUG_LOG("old_string [%s] ", old_string);
403 EM_DEBUG_LOG("new_string [%s] ", new_string);
405 p = strstr(source_string, old_string);
408 EM_DEBUG_EXCEPTION("Orig not found in source_string");
412 buf_len = EM_SAFE_STRLEN(source_string) + 1024;
413 buffer = (char *)em_malloc(buf_len);
415 if(p - source_string < EM_SAFE_STRLEN(source_string) + 1024 + 1) {
416 strncpy(buffer, source_string, p - source_string);
418 EM_DEBUG_LOG("BUFFER [%s]", buffer);
420 split_str = em_split_file_path(p);
423 EM_DEBUG_EXCEPTION(">> SPLIT STRING IS NULL ");
427 q = strstr(split_str, old_string);
429 EM_DEBUG_LOG("Split string [%s]", split_str);
430 snprintf(buffer + EM_SAFE_STRLEN(buffer), buf_len - EM_SAFE_STRLEN(buffer), "%s%s", new_string, q+strlen(old_string)); /*prevent 34353*/
431 EM_DEBUG_LOG("BUFFER 1 [%s]", buffer);
432 EM_SAFE_FREE(split_str);
433 EM_DEBUG_FUNC_END("Suceeded");
438 EM_DEBUG_EXCEPTION("Buffer is too small.");
439 EM_SAFE_FREE(buffer);
444 EM_SAFE_FREE(split_str);
445 EM_SAFE_FREE(buffer);
447 EM_DEBUG_FUNC_END("Failed");
453 int emcore_mime_flush_receiving_buffer(void *stream, int is_file, char *boundary_string, char *boundary_end_string, int *end_of_parsing, int *err_code)
455 EM_DEBUG_FUNC_BEGIN("stream[%p], is_file[%d], boundary_string[%s], boundary_end_string[%s], end_of_parsing[%p], err_code[%p]", stream, is_file, boundary_string, boundary_end_string, end_of_parsing, err_code);
456 int err = EMAIL_ERROR_NONE;
457 int local_end_of_parsing = 0;
458 char buf[MIME_LINE_LEN] = {0, };
461 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
463 *err_code = EMAIL_ERROR_INVALID_PARAM;
468 if (!emcore_check_thread_status()) {
469 EM_DEBUG_FUNC_END("EMAIL_ERROR_CANCELLED");
471 *err_code = EMAIL_ERROR_CANCELLED;
475 if ((is_file == 0 && !emcore_mime_get_line_from_sock(stream, buf, MIME_LINE_LEN, &err)) ||
476 (is_file == 1 && !emcore_get_line_from_file(stream, buf, MIME_LINE_LEN, &err))) {
477 if (err != EMAIL_ERROR_NO_MORE_DATA) {
478 EM_DEBUG_EXCEPTION("file : [%d], emcore_mime_get_line_from_sock or emcore_mime_get_line_from_file failed", is_file);
479 local_end_of_parsing = 0;
483 local_end_of_parsing = 1;
487 if (boundary_string && boundary_end_string) {
488 if (!strcmp(buf, boundary_string)) {
489 EM_DEBUG_LOG("found boundary");
490 local_end_of_parsing = 0;
493 else if (!strcmp(buf, boundary_end_string)) {
494 EM_DEBUG_LOG("found boundary_end");
495 local_end_of_parsing = 1;
502 *end_of_parsing = local_end_of_parsing;
511 int emcore_parse_mime(void *stream, int is_file, struct _m_content_info *cnt_info, int *err_code)
513 EM_DEBUG_FUNC_BEGIN("stream[%p], is_file[%d], cnt_info[%p], err_code[%p]", stream, is_file, cnt_info, err_code);
515 struct _m_mesg *mmsg = em_malloc(sizeof(struct _m_mesg));
517 if (!mmsg) return false;
519 memset(mmsg, 0x00, sizeof(struct _m_mesg));
521 /* 1. parse the first found header */
522 EM_DEBUG_LOG(">>>>>> 1. parse the first found header");
523 if (!emcore_mime_parse_header(stream, is_file, &mmsg->rfc822header, &mmsg->header, err_code)) {
528 if (!emcore_check_thread_status()) {
529 if (err_code != NULL)
530 *err_code = EMAIL_ERROR_CANCELLED;
531 emcore_mime_free_mime(mmsg);
536 EM_DEBUG_LOG(">>>>>> 2. parse body");
537 if (mmsg && mmsg->header && mmsg->header->part_header && mmsg->header->part_header->parameter) {
538 EM_DEBUG_LOG("name[%s]", mmsg->header->part_header->parameter->name);
539 EM_DEBUG_LOG("value[%s]", mmsg->header->part_header->parameter->value);
540 EM_DEBUG_LOG("next : %p", mmsg->header->part_header->parameter->next);
543 if (!emcore_mime_parse_body(stream, is_file, mmsg, cnt_info, NULL, err_code)) {
549 EM_DEBUG_LOG(">>>>>> 3. free memory");
550 if (mmsg && mmsg->header && mmsg->header->part_header && mmsg->header->part_header->parameter) {
551 EM_DEBUG_LOG("name[%s]", mmsg->header->part_header->parameter->name);
552 EM_DEBUG_LOG("value[%s]", mmsg->header->part_header->parameter->value);
553 EM_DEBUG_LOG("next : %p", mmsg->header->part_header->parameter->next);
555 emcore_mime_free_mime(mmsg);
560 int emcore_mime_parse_header(void *stream, int is_file, struct _rfc822header **rfc822header, struct _m_mesg_header **header, int *err_code)
562 EM_DEBUG_FUNC_BEGIN("stream[%p], is_file[%d], rfc822header[%p], header[%p], err_code[%p]", stream, is_file, rfc822header, header, err_code);
564 struct _m_mesg_header *tmp_header = NULL;
565 struct _rfc822header *tmp_rfc822header = NULL;
566 char buf[MIME_LINE_LEN] = {0, };
572 if (!emcore_check_thread_status()) {
573 if (err_code != NULL)
574 *err_code = EMAIL_ERROR_CANCELLED;
579 if ((is_file == 0 && !emcore_mime_get_line_from_sock(stream, buf, MIME_LINE_LEN, err_code)) ||
580 (is_file == 1 && !emcore_get_line_from_file(stream, buf, MIME_LINE_LEN, err_code))) {
584 if (!(tmp_header = em_malloc(sizeof(struct _m_mesg_header)))) {
585 EM_DEBUG_EXCEPTION("malloc failed...");
586 if (err_code != NULL)
587 *err_code = EMAIL_ERROR_OUT_OF_MEMORY;
591 if (!emcore_check_thread_status()) {
592 if (err_code != NULL)
593 *err_code = EMAIL_ERROR_CANCELLED;
598 EM_DEBUG_LOG("buf[%s]", buf);
600 if (!strncmp(buf, CRLF_STRING, 2))
603 is_longheader = (buf[0] == ' ' || buf[0] == '\t') ? TRUE : FALSE;
606 if (!is_longheader) { /* Normal header (format : "Name : Value" or "Name : Value; Parameters" */
611 /* EM_DEBUG_FUNC_BEGIN() */
612 if ((pTemp = strtok(buf, ":")) == NULL)
615 name = EM_SAFE_STRDUP(pTemp);
617 value = strtok(NULL, CRLF_STRING);
619 em_upper_string(name);
621 else { /* Long header */
622 value = strtok(buf, CRLF_STRING);
626 /* --> 2007-05-08 by cy */
630 EM_DEBUG_LOG("> name[%s]", name);
631 EM_DEBUG_LOG("> value[%s]", value);
633 /* MIME Part Heade */
634 if (memcmp(name, "CONTENT-", 8) == 0 && value) {
636 emcore_mime_set_part_header_value(&tmp_header->part_header, name, value, err_code);
638 if (tmp_header->part_header && tmp_header->part_header->parameter) {
639 EM_DEBUG_LOG("name[%s]", tmp_header->part_header->parameter->name);
640 EM_DEBUG_LOG("value[%s]", tmp_header->part_header->parameter->value);
641 EM_DEBUG_LOG("next : %p", tmp_header->part_header->parameter->next);
644 /* MIME Version Heade */
646 else if (memcmp(name, "MIME-VERSION", 12) == 0) {
647 /* EM_DEBUG_FUNC_BEGIN() */
648 /* ignored because we need only contents information */
649 /* tmp_header->version = EM_SAFE_STRDUP(value) */
654 /* in socket stream case, ignored because we need only contents information */
656 emcore_mime_set_rfc822_header_value(&tmp_rfc822header, name, value, err_code);
659 if (!emcore_check_thread_status()) {
660 if (err_code != NULL)
661 *err_code = EMAIL_ERROR_CANCELLED;
665 if ((is_file == 0 && !emcore_mime_get_line_from_sock(stream, buf, MIME_LINE_LEN, err_code)) ||
666 (is_file == 1 && !emcore_get_line_from_file(stream, buf, MIME_LINE_LEN, err_code))) {
668 if (tmp_rfc822header)
669 emcore_mime_free_rfc822_header(tmp_rfc822header);
673 emcore_mime_free_part_header(tmp_header->part_header);
675 EM_SAFE_FREE(tmp_header->version);
676 EM_SAFE_FREE(tmp_header);
682 *header = tmp_header;
683 *rfc822header = tmp_rfc822header;
690 int emcore_mime_parse_part_header(void *stream, int is_file, struct _m_part_header **header, int *err_code)
692 EM_DEBUG_FUNC_BEGIN("stream[%p], is_file[%d], header[%p], err_code[%p]", stream, is_file, header, err_code);
694 struct _m_part_header *tmp_header = NULL;
695 char buf[MIME_LINE_LEN] = {0x00};
699 int is_longheader = false;
701 if (!emcore_check_thread_status()) {
702 if (err_code != NULL)
703 *err_code = EMAIL_ERROR_CANCELLED;
707 if ((is_file == 0 && !emcore_mime_get_line_from_sock(stream, buf, MIME_LINE_LEN, err_code)) ||
708 (is_file == 1 && !emcore_get_line_from_file(stream, buf, MIME_LINE_LEN, err_code)))
711 tmp_header = em_malloc(sizeof(struct _m_part_header));
714 EM_DEBUG_EXCEPTION("em_malloc failed");
718 memset(tmp_header, 0, sizeof(struct _m_part_header));
721 if (!strncmp(buf, CRLF_STRING, EM_SAFE_STRLEN(CRLF_STRING))) break;
723 is_longheader = (buf[0] == ' ' || buf[0] == TAB);
725 if (!is_longheader) { /* Normal header (format : "Name : Value" or "Name : Value; Parameters" */
727 p = strtok(buf , ":");
730 name = EM_SAFE_STRDUP(p);
731 value = strtok(NULL, CRLF_STRING);
732 em_upper_string(name);
735 else /* Long header */
736 value = strtok(buf, CRLF_STRING);
741 emcore_mime_set_part_header_value(&tmp_header, name, value, err_code);
743 if (!emcore_check_thread_status()) {
744 if (err_code != NULL)
745 *err_code = EMAIL_ERROR_CANCELLED;
749 if ((is_file == 0 && !emcore_mime_get_line_from_sock(stream, buf, MIME_LINE_LEN, err_code)) ||
750 (is_file == 1 && !emcore_get_line_from_file(stream, buf, MIME_LINE_LEN, err_code))) {
752 EM_SAFE_FREE(tmp_header);
758 *header = tmp_header;
766 int emcore_mime_parse_body(void *stream, int is_file, struct _m_mesg *mmsg, struct _m_content_info *cnt_info, void *callback, int *err_code)
768 EM_DEBUG_FUNC_BEGIN("stream[%p], is_file[%d], mmsg[%p], cnt_info[%p], callback[%p], err_code[%p]", stream, is_file, mmsg, cnt_info, callback, err_code);
771 EM_DEBUG_EXCEPTION("Invalid paramter");
772 *err_code = EMAIL_ERROR_INVALID_PARAM;
776 char *content_type = NULL, *content_encoding = NULL, *holder = NULL, *attachment_name, *t = NULL;
777 int type = 0, end_of_parsing = 0, size;
778 int err = EMAIL_ERROR_NONE;
780 if (!emcore_check_thread_status()) {
781 if (err_code != NULL)
782 *err_code = EMAIL_ERROR_CANCELLED;
787 content_type = emcore_mime_get_header_value(mmsg->header->part_header, CONTENT_TYPE, err_code);
789 content_type = "TEXT/PLAIN";
792 content_encoding = emcore_mime_get_header_value(mmsg->header->part_header, CONTENT_ENCODING, err_code);
793 if (!content_encoding)
794 content_encoding = "7BIT";
796 if (strstr(content_type, TEXT_STR)) type = TYPE_TEXT;
797 else if (strstr(content_type, IMAGE_STR)) type = TYPE_IMAGE;
798 else if (strstr(content_type, AUDIO_STR)) type = TYPE_AUDIO;
799 else if (strstr(content_type, VIDEO_STR)) type = TYPE_VIDEO;
800 else if (strstr(content_type, APPLICATION_STR)) type = TYPE_APPLICATION;
801 else if (strstr(content_type, MULTIPART_STR)) type = TYPE_MULTIPART;
802 else if (strstr(content_type, MESSAGE_STR)) type = TYPE_MESSAGE;
803 else type = TYPE_UNKNOWN;
807 if (mmsg->header && !emcore_mime_get_header_value(mmsg->header->part_header, CONTENT_BOUNDARY, &err)) {
808 EM_DEBUG_FUNC_END("false");
809 if (err_code != NULL)
814 if (mmsg->header && !emcore_mime_parse_part(stream, is_file, mmsg->header->part_header, &mmsg->nested, cnt_info, &end_of_parsing, &err)) {
815 EM_DEBUG_FUNC_END("false");
816 if (err_code != NULL)
821 /* after finishing body parsing, make stream empty to get next mail. (get line from sock or file until '.' is read */
822 if (end_of_parsing == true && err != EMAIL_ERROR_NO_MORE_DATA)
823 emcore_mime_flush_receiving_buffer(stream, is_file, NULL, NULL, NULL, err_code);
828 attachment_name = NULL;
830 if (mmsg->header && emcore_mime_get_header_value(mmsg->header->part_header, CONTENT_DISPOSITION, err_code)) {
831 attachment_name = emcore_mime_get_header_value(mmsg->header->part_header, CONTENT_FILENAME, err_code);
832 /* if (!attachment_name) attachment_name = "unknown" */
833 if (attachment_name) EM_DEBUG_LOG(" attachment = [%s]", attachment_name);
836 if (strstr(content_type, "PKCS7-MIME")) {
837 EM_DEBUG_LOG("Encrypted mail do not include the body");
838 cnt_info->file = em_malloc(sizeof(struct attachment_info));
839 if (cnt_info->file) {
840 cnt_info->file->type = 2;
841 cnt_info->file->name = EM_SAFE_STRDUP(attachment_name);
842 if (!emcore_mime_get_content_data(stream, is_file, false, NULL, content_encoding, &end_of_parsing, SAVE_TYPE_FILE, &holder, &size, NULL, err_code)) {
843 EM_DEBUG_EXCEPTION("emcore_mime_get_content_data failed : [%d]", err_code);
846 cnt_info->file->save = holder;
847 cnt_info->file->size = size;
852 if (cnt_info->grab_type & GRAB_TYPE_TEXT) {
854 /* get content data. content data is saved in file */
855 if (!emcore_mime_get_content_data(stream, is_file, true, NULL, content_encoding, &end_of_parsing, SAVE_TYPE_FILE, &holder, &size, NULL, err_code)) {
856 EM_DEBUG_EXCEPTION("emcore_mime_get_content_data failed : [%d]", err_code);
860 EM_DEBUG_LOG("After emcore_mime_get_content_data");
862 char *charset = mmsg->header? emcore_mime_get_header_value(mmsg->header->part_header, CONTENT_CHARSET, err_code) : NULL; /* prevent 27453 */
863 EM_DEBUG_LOG(">>>> charset [%s]", charset);
865 if (mmsg->header && mmsg->header->part_header && strstr((t = emcore_mime_get_header_value(mmsg->header->part_header, CONTENT_TYPE, err_code)) ? t : "", "HTML")) {
866 if (!charset || !strncmp(charset, "X-UNKNOWN", strlen("X-UNKNOWN")))
867 cnt_info->text.html_charset = strdup("UTF-8");
869 cnt_info->text.html_charset = EM_SAFE_STRDUP(charset);
870 EM_DEBUG_LOG(">>>> cnt_info->text.html_charset [%s]", cnt_info->text.html_charset);
872 cnt_info->text.html = holder;
873 EM_DEBUG_LOG(">>>> cnt_info->text.html [%s]", cnt_info->text.html);
875 else if (mmsg->header) {
877 if (!charset || !strncmp(charset, "X-UNKNOWN", strlen("X-UNKNOWN")))
878 cnt_info->text.plain_charset = strdup("UTF-8");
880 cnt_info->text.plain_charset = EM_SAFE_STRDUP(charset);
881 EM_DEBUG_LOG(">>>> cnt_info->text.plain_charset [%s]", cnt_info->text.plain_charset);
883 cnt_info->text.plain = holder;
884 EM_DEBUG_LOG(">>>> cnt_info->text.plain [%s]", cnt_info->text.plain);
894 int emcore_mime_parse_part(void *stream, int is_file, struct _m_part_header *parent_header, struct _m_part *nested, struct _m_content_info *cnt_info, int *eop, int *err_code)
896 EM_DEBUG_FUNC_BEGIN("stream[%p], is_file[%d], parent_header[%p], nested[%p], cnt_info[%p], eop[%p], err_code[%p]", stream, is_file, parent_header, nested, cnt_info, eop, err_code);
898 struct _m_body *tmp_body = NULL;
899 struct _m_part **p = NULL;
900 char buf[MIME_LINE_LEN] = {0x00, };
901 char boundary[BOUNDARY_LEN] = {0x00, };
902 char boundary_end[BOUNDARY_LEN] = {0x00, };
903 char mime_type_buffer[128] = { 0, };
904 char *boundary_str = NULL;
905 char *content_type = NULL;
906 char *content_encoding = NULL;
908 char *attachment_name = NULL;
909 char *content_disposition = NULL;
912 int content_disposition_type = 0;
913 int end_of_parsing = 0;
914 int size = 0, local_err_code = EMAIL_ERROR_NONE;
918 boundary_str = emcore_mime_get_header_value(parent_header, CONTENT_BOUNDARY, err_code);
920 SNPRINTF(boundary, BOUNDARY_LEN, "--%s%s", boundary_str, CRLF_STRING);
921 SNPRINTF(boundary_end, BOUNDARY_LEN, "--%s%s", boundary_str, "--\r\n");
926 /* goto the first found useful mime dat */
927 EM_DEBUG_LOG("Before first loop");
929 if (!emcore_check_thread_status()) {
930 if (err_code != NULL)
931 *err_code = EMAIL_ERROR_CANCELLED;
934 if ((is_file == 0 && !emcore_mime_get_line_from_sock(stream, buf, MIME_LINE_LEN, err_code)) ||
935 (is_file == 1 && !emcore_get_line_from_file(stream, buf, MIME_LINE_LEN, err_code))) {
936 EM_DEBUG_EXCEPTION("emcore_mime_get_line_from_sock failed.");
939 EM_DEBUG_FUNC_END("false");
943 if (!strcmp(buf, boundary))
947 EM_DEBUG_LOG("Before second loop");
949 if (!(tmp_body = em_malloc(sizeof(struct _m_body)))) {
950 EM_DEBUG_EXCEPTION("em_malloc failed.");
952 emcore_mime_free_part_body(nested->body);
954 emcore_mime_free_part(nested->next);
955 EM_DEBUG_FUNC_END("false");
959 memset(tmp_body, 0, sizeof(struct _m_body));
961 /* parsing MIME Header */
962 if (!emcore_mime_parse_part_header(stream, is_file, &tmp_body->part_header, err_code)) {
963 EM_DEBUG_EXCEPTION("emcore_mime_parse_part_header failed.");
965 emcore_mime_free_part_body(nested->body);
967 emcore_mime_free_part(nested->next);
969 emcore_mime_free_part_body(tmp_body);
973 content_type = emcore_mime_get_header_value(tmp_body->part_header, CONTENT_TYPE, err_code);
976 content_type = "TEXT/PLAIN";
978 content_encoding = emcore_mime_get_header_value(tmp_body->part_header, CONTENT_ENCODING, err_code);
979 if (!content_encoding)
980 content_encoding = "7BIT";
982 if (strstr(content_type, TEXT_STR)) type = TYPE_TEXT;
983 else if (strstr(content_type, IMAGE_STR)) type = TYPE_IMAGE;
984 else if (strstr(content_type, AUDIO_STR)) type = TYPE_AUDIO;
985 else if (strstr(content_type, VIDEO_STR)) type = TYPE_VIDEO;
986 else if (strstr(content_type, APPLICATION_STR)) type = TYPE_APPLICATION;
987 else if (strstr(content_type, MULTIPART_STR)) type = TYPE_MULTIPART;
988 else if (strstr(content_type, MESSAGE_STR)) type = TYPE_MESSAGE;
989 else type = TYPE_UNKNOWN;
993 EM_DEBUG_LOG("TYPE_MULTIPART");
994 if (!emcore_mime_get_header_value(tmp_body->part_header, CONTENT_BOUNDARY, err_code)) {
995 EM_DEBUG_EXCEPTION("emcore_mime_get_header_value failed.");
996 emcore_mime_free_part_body(tmp_body);
997 EM_DEBUG_FUNC_END("false");
1001 emcore_mime_parse_part(stream, is_file, tmp_body->part_header, &tmp_body->nested, cnt_info, &end_of_parsing, &local_err_code);
1004 nested->body = tmp_body;
1008 while (*p && (*p)->next)
1014 if (!(*p = em_malloc(sizeof(struct _m_part)))) {
1015 EM_DEBUG_EXCEPTION("em_malloc failed");
1016 if (nested->body) emcore_mime_free_part_body(nested->body);
1017 if (nested->next) emcore_mime_free_part(nested->next);
1018 emcore_mime_free_part_body(tmp_body);
1019 EM_DEBUG_FUNC_END("false");
1023 (*p)->body = tmp_body;
1028 *err_code = local_err_code;
1030 if (end_of_parsing && local_err_code != EMAIL_ERROR_NO_MORE_DATA) /* working with imap */
1031 /* if (!end_of_parsing) */ /* working with pop */ {
1032 EM_DEBUG_LOG("Enter flushing socket buffer.");
1033 emcore_mime_flush_receiving_buffer(stream, is_file, boundary, boundary_end, &end_of_parsing, err_code);
1039 EM_DEBUG_LOG("default");
1040 attachment_name = NULL;
1041 content_disposition = NULL;
1043 if (type == TYPE_MESSAGE)
1046 if (is_skip == true) {
1047 if (!emcore_mime_skip_content_data(stream, is_file, boundary_str, &end_of_parsing, &size, NULL, err_code))
1048 EM_DEBUG_EXCEPTION("emcore_mime_skip_content_data failed...");
1050 emcore_mime_free_part_body(tmp_body);
1051 EM_DEBUG_LOG_MIME("break");
1055 /* first check inline content */
1056 /* if the content id or content location exis */
1057 content_disposition = emcore_mime_get_header_value(tmp_body->part_header, CONTENT_DISPOSITION, err_code);
1058 EM_DEBUG_LOG("content_disposition : [%s]", content_disposition);
1060 attachment_name = emcore_mime_get_header_value(tmp_body->part_header, CONTENT_ID, err_code);
1061 EM_DEBUG_LOG("content_id : [%s]", attachment_name);
1063 if (attachment_name) {
1064 if (emcore_search_string_from_file(cnt_info->text.html, attachment_name, &result) == EMAIL_ERROR_NONE && result) {
1065 content_disposition_type = INLINE_ATTACHMENT;
1066 } else if (!strcasecmp(content_disposition ? content_disposition : "", "attachment")) {
1067 attachment_name = emcore_mime_get_header_value(tmp_body->part_header, CONTENT_NAME, err_code);
1069 if (!attachment_name)
1070 attachment_name = emcore_mime_get_header_value(tmp_body->part_header, CONTENT_FILENAME, err_code);
1072 content_disposition_type = ATTACHMENT;
1075 EM_DEBUG_EXCEPTION("Unknown mime type");
1078 if (!strcasecmp(content_disposition ? content_disposition : "", "attachment")) {
1079 attachment_name = emcore_mime_get_header_value(tmp_body->part_header, CONTENT_NAME, err_code);
1081 if (!attachment_name)
1082 attachment_name = emcore_mime_get_header_value(tmp_body->part_header, CONTENT_FILENAME, err_code);
1084 content_disposition_type = ATTACHMENT;
1086 } else if (!strcasecmp(content_disposition ? content_disposition : "", "inline")) {
1087 attachment_name = emcore_mime_get_header_value(tmp_body->part_header, CONTENT_NAME, err_code);
1089 if (!attachment_name)
1090 attachment_name = emcore_mime_get_header_value(tmp_body->part_header, CONTENT_FILENAME, err_code);
1092 content_disposition_type = INLINE_ATTACHMENT;
1093 } else if (strstr(content_type ? content_type : "", "PKCS7")) {
1094 attachment_name = emcore_mime_get_header_value(tmp_body->part_header, CONTENT_NAME, err_code);
1095 EM_DEBUG_LOG_MIME(">> attachment = [%s]", attachment_name ? attachment_name : NIL);
1097 content_disposition_type = ATTACHMENT;
1100 EM_DEBUG_LOG("No attachment");
1104 if (!emcore_check_thread_status()) {
1105 if (err_code != NULL)
1106 *err_code = EMAIL_ERROR_CANCELLED;
1107 EM_DEBUG_EXCEPTION("EMAIL_ERROR_CANCELLED");
1108 emcore_mime_free_part_body(tmp_body);
1109 EM_DEBUG_FUNC_END("false");
1113 EM_DEBUG_LOG("attachment_name : [%s]", attachment_name);
1114 /* get content and content information */
1115 if (!attachment_name) { /* text */
1116 /* get content by buffer */
1117 EM_DEBUG_LOG_MIME("attachment_name is NULL. It's a text message");
1118 if (!emcore_mime_get_content_data(stream, is_file, true, boundary_str, content_encoding, &end_of_parsing, SAVE_TYPE_FILE, &holder, &size, NULL, err_code)) {
1119 EM_DEBUG_EXCEPTION("emcore_mime_get_content_data failed [%d]", err_code);
1120 emcore_mime_free_part_body(tmp_body);
1124 EM_DEBUG_LOG("After emcore_mime_get_content_data");
1126 if (cnt_info->grab_type & GRAB_TYPE_TEXT) {
1127 char *charset = emcore_mime_get_header_value(tmp_body->part_header, CONTENT_CHARSET, err_code);
1128 EM_DEBUG_LOG(" charset [%s]", charset);
1130 if (tmp_body->part_header && strstr(content_type ? content_type : "", "HTML")) {
1131 if (!charset || !strncmp(charset, "X-UNKNOWN", strlen("X-UNKNOWN")))
1132 cnt_info->text.html_charset = strdup("UTF-8");
1134 cnt_info->text.html_charset = EM_SAFE_STRDUP(charset);
1135 EM_DEBUG_LOG(" cnt_info->text.html_charset [%s]", cnt_info->text.html_charset);
1137 cnt_info->text.html = holder;
1138 EM_DEBUG_LOG(" cnt_info->text.html [%s]", cnt_info->text.html);
1140 if (!charset || !strncmp(charset, "X-UNKNOWN", strlen("X-UNKNOWN")))
1141 cnt_info->text.plain_charset = strdup("UTF-8");
1143 cnt_info->text.plain_charset = EM_SAFE_STRDUP(charset);
1144 EM_DEBUG_LOG(" cnt_info->text.plain_charset [%s]", cnt_info->text.plain_charset);
1146 cnt_info->text.plain = holder;
1147 EM_DEBUG_LOG(" cnt_info->text.plain [%s]", cnt_info->text.plain);
1155 } else { /* attachment */
1156 EM_DEBUG_LOG("attachment_name is not NULL. It's a attachment");
1157 struct attachment_info *file = NULL;
1158 struct attachment_info *temp_file = cnt_info->file;
1160 file = em_malloc(sizeof(struct attachment_info));
1162 EM_DEBUG_EXCEPTION("em_malloc failed...");
1163 emcore_mime_free_part_body(tmp_body);
1164 EM_DEBUG_FUNC_END("false");
1168 file->type = content_disposition_type;
1170 EM_DEBUG_LOG("file->type : %d", file->type);
1172 file->name = EM_SAFE_STRDUP(attachment_name);
1173 file->content_id = EM_SAFE_STRDUP(tmp_body->part_header->content_id);
1174 if(tmp_body->part_header->type && tmp_body->part_header->subtype) {
1175 SNPRINTF(mime_type_buffer, 128, "%s/%s", tmp_body->part_header->type, tmp_body->part_header->subtype);
1176 file->attachment_mime_type = EM_SAFE_STRDUP(mime_type_buffer);
1179 /* check if the current file is target file */
1180 if ((cnt_info->grab_type & GRAB_TYPE_ATTACHMENT) || file->type == INLINE_ATTACHMENT) {
1181 /* get content by file */
1182 EM_DEBUG_LOG_MIME("Trying to get content");
1183 if (!emcore_mime_get_content_data(stream, is_file, false, boundary_str, content_encoding, &end_of_parsing, SAVE_TYPE_FILE, &holder, &size, NULL, err_code)) {
1184 EM_DEBUG_EXCEPTION("emcore_mime_get_content_data failed [%d]", err_code);
1185 emcore_mime_free_part_body(tmp_body);
1186 emcore_free_attachment_info(file);
1187 EM_DEBUG_FUNC_END("false");
1191 file->save = holder;
1193 /* only get content size */
1194 EM_DEBUG_LOG_MIME("Pass downloading");
1195 if (!emcore_mime_get_content_data(stream, is_file, false, boundary_str, content_encoding, &end_of_parsing, SAVE_TYPE_SIZE, NULL, &size, NULL, err_code)) {
1196 EM_DEBUG_EXCEPTION("emcore_mime_get_content_data failed [%d]", err_code);
1197 emcore_mime_free_part_body(tmp_body);
1198 emcore_free_attachment_info(file);
1199 EM_DEBUG_FUNC_END("false");
1207 EM_DEBUG_LOG("end_of_parsing [%d], err_code [%d]", end_of_parsing, *err_code);
1211 if (strstr(content_type, APPLICATION_STR)) {
1212 pTemp = content_type + EM_SAFE_STRLEN(APPLICATION_STR);
1214 if (strcasecmp(pTemp, MIME_SUBTYPE_DRM_OBJECT) == 0)
1215 file->drm = EMAIL_ATTACHMENT_DRM_OBJECT;
1216 else if (strcasecmp(pTemp, MIME_SUBTYPE_DRM_RIGHTS) == 0)
1217 file->drm = EMAIL_ATTACHMENT_DRM_RIGHTS;
1218 else if (strcasecmp(pTemp, MIME_SUBTYPE_DRM_DCF) == 0)
1219 file->drm = EMAIL_ATTACHMENT_DRM_DCF;
1222 while (temp_file && temp_file->next)
1223 temp_file = temp_file->next;
1225 if (temp_file == NULL)
1226 cnt_info->file = file;
1228 temp_file->next = file;
1231 if (!emcore_check_thread_status()) {
1232 if (err_code != NULL)
1233 *err_code = EMAIL_ERROR_CANCELLED;
1234 EM_DEBUG_EXCEPTION("EMAIL_ERROR_CANCELLED");
1235 emcore_mime_free_part_body(tmp_body);
1236 EM_DEBUG_FUNC_END("false");
1241 nested->body = tmp_body;
1245 while (*p && (*p)->next)
1251 if (!(*p = em_malloc(sizeof(struct _m_part)))) {
1252 EM_DEBUG_EXCEPTION("em_malloc failed");
1253 if (nested->body) emcore_mime_free_part_body(nested->body);
1254 if (nested->next) emcore_mime_free_part(nested->next);
1256 emcore_mime_free_part_body(tmp_body);
1257 EM_DEBUG_FUNC_END("false");
1261 (*p)->body = tmp_body;
1274 *eop = end_of_parsing;
1276 EM_DEBUG_FUNC_END("end_of_parsing [%d]", end_of_parsing);
1280 /* set RFC822 Heade */
1281 int emcore_mime_set_rfc822_header_value(struct _rfc822header **header, char *name, char *value, int *err_code)
1283 EM_DEBUG_FUNC_BEGIN("header[%p], name[%s], value[%s], err_code[%p]", header, name, value, err_code);
1288 if (!value || !*value || !name ) return false; /*prevent 34354*/
1291 *header = em_malloc(sizeof(struct _rfc822header));
1293 EM_DEBUG_EXCEPTION("em_malloc failed");
1299 em_upper_string(name);
1301 if (strncmp(name, "RETURN-PATH", strlen("RETURN-PATH")) == 0)
1302 p = &(*header)->return_path;/* Return-Rat */
1303 else if (strncmp(name, "RECEIVED", strlen("RECEIVED")) == 0)
1304 p = &(*header)->received; /* Receive */
1305 else if (strncmp(name, "REPLY-TO", strlen("REPLY-TO")) == 0)
1306 p = &(*header)->reply_to; /* Reply-T */
1307 else if (strncmp(name, "DATE", strlen("DATE")) == 0)
1308 p = &(*header)->date; /* Dat */
1309 else if (strncmp(name, "FROM", strlen("FROM")) == 0)
1310 p = &(*header)->from; /* Fro */
1311 else if (strncmp(name, "SUBJECT", strlen("SUBJECT")) == 0)
1312 p = &(*header)->subject; /* Subjec */
1313 else if (strncmp(name, "SENDER", strlen("SENDER")) == 0)
1314 p = &(*header)->sender; /* Sende */
1315 else if (strncmp(name, "TO", strlen("TO")) == 0)
1316 p = &(*header)->to; /* T */
1317 else if (strncmp(name, "CC", strlen("CC")) == 0)
1318 p = &(*header)->cc; /* C */
1319 else if (strncmp(name, "BCC", strlen("BCC")) == 0)
1320 p = &(*header)->bcc; /* Bc */
1321 else if (strncmp(name, "X-PRIORITY", strlen("X-PRIORITY")) == 0)
1322 p = &(*header)->priority; /* Prorit */
1323 else if (strncmp(name, "X-MSMAIL-PRIORITY", strlen("X-MSMAIL-PRIORITY")) == 0)
1324 p = &(*header)->ms_priority;/* Prorit */
1325 else if (strncmp(name, "DISPOSITION-NOTIFICATION-TO", strlen("DISPOSITION-NOTIFICATION-TO")) == 0)
1326 p = &(*header)->dsp_noti_to;/* Disposition-Notification-T */
1332 *p = EM_SAFE_STRDUP(value);
1333 else { /* Long Header */
1334 if (!(t = realloc(*p, strlen(*p) + strlen(value)+1))) /*prevent 34354*/
1337 strncat(t, value, strlen(value)); /*prevent 34354*/
1344 /* set MIME Part Heade */
1345 int emcore_mime_set_part_header_value(struct _m_part_header **header, char *name, char *value, int *err_code)
1347 EM_DEBUG_FUNC_BEGIN("header[%p], name[%s], value[%s], err_code[%p]", header, name, value, err_code);
1349 if (!name || !value) {
1350 EM_DEBUG_EXCEPTION("Invalid parameter");
1351 if (err_code != NULL)
1352 *err_code = EMAIL_ERROR_INVALID_PARAM;
1356 struct _parameter *p = NULL;
1360 *header = em_malloc(sizeof(struct _m_part_header));
1362 EM_DEBUG_EXCEPTION("em_malloc failed...");
1367 em_upper_string(name);
1368 em_trim_left(value);
1369 em_trim_right(value);
1371 if (!emcore_check_thread_status()) {
1372 if (err_code != NULL)
1373 *err_code = EMAIL_ERROR_CANCELLED;
1378 if (strncmp(name, "CONTENT-TYPE", strlen("CONTENT-TYPE")) == 0) {
1379 p_val = strtok(value, ";");
1382 if (!(*header)->type) { /* Content-Type */
1383 em_upper_string(p_val);
1384 (*header)->type = EM_SAFE_STRDUP(p_val);
1386 else { /* Content-Type Parameter (format : "name =value" */
1387 if (emcore_mime_get_param_from_str(p_val, &p, err_code))
1388 emcore_mime_add_param_to_list(&((*header)->parameter), p, err_code);
1389 else /* name= CRLF value */ {
1390 struct _parameter *t = (*header)->parameter;
1391 while (t && t->next) {
1395 EM_DEBUG_LOG("name : [%s]", t->name);
1396 EM_DEBUG_LOG("value : [%s]", t->value);
1398 if (t->value == NULL) {
1399 char *pointer = NULL;
1401 if (EM_SAFE_STRLEN(p_val) > 0) {
1402 if ((pointer = strchr(p_val, '\"'))) {
1403 p_val = pointer + 1;
1404 if (!*p_val) return false;
1406 if ((pointer = strchr(p_val, '\"')))
1409 /* = ? ENCODING_TYPE ? B(Q) ? ENCODED_STRING ? */
1410 int err = EMAIL_ERROR_NONE;
1411 char *utf8_text = NULL;
1413 if (!(utf8_text = emcore_decode_rfc2047_text(p_val, &err)))
1414 EM_DEBUG_EXCEPTION("emcore_decode_rfc2047_text failed [%d]", err);
1415 EM_DEBUG_LOG("utf8_text : [%s]", utf8_text);
1416 t->value = EM_SAFE_STRDUP(utf8_text);
1423 /* repeatedly get paramete */
1424 while ((p_val = strtok(NULL, ";"))) {
1425 if (emcore_mime_get_param_from_str(p_val, &p, err_code))
1426 emcore_mime_add_param_to_list(&((*header)->parameter), p, err_code);
1430 else if (strncmp(name, "CONTENT-TRANSFER-ENCODING", strlen("CONTENT-TRANSFER-ENCODING")) == 0) {
1431 em_upper_string(value);
1432 (*header)->encoding = EM_SAFE_STRDUP(value);
1434 else if (strncmp(name, "CONTENT-DESCRPTION", strlen("CONTENT-DESCRPTION")) == 0) {
1435 em_upper_string(value);
1436 (*header)->desc = EM_SAFE_STRDUP(value);
1438 else if (strncmp(name, "CONTENT-DISPOSITION", strlen("CONTENT-DISPOSITION")) == 0) {
1439 p_val = strtok(value, ";");
1442 if (!(*header)->disp_type) { /* Content-Dispositio */
1443 em_upper_string(p_val);
1444 (*header)->disp_type = EM_SAFE_STRDUP(p_val);
1446 else { /* Content-Disposition parameter (format : "name =value" */
1447 if (emcore_mime_get_param_from_str(p_val, &p, err_code))
1448 emcore_mime_add_param_to_list(&((*header)->disp_parameter), p, err_code);
1451 /* repeatedly get paramete */
1452 while ((p_val = strtok(NULL, ";"))) {
1453 if (emcore_mime_get_param_from_str(p_val, &p, err_code))
1454 emcore_mime_add_param_to_list(&((*header)->disp_parameter), p, err_code);
1458 else if (strncmp(name, "CONTENT-ID", strlen("CONTENT-ID")) == 0) {
1460 len = EM_SAFE_STRLEN(value);
1461 /* em_upper_string(value) */
1463 if ((len) && (value[0] == '<')) {
1468 if ((len > 1) && (value[len-1] == '>'))
1469 value[len-1] = '\0';
1471 (*header)->content_id = EM_SAFE_STRDUP(value);
1473 else if (strncmp(name, "CONTENT-LOCATION", strlen("CONTENT-LOCATION")) == 0)
1474 (*header)->content_location = EM_SAFE_STRDUP(value);
1476 EM_DEBUG_FUNC_END();
1480 /* get header parameter from string */
1481 int emcore_mime_get_param_from_str(char *str, struct _parameter **param, int *err_code)
1483 EM_DEBUG_FUNC_BEGIN("str[%s], param[%p], err_code[%p]", str, param, err_code);
1485 char *p_name, *p_val, *p;
1489 /* Parameter Check */
1490 if (!(p = strchr(str, '='))) return false;
1497 em_trim_left(p_name);
1498 em_trim_right(p_name);
1500 if (!*p_name) return false;
1502 if (!(*param = em_malloc(sizeof(struct _parameter)))) return false;
1504 (*param)->next = NULL;
1507 /* Check string length */
1508 if (EM_SAFE_STRLEN(p_name) > 0) {
1509 em_upper_string(p_name);
1510 (*param)->name = EM_SAFE_STRDUP(p_name);
1513 em_trim_left(p_val);
1514 em_trim_right(p_val);
1517 EM_DEBUG_LOG("Parameter value is NULL");
1521 if (EM_SAFE_STRLEN(p_val) > 0) {
1522 if ((p = strchr(p_val, '\"'))) {
1524 if (!*p_val) return false;
1526 if ((p = strchr(p_val, '\"')))
1529 if (strncmp(p_name, "BOUNDARY", strlen("BOUNDARY")) != 0 && !strstr(p_name, "NAME"))
1530 em_upper_string(p_val);
1532 /* = ? ENCODING_TYPE ? B(Q) ? ENCODED_STRING ? */
1533 int err = EMAIL_ERROR_NONE;
1534 char *utf8_text = NULL;
1536 if (!(utf8_text = emcore_decode_rfc2047_text(p_val, &err)))
1537 EM_DEBUG_EXCEPTION("emcore_decode_rfc2047_text failed [%d]", err);
1538 (*param)->value = utf8_text;
1540 EM_DEBUG_FUNC_END();
1544 /* add a parameter to parameter lis */
1545 int emcore_mime_add_param_to_list(struct _parameter **param_list, struct _parameter *param, int *err_code)
1547 struct _parameter **t = param_list;
1549 while (*t && (*t)->next)
1560 /* get header value from MIME Part Heade */
1561 char *emcore_mime_get_header_value(struct _m_part_header *header, int type, int *err_code)
1563 EM_DEBUG_FUNC_BEGIN("header[%p], type[%d], err_code[%p]", header, type, err_code);
1565 struct _parameter *p = NULL;
1569 EM_DEBUG_EXCEPTION("header[%p], type[%d]", header, type);
1571 if (err_code != NULL)
1572 *err_code = EMAIL_ERROR_INVALID_PARAM;
1578 return header->type;
1580 case CONTENT_SUBTYPE:
1581 return header->subtype;
1583 case CONTENT_ENCODING:
1584 return header->encoding;
1586 case CONTENT_CHARSET:
1588 p = header->parameter;
1591 case CONTENT_DISPOSITION:
1592 return header->disp_type;
1596 p = header->parameter;
1599 case CONTENT_FILENAME:
1601 p = header->disp_parameter;
1604 case CONTENT_BOUNDARY:
1606 p = header->parameter;
1609 case CONTENT_REPORT_TYPE:
1610 name = "REPORT-TYPE";
1611 p = header->parameter;
1615 return header->content_id;
1617 case CONTENT_LOCATION:
1618 return header->content_location;
1624 for (; p; p = p->next) {
1625 if (strcmp(p->name, name) == 0)
1631 EM_DEBUG_FUNC_END();
1636 * decode body text (quoted-printable, base64)
1637 * enc_type : encoding type (base64/quotedprintable)
1639 INTERNAL_FUNC int emcore_decode_body_text(char *enc_buf, int enc_len, int enc_type, int *dec_len, int *err_code)
1641 EM_DEBUG_FUNC_BEGIN("enc_buf[%p], enc_len[%d], enc_type[%d], dec_len[%p]", enc_buf, enc_len, enc_type, dec_len);
1642 unsigned char *content = NULL;
1644 /* too many called */
1648 case ENCQUOTEDPRINTABLE:
1649 EM_DEBUG_LOG("ENCQUOTEDPRINTABLE");
1650 content = rfc822_qprint((unsigned char *)enc_buf, (unsigned long)enc_len, (unsigned long *)dec_len);
1654 EM_DEBUG_LOG("ENCBASE64");
1655 content = rfc822_base64((unsigned char *)enc_buf, (unsigned long)enc_len, (unsigned long *)dec_len);
1667 if (enc_len < *dec_len) {
1668 EM_DEBUG_EXCEPTION("Decoded length is too big to store it");
1671 memcpy(enc_buf, content, *dec_len);
1672 enc_buf[*dec_len] = '\0';
1673 EM_SAFE_FREE(content);
1675 EM_DEBUG_FUNC_END();
1679 /* 1. if boundary is NULL, contnent has not multipart */
1680 /* 2. if boundary isn't NULL, content is from current line to the next found boundary */
1681 /* if next found boundary is the other part boundary ("--boundary"), return and set end_of_parsing to 1 */
1682 /* if next found boundary is the multipart ending boundary ("--boundary--"), return and set end_of_parsing to 0 */
1683 /* mode - SAVE_TYPE_SIZE : no saving (only hold content size */
1684 /* SAVE_TYPE_BUFFER : content is saved to buffer (holder is buffer */
1685 /* SAVE_TYPE_FILE : content is saved to temporary file (holder is file name */
1686 int emcore_mime_get_content_data(void *stream, int is_file, int is_text, char *boundary_str, char *content_encoding, int *end_of_parsing, int mode, char **holder, int *size, void *callback, int *err_code)
1688 EM_DEBUG_FUNC_BEGIN("stream[%p], is_file[%d], boundary_str[%s], content_encoding[%s], end_of_parsing[%p], mode[%d], holder[%p], size[%p], callback[%p], err_code[%p]", stream, is_file, boundary_str, content_encoding, end_of_parsing, mode, holder, size, callback, err_code);
1690 int encoding = ENC7BIT;
1691 int error = EMAIL_ERROR_NONE, ret = false;
1695 if ((mode == SAVE_TYPE_FILE || mode == SAVE_TYPE_BUFFER) && !holder)
1704 EM_DEBUG_LOG("get content");
1706 if (content_encoding) {
1707 switch (content_encoding[0]) {
1709 encoding = ENCQUOTEDPRINTABLE;
1710 break; /* qutoed-printabl */
1712 if (content_encoding[1] == 'A') {
1713 encoding = ENCBASE64;
1716 if (content_encoding[1] == 'I') {
1717 encoding = ENCBINARY;
1729 encoding = ENCOTHER;
1734 /* saving type is file */
1735 if (mode == SAVE_TYPE_FILE) {
1736 *holder = emcore_mime_get_save_file_name(&error);
1738 EM_DEBUG_LOG("holder[%s]", *holder);
1740 fd = open(*holder, O_WRONLY|O_CREAT, 0644);
1742 EM_DEBUG_EXCEPTION("holder open failed : holder is a filename that will be saved.");
1748 EM_DEBUG_LOG("from file");
1749 error = emcore_decode_body_text_from_file((FILE *)stream, boundary_str, encoding, mode, is_text, fd, holder, end_of_parsing, &sz);
1750 if (error != EMAIL_ERROR_NONE) {
1751 if (error != EMAIL_ERROR_NO_MORE_DATA) {
1752 EM_DEBUG_EXCEPTION("emcore_decode_body_text_from_file failed : [%d]", error);
1757 EM_DEBUG_LOG("from sock");
1758 error = emcore_decode_body_text_from_sock(stream, boundary_str, encoding, mode, is_text, fd, holder, end_of_parsing, &sz);
1759 if (error != EMAIL_ERROR_NONE) {
1760 EM_DEBUG_EXCEPTION("emcore_decode_body_text_from_sock failed : [%d]", error);
1767 if (err_code != NULL)
1770 if(fd>0) close(fd); /*prevent 32736*/
1777 EM_DEBUG_FUNC_END("ret [%d], sz [%d]", ret, sz);
1781 int emcore_mime_skip_content_data(void *stream,
1784 int *end_of_parsing,
1789 EM_DEBUG_FUNC_BEGIN("stream[%p], is_file[%d], boundary_str[%s], end_of_parsing[%p], size[%p], callback[%p], err_code[%p]", stream, is_file, boundary_str, end_of_parsing, size, callback, err_code);
1791 char buf[MIME_LINE_LEN] = {0x00}, boundary[BOUNDARY_LEN], boundary_end[BOUNDARY_LEN];
1797 EM_DEBUG_LOG(">>> skip content <<<<<<<<<<<<<");
1799 if (!boundary_str) { /* if no boundary, this content is from current line to end of all multipart */
1802 if (!emcore_check_thread_status()) {
1803 if (err_code != NULL)
1804 *err_code = EMAIL_ERROR_CANCELLED;
1807 if ((is_file == 0 && !emcore_mime_get_line_from_sock(stream, buf, MIME_LINE_LEN, err_code)) ||
1808 (is_file == 1 && !emcore_get_line_from_file(stream, buf, MIME_LINE_LEN, err_code))) {
1809 *end_of_parsing = 1;
1814 sz += EM_SAFE_STRLEN(buf);
1817 else { /* if there boundary, this content is from current line to ending boundary */
1818 memset(boundary, 0x00, BOUNDARY_LEN);
1819 memset(boundary_end, 0x00, BOUNDARY_LEN);
1821 SNPRINTF(boundary, BOUNDARY_LEN, "--%s%s", boundary_str, CRLF_STRING);
1822 SNPRINTF(boundary_end, BOUNDARY_LEN, "--%s%s", boundary_str, "--\r\n");
1826 if (!emcore_check_thread_status()) {
1827 if (err_code != NULL)
1828 *err_code = EMAIL_ERROR_CANCELLED;
1831 if ((is_file == 0 && !emcore_mime_get_line_from_sock(stream, buf, MIME_LINE_LEN, err_code)) ||
1832 (is_file == 1 && !emcore_get_line_from_file(stream, buf, MIME_LINE_LEN, err_code))) {
1834 *end_of_parsing = 1;
1840 if (!strcmp(buf, boundary)) { /* the other part started. the parsing of other part will be started */
1841 *end_of_parsing = 0;
1846 else if (!strcmp(buf, boundary_end)) { /* if ending boundary, the parsing of other multipart will be started */
1847 *end_of_parsing = 1;
1853 sz += EM_SAFE_STRLEN(buf);
1859 EM_DEBUG_FUNC_END();
1863 /* get temporary file name */
1864 char *emcore_mime_get_save_file_name(int *err_code)
1866 EM_DEBUG_FUNC_BEGIN();
1870 gettimeofday(&tv, NULL);
1873 memset(tempname, 0x00, sizeof(tempname));
1875 SNPRINTF(tempname, sizeof(tempname), "%s%s%d", MAILTEMP, DIR_SEPERATOR, rand());
1876 EM_DEBUG_FUNC_END();
1877 return EM_SAFE_STRDUP(tempname);
1880 /* get a line from file pointer */
1881 char *emcore_get_line_from_file(void *stream, char *buf, int size, int *err_code)
1883 if (!fgets(buf, size, (FILE *)stream)) {
1884 if (feof((FILE *)stream)) {
1885 *err_code = EMAIL_ERROR_NO_MORE_DATA;
1893 /* get a line from POP3 mail stream */
1894 /* emcore_mail_cmd_read_mail_pop3 must be called before this function */
1895 char *emcore_mime_get_line_from_sock(void *stream, char *buf, int size, int *err_code)
1897 EM_DEBUG_FUNC_BEGIN("stream[%p], buf[%p]", stream, buf);
1898 POP3LOCAL *p_pop3local = NULL;
1900 if (!stream || !buf) {
1901 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
1902 if (err_code != NULL)
1903 *err_code = EMAIL_ERROR_INVALID_PARAM;
1907 memset(buf, 0x00, size);
1909 p_pop3local = (POP3LOCAL *)(((MAILSTREAM *)stream)->local);
1911 EM_DEBUG_EXCEPTION("stream->local[%p]", p_pop3local);
1912 if (err_code != NULL)
1913 *err_code = EMAIL_ERROR_INVALID_PARAM;
1917 if (!pop3_reply((MAILSTREAM *)stream)) { /* if TRUE, check respons */
1918 EM_DEBUG_LOG("p_pop3local->response 1[%s]", p_pop3local->response);
1919 if (p_pop3local->response) {
1920 if (*p_pop3local->response == '.' && EM_SAFE_STRLEN(p_pop3local->response) == 1) {
1921 free(p_pop3local->response);
1922 p_pop3local->response = NULL;
1923 if (err_code != NULL)
1924 *err_code = EMAIL_ERROR_NO_MORE_DATA;
1925 EM_DEBUG_FUNC_END("end of response");
1928 EM_DEBUG_LOG("Not end of response");
1929 strncpy(buf, p_pop3local->response, size-1);
1930 strncat(buf, CRLF_STRING, size-(EM_SAFE_STRLEN(buf) + 1));
1932 free(p_pop3local->response);
1933 p_pop3local->response = NULL;
1939 EM_DEBUG_LOG("p_pop3local->response 2[%s]", p_pop3local->response);
1940 if (p_pop3local->response)
1942 /* if response isn't NULL, check whether this response start with '+' */
1943 /* if the first character is '+', return error because this response is normal data */
1944 strncpy(buf, p_pop3local->response, size-1);
1945 strncat(buf, CRLF_STRING, size-(EM_SAFE_STRLEN(buf)+1));
1946 free(p_pop3local->response); p_pop3local->response = NULL;
1950 EM_DEBUG_EXCEPTION("p_pop3local->response is null. network error... ");
1951 if (err_code != NULL)
1952 *err_code = EMAIL_ERROR_INVALID_RESPONSE;
1953 EM_DEBUG_FUNC_END();
1959 int received_percentage, last_notified_percentage;
1960 _pop3_received_body_size += EM_SAFE_STRLEN(buf);
1962 last_notified_percentage = (double)_pop3_last_notified_body_size / (double)_pop3_total_body_size *100.0;
1963 received_percentage = (double)_pop3_received_body_size / (double)_pop3_total_body_size *100.0;
1965 EM_DEBUG_LOG("_pop3_received_body_size = %d, _pop3_total_body_size = %d", _pop3_received_body_size, _pop3_total_body_size);
1966 EM_DEBUG_LOG("received_percentage = %d, last_notified_percentage = %d", received_percentage, last_notified_percentage);
1968 if (received_percentage > last_notified_percentage + 5) {
1969 if (!emcore_notify_network_event(NOTI_DOWNLOAD_BODY_START, _pop3_receiving_mail_id, "dummy-file", _pop3_total_body_size, _pop3_received_body_size))
1970 EM_DEBUG_EXCEPTION(" emcore_notify_network_event [NOTI_DOWNLOAD_BODY_START] Failed >>>> ");
1972 EM_DEBUG_LOG("NOTI_DOWNLOAD_BODY_START notified (%d / %d)", _pop3_received_body_size, _pop3_total_body_size);
1973 _pop3_last_notified_body_size = _pop3_received_body_size;
1976 EM_DEBUG_FUNC_END();
1980 void emcore_mime_free_param(struct _parameter *param)
1982 struct _parameter *t, *p = param;
1983 EM_DEBUG_FUNC_BEGIN();
1986 EM_SAFE_FREE(p->name);
1987 EM_SAFE_FREE(p->value);
1991 EM_DEBUG_FUNC_END();
1994 void emcore_mime_free_part_header(struct _m_part_header *header)
1996 EM_DEBUG_FUNC_BEGIN();
1997 if (!header) return ;
1998 EM_SAFE_FREE(header->type);
1999 if (header->parameter) emcore_mime_free_param(header->parameter);
2000 EM_SAFE_FREE(header->subtype);
2001 EM_SAFE_FREE(header->encoding);
2002 EM_SAFE_FREE(header->desc);
2003 EM_SAFE_FREE(header->disp_type);
2004 if (header->disp_parameter) emcore_mime_free_param(header->disp_parameter);
2005 free(header); header = NULL;
2006 EM_DEBUG_FUNC_END();
2009 void emcore_mime_free_message_header(struct _m_mesg_header *header)
2011 EM_DEBUG_FUNC_BEGIN();
2012 if (!header) return ;
2013 EM_SAFE_FREE(header->version);
2014 if (header->part_header) emcore_mime_free_part_header(header->part_header);
2015 free(header); header = NULL;
2016 EM_DEBUG_FUNC_END();
2019 void emcore_mime_free_rfc822_header(struct _rfc822header *header)
2021 EM_DEBUG_FUNC_BEGIN();
2022 if (!header) return ;
2023 EM_SAFE_FREE(header->return_path);
2024 EM_SAFE_FREE(header->received);
2025 EM_SAFE_FREE(header->reply_to);
2026 EM_SAFE_FREE(header->date);
2027 EM_SAFE_FREE(header->from);
2028 EM_SAFE_FREE(header->subject);
2029 EM_SAFE_FREE(header->sender);
2030 EM_SAFE_FREE(header->to);
2031 EM_SAFE_FREE(header->cc);
2032 EM_SAFE_FREE(header->bcc);
2033 free(header); header = NULL;
2034 EM_DEBUG_FUNC_END();
2037 void emcore_mime_free_part_body(struct _m_body *body)
2039 EM_DEBUG_FUNC_BEGIN();
2041 if (body->part_header) emcore_mime_free_part_header(body->part_header);
2042 EM_SAFE_FREE(body->text);
2043 if (body->nested.body) emcore_mime_free_part_body(body->nested.body);
2044 if (body->nested.next) emcore_mime_free_part(body->nested.next);
2045 free(body); body = NULL;
2046 EM_DEBUG_FUNC_END();
2049 void emcore_mime_free_part(struct _m_part *part)
2051 EM_DEBUG_FUNC_BEGIN();
2053 if (part->body) emcore_mime_free_part_body(part->body);
2054 if (part->next) emcore_mime_free_part(part->next);
2055 free(part);part = NULL;
2056 EM_DEBUG_FUNC_END();
2059 void emcore_mime_free_mime(struct _m_mesg *mmsg)
2061 EM_DEBUG_FUNC_BEGIN();
2064 if (mmsg->header) emcore_mime_free_message_header(mmsg->header);
2065 if (mmsg->rfc822header) emcore_mime_free_rfc822_header(mmsg->rfc822header);
2066 if (mmsg->nested.body) emcore_mime_free_part_body(mmsg->nested.body);
2067 if (mmsg->nested.next) emcore_mime_free_part(mmsg->nested.next);
2068 EM_SAFE_FREE(mmsg->text);
2069 free(mmsg); mmsg = NULL;
2070 EM_DEBUG_FUNC_END();
2073 void emcore_free_content_info(struct _m_content_info *cnt_info)
2075 EM_DEBUG_FUNC_BEGIN();
2076 struct attachment_info *p;
2078 if (!cnt_info) return ;
2079 EM_SAFE_FREE(cnt_info->text.plain);
2080 EM_SAFE_FREE(cnt_info->text.plain_charset);
2081 EM_SAFE_FREE(cnt_info->text.html);
2082 while (cnt_info->file) {
2083 p = cnt_info->file->next;
2084 EM_SAFE_FREE(cnt_info->file->name);
2085 EM_SAFE_FREE(cnt_info->file->save);
2086 EM_SAFE_FREE(cnt_info->file->attachment_mime_type);
2087 EM_SAFE_FREE(cnt_info->file->content_id);
2088 free(cnt_info->file); cnt_info->file = NULL;
2091 free(cnt_info);cnt_info = NULL;
2092 EM_DEBUG_FUNC_END();
2095 void emcore_free_attachment_info(struct attachment_info *attchment)
2097 EM_DEBUG_FUNC_BEGIN();
2098 struct attachment_info *p;
2100 if (!attchment) return;
2103 p = attchment->next;
2104 EM_SAFE_FREE(attchment->name);
2105 EM_SAFE_FREE(attchment->save);
2106 EM_SAFE_FREE(attchment->attachment_mime_type);
2107 EM_SAFE_FREE(attchment->content_id);
2108 EM_SAFE_FREE(attchment);
2112 EM_DEBUG_FUNC_END();
2115 /* get body-part in nested part */
2116 static PARTLIST *emcore_get_allnested_part_full(MAILSTREAM *stream, int msg_uid, BODY *body, struct _m_content_info *cnt_info, int *err_code, PARTLIST *section_list)
2118 EM_DEBUG_FUNC_BEGIN("stream[%p], msg_uid[%d], body[%p], cnt_info[%p], err_code[%p]", stream, msg_uid, body, cnt_info, err_code);
2120 PART *part_child = body->nested.part;
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 EM_DEBUG_FUNC_END();
2128 return section_list;
2131 /* get body-part in alternative multiple part */
2132 static PARTLIST *emcore_get_alternative_multi_part_full(MAILSTREAM *stream, int msg_uid, BODY *body, struct _m_content_info *cnt_info, int *err_code, PARTLIST *section_list)
2134 EM_DEBUG_FUNC_BEGIN("stream[%p], msg_uid[%d], body[%p], cnt_info[%p], err_code[%p]", stream, msg_uid, body, cnt_info, err_code);
2136 PART *part_child = body->nested.part;
2138 /* find the best sub part we can show */
2139 while (part_child) {
2140 section_list = emcore_get_body_full(stream, msg_uid, &part_child->body, cnt_info, err_code, section_list);
2141 part_child = part_child->next;
2144 EM_DEBUG_FUNC_END("section_list[%p]", section_list);
2145 return section_list;
2148 /* get body part in signed multiple part */
2149 static PARTLIST *emcore_get_signed_multi_part_full(MAILSTREAM *stream, int msg_uid, BODY *body, struct _m_content_info *cnt_info, int *err_code, PARTLIST *section_list)
2151 EM_DEBUG_FUNC_BEGIN("stream[%p], msg_uid[%d], body[%p], cnt_info[%p], err_code[%p]", stream, msg_uid, body, cnt_info, err_code);
2153 PART *part_child = body->nested.part;
2155 /* find the best sub part we can show */
2156 while (part_child) {
2157 section_list = emcore_get_body_full(stream, msg_uid, &part_child->body, cnt_info, err_code, section_list);
2158 part_child = part_child->next;
2161 EM_DEBUG_FUNC_END();
2162 return section_list;
2165 /* get body part in encrypted multiple part */
2166 static PARTLIST *emcore_get_encrypted_multi_part_full(MAILSTREAM *stream, int msg_uid, BODY *body, struct _m_content_info *cnt_info, int *err_code, PARTLIST *section_list)
2168 EM_DEBUG_FUNC_BEGIN("stream[%p], msg_uid[%d], body[%p], cnt_info[%p], err_code[%p]", stream, msg_uid, body, cnt_info, err_code);
2170 /* "protocol" = "application/pgp-encrypted */
2171 EM_DEBUG_FUNC_END();
2172 return section_list;
2175 /* get body part in multiple part */
2176 static PARTLIST *emcore_get_multi_part_full(MAILSTREAM *stream, int msg_uid, BODY *body, struct _m_content_info *cnt_info, int *err_code, PARTLIST *section_list)
2178 EM_DEBUG_FUNC_BEGIN("stream[%p], msg_uid[%d], body[%p], cnt_info[%p], err_code[%p]", stream, msg_uid, body, cnt_info, err_code);
2180 switch (body->subtype[0]) {
2181 case 'A': /* ALTERNATIV */
2182 return section_list = emcore_get_alternative_multi_part_full(stream, msg_uid, body, cnt_info, err_code, section_list);
2184 case 'S': /* SIGNE */
2185 return section_list = emcore_get_signed_multi_part_full(stream, msg_uid, body, cnt_info, err_code, section_list);
2187 case 'E': /* ENCRYPTE */
2188 return section_list = emcore_get_encrypted_multi_part_full(stream, msg_uid, body, cnt_info, err_code, section_list);
2190 default: /* process all unknown as MIXED (according to the RFC 2047 */
2191 return section_list = emcore_get_allnested_part_full(stream, msg_uid, body, cnt_info, err_code, section_list);
2193 EM_DEBUG_FUNC_END();
2197 PARTLIST* emcore_get_body_full(MAILSTREAM *stream, int msg_uid, BODY *body, struct _m_content_info *cnt_info, int *err_code, PARTLIST *section_list)
2199 EM_DEBUG_FUNC_BEGIN("stream[%p], msg_uid[%d], body[%p], cnt_info[%p], err_code[%p]", stream, msg_uid, body, cnt_info, err_code);
2200 char content_type_buffer[512] = { 0, };
2202 if (!stream || !body || !cnt_info) {
2203 EM_DEBUG_EXCEPTION("stream[%p], msg_uid[%d], body[%p], cnt_info[%p]", stream, msg_uid, body, cnt_info);
2204 if (err_code != NULL)
2205 *err_code = EMAIL_ERROR_INVALID_PARAM;
2206 EM_DEBUG_FUNC_END();
2210 switch (body->type) {
2212 section_list = emcore_get_multi_part_full(stream, msg_uid, body, cnt_info, err_code, section_list);
2213 EM_DEBUG_FUNC_END("section_list [%p]", section_list);
2214 return section_list;
2220 case TYPEAPPLICATION:
2227 /* Form list of attachment followed by list of inline images */
2228 if (body->id || body->location || body->disposition.type) {
2230 char filename[512] = {0, };
2231 struct attachment_info *current_ai = NULL;
2232 struct attachment_info *ai = NULL;
2234 if (emcore_get_file_pointer(body, true, filename, cnt_info, (int*)NULL) < 0)
2235 EM_DEBUG_EXCEPTION("emcore_get_file_pointer failed");
2237 /* To form list of attachment info - Attachment list followed by inline attachment list */
2238 current_ai = cnt_info->file;
2240 EM_DEBUG_LOG("current_ai - %p", current_ai);
2242 ai = em_malloc(sizeof(struct attachment_info));
2244 EM_DEBUG_EXCEPTION("em_malloc failed...");
2246 *err_code = EMAIL_ERROR_OUT_OF_MEMORY;
2250 if ((body->id) || (body->location) || ((body->disposition.type != NULL) && ((body->disposition.type[0] == 'i') || (body->disposition.type[0] == 'I'))))
2251 ai->type = 1; /* inline contents */
2253 ai->type = 2; /* attachment */
2255 ai->name = EM_SAFE_STRDUP(filename);
2256 ai->size = body->size.bytes;
2257 ai->content_id = EM_SAFE_STRDUP(body->id);
2258 if (emcore_get_content_type_from_mail_bodystruct(body, 512, content_type_buffer) == EMAIL_ERROR_NONE)
2259 ai->attachment_mime_type = EM_SAFE_STRDUP(content_type_buffer);
2261 #ifdef __ATTACHMENT_OPTI__
2262 ai->encoding = body->encoding;
2264 ai->section = EM_SAFE_STRDUP(body->sparep);
2266 EM_DEBUG_LOG("Encoding - %d Section No - %s ", ai->encoding, ai->section);
2269 EM_DEBUG_LOG("Type[%d], Name[%s], Path[%s] ", ai->type, ai->name, ai->save);
2270 if (body->type == TYPEAPPLICATION) {
2271 if (!strcasecmp(body->subtype, MIME_SUBTYPE_DRM_OBJECT))
2272 ai->drm = EMAIL_ATTACHMENT_DRM_OBJECT;
2273 else if (!strcasecmp(body->subtype, MIME_SUBTYPE_DRM_RIGHTS))
2274 ai->drm = EMAIL_ATTACHMENT_DRM_RIGHTS;
2275 else if (!strcasecmp(body->subtype, MIME_SUBTYPE_DRM_DCF))
2276 ai->drm = EMAIL_ATTACHMENT_DRM_DCF;
2277 else if (!strcasecmp(body->subtype, "pkcs7-mime"))
2278 cnt_info->grab_type = cnt_info->grab_type | GRAB_TYPE_ATTACHMENT;
2281 if (current_ai == NULL) {
2282 cnt_info->file = ai;
2284 while(current_ai->next != NULL)
2285 current_ai = current_ai->next;
2287 current_ai->next = ai;
2292 /* if (cnt_info->grab_type == GRAB_TYPE_ATTACHMENT */
2293 if (cnt_info->grab_type & GRAB_TYPE_ATTACHMENT) {
2294 if (((body->disposition.type != NULL) && ((body->disposition.type[0] == 'a') || (body->disposition.type[0] == 'A'))) && (cnt_info->file != NULL)) {
2295 PARAMETER *param = NULL;
2298 param = body->parameter;
2301 if (!strcasecmp(param->attribute, "NAME")) {
2302 fn = EM_SAFE_STRDUP(param->value);
2305 if (!strcasecmp(param->attribute, "FILENAME")) {
2306 fn = EM_SAFE_STRDUP(param->value);
2309 param = param->next;
2311 if ((fn != NULL)&& (!strcmp(fn, cnt_info->file->name)) && (body->size.bytes == cnt_info->file->size)) /* checks to zero in on particular attachmen */ {
2312 section_list = emcore_add_node(section_list, body);
2313 if (section_list == NULL) {
2314 EM_DEBUG_EXCEPTION("adding node to section list failed");
2316 *err_code = EMAIL_ERROR_OUT_OF_MEMORY;
2322 EM_DEBUG_FUNC_END("section_list [%p]", section_list);
2323 return section_list; /* single attachment download, so if a match found break the recursion */
2330 /* get a section list which has only plain, html and inline */
2331 if (!((body->disposition.type != NULL) && ((body->disposition.type[0] == 'a') || (body->disposition.type[0] == 'A'))))/* if the body not an attachmen */ {
2332 section_list = emcore_add_node(section_list, body);
2333 if (section_list == NULL) {
2334 EM_DEBUG_EXCEPTION("adding node to section list failed");
2336 *err_code = EMAIL_ERROR_OUT_OF_MEMORY;
2348 if(section_list == NULL && err_code != NULL) {
2349 *err_code = EMAIL_ERROR_ON_PARSING;
2352 EM_DEBUG_FUNC_END("section_list [%p]", section_list);
2353 return section_list;
2356 INTERNAL_FUNC int emcore_get_body_part_list_full(MAILSTREAM *stream, int msg_uid, int account_id, int mail_id, BODY *body, struct _m_content_info *cnt_info, int *err_code, PARTLIST *section_list, int event_handle)
2358 EM_DEBUG_FUNC_BEGIN("stream[%p], msg_uid[%d], body[%p], cnt_info[%p], err_code[%p]", stream, msg_uid, body, cnt_info, err_code);
2360 if (!stream || !body || !cnt_info) {
2361 EM_DEBUG_EXCEPTION("stream[%p], msg_uid[%d], body[%p], cnt_info[%p]", stream, msg_uid, body, cnt_info);
2363 if (err_code != NULL)
2364 *err_code = EMAIL_ERROR_INVALID_PARAM;
2367 section_list = emcore_get_body_full(stream, msg_uid, body, cnt_info, err_code, section_list);
2369 if (section_list == NULL) {
2370 /* assumed at least one body part exist */
2372 EM_DEBUG_EXCEPTION("emcore_get_body_full failed [%d]", *err_code);
2374 EM_DEBUG_EXCEPTION("emcore_get_body_full failed");
2378 if (emcore_get_body_part_imap_full(stream, msg_uid, account_id, mail_id, section_list, cnt_info, err_code, event_handle) < 0) {
2379 EM_DEBUG_EXCEPTION("emcore_get_body_part_imap_full failed");
2380 emcore_free_section_list(section_list);
2383 emcore_free_section_list(section_list);
2387 static int emcore_write_response_into_file(char *filename, char *write_mode, char *encoded, int encoding_type, char *subtype, int account_id, int mail_id, int *err)
2389 EM_DEBUG_FUNC_BEGIN();
2390 int temp_decoded_len = 0;
2391 int inline_support = 0;
2393 int error = EMAIL_ERROR_NONE;
2394 int not_found = true;
2395 int encoded_len = 0;
2396 int written_bytes = 0;
2397 unsigned long decoded_len = 0;
2398 char *decoded = NULL;
2399 char *decoded_temp = NULL;
2400 char save_file_name[MAX_PATH+1] = {0, };
2401 char html_cid_path[MAX_PATH+1] = {0, };
2403 PARAMETER *param = NULL;
2404 PARAMETER *param1 = NULL;
2407 if (!encoded || !filename || !write_mode) {
2408 EM_DEBUG_EXCEPTION("Invalid Param ");
2409 if( err ) *err = EMAIL_ERROR_INVALID_PARAM; /* prevent 28347 */
2414 EM_DEBUG_LOG("Encoded buffer length [%d]", EM_SAFE_STRLEN(encoded));
2415 encoded_len = EM_SAFE_STRLEN(encoded);
2417 EM_DEBUG_LOG("encoding_type [%d]", encoding_type);
2418 switch (encoding_type) {
2419 case ENCQUOTEDPRINTABLE: {
2420 unsigned char *orignal = (unsigned char *)g_strdup_printf("%s\r\n", encoded);
2421 decoded = (char *)rfc822_qprint(orignal, encoded_len + 2, &decoded_len);
2427 decoded = (char *)rfc822_base64((unsigned char *)encoded, encoded_len, &decoded_len);
2431 unsigned char *orignal = (unsigned char *)g_strdup_printf("%s\r\n", encoded);
2432 decoded = em_malloc(encoded_len + 3); /*prevent 28347*/
2434 EM_DEBUG_EXCEPTION("em_malloc failed");
2435 error = EMAIL_ERROR_OUT_OF_MEMORY;
2438 memcpy(decoded, orignal, encoded_len + 3);
2439 decoded_len = encoded_len + 2;
2445 if (decoded != NULL) {
2446 EM_DEBUG_LOG("Decoded Length [%d] " , decoded_len);
2447 EM_DEBUG_LOG("filename [%s] " , filename);
2449 if (!(fp = fopen(filename, write_mode))) {
2450 EM_DEBUG_EXCEPTION("fopen failed - %s", filename);
2451 error = EMAIL_ERROR_SYSTEM_FAILURE; /*prevent 28347*/
2455 if (subtype && subtype[0] == 'H') {
2456 char body_inline_id[512] = {0};
2458 while (strstr(decoded, "cid:")) {
2459 EM_DEBUG_LOG("Found cid:");
2461 if (g_inline_count) {
2462 BODY *body_inline = NULL;
2463 int inline_count = 0;
2464 char *decoded_content_id = NULL;
2465 while (inline_count < g_inline_count && g_inline_list[inline_count]) {
2466 EM_DEBUG_LOG("inline_count [%d], g_inline_count [%d]", inline_count, g_inline_count);
2467 body_inline = g_inline_list[inline_count];
2468 param = body_inline->disposition.parameter;
2469 param1 = body_inline->parameter;
2471 memset(body_inline_id, 0x00, 512);
2473 if (body_inline->id && EM_SAFE_STRLEN(body_inline->id) > 0) { /*prevent 27454*/
2474 EM_DEBUG_LOG("body_inline->id - %s", body_inline->id);
2475 EM_DEBUG_LOG("param - %p param1 - %p", param, param1);
2476 decoded_content_id = strstr(decoded, "cid:");
2478 if (body_inline->id[0] == '<')
2479 memcpy(body_inline_id, body_inline->id + 1, EM_SAFE_STRLEN(body_inline->id) - 2);
2481 memcpy(body_inline_id, body_inline->id , EM_SAFE_STRLEN(body_inline->id));
2483 EM_DEBUG_LOG("Inline body_inline_id [%s] ", body_inline_id);
2485 if ((param || param1) && 0 == strncmp(body_inline_id , decoded_content_id + strlen("cid:"), EM_SAFE_STRLEN(body_inline_id))) {
2486 EM_DEBUG_LOG(" Inline CID Found ");
2488 memset(save_file_name, 0x00, MAX_PATH);
2489 memset(html_cid_path, 0x00, MAX_PATH);
2491 /* Finding 'filename' attribute from content inf */
2492 emcore_get_file_pointer(body_inline, true, save_file_name, NULL, &error);
2494 if (EM_SAFE_STRLEN(save_file_name) > 0) {
2495 /* Content ID will be replaced with its file name in html */
2496 memcpy(html_cid_path, decoded_content_id , strlen("cid:") + EM_SAFE_STRLEN(body_inline_id));
2498 EM_DEBUG_LOG("Replacing %s with %s ", html_cid_path, save_file_name);
2499 if ((decoded_temp = em_replace_string(decoded, html_cid_path, save_file_name))) {
2500 EM_SAFE_FREE(decoded);
2501 decoded = decoded_temp;
2502 decoded_len = EM_SAFE_STRLEN(decoded);
2503 EM_DEBUG_LOG("Decoded Length [%d] ", decoded_len);
2506 /* only_body_download = false */
2519 EM_DEBUG_LOG("not_found is true");
2520 memset(body_inline_id, 0x00, sizeof(body_inline_id));
2521 decoded_temp = em_replace_string_with_split_file_path(decoded, "cid:", body_inline_id);
2523 /* only_body_download = false */
2524 /* EM_DEBUG_LOG(">>>> decoded_temp 2 [ %s ] ", decoded_temp) */
2525 EM_SAFE_FREE(decoded);
2526 decoded = decoded_temp;
2527 temp_decoded_len = EM_SAFE_STRLEN(body_inline_id);
2528 decoded_len = EM_SAFE_STRLEN(decoded);
2529 EM_DEBUG_LOG("Decoded Length [%d] ", decoded_len);
2536 EM_DEBUG_LOG("Trying to fwrite. decoded_len [%d]", decoded_len);
2538 if (decoded_len > 0 && fwrite(decoded, decoded_len, 1, fp) == 0) {
2539 EM_DEBUG_EXCEPTION("Error Occured while writing. fwrite(\"%s\") failed. decoded_len [%d], written_bytes [%d] ", decoded, decoded_len, written_bytes);
2540 error = EMAIL_ERROR_SYSTEM_FAILURE;
2544 EM_DEBUG_LOG("fwrite succeed");
2547 EM_DEBUG_EXCEPTION("Error Occured while decoding ");
2557 EM_SAFE_FREE(decoded);
2562 EM_DEBUG_FUNC_END();
2568 static BODY *emcore_select_body_structure_from_section_list(PARTLIST *section_list, char *section)
2570 PARTLIST *temp = section_list;
2573 while (temp != NULL) {
2575 if (!strcmp(section, body->sparep))
2577 temp = (PARTLIST *)temp->next;
2583 #define MAX_WRITE_BUFFER_SIZE 0 /* should be tuned */
2585 static int imap_mail_write_body_to_file(MAILSTREAM *stream, int account_id, int mail_id, int is_attachment, char *filepath, int uid, char *section, int encoding, int *decoded_total, char *section_subtype, int *err_code)
2587 EM_PROFILE_BEGIN(imapMailWriteBodyToFile);
2588 EM_DEBUG_FUNC_BEGIN("stream[%p], filepath[%s], uid[%d], section[%s], encoding[%d], decoded_total[%p], err_code[%p]", stream, filepath, uid, section, encoding, decoded_total, err_code);
2591 int err = EMAIL_ERROR_NONE;
2593 IMAPLOCAL *imaplocal = NULL;
2594 char tag[16], command[64];
2595 char *response = NULL;
2596 char *decoded = NULL;
2597 int body_size = 0, total = 0;
2598 char *file_id = NULL;
2599 char server_uid[129] = { 0, };
2600 char *filename = NULL;
2601 int server_response_yn = 0;
2602 int write_flag = false;
2603 unsigned char encoded[DOWNLOAD_MAX_BUFFER_SIZE] = {0, };
2604 unsigned char test_buffer[LOCAL_MAX_BUFFER_SIZE] = {0, };
2605 int flag_first_write = true;
2607 if (!stream || !filepath || !section) {
2608 EM_DEBUG_EXCEPTION("stream[%p], filepath[%s], uid[%d], section[%s], encoding[%d], decoded_total[%p]", stream, filepath, uid, section, encoding, decoded_total);
2609 err = EMAIL_ERROR_INVALID_PARAM;
2613 FINISH_OFF_IF_CANCELED;
2615 if (!(fp = fopen(filepath, "wb+"))) {
2616 EM_DEBUG_EXCEPTION("fopen failed - %s", filepath);
2617 err = EMAIL_ERROR_SYSTEM_FAILURE; /* EMAIL_ERROR_UNKNOWN */
2621 imaplocal = stream->local;
2623 if (!imaplocal->netstream) {
2624 EM_DEBUG_EXCEPTION("invalid IMAP4 stream detected... %p", imaplocal->netstream);
2625 err = EMAIL_ERROR_INVALID_STREAM;
2629 EM_DEBUG_LOG(" next_decode_string = false ");
2630 next_decode_string = false;
2632 memset(tag, 0x00, sizeof(tag));
2633 memset(command, 0x00, sizeof(command));
2635 SNPRINTF(tag, sizeof(tag), "%08lx", 0xffffffff & (stream->gensym++));
2636 SNPRINTF(command, sizeof(command), "%s UID FETCH %d BODY.PEEK[%s]\015\012", tag, uid, section);
2638 EM_DEBUG_LOG("[IMAP4] >>> [%s]", command);
2640 /* send command : get msgno/uid for all messag */
2641 if (!net_sout(imaplocal->netstream, command, (int)EM_SAFE_STRLEN(command))) {
2642 EM_DEBUG_EXCEPTION("net_sout failed...");
2643 err = EMAIL_ERROR_CONNECTION_BROKEN;
2647 while (imaplocal->netstream) {
2651 if (!emcore_check_thread_status()) {
2652 EM_DEBUG_LOG("Canceled...");
2653 /* Is it realy required ? It might cause crashes.
2654 if (imaplocal->netstream)
2655 net_close (imaplocal->netstream);
2657 imaplocal->netstream = NULL;
2658 err = EMAIL_ERROR_CANCELLED;
2662 /* receive respons */
2663 if (!(response = net_getline(imaplocal->netstream))) {
2664 EM_DEBUG_EXCEPTION("net_getline failed...");
2665 err = EMAIL_ERROR_INVALID_RESPONSE;
2668 #ifdef FEATURE_CORE_DEBUG
2669 EM_DEBUG_LOG("recv[%s]", response);
2673 if (response[0] == '*' && !server_response_yn) { /* start of respons */
2675 if ((p = strstr(response, "BODY[")) /* || (p = strstr(s + 1, "BODY["))*/) {
2676 server_response_yn = 1;
2677 p += strlen("BODY[");
2685 if (strcmp(section, p)) {
2686 err = EMAIL_ERROR_INVALID_RESPONSE;
2690 if ((p = strstr(s+1, " {"))) {
2699 body_size = atoi(p);
2701 else { /* no body length is replied */
2702 if ((p = strstr(s+1, " \""))) { /* seek the termination of double quot */
2705 if ((t = strstr(p, "\""))) {
2708 EM_DEBUG_LOG("Body : start[%p] end[%p] : body[%s]", p, t, p);
2710 EM_SAFE_FREE(response);
2711 response = EM_SAFE_STRDUP(p);
2715 err = EMAIL_ERROR_INVALID_RESPONSE;
2720 err = EMAIL_ERROR_INVALID_RESPONSE;
2725 /* sending progress noti to application.
2730 parse_file_path_to_filename(filepath, &file_id);
2733 sprintf(server_uid, "%d", uid);
2735 EM_DEBUG_LOG("file_id [%s]", file_id);
2736 EM_DEBUG_LOG("filename [%p]-[%s]", filename, filename);
2737 EM_DEBUG_LOG("body_size [%d]", body_size);
2738 EM_DEBUG_LOG("server_uid [%s]", server_uid);
2739 EM_DEBUG_LOG("mail_id [%d]", mail_id);
2741 if (is_attachment) {
2742 EM_DEBUG_LOG("Attachment number [%d]", is_attachment);
2743 if (!emcore_notify_network_event(NOTI_DOWNLOAD_ATTACH_START, mail_id, filename, is_attachment, 0))
2744 EM_DEBUG_EXCEPTION(" emcore_notify_network_event [ NOTI_DOWNLOAD_ATTACH_START] Failed >>>> ");
2745 _imap4_download_noti_interval_value = body_size *DOWNLOAD_NOTI_INTERVAL_PERCENT / 100;
2746 _imap4_total_body_size = body_size;
2749 if (multi_part_body_size) {
2750 EM_DEBUG_LOG("Multipart body size is [%d]", multi_part_body_size);
2751 if (!emcore_notify_network_event(NOTI_DOWNLOAD_MULTIPART_BODY, mail_id, filename, multi_part_body_size, 0))
2752 EM_DEBUG_EXCEPTION(" emcore_notify_network_event [ NOTI_DOWNLOAD_BODY_START] Failed >>>> ");
2753 _imap4_download_noti_interval_value = multi_part_body_size *DOWNLOAD_NOTI_INTERVAL_PERCENT / 100;
2754 /* _imap4_total_body_size should be set before calling this functio */
2755 /* _imap4_total_body_size */
2758 if (!emcore_notify_network_event(NOTI_DOWNLOAD_BODY_START, mail_id, filename, body_size, 0))
2759 EM_DEBUG_EXCEPTION(" emcore_notify_network_event [ NOTI_DOWNLOAD_BODY_START] Failed >>>>");
2760 _imap4_download_noti_interval_value = body_size *DOWNLOAD_NOTI_INTERVAL_PERCENT / 100;
2761 _imap4_total_body_size = body_size;
2764 if (_imap4_download_noti_interval_value > DOWNLOAD_NOTI_INTERVAL_SIZE) {
2765 _imap4_download_noti_interval_value = DOWNLOAD_NOTI_INTERVAL_SIZE;
2767 if (body_size < DOWNLOAD_MAX_BUFFER_SIZE) {
2768 if (net_getbuffer (imaplocal->netstream, (long)body_size, (char *)encoded) <= 0) {
2769 EM_DEBUG_EXCEPTION("net_getbuffer failed...");
2770 err = EMAIL_ERROR_NO_RESPONSE;
2774 if (!emcore_write_response_into_file(filepath, "wb+", (char *)encoded, encoding, section_subtype, account_id, mail_id, &err)) {
2775 EM_DEBUG_EXCEPTION("write_response_into_file failed [%d]", err);
2779 total = EM_SAFE_STRLEN((char *)encoded);
2780 EM_DEBUG_LOG("total = %d", total);
2781 EM_DEBUG_LOG("write_response_into_file successful %s.....", filename);
2783 if (((_imap4_last_notified_body_size + _imap4_download_noti_interval_value) <= _imap4_received_body_size)
2784 || (_imap4_received_body_size >= _imap4_total_body_size)) /* 100 */ {
2785 /* In some situation, total_encoded_len includes the length of dummy bytes. So it might be greater than body_size */
2787 if (total > body_size)
2788 gap = total - body_size;
2789 _imap4_received_body_size -= gap;
2790 _imap4_last_notified_body_size = _imap4_received_body_size;
2793 EM_DEBUG_LOG("DOWNLOADING STATUS NOTIFY : Encoded[%d] / [%d] = %d %% Completed. -- Total Decoded[%d]", total, body_size, 100*total/body_size, total);
2795 if(_imap4_total_body_size > 0)
2796 EM_DEBUG_LOG("DOWNLOADING STATUS NOTIFY : Total[%d] / [%d] = %d %% Completed.", _imap4_received_body_size, _imap4_total_body_size, 100*_imap4_received_body_size/_imap4_total_body_size);
2798 if (is_attachment) {
2799 if (_imap4_total_body_size && !emcore_notify_network_event(NOTI_DOWNLOAD_ATTACH_START, mail_id, filename, is_attachment, 100 *_imap4_received_body_size / _imap4_total_body_size))
2800 EM_DEBUG_EXCEPTION(" emcore_notify_network_event [ NOTI_DOWNLOAD_ATTACH_START] Failed >>>> ");
2803 if (multi_part_body_size) {
2804 if (!emcore_notify_network_event(NOTI_DOWNLOAD_MULTIPART_BODY, mail_id, filename, _imap4_total_body_size, _imap4_received_body_size))
2805 EM_DEBUG_EXCEPTION(" emcore_notify_network_event [ NOTI_DOWNLOAD_BODY_START] Failed >>>> ");
2808 if (!emcore_notify_network_event(NOTI_DOWNLOAD_BODY_START, mail_id, filename, _imap4_total_body_size, _imap4_received_body_size))
2809 EM_DEBUG_EXCEPTION(" emcore_notify_network_event [ NOTI_DOWNLOAD_BODY_START] Failed >>>>");
2811 } /* if (is_attachment) .. else .. */
2815 int temp_body_size = body_size;
2818 if (encoding == ENCBASE64)
2819 x = (sizeof(encoded)/78) *78; /* to solve base64 decoding pro */
2821 x = sizeof(encoded)-1;
2823 memset(test_buffer, 0x00, sizeof(test_buffer));
2824 while (temp_body_size && (total <body_size)) {
2826 memset(test_buffer, 0x00, sizeof(test_buffer));
2827 while ((total != body_size) && temp_body_size && ((EM_SAFE_STRLEN((char *)test_buffer) + x) < sizeof(test_buffer))) {
2828 memset(encoded, 0x00, sizeof(encoded));
2830 if (net_getbuffer (imaplocal->netstream, (long)x, (char *)encoded) <= 0) {
2831 EM_DEBUG_EXCEPTION("net_getbuffer failed...");
2832 err = EMAIL_ERROR_NO_RESPONSE;
2836 temp_body_size = temp_body_size - x;
2837 strncat((char *)test_buffer, (char *)encoded, EM_SAFE_STRLEN((char *)encoded));
2839 _imap4_received_body_size += EM_SAFE_STRLEN((char *)encoded);
2841 if ( !(temp_body_size/x) && temp_body_size%x)
2842 x = temp_body_size%x;
2844 if (((_imap4_last_notified_body_size + _imap4_download_noti_interval_value) <= _imap4_received_body_size)
2845 || (_imap4_received_body_size >= _imap4_total_body_size)) /* 100 */ {
2846 /* In some situation, total_encoded_len includes the length of dummy bytes. So it might be greater than body_size */
2848 if (total > body_size)
2849 gap = total - body_size;
2850 _imap4_received_body_size -= gap;
2851 _imap4_last_notified_body_size = _imap4_received_body_size;
2853 /* EM_DEBUG_LOG("DOWNLOADING STATUS NOTIFY : Encoded[%d] / [%d] = %d %% Completed. -- Total Decoded[%d]", total, body_size, 100*total/body_size, total) */
2854 EM_DEBUG_LOG("DOWNLOADING STATUS NOTIFY : Total[%d] / [%d] = %d %% Completed.", _imap4_received_body_size, _imap4_total_body_size, 100*_imap4_received_body_size/_imap4_total_body_size);
2856 if (is_attachment) {
2857 if (!emcore_notify_network_event(NOTI_DOWNLOAD_ATTACH_START, mail_id, filename, is_attachment, 100 *_imap4_received_body_size / _imap4_total_body_size))
2858 EM_DEBUG_EXCEPTION(" emcore_notify_network_event [ NOTI_DOWNLOAD_ATTACH_START] Failed >>>> ");
2861 if (multi_part_body_size) {
2862 /* EM_DEBUG_LOG("DOWNLOADING.......... : Multipart body size is [%d]", multi_part_body_size) */
2863 if (!emcore_notify_network_event(NOTI_DOWNLOAD_MULTIPART_BODY, mail_id, filename, _imap4_total_body_size, _imap4_received_body_size))
2864 EM_DEBUG_EXCEPTION(" emcore_notify_network_event [ NOTI_DOWNLOAD_BODY_START] Failed >>>> ");
2867 if (!emcore_notify_network_event(NOTI_DOWNLOAD_BODY_START, mail_id, filename, _imap4_total_body_size, _imap4_received_body_size))
2868 EM_DEBUG_EXCEPTION(" emcore_notify_network_event [ NOTI_DOWNLOAD_BODY_START] Failed >>>>");
2870 } /* if (is_attachment) .. else .. */
2876 if (flag_first_write == true) {
2877 if (!emcore_write_response_into_file(filepath, "wb+", (char *)test_buffer, encoding, section_subtype, account_id, mail_id, &err)) {
2878 EM_DEBUG_EXCEPTION("write_response_into_file %s failed [%d]", filepath, err);
2881 flag_first_write = false;
2884 if (!emcore_write_response_into_file(filepath, "ab+", (char *)test_buffer, encoding, section_subtype, account_id, mail_id, &err)) /* append */ {
2885 EM_DEBUG_EXCEPTION("write_response_into_file %s failed [%d]", filepath, err);
2889 EM_DEBUG_LOG("%d has been written", EM_SAFE_STRLEN((char *)test_buffer));
2896 err = EMAIL_ERROR_INVALID_RESPONSE;
2901 else if (!strncmp(response, tag, EM_SAFE_STRLEN(tag))) { /* end of respons */
2902 if (!strncmp(response + EM_SAFE_STRLEN(tag) + 1, "OK", 2)) {
2903 EM_SAFE_FREE(response);
2905 else { /* 'NO' or 'BAD */
2906 err = EMAIL_ERROR_IMAP4_FETCH_UID_FAILURE;
2912 else if (!strcmp(response, ")")) {
2913 /* The end of response which contains body informatio */
2917 } /* while (imaplocal->netstream) */
2919 if (decoded_total != NULL)
2920 *decoded_total = total;
2925 EM_SAFE_FREE(decoded);
2926 EM_SAFE_FREE(response);
2931 if (ret == false) { /* delete temp fil */
2932 struct stat temp_file_stat;
2933 if (filepath && stat(filepath, &temp_file_stat) == 0)
2937 if (err_code != NULL)
2940 EM_PROFILE_END(imapMailWriteBodyToFile);
2945 static int emcore_get_body_part_imap_full(MAILSTREAM *stream, int msg_uid, int account_id, int mail_id, PARTLIST *section_list, struct _m_content_info *cnt_info, int *err_code, int event_handle)
2947 EM_DEBUG_FUNC_BEGIN("stream[%p], msg_uid[%d], body[%p], cnt_info[%p], err_code[%p]", stream, msg_uid, section_list, cnt_info, err_code);
2949 int err = EMAIL_ERROR_NONE;
2950 char sections[IMAP_MAX_COMMAND_LENGTH] = { 0, };
2951 IMAPLOCAL *imaplocal = NULL;
2952 char tag[16] = { 0, }, command[IMAP_MAX_COMMAND_LENGTH] = { 0, };
2953 char section[16] = {0};
2954 char *response = NULL;
2956 int server_response_yn = 0;
2959 char filename[512] = {0, };
2960 int return_value = 0 ;
2962 unsigned char encoded[DOWNLOAD_MAX_BUFFER_SIZE] = {0};
2963 unsigned char test_buffer[LOCAL_MAX_BUFFER_SIZE] = {0};
2964 struct attachment_info *ai = NULL;
2967 int flag_first_write = 1;
2968 int imap4_total_body_download_progress = 0, progress = 0;
2970 if (!(imaplocal = stream->local) || !imaplocal->netstream || !section_list || !cnt_info) {
2971 EM_DEBUG_EXCEPTION("invalid IMAP4 stream detected...");
2972 err = EMAIL_ERROR_INVALID_PARAM;
2977 if (section_list != NULL) {
2978 PARTLIST *temp = section_list;
2980 if (cnt_info->grab_type == GRAB_TYPE_ATTACHMENT) {
2981 /* to download attachment */
2983 if (body->sparep != NULL) {
2984 snprintf(sections, sizeof(sections), "BODY.PEEK[%s]", (char *)body->sparep);
2987 EM_DEBUG_EXCEPTION("body->sparep can not be null. ");
2994 while (temp != NULL) {
2998 if ((body->type == TYPETEXT) || (body->id != NULL) || ((body->disposition.type != NULL) && ((body->disposition.type[0] == 'i') || (body->disposition.type[0] == 'I')))) {
2999 snprintf(t, sizeof(t), "BODY.PEEK[%s] ", (char *)body->sparep); /* body parts seperated by period */
3000 strcat(sections, t);
3002 temp = (PARTLIST *)temp->next;
3007 if ((EM_SAFE_STRLEN(sections) == (sizeof(sections)-1)) || (EM_SAFE_STRLEN(sections) == 0)) {
3008 EM_DEBUG_EXCEPTION(" Too many body parts or nil. IMAP command may cross 1000bytes.");
3013 if (sections[EM_SAFE_STRLEN(sections)-1] == ' ') {
3014 sections[EM_SAFE_STRLEN(sections)-1] = '\0';
3017 EM_DEBUG_LOG("sections <%s>", sections);
3019 SNPRINTF(tag, sizeof(tag), "%08lx", 0xffffffff & (stream->gensym++));
3020 SNPRINTF(command, sizeof(command), "%s UID FETCH %d (%s)\015\012", tag, msg_uid, sections);
3021 EM_DEBUG_LOG("command %s", command);
3023 if (EM_SAFE_STRLEN(command) == (sizeof(command)-1)) {
3024 EM_DEBUG_EXCEPTION("Too many body parts. IMAP command will fail.");
3029 /* send command : get msgno/uid for all message */
3030 if (!net_sout(imaplocal->netstream, command, (int)EM_SAFE_STRLEN(command))) {
3031 EM_DEBUG_EXCEPTION("net_sout failed...");
3032 err = EMAIL_ERROR_CONNECTION_BROKEN;
3036 while (imaplocal->netstream) {
3038 /* receive respons */
3039 if (!(response = net_getline(imaplocal->netstream))) {
3040 EM_DEBUG_EXCEPTION("net_getline failed...");
3041 err = EMAIL_ERROR_INVALID_RESPONSE;
3046 if (strstr(response, "BODY[")) {
3048 if (!server_response_yn) /* start of response */ {
3049 if (response[0] != '*') {
3050 err = EMAIL_ERROR_INVALID_RESPONSE;
3051 EM_DEBUG_EXCEPTION("Start of response doesn't contain *");
3055 server_response_yn = 1;
3058 flag_first_write = 1;
3060 memset(encoded, 0x00, sizeof(encoded));
3062 if (emcore_get_section_body_size(response, section, &body_size)<0) {
3063 EM_DEBUG_EXCEPTION("emcore_get_section_body_size failed [%d]", err);
3064 err = EMAIL_ERROR_INVALID_RESPONSE;
3068 EM_DEBUG_LOG("body_size-%d", body_size);
3070 /* get body from seciton_list */
3071 if ((body = emcore_select_body_structure_from_section_list(section_list, section)) == NULL) {
3072 EM_DEBUG_EXCEPTION("emcore_select_body_structure_from_section_list failed [%d]", err);
3073 err = EMAIL_ERROR_INVALID_RESPONSE;
3077 encoding = body->encoding;
3079 /* if (emcore_get_file_pointer(account_id, mail_id, body, buf, cnt_info , err)<0) {
3080 EM_DEBUG_EXCEPTION("emcore_get_file_pointer failed [%d]", err);
3084 if (!emcore_get_temp_file_name(&buf, &err)) {
3085 EM_DEBUG_EXCEPTION("emcore_get_temp_file_name failed [%d]", err);
3089 EM_DEBUG_LOG("buf : %s", buf);
3091 /* notifying UI start */
3092 /* parse_file_path_to_filename(buf, &file_id); */
3093 /* EM_DEBUG_LOG(">>>> filename - %p >>>>>>", file_id) */
3095 if (body->type == TYPETEXT && body->subtype && (!body->disposition.type || (body->disposition.type && (body->disposition.type[0] == 'i' || body->disposition.type[0] == 'I')))) {
3096 if (body->subtype[0] == 'H')
3097 cnt_info->text.html = buf;
3099 cnt_info->text.plain = buf;
3101 PARAMETER *param = NULL;
3103 param = body->parameter;
3106 if (!strcasecmp(param->attribute, "CHARSET")) {
3107 cnt_info->text.plain_charset = EM_SAFE_STRDUP(param->value);
3110 param = param->next;
3113 else if (body->subtype && (body->id || body->location || body->disposition.type)) { /*prevent 23712*/ /*refactoring : body->subtype*/
3115 if (emcore_get_file_pointer(body, false, filename, cnt_info , &err)<0) {
3116 EM_DEBUG_EXCEPTION("emcore_get_file_pointer failed [%d]", err);
3120 /* Search info from attachment list followed by inline attachment list */
3122 ai = cnt_info->file;
3123 EM_DEBUG_LOG("ai - %p ", (ai));
3125 /* For Inline content append to the end */
3126 for (i = 1; ai; ai = ai->next, i++) {
3127 if (ai->save == NULL && (ai->content_id != NULL && EM_SAFE_STRCMP(ai->content_id, body->id) == 0)) {
3128 EM_DEBUG_LOG("Found matching details ");
3135 FINISH_OFF_IF_CANCELED;
3137 if (cnt_info->grab_type == GRAB_TYPE_ATTACHMENT) {
3138 if (!emcore_notify_network_event(NOTI_DOWNLOAD_ATTACH_START, mail_id, buf, cnt_info->file_no, 0))
3139 EM_DEBUG_EXCEPTION(" emcore_notify_network_event [ NOTI_DOWNLOAD_ATTACH_START] Failed >>>> ");
3141 _imap4_download_noti_interval_value = body_size *DOWNLOAD_NOTI_INTERVAL_PERCENT / 100;
3142 _imap4_total_body_size = body_size;
3145 if (multi_part_body_size) {
3146 EM_DEBUG_LOG("Multipart body size is [%d]", multi_part_body_size);
3147 if (!emcore_notify_network_event(NOTI_DOWNLOAD_MULTIPART_BODY, mail_id, buf, multi_part_body_size, 0))
3148 EM_DEBUG_EXCEPTION(" emcore_notify_network_event [ NOTI_DOWNLOAD_BODY_START] Failed >>>> ");
3150 _imap4_download_noti_interval_value = multi_part_body_size *DOWNLOAD_NOTI_INTERVAL_PERCENT / 100;
3153 if (!emcore_notify_network_event(NOTI_DOWNLOAD_BODY_START, mail_id, buf, body_size, 0))
3154 EM_DEBUG_EXCEPTION(" emcore_notify_network_event [ NOTI_DOWNLOAD_BODY_START] Failed >>>> ");
3156 _imap4_download_noti_interval_value = body_size *DOWNLOAD_NOTI_INTERVAL_PERCENT / 100;
3157 _imap4_total_body_size = body_size;
3162 if (_imap4_download_noti_interval_value > DOWNLOAD_NOTI_INTERVAL_SIZE) {
3163 _imap4_download_noti_interval_value = DOWNLOAD_NOTI_INTERVAL_SIZE;
3166 /* EM_SAFE_FREE(file_id) */
3167 /* notifying UI end */
3169 if (body_size < DOWNLOAD_MAX_BUFFER_SIZE) {
3170 if (net_getbuffer (imaplocal->netstream, (long)body_size, (char *)encoded) <= 0) {
3171 EM_DEBUG_EXCEPTION("net_getbuffer failed...");
3172 err = EMAIL_ERROR_NO_RESPONSE;
3176 if (!emcore_write_response_into_file(buf, "wb+", (char *)encoded, encoding, body->subtype, account_id, mail_id, &err)) {
3177 EM_DEBUG_EXCEPTION("write_response_into_file failed [%d]", err);
3182 EM_DEBUG_LOG("total = %d", total);
3183 EM_DEBUG_LOG("write_response_into_file successful %s.....", buf);
3185 total = _imap4_received_body_size = EM_SAFE_STRLEN((char *)encoded);
3187 EM_DEBUG_LOG("_imap4_last_notified_body_size [%d]", _imap4_last_notified_body_size);
3188 EM_DEBUG_LOG("_imap4_download_noti_interval_value [%d]", _imap4_download_noti_interval_value);
3189 EM_DEBUG_LOG("_imap4_received_body_size [%d]", _imap4_received_body_size);
3190 EM_DEBUG_LOG("_imap4_total_body_size [%d] ", _imap4_total_body_size);
3192 if (((_imap4_last_notified_body_size + _imap4_download_noti_interval_value) <= _imap4_received_body_size)
3193 || (_imap4_received_body_size >= _imap4_total_body_size)) /* 100 */ {
3194 /* In some situation, total_encoded_len includes the length of dummy bytes. So it might be greater than body_size */
3197 if (total > body_size)
3198 gap = total - body_size;
3199 _imap4_received_body_size -= gap;
3200 _imap4_last_notified_body_size = _imap4_received_body_size;
3201 if (_imap4_total_body_size)
3202 imap4_total_body_download_progress = 100*_imap4_received_body_size/_imap4_total_body_size;
3204 imap4_total_body_download_progress = _imap4_received_body_size;
3206 EM_DEBUG_LOG("3 : body_size %d", body_size);
3209 progress = 100*total/body_size;
3211 progress = body_size;
3213 EM_DEBUG_LOG("DOWNLOADING STATUS NOTIFY : Encoded[%d] / [%d] = %d %% Completed. -- Total Decoded[%d]", total, body_size, progress, total);
3214 EM_DEBUG_LOG("DOWNLOADING STATUS NOTIFY : Total[%d] / [%d] = %d %% Completed.", _imap4_received_body_size, _imap4_total_body_size, imap4_total_body_download_progress);
3216 if (cnt_info->grab_type == GRAB_TYPE_ATTACHMENT) {
3217 if (!emcore_notify_network_event(NOTI_DOWNLOAD_ATTACH_START, mail_id, buf, cnt_info->file_no, imap4_total_body_download_progress))
3218 EM_DEBUG_EXCEPTION(" emcore_notify_network_event [ NOTI_DOWNLOAD_ATTACH_START] Failed >>>> ");
3221 if (multi_part_body_size) {
3222 /* EM_DEBUG_LOG("DOWNLOADING.......... : Multipart body size is [%d]", multi_part_body_size) */
3223 if (!emcore_notify_network_event(NOTI_DOWNLOAD_MULTIPART_BODY, mail_id, buf, _imap4_total_body_size, _imap4_received_body_size))
3224 EM_DEBUG_EXCEPTION(" emcore_notify_network_event [ NOTI_DOWNLOAD_BODY_START] Failed >>>> ");
3227 if (!emcore_notify_network_event(NOTI_DOWNLOAD_BODY_START, mail_id, buf, _imap4_total_body_size, _imap4_received_body_size))
3228 EM_DEBUG_EXCEPTION(" emcore_notify_network_event [ NOTI_DOWNLOAD_BODY_START] Failed >>>>");
3230 } /* if (is_attachment) .. else .. */
3237 int temp_body_size = body_size;
3240 if (encoding == ENCBASE64)
3241 x = (sizeof(encoded)/78) *78; /* to solve base64 decoding pro */
3243 x = sizeof(encoded)-1;
3245 memset(test_buffer, 0x00, sizeof(test_buffer));
3246 while (temp_body_size && (total <body_size)) {
3248 memset(test_buffer, 0x00, sizeof(test_buffer));
3249 while ((total != body_size) && temp_body_size && ((EM_SAFE_STRLEN((char *)test_buffer) + x) < sizeof(test_buffer))) {
3250 memset(encoded, 0x00, sizeof(encoded));
3252 if (net_getbuffer (imaplocal->netstream, (long)x, (char *)encoded) <= 0) {
3253 EM_DEBUG_EXCEPTION("net_getbuffer failed...");
3254 err = EMAIL_ERROR_NO_RESPONSE;
3259 temp_body_size = temp_body_size - x;
3260 strncat((char *)test_buffer, (char *)encoded, EM_SAFE_STRLEN((char *)encoded));
3262 _imap4_received_body_size += EM_SAFE_STRLEN((char *)encoded);
3264 EM_DEBUG_LOG("total = %d", total);
3266 if ( !(temp_body_size/x) && temp_body_size%x)
3267 x = temp_body_size%x;
3269 EM_DEBUG_LOG(" _imap4_last_notified_body_size - %d ", _imap4_last_notified_body_size);
3270 EM_DEBUG_LOG(" _imap4_download_noti_interval_value - %d ", _imap4_download_noti_interval_value);
3271 EM_DEBUG_LOG(" _imap4_received_body_size - %d ", _imap4_received_body_size);
3272 EM_DEBUG_LOG(" _imap4_received_body_size - %d ", _imap4_received_body_size);
3273 EM_DEBUG_LOG(" _imap4_total_body_size - %d ", _imap4_total_body_size);
3275 if (_imap4_total_body_size)
3276 imap4_total_body_download_progress = 100*_imap4_received_body_size/_imap4_total_body_size;
3278 imap4_total_body_download_progress = _imap4_received_body_size;
3280 if (((_imap4_last_notified_body_size + _imap4_download_noti_interval_value) <= _imap4_received_body_size)
3281 || (_imap4_received_body_size >= _imap4_total_body_size)) /* 100 */ {
3282 /* In some situation, total_encoded_len includes the length of dummy bytes. So it might be greater than body_size */
3284 if (total > body_size)
3285 gap = total - body_size;
3286 _imap4_received_body_size -= gap;
3287 _imap4_last_notified_body_size = _imap4_received_body_size;
3289 progress = 100*total/body_size; /*prevent 40023*/
3291 EM_DEBUG_LOG("DOWNLOADING STATUS NOTIFY : Encoded[%d] / [%d] = %d %% Completed. -- Total Decoded[%d]", total, body_size, progress, total);
3292 EM_DEBUG_LOG("DOWNLOADING STATUS NOTIFY : Total[%d] / [%d] = %d %% Completed.", _imap4_received_body_size, _imap4_total_body_size, imap4_total_body_download_progress);
3294 if (cnt_info->grab_type == GRAB_TYPE_ATTACHMENT) {
3295 if (!emcore_notify_network_event(NOTI_DOWNLOAD_ATTACH_START, mail_id, buf, cnt_info->file_no, imap4_total_body_download_progress))
3296 EM_DEBUG_EXCEPTION(" emcore_notify_network_event [ NOTI_DOWNLOAD_ATTACH_START] Failed >>>> ");
3299 if (multi_part_body_size) {
3300 /* EM_DEBUG_LOG("DOWNLOADING.......... : Multipart body size is [%d]", multi_part_body_size) */
3301 if (!emcore_notify_network_event(NOTI_DOWNLOAD_MULTIPART_BODY, mail_id, buf, _imap4_total_body_size, _imap4_received_body_size))
3302 EM_DEBUG_EXCEPTION(" emcore_notify_network_event [ NOTI_DOWNLOAD_BODY_START] Failed >>>> ");
3305 if (!emcore_notify_network_event(NOTI_DOWNLOAD_BODY_START, mail_id, buf, _imap4_total_body_size, _imap4_received_body_size))
3306 EM_DEBUG_EXCEPTION(" emcore_notify_network_event [ NOTI_DOWNLOAD_BODY_START] Failed >>>>");
3308 } /* if (is_attachment) .. else .. */
3312 if (flag_first_write == 1) {
3313 if (!emcore_write_response_into_file(buf, "wb+", (char *)test_buffer, encoding, body->subtype, account_id, mail_id, &err)) {
3314 EM_DEBUG_EXCEPTION("write_response_into_file %s failed [%d]", buf, err);
3318 flag_first_write = 0;
3321 if (!emcore_write_response_into_file(buf, "ab+", (char *)test_buffer, encoding, body->subtype, account_id, mail_id, &err)) /* append */ {
3322 EM_DEBUG_EXCEPTION("write_response_into_file %s failed [%d]", buf, err);
3327 EM_DEBUG_LOG("%d has been written", EM_SAFE_STRLEN((char *)test_buffer));
3331 else if (!strncmp(response, tag, EM_SAFE_STRLEN(tag))) /* end of respons */ {
3332 if (!strncmp(response + EM_SAFE_STRLEN(tag) + 1, "OK", 2))
3333 EM_SAFE_FREE(response);
3334 else /* 'NO' or 'BAD */ {
3335 err = EMAIL_ERROR_IMAP4_FETCH_UID_FAILURE;
3342 else if (!strcmp(response, ")")) {
3357 EM_SAFE_FREE(response);
3359 return return_value;
3362 static int _find_duplicated_inline_content_file(char *input_source_file_name, struct _m_content_info *input_content_info, bool *output_result)
3364 EM_DEBUG_FUNC_BEGIN("input_source_file_name [%p], input_content_info [%p], output_result [%p]", input_source_file_name,input_content_info, output_result);
3365 struct attachment_info *cur_attachment_info = NULL;
3366 int err = EMAIL_ERROR_NONE;
3367 bool result = false;
3369 if(!input_source_file_name || !input_content_info || !output_result) {
3370 EM_DEBUG_EXCEPTION("Invalid parameter");
3371 return EMAIL_ERROR_INVALID_PARAM;
3374 cur_attachment_info = input_content_info->file;
3376 while(cur_attachment_info) {
3377 if(strcmp(input_source_file_name, cur_attachment_info->name) == 0) {
3381 cur_attachment_info = cur_attachment_info->next;
3384 *output_result = result;
3386 EM_DEBUG_FUNC_END("err [%d], result [%d]", err, result);
3390 static int _modify_file_name_string_for_duplicated_inline_content(char *input_source_file_name, struct _m_content_info *input_content_info)
3392 EM_DEBUG_FUNC_BEGIN("input_source_file_name [%p], input_content_info [%p]", input_source_file_name,input_content_info);
3393 int err = EMAIL_ERROR_NONE;
3394 char temp_file_name[MAX_PATH] = { 0, };
3395 char *file_name = NULL;
3396 char *extension = NULL;
3398 if(!input_source_file_name || !input_content_info) {
3399 EM_DEBUG_EXCEPTION("Invalid parameter");
3400 return EMAIL_ERROR_INVALID_PARAM;
3403 if ( (err = em_get_file_name_and_extension_from_file_path(input_source_file_name, &file_name, &extension)) != EMAIL_ERROR_NONE) {
3404 EM_DEBUG_EXCEPTION("em_get_file_name_and_extension_from_file_path failed [%d]", err);
3408 if(file_name && extension)
3409 SNPRINTF(temp_file_name, MAX_PATH, "%s_.%s", file_name, extension);
3411 SNPRINTF(temp_file_name, MAX_PATH, "%s_", file_name);
3413 EM_SAFE_STRCPY(input_source_file_name, temp_file_name);
3417 EM_SAFE_FREE(file_name);
3418 EM_SAFE_FREE(extension);
3420 EM_DEBUG_FUNC_END("err [%d], temp_file_name [%s]", err, temp_file_name);
3424 static int emcore_get_file_pointer(BODY *body, bool input_check_duplicated_file_name, char *output_file_name_string, struct _m_content_info *cnt_info , int *err)
3426 EM_DEBUG_FUNC_BEGIN();
3428 char *decoded_filename = NULL;
3429 char attachment_file_name[MAX_PATH] = { 0, };
3430 char attachment_file_name_source[MAX_PATH] = {0, };
3431 int error = EMAIL_ERROR_NONE;
3432 bool file_name_duplicated = false;
3434 if ((body->type == TYPETEXT) && (body->disposition.type == NULL)) {
3435 EM_DEBUG_LOG("body->type == TYPETEXT");
3437 EM_DEBUG_EXCEPTION("But, cnt_info is null");
3438 error = EMAIL_ERROR_INVALID_PARAM;
3441 if (body->subtype[0] == 'H') {
3442 if (cnt_info->text.plain_charset != NULL) {
3443 memcpy(output_file_name_string, cnt_info->text.plain_charset, EM_SAFE_STRLEN(cnt_info->text.plain_charset));
3444 strcat(output_file_name_string, HTML_EXTENSION_STRING);
3447 memcpy(output_file_name_string, "UTF-8.htm", strlen("UTF-8.htm"));
3449 cnt_info->text.html = EM_SAFE_STRDUP(output_file_name_string);
3452 PARAMETER *param = body->parameter;
3453 char charset_string[512];
3455 if (emcore_get_attribute_value_of_body_part(param, "CHARSET", charset_string, 512, false, &error)) {
3456 cnt_info->text.plain_charset = EM_SAFE_STRDUP(charset_string);
3457 memcpy(output_file_name_string, cnt_info->text.plain_charset, EM_SAFE_STRLEN(cnt_info->text.plain_charset));
3460 memcpy(output_file_name_string, "UTF-8", strlen("UTF-8"));
3462 cnt_info->text.plain = EM_SAFE_STRDUP(output_file_name_string);
3466 else if ((body->id != NULL) || ((body->disposition.type != NULL) && ((body->disposition.type[0] == 'i') || (body->disposition.type[0] == 'I')))) {
3467 /* body id is exising or disposition type is inline */
3469 if (body->parameter) /* Get actual name of file */ {
3470 PARAMETER *param_body = body->parameter;
3471 if (!emcore_get_attribute_value_of_body_part(param_body, "NAME", attachment_file_name_source, MAX_PATH, true, &error))
3472 emcore_get_attribute_value_of_body_part(param_body, "CHARSET", attachment_file_name_source, MAX_PATH, true, &error);
3473 if (!emcore_make_attachment_file_name_with_extension(attachment_file_name_source, body->subtype, attachment_file_name, MAX_PATH, &error)) {
3474 EM_DEBUG_EXCEPTION("emcore_make_attachment_file_name_with_extension failed [%d]", error);
3478 else if (body->disposition.type) {
3479 PARAMETER *param_disposition = body->disposition.parameter;
3480 EM_DEBUG_LOG("body->disposition.type exist");
3481 emcore_get_attribute_value_of_body_part(param_disposition, "filename", attachment_file_name_source, MAX_PATH, true, &error);
3482 if (!emcore_make_attachment_file_name_with_extension(attachment_file_name_source, body->subtype, attachment_file_name, MAX_PATH, &error)) {
3483 EM_DEBUG_EXCEPTION("emcore_make_attachment_file_name_with_extension failed [%d]", error);
3487 else { /* body id is not null but disposition type is null */
3488 if ((body->id[0] == '<'))
3489 SNPRINTF(attachment_file_name, MAX_PATH, "%s", body->id+1); /* fname = em_parse_filename(body->id + 1 */
3491 SNPRINTF(attachment_file_name, MAX_PATH, "%s", body->id); /* fname = em_parse_filename(body->id */
3493 len = EM_SAFE_STRLEN(attachment_file_name);
3495 if ((len > 1) && (attachment_file_name[len-1] == '>'))
3496 attachment_file_name[len - 1] = '\0';
3497 decoded_filename = emcore_decode_rfc2047_text(attachment_file_name, &error);
3499 EM_DEBUG_LOG("attachment_file_name [%s]", attachment_file_name);
3500 if (decoded_filename != NULL)
3501 memcpy(output_file_name_string, decoded_filename, EM_SAFE_STRLEN(decoded_filename));
3503 memcpy(output_file_name_string, attachment_file_name, EM_SAFE_STRLEN(attachment_file_name));
3506 else if (body->disposition.type != NULL) { /* disposition type is existing and not inline and body_id is nul */
3507 PARAMETER *param = body->parameter;
3508 if (!emcore_get_attribute_value_of_body_part(param, "NAME", attachment_file_name, MAX_PATH, true, &error))
3509 emcore_get_attribute_value_of_body_part(param, "FILENAME", attachment_file_name, MAX_PATH, true, &error);
3510 memcpy(output_file_name_string, attachment_file_name, EM_SAFE_STRLEN(attachment_file_name));
3513 if(input_check_duplicated_file_name) {
3514 if ( (error = _find_duplicated_inline_content_file(output_file_name_string, cnt_info, &file_name_duplicated)) != EMAIL_ERROR_NONE) {
3515 EM_DEBUG_EXCEPTION("_find_duplicated_inline_content_file failed [%d]", error);
3519 if (file_name_duplicated == true) {
3520 if ( ( error = _modify_file_name_string_for_duplicated_inline_content(output_file_name_string, cnt_info)) != EMAIL_ERROR_NONE) {
3521 EM_DEBUG_EXCEPTION("_modify_file_name_string_for_duplicated_inline_content failed [%d]", error);
3529 EM_SAFE_FREE(decoded_filename);
3534 EM_DEBUG_FUNC_END("output_file_name_string[%s], error [%d]", output_file_name_string, error);
3539 static PARTLIST *emcore_add_node(PARTLIST *section_list, BODY *body)
3541 PARTLIST *temp = (PARTLIST *)malloc(sizeof(PARTLIST));
3544 EM_DEBUG_EXCEPTION("PARTLIST node creation failed");
3550 if (section_list == NULL)/* first node in list */ {
3551 section_list = temp;
3553 else/* has min 1 nod */ {
3554 PARTLIST *t = section_list;
3555 while (t->next != NULL) /* go to last nod */ {
3556 t = (PARTLIST *) t->next;
3558 t->next = (PART *)temp;/* I think this should be PARTLIST, but why this is PART */
3560 in imap-2007e/c-client/mail.h
3567 return section_list;
3571 static void emcore_free_section_list(PARTLIST *section_list)
3573 PARTLIST *temp = NULL;
3575 while (section_list != NULL) {
3576 temp = (PARTLIST *)section_list->next;
3577 EM_SAFE_FREE(section_list);
3578 section_list = temp;
3582 static int emcore_get_section_body_size(char *response, char *section, int *body_size)
3587 if ((p = strstr(response, "BODY[")) /* || (p = strstr(s + 1, "BODY["))*/) {
3589 p += strlen("BODY[");
3599 /* if (strcmp(section, p)) {
3600 err = EMAIL_ERROR_INVALID_RESPONSE;
3603 p = strstr(s+1, " {");
3616 /* sending progress noti to application.
3634 static char *em_parse_filename(char *filename)
3636 EM_DEBUG_FUNC_BEGIN("filename [%p] ", filename);
3638 EM_DEBUG_EXCEPTION("filename is NULL ");
3642 char delims[] = "@";
3643 char *result = NULL;
3644 static char parsed_filename[512] = {0, };
3646 memset(parsed_filename, 0x00, 512);
3648 if (!strstr(filename, delims)) {
3649 EM_DEBUG_EXCEPTION("FileName does not contain @ ");
3653 result = strtok(filename, delims);
3655 if (strcasestr(result, ".bmp") || strcasestr(result, ".jpeg") || strcasestr(result, ".png") || strcasestr(result, ".jpg"))
3656 sprintf(parsed_filename + EM_SAFE_STRLEN(parsed_filename), "%s", result);
3658 sprintf(parsed_filename + EM_SAFE_STRLEN(parsed_filename), "%s%s", result, ".jpeg");
3660 EM_DEBUG_LOG(">>> FileName [ %s ] ", result);
3662 EM_DEBUG_FUNC_END("parsed_filename [%s] ", parsed_filename);
3663 return parsed_filename;
3666 #define CONTENT_TYPE_STRING_IN_MIME_HEAEDER "Content-Type:"
3668 INTERNAL_FUNC int emcore_get_content_type_from_mime_string(char *input_mime_string, char **output_content_type)
3670 EM_DEBUG_FUNC_BEGIN("input_mime_string [%p], output_content_type [%p]", input_mime_string, output_content_type);
3672 int err = EMAIL_ERROR_NONE;
3673 int temp_mime_header_string_length = 0;
3674 char result_content_type[256] = { 0, };
3675 char *temp_mime_header_string = NULL;
3676 char *temp_content_type_start = NULL;
3677 char *temp_content_type_end = NULL;
3679 if(input_mime_string == NULL || output_content_type == NULL) {
3680 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
3681 err = EMAIL_ERROR_INVALID_PARAM;
3685 temp_mime_header_string_length = EM_SAFE_STRLEN(input_mime_string);
3686 temp_mime_header_string = input_mime_string;
3688 EM_DEBUG_LOG("temp_mime_header_string [%s]", temp_mime_header_string);
3690 temp_content_type_start = strcasestr(temp_mime_header_string, CONTENT_TYPE_STRING_IN_MIME_HEAEDER);
3692 if(temp_content_type_start == NULL) {
3693 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_DATA");
3694 err = EMAIL_ERROR_INVALID_DATA;
3698 temp_content_type_start += EM_SAFE_STRLEN(CONTENT_TYPE_STRING_IN_MIME_HEAEDER);
3699 temp_content_type_end = temp_content_type_start;
3701 while(temp_content_type_end && temp_content_type_end < (temp_mime_header_string + temp_mime_header_string_length) && *temp_content_type_end != ';')
3702 temp_content_type_end++;
3704 if(temp_content_type_end && *temp_content_type_end == ';') {
3705 if(temp_content_type_end - temp_content_type_start < 256) {
3706 memcpy(result_content_type, temp_content_type_start, temp_content_type_end - temp_content_type_start);
3707 EM_DEBUG_LOG("result_content_type [%s]", result_content_type);
3708 *output_content_type = EM_SAFE_STRDUP(result_content_type);
3709 em_trim_left(*output_content_type);
3713 EM_DEBUG_EXCEPTION("temp_content_type_end - temp_content_type_start [%d]", temp_content_type_end - temp_content_type_start);
3714 err = EMAIL_ERROR_DATA_TOO_LONG;
3722 EM_DEBUG_FUNC_END("err [%d]", err);
3726 #define SUBTYPE_STRING_LENGTH 128
3728 INTERNAL_FUNC int emcore_get_content_type_from_mail_bodystruct(BODY *input_body, int input_buffer_length, char *output_content_type)
3730 EM_DEBUG_FUNC_BEGIN("input_body [%p], input_buffer_length [%d], output_content_type [%p]", input_body, input_buffer_length, output_content_type);
3731 int err = EMAIL_ERROR_NONE;
3732 char subtype_string[SUBTYPE_STRING_LENGTH] = { 0 , };
3734 if(input_body == NULL || output_content_type == NULL || input_buffer_length == 0) {
3735 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
3736 err = EMAIL_ERROR_INVALID_PARAM;
3740 EM_SAFE_STRNCPY(subtype_string, input_body->subtype, SUBTYPE_STRING_LENGTH-1); /* prevent 21983 */
3741 em_lower_string(subtype_string);
3743 switch(input_body->type) {
3745 SNPRINTF(output_content_type, input_buffer_length, "text/%s", subtype_string);
3747 case TYPEMULTIPART :
3748 SNPRINTF(output_content_type, input_buffer_length, "multipart/%s", subtype_string);
3751 SNPRINTF(output_content_type, input_buffer_length, "message/%s", subtype_string);
3753 case TYPEAPPLICATION :
3754 SNPRINTF(output_content_type, input_buffer_length, "application/%s", subtype_string);
3757 SNPRINTF(output_content_type, input_buffer_length, "audio/%s", subtype_string);
3760 SNPRINTF(output_content_type, input_buffer_length, "image/%s", subtype_string);
3763 SNPRINTF(output_content_type, input_buffer_length, "video/%s", subtype_string);
3766 SNPRINTF(output_content_type, input_buffer_length, "model/%s", subtype_string);
3769 SNPRINTF(output_content_type, input_buffer_length, "other/%s", subtype_string);
3772 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
3773 err = EMAIL_ERROR_INVALID_PARAM;
3778 EM_DEBUG_LOG("output_content_type [%s]", output_content_type);
3782 EM_DEBUG_FUNC_END("err [%d]", err);
3786 INTERNAL_FUNC int emcore_get_attribute_value_of_body_part(PARAMETER *input_param, char *atribute_name, char *output_value, int output_buffer_length, int with_rfc2047_text, int *err_code)
3788 EM_DEBUG_FUNC_BEGIN("input_param [%p], atribute_name [%s], output_buffer_length [%d], with_rfc2047_text [%d]", input_param, atribute_name, output_buffer_length, with_rfc2047_text);
3789 PARAMETER *temp_param = input_param;
3790 char *decoded_value = NULL, *result_value = NULL;
3791 int ret = false, err = EMAIL_ERROR_NONE;
3794 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
3795 err = EMAIL_ERROR_INVALID_PARAM;
3799 memset(output_value, 0, output_buffer_length);
3801 while (temp_param) {
3802 EM_DEBUG_LOG("temp_param->attribute [%s]", temp_param->attribute);
3803 if (!strcasecmp(temp_param->attribute, atribute_name)) {
3804 EM_DEBUG_LOG("temp_param->value [%s]", temp_param->value);
3805 if (temp_param->value) {
3806 if (with_rfc2047_text) {
3807 decoded_value = emcore_decode_rfc2047_text(temp_param->value, &err);
3809 result_value = decoded_value;
3811 result_value = decoded_value;
3814 result_value = temp_param->value;
3817 EM_DEBUG_EXCEPTION("EMAIL_ERROR_DATA_NOT_FOUND");
3818 err = EMAIL_ERROR_DATA_NOT_FOUND;
3821 EM_DEBUG_LOG("result_value [%s]", result_value);
3823 if(output_buffer_length > EM_SAFE_STRLEN(result_value)) {
3824 strncpy(output_value, result_value, output_buffer_length);
3825 output_value[EM_SAFE_STRLEN(result_value)] = NULL_CHAR;
3829 EM_DEBUG_EXCEPTION("buffer is too short");
3830 err = EMAIL_ERROR_DATA_TOO_LONG;
3837 temp_param = temp_param->next;
3841 EM_SAFE_FREE(decoded_value);
3846 EM_DEBUG_FUNC_END("ret [%d]", ret);
3852 *download body part of imap mail (body-text and attachment)
3854 static int emcore_get_body_part_imap(MAILSTREAM *stream, int account_id, int mail_id, int msg_uid, BODY *body, struct _m_content_info *cnt_info, int *err_code)
3856 EM_DEBUG_FUNC_BEGIN("stream[%p], msg_uid[%d], body[%p], cnt_info[%p], err_code[%p]", stream, msg_uid, body, cnt_info, err_code);
3858 int err = EMAIL_ERROR_NONE, ret = -1;
3859 struct attachment_info **ai;
3860 struct attachment_info *prev_ai = NULL;
3861 struct attachment_info *next_ai = NULL;
3862 char *savefile = NULL;
3863 char *o_data = NULL;
3864 char filename[MAX_PATH + 1] = { 0, };
3865 char *decoded_filename = NULL;
3866 int is_attachment = 0;
3868 char *filename_temp = NULL;
3869 char charset_value_buffer[512] = { 0, };
3870 char content_type_buffer[512] = { 0, };
3875 char *sparep = NULL;
3876 unsigned short encode = 0;
3877 int section_plain = 0;
3878 int section_html = 0;
3879 int is_pbd = (account_id == 0 && mail_id == 0) ? true : false;
3882 EM_DEBUG_LOG("Grab Type [ %d ] ", cnt_info->grab_type);
3885 if (body->type > TYPEOTHER) { /* unknown type */
3886 EM_DEBUG_EXCEPTION("Unknown type.");
3887 err = EMAIL_ERROR_NOT_SUPPORTED;
3891 if (NULL == body->subtype) {
3892 EM_DEBUG_LOG("body->subtype is null. "); /* not exceptional case */
3893 if (err_code != NULL)
3894 *err_code = EMAIL_ERROR_INVALID_PARAM;
3899 if (!emcore_get_temp_file_name(&o_data, &err) || !o_data) {
3900 EM_DEBUG_EXCEPTION("emcore_get_temp_file_name failed [%d]", err);
3901 if (err_code != NULL)
3907 if (body->subtype[0] == 'P') { /* Sub type is PLAIN_TEX */
3908 if (cnt_info->text.plain != NULL)
3909 EM_SAFE_FREE(o_data);
3912 if (body->type == TYPETEXT && body->subtype &&
3913 (!body->disposition.type || (body->disposition.type && (body->disposition.type[0] == 'i' || body->disposition.type[0] == 'I')))) {
3914 if (body->subtype[0] == 'H') /* HTM */
3915 cnt_info->text.html = o_data;
3917 cnt_info->text.plain = o_data;
3919 memset(charset_value_buffer, 0, 512);
3921 if (emcore_get_attribute_value_of_body_part(body->parameter, "CHARSET", charset_value_buffer, 512, true, &err)) {
3922 cnt_info->text.plain_charset = EM_SAFE_STRDUP(charset_value_buffer);
3923 EM_DEBUG_LOG(">>>>> CHARSET [%s] ", filename);
3928 if ((body->id) && EM_SAFE_STRLEN(body->id) > 1) { /* if Content-ID or Content-Location exists, it is inline contents */
3929 EM_DEBUG_LOG("body->id exist");
3931 /* Get actual name of file - fix for inline images to be stored with actual names and not .jpeg */
3932 if (body->parameter) {
3933 PARAMETER *param1 = body->parameter;
3935 EM_DEBUG_LOG("param1->attribute - %s ", param1->attribute);
3936 if (!strcasecmp(param1->attribute, "NAME")) { /* attribute is "NAME" */
3937 char *extcheck = NULL;
3939 if (param1->value) {
3940 decoded_filename = emcore_decode_rfc2047_text(param1->value, &err);
3941 strncpy(filename, decoded_filename, MAX_PATH);
3942 EM_SAFE_FREE(decoded_filename);
3944 EM_DEBUG_LOG(">>>>> FILENAME [%s] ", filename);
3945 extcheck = strchr(filename, '.');
3948 EM_DEBUG_LOG(">>>> Extension Exist in the Attachment [ %s ] ", extcheck);
3949 else /* No extension attached , So add the Extension based on the subtyp */ {
3950 if (body->subtype) {
3951 strcat(filename, ".");
3952 strcat(filename, body->subtype);
3953 EM_DEBUG_LOG(">>>>> FILENAME Identified the Extension [%s] ", filename);
3956 EM_DEBUG_EXCEPTION("UnKnown Extesnsion : _ (");
3962 param1 = param1->next;
3966 else if (body->disposition.type) {
3967 PARAMETER *param = body->disposition.parameter;
3970 EM_DEBUG_LOG(">>>>> body->disposition.parameter->attribute [ %s ] ", param->attribute);
3971 EM_DEBUG_LOG(">>>>> body->disposition.parameter->value [ %s ] ", param->value);
3973 /* attribute is "filename" */
3974 if (!strcasecmp(param->attribute, "filename")) {
3975 decoded_filename = emcore_decode_rfc2047_text(param->value, &err);
3976 strncpy(filename, decoded_filename, MAX_PATH);
3977 EM_SAFE_FREE(decoded_filename);
3978 EM_DEBUG_LOG(">>>>> FILENAME [%s] ", filename);
3982 param = param->next;
3986 if ((body->id[0] == '<'))
3987 SNPRINTF(filename, MAX_PATH, "%s", body->id+1);
3989 SNPRINTF(filename, MAX_PATH, "%s", body->id);
3991 len = EM_SAFE_STRLEN(filename);
3993 if ((len > 1) && (filename[len-1] == '>'))
3994 filename[len-1] = '\0';
3996 /* is_attachment = 1; */
3999 else if (body->location) {
4000 EM_DEBUG_LOG("body->location exist");
4002 decoded_filename = emcore_decode_rfc2047_text(body->location, &err);
4003 strncpy(filename, decoded_filename, MAX_PATH);
4004 EM_SAFE_FREE(decoded_filename);
4005 EM_DEBUG_LOG("body->location [%s]", body->location);
4007 else if (is_pbd && (strncmp(body->subtype, "RFC822", strlen("RFC822")) == 0) && (cnt_info->grab_type == 0 || (cnt_info->grab_type & GRAB_TYPE_ATTACHMENT))) {
4008 EM_DEBUG_LOG("Beause subtype is RFC822. This is ttachment");
4011 if (cnt_info->grab_type == 0) {
4012 if ((body->nested.msg != NULL) && (body->nested.msg->env != NULL) && (body->nested.msg->env->subject != NULL)) {
4013 decoded_filename = emcore_decode_rfc2047_text(body->nested.msg->env->subject, &err);
4014 strncpy(filename, decoded_filename, MAX_PATH);
4015 EM_SAFE_FREE(decoded_filename);
4018 strncpy(filename, "Unknown <message/rfc822>", MAX_PATH);
4020 else if (cnt_info->grab_type & GRAB_TYPE_ATTACHMENT) {
4021 BODY *temp_body = NULL;
4022 if (body->nested.msg->env->subject != NULL) {
4024 int subject_count = 0;
4025 if (g_str_has_prefix(body->nested.msg->env->subject, "= ? ") && g_str_has_suffix(body->nested.msg->env->subject, " ? = "))
4026 strncpy(filename, "unknown", MAX_PATH);
4028 for (subject_count = 0; body->nested.msg->env->subject[subject_count] != '\0' ; subject_count++) {
4029 if (body->nested.msg->env->subject[subject_count] != ':' &&
4030 body->nested.msg->env->subject[subject_count] != ';' &&
4031 body->nested.msg->env->subject[subject_count] != '*' &&
4032 body->nested.msg->env->subject[subject_count] != '?' &&
4033 body->nested.msg->env->subject[subject_count] != '\"' &&
4034 body->nested.msg->env->subject[subject_count] != '<' &&
4035 body->nested.msg->env->subject[subject_count] != '>' &&
4036 body->nested.msg->env->subject[subject_count] != '|' &&
4037 body->nested.msg->env->subject[subject_count] != '/') {
4038 filename[i] = body->nested.msg->env->subject[subject_count];
4047 strncpy(filename, "Unknown", MAX_PATH);
4049 body = ((MESSAGE *)body->nested.msg)->body;
4050 part = body->nested.part;
4052 if ((body->subtype[0] == 'P') || (body->subtype[0] == 'H'))
4054 else if (part != NULL) {
4055 temp_body = &(part->body);
4056 if ((temp_body->subtype[0] == 'P' || temp_body->subtype[0] == 'H') && part->next != NULL) {
4058 temp_body = &(part->body);
4063 if (temp_body->subtype[0] == 'P')
4065 else if (temp_body->subtype[0] == 'H')
4068 sparep = temp_body->sparep;
4069 encode = temp_body->encoding;
4074 else if (body->disposition.type) /* if disposition exists, get filename from disposition parameter */ { /* "attachment" or "inline" or etc.. */
4075 EM_DEBUG_LOG("body->disposition.type exist");
4078 if (emcore_get_attribute_value_of_body_part(body->disposition.parameter, "filename", filename, MAX_PATH, true, &err))
4079 EM_DEBUG_LOG(">>>>> FILENAME [%s] ", filename);
4081 if (!*filename) { /* If the part has no filename, it may be report ms */
4082 if ((body->disposition.type[0] == 'i' || body->disposition.type[0] == 'I') && body->parameter && body->parameter->attribute && strcasecmp(body->parameter->attribute, "NAME"))
4084 else if (body->parameter) /* Fix for the MMS attachment File name as unknown */ {
4085 char *extcheck = NULL;
4087 if (emcore_get_attribute_value_of_body_part(body->parameter, "NAME", filename, MAX_PATH, true, &err))
4088 EM_DEBUG_LOG("NAME [%s] ", filename);
4090 extcheck = strchr(filename, '.');
4093 EM_DEBUG_LOG(">>>> Extension Exist in the Attachment [ %s ] ", extcheck);
4094 else { /* No extension attached , So add the Extension based on the subtype */
4095 if (body->subtype) {
4096 if (EM_SAFE_STRLEN(filename) + EM_SAFE_STRLEN(body->subtype) + 1 < MAX_PATH) {
4097 strcat(filename, ".");
4098 strcat(filename, body->subtype);
4100 EM_DEBUG_LOG(">>>>> FILENAME Identified the Extension [%s] ", filename);
4103 EM_DEBUG_EXCEPTION("UnKnown Extesnsion : _ (");
4108 strncpy(filename, "unknown", MAX_PATH);
4111 if ((body->disposition.type[0] == 'i' || body->disposition.type[0] == 'I'))
4116 /* if (!is_pbd) */ {
4117 EM_DEBUG_LOG("filename [%s]", filename);
4119 decoded_filename = emcore_decode_rfc2047_text(filename, &err);
4120 strncpy(filename, decoded_filename, MAX_PATH);
4121 EM_SAFE_FREE(decoded_filename);
4122 filename_temp = em_parse_filename(filename);
4123 if (filename_temp) {
4124 strncpy(filename, filename_temp, MAX_PATH);
4125 EM_DEBUG_LOG("filename [%s]", filename);
4129 EM_DEBUG_LOG("is_attachment [%d]", is_attachment);
4131 if (!is_attachment) { /* Text or RFC822 Message */
4132 EM_DEBUG_LOG("Multipart is not attachment, body->type = %d", body->type);
4133 if ((cnt_info->grab_type & GRAB_TYPE_TEXT) && (body->type == TYPEMESSAGE || body->type == TYPETEXT || body->type == TYPEIMAGE)) {
4136 else { /* fetch body */
4137 if (!emcore_get_temp_file_name(&o_data, &err)) {
4138 EM_DEBUG_EXCEPTION("emcore_get_temp_file_name failed [%d]", err);
4142 if (!imap_mail_write_body_to_file(stream, account_id, mail_id, 0, o_data, msg_uid, body->sparep, body->encoding, &o_data_len, body->subtype, &err)) {
4143 EM_DEBUG_EXCEPTION("imap_mail_write_body_to_file failed [%d]", err);
4144 if(err == EMAIL_ERROR_INVALID_STREAM) {
4145 email_session_t *session = NULL;
4146 emcore_get_current_session(&session);
4147 err = session->error;
4154 switch (body->type) {
4156 EM_DEBUG_LOG("TYPETEXT");
4157 if (body->subtype[0] == 'H')
4158 cnt_info->text.html = o_data;
4160 cnt_info->text.plain = o_data;
4161 memset(charset_value_buffer, 0, 512);
4162 if (emcore_get_attribute_value_of_body_part(body->parameter, "CHARSET", charset_value_buffer, 512, true, &err))
4163 cnt_info->text.plain_charset = EM_SAFE_STRDUP(charset_value_buffer);
4167 case TYPEAPPLICATION:
4170 /* Inline Content - suspect of crash on partial body download */
4172 EM_DEBUG_LOG("TYPEIMAGE or TYPEAPPLICATION : inline content");
4173 ai = &(cnt_info->file);
4175 dec_len = body->size.bytes;
4176 if ((cnt_info->grab_type & GRAB_TYPE_ATTACHMENT) &&
4177 (cnt_info->grab_type & GRAB_TYPE_TEXT)) { /* it is 'download all */
4178 only_body_download = false;
4179 cnt_info->file_no = 1;
4182 /* add attachment info to content info */
4183 if (!(*ai = em_malloc(sizeof(struct attachment_info)))) {
4184 EM_DEBUG_EXCEPTION("em_malloc failed...");
4185 if (err_code != NULL)
4186 *err_code = EMAIL_ERROR_OUT_OF_MEMORY;
4190 if (((body->id) || (body->location)) && body->type == TYPEIMAGE)
4191 (*ai)->type = 1; /* inline */
4193 (*ai)->type = 2; /* attachment */
4195 (*ai)->name = EM_SAFE_STRDUP(filename);
4196 (*ai)->size = body->size.bytes;
4197 (*ai)->save = o_data;
4198 (*ai)->content_id = EM_SAFE_STRDUP(body->id);
4200 memset(content_type_buffer, 0, 512);
4201 if ( (err = emcore_get_content_type_from_mail_bodystruct(body, 512, content_type_buffer) ) == EMAIL_ERROR_NONE)
4202 (*ai)->attachment_mime_type = EM_SAFE_STRDUP(content_type_buffer);
4204 EM_DEBUG_LOG("name[%s], size[%d], save[%s], content_id[%s], content_type_buffer [%s]", cnt_info->file->name, cnt_info->file->size, cnt_info->file->save, content_type_buffer);
4205 #ifdef __ATTACHMENT_OPTI__
4206 (*ai)->encoding = body->encoding;
4208 (*ai)->section = EM_SAFE_STRDUP(body->sparep);
4209 EM_DEBUG_LOG(" Encoding - %d Section No - %s ", (*ai)->encoding, (*ai)->section);
4214 case TYPEMESSAGE: /* RFC822 Message */
4215 EM_DEBUG_EXCEPTION("MESSAGE/RFC822");
4216 err = EMAIL_ERROR_NOT_SUPPORTED;
4220 EM_DEBUG_EXCEPTION("Unknown type. body->type [%d]", body->type);
4221 err = EMAIL_ERROR_NOT_SUPPORTED;
4225 stream->text.data = NULL; /* ? ? ? ? ? ? ? ? */
4227 else { /* Attachment */
4230 ai = &cnt_info->file;
4231 EM_DEBUG_LOG(" ai - %p ", (*ai));
4233 if ((body->id) || (body->location)) {
4234 /* For Inline content append to the end */
4235 for (i = 1; *ai; ai = &(*ai)->next)
4238 else { /* For attachment - search till Inline content found and insert before inline */
4239 for (i = 1; *ai; ai = &(*ai)->next) {
4240 if ((*ai)->type == 1) {
4241 /* Means inline image */
4242 EM_DEBUG_LOG("Found Inline Content ");
4251 EM_DEBUG_LOG("i - %d next_ai - %p prev_ai - %p", i, next_ai, prev_ai);
4253 if ((cnt_info->grab_type & GRAB_TYPE_ATTACHMENT) &&
4254 (cnt_info->grab_type & GRAB_TYPE_TEXT)) { /* it is 'download all */
4255 EM_DEBUG_LOG("Download All");
4256 only_body_download = false;
4257 cnt_info->file_no = 1;
4260 /* meaningless code */
4261 dec_len = body->size.bytes;
4264 EM_DEBUG_LOG("BODY ID [ %s ]", body->id);
4266 EM_DEBUG_LOG("BODY ID IS NULL");
4268 EM_DEBUG_LOG("i : %d, cnt_info->file_no : %d", i, cnt_info->file_no);
4271 ((cnt_info->grab_type & GRAB_TYPE_ATTACHMENT) && i == cnt_info->file_no) || /* Is it correct attachment */
4272 (((body->id) || (body->location)) && (cnt_info->grab_type & GRAB_TYPE_TEXT)) /* Is it inline contents */
4274 /* fetch attachment */
4275 EM_DEBUG_LOG("attachment (enc) : %s %ld bytes", filename, body->size.bytes);
4276 EM_DEBUG_LOG(">>>>> ONLY BODY DOWNLOAD [ %d ] ", only_body_download);
4278 if (only_body_download == false) {
4279 if (!emcore_get_temp_file_name(&savefile, &err)) {
4280 EM_DEBUG_EXCEPTION("emcore_get_temp_file_name failed [%d]", err);
4285 if (!imap_mail_write_body_to_file(stream, account_id, mail_id, cnt_info->file_no, savefile, msg_uid, body->sparep, body->encoding, &dec_len, body->subtype, &err)) {
4286 EM_DEBUG_EXCEPTION("imap_mail_write_body_to_file failed [%d]", err);
4293 EM_DEBUG_LOG("attachment (dec) : %s %d bytes", filename, dec_len);
4295 /* add attachment info to content inf */
4296 if (!(*ai = em_malloc(sizeof(struct attachment_info)))) {
4297 EM_DEBUG_EXCEPTION("em_malloc failed...");
4298 err = EMAIL_ERROR_OUT_OF_MEMORY;
4302 if ((body->id) || (body->location))
4308 if (savefile != NULL) {
4309 if (section_plain == 1)
4310 strcat(filename, ".txt");
4311 if (section_html == 1)
4312 strcat(filename, ".html");
4317 (*ai)->name = EM_SAFE_STRDUP(filename);
4318 (*ai)->size = dec_len;
4319 (*ai)->save = savefile;
4320 (*ai)->content_id = EM_SAFE_STRDUP(body->id);
4322 memset(content_type_buffer, 0, 512);
4323 if ( (err = emcore_get_content_type_from_mail_bodystruct(body, 512, content_type_buffer) ) == EMAIL_ERROR_NONE)
4324 (*ai)->attachment_mime_type = EM_SAFE_STRDUP(content_type_buffer);
4325 #ifdef __ATTACHMENT_OPTI__
4326 (*ai)->encoding = body->encoding;
4328 (*ai)->section = EM_SAFE_STRDUP(body->sparep);
4330 EM_DEBUG_LOG(" Encoding - %d Section No - %s ", (*ai)->encoding, (*ai)->section);
4332 if (body->type == TYPEAPPLICATION) {
4333 if (!strcasecmp(body->subtype, MIME_SUBTYPE_DRM_OBJECT))
4334 (*ai)->drm = EMAIL_ATTACHMENT_DRM_OBJECT;
4335 else if (!strcasecmp(body->subtype, MIME_SUBTYPE_DRM_RIGHTS))
4336 (*ai)->drm = EMAIL_ATTACHMENT_DRM_RIGHTS;
4337 else if (!strcasecmp(body->subtype, MIME_SUBTYPE_DRM_DCF))
4338 (*ai)->drm = EMAIL_ATTACHMENT_DRM_DCF;
4341 /* All inline images information are stored at the end of list */
4342 if ((*ai)->type != 1 && next_ai != NULL) {
4343 /* Means next_ai points to the inline attachment info structure */
4344 if (prev_ai == NULL) {
4345 /* First node is inline attachment */
4346 (*ai)->next = next_ai;
4347 cnt_info->file = (*ai);
4350 prev_ai->next = (*ai);
4351 (*ai)->next = next_ai;
4360 EM_DEBUG_FUNC_END("ret [%d]", ret);
4363 /* get body-part in nested part */
4365 static int emcore_get_allnested_part(MAILSTREAM *stream, int account_id, int mail_id, int msg_uid, BODY *body, struct _m_content_info *cnt_info, int *err_code)
4367 EM_DEBUG_FUNC_BEGIN("stream[%p], msg_uid[%d], body[%p], cnt_info[%p], err_code[%p]", stream, msg_uid, body, cnt_info, err_code);
4368 PART *part_child = body->nested.part;
4370 while (part_child) {
4371 if (emcore_get_body(stream, account_id, mail_id, msg_uid, &part_child->body, cnt_info, err_code) < 0)
4374 part_child = part_child->next;
4377 EM_DEBUG_FUNC_END();
4381 /* get body-part in alternative multiple part */
4382 static int emcore_get_alternative_multi_part(MAILSTREAM *stream, int account_id, int mail_id, int msg_uid, BODY *body, struct _m_content_info *cnt_info, int *err_code)
4384 EM_DEBUG_FUNC_BEGIN("stream[%p], msg_uid[%d], body[%p], cnt_info[%p], err_code[%p]", stream, msg_uid, body, cnt_info, err_code);
4386 PART *part_child = body->nested.part;
4388 /* find the best sub part we can show */
4389 while (part_child) {
4390 if (emcore_get_body(stream, account_id, mail_id, msg_uid, &part_child->body, cnt_info, err_code) < 0)
4393 part_child = part_child->next;
4395 EM_DEBUG_FUNC_END();
4399 /* get body part in signed multiple part */
4400 static int emcore_get_signed_multi_part(MAILSTREAM *stream, int account_id, int mail_id, int msg_uid, BODY *body, struct _m_content_info *cnt_info, int *err_code)
4402 EM_DEBUG_FUNC_BEGIN("stream[%p], msg_uid[%d], body[%p], cnt_info[%p], err_code[%p]", stream, msg_uid, body, cnt_info, err_code);
4404 PART *part_child = body->nested.part;
4406 /* find the best sub part we can show */
4407 while (part_child) {
4408 if (emcore_get_body(stream, account_id, mail_id, msg_uid, &part_child->body, cnt_info, err_code) < 0)
4411 part_child = part_child->next;
4414 EM_DEBUG_FUNC_END();
4418 /* get body part in encrypted multiple part */
4419 static int emcore_get_encrypted_multi_part(MAILSTREAM *stream, int account_id, int mail_id, int msg_uid, BODY *body, struct _m_content_info *cnt_info, int *err_code)
4421 EM_DEBUG_FUNC_BEGIN("stream[%p], msg_uid[%d], body[%p], cnt_info[%p], err_code[%p]", stream, msg_uid, body, cnt_info, err_code);
4422 EM_DEBUG_FUNC_END();
4426 /* get body part in multiple part */
4427 static int emcore_get_multi_part(MAILSTREAM *stream, int account_id, int mail_id, int msg_uid, BODY *body, struct _m_content_info *cnt_info, int *err_code)
4429 EM_DEBUG_FUNC_BEGIN("stream[%p], msg_uid[%d], body[%p], cnt_info[%p], err_code[%p]", stream, msg_uid, body, cnt_info, err_code);
4432 EM_DEBUG_EXCEPTION("Invalid Parameter.");
4434 *err_code = EMAIL_ERROR_INVALID_PARAM;
4438 switch (body->subtype[0]) {
4439 case 'A': /* ALTERNATIVE */
4440 EM_DEBUG_LOG("body->subtype[0] = ALTERNATIVE");
4441 return emcore_get_alternative_multi_part(stream, account_id, mail_id, msg_uid, body, cnt_info, err_code);
4443 case 'S': /* SIGNED */
4444 EM_DEBUG_LOG("body->subtype[0] = SIGNED");
4445 return emcore_get_signed_multi_part(stream, account_id, mail_id, msg_uid, body, cnt_info, err_code);
4447 case 'E': /* ENCRYPTED */
4448 EM_DEBUG_LOG("body->subtype[0] = ENCRYPTED");
4449 return emcore_get_encrypted_multi_part(stream, account_id, mail_id, msg_uid, body, cnt_info, err_code);
4451 default: /* process all unknown as MIXED (according to the RFC 2047) */
4452 EM_DEBUG_LOG("body->subtype[0] = [%c].", body->subtype[0]);
4453 return emcore_get_allnested_part(stream, account_id, mail_id, msg_uid, body, cnt_info, err_code);
4455 /* Delete the dead code */
4458 /* get body data by body structure */
4459 /* if POP3, ignored */
4460 INTERNAL_FUNC int emcore_get_body(MAILSTREAM *stream, int account_id, int mail_id, int msg_uid, BODY *body, struct _m_content_info *cnt_info, int *err_code)
4462 EM_DEBUG_FUNC_BEGIN("stream[%p], msg_uid[%d], body[%p], cnt_info[%p], err_code[%p]", stream, msg_uid, body, cnt_info, err_code);
4464 if (!stream || !body || !cnt_info) {
4465 EM_DEBUG_EXCEPTION("Invalid parameter");
4467 if (err_code != NULL)
4468 *err_code = EMAIL_ERROR_INVALID_PARAM;
4472 EM_DEBUG_LOG("body->type [%d]", body->type);
4474 switch (body->type) {
4476 return emcore_get_multi_part(stream, account_id, mail_id, msg_uid, body, cnt_info, err_code);
4478 case TYPEMESSAGE: /* not support */
4479 if (strcasecmp(body->subtype, "RFC822") == 0)
4480 return emcore_get_body_part_imap(stream, account_id, mail_id, msg_uid, body, cnt_info, err_code);
4484 case TYPEAPPLICATION:
4490 /* exactly, get a pure body part (text and attachment */
4491 return emcore_get_body_part_imap(stream, account_id, mail_id, msg_uid, body, cnt_info, err_code);
4496 EM_DEBUG_FUNC_END();
4500 /* get body structure */
4501 INTERNAL_FUNC int emcore_get_body_structure(MAILSTREAM *stream, int msg_uid, BODY **body, int *err_code)
4503 EM_DEBUG_FUNC_BEGIN("stream[%p], msg_uid[%d], body[%p], err_code[%p]", stream, msg_uid, body, err_code);
4505 EM_IF_NULL_RETURN_VALUE(stream, false);
4506 EM_IF_NULL_RETURN_VALUE(body, false);
4508 #ifdef __FEATURE_HEADER_OPTIMIZATION__
4509 ENVELOPE *env = mail_fetch_structure(stream, msg_uid, body, FT_UID | FT_PEEK | FT_NOLOOKAHEAD, 1);
4511 ENVELOPE *env = mail_fetch_structure(stream, msg_uid, body, FT_UID | FT_PEEK | FT_NOLOOKAHEAD);
4515 *err_code = EMAIL_ERROR_MAIL_NOT_FOUND_ON_SERVER;
4516 EM_DEBUG_EXCEPTION("mail_fetch_structure failed");
4520 #ifdef FEATURE_CORE_DEBUG
4521 _print_body(*body, true); /* shasikala.p@partner.samsung.com */
4523 EM_DEBUG_FUNC_END();
4527 int emcore_set_fetch_part_section(BODY *body, char *section_pfx, int section_subno, int enable_inline_list, int *total_mail_size, int *err_code);
4529 /* set body section to be fetched */
4530 INTERNAL_FUNC int emcore_set_fetch_body_section(BODY *body, int enable_inline_list, int *total_mail_size, int *err_code)
4532 EM_DEBUG_FUNC_BEGIN("body[%p], err_code[%p]", body, err_code);
4535 EM_DEBUG_EXCEPTION("body [%p]", body);
4536 if (err_code != NULL)
4537 *err_code = EMAIL_ERROR_INVALID_PARAM;
4541 // body->id = cpystr("1"); /* top level body */
4542 EM_DEBUG_LOG("body->id : [%s]", body->id);
4545 EM_SAFE_FREE(g_inline_list);
4546 emcore_set_fetch_part_section(body, (char *)NULL, 0, enable_inline_list, total_mail_size, err_code);
4548 if (body && body->id)
4549 EM_DEBUG_LOG(">>>>> FILE NAME [%s] ", body->id);
4551 EM_DEBUG_LOG(">>>>> BODY NULL ");
4553 EM_DEBUG_FUNC_END();
4557 /* set part section of body to be fetched */
4558 int emcore_set_fetch_part_section(BODY *body, char *section_pfx, int section_subno, int enable_inline_list, int *total_mail_size, int *err_code)
4560 EM_DEBUG_FUNC_BEGIN("body[%p], section_pfx[%s], section_subno[%d], err_code[%p]", body, section_pfx, section_subno, err_code);
4563 char section[64] = {0x00, };
4565 /* multipart doesn't have a row to itself */
4566 if (body->type == TYPEMULTIPART) {
4567 /* if not first time, extend prefix */
4569 SNPRINTF(section, sizeof(section), "%s%d.", section_pfx, ++section_subno);
4575 for (section_subno = 0, part = body->nested.part; part; part = part->next)
4576 emcore_set_fetch_part_section(&part->body, section, section_subno++, enable_inline_list, total_mail_size, err_code);
4579 if (!section_pfx) /* dummy prefix if top level */
4582 SNPRINTF(section, sizeof(section), "%s%d", section_pfx, ++section_subno);
4584 if (enable_inline_list && ((body->disposition.type && (body->disposition.type[0] == 'i' || body->disposition.type[0] == 'I')) ||
4585 (!body->disposition.type && body->id))) {
4587 temp = realloc(g_inline_list, sizeof(BODY *) *(g_inline_count + 1));
4589 memset(temp+g_inline_count, 0x00, sizeof(BODY *));
4590 g_inline_list = temp;
4591 g_inline_list[g_inline_count] = body;
4596 EM_DEBUG_EXCEPTION("realloc fails");
4599 EM_DEBUG_LOG("Update g_inline_list with inline count [%d]", g_inline_count);
4602 /* if ((total_mail_size != NULL) && !(body->disposition.type && (body->disposition.type[0] == 'a' || body->disposition.type[0] == 'A')) */
4603 if (total_mail_size != NULL) {
4604 *total_mail_size = *total_mail_size + (int)body->size.bytes;
4605 EM_DEBUG_LOG("body->size.bytes [%d]", body->size.bytes);
4608 /* encapsulated message ? */
4609 if ((body->type == TYPEMESSAGE) && !strcasecmp(body->subtype, "RFC822") && (body = ((MESSAGE *)body->nested.msg)->body)) {
4610 if (body->type == TYPEMULTIPART) {
4612 emcore_set_fetch_part_section(body, section, section_subno-1, enable_inline_list, total_mail_size, err_code);
4614 else { /* build encapsulation prefi */
4615 SNPRINTF(section, sizeof(section), "%s%d.", section_pfx, section_subno);
4616 emcore_set_fetch_part_section(body, section, 0, enable_inline_list, total_mail_size, err_code);
4620 /* set body section */
4622 body->sparep = cpystr(section);
4625 EM_DEBUG_FUNC_END();
4630 static void parse_file_path_to_filename(char *src_string, char **out_string)
4633 char *filepath = NULL;
4638 filepath = EM_SAFE_STRDUP(src_string);
4639 token = strtok_r(filepath, "/", &str);
4644 } while ((token = strtok_r(NULL , "/", &str)));
4646 *out_string = EM_SAFE_STRDUP(prev1);
4647 EM_SAFE_FREE(filepath);
4650 static char *emcore_decode_rfc2047_word(char *encoded_word, int *err_code)
4652 EM_DEBUG_FUNC_BEGIN("encoded_word[%s], err_code[%p]", encoded_word, err_code);
4654 int err = EMAIL_ERROR_NONE;
4655 int base64_encoded = false, length = 0;
4656 SIZEDTEXT src = { NULL, 0 };
4657 SIZEDTEXT dst = { NULL, 0 };
4658 gchar *charset = NULL, *encoded_text = NULL;
4659 char *decoded_text = NULL, *decoded_word = NULL;
4660 char *current = NULL, *start = NULL, *end = NULL;
4661 char *buffer = (char*) em_malloc(EM_SAFE_STRLEN(encoded_word) * 2 + 1);
4663 if (buffer == NULL) {
4664 EM_DEBUG_EXCEPTION("Memory allocation fail");
4665 err = EMAIL_ERROR_OUT_OF_MEMORY;
4671 /* encoding format : =?charset?encoding?encoded-text ?= */
4672 /* charset : UTF-8, EUC-KR, ... */
4673 /* encoding : b/B (BASE64), q/Q (QUOTED-PRINTABLE) */
4674 current = encoded_word;
4676 while (*current != NULL_CHAR) {
4678 start = strstr(current, "=?"); /* start of encoding */
4679 end = strstr(current, "?="); /* end of encoding */
4681 #ifdef FEATURE_CORE_DEBUG
4682 EM_DEBUG_LOG("current[%p][%s], start[%p][%s], end[%p][%s]", current, current, start, start, end, end);
4684 if (start != NULL) {
4685 if (current != start) { /* copy the string between current and start to buffer */
4686 strncat(buffer, current, start - current);
4688 #ifdef FEATURE_CORE_DEBUG
4689 EM_DEBUG_LOG("1 - Buffer[%s]", buffer);
4693 if (end) { /* decode text between start and end */
4694 char *p = strstr(start, "?b?");
4696 if (p || (p = strstr(start, "?B?"))) /* BASE64 */
4697 base64_encoded = true;
4699 p = strstr(start, "?q?");
4701 if (p || (p = strstr(start, "?Q?"))) /* QUOTED-PRINTABLE */
4702 base64_encoded = false;
4704 EM_DEBUG_EXCEPTION("unknown encoding found...");
4706 err = EMAIL_ERROR_UNKNOWN;
4711 if (base64_encoded) { /* BASE64 */
4712 charset = g_strndup(start + 2, p - (start + 2));
4713 encoded_text = g_strndup(p + 3, end - (p + 3));
4715 else { /* QUOTED-PRINTABLE */
4716 charset = g_strndup(start + 2, p - (start + 2));
4717 if (*(p+3) == '=') { /* encoded text might start with '='. ex) '?Q?=E0' */
4718 end = strstr(p+3, "?="); /* find new end flag */
4720 encoded_text = g_strndup(p + 3, end - (p + 3));
4722 else { /* end flag is not found */
4723 EM_DEBUG_EXCEPTION("emcore_decode_rfc2047_word decoding error : '?=' is not found...");
4725 err = EMAIL_ERROR_UNKNOWN;
4730 encoded_text = g_strndup(p + 3, end - (p + 3));
4734 #ifdef FEATURE_CORE_DEBUG
4735 EM_DEBUG_LOG("\t >>>>>>>>>>>>>>> CHARSET[%s]", charset);
4736 EM_DEBUG_LOG("\t >>>>>>>>>>>>>>> ENCODED_TEXT[%s]", encoded_text);
4739 unsigned long len = 0;
4740 if (encoded_text != NULL) {
4741 if (base64_encoded == true) {
4742 if (!(decoded_text = (char *)rfc822_base64((unsigned char *)encoded_text, EM_SAFE_STRLEN(encoded_text), &len))) {
4743 EM_DEBUG_EXCEPTION("rfc822_base64 falied...");
4748 g_strdelimit(encoded_text, "_", ' ');
4750 if (!(decoded_text = (char *)rfc822_qprint((unsigned char *)encoded_text, EM_SAFE_STRLEN(encoded_text), &len))) {
4751 EM_DEBUG_EXCEPTION("rfc822_base64 falied...");
4756 src.data = (unsigned char *)decoded_text;
4757 src.size = EM_SAFE_STRLEN(decoded_text);
4759 if (!utf8_text(&src, charset, &dst, 0)) {
4760 EM_DEBUG_EXCEPTION("utf8_text falied...");
4762 strncat(buffer, (char *)src.data, src.size); /* Eventhough failed to decode, downloading should go on. Kyuho Jo */
4765 strncat(buffer, (char *)dst.data, dst.size);
4767 #ifdef FEATURE_CORE_DEBUG
4768 EM_DEBUG_LOG("2 - Buffer[%s]", buffer);
4771 /* free all of the temp variables */
4772 if (dst.data != NULL && dst.data != src.data)
4773 EM_SAFE_FREE(dst.data);
4775 EM_SAFE_FREE(decoded_text);
4777 g_free(encoded_text);
4778 encoded_text = NULL;
4780 if (charset != NULL) {
4785 current = end + 2; /* skip '?=' */
4788 /* unencoded text */
4789 length = EM_SAFE_STRLEN(start);
4790 strncat(buffer, start, length);
4791 current = start + length;
4792 #ifdef FEATURE_CORE_DEBUG
4793 EM_DEBUG_LOG("3 - Buffer[%s]", buffer);
4798 /* unencoded text */
4799 length = EM_SAFE_STRLEN(current);
4800 strncat(buffer, current, length);
4801 current = current + length;
4802 #ifdef FEATURE_CORE_DEBUG
4803 EM_DEBUG_LOG("4 - Buffer[%s]", buffer);
4808 decoded_word = EM_SAFE_STRDUP(buffer);
4810 #ifdef FEATURE_CORE_DEBUG
4811 EM_DEBUG_LOG(">>>>>>>>>>>>>>> DECODED_WORD[%s]", decoded_word);
4815 if (dst.data != NULL && dst.data != src.data)
4816 EM_SAFE_FREE(dst.data);
4817 EM_SAFE_FREE(decoded_text);
4818 EM_SAFE_FREE(buffer);
4820 if (encoded_text != NULL)
4821 g_free(encoded_text);
4822 if (charset != NULL)
4825 if (err_code != NULL)
4828 EM_DEBUG_FUNC_END();
4829 return decoded_word;
4832 INTERNAL_FUNC char *emcore_decode_rfc2047_text(char *rfc2047_text, int *err_code)
4834 EM_DEBUG_FUNC_BEGIN("rfc2047_text[%s], err_code[%p]", rfc2047_text, err_code);
4837 int err = EMAIL_ERROR_NONE;
4839 if (!rfc2047_text) {
4840 EM_DEBUG_EXCEPTION("rfc2047_text[%p]", rfc2047_text);
4841 if (err_code != NULL)
4842 *err_code = EMAIL_ERROR_INVALID_PARAM;
4848 gchar **encoded_words = g_strsplit_set(rfc2047_text, " \t\r\n", -1);
4849 gchar **decoded_words = g_new0(char *, g_strv_length(encoded_words) + 1);
4851 /* EM_DEBUG_LOG("g_strv_length(encoded_words) [%d]", g_strv_length(encoded_words)); */
4853 if (encoded_words != NULL) {
4856 while (encoded_words[i] != NULL) {
4857 if (!(decoded_words[i] = emcore_decode_rfc2047_word(encoded_words[i], &err))) {
4858 EM_DEBUG_EXCEPTION("emcore_decode_rfc2047_word falied [%d]", err);
4864 text = g_strjoinv(" ", decoded_words);
4867 text = EM_SAFE_STRDUP(rfc2047_text);
4869 #ifdef FEATURE_CORE_DEBUG
4870 EM_DEBUG_LOG(">>>>>>>>>>>>>>>>> TEXT[%s]", text);
4871 #endif /* FEATURE_CORE_DEBUG */
4876 g_strfreev(decoded_words);
4877 g_strfreev(encoded_words);
4879 if (err_code != NULL)
4881 EM_DEBUG_FUNC_END();
4885 INTERNAL_FUNC int emcore_make_mail_data_from_mime_data(struct _m_mesg *mmsg, struct _m_content_info *cnt_info, email_mail_data_t **output_mail_data, email_attachment_data_t **output_attachment_data, int *output_attachment_count, int *err_code)
4887 EM_DEBUG_FUNC_BEGIN();
4889 int err = EMAIL_ERROR_NONE;
4890 int local_attachment_count = 0;
4891 int local_inline_content_count = 0;
4892 int attachment_num = 0;
4894 int eml_mail_id = 0;
4896 char html_body[MAX_PATH] = {0, };
4897 struct tm temp_time_info;
4899 struct attachment_info *ai = NULL;
4900 char *encoded_subject = NULL;
4901 email_attachment_data_t *attachment = NULL;
4902 email_mail_data_t *p_mail_data = NULL;
4903 MESSAGECACHE mail_cache_element = {0, };
4905 if (!mmsg || !cnt_info || !output_mail_data || !output_attachment_data) {
4906 EM_DEBUG_EXCEPTION("Invalid parameter");
4907 err = EMAIL_ERROR_INVALID_PARAM;
4911 p_mail_data = (email_mail_data_t *)em_malloc(sizeof(email_mail_data_t));
4912 if (p_mail_data == NULL) {
4913 EM_DEBUG_EXCEPTION("em_malloc failed");
4914 err = EMAIL_ERROR_OUT_OF_MEMORY;
4918 memset(&mail_cache_element, 0x00, sizeof(MESSAGECACHE));
4919 memset((void *)&temp_time_info, 0, sizeof(struct tm));
4921 /* Create rand mail id of eml */
4922 gettimeofday(&tv, NULL);
4924 eml_mail_id = rand();
4926 p_mail_data->mail_id = eml_mail_id;
4927 p_mail_data->account_id = EML_FOLDER;
4929 if (mmsg->rfc822header->date)
4930 mail_parse_date(&mail_cache_element, (unsigned char *)mmsg->rfc822header->date);
4932 temp_time_info.tm_sec = mail_cache_element.seconds;
4933 temp_time_info.tm_min = mail_cache_element.minutes - mail_cache_element.zminutes;
4934 temp_time_info.tm_hour = mail_cache_element.hours - mail_cache_element.zhours;
4936 if (mail_cache_element.hours - mail_cache_element.zhours < 0) {
4937 temp_time_info.tm_mday = mail_cache_element.day - 1;
4938 temp_time_info.tm_hour += 24;
4940 temp_time_info.tm_mday = mail_cache_element.day;
4942 temp_time_info.tm_mon = mail_cache_element.month - 1;
4943 temp_time_info.tm_year = mail_cache_element.year + 70;
4945 encoded_subject = emcore_decode_rfc2047_text(mmsg->rfc822header->subject, NULL);
4947 p_mail_data->date_time = timegm(&temp_time_info);
4948 p_mail_data->full_address_return = EM_SAFE_STRDUP(mmsg->rfc822header->return_path);
4949 p_mail_data->email_address_recipient = EM_SAFE_STRDUP(mmsg->rfc822header->received);
4950 p_mail_data->full_address_from = EM_SAFE_STRDUP(mmsg->rfc822header->from);
4951 p_mail_data->subject = EM_SAFE_STRDUP(encoded_subject);
4952 p_mail_data->email_address_sender = EM_SAFE_STRDUP(mmsg->rfc822header->sender);
4953 p_mail_data->full_address_to = EM_SAFE_STRDUP(mmsg->rfc822header->to);
4954 p_mail_data->full_address_cc = EM_SAFE_STRDUP(mmsg->rfc822header->cc);
4955 p_mail_data->full_address_bcc = EM_SAFE_STRDUP(mmsg->rfc822header->bcc);
4956 p_mail_data->full_address_reply = EM_SAFE_STRDUP(mmsg->rfc822header->reply_to);
4957 p_mail_data->body_download_status = EMAIL_BODY_DOWNLOAD_STATUS_FULLY_DOWNLOADED;
4959 EM_DEBUG_LOG("cnt_info->text.plain [%s], cnt_info->text.html [%s]", cnt_info->text.plain, cnt_info->text.html);
4961 if (cnt_info->text.plain) {
4962 EM_DEBUG_LOG("cnt_info->text.plain [%s]", cnt_info->text.plain);
4963 if (!emstorage_create_dir(EML_FOLDER, eml_mail_id, 0, &err)) {
4964 EM_DEBUG_EXCEPTION("emstorage_create_dir failed [%d]", err);
4968 if (!emstorage_get_save_name(EML_FOLDER, eml_mail_id, 0, cnt_info->text.plain_charset ? cnt_info->text.plain_charset : UNKNOWN_CHARSET_PLAIN_TEXT_FILE, buf, &err)) {
4969 EM_DEBUG_EXCEPTION("emstorage_get_save_name failed [%d]", err);
4973 if (!emstorage_move_file(cnt_info->text.plain, buf, false, &err)) {
4974 EM_DEBUG_EXCEPTION("emstorage_move_file failed [%d]", err);
4978 p_mail_data->file_path_plain = EM_SAFE_STRDUP(buf);
4979 EM_DEBUG_LOG("mail_data->file_path_plain [%s]", p_mail_data->file_path_plain);
4982 if (cnt_info->text.html) {
4983 if (!emstorage_create_dir(EML_FOLDER, eml_mail_id, 0, &err)) {
4984 EM_DEBUG_EXCEPTION("emstorage_create_dir failed [%d]", err);
4988 if (cnt_info->text.html_charset != NULL) {
4989 SNPRINTF(html_body, MAX_PATH, "%s%s", cnt_info->text.html_charset, HTML_EXTENSION_STRING);
4991 strcpy(html_body, UNKNOWN_CHARSET_HTML_TEXT_FILE);
4994 if (!emstorage_get_save_name(EML_FOLDER, eml_mail_id, 0, html_body, buf, &err)) {
4995 EM_DEBUG_EXCEPTION("emstorage_get_save_name failed [%d]", err);
4999 if (!emstorage_move_file(cnt_info->text.html, buf, false, &err)) {
5000 EM_DEBUG_EXCEPTION("emstorage_move_file failed [%d]", err);
5003 p_mail_data->file_path_html = EM_SAFE_STRDUP(buf);
5007 for (ai = cnt_info->file; ai; ai = ai->next, attachment_num++) {}
5008 EM_DEBUG_LOG("attachment_num : [%d]", attachment_num);
5010 if (attachment_num > 0) {
5011 attachment = (email_attachment_data_t *)em_malloc(sizeof(email_attachment_data_t) * attachment_num);
5012 if (attachment == NULL) {
5013 EM_DEBUG_EXCEPTION("em_malloc failed");
5014 err = EMAIL_ERROR_OUT_OF_MEMORY;
5018 for (ai = cnt_info->file; ai; ai = ai->next, i++) {
5019 attachment[i].attachment_id = 0;
5020 attachment[i].attachment_size = ai->size;
5021 attachment[i].attachment_name = EM_SAFE_STRDUP(ai->name);
5022 attachment[i].drm_status = ai->drm;
5023 attachment[i].save_status = 0;
5024 attachment[i].inline_content_status = ai->type == 1;
5025 attachment[i].attachment_mime_type = ai->attachment_mime_type;
5026 #ifdef __ATTACHMENT_OPTI__
5027 attachment[i].encoding = ai->encoding;
5028 attachment[i].section = ai->section;
5030 EM_DEBUG_LOG("attachment[%d].attachment_id[%d]", i, attachment[i].attachment_id);
5031 EM_DEBUG_LOG("attachment[%d].attachment_size[%d]", i, attachment[i].attachment_size);
5032 EM_DEBUG_LOG("attachment[%d].attachment_name[%s]", i, attachment[i].attachment_name);
5033 EM_DEBUG_LOG("attachment[%d].drm_status[%d]", i, attachment[i].drm_status);
5034 EM_DEBUG_LOG("attachment[%d].inline_content_status[%d]", i, attachment[i].inline_content_status);
5037 local_inline_content_count ++;
5038 local_attachment_count++;
5041 attachment[i].save_status = 1;
5042 if (ai->type == 1) { /* it is inline content */
5043 if (!emstorage_create_dir(EML_FOLDER, eml_mail_id, 0, &err)) {
5044 EM_DEBUG_EXCEPTION("emstorage_create_dir failed [%d]", err);
5047 if (!emstorage_get_save_name(EML_FOLDER, eml_mail_id, 0, attachment[i].attachment_name, buf, &err)) {
5048 EM_DEBUG_EXCEPTION("emstorage_get_save_name failed [%d]", err);
5053 if (!emstorage_create_dir(EML_FOLDER, eml_mail_id, i, &err)) {
5054 EM_DEBUG_EXCEPTION("emstorage_create_dir failed [%d]", err);
5058 if (!emstorage_get_save_name(EML_FOLDER, eml_mail_id, i, attachment[i].attachment_name, buf, &err)) {
5059 EM_DEBUG_EXCEPTION("emstorage_get_save_name failed [%d]", err);
5064 if (!emstorage_move_file(ai->save, buf, false, &err)) {
5065 EM_DEBUG_EXCEPTION("emstorage_move_file failed [%d]", err);
5067 /* delete all created files. */
5068 if (!emstorage_get_save_name(EML_FOLDER, eml_mail_id, 0, NULL, buf, NULL)) {
5069 EM_DEBUG_EXCEPTION("emstorage_get_save_name failed...");
5070 /* goto FINISH_OFF; */
5073 if (!emstorage_delete_dir(buf, NULL)) {
5074 EM_DEBUG_EXCEPTION("emstorage_delete_dir failed...");
5075 /* goto FINISH_OFF; */
5082 attachment[i].attachment_path = EM_SAFE_STRDUP(buf);
5086 EM_DEBUG_LOG("attachment[%d].attachment_path[%s]", i, attachment[i].attachment_path);
5089 EM_DEBUG_LOG("Check #1");
5091 p_mail_data->attachment_count = local_attachment_count;
5092 p_mail_data->inline_content_count = local_inline_content_count;
5094 eml_data_count += 1;
5100 if (output_mail_data)
5101 *output_mail_data = p_mail_data;
5103 if (output_attachment_data)
5104 *output_attachment_data = attachment;
5106 if (output_attachment_count)
5107 *output_attachment_count = local_attachment_count;
5110 emcore_free_mail_data(p_mail_data);
5111 EM_SAFE_FREE(p_mail_data);
5115 emcore_free_attachment_data(&attachment, attachment_num, NULL);
5118 EM_SAFE_FREE(encoded_subject);
5123 EM_DEBUG_FUNC_END("ret : [%d]", ret);
5127 INTERNAL_FUNC int emcore_parse_mime_file_to_mail(char *eml_file_path, email_mail_data_t **output_mail_data, email_attachment_data_t **output_attachment_data, int *output_attachment_count, int *err_code)
5129 EM_DEBUG_FUNC_BEGIN("eml_file_path : [%s], output_mail_data : [%p]", eml_file_path, output_mail_data);
5131 int err = EMAIL_ERROR_NONE;
5134 FILE *eml_fp = NULL;
5135 struct _m_content_info *cnt_info = NULL;
5136 struct _m_mesg *mmsg = NULL;
5139 if (!eml_file_path || !output_mail_data || !output_attachment_data || !output_attachment_count) {
5140 EM_DEBUG_EXCEPTION("Invalid paramter");
5141 err = EMAIL_ERROR_INVALID_PARAM;
5145 cnt_info = (struct _m_content_info *)em_malloc(sizeof(struct _m_content_info));
5146 if (cnt_info == NULL) {
5147 EM_DEBUG_EXCEPTION("em_malloc failed...");
5148 err = EMAIL_ERROR_OUT_OF_MEMORY;
5152 cnt_info->grab_type = GRAB_TYPE_TEXT | GRAB_TYPE_ATTACHMENT;
5154 mmsg = (struct _m_mesg *)em_malloc(sizeof(struct _m_mesg));
5156 EM_DEBUG_EXCEPTION("em_malloc failed");
5157 err = EMAIL_ERROR_OUT_OF_MEMORY;
5161 eml_fp = fopen(eml_file_path, "r");
5162 if (eml_fp == NULL) {
5163 EM_DEBUG_EXCEPTION("file open failed");
5164 err = EMAIL_ERROR_ON_PARSING;
5168 if (!emcore_mime_parse_header(eml_fp, is_file, &mmsg->rfc822header, &mmsg->header, &err)) {
5169 EM_DEBUG_EXCEPTION("emcore_mime_parse_header failed : [%d]", err);
5170 err = EMAIL_ERROR_INVALID_DATA;
5174 if (!mmsg->header->part_header) {
5175 EM_DEBUG_EXCEPTION("Invalid eml format");
5176 err = EMAIL_ERROR_INVALID_DATA;
5180 if (!emcore_mime_parse_body(eml_fp, is_file, mmsg, cnt_info, NULL, &err)) {
5181 EM_DEBUG_EXCEPTION("emcore_mime_parse_body failed : [%d]", err);
5182 err = EMAIL_ERROR_INVALID_DATA;
5186 if (!emcore_make_mail_data_from_mime_data(mmsg, cnt_info, output_mail_data, output_attachment_data, output_attachment_count, &err)) {
5187 EM_DEBUG_EXCEPTION("emcore_make_mail_tbl_data_from_mime failed : [%d]", err);
5200 emcore_mime_free_mime(mmsg);
5203 emcore_free_content_info(cnt_info);
5208 EM_DEBUG_FUNC_END("err : %d", err);
5212 INTERNAL_FUNC int emcore_delete_parsed_data(email_mail_data_t *input_mail_data, int *err_code)
5214 EM_DEBUG_FUNC_BEGIN("input_mail_data : [%p]", input_mail_data);
5215 int err = EMAIL_ERROR_NONE;
5219 if (!input_mail_data) {
5220 EM_DEBUG_EXCEPTION("Invliad parameter");
5221 err = EMAIL_ERROR_INVALID_PARAM;
5225 if ((input_mail_data->account_id != EML_FOLDER) && (!input_mail_data->mail_id)) {
5226 EM_DEBUG_EXCEPTION("Invliad parameter: account_id[%d], mail_id[%d]", input_mail_data->account_id, input_mail_data->mail_id);
5227 err = EMAIL_ERROR_INVALID_PARAM;
5231 eml_data_count = eml_data_count - 1;
5233 if (eml_data_count == 0) {
5234 SNPRINTF(buf, sizeof(buf), "%s%s%d", MAILHOME, DIR_SEPERATOR, input_mail_data->account_id);
5236 SNPRINTF(buf, sizeof(buf), "%s%s%d%s%d", MAILHOME, DIR_SEPERATOR, input_mail_data->account_id, DIR_SEPERATOR, input_mail_data->mail_id);
5239 EM_DEBUG_LOG("Directory : [%s]", buf);
5241 if (!emstorage_delete_dir(buf, &err)) {
5242 EM_DEBUG_EXCEPTION("emstorage_delete_dir failed");
5256 INTERNAL_FUNC int emcore_get_mime_entity(char *mime_path, char **output_path, int *err_code)
5258 EM_DEBUG_FUNC_BEGIN("mime_path : [%s], output_path : [%p]", mime_path, *output_path);
5260 int err = EMAIL_ERROR_NONE;
5263 long start_mime_entity = 0;
5264 long end_mime_entity = 0;
5265 char buf[MIME_LINE_LEN] = {0x00, };
5266 char *mime_entity_path = NULL;
5267 char *content_type = NULL;
5268 char boundary[BOUNDARY_LEN] = {0x00,};
5269 char *boundary_string = NULL;
5270 char *p_mime_entity = NULL;
5271 FILE *fp_read = NULL;
5272 FILE *fp_write = NULL;
5273 struct _m_mesg *mmsg = NULL;
5276 EM_DEBUG_EXCEPTION("Invalid parameter");
5277 err = EMAIL_ERROR_INVALID_PARAM;
5281 /* Get the header info */
5282 mmsg = (struct _m_mesg *)em_malloc(sizeof(struct _m_mesg));
5284 EM_DEBUG_EXCEPTION("em_malloc failed");
5285 err = EMAIL_ERROR_OUT_OF_MEMORY;
5289 fp_read = fopen(mime_path, "r");
5290 if (fp_read == NULL) {
5291 EM_DEBUG_EXCEPTION("File open(read) is failed : filename [%s]", mime_path);
5292 err = EMAIL_ERROR_SYSTEM_FAILURE;
5296 if (!emcore_mime_parse_header(fp_read, is_file, &mmsg->rfc822header, &mmsg->header, &err)) {
5297 EM_DEBUG_EXCEPTION("emcore_mime_parse_header failed : [%d]", err);
5301 /* Parsing the mime header */
5302 content_type = emcore_mime_get_header_value(mmsg->header->part_header, CONTENT_TYPE, NULL);
5303 EM_DEBUG_LOG("Content_type : [%s]", content_type);
5304 if (strcasestr(content_type, "signed") == NULL) {
5305 EM_DEBUG_EXCEPTION("Invalid parameter : No signed mail");
5306 err = EMAIL_ERROR_INVALID_PARAM;
5310 /* Create mime_entity file */
5311 if (!emcore_get_temp_file_name(&mime_entity_path, &err)) {
5312 EM_DEBUG_EXCEPTION("emcore_get_temp_file_name failed[%d]", err);
5315 EM_DEBUG_LOG("mime_entity_path = %s", mime_entity_path);
5317 fp_write = fopen(mime_entity_path, "w");
5318 if (fp_write == NULL) {
5319 EM_DEBUG_EXCEPTION("File open(write) is failed : filename [%s]", mime_entity_path);
5320 err = EMAIL_ERROR_SYSTEM_FAILURE;
5324 boundary_string = emcore_mime_get_header_value(mmsg->header->part_header, CONTENT_BOUNDARY, NULL);
5325 SNPRINTF(boundary, BOUNDARY_LEN, "--%s%s", boundary_string, CRLF_STRING);
5328 if (!emcore_get_line_from_file((void *)fp_read, buf, MIME_LINE_LEN, &err)) {
5329 EM_DEBUG_EXCEPTION("emcore_mime_get_line_from_file failed [%d]", err);
5330 EM_DEBUG_LOG("this mail is partial body");
5331 err = EMAIL_ERROR_INVALID_MAIL;
5335 if (!strcmp(buf, boundary)) {
5338 start_mime_entity = ftell(fp_read);
5339 if( start_mime_entity < 0 ) { /*prevent 24473*/
5340 EM_DEBUG_EXCEPTION("ftell failed [%s]", EM_STRERROR(errno));
5343 } else if (search == 2) {
5344 end_mime_entity = ftell(fp_read);
5345 if( end_mime_entity < 0 ) { /*prevent 24473*/
5346 EM_DEBUG_EXCEPTION("ftell failed [%s]", EM_STRERROR(errno));
5354 p_mime_entity = em_malloc(end_mime_entity - start_mime_entity);
5355 if (p_mime_entity == NULL) {
5356 EM_DEBUG_EXCEPTION("em_malloc failed");
5357 err = EMAIL_ERROR_OUT_OF_MEMORY;
5361 if (fseek(fp_read, start_mime_entity, SEEK_SET) < 0) {
5362 EM_DEBUG_EXCEPTION("fseek failed");
5363 err = EMAIL_ERROR_SYSTEM_FAILURE;
5367 /* +2 : CRLF line */
5368 if ((ret = fread(p_mime_entity, 1, end_mime_entity - (start_mime_entity + EM_SAFE_STRLEN(boundary) + 2), fp_read)) < 0) {
5369 EM_DEBUG_EXCEPTION("fread failed");
5370 err = EMAIL_ERROR_SYSTEM_FAILURE;
5374 fprintf(fp_write, "%s", p_mime_entity);
5387 emcore_mime_free_mime(mmsg);
5390 *output_path = mime_entity_path;
5395 EM_SAFE_FREE(p_mime_entity);
5397 EM_DEBUG_FUNC_END();
5401 int emcore_decode_body_text_from_file(FILE *stream, char *boundary_str, int encoding, int mode, int is_text, int fd, char **holder, int *end_of_parsing, int *size)
5403 EM_DEBUG_FUNC_BEGIN();
5404 int error = EMAIL_ERROR_NONE;
5406 int partial_body = 0;
5408 long start_location = 0;
5409 long end_location = 0;
5410 char boundary[BOUNDARY_LEN] = {0x00, };
5411 char boundary_end[BOUNDARY_LEN] = {0x00, };
5412 char buf[MIME_LINE_LEN] = {0x00, };
5414 int modified_body_size = 0;
5415 char *modified_body = NULL;
5418 /* if there boundary, this content is from current line to ending boundary */
5419 memset(boundary, 0x00, BOUNDARY_LEN);
5420 memset(boundary_end, 0x00, BOUNDARY_LEN);
5422 SNPRINTF(boundary, BOUNDARY_LEN, "--%s%s", boundary_str, CRLF_STRING);
5423 SNPRINTF(boundary_end, BOUNDARY_LEN, "--%s%s", boundary_str, "--\r\n");
5426 start_location = ftell(stream);
5427 if(start_location < 0 ) { /*prevent 35555*/
5428 error = EMAIL_ERROR_INVALID_PARAM;
5429 EM_DEBUG_EXCEPTION("ftell failed : %s", EM_STRERROR(errno));
5434 if (!emcore_get_line_from_file(stream, buf, MIME_LINE_LEN, &error)) {
5435 if (error != EMAIL_ERROR_NO_MORE_DATA) {
5436 EM_DEBUG_EXCEPTION("emcore_get_line_from_file failed");
5437 error = EMAIL_ERROR_SYSTEM_FAILURE;
5442 *end_of_parsing = 1;
5447 if (!strcmp(buf, boundary)) { /* the other part started. the parsing of other part will be started */
5448 *end_of_parsing = 0;
5451 else if (!strcmp(buf, boundary_end)) { /* if ending boundary, the parsing of other multipart will be started */
5452 *end_of_parsing = 1;
5458 end_location = ftell(stream);
5459 if(end_location < 0 ) { /*prevent 35555*/
5460 error = EMAIL_ERROR_INVALID_PARAM;
5461 EM_DEBUG_EXCEPTION("ftell failed : %s", EM_STRERROR(errno));
5466 p_size = end_location - start_location;
5468 p_size = end_location - start_location - EM_SAFE_STRLEN(buf);
5470 body = em_malloc(p_size + 1);
5472 EM_DEBUG_EXCEPTION("em_malloc failed");
5473 error = EMAIL_ERROR_OUT_OF_MEMORY;
5477 fseek(stream, start_location, SEEK_SET);
5478 if (fread(body, sizeof(char), p_size, stream) != p_size) {
5479 EM_DEBUG_EXCEPTION("fread failed");
5480 error = EMAIL_ERROR_SYSTEM_FAILURE;
5484 if (mode > SAVE_TYPE_SIZE) { /* decode content */
5485 emcore_decode_body_text(body, p_size, encoding, &dec_len, &error);
5488 modified_body = em_replace_all_string(body, "cid:", "");
5489 modified_body_size = EM_SAFE_STRLEN(modified_body); /*prevent 35585 */
5492 if (modified_body == NULL) {
5493 modified_body = em_malloc(dec_len + 1);
5494 if (modified_body == NULL) {
5495 EM_DEBUG_EXCEPTION("em_malloc failed");
5496 error = EMAIL_ERROR_OUT_OF_MEMORY;
5500 memcpy(modified_body, body, dec_len); /*prevent 35585 */
5501 modified_body_size = dec_len;
5504 if (mode == SAVE_TYPE_BUFFER) { /* save content to buffer */
5505 *holder = EM_SAFE_STRDUP(modified_body);
5506 } else if (mode == SAVE_TYPE_FILE) { /* save content to file */
5507 if (write(fd, modified_body, modified_body_size) != modified_body_size) {
5508 EM_DEBUG_EXCEPTION("write failed");
5509 error = EMAIL_ERROR_SYSTEM_FAILURE;
5515 fseek((FILE *)stream, end_location, SEEK_SET);
5520 *size = modified_body_size;
5522 EM_SAFE_FREE(modified_body);
5523 EM_SAFE_FREE(body); /*prevent 35585 */
5527 int emcore_decode_body_text_from_sock(void *stream, char *boundary_str, int encoding, int mode, int is_text, int fd, char **holder, int *end_of_parsing, int *size)
5529 EM_DEBUG_FUNC_BEGIN();
5530 int error = EMAIL_ERROR_NONE;
5533 char boundary[BOUNDARY_LEN] = {0x00, };
5534 char boundary_end[BOUNDARY_LEN] = {0x00, };
5535 char buf[MIME_LINE_LEN] = {0x00, };
5536 char *result_buffer = NULL;
5537 int result_buffer_size = 0;
5541 /* if there boundary, this content is from current line to ending boundary */
5542 memset(boundary, 0x00, BOUNDARY_LEN);
5543 memset(boundary_end, 0x00, BOUNDARY_LEN);
5545 SNPRINTF(boundary, BOUNDARY_LEN, "--%s%s", boundary_str, CRLF_STRING);
5546 SNPRINTF(boundary_end, BOUNDARY_LEN, "--%s%s", boundary_str, "--\r\n");
5550 if (!emcore_check_thread_status()) {
5551 EM_DEBUG_EXCEPTION("EMAIL_ERROR_CANCELLED");
5552 error = EMAIL_ERROR_CANCELLED;
5556 if (!emcore_mime_get_line_from_sock(stream, buf, MIME_LINE_LEN, &error)) {
5557 if (error != EMAIL_ERROR_NO_MORE_DATA) {
5558 EM_DEBUG_EXCEPTION("emcore_mime_get_line_from_sock failed");
5559 error = EMAIL_ERROR_SYSTEM_FAILURE;
5563 EM_DEBUG_LOG("This mail is partial body");
5565 *end_of_parsing = 1;
5567 error = EMAIL_ERROR_NONE;
5573 if (!strcmp(buf, boundary)) { /* the other part started. the parsing of other part will be started */
5574 *end_of_parsing = 0;
5577 else if (!strcmp(buf, boundary_end)) { /* if ending boundary, the parsing of other multipart will be started */
5578 *end_of_parsing = 1;
5583 /* parsing string started by '.' in POP3 */
5584 if ((buf[0] == '.' && buf[1] == '.') && (encoding == ENCQUOTEDPRINTABLE || encoding == ENC7BIT)) {
5585 strncpy(buf, buf+1, MIME_LINE_LEN-1);
5586 buf[EM_SAFE_STRLEN(buf)] = NULL_CHAR;
5589 if (encoding == ENCBASE64) {
5590 if (EM_SAFE_STRLEN(buf) >= 2)
5591 buf[EM_SAFE_STRLEN(buf)-2] = NULL_CHAR;
5592 } else if (encoding == ENCQUOTEDPRINTABLE) {
5593 /* if (strcmp(buf, CRLF_STRING) == 0 */
5597 dec_len = EM_SAFE_STRLEN(buf);
5599 if (mode > SAVE_TYPE_SIZE) { /* decode content */
5600 emcore_decode_body_text(buf, dec_len, encoding, &dec_len, &error);
5603 result_buffer = em_replace_string(buf, "cid:", "");
5605 result_buffer_size = EM_SAFE_STRLEN(result_buffer);
5608 if (result_buffer == NULL) {
5609 result_buffer = strdup(buf); /*prevent 35499*/
5610 result_buffer_size = dec_len;
5613 if (mode == SAVE_TYPE_BUFFER) { /* save content to buffer */
5614 pTemp = realloc(*holder, sz + result_buffer_size + 2);
5616 EM_DEBUG_EXCEPTION("realloc failed...");
5617 error = EMAIL_ERROR_OUT_OF_MEMORY;
5619 EM_SAFE_FREE(*holder);
5620 EM_SAFE_FREE(result_buffer);
5626 memcpy(*holder + sz, result_buffer, result_buffer_size);
5627 (*holder)[sz + EM_SAFE_STRLEN(result_buffer) + 1] = NULL_CHAR;
5628 } else if (mode == SAVE_TYPE_FILE) { /* save content to file */
5629 if (write(fd, result_buffer, result_buffer_size) != result_buffer_size) {
5630 EM_DEBUG_EXCEPTION("write failed");
5631 error = EMAIL_ERROR_SYSTEM_FAILURE;
5636 EM_SAFE_FREE(result_buffer);
5643 EM_SAFE_FREE(result_buffer); /*prevent 35499*/
5645 if (error == EMAIL_ERROR_NONE) {
5650 EM_DEBUG_FUNC_END("error [%d], sz[%d]", error, sz);