4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Kyuho Jo <kyuho.jo@samsung.com>, Sunghyun Kwon <sh0701.kwon@samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
24 /* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ***
25 *File : email-core-mime.c
26 *Desc : MIME Operation
31 * 2011.04.14 : created
32 ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ***/
42 #include "email-internal-types.h"
44 #include "email-utilities.h"
45 #include "email-core-global.h"
46 #include "email-core-utils.h"
47 #include "email-core-mail.h"
48 #include "email-core-mime.h"
49 #include "email-storage.h"
50 #include "email-core-event.h"
51 #include "email-core-account.h"
52 #include "email-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 char buf[MIME_LINE_LEN] = {0, };
457 int local_end_of_parsing = 0;
461 *err_code = EMAIL_ERROR_INVALID_PARAM;
462 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
467 if (!emcore_check_thread_status()) {
468 if (err_code != NULL)
469 *err_code = EMAIL_ERROR_CANCELLED;
470 EM_DEBUG_FUNC_END("EMAIL_ERROR_CANCELLED");
474 if ((is_file == 0 && !emcore_mime_get_line_from_sock(stream, buf, MIME_LINE_LEN, err_code)) ||
475 (is_file == 1 && !emcore_get_line_from_file(stream, buf, MIME_LINE_LEN, err_code))) {
476 EM_DEBUG_EXCEPTION("emcore_mime_get_line_from_sock failed");
477 local_end_of_parsing = 0;
481 if (boundary_string && boundary_end_string) {
482 if (!strcmp(buf, boundary_string)) {
483 EM_DEBUG_LOG("found boundary");
484 local_end_of_parsing = 0;
487 else if (!strcmp(buf, boundary_end_string)) {
488 EM_DEBUG_LOG("found boundary_end");
489 local_end_of_parsing = 1;
496 *end_of_parsing = local_end_of_parsing;
502 int emcore_parse_mime(void *stream, int is_file, struct _m_content_info *cnt_info, int *err_code)
504 EM_DEBUG_FUNC_BEGIN("stream[%p], is_file[%d], cnt_info[%p], err_code[%p]", stream, is_file, cnt_info, err_code);
506 struct _m_mesg *mmsg = em_malloc(sizeof(struct _m_mesg));
508 if (!mmsg) return false;
510 memset(mmsg, 0x00, sizeof(struct _m_mesg));
512 /* 1. parse the first found header */
513 EM_DEBUG_LOG(">>>>>> 1. parse the first found header");
514 if (!emcore_mime_parse_header(stream, is_file, &mmsg->rfc822header, &mmsg->header, err_code)) {
519 if (!emcore_check_thread_status()) {
520 if (err_code != NULL)
521 *err_code = EMAIL_ERROR_CANCELLED;
522 emcore_mime_free_mime(mmsg);
527 EM_DEBUG_LOG(">>>>>> 2. parse body");
528 if (mmsg && mmsg->header && mmsg->header->part_header && mmsg->header->part_header->parameter) {
529 EM_DEBUG_LOG("name[%s]", mmsg->header->part_header->parameter->name);
530 EM_DEBUG_LOG("value[%s]", mmsg->header->part_header->parameter->value);
531 EM_DEBUG_LOG("next : %p", mmsg->header->part_header->parameter->next);
534 if (!emcore_mime_parse_body(stream, is_file, mmsg, cnt_info, NULL, err_code)) {
540 EM_DEBUG_LOG(">>>>>> 3. free memory");
541 if (mmsg && mmsg->header && mmsg->header->part_header && mmsg->header->part_header->parameter) {
542 EM_DEBUG_LOG("name[%s]", mmsg->header->part_header->parameter->name);
543 EM_DEBUG_LOG("value[%s]", mmsg->header->part_header->parameter->value);
544 EM_DEBUG_LOG("next : %p", mmsg->header->part_header->parameter->next);
546 emcore_mime_free_mime(mmsg);
551 int emcore_mime_parse_header(void *stream, int is_file, struct _rfc822header **rfc822header, struct _m_mesg_header **header, int *err_code)
553 EM_DEBUG_FUNC_BEGIN("stream[%p], is_file[%d], rfc822header[%p], header[%p], err_code[%p]", stream, is_file, rfc822header, header, err_code);
555 struct _m_mesg_header *tmp_header = NULL;
556 struct _rfc822header *tmp_rfc822header = NULL;
557 char buf[MIME_LINE_LEN] = {0, };
563 if (!emcore_check_thread_status()) {
564 if (err_code != NULL)
565 *err_code = EMAIL_ERROR_CANCELLED;
570 if ((is_file == 0 && !emcore_mime_get_line_from_sock(stream, buf, MIME_LINE_LEN, err_code)) ||
571 (is_file == 1 && !emcore_get_line_from_file(stream, buf, MIME_LINE_LEN, err_code))) {
575 if (!(tmp_header = em_malloc(sizeof(struct _m_mesg_header)))) {
576 EM_DEBUG_EXCEPTION("malloc failed...");
577 if (err_code != NULL)
578 *err_code = EMAIL_ERROR_OUT_OF_MEMORY;
582 if (!emcore_check_thread_status()) {
583 if (err_code != NULL)
584 *err_code = EMAIL_ERROR_CANCELLED;
589 EM_DEBUG_LOG("buf[%s]", buf);
591 if (!strncmp(buf, CRLF_STRING, 2))
594 is_longheader = (buf[0] == ' ' || buf[0] == '\t') ? TRUE : FALSE;
597 if (!is_longheader) { /* Normal header (format : "Name : Value" or "Name : Value; Parameters" */
602 /* EM_DEBUG_FUNC_BEGIN() */
603 if ((pTemp = strtok(buf, ":")) == NULL)
606 name = EM_SAFE_STRDUP(pTemp);
608 value = strtok(NULL, CRLF_STRING);
610 em_upper_string(name);
612 else { /* Long header */
613 value = strtok(buf, CRLF_STRING);
617 /* --> 2007-05-08 by cy */
621 EM_DEBUG_LOG("> name[%s]", name);
622 EM_DEBUG_LOG("> value[%s]", value);
624 /* MIME Part Heade */
625 if (memcmp(name, "CONTENT-", 8) == 0 && value) {
627 emcore_mime_set_part_header_value(&tmp_header->part_header, name, value, err_code);
629 if (tmp_header->part_header && tmp_header->part_header->parameter) {
630 EM_DEBUG_LOG("name[%s]", tmp_header->part_header->parameter->name);
631 EM_DEBUG_LOG("value[%s]", tmp_header->part_header->parameter->value);
632 EM_DEBUG_LOG("next : %p", tmp_header->part_header->parameter->next);
635 /* MIME Version Heade */
637 else if (memcmp(name, "MIME-VERSION", 12) == 0) {
638 /* EM_DEBUG_FUNC_BEGIN() */
639 /* ignored because we need only contents information */
640 /* tmp_header->version = EM_SAFE_STRDUP(value) */
645 /* in socket stream case, ignored because we need only contents information */
647 emcore_mime_set_rfc822_header_value(&tmp_rfc822header, name, value, err_code);
650 if (!emcore_check_thread_status()) {
651 if (err_code != NULL)
652 *err_code = EMAIL_ERROR_CANCELLED;
656 if ((is_file == 0 && !emcore_mime_get_line_from_sock(stream, buf, MIME_LINE_LEN, err_code)) ||
657 (is_file == 1 && !emcore_get_line_from_file(stream, buf, MIME_LINE_LEN, err_code))) {
659 if (tmp_rfc822header)
660 emcore_mime_free_rfc822_header(tmp_rfc822header);
664 emcore_mime_free_part_header(tmp_header->part_header);
666 EM_SAFE_FREE(tmp_header->version);
667 EM_SAFE_FREE(tmp_header);
673 *header = tmp_header;
674 *rfc822header = tmp_rfc822header;
681 int emcore_mime_parse_part_header(void *stream, int is_file, struct _m_part_header **header, int *err_code)
683 EM_DEBUG_FUNC_BEGIN("stream[%p], is_file[%d], header[%p], err_code[%p]", stream, is_file, header, err_code);
685 struct _m_part_header *tmp_header = NULL;
686 char buf[MIME_LINE_LEN] = {0x00};
690 int is_longheader = false;
692 if (!emcore_check_thread_status()) {
693 if (err_code != NULL)
694 *err_code = EMAIL_ERROR_CANCELLED;
698 if ((is_file == 0 && !emcore_mime_get_line_from_sock(stream, buf, MIME_LINE_LEN, err_code)) ||
699 (is_file == 1 && !emcore_get_line_from_file(stream, buf, MIME_LINE_LEN, err_code)))
702 tmp_header = em_malloc(sizeof(struct _m_part_header));
705 EM_DEBUG_EXCEPTION("em_malloc failed");
709 memset(tmp_header, 0, sizeof(struct _m_part_header));
712 if (!strncmp(buf, CRLF_STRING, EM_SAFE_STRLEN(CRLF_STRING))) break;
714 is_longheader = (buf[0] == ' ' || buf[0] == TAB);
716 if (!is_longheader) { /* Normal header (format : "Name : Value" or "Name : Value; Parameters" */
718 p = strtok(buf , ":");
721 name = EM_SAFE_STRDUP(p);
722 value = strtok(NULL, CRLF_STRING);
723 em_upper_string(name);
726 else /* Long header */
727 value = strtok(buf, CRLF_STRING);
732 emcore_mime_set_part_header_value(&tmp_header, name, value, err_code);
734 if (!emcore_check_thread_status()) {
735 if (err_code != NULL)
736 *err_code = EMAIL_ERROR_CANCELLED;
740 if ((is_file == 0 && !emcore_mime_get_line_from_sock(stream, buf, MIME_LINE_LEN, err_code)) ||
741 (is_file == 1 && !emcore_get_line_from_file(stream, buf, MIME_LINE_LEN, err_code))) {
743 EM_SAFE_FREE(tmp_header);
749 *header = tmp_header;
757 int emcore_mime_parse_body(void *stream, int is_file, struct _m_mesg *mmsg, struct _m_content_info *cnt_info, void *callback, int *err_code)
759 EM_DEBUG_FUNC_BEGIN("stream[%p], is_file[%d], mmsg[%p], cnt_info[%p], callback[%p], err_code[%p]", stream, is_file, mmsg, cnt_info, callback, err_code);
761 char *content_type = NULL, *content_encoding = NULL, *holder = NULL, *attachment_name, *t = NULL;
762 int type = 0, end_of_parsing = 0, size, local_err_code = EMAIL_ERROR_NONE;
764 if (!emcore_check_thread_status()) {
765 if (err_code != NULL)
766 *err_code = EMAIL_ERROR_CANCELLED;
771 content_type = emcore_mime_get_header_value(mmsg->header->part_header, CONTENT_TYPE, err_code);
773 content_type = "TEXT/PLAIN";
776 content_encoding = emcore_mime_get_header_value(mmsg->header->part_header, CONTENT_ENCODING, err_code);
777 if (!content_encoding)
778 content_encoding = "7BIT";
780 if (strstr(content_type, TEXT_STR)) type = TYPE_TEXT;
781 else if (strstr(content_type, IMAGE_STR)) type = TYPE_IMAGE;
782 else if (strstr(content_type, AUDIO_STR)) type = TYPE_AUDIO;
783 else if (strstr(content_type, VIDEO_STR)) type = TYPE_VIDEO;
784 else if (strstr(content_type, APPLICATION_STR)) type = TYPE_APPLICATION;
785 else if (strstr(content_type, MULTIPART_STR)) type = TYPE_MULTIPART;
786 else if (strstr(content_type, MESSAGE_STR)) type = TYPE_MESSAGE;
787 else type = TYPE_UNKNOWN;
791 if (mmsg->header && !emcore_mime_get_header_value(mmsg->header->part_header, CONTENT_BOUNDARY, err_code)) {
792 EM_DEBUG_FUNC_END("false");
796 if (mmsg->header && !emcore_mime_parse_part(stream, is_file, mmsg->header->part_header, &mmsg->nested, cnt_info, &end_of_parsing, &local_err_code)) {
797 EM_DEBUG_FUNC_END("false");
801 /* after finishing body parsing, make stream empty to get next mail. (get line from sock or file until '.' is read */
802 if (end_of_parsing == true && local_err_code != EMAIL_ERROR_NO_MORE_DATA)
803 emcore_mime_flush_receiving_buffer(stream, is_file, NULL, NULL, NULL, err_code);
806 *err_code = local_err_code;
811 attachment_name = NULL;
813 if (mmsg->header && emcore_mime_get_header_value(mmsg->header->part_header, CONTENT_DISPOSITION, err_code)) {
814 attachment_name = emcore_mime_get_header_value(mmsg->header->part_header, CONTENT_FILENAME, err_code);
815 /* if (!attachment_name) attachment_name = "unknown" */
816 if (attachment_name) EM_DEBUG_LOG(" attachment = [%s]", attachment_name);
819 if (strstr(content_type, "PKCS7-MIME")) {
820 EM_DEBUG_LOG("Encrypted mail do not include the body");
821 cnt_info->file = em_malloc(sizeof(struct attachment_info));
822 if (cnt_info->file) {
823 cnt_info->file->type = 2;
824 cnt_info->file->name = EM_SAFE_STRDUP(attachment_name);
825 if (!emcore_mime_get_content_data(stream, is_file, false, NULL, content_encoding, &end_of_parsing, SAVE_TYPE_FILE, &holder, &size, NULL, err_code)) {
826 EM_DEBUG_EXCEPTION("emcore_mime_get_content_data failed : [%d]", err_code);
829 cnt_info->file->save = holder;
830 cnt_info->file->size = size;
835 if (cnt_info->grab_type & GRAB_TYPE_TEXT) {
837 /* get content data. content data is saved in file */
838 if (!emcore_mime_get_content_data(stream, is_file, true, NULL, content_encoding, &end_of_parsing, SAVE_TYPE_FILE, &holder, &size, NULL, err_code)) {
839 EM_DEBUG_EXCEPTION("emcore_mime_get_content_data failed : [%d]", err_code);
843 EM_DEBUG_LOG("After emcore_mime_get_content_data");
845 char *charset = mmsg->header? emcore_mime_get_header_value(mmsg->header->part_header, CONTENT_CHARSET, err_code) : NULL; /* prevent 27453 */
847 EM_DEBUG_LOG(">>>> charset [%s]", charset);
849 if (mmsg->header && mmsg->header->part_header && strstr((t = emcore_mime_get_header_value(mmsg->header->part_header, CONTENT_TYPE, err_code)) ? t : "", "HTML")) {
850 if (!charset || !strncmp(charset, "X-UNKNOWN", strlen("X-UNKNOWN")))
851 cnt_info->text.plain_charset = strdup("UTF-8");
853 cnt_info->text.plain_charset = EM_SAFE_STRDUP(charset);
855 EM_DEBUG_LOG(">>>> cnt_info->text.plain_charset [%s]", cnt_info->text.plain_charset);
857 cnt_info->text.html = holder;
859 EM_DEBUG_LOG(">>>> cnt_info->text.plain [%s]", cnt_info->text.html);
862 else if (mmsg->header) {
864 if (!charset || !strncmp(charset, "X-UNKNOWN", strlen("X-UNKNOWN")))
865 cnt_info->text.plain_charset = strdup("UTF-8");
867 cnt_info->text.plain_charset = EM_SAFE_STRDUP(charset);
869 EM_DEBUG_LOG(">>>> cnt_info->text.plain_charset [%s]", cnt_info->text.plain_charset);
871 cnt_info->text.plain = holder;
873 EM_DEBUG_LOG(">>>> cnt_info->text.plain [%s]", cnt_info->text.plain);
883 int emcore_mime_parse_part(void *stream, int is_file, struct _m_part_header *parent_header, struct _m_part *nested, struct _m_content_info *cnt_info, int *eop, int *err_code)
885 EM_DEBUG_FUNC_BEGIN("stream[%p], is_file[%d], parent_header[%p], nested[%p], cnt_info[%p], eop[%p], err_code[%p]", stream, is_file, parent_header, nested, cnt_info, eop, err_code);
887 struct _m_body *tmp_body = NULL;
888 struct _m_part **p = NULL;
889 char buf[MIME_LINE_LEN] = {0x00, };
890 char boundary[BOUNDARY_LEN] = {0x00, };
891 char boundary_end[BOUNDARY_LEN] = {0x00, };
892 char mime_type_buffer[128] = { 0, };
893 char *boundary_str = NULL;
894 char *content_type = NULL;
895 char *content_encoding = NULL;
897 char *attachment_name = NULL;
898 char *content_disposition = NULL;
902 int content_disposition_type = 0;
903 int end_of_parsing = 0;
904 int size = 0, local_err_code = EMAIL_ERROR_NONE;
908 boundary_str = emcore_mime_get_header_value(parent_header, CONTENT_BOUNDARY, err_code);
910 SNPRINTF(boundary, BOUNDARY_LEN, "--%s%s", boundary_str, CRLF_STRING);
911 SNPRINTF(boundary_end, BOUNDARY_LEN, "--%s%s", boundary_str, "--\r\n");
916 /* goto the first found useful mime dat */
917 EM_DEBUG_LOG("Before first loop");
919 if (!emcore_check_thread_status()) {
920 if (err_code != NULL)
921 *err_code = EMAIL_ERROR_CANCELLED;
924 if ((is_file == 0 && !emcore_mime_get_line_from_sock(stream, buf, MIME_LINE_LEN, err_code)) ||
925 (is_file == 1 && !emcore_get_line_from_file(stream, buf, MIME_LINE_LEN, err_code))) {
926 EM_DEBUG_EXCEPTION("emcore_mime_get_line_from_sock failed.");
929 EM_DEBUG_FUNC_END("false");
933 if (!strcmp(buf, boundary))
937 EM_DEBUG_LOG("Before second loop");
939 if (!(tmp_body = em_malloc(sizeof(struct _m_body)))) {
940 EM_DEBUG_EXCEPTION("em_malloc failed.");
942 emcore_mime_free_part_body(nested->body);
944 emcore_mime_free_part(nested->next);
945 EM_DEBUG_FUNC_END("false");
949 memset(tmp_body, 0, sizeof(struct _m_body));
951 /* parsing MIME Header */
952 if (!emcore_mime_parse_part_header(stream, is_file, &tmp_body->part_header, err_code)) {
953 EM_DEBUG_EXCEPTION("emcore_mime_parse_part_header failed.");
955 emcore_mime_free_part_body(nested->body);
957 emcore_mime_free_part(nested->next);
959 emcore_mime_free_part_body(tmp_body);
963 content_type = emcore_mime_get_header_value(tmp_body->part_header, CONTENT_TYPE, err_code);
966 content_type = "TEXT/PLAIN";
968 content_encoding = emcore_mime_get_header_value(tmp_body->part_header, CONTENT_ENCODING, err_code);
969 if (!content_encoding)
970 content_encoding = "7BIT";
972 if (strstr(content_type, TEXT_STR)) type = TYPE_TEXT;
973 else if (strstr(content_type, IMAGE_STR)) type = TYPE_IMAGE;
974 else if (strstr(content_type, AUDIO_STR)) type = TYPE_AUDIO;
975 else if (strstr(content_type, VIDEO_STR)) type = TYPE_VIDEO;
976 else if (strstr(content_type, APPLICATION_STR)) type = TYPE_APPLICATION;
977 else if (strstr(content_type, MULTIPART_STR)) type = TYPE_MULTIPART;
978 else if (strstr(content_type, MESSAGE_STR)) type = TYPE_MESSAGE;
979 else type = TYPE_UNKNOWN;
983 EM_DEBUG_LOG("TYPE_MULTIPART");
984 if (!emcore_mime_get_header_value(tmp_body->part_header, CONTENT_BOUNDARY, err_code)) {
985 EM_DEBUG_EXCEPTION("emcore_mime_get_header_value failed.");
986 emcore_mime_free_part_body(tmp_body);
987 EM_DEBUG_FUNC_END("false");
991 emcore_mime_parse_part(stream, is_file, tmp_body->part_header, &tmp_body->nested, cnt_info, &end_of_parsing, &local_err_code);
994 nested->body = tmp_body;
998 while (*p && (*p)->next)
1004 if (!(*p = em_malloc(sizeof(struct _m_part)))) {
1005 EM_DEBUG_EXCEPTION("em_malloc failed");
1006 if (nested->body) emcore_mime_free_part_body(nested->body);
1007 if (nested->next) emcore_mime_free_part(nested->next);
1008 emcore_mime_free_part_body(tmp_body);
1009 EM_DEBUG_FUNC_END("false");
1013 (*p)->body = tmp_body;
1018 *err_code = local_err_code;
1020 if (end_of_parsing && local_err_code != EMAIL_ERROR_NO_MORE_DATA) /* working with imap */
1021 /* if (!end_of_parsing) */ /* working with pop */ {
1022 EM_DEBUG_LOG("Enter flushing socket buffer.");
1023 emcore_mime_flush_receiving_buffer(stream, is_file, boundary, boundary_end, &end_of_parsing, err_code);
1029 EM_DEBUG_LOG("default");
1030 attachment_name = NULL;
1031 content_disposition = NULL;
1033 if (type == TYPE_MESSAGE)
1036 if (is_skip == true) {
1037 if (!emcore_mime_skip_content_data(stream, is_file, boundary_str, &end_of_parsing, &size, NULL, err_code))
1038 EM_DEBUG_EXCEPTION("emcore_mime_skip_content_data failed...");
1040 emcore_mime_free_part_body(tmp_body);
1041 EM_DEBUG_LOG_MIME("break");
1045 /* first check inline content */
1046 /* if the content id or content location exis */
1047 t = emcore_mime_get_header_value(tmp_body->part_header, CONTENT_TYPE, err_code);
1048 EM_DEBUG_LOG("content_type : [%s]", t);
1050 if (!strstr(t ? t : "", "HTML")) {
1051 content_disposition = emcore_mime_get_header_value(tmp_body->part_header, CONTENT_DISPOSITION, err_code);
1052 EM_DEBUG_LOG("content_disposition : [%s]", content_disposition);
1054 attachment_name = emcore_mime_get_header_value(tmp_body->part_header, CONTENT_ID, err_code);
1055 EM_DEBUG_LOG("content_id : [%s]", attachment_name);
1057 if (attachment_name) {
1058 if (emcore_search_string_from_file(cnt_info->text.html, attachment_name, &result) == EMAIL_ERROR_NONE && result) {
1059 content_disposition_type = INLINE_ATTACHMENT;
1060 } else if (!strcasecmp(content_disposition ? content_disposition : "", "attachment")) {
1061 attachment_name = emcore_mime_get_header_value(tmp_body->part_header, CONTENT_NAME, err_code);
1063 if (!attachment_name)
1064 attachment_name = emcore_mime_get_header_value(tmp_body->part_header, CONTENT_FILENAME, err_code);
1066 content_disposition_type = ATTACHMENT;
1069 EM_DEBUG_EXCEPTION("Unknown mime type");
1072 if (!strcasecmp(content_disposition ? content_disposition : "", "attachment")) {
1073 attachment_name = emcore_mime_get_header_value(tmp_body->part_header, CONTENT_NAME, err_code);
1075 if (!attachment_name)
1076 attachment_name = emcore_mime_get_header_value(tmp_body->part_header, CONTENT_FILENAME, err_code);
1078 content_disposition_type = ATTACHMENT;
1080 } else if (!strcasecmp(content_disposition ? content_disposition : "", "inline")) {
1081 attachment_name = emcore_mime_get_header_value(tmp_body->part_header, CONTENT_NAME, err_code);
1083 if (!attachment_name)
1084 attachment_name = emcore_mime_get_header_value(tmp_body->part_header, CONTENT_FILENAME, err_code);
1086 content_disposition_type = INLINE_ATTACHMENT;
1087 } else if (strstr(content_type, "PKCS7")) {
1088 attachment_name = emcore_mime_get_header_value(tmp_body->part_header, CONTENT_NAME, err_code);
1089 EM_DEBUG_LOG_MIME(">> attachment = [%s]", attachment_name ? attachment_name : NIL);
1091 content_disposition_type = ATTACHMENT;
1094 EM_DEBUG_EXCEPTION("Unknown mime");
1100 if (!emcore_check_thread_status()) {
1101 if (err_code != NULL)
1102 *err_code = EMAIL_ERROR_CANCELLED;
1103 EM_DEBUG_EXCEPTION("EMAIL_ERROR_CANCELLED");
1104 emcore_mime_free_part_body(tmp_body);
1105 EM_DEBUG_FUNC_END("false");
1109 EM_DEBUG_LOG("attachment_name : [%s]", attachment_name);
1110 /* get content and content information */
1111 if (!attachment_name) { /* text */
1112 /* get content by buffer */
1113 EM_DEBUG_LOG_MIME("attachment_name is NULL. It's a text message");
1114 if (!emcore_mime_get_content_data(stream, is_file, true, boundary_str, content_encoding, &end_of_parsing, SAVE_TYPE_FILE, &holder, &size, NULL, err_code)) {
1115 EM_DEBUG_EXCEPTION("emcore_mime_get_content_data failed [%d]", err_code);
1116 emcore_mime_free_part_body(tmp_body);
1120 EM_DEBUG_LOG("After emcore_mime_get_content_data");
1122 if (cnt_info->grab_type & GRAB_TYPE_TEXT) {
1123 if (tmp_body->part_header && strstr(t ? t : "", "HTML")) {
1124 cnt_info->text.html = holder;
1126 EM_DEBUG_LOG(" cnt_info->text.html [%s]", cnt_info->text.html);
1129 char *charset = emcore_mime_get_header_value(tmp_body->part_header, CONTENT_CHARSET, err_code);
1130 EM_DEBUG_LOG(" charset [%s]", charset);
1132 if (!charset || !strncmp(charset, "X-UNKNOWN", strlen("X-UNKNOWN")))
1133 cnt_info->text.plain_charset = strdup("UTF-8");
1135 cnt_info->text.plain_charset = EM_SAFE_STRDUP(charset);
1137 EM_DEBUG_LOG(" cnt_info->text.plain_charset [%s]", cnt_info->text.plain_charset);
1139 cnt_info->text.plain = holder;
1141 EM_DEBUG_LOG(" cnt_info->text.plain [%s]", cnt_info->text.plain);
1151 else { /* attachment */
1152 EM_DEBUG_LOG("attachment_name is not NULL. It's a attachment");
1153 struct attachment_info *file = NULL;
1154 struct attachment_info *temp_file = cnt_info->file;
1156 file = em_malloc(sizeof(struct attachment_info));
1158 EM_DEBUG_EXCEPTION("em_malloc failed...");
1159 emcore_mime_free_part_body(tmp_body);
1160 EM_DEBUG_FUNC_END("false");
1164 file->type = content_disposition_type;
1166 EM_DEBUG_LOG("file->type : %d", file->type);
1168 file->name = EM_SAFE_STRDUP(attachment_name);
1169 file->content_id = EM_SAFE_STRDUP(tmp_body->part_header->content_id);
1170 if(tmp_body->part_header->type && tmp_body->part_header->subtype) {
1171 SNPRINTF(mime_type_buffer, 128, "%s/%s", tmp_body->part_header->type, tmp_body->part_header->subtype);
1172 file->attachment_mime_type = EM_SAFE_STRDUP(mime_type_buffer);
1175 /* check if the current file is target file */
1176 if ((cnt_info->grab_type & GRAB_TYPE_ATTACHMENT) || file->type == INLINE_ATTACHMENT) {
1177 /* get content by file */
1178 EM_DEBUG_LOG_MIME("Trying to get content");
1179 if (!emcore_mime_get_content_data(stream, is_file, false, boundary_str, content_encoding, &end_of_parsing, SAVE_TYPE_FILE, &holder, &size, NULL, err_code)) {
1180 EM_DEBUG_EXCEPTION("emcore_mime_get_content_data failed [%d]", err_code);
1181 emcore_mime_free_part_body(tmp_body);
1182 emcore_free_attachment_info(file);
1183 EM_DEBUG_FUNC_END("false");
1187 file->save = holder;
1189 /* only get content size */
1190 EM_DEBUG_LOG_MIME("Pass downloading");
1191 if (!emcore_mime_get_content_data(stream, is_file, false, boundary_str, content_encoding, &end_of_parsing, SAVE_TYPE_SIZE, NULL, &size, NULL, err_code)) {
1192 EM_DEBUG_EXCEPTION("emcore_mime_get_content_data failed [%d]", err_code);
1193 emcore_mime_free_part_body(tmp_body);
1194 emcore_free_attachment_info(file);
1195 EM_DEBUG_FUNC_END("false");
1203 EM_DEBUG_LOG("end_of_parsing [%d], err_code [%d]", end_of_parsing, *err_code);
1207 if (strstr(content_type, APPLICATION_STR)) {
1208 pTemp = content_type + EM_SAFE_STRLEN(APPLICATION_STR);
1210 if (strcasecmp(pTemp, MIME_SUBTYPE_DRM_OBJECT) == 0)
1211 file->drm = EMAIL_ATTACHMENT_DRM_OBJECT;
1212 else if (strcasecmp(pTemp, MIME_SUBTYPE_DRM_RIGHTS) == 0)
1213 file->drm = EMAIL_ATTACHMENT_DRM_RIGHTS;
1214 else if (strcasecmp(pTemp, MIME_SUBTYPE_DRM_DCF) == 0)
1215 file->drm = EMAIL_ATTACHMENT_DRM_DCF;
1218 while (temp_file && temp_file->next)
1219 temp_file = temp_file->next;
1221 if (temp_file == NULL)
1222 cnt_info->file = file;
1224 temp_file->next = file;
1227 if (!emcore_check_thread_status()) {
1228 if (err_code != NULL)
1229 *err_code = EMAIL_ERROR_CANCELLED;
1230 EM_DEBUG_EXCEPTION("EMAIL_ERROR_CANCELLED");
1231 emcore_mime_free_part_body(tmp_body);
1232 EM_DEBUG_FUNC_END("false");
1237 nested->body = tmp_body;
1241 while (*p && (*p)->next)
1247 if (!(*p = em_malloc(sizeof(struct _m_part)))) {
1248 EM_DEBUG_EXCEPTION("em_malloc failed");
1249 if (nested->body) emcore_mime_free_part_body(nested->body);
1250 if (nested->next) emcore_mime_free_part(nested->next);
1252 emcore_mime_free_part_body(tmp_body);
1253 EM_DEBUG_FUNC_END("false");
1257 (*p)->body = tmp_body;
1270 *eop = end_of_parsing;
1272 EM_DEBUG_FUNC_END("end_of_parsing [%d]", end_of_parsing);
1276 /* set RFC822 Heade */
1277 int emcore_mime_set_rfc822_header_value(struct _rfc822header **header, char *name, char *value, int *err_code)
1279 EM_DEBUG_FUNC_BEGIN("header[%p], name[%s], value[%s], err_code[%p]", header, name, value, err_code);
1284 if (!value || !*value || !name ) return false; /*prevent 34354*/
1287 *header = em_malloc(sizeof(struct _rfc822header));
1289 EM_DEBUG_EXCEPTION("em_malloc failed");
1295 em_upper_string(name);
1297 if (strncmp(name, "RETURN-PATH", strlen("RETURN-PATH")) == 0)
1298 p = &(*header)->return_path;/* Return-Rat */
1299 else if (strncmp(name, "RECEIVED", strlen("RECEIVED")) == 0)
1300 p = &(*header)->received; /* Receive */
1301 else if (strncmp(name, "REPLY-TO", strlen("REPLY-TO")) == 0)
1302 p = &(*header)->reply_to; /* Reply-T */
1303 else if (strncmp(name, "DATE", strlen("DATE")) == 0)
1304 p = &(*header)->date; /* Dat */
1305 else if (strncmp(name, "FROM", strlen("FROM")) == 0)
1306 p = &(*header)->from; /* Fro */
1307 else if (strncmp(name, "SUBJECT", strlen("SUBJECT")) == 0)
1308 p = &(*header)->subject; /* Subjec */
1309 else if (strncmp(name, "SENDER", strlen("SENDER")) == 0)
1310 p = &(*header)->sender; /* Sende */
1311 else if (strncmp(name, "TO", strlen("TO")) == 0)
1312 p = &(*header)->to; /* T */
1313 else if (strncmp(name, "CC", strlen("CC")) == 0)
1314 p = &(*header)->cc; /* C */
1315 else if (strncmp(name, "BCC", strlen("BCC")) == 0)
1316 p = &(*header)->bcc; /* Bc */
1317 else if (strncmp(name, "X-PRIORITY", strlen("X-PRIORITY")) == 0)
1318 p = &(*header)->priority; /* Prorit */
1319 else if (strncmp(name, "X-MSMAIL-PRIORITY", strlen("X-MSMAIL-PRIORITY")) == 0)
1320 p = &(*header)->ms_priority;/* Prorit */
1321 else if (strncmp(name, "DISPOSITION-NOTIFICATION-TO", strlen("DISPOSITION-NOTIFICATION-TO")) == 0)
1322 p = &(*header)->dsp_noti_to;/* Disposition-Notification-T */
1328 *p = EM_SAFE_STRDUP(value);
1329 else { /* Long Header */
1330 if (!(t = realloc(*p, strlen(*p) + strlen(value)+1))) /*prevent 34354*/
1333 strncat(t, value, strlen(value)); /*prevent 34354*/
1340 /* set MIME Part Heade */
1341 int emcore_mime_set_part_header_value(struct _m_part_header **header, char *name, char *value, int *err_code)
1343 EM_DEBUG_FUNC_BEGIN("header[%p], name[%s], value[%s], err_code[%p]", header, name, value, err_code);
1345 if (!name || !value) {
1346 EM_DEBUG_EXCEPTION("Invalid parameter");
1347 if (err_code != NULL)
1348 *err_code = EMAIL_ERROR_INVALID_PARAM;
1352 struct _parameter *p = NULL;
1356 *header = em_malloc(sizeof(struct _m_part_header));
1358 EM_DEBUG_EXCEPTION("em_malloc failed...");
1363 em_upper_string(name);
1364 em_trim_left(value);
1365 em_trim_right(value);
1367 if (!emcore_check_thread_status()) {
1368 if (err_code != NULL)
1369 *err_code = EMAIL_ERROR_CANCELLED;
1374 if (strncmp(name, "CONTENT-TYPE", strlen("CONTENT-TYPE")) == 0) {
1375 p_val = strtok(value, ";");
1378 if (!(*header)->type) { /* Content-Type */
1379 em_upper_string(p_val);
1380 (*header)->type = EM_SAFE_STRDUP(p_val);
1382 else { /* Content-Type Parameter (format : "name =value" */
1383 if (emcore_mime_get_param_from_str(p_val, &p, err_code))
1384 emcore_mime_add_param_to_list(&((*header)->parameter), p, err_code);
1385 else /* name= CRLF value */ {
1386 struct _parameter *t = (*header)->parameter;
1387 while (t && t->next) {
1391 EM_DEBUG_LOG("name : [%s]", t->name);
1392 EM_DEBUG_LOG("value : [%s]", t->value);
1394 if (t->value == NULL) {
1395 char *pointer = NULL;
1397 if (EM_SAFE_STRLEN(p_val) > 0) {
1398 if ((pointer = strchr(p_val, '\"'))) {
1399 p_val = pointer + 1;
1400 if (!*p_val) return false;
1402 if ((pointer = strchr(p_val, '\"')))
1405 /* = ? ENCODING_TYPE ? B(Q) ? ENCODED_STRING ? */
1406 int err = EMAIL_ERROR_NONE;
1407 char *utf8_text = NULL;
1409 if (!(utf8_text = emcore_decode_rfc2047_text(p_val, &err)))
1410 EM_DEBUG_EXCEPTION("emcore_decode_rfc2047_text failed [%d]", err);
1411 EM_DEBUG_LOG("utf8_text : [%s]", utf8_text);
1412 t->value = EM_SAFE_STRDUP(utf8_text);
1419 /* repeatedly get paramete */
1420 while ((p_val = strtok(NULL, ";"))) {
1421 if (emcore_mime_get_param_from_str(p_val, &p, err_code))
1422 emcore_mime_add_param_to_list(&((*header)->parameter), p, err_code);
1426 else if (strncmp(name, "CONTENT-TRANSFER-ENCODING", strlen("CONTENT-TRANSFER-ENCODING")) == 0) {
1427 em_upper_string(value);
1428 (*header)->encoding = EM_SAFE_STRDUP(value);
1430 else if (strncmp(name, "CONTENT-DESCRPTION", strlen("CONTENT-DESCRPTION")) == 0) {
1431 em_upper_string(value);
1432 (*header)->desc = EM_SAFE_STRDUP(value);
1434 else if (strncmp(name, "CONTENT-DISPOSITION", strlen("CONTENT-DISPOSITION")) == 0) {
1435 p_val = strtok(value, ";");
1438 if (!(*header)->disp_type) { /* Content-Dispositio */
1439 em_upper_string(p_val);
1440 (*header)->disp_type = EM_SAFE_STRDUP(p_val);
1442 else { /* Content-Disposition parameter (format : "name =value" */
1443 if (emcore_mime_get_param_from_str(p_val, &p, err_code))
1444 emcore_mime_add_param_to_list(&((*header)->disp_parameter), p, err_code);
1447 /* repeatedly get paramete */
1448 while ((p_val = strtok(NULL, ";"))) {
1449 if (emcore_mime_get_param_from_str(p_val, &p, err_code))
1450 emcore_mime_add_param_to_list(&((*header)->disp_parameter), p, err_code);
1454 else if (strncmp(name, "CONTENT-ID", strlen("CONTENT-ID")) == 0) {
1456 len = EM_SAFE_STRLEN(value);
1457 /* em_upper_string(value) */
1459 if ((len) && (value[0] == '<')) {
1464 if ((len > 1) && (value[len-1] == '>'))
1465 value[len-1] = '\0';
1467 (*header)->content_id = EM_SAFE_STRDUP(value);
1469 else if (strncmp(name, "CONTENT-LOCATION", strlen("CONTENT-LOCATION")) == 0)
1470 (*header)->content_location = EM_SAFE_STRDUP(value);
1472 EM_DEBUG_FUNC_END();
1476 /* get header parameter from string */
1477 int emcore_mime_get_param_from_str(char *str, struct _parameter **param, int *err_code)
1479 EM_DEBUG_FUNC_BEGIN("str[%s], param[%p], err_code[%p]", str, param, err_code);
1481 char *p_name, *p_val, *p;
1485 /* Parameter Check */
1486 if (!(p = strchr(str, '='))) return false;
1493 em_trim_left(p_name);
1494 em_trim_right(p_name);
1496 if (!*p_name) return false;
1498 if (!(*param = em_malloc(sizeof(struct _parameter)))) return false;
1500 (*param)->next = NULL;
1503 /* Check string length */
1504 if (EM_SAFE_STRLEN(p_name) > 0) {
1505 em_upper_string(p_name);
1506 (*param)->name = EM_SAFE_STRDUP(p_name);
1509 em_trim_left(p_val);
1510 em_trim_right(p_val);
1513 EM_DEBUG_LOG("Parameter value is NULL");
1517 if (EM_SAFE_STRLEN(p_val) > 0) {
1518 if ((p = strchr(p_val, '\"'))) {
1520 if (!*p_val) return false;
1522 if ((p = strchr(p_val, '\"')))
1525 if (strncmp(p_name, "BOUNDARY", strlen("BOUNDARY")) != 0 && !strstr(p_name, "NAME"))
1526 em_upper_string(p_val);
1528 /* = ? ENCODING_TYPE ? B(Q) ? ENCODED_STRING ? */
1529 int err = EMAIL_ERROR_NONE;
1530 char *utf8_text = NULL;
1532 if (!(utf8_text = emcore_decode_rfc2047_text(p_val, &err)))
1533 EM_DEBUG_EXCEPTION("emcore_decode_rfc2047_text failed [%d]", err);
1534 (*param)->value = utf8_text;
1536 EM_DEBUG_FUNC_END();
1540 /* add a parameter to parameter lis */
1541 int emcore_mime_add_param_to_list(struct _parameter **param_list, struct _parameter *param, int *err_code)
1543 struct _parameter **t = param_list;
1545 while (*t && (*t)->next)
1556 /* get header value from MIME Part Heade */
1557 char *emcore_mime_get_header_value(struct _m_part_header *header, int type, int *err_code)
1559 EM_DEBUG_FUNC_BEGIN("header[%p], type[%d], err_code[%p]", header, type, err_code);
1561 struct _parameter *p = NULL;
1565 EM_DEBUG_EXCEPTION("header[%p], type[%d]", header, type);
1567 if (err_code != NULL)
1568 *err_code = EMAIL_ERROR_INVALID_PARAM;
1574 return header->type;
1576 case CONTENT_SUBTYPE:
1577 return header->subtype;
1579 case CONTENT_ENCODING:
1580 return header->encoding;
1582 case CONTENT_CHARSET:
1584 p = header->parameter;
1587 case CONTENT_DISPOSITION:
1588 return header->disp_type;
1592 p = header->parameter;
1595 case CONTENT_FILENAME:
1597 p = header->disp_parameter;
1600 case CONTENT_BOUNDARY:
1602 p = header->parameter;
1605 case CONTENT_REPORT_TYPE:
1606 name = "REPORT-TYPE";
1607 p = header->parameter;
1611 return header->content_id;
1613 case CONTENT_LOCATION:
1614 return header->content_location;
1620 for (; p; p = p->next) {
1621 if (strcmp(p->name, name) == 0)
1627 EM_DEBUG_FUNC_END();
1632 * decode body text (quoted-printable, base64)
1633 * enc_type : encoding type (base64/quotedprintable)
1635 INTERNAL_FUNC int emcore_decode_body_text(char *enc_buf, int enc_len, int enc_type, int *dec_len, int *err_code)
1637 EM_DEBUG_FUNC_BEGIN("enc_buf[%p], enc_len[%d], enc_type[%d], dec_len[%p]", enc_buf, enc_len, enc_type, dec_len);
1638 unsigned char *content = NULL;
1640 /* too many called */
1644 case ENCQUOTEDPRINTABLE:
1645 EM_DEBUG_LOG("ENCQUOTEDPRINTABLE");
1646 content = rfc822_qprint((unsigned char *)enc_buf, (unsigned long)enc_len, (unsigned long *)dec_len);
1650 EM_DEBUG_LOG("ENCBASE64");
1651 content = rfc822_base64((unsigned char *)enc_buf, (unsigned long)enc_len, (unsigned long *)dec_len);
1663 if (enc_len < *dec_len) {
1664 EM_DEBUG_EXCEPTION("Decoded length is too big to store it");
1667 memcpy(enc_buf, content, *dec_len);
1668 enc_buf[*dec_len] = '\0';
1669 EM_SAFE_FREE(content);
1671 EM_DEBUG_FUNC_END();
1675 /* 1. if boundary is NULL, contnent has not multipart */
1676 /* 2. if boundary isn't NULL, content is from current line to the next found boundary */
1677 /* if next found boundary is the other part boundary ("--boundary"), return and set end_of_parsing to 1 */
1678 /* if next found boundary is the multipart ending boundary ("--boundary--"), return and set end_of_parsing to 0 */
1679 /* mode - SAVE_TYPE_SIZE : no saving (only hold content size */
1680 /* SAVE_TYPE_BUFFER : content is saved to buffer (holder is buffer */
1681 /* SAVE_TYPE_FILE : content is saved to temporary file (holder is file name */
1682 int emcore_mime_get_content_data(void *stream, int is_file, int is_text, char *boundary_str, char *content_encoding, int *end_of_parsing, int mode, char **holder, int *size, void *callback, int *err_code)
1684 EM_DEBUG_FUNC_BEGIN("stream[%p], is_file[%d], boundary_str[%s], content_encoding[%s], end_of_parsing[%p], mode[%d], holder[%p], size[%p], callback[%p], err_code[%p]", stream, is_file, boundary_str, content_encoding, end_of_parsing, mode, holder, size, callback, err_code);
1686 int encoding = ENC7BIT;
1687 int error = EMAIL_ERROR_NONE, ret = false;
1691 if ((mode == SAVE_TYPE_FILE || mode == SAVE_TYPE_BUFFER) && !holder)
1700 EM_DEBUG_LOG("get content");
1702 if (content_encoding) {
1703 switch (content_encoding[0]) {
1705 encoding = ENCQUOTEDPRINTABLE;
1706 break; /* qutoed-printabl */
1708 if (content_encoding[1] == 'A') {
1709 encoding = ENCBASE64;
1712 if (content_encoding[1] == 'I') {
1713 encoding = ENCBINARY;
1725 encoding = ENCOTHER;
1730 /* saving type is file */
1731 if (mode == SAVE_TYPE_FILE) {
1732 *holder = emcore_mime_get_save_file_name(&error);
1734 EM_DEBUG_LOG("holder[%s]", *holder);
1736 fd = open(*holder, O_WRONLY|O_CREAT, 0644);
1738 EM_DEBUG_EXCEPTION("holder open failed : holder is a filename that will be saved.");
1744 EM_DEBUG_LOG("from file");
1745 error = emcore_decode_body_text_from_file((FILE *)stream, boundary_str, encoding, mode, is_text, fd, holder, end_of_parsing, size);
1746 if (error != EMAIL_ERROR_NONE) {
1747 if (error != EMAIL_ERROR_NO_MORE_DATA) {
1748 EM_DEBUG_EXCEPTION("emcore_decode_body_text_from_file failed : [%d]", error);
1753 EM_DEBUG_LOG("from sock");
1754 error = emcore_decode_body_text_from_sock(stream, boundary_str, encoding, mode, is_text, fd, holder, end_of_parsing, &sz);
1755 if (error != EMAIL_ERROR_NONE) {
1756 EM_DEBUG_EXCEPTION("emcore_decode_body_text_from_sock failed : [%d]", error);
1763 if (err_code != NULL)
1766 if(fd>0) close(fd); /*prevent 32736*/
1773 EM_DEBUG_FUNC_END("ret [%d], sz [%d]", ret, sz);
1777 int emcore_mime_skip_content_data(void *stream,
1780 int *end_of_parsing,
1785 EM_DEBUG_FUNC_BEGIN("stream[%p], is_file[%d], boundary_str[%s], end_of_parsing[%p], size[%p], callback[%p], err_code[%p]", stream, is_file, boundary_str, end_of_parsing, size, callback, err_code);
1787 char buf[MIME_LINE_LEN] = {0x00}, boundary[BOUNDARY_LEN], boundary_end[BOUNDARY_LEN];
1793 EM_DEBUG_LOG(">>> skip content <<<<<<<<<<<<<");
1795 if (!boundary_str) { /* if no boundary, this content is from current line to end of all multipart */
1798 if (!emcore_check_thread_status()) {
1799 if (err_code != NULL)
1800 *err_code = EMAIL_ERROR_CANCELLED;
1803 if ((is_file == 0 && !emcore_mime_get_line_from_sock(stream, buf, MIME_LINE_LEN, err_code)) ||
1804 (is_file == 1 && !emcore_get_line_from_file(stream, buf, MIME_LINE_LEN, err_code))) {
1805 *end_of_parsing = 1;
1810 sz += EM_SAFE_STRLEN(buf);
1813 else { /* if there boundary, this content is from current line to ending boundary */
1814 memset(boundary, 0x00, BOUNDARY_LEN);
1815 memset(boundary_end, 0x00, BOUNDARY_LEN);
1817 SNPRINTF(boundary, BOUNDARY_LEN, "--%s%s", boundary_str, CRLF_STRING);
1818 SNPRINTF(boundary_end, BOUNDARY_LEN, "--%s%s", boundary_str, "--\r\n");
1822 if (!emcore_check_thread_status()) {
1823 if (err_code != NULL)
1824 *err_code = EMAIL_ERROR_CANCELLED;
1827 if ((is_file == 0 && !emcore_mime_get_line_from_sock(stream, buf, MIME_LINE_LEN, err_code)) ||
1828 (is_file == 1 && !emcore_get_line_from_file(stream, buf, MIME_LINE_LEN, err_code))) {
1830 *end_of_parsing = 1;
1836 if (!strcmp(buf, boundary)) { /* the other part started. the parsing of other part will be started */
1837 *end_of_parsing = 0;
1842 else if (!strcmp(buf, boundary_end)) { /* if ending boundary, the parsing of other multipart will be started */
1843 *end_of_parsing = 1;
1849 sz += EM_SAFE_STRLEN(buf);
1855 EM_DEBUG_FUNC_END();
1859 /* get temporary file name */
1860 char *emcore_mime_get_save_file_name(int *err_code)
1862 EM_DEBUG_FUNC_BEGIN();
1866 gettimeofday(&tv, NULL);
1869 memset(tempname, 0x00, sizeof(tempname));
1871 SNPRINTF(tempname, sizeof(tempname), "%s%s%d", MAILTEMP, DIR_SEPERATOR, rand());
1872 EM_DEBUG_FUNC_END();
1873 return EM_SAFE_STRDUP(tempname);
1876 /* get a line from file pointer */
1877 char *emcore_get_line_from_file(void *stream, char *buf, int size, int *err_code)
1879 if (!fgets(buf, size, (FILE *)stream)) {
1880 if (feof((FILE *)stream)) {
1881 *err_code = EMAIL_ERROR_NO_MORE_DATA;
1889 /* get a line from POP3 mail stream */
1890 /* emcore_mail_cmd_read_mail_pop3 must be called before this function */
1891 char *emcore_mime_get_line_from_sock(void *stream, char *buf, int size, int *err_code)
1893 EM_DEBUG_FUNC_BEGIN("stream[%p], buf[%p]", stream, buf);
1894 POP3LOCAL *p_pop3local = NULL;
1896 if (!stream || !buf) {
1897 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
1898 if (err_code != NULL)
1899 *err_code = EMAIL_ERROR_INVALID_PARAM;
1903 memset(buf, 0x00, size);
1905 p_pop3local = (POP3LOCAL *)(((MAILSTREAM *)stream)->local);
1907 EM_DEBUG_EXCEPTION("stream->local[%p]", p_pop3local);
1908 if (err_code != NULL)
1909 *err_code = EMAIL_ERROR_INVALID_PARAM;
1913 if (!pop3_reply((MAILSTREAM *)stream)) { /* if TRUE, check respons */
1914 EM_DEBUG_LOG("p_pop3local->response 1[%s]", p_pop3local->response);
1915 if (p_pop3local->response) {
1916 if (*p_pop3local->response == '.' && EM_SAFE_STRLEN(p_pop3local->response) == 1) {
1917 free(p_pop3local->response);
1918 p_pop3local->response = NULL;
1919 if (err_code != NULL)
1920 *err_code = EMAIL_ERROR_NO_MORE_DATA;
1921 EM_DEBUG_FUNC_END("end of response");
1924 EM_DEBUG_LOG("Not end of response");
1925 strncpy(buf, p_pop3local->response, size-1);
1926 strncat(buf, CRLF_STRING, size-(EM_SAFE_STRLEN(buf) + 1));
1928 free(p_pop3local->response);
1929 p_pop3local->response = NULL;
1935 EM_DEBUG_LOG("p_pop3local->response 2[%s]", p_pop3local->response);
1936 if (p_pop3local->response)
1938 /* if response isn't NULL, check whether this response start with '+' */
1939 /* if the first character is '+', return error because this response is normal data */
1940 strncpy(buf, p_pop3local->response, size-1);
1941 strncat(buf, CRLF_STRING, size-(EM_SAFE_STRLEN(buf)+1));
1942 free(p_pop3local->response); p_pop3local->response = NULL;
1946 EM_DEBUG_EXCEPTION("p_pop3local->response is null. network error... ");
1947 if (err_code != NULL)
1948 *err_code = EMAIL_ERROR_INVALID_RESPONSE;
1949 EM_DEBUG_FUNC_END();
1955 int received_percentage, last_notified_percentage;
1956 _pop3_received_body_size += EM_SAFE_STRLEN(buf);
1958 last_notified_percentage = (double)_pop3_last_notified_body_size / (double)_pop3_total_body_size *100.0;
1959 received_percentage = (double)_pop3_received_body_size / (double)_pop3_total_body_size *100.0;
1961 EM_DEBUG_LOG("_pop3_received_body_size = %d, _pop3_total_body_size = %d", _pop3_received_body_size, _pop3_total_body_size);
1962 EM_DEBUG_LOG("received_percentage = %d, last_notified_percentage = %d", received_percentage, last_notified_percentage);
1964 if (received_percentage > last_notified_percentage + 5) {
1965 if (!emcore_notify_network_event(NOTI_DOWNLOAD_BODY_START, _pop3_receiving_mail_id, "dummy-file", _pop3_total_body_size, _pop3_received_body_size))
1966 EM_DEBUG_EXCEPTION(" emcore_notify_network_event [NOTI_DOWNLOAD_BODY_START] Failed >>>> ");
1968 EM_DEBUG_LOG("NOTI_DOWNLOAD_BODY_START notified (%d / %d)", _pop3_received_body_size, _pop3_total_body_size);
1969 _pop3_last_notified_body_size = _pop3_received_body_size;
1972 EM_DEBUG_FUNC_END();
1976 void emcore_mime_free_param(struct _parameter *param)
1978 struct _parameter *t, *p = param;
1979 EM_DEBUG_FUNC_BEGIN();
1982 EM_SAFE_FREE(p->name);
1983 EM_SAFE_FREE(p->value);
1987 EM_DEBUG_FUNC_END();
1990 void emcore_mime_free_part_header(struct _m_part_header *header)
1992 EM_DEBUG_FUNC_BEGIN();
1993 if (!header) return ;
1994 EM_SAFE_FREE(header->type);
1995 if (header->parameter) emcore_mime_free_param(header->parameter);
1996 EM_SAFE_FREE(header->subtype);
1997 EM_SAFE_FREE(header->encoding);
1998 EM_SAFE_FREE(header->desc);
1999 EM_SAFE_FREE(header->disp_type);
2000 if (header->disp_parameter) emcore_mime_free_param(header->disp_parameter);
2001 free(header); header = NULL;
2002 EM_DEBUG_FUNC_END();
2005 void emcore_mime_free_message_header(struct _m_mesg_header *header)
2007 EM_DEBUG_FUNC_BEGIN();
2008 if (!header) return ;
2009 EM_SAFE_FREE(header->version);
2010 if (header->part_header) emcore_mime_free_part_header(header->part_header);
2011 free(header); header = NULL;
2012 EM_DEBUG_FUNC_END();
2015 void emcore_mime_free_rfc822_header(struct _rfc822header *header)
2017 EM_DEBUG_FUNC_BEGIN();
2018 if (!header) return ;
2019 EM_SAFE_FREE(header->return_path);
2020 EM_SAFE_FREE(header->received);
2021 EM_SAFE_FREE(header->reply_to);
2022 EM_SAFE_FREE(header->date);
2023 EM_SAFE_FREE(header->from);
2024 EM_SAFE_FREE(header->subject);
2025 EM_SAFE_FREE(header->sender);
2026 EM_SAFE_FREE(header->to);
2027 EM_SAFE_FREE(header->cc);
2028 EM_SAFE_FREE(header->bcc);
2029 free(header); header = NULL;
2030 EM_DEBUG_FUNC_END();
2033 void emcore_mime_free_part_body(struct _m_body *body)
2035 EM_DEBUG_FUNC_BEGIN();
2037 if (body->part_header) emcore_mime_free_part_header(body->part_header);
2038 EM_SAFE_FREE(body->text);
2039 if (body->nested.body) emcore_mime_free_part_body(body->nested.body);
2040 if (body->nested.next) emcore_mime_free_part(body->nested.next);
2041 free(body); body = NULL;
2042 EM_DEBUG_FUNC_END();
2045 void emcore_mime_free_part(struct _m_part *part)
2047 EM_DEBUG_FUNC_BEGIN();
2049 if (part->body) emcore_mime_free_part_body(part->body);
2050 if (part->next) emcore_mime_free_part(part->next);
2051 free(part);part = NULL;
2052 EM_DEBUG_FUNC_END();
2055 void emcore_mime_free_mime(struct _m_mesg *mmsg)
2057 EM_DEBUG_FUNC_BEGIN();
2060 if (mmsg->header) emcore_mime_free_message_header(mmsg->header);
2061 if (mmsg->rfc822header) emcore_mime_free_rfc822_header(mmsg->rfc822header);
2062 if (mmsg->nested.body) emcore_mime_free_part_body(mmsg->nested.body);
2063 if (mmsg->nested.next) emcore_mime_free_part(mmsg->nested.next);
2064 EM_SAFE_FREE(mmsg->text);
2065 free(mmsg); mmsg = NULL;
2066 EM_DEBUG_FUNC_END();
2069 void emcore_free_content_info(struct _m_content_info *cnt_info)
2071 EM_DEBUG_FUNC_BEGIN();
2072 struct attachment_info *p;
2074 if (!cnt_info) return ;
2075 EM_SAFE_FREE(cnt_info->text.plain);
2076 EM_SAFE_FREE(cnt_info->text.plain_charset);
2077 EM_SAFE_FREE(cnt_info->text.html);
2078 while (cnt_info->file) {
2079 p = cnt_info->file->next;
2080 EM_SAFE_FREE(cnt_info->file->name);
2081 EM_SAFE_FREE(cnt_info->file->save);
2082 EM_SAFE_FREE(cnt_info->file->attachment_mime_type);
2083 EM_SAFE_FREE(cnt_info->file->content_id);
2084 free(cnt_info->file); cnt_info->file = NULL;
2087 free(cnt_info);cnt_info = NULL;
2088 EM_DEBUG_FUNC_END();
2091 void emcore_free_attachment_info(struct attachment_info *attchment)
2093 EM_DEBUG_FUNC_BEGIN();
2094 struct attachment_info *p;
2096 if (!attchment) return;
2099 p = attchment->next;
2100 EM_SAFE_FREE(attchment->name);
2101 EM_SAFE_FREE(attchment->save);
2102 EM_SAFE_FREE(attchment->attachment_mime_type);
2103 EM_SAFE_FREE(attchment->content_id);
2104 EM_SAFE_FREE(attchment);
2108 EM_DEBUG_FUNC_END();
2111 /* get body-part in nested part */
2112 static PARTLIST *emcore_get_allnested_part_full(MAILSTREAM *stream, int msg_uid, BODY *body, struct _m_content_info *cnt_info, int *err_code, PARTLIST *section_list)
2114 EM_DEBUG_FUNC_BEGIN("stream[%p], msg_uid[%d], body[%p], cnt_info[%p], err_code[%p]", stream, msg_uid, body, cnt_info, err_code);
2116 PART *part_child = body->nested.part;
2118 while (part_child) {
2119 section_list = emcore_get_body_full(stream, msg_uid, &part_child->body, cnt_info, err_code, section_list);
2120 part_child = part_child->next;
2123 EM_DEBUG_FUNC_END();
2124 return section_list;
2127 /* get body-part in alternative multiple part */
2128 static PARTLIST *emcore_get_alternative_multi_part_full(MAILSTREAM *stream, int msg_uid, BODY *body, struct _m_content_info *cnt_info, int *err_code, PARTLIST *section_list)
2130 EM_DEBUG_FUNC_BEGIN("stream[%p], msg_uid[%d], body[%p], cnt_info[%p], err_code[%p]", stream, msg_uid, body, cnt_info, err_code);
2132 PART *part_child = body->nested.part;
2134 /* find the best sub part we can show */
2135 while (part_child) {
2136 section_list = emcore_get_body_full(stream, msg_uid, &part_child->body, cnt_info, err_code, section_list);
2137 part_child = part_child->next;
2140 EM_DEBUG_FUNC_END("section_list[%p]", section_list);
2141 return section_list;
2144 /* get body part in signed multiple part */
2145 static PARTLIST *emcore_get_signed_multi_part_full(MAILSTREAM *stream, int msg_uid, BODY *body, struct _m_content_info *cnt_info, int *err_code, PARTLIST *section_list)
2147 EM_DEBUG_FUNC_BEGIN("stream[%p], msg_uid[%d], body[%p], cnt_info[%p], err_code[%p]", stream, msg_uid, body, cnt_info, err_code);
2149 PART *part_child = body->nested.part;
2151 /* find the best sub part we can show */
2152 while (part_child) {
2153 section_list = emcore_get_body_full(stream, msg_uid, &part_child->body, cnt_info, err_code, section_list);
2154 part_child = part_child->next;
2157 EM_DEBUG_FUNC_END();
2158 return section_list;
2161 /* get body part in encrypted multiple part */
2162 static PARTLIST *emcore_get_encrypted_multi_part_full(MAILSTREAM *stream, int msg_uid, BODY *body, struct _m_content_info *cnt_info, int *err_code, PARTLIST *section_list)
2164 EM_DEBUG_FUNC_BEGIN("stream[%p], msg_uid[%d], body[%p], cnt_info[%p], err_code[%p]", stream, msg_uid, body, cnt_info, err_code);
2166 /* "protocol" = "application/pgp-encrypted */
2167 EM_DEBUG_FUNC_END();
2168 return section_list;
2171 /* get body part in multiple part */
2172 static PARTLIST *emcore_get_multi_part_full(MAILSTREAM *stream, int msg_uid, BODY *body, struct _m_content_info *cnt_info, int *err_code, PARTLIST *section_list)
2174 EM_DEBUG_FUNC_BEGIN("stream[%p], msg_uid[%d], body[%p], cnt_info[%p], err_code[%p]", stream, msg_uid, body, cnt_info, err_code);
2176 switch (body->subtype[0]) {
2177 case 'A': /* ALTERNATIV */
2178 return section_list = emcore_get_alternative_multi_part_full(stream, msg_uid, body, cnt_info, err_code, section_list);
2180 case 'S': /* SIGNE */
2181 return section_list = emcore_get_signed_multi_part_full(stream, msg_uid, body, cnt_info, err_code, section_list);
2183 case 'E': /* ENCRYPTE */
2184 return section_list = emcore_get_encrypted_multi_part_full(stream, msg_uid, body, cnt_info, err_code, section_list);
2186 default: /* process all unknown as MIXED (according to the RFC 2047 */
2187 return section_list = emcore_get_allnested_part_full(stream, msg_uid, body, cnt_info, err_code, section_list);
2189 EM_DEBUG_FUNC_END();
2193 PARTLIST* emcore_get_body_full(MAILSTREAM *stream, int msg_uid, BODY *body, struct _m_content_info *cnt_info, int *err_code, PARTLIST *section_list)
2195 EM_DEBUG_FUNC_BEGIN("stream[%p], msg_uid[%d], body[%p], cnt_info[%p], err_code[%p]", stream, msg_uid, body, cnt_info, err_code);
2196 char content_type_buffer[512] = { 0, };
2198 if (!stream || !body || !cnt_info) {
2199 EM_DEBUG_EXCEPTION("stream[%p], msg_uid[%d], body[%p], cnt_info[%p]", stream, msg_uid, body, cnt_info);
2200 if (err_code != NULL)
2201 *err_code = EMAIL_ERROR_INVALID_PARAM;
2202 EM_DEBUG_FUNC_END();
2206 switch (body->type) {
2208 section_list = emcore_get_multi_part_full(stream, msg_uid, body, cnt_info, err_code, section_list);
2209 EM_DEBUG_FUNC_END("section_list [%p]", section_list);
2210 return section_list;
2216 case TYPEAPPLICATION:
2223 /* Form list of attachment followed by list of inline images */
2224 if (body->id || body->location || body->disposition.type) {
2226 char filename[512] = {0, };
2227 struct attachment_info *ai = NULL;
2228 struct attachment_info *prev_ai = NULL;
2229 struct attachment_info *next_ai = NULL;
2232 if (emcore_get_file_pointer(body, true, filename, cnt_info, (int*)NULL) < 0)
2233 EM_DEBUG_EXCEPTION("emcore_get_file_pointer failed");
2235 /* To form list of attachment info - Attachment list followed by inline attachment list */
2238 ai = cnt_info->file;
2240 EM_DEBUG_LOG("ai - %p", ai);
2243 /* if ((body->id) || (body->location) */
2244 if ((body->id) || (body->location) || ((body->disposition.type != NULL) && ((body->disposition.type[0] == 'i') || (body->disposition.type[0] == 'I')))) {
2245 /* For Inline content append to the end */
2246 for (i = 1; ai; ai = ai->next)
2250 /* For attachment - search till Inline content found and insert before inline */
2251 for (i = 1; ai; ai = ai->next) {
2252 if (ai->type == 1) {
2253 /* Means inline image */
2254 EM_DEBUG_LOG("Found Inline Content ");
2264 ai = em_malloc(sizeof(struct attachment_info));
2266 EM_DEBUG_EXCEPTION("em_malloc failed...");
2268 *err_code = EMAIL_ERROR_OUT_OF_MEMORY;
2271 cnt_info->file = ai;
2273 if ((body->id) || (body->location) || ((body->disposition.type != NULL) && ((body->disposition.type[0] == 'i') || (body->disposition.type[0] == 'I'))))
2274 ai->type = 1; /* inline contents */
2276 ai->type = 2; /* attachment */
2278 ai->name = EM_SAFE_STRDUP(filename);
2279 ai->size = body->size.bytes;
2280 ai->content_id = EM_SAFE_STRDUP(body->id);
2281 if (emcore_get_content_type_from_mail_bodystruct(body, 512, content_type_buffer) == EMAIL_ERROR_NONE)
2282 ai->attachment_mime_type = EM_SAFE_STRDUP(content_type_buffer);
2284 #ifdef __ATTACHMENT_OPTI__
2285 ai->encoding = body->encoding;
2287 ai->section = EM_SAFE_STRDUP(body->sparep);
2289 EM_DEBUG_LOG("Encoding - %d Section No - %s ", ai->encoding, ai->section);
2292 EM_DEBUG_LOG("Type[%d], Name[%s], Path[%s] ", ai->type, ai->name, ai->save);
2293 if (body->type == TYPEAPPLICATION) {
2294 if (!strcasecmp(body->subtype, MIME_SUBTYPE_DRM_OBJECT))
2295 ai->drm = EMAIL_ATTACHMENT_DRM_OBJECT;
2296 else if (!strcasecmp(body->subtype, MIME_SUBTYPE_DRM_RIGHTS))
2297 ai->drm = EMAIL_ATTACHMENT_DRM_RIGHTS;
2298 else if (!strcasecmp(body->subtype, MIME_SUBTYPE_DRM_DCF))
2299 ai->drm = EMAIL_ATTACHMENT_DRM_DCF;
2300 else if (!strcasecmp(body->subtype, "pkcs7-mime"))
2301 cnt_info->grab_type = cnt_info->grab_type | GRAB_TYPE_ATTACHMENT;
2304 if (ai->type != 1 && next_ai != NULL) {
2305 /* Means next_ai points to the inline attachment info structure */
2306 if (prev_ai == NULL) {
2307 /* First node is inline attachment */
2309 cnt_info->file = ai;
2320 /* if (cnt_info->grab_type == GRAB_TYPE_ATTACHMENT */
2321 if (cnt_info->grab_type & GRAB_TYPE_ATTACHMENT) {
2322 if (((body->disposition.type != NULL) && ((body->disposition.type[0] == 'a') || (body->disposition.type[0] == 'A'))) && (cnt_info->file != NULL)) {
2323 PARAMETER *param = NULL;
2326 param = body->parameter;
2329 if (!strcasecmp(param->attribute, "NAME")) {
2330 fn = EM_SAFE_STRDUP(param->value);
2333 if (!strcasecmp(param->attribute, "FILENAME")) {
2334 fn = EM_SAFE_STRDUP(param->value);
2337 param = param->next;
2339 if ((fn != NULL)&& (!strcmp(fn, cnt_info->file->name)) && (body->size.bytes == cnt_info->file->size)) /* checks to zero in on particular attachmen */ {
2340 section_list = emcore_add_node(section_list, body);
2341 if (section_list == NULL) {
2342 EM_DEBUG_EXCEPTION("adding node to section list failed");
2344 *err_code = EMAIL_ERROR_OUT_OF_MEMORY;
2350 EM_DEBUG_FUNC_END("section_list [%p]", section_list);
2351 return section_list; /* single attachment download, so if a match found break the recursion */
2358 /* get a section list which has only plain, html and inline */
2359 if (!((body->disposition.type != NULL) && ((body->disposition.type[0] == 'a') || (body->disposition.type[0] == 'A'))))/* if the body not an attachmen */ {
2360 section_list = emcore_add_node(section_list, body);
2361 if (section_list == NULL) {
2362 EM_DEBUG_EXCEPTION("adding node to section list failed");
2364 *err_code = EMAIL_ERROR_OUT_OF_MEMORY;
2376 if(section_list == NULL && err_code != NULL) {
2377 *err_code = EMAIL_ERROR_ON_PARSING;
2380 EM_DEBUG_FUNC_END("section_list [%p]", section_list);
2381 return section_list;
2384 INTERNAL_FUNC int emcore_get_body_part_list_full(MAILSTREAM *stream, int msg_uid, int account_id, int mail_id, BODY *body, struct _m_content_info *cnt_info, int *err_code, PARTLIST *section_list, int event_handle)
2386 EM_DEBUG_FUNC_BEGIN("stream[%p], msg_uid[%d], body[%p], cnt_info[%p], err_code[%p]", stream, msg_uid, body, cnt_info, err_code);
2388 if (!stream || !body || !cnt_info) {
2389 EM_DEBUG_EXCEPTION("stream[%p], msg_uid[%d], body[%p], cnt_info[%p]", stream, msg_uid, body, cnt_info);
2391 if (err_code != NULL)
2392 *err_code = EMAIL_ERROR_INVALID_PARAM;
2395 section_list = emcore_get_body_full(stream, msg_uid, body, cnt_info, err_code, section_list);
2397 if (section_list == NULL) {
2398 /* assumed at least one body part exist */
2400 EM_DEBUG_EXCEPTION("emcore_get_body_full failed [%d]", *err_code);
2402 EM_DEBUG_EXCEPTION("emcore_get_body_full failed");
2406 if (emcore_get_body_part_imap_full(stream, msg_uid, account_id, mail_id, section_list, cnt_info, err_code, event_handle) < 0) {
2407 EM_DEBUG_EXCEPTION("emcore_get_body_part_imap_full failed");
2408 emcore_free_section_list(section_list);
2411 emcore_free_section_list(section_list);
2415 static int emcore_write_response_into_file(char *filename, char *write_mode, char *encoded, int encoding_type, char *subtype, int account_id, int mail_id, int *err)
2417 EM_DEBUG_FUNC_BEGIN();
2418 int temp_decoded_len = 0;
2419 int inline_support = 0;
2421 int error = EMAIL_ERROR_NONE;
2422 int not_found = true;
2423 int encoded_len = 0;
2424 int written_bytes = 0;
2425 unsigned long decoded_len = 0;
2426 char *decoded = NULL;
2427 char *decoded_temp = NULL;
2428 char save_file_name[MAX_PATH+1] = {0, };
2429 char html_cid_path[MAX_PATH+1] = {0, };
2431 PARAMETER *param = NULL;
2432 PARAMETER *param1 = NULL;
2435 if (!encoded || !filename || !write_mode) {
2436 EM_DEBUG_EXCEPTION("Invalid Param ");
2437 if( err ) *err = EMAIL_ERROR_INVALID_PARAM; /* prevent 28347 */
2442 EM_DEBUG_LOG("Encoded buffer length [%d]", EM_SAFE_STRLEN(encoded));
2443 encoded_len = EM_SAFE_STRLEN(encoded);
2445 EM_DEBUG_LOG("encoding_type [%d]", encoding_type);
2446 switch (encoding_type) {
2447 case ENCQUOTEDPRINTABLE: {
2448 unsigned char *orignal = (unsigned char *)g_strdup_printf("%s\r\n", encoded);
2449 decoded = (char *)rfc822_qprint(orignal, encoded_len + 2, &decoded_len);
2455 decoded = (char *)rfc822_base64((unsigned char *)encoded, encoded_len, &decoded_len);
2459 unsigned char *orignal = (unsigned char *)g_strdup_printf("%s\r\n", encoded);
2460 memcpy(decoded = malloc(encoded_len + 3), orignal, encoded_len + 3);
2461 decoded_len = encoded_len + 2;
2467 if (decoded != NULL) {
2468 EM_DEBUG_LOG("Decoded Length [%d] " , decoded_len);
2469 EM_DEBUG_LOG("filename [%s] " , filename);
2471 if (!(fp = fopen(filename, write_mode))) {
2472 EM_DEBUG_EXCEPTION("fopen failed - %s", filename);
2473 error = EMAIL_ERROR_SYSTEM_FAILURE;
2474 EM_SAFE_FREE(decoded);
2478 if (subtype && subtype[0] == 'H') {
2479 char body_inline_id[512] = {0};
2481 while (strstr(decoded, "cid:")) {
2482 EM_DEBUG_LOG("Found cid:");
2484 if (g_inline_count) {
2485 BODY *body_inline = NULL;
2486 int inline_count = 0;
2487 char *decoded_content_id = NULL;
2488 while (inline_count < g_inline_count && g_inline_list[inline_count]) {
2489 EM_DEBUG_LOG("inline_count [%d], g_inline_count [%d]", inline_count, g_inline_count);
2490 body_inline = g_inline_list[inline_count];
2491 param = body_inline->disposition.parameter;
2492 param1 = body_inline->parameter;
2494 memset(body_inline_id, 0x00, 512);
2496 if (body_inline->id && EM_SAFE_STRLEN(body_inline->id) > 0) { /*prevent 27454*/
2497 EM_DEBUG_LOG("body_inline->id - %s", body_inline->id);
2498 EM_DEBUG_LOG("param - %p param1 - %p", param, param1);
2499 decoded_content_id = strstr(decoded, "cid:");
2501 if (body_inline->id[0] == '<')
2502 memcpy(body_inline_id, body_inline->id + 1, EM_SAFE_STRLEN(body_inline->id) - 2);
2504 memcpy(body_inline_id, body_inline->id , EM_SAFE_STRLEN(body_inline->id));
2506 EM_DEBUG_LOG("Inline body_inline_id [%s] ", body_inline_id);
2508 if ((param || param1) && 0 == strncmp(body_inline_id , decoded_content_id + strlen("cid:"), EM_SAFE_STRLEN(body_inline_id))) {
2509 EM_DEBUG_LOG(" Inline CID Found ");
2511 memset(save_file_name, 0x00, MAX_PATH);
2512 memset(html_cid_path, 0x00, MAX_PATH);
2514 /* Finding 'filename' attribute from content inf */
2515 emcore_get_file_pointer(body_inline, true, save_file_name, NULL, &error);
2517 if (EM_SAFE_STRLEN(save_file_name) > 0) {
2518 /* Content ID will be replaced with its file name in html */
2519 memcpy(html_cid_path, decoded_content_id , strlen("cid:") + EM_SAFE_STRLEN(body_inline_id));
2521 EM_DEBUG_LOG("Replacing %s with %s ", html_cid_path, save_file_name);
2522 if ((decoded_temp = em_replace_string(decoded, html_cid_path, save_file_name))) {
2523 EM_SAFE_FREE(decoded);
2524 decoded = decoded_temp;
2525 decoded_len = EM_SAFE_STRLEN(decoded);
2526 EM_DEBUG_LOG("Decoded Length [%d] ", decoded_len);
2529 /* only_body_download = false */
2542 EM_DEBUG_LOG("not_found is true");
2543 memset(body_inline_id, 0x00, sizeof(body_inline_id));
2544 decoded_temp = em_replace_string_with_split_file_path(decoded, "cid:", body_inline_id);
2546 /* only_body_download = false */
2547 /* EM_DEBUG_LOG(">>>> decoded_temp 2 [ %s ] ", decoded_temp) */
2548 EM_SAFE_FREE(decoded);
2549 decoded = decoded_temp;
2550 temp_decoded_len = EM_SAFE_STRLEN(body_inline_id);
2551 decoded_len = EM_SAFE_STRLEN(decoded);
2552 EM_DEBUG_LOG("Decoded Length [%d] ", decoded_len);
2559 EM_DEBUG_LOG("Trying to fwrite. decoded_len [%d]", decoded_len);
2561 if (decoded_len > 0 && fwrite(decoded, decoded_len, 1, fp) == 0) {
2562 EM_DEBUG_EXCEPTION("Error Occured while writing. fwrite(\"%s\") failed. decoded_len [%d], written_bytes [%d] ", decoded, decoded_len, written_bytes);
2563 error = EMAIL_ERROR_SYSTEM_FAILURE;
2567 EM_DEBUG_LOG("fwrite succeed");
2570 EM_DEBUG_EXCEPTION("Error Occured while decoding ");
2580 EM_SAFE_FREE(decoded);
2585 EM_DEBUG_FUNC_END();
2591 static BODY *emcore_select_body_structure_from_section_list(PARTLIST *section_list, char *section)
2593 PARTLIST *temp = section_list;
2596 while (temp != NULL) {
2598 if (!strcmp(section, body->sparep))
2600 temp = (PARTLIST *)temp->next;
2606 #define MAX_WRITE_BUFFER_SIZE 0 /* should be tuned */
2608 static int imap_mail_write_body_to_file(MAILSTREAM *stream, int account_id, int mail_id, int is_attachment, char *filepath, int uid, char *section, int encoding, int *decoded_total, char *section_subtype, int *err_code)
2610 EM_PROFILE_BEGIN(imapMailWriteBodyToFile);
2611 EM_DEBUG_FUNC_BEGIN("stream[%p], filepath[%s], uid[%d], section[%s], encoding[%d], decoded_total[%p], err_code[%p]", stream, filepath, uid, section, encoding, decoded_total, err_code);
2614 int err = EMAIL_ERROR_NONE;
2616 IMAPLOCAL *imaplocal = NULL;
2617 char tag[16], command[64];
2618 char *response = NULL;
2619 char *decoded = NULL;
2620 int body_size = 0, total = 0;
2621 char *file_id = NULL;
2622 char server_uid[129] = { 0, };
2623 char *filename = NULL;
2624 int server_response_yn = 0;
2625 int write_flag = false;
2626 char *write_buffer = NULL;
2627 unsigned char encoded[DOWNLOAD_MAX_BUFFER_SIZE] = {0, };
2628 unsigned char test_buffer[LOCAL_MAX_BUFFER_SIZE] = {0, };
2629 int flag_first_write = true;
2630 int max_write_buffer_size = MAX_WRITE_BUFFER_SIZE;
2632 if (!stream || !filepath || !section) {
2633 EM_DEBUG_EXCEPTION("stream[%p], filepath[%s], uid[%d], section[%s], encoding[%d], decoded_total[%p]", stream, filepath, uid, section, encoding, decoded_total);
2634 err = EMAIL_ERROR_INVALID_PARAM;
2638 EM_DEBUG_LOG(">>> WRITE BUFFER SIZE : %d KB", max_write_buffer_size);
2640 if (max_write_buffer_size > 0) {
2641 max_write_buffer_size *= 1024; /* KB -> byte */
2642 if (!(write_buffer = em_malloc(sizeof(char) *max_write_buffer_size))) {
2643 EM_DEBUG_EXCEPTION("em_malloc failed...");
2644 err = EMAIL_ERROR_OUT_OF_MEMORY;
2649 FINISH_OFF_IF_CANCELED;
2651 if (!(fp = fopen(filepath, "wb+"))) {
2652 EM_DEBUG_EXCEPTION("fopen failed - %s", filepath);
2653 err = EMAIL_ERROR_SYSTEM_FAILURE; /* EMAIL_ERROR_UNKNOWN */
2657 imaplocal = stream->local;
2659 if (!imaplocal->netstream) {
2660 EM_DEBUG_EXCEPTION("invalid IMAP4 stream detected... %p", imaplocal->netstream);
2661 err = EMAIL_ERROR_INVALID_STREAM;
2665 EM_DEBUG_LOG(" next_decode_string = false ");
2666 next_decode_string = false;
2668 memset(tag, 0x00, sizeof(tag));
2669 memset(command, 0x00, sizeof(command));
2671 SNPRINTF(tag, sizeof(tag), "%08lx", 0xffffffff & (stream->gensym++));
2672 SNPRINTF(command, sizeof(command), "%s UID FETCH %d BODY.PEEK[%s]\015\012", tag, uid, section);
2674 EM_DEBUG_LOG("[IMAP4] >>> [%s]", command);
2676 /* send command : get msgno/uid for all messag */
2677 if (!net_sout(imaplocal->netstream, command, (int)EM_SAFE_STRLEN(command))) {
2678 EM_DEBUG_EXCEPTION("net_sout failed...");
2679 err = EMAIL_ERROR_CONNECTION_BROKEN;
2683 while (imaplocal->netstream) {
2687 if (!emcore_check_thread_status()) {
2688 EM_DEBUG_LOG("Canceled...");
2689 /* Is it realy required ? It might cause crashes.
2690 if (imaplocal->netstream)
2691 net_close (imaplocal->netstream);
2693 imaplocal->netstream = NULL;
2694 err = EMAIL_ERROR_CANCELLED;
2698 /* receive respons */
2699 if (!(response = net_getline(imaplocal->netstream))) {
2700 EM_DEBUG_EXCEPTION("net_getline failed...");
2701 err = EMAIL_ERROR_INVALID_RESPONSE;
2704 #ifdef FEATURE_CORE_DEBUG
2705 EM_DEBUG_LOG("recv[%s]", response);
2709 if (response[0] == '*' && !server_response_yn) { /* start of respons */
2711 if ((p = strstr(response, "BODY[")) /* || (p = strstr(s + 1, "BODY["))*/) {
2712 server_response_yn = 1;
2713 p += strlen("BODY[");
2721 if (strcmp(section, p)) {
2722 err = EMAIL_ERROR_INVALID_RESPONSE;
2726 if ((p = strstr(s+1, " {"))) {
2735 body_size = atoi(p);
2737 else { /* no body length is replied */
2738 if ((p = strstr(s+1, " \""))) { /* seek the termination of double quot */
2741 if ((t = strstr(p, "\""))) {
2744 EM_DEBUG_LOG("Body : start[%p] end[%p] : body[%s]", p, t, p);
2746 EM_SAFE_FREE(response);
2747 response = EM_SAFE_STRDUP(p);
2751 err = EMAIL_ERROR_INVALID_RESPONSE;
2756 err = EMAIL_ERROR_INVALID_RESPONSE;
2761 /* sending progress noti to application.
2766 parse_file_path_to_filename(filepath, &file_id);
2769 sprintf(server_uid, "%d", uid);
2771 EM_DEBUG_LOG("file_id [%s]", file_id);
2772 EM_DEBUG_LOG("filename [%p]-[%s]", filename, filename);
2773 EM_DEBUG_LOG("body_size [%d]", body_size);
2774 EM_DEBUG_LOG("server_uid [%s]", server_uid);
2775 EM_DEBUG_LOG("mail_id [%d]", mail_id);
2777 if (is_attachment) {
2778 EM_DEBUG_LOG("Attachment number [%d]", is_attachment);
2779 if (!emcore_notify_network_event(NOTI_DOWNLOAD_ATTACH_START, mail_id, filename, is_attachment, 0))
2780 EM_DEBUG_EXCEPTION(" emcore_notify_network_event [ NOTI_DOWNLOAD_ATTACH_START] Failed >>>> ");
2781 _imap4_download_noti_interval_value = body_size *DOWNLOAD_NOTI_INTERVAL_PERCENT / 100;
2782 _imap4_total_body_size = body_size;
2785 if (multi_part_body_size) {
2786 EM_DEBUG_LOG("Multipart body size is [%d]", multi_part_body_size);
2787 if (!emcore_notify_network_event(NOTI_DOWNLOAD_MULTIPART_BODY, mail_id, filename, multi_part_body_size, 0))
2788 EM_DEBUG_EXCEPTION(" emcore_notify_network_event [ NOTI_DOWNLOAD_BODY_START] Failed >>>> ");
2789 _imap4_download_noti_interval_value = multi_part_body_size *DOWNLOAD_NOTI_INTERVAL_PERCENT / 100;
2790 /* _imap4_total_body_size should be set before calling this functio */
2791 /* _imap4_total_body_size */
2794 if (!emcore_notify_network_event(NOTI_DOWNLOAD_BODY_START, mail_id, filename, body_size, 0))
2795 EM_DEBUG_EXCEPTION(" emcore_notify_network_event [ NOTI_DOWNLOAD_BODY_START] Failed >>>>");
2796 _imap4_download_noti_interval_value = body_size *DOWNLOAD_NOTI_INTERVAL_PERCENT / 100;
2797 _imap4_total_body_size = body_size;
2800 if (_imap4_download_noti_interval_value > DOWNLOAD_NOTI_INTERVAL_SIZE) {
2801 _imap4_download_noti_interval_value = DOWNLOAD_NOTI_INTERVAL_SIZE;
2803 if (body_size < DOWNLOAD_MAX_BUFFER_SIZE) {
2804 if (net_getbuffer (imaplocal->netstream, (long)body_size, (char *)encoded) <= 0) {
2805 EM_DEBUG_EXCEPTION("net_getbuffer failed...");
2806 err = EMAIL_ERROR_NO_RESPONSE;
2810 if (!emcore_write_response_into_file(filepath, "wb+", (char *)encoded, encoding, section_subtype, account_id, mail_id, &err)) {
2811 EM_DEBUG_EXCEPTION("write_response_into_file failed [%d]", err);
2815 total = EM_SAFE_STRLEN((char *)encoded);
2816 EM_DEBUG_LOG("total = %d", total);
2817 EM_DEBUG_LOG("write_response_into_file successful %s.....", filename);
2819 if (((_imap4_last_notified_body_size + _imap4_download_noti_interval_value) <= _imap4_received_body_size)
2820 || (_imap4_received_body_size >= _imap4_total_body_size)) /* 100 */ {
2821 /* In some situation, total_encoded_len includes the length of dummy bytes. So it might be greater than body_size */
2823 if (total > body_size)
2824 gap = total - body_size;
2825 _imap4_received_body_size -= gap;
2826 _imap4_last_notified_body_size = _imap4_received_body_size;
2829 EM_DEBUG_LOG("DOWNLOADING STATUS NOTIFY : Encoded[%d] / [%d] = %d %% Completed. -- Total Decoded[%d]", total, body_size, 100*total/body_size, total);
2831 if(_imap4_total_body_size > 0)
2832 EM_DEBUG_LOG("DOWNLOADING STATUS NOTIFY : Total[%d] / [%d] = %d %% Completed.", _imap4_received_body_size, _imap4_total_body_size, 100*_imap4_received_body_size/_imap4_total_body_size);
2834 if (is_attachment) {
2835 if (_imap4_total_body_size && !emcore_notify_network_event(NOTI_DOWNLOAD_ATTACH_START, mail_id, filename, is_attachment, 100 *_imap4_received_body_size / _imap4_total_body_size))
2836 EM_DEBUG_EXCEPTION(" emcore_notify_network_event [ NOTI_DOWNLOAD_ATTACH_START] Failed >>>> ");
2839 if (multi_part_body_size) {
2840 if (!emcore_notify_network_event(NOTI_DOWNLOAD_MULTIPART_BODY, mail_id, filename, _imap4_total_body_size, _imap4_received_body_size))
2841 EM_DEBUG_EXCEPTION(" emcore_notify_network_event [ NOTI_DOWNLOAD_BODY_START] Failed >>>> ");
2844 if (!emcore_notify_network_event(NOTI_DOWNLOAD_BODY_START, mail_id, filename, _imap4_total_body_size, _imap4_received_body_size))
2845 EM_DEBUG_EXCEPTION(" emcore_notify_network_event [ NOTI_DOWNLOAD_BODY_START] Failed >>>>");
2847 } /* if (is_attachment) .. else .. */
2851 int temp_body_size = body_size;
2854 if (encoding == ENCBASE64)
2855 x = (sizeof(encoded)/78) *78; /* to solve base64 decoding pro */
2857 x = sizeof(encoded)-1;
2859 memset(test_buffer, 0x00, sizeof(test_buffer));
2860 while (temp_body_size && (total <body_size)) {
2862 memset(test_buffer, 0x00, sizeof(test_buffer));
2863 while ((total != body_size) && temp_body_size && ((EM_SAFE_STRLEN((char *)test_buffer) + x) < sizeof(test_buffer))) {
2864 memset(encoded, 0x00, sizeof(encoded));
2866 if (net_getbuffer (imaplocal->netstream, (long)x, (char *)encoded) <= 0) {
2867 EM_DEBUG_EXCEPTION("net_getbuffer failed...");
2868 err = EMAIL_ERROR_NO_RESPONSE;
2872 temp_body_size = temp_body_size - x;
2873 strncat((char *)test_buffer, (char *)encoded, EM_SAFE_STRLEN((char *)encoded));
2875 _imap4_received_body_size += EM_SAFE_STRLEN((char *)encoded);
2877 if ( !(temp_body_size/x) && temp_body_size%x)
2878 x = temp_body_size%x;
2880 if (((_imap4_last_notified_body_size + _imap4_download_noti_interval_value) <= _imap4_received_body_size)
2881 || (_imap4_received_body_size >= _imap4_total_body_size)) /* 100 */ {
2882 /* In some situation, total_encoded_len includes the length of dummy bytes. So it might be greater than body_size */
2884 if (total > body_size)
2885 gap = total - body_size;
2886 _imap4_received_body_size -= gap;
2887 _imap4_last_notified_body_size = _imap4_received_body_size;
2889 /* EM_DEBUG_LOG("DOWNLOADING STATUS NOTIFY : Encoded[%d] / [%d] = %d %% Completed. -- Total Decoded[%d]", total, body_size, 100*total/body_size, total) */
2890 EM_DEBUG_LOG("DOWNLOADING STATUS NOTIFY : Total[%d] / [%d] = %d %% Completed.", _imap4_received_body_size, _imap4_total_body_size, 100*_imap4_received_body_size/_imap4_total_body_size);
2892 if (is_attachment) {
2893 if (!emcore_notify_network_event(NOTI_DOWNLOAD_ATTACH_START, mail_id, filename, is_attachment, 100 *_imap4_received_body_size / _imap4_total_body_size))
2894 EM_DEBUG_EXCEPTION(" emcore_notify_network_event [ NOTI_DOWNLOAD_ATTACH_START] Failed >>>> ");
2897 if (multi_part_body_size) {
2898 /* EM_DEBUG_LOG("DOWNLOADING.......... : Multipart body size is [%d]", multi_part_body_size) */
2899 if (!emcore_notify_network_event(NOTI_DOWNLOAD_MULTIPART_BODY, mail_id, filename, _imap4_total_body_size, _imap4_received_body_size))
2900 EM_DEBUG_EXCEPTION(" emcore_notify_network_event [ NOTI_DOWNLOAD_BODY_START] Failed >>>> ");
2903 if (!emcore_notify_network_event(NOTI_DOWNLOAD_BODY_START, mail_id, filename, _imap4_total_body_size, _imap4_received_body_size))
2904 EM_DEBUG_EXCEPTION(" emcore_notify_network_event [ NOTI_DOWNLOAD_BODY_START] Failed >>>>");
2906 } /* if (is_attachment) .. else .. */
2912 if (flag_first_write == true) {
2913 if (!emcore_write_response_into_file(filepath, "wb+", (char *)test_buffer, encoding, section_subtype, account_id, mail_id, &err)) {
2914 EM_DEBUG_EXCEPTION("write_response_into_file %s failed [%d]", filepath, err);
2917 flag_first_write = false;
2920 if (!emcore_write_response_into_file(filepath, "ab+", (char *)test_buffer, encoding, section_subtype, account_id, mail_id, &err)) /* append */ {
2921 EM_DEBUG_EXCEPTION("write_response_into_file %s failed [%d]", filepath, err);
2925 EM_DEBUG_LOG("%d has been written", EM_SAFE_STRLEN((char *)test_buffer));
2932 err = EMAIL_ERROR_INVALID_RESPONSE;
2937 else if (!strncmp(response, tag, EM_SAFE_STRLEN(tag))) { /* end of respons */
2938 if (!strncmp(response + EM_SAFE_STRLEN(tag) + 1, "OK", 2)) {
2939 EM_SAFE_FREE(response);
2941 else { /* 'NO' or 'BAD */
2942 err = EMAIL_ERROR_IMAP4_FETCH_UID_FAILURE;
2948 else if (!strcmp(response, ")")) {
2949 /* The end of response which contains body informatio */
2953 } /* while (imaplocal->netstream) */
2955 if (decoded_total != NULL)
2956 *decoded_total = total;
2961 EM_SAFE_FREE(decoded);
2962 EM_SAFE_FREE(response);
2967 EM_SAFE_FREE(write_buffer);
2969 if (ret == false) { /* delete temp fil */
2970 struct stat temp_file_stat;
2971 if (filepath && stat(filepath, &temp_file_stat) == 0)
2975 if (err_code != NULL)
2978 EM_PROFILE_END(imapMailWriteBodyToFile);
2983 static int emcore_get_body_part_imap_full(MAILSTREAM *stream, int msg_uid, int account_id, int mail_id, PARTLIST *section_list, struct _m_content_info *cnt_info, int *err_code, int event_handle)
2985 EM_DEBUG_FUNC_BEGIN("stream[%p], msg_uid[%d], body[%p], cnt_info[%p], err_code[%p]", stream, msg_uid, section_list, cnt_info, err_code);
2987 int err = EMAIL_ERROR_NONE;
2988 char sections[IMAP_MAX_COMMAND_LENGTH] = { 0, };
2989 IMAPLOCAL *imaplocal = NULL;
2990 char tag[16] = { 0, }, command[IMAP_MAX_COMMAND_LENGTH] = { 0, };
2991 char section[16] = {0};
2992 char *response = NULL;
2994 int server_response_yn = 0;
2997 char filename[512] = {0, };
2998 int return_value = 0 ;
3000 unsigned char encoded[DOWNLOAD_MAX_BUFFER_SIZE] = {0};
3001 unsigned char test_buffer[LOCAL_MAX_BUFFER_SIZE] = {0};
3002 struct attachment_info *ai = NULL;
3005 int flag_first_write = 1;
3006 int imap4_total_body_download_progress = 0, progress = 0;
3008 if (!(imaplocal = stream->local) || !imaplocal->netstream || !section_list || !cnt_info) {
3009 EM_DEBUG_EXCEPTION("invalid IMAP4 stream detected...");
3010 err = EMAIL_ERROR_INVALID_PARAM;
3015 if (section_list != NULL) {
3016 PARTLIST *temp = section_list;
3018 if (cnt_info->grab_type == GRAB_TYPE_ATTACHMENT) {
3019 /* to download attachment */
3021 if (body->sparep != NULL) {
3022 snprintf(sections, sizeof(sections), "BODY.PEEK[%s]", (char *)body->sparep);
3025 EM_DEBUG_EXCEPTION("body->sparep can not be null. ");
3032 while (temp != NULL) {
3036 if ((body->type == TYPETEXT) || (body->id != NULL) || ((body->disposition.type != NULL) && ((body->disposition.type[0] == 'i') || (body->disposition.type[0] == 'I')))) {
3037 snprintf(t, sizeof(t), "BODY.PEEK[%s] ", (char *)body->sparep); /* body parts seperated by period */
3038 strcat(sections, t);
3040 temp = (PARTLIST *)temp->next;
3045 if ((EM_SAFE_STRLEN(sections) == (sizeof(sections)-1)) || (EM_SAFE_STRLEN(sections) == 0)) {
3046 EM_DEBUG_EXCEPTION(" Too many body parts or nil. IMAP command may cross 1000bytes.");
3051 if (sections[EM_SAFE_STRLEN(sections)-1] == ' ') {
3052 sections[EM_SAFE_STRLEN(sections)-1] = '\0';
3055 EM_DEBUG_LOG("sections <%s>", sections);
3057 SNPRINTF(tag, sizeof(tag), "%08lx", 0xffffffff & (stream->gensym++));
3058 SNPRINTF(command, sizeof(command), "%s UID FETCH %d (%s)\015\012", tag, msg_uid, sections);
3059 EM_DEBUG_LOG("command %s", command);
3061 if (EM_SAFE_STRLEN(command) == (sizeof(command)-1)) {
3062 EM_DEBUG_EXCEPTION("Too many body parts. IMAP command will fail.");
3067 /* send command : get msgno/uid for all message */
3068 if (!net_sout(imaplocal->netstream, command, (int)EM_SAFE_STRLEN(command))) {
3069 EM_DEBUG_EXCEPTION("net_sout failed...");
3070 err = EMAIL_ERROR_CONNECTION_BROKEN;
3074 while (imaplocal->netstream) {
3076 /* receive respons */
3077 if (!(response = net_getline(imaplocal->netstream))) {
3078 EM_DEBUG_EXCEPTION("net_getline failed...");
3079 err = EMAIL_ERROR_INVALID_RESPONSE;
3084 if (strstr(response, "BODY[")) {
3086 if (!server_response_yn) /* start of response */ {
3087 if (response[0] != '*') {
3088 err = EMAIL_ERROR_INVALID_RESPONSE;
3089 EM_DEBUG_EXCEPTION("Start of response doesn't contain *");
3093 server_response_yn = 1;
3096 flag_first_write = 1;
3098 memset(encoded, 0x00, sizeof(encoded));
3100 if (emcore_get_section_body_size(response, section, &body_size)<0) {
3101 EM_DEBUG_EXCEPTION("emcore_get_section_body_size failed [%d]", err);
3102 err = EMAIL_ERROR_INVALID_RESPONSE;
3106 EM_DEBUG_LOG("body_size-%d", body_size);
3108 /* get body from seciton_list */
3109 if ((body = emcore_select_body_structure_from_section_list(section_list, section)) == NULL) {
3110 EM_DEBUG_EXCEPTION("emcore_select_body_structure_from_section_list failed [%d]", err);
3111 err = EMAIL_ERROR_INVALID_RESPONSE;
3115 encoding = body->encoding;
3117 /* if (emcore_get_file_pointer(account_id, mail_id, body, buf, cnt_info , err)<0) {
3118 EM_DEBUG_EXCEPTION("emcore_get_file_pointer failed [%d]", err);
3122 if (!emcore_get_temp_file_name(&buf, &err)) {
3123 EM_DEBUG_EXCEPTION("emcore_get_temp_file_name failed [%d]", err);
3127 EM_DEBUG_LOG("buf : %s", buf);
3129 /* notifying UI start */
3130 /* parse_file_path_to_filename(buf, &file_id); */
3131 /* EM_DEBUG_LOG(">>>> filename - %p >>>>>>", file_id) */
3133 if (body->type == TYPETEXT && body->subtype && (!body->disposition.type || (body->disposition.type && (body->disposition.type[0] == 'i' || body->disposition.type[0] == 'I')))) {
3134 if (body->subtype[0] == 'H')
3135 cnt_info->text.html = buf;
3137 cnt_info->text.plain = buf;
3139 PARAMETER *param = NULL;
3141 param = body->parameter;
3144 if (!strcasecmp(param->attribute, "CHARSET")) {
3145 cnt_info->text.plain_charset = EM_SAFE_STRDUP(param->value);
3148 param = param->next;
3151 else if (body->id || body->location || body->disposition.type) {
3153 if (emcore_get_file_pointer(body, false, filename, cnt_info , &err)<0) {
3154 EM_DEBUG_EXCEPTION("emcore_get_file_pointer failed [%d]", err);
3158 /* Search info from attachment list followed by inline attachment list */
3160 ai = cnt_info->file;
3161 EM_DEBUG_LOG("ai - %p ", (ai));
3163 /* For Inline content append to the end */
3164 for (i = 1; ai; ai = ai->next, i++) {
3165 if (ai->save == NULL && (ai->content_id != NULL && EM_SAFE_STRCMP(ai->content_id, body->id) == 0)) {
3166 EM_DEBUG_LOG("Found matching details ");
3173 FINISH_OFF_IF_CANCELED;
3175 if (cnt_info->grab_type == GRAB_TYPE_ATTACHMENT) {
3176 if (!emcore_notify_network_event(NOTI_DOWNLOAD_ATTACH_START, mail_id, buf, cnt_info->file_no, 0))
3177 EM_DEBUG_EXCEPTION(" emcore_notify_network_event [ NOTI_DOWNLOAD_ATTACH_START] Failed >>>> ");
3179 _imap4_download_noti_interval_value = body_size *DOWNLOAD_NOTI_INTERVAL_PERCENT / 100;
3180 _imap4_total_body_size = body_size;
3183 if (multi_part_body_size) {
3184 EM_DEBUG_LOG("Multipart body size is [%d]", multi_part_body_size);
3185 if (!emcore_notify_network_event(NOTI_DOWNLOAD_MULTIPART_BODY, mail_id, buf, multi_part_body_size, 0))
3186 EM_DEBUG_EXCEPTION(" emcore_notify_network_event [ NOTI_DOWNLOAD_BODY_START] Failed >>>> ");
3188 _imap4_download_noti_interval_value = multi_part_body_size *DOWNLOAD_NOTI_INTERVAL_PERCENT / 100;
3191 if (!emcore_notify_network_event(NOTI_DOWNLOAD_BODY_START, mail_id, buf, body_size, 0))
3192 EM_DEBUG_EXCEPTION(" emcore_notify_network_event [ NOTI_DOWNLOAD_BODY_START] Failed >>>> ");
3194 _imap4_download_noti_interval_value = body_size *DOWNLOAD_NOTI_INTERVAL_PERCENT / 100;
3195 _imap4_total_body_size = body_size;
3200 if (_imap4_download_noti_interval_value > DOWNLOAD_NOTI_INTERVAL_SIZE) {
3201 _imap4_download_noti_interval_value = DOWNLOAD_NOTI_INTERVAL_SIZE;
3204 /* EM_SAFE_FREE(file_id) */
3205 /* notifying UI end */
3207 if (body_size < DOWNLOAD_MAX_BUFFER_SIZE) {
3208 if (net_getbuffer (imaplocal->netstream, (long)body_size, (char *)encoded) <= 0) {
3209 EM_DEBUG_EXCEPTION("net_getbuffer failed...");
3210 err = EMAIL_ERROR_NO_RESPONSE;
3214 if (!emcore_write_response_into_file(buf, "wb+", (char *)encoded, encoding, body->subtype, account_id, mail_id, &err)) {
3215 EM_DEBUG_EXCEPTION("write_response_into_file failed [%d]", err);
3220 EM_DEBUG_LOG("total = %d", total);
3221 EM_DEBUG_LOG("write_response_into_file successful %s.....", buf);
3223 total = _imap4_received_body_size = EM_SAFE_STRLEN((char *)encoded);
3225 EM_DEBUG_LOG("_imap4_last_notified_body_size [%d]", _imap4_last_notified_body_size);
3226 EM_DEBUG_LOG("_imap4_download_noti_interval_value [%d]", _imap4_download_noti_interval_value);
3227 EM_DEBUG_LOG("_imap4_received_body_size [%d]", _imap4_received_body_size);
3228 EM_DEBUG_LOG("_imap4_total_body_size [%d] ", _imap4_total_body_size);
3230 if (((_imap4_last_notified_body_size + _imap4_download_noti_interval_value) <= _imap4_received_body_size)
3231 || (_imap4_received_body_size >= _imap4_total_body_size)) /* 100 */ {
3232 /* In some situation, total_encoded_len includes the length of dummy bytes. So it might be greater than body_size */
3235 if (total > body_size)
3236 gap = total - body_size;
3237 _imap4_received_body_size -= gap;
3238 _imap4_last_notified_body_size = _imap4_received_body_size;
3239 if (_imap4_total_body_size)
3240 imap4_total_body_download_progress = 100*_imap4_received_body_size/_imap4_total_body_size;
3242 imap4_total_body_download_progress = _imap4_received_body_size;
3244 EM_DEBUG_LOG("3 : body_size %d", body_size);
3247 progress = 100*total/body_size;
3249 progress = body_size;
3251 EM_DEBUG_LOG("DOWNLOADING STATUS NOTIFY : Encoded[%d] / [%d] = %d %% Completed. -- Total Decoded[%d]", total, body_size, progress, total);
3252 EM_DEBUG_LOG("DOWNLOADING STATUS NOTIFY : Total[%d] / [%d] = %d %% Completed.", _imap4_received_body_size, _imap4_total_body_size, imap4_total_body_download_progress);
3254 if (cnt_info->grab_type == GRAB_TYPE_ATTACHMENT) {
3255 if (!emcore_notify_network_event(NOTI_DOWNLOAD_ATTACH_START, mail_id, buf, cnt_info->file_no, imap4_total_body_download_progress))
3256 EM_DEBUG_EXCEPTION(" emcore_notify_network_event [ NOTI_DOWNLOAD_ATTACH_START] Failed >>>> ");
3259 if (multi_part_body_size) {
3260 /* EM_DEBUG_LOG("DOWNLOADING.......... : Multipart body size is [%d]", multi_part_body_size) */
3261 if (!emcore_notify_network_event(NOTI_DOWNLOAD_MULTIPART_BODY, mail_id, buf, _imap4_total_body_size, _imap4_received_body_size))
3262 EM_DEBUG_EXCEPTION(" emcore_notify_network_event [ NOTI_DOWNLOAD_BODY_START] Failed >>>> ");
3265 if (!emcore_notify_network_event(NOTI_DOWNLOAD_BODY_START, mail_id, buf, _imap4_total_body_size, _imap4_received_body_size))
3266 EM_DEBUG_EXCEPTION(" emcore_notify_network_event [ NOTI_DOWNLOAD_BODY_START] Failed >>>>");
3268 } /* if (is_attachment) .. else .. */
3275 int temp_body_size = body_size;
3278 if (encoding == ENCBASE64)
3279 x = (sizeof(encoded)/78) *78; /* to solve base64 decoding pro */
3281 x = sizeof(encoded)-1;
3283 memset(test_buffer, 0x00, sizeof(test_buffer));
3284 while (temp_body_size && (total <body_size)) {
3286 memset(test_buffer, 0x00, sizeof(test_buffer));
3287 while ((total != body_size) && temp_body_size && ((EM_SAFE_STRLEN((char *)test_buffer) + x) < sizeof(test_buffer))) {
3288 memset(encoded, 0x00, sizeof(encoded));
3290 if (net_getbuffer (imaplocal->netstream, (long)x, (char *)encoded) <= 0) {
3291 EM_DEBUG_EXCEPTION("net_getbuffer failed...");
3292 err = EMAIL_ERROR_NO_RESPONSE;
3297 temp_body_size = temp_body_size - x;
3298 strncat((char *)test_buffer, (char *)encoded, EM_SAFE_STRLEN((char *)encoded));
3300 _imap4_received_body_size += EM_SAFE_STRLEN((char *)encoded);
3302 EM_DEBUG_LOG("total = %d", total);
3304 if ( !(temp_body_size/x) && temp_body_size%x)
3305 x = temp_body_size%x;
3307 EM_DEBUG_LOG(" _imap4_last_notified_body_size - %d ", _imap4_last_notified_body_size);
3308 EM_DEBUG_LOG(" _imap4_download_noti_interval_value - %d ", _imap4_download_noti_interval_value);
3309 EM_DEBUG_LOG(" _imap4_received_body_size - %d ", _imap4_received_body_size);
3310 EM_DEBUG_LOG(" _imap4_received_body_size - %d ", _imap4_received_body_size);
3311 EM_DEBUG_LOG(" _imap4_total_body_size - %d ", _imap4_total_body_size);
3313 if (_imap4_total_body_size)
3314 imap4_total_body_download_progress = 100*_imap4_received_body_size/_imap4_total_body_size;
3316 imap4_total_body_download_progress = _imap4_received_body_size;
3318 if (((_imap4_last_notified_body_size + _imap4_download_noti_interval_value) <= _imap4_received_body_size)
3319 || (_imap4_received_body_size >= _imap4_total_body_size)) /* 100 */ {
3320 /* In some situation, total_encoded_len includes the length of dummy bytes. So it might be greater than body_size */
3322 if (total > body_size)
3323 gap = total - body_size;
3324 _imap4_received_body_size -= gap;
3325 _imap4_last_notified_body_size = _imap4_received_body_size;
3328 progress = 100*total/body_size;
3330 progress = body_size;
3332 EM_DEBUG_LOG("DOWNLOADING STATUS NOTIFY : Encoded[%d] / [%d] = %d %% Completed. -- Total Decoded[%d]", total, body_size, progress, total);
3333 EM_DEBUG_LOG("DOWNLOADING STATUS NOTIFY : Total[%d] / [%d] = %d %% Completed.", _imap4_received_body_size, _imap4_total_body_size, imap4_total_body_download_progress);
3335 if (cnt_info->grab_type == GRAB_TYPE_ATTACHMENT) {
3336 if (!emcore_notify_network_event(NOTI_DOWNLOAD_ATTACH_START, mail_id, buf, cnt_info->file_no, imap4_total_body_download_progress))
3337 EM_DEBUG_EXCEPTION(" emcore_notify_network_event [ NOTI_DOWNLOAD_ATTACH_START] Failed >>>> ");
3340 if (multi_part_body_size) {
3341 /* EM_DEBUG_LOG("DOWNLOADING.......... : Multipart body size is [%d]", multi_part_body_size) */
3342 if (!emcore_notify_network_event(NOTI_DOWNLOAD_MULTIPART_BODY, mail_id, buf, _imap4_total_body_size, _imap4_received_body_size))
3343 EM_DEBUG_EXCEPTION(" emcore_notify_network_event [ NOTI_DOWNLOAD_BODY_START] Failed >>>> ");
3346 if (!emcore_notify_network_event(NOTI_DOWNLOAD_BODY_START, mail_id, buf, _imap4_total_body_size, _imap4_received_body_size))
3347 EM_DEBUG_EXCEPTION(" emcore_notify_network_event [ NOTI_DOWNLOAD_BODY_START] Failed >>>>");
3349 } /* if (is_attachment) .. else .. */
3353 if (flag_first_write == 1) {
3354 if (!emcore_write_response_into_file(buf, "wb+", (char *)test_buffer, encoding, body->subtype, account_id, mail_id, &err)) {
3355 EM_DEBUG_EXCEPTION("write_response_into_file %s failed [%d]", buf, err);
3359 flag_first_write = 0;
3362 if (!emcore_write_response_into_file(buf, "ab+", (char *)test_buffer, encoding, body->subtype, account_id, mail_id, &err)) /* append */ {
3363 EM_DEBUG_EXCEPTION("write_response_into_file %s failed [%d]", buf, err);
3368 EM_DEBUG_LOG("%d has been written", EM_SAFE_STRLEN((char *)test_buffer));
3372 else if (!strncmp(response, tag, EM_SAFE_STRLEN(tag))) /* end of respons */ {
3373 if (!strncmp(response + EM_SAFE_STRLEN(tag) + 1, "OK", 2))
3374 EM_SAFE_FREE(response);
3375 else /* 'NO' or 'BAD */ {
3376 err = EMAIL_ERROR_IMAP4_FETCH_UID_FAILURE;
3383 else if (!strcmp(response, ")")) {
3398 EM_SAFE_FREE(response);
3400 return return_value;
3403 static int _find_duplicated_inline_content_file(char *input_source_file_name, struct _m_content_info *input_content_info, bool *output_result)
3405 EM_DEBUG_FUNC_BEGIN("input_source_file_name [%p], input_content_info [%p], output_result [%p]", input_source_file_name,input_content_info, output_result);
3406 struct attachment_info *cur_attachment_info = NULL;
3407 int err = EMAIL_ERROR_NONE;
3408 bool result = false;
3410 if(!input_source_file_name || !input_content_info || !output_result) {
3411 EM_DEBUG_EXCEPTION("Invalid parameter");
3412 return EMAIL_ERROR_INVALID_PARAM;
3415 cur_attachment_info = input_content_info->file;
3417 while(cur_attachment_info) {
3418 if(strcmp(input_source_file_name, cur_attachment_info->name) == 0) {
3422 cur_attachment_info = cur_attachment_info->next;
3425 *output_result = result;
3427 EM_DEBUG_FUNC_END("err [%d], result [%d]", err, result);
3431 static int _modify_file_name_string_for_duplicated_inline_content(char *input_source_file_name, struct _m_content_info *input_content_info)
3433 EM_DEBUG_FUNC_BEGIN("input_source_file_name [%p], input_content_info [%p]", input_source_file_name,input_content_info);
3434 int err = EMAIL_ERROR_NONE;
3435 char temp_file_name[MAX_PATH] = { 0, };
3436 char *file_name = NULL;
3437 char *extension = NULL;
3439 if(!input_source_file_name || !input_content_info) {
3440 EM_DEBUG_EXCEPTION("Invalid parameter");
3441 return EMAIL_ERROR_INVALID_PARAM;
3444 if ( (err = em_get_file_name_and_extension_from_file_path(input_source_file_name, &file_name, &extension)) != EMAIL_ERROR_NONE) {
3445 EM_DEBUG_EXCEPTION("em_get_file_name_and_extension_from_file_path failed [%d]", err);
3449 if(file_name && extension)
3450 SNPRINTF(temp_file_name, MAX_PATH, "%s_.%s", file_name, extension);
3452 SNPRINTF(temp_file_name, MAX_PATH, "%s_", file_name);
3454 EM_SAFE_STRCPY(input_source_file_name, temp_file_name);
3458 EM_SAFE_FREE(file_name);
3459 EM_SAFE_FREE(extension);
3461 EM_DEBUG_FUNC_END("err [%d], temp_file_name [%s]", err, temp_file_name);
3465 static int emcore_get_file_pointer(BODY *body, bool input_check_duplicated_file_name, char *output_file_name_string, struct _m_content_info *cnt_info , int *err)
3467 EM_DEBUG_FUNC_BEGIN();
3469 char *decoded_filename = NULL;
3470 char attachment_file_name[MAX_PATH] = { 0, };
3471 char attachment_file_name_source[MAX_PATH] = {0, };
3472 int error = EMAIL_ERROR_NONE;
3473 bool file_name_duplicated = false;
3475 if ((body->type == TYPETEXT) && (body->disposition.type == NULL)) {
3476 EM_DEBUG_LOG("body->type == TYPETEXT");
3478 EM_DEBUG_EXCEPTION("But, cnt_info is null");
3479 error = EMAIL_ERROR_INVALID_PARAM;
3482 if (body->subtype[0] == 'H') {
3483 if (cnt_info->text.plain_charset != NULL) {
3484 memcpy(output_file_name_string, cnt_info->text.plain_charset, EM_SAFE_STRLEN(cnt_info->text.plain_charset));
3485 strcat(output_file_name_string, HTML_EXTENSION_STRING);
3488 memcpy(output_file_name_string, "UTF-8.htm", strlen("UTF-8.htm"));
3490 cnt_info->text.html = EM_SAFE_STRDUP(output_file_name_string);
3493 PARAMETER *param = body->parameter;
3494 char charset_string[512];
3496 if (emcore_get_attribute_value_of_body_part(param, "CHARSET", charset_string, 512, false, &error)) {
3497 cnt_info->text.plain_charset = EM_SAFE_STRDUP(charset_string);
3498 memcpy(output_file_name_string, cnt_info->text.plain_charset, EM_SAFE_STRLEN(cnt_info->text.plain_charset));
3501 memcpy(output_file_name_string, "UTF-8", strlen("UTF-8"));
3503 cnt_info->text.plain = EM_SAFE_STRDUP(output_file_name_string);
3507 else if ((body->id != NULL) || ((body->disposition.type != NULL) && ((body->disposition.type[0] == 'i') || (body->disposition.type[0] == 'I')))) {
3508 /* body id is exising or disposition type is inline */
3510 if (body->parameter) /* Get actual name of file */ {
3511 PARAMETER *param_body = body->parameter;
3512 if (!emcore_get_attribute_value_of_body_part(param_body, "NAME", attachment_file_name_source, MAX_PATH, true, &error))
3513 emcore_get_attribute_value_of_body_part(param_body, "CHARSET", attachment_file_name_source, MAX_PATH, true, &error);
3514 if (!emcore_make_attachment_file_name_with_extension(attachment_file_name_source, body->subtype, attachment_file_name, MAX_PATH, &error)) {
3515 EM_DEBUG_EXCEPTION("emcore_make_attachment_file_name_with_extension failed [%d]", error);
3519 else if (body->disposition.type) {
3520 PARAMETER *param_disposition = body->disposition.parameter;
3521 EM_DEBUG_LOG("body->disposition.type exist");
3522 emcore_get_attribute_value_of_body_part(param_disposition, "filename", attachment_file_name_source, MAX_PATH, true, &error);
3523 if (!emcore_make_attachment_file_name_with_extension(attachment_file_name_source, body->subtype, attachment_file_name, MAX_PATH, &error)) {
3524 EM_DEBUG_EXCEPTION("emcore_make_attachment_file_name_with_extension failed [%d]", error);
3528 else { /* body id is not null but disposition type is null */
3529 if ((body->id[0] == '<'))
3530 SNPRINTF(attachment_file_name, MAX_PATH, "%s", body->id+1); /* fname = em_parse_filename(body->id + 1 */
3532 SNPRINTF(attachment_file_name, MAX_PATH, "%s", body->id); /* fname = em_parse_filename(body->id */
3534 len = EM_SAFE_STRLEN(attachment_file_name);
3536 if ((len > 1) && (attachment_file_name[len-1] == '>'))
3537 attachment_file_name[len - 1] = '\0';
3538 decoded_filename = emcore_decode_rfc2047_text(attachment_file_name, &error);
3540 EM_DEBUG_LOG("attachment_file_name [%s]", attachment_file_name);
3541 if (decoded_filename != NULL)
3542 memcpy(output_file_name_string, decoded_filename, EM_SAFE_STRLEN(decoded_filename));
3544 memcpy(output_file_name_string, attachment_file_name, EM_SAFE_STRLEN(attachment_file_name));
3547 else if (body->disposition.type != NULL) { /* disposition type is existing and not inline and body_id is nul */
3548 PARAMETER *param = body->parameter;
3549 if (!emcore_get_attribute_value_of_body_part(param, "NAME", attachment_file_name, MAX_PATH, true, &error))
3550 emcore_get_attribute_value_of_body_part(param, "FILENAME", attachment_file_name, MAX_PATH, true, &error);
3551 memcpy(output_file_name_string, attachment_file_name, EM_SAFE_STRLEN(attachment_file_name));
3554 if(input_check_duplicated_file_name) {
3555 if ( (error = _find_duplicated_inline_content_file(output_file_name_string, cnt_info, &file_name_duplicated)) != EMAIL_ERROR_NONE) {
3556 EM_DEBUG_EXCEPTION("_find_duplicated_inline_content_file failed [%d]", error);
3560 if (file_name_duplicated == true) {
3561 if ( ( error = _modify_file_name_string_for_duplicated_inline_content(output_file_name_string, cnt_info)) != EMAIL_ERROR_NONE) {
3562 EM_DEBUG_EXCEPTION("_modify_file_name_string_for_duplicated_inline_content failed [%d]", error);
3570 EM_SAFE_FREE(decoded_filename);
3575 EM_DEBUG_FUNC_END("output_file_name_string[%s], error [%d]", output_file_name_string, error);
3580 static PARTLIST *emcore_add_node(PARTLIST *section_list, BODY *body)
3582 PARTLIST *temp = (PARTLIST *)malloc(sizeof(PARTLIST));
3585 EM_DEBUG_EXCEPTION("PARTLIST node creation failed");
3591 if (section_list == NULL)/* first node in list */ {
3592 section_list = temp;
3594 else/* has min 1 nod */ {
3595 PARTLIST *t = section_list;
3596 while (t->next != NULL) /* go to last nod */ {
3597 t = (PARTLIST *) t->next;
3599 t->next = (PART *)temp;/* I think this should be PARTLIST, but why this is PART */
3601 in imap-2007e/c-client/mail.h
3608 return section_list;
3612 static void emcore_free_section_list(PARTLIST *section_list)
3614 PARTLIST *temp = NULL;
3616 while (section_list != NULL) {
3617 temp = (PARTLIST *)section_list->next;
3618 EM_SAFE_FREE(section_list);
3619 section_list = temp;
3623 static int emcore_get_section_body_size(char *response, char *section, int *body_size)
3628 if ((p = strstr(response, "BODY[")) /* || (p = strstr(s + 1, "BODY["))*/) {
3630 p += strlen("BODY[");
3640 /* if (strcmp(section, p)) {
3641 err = EMAIL_ERROR_INVALID_RESPONSE;
3644 p = strstr(s+1, " {");
3657 /* sending progress noti to application.
3675 static char *em_parse_filename(char *filename)
3677 EM_DEBUG_FUNC_BEGIN("filename [%p] ", filename);
3679 EM_DEBUG_EXCEPTION("filename is NULL ");
3683 char delims[] = "@";
3684 char *result = NULL;
3685 static char parsed_filename[512] = {0, };
3687 memset(parsed_filename, 0x00, 512);
3689 if (!strstr(filename, delims)) {
3690 EM_DEBUG_EXCEPTION("FileName does not contain @ ");
3694 result = strtok(filename, delims);
3696 if (strcasestr(result, ".bmp") || strcasestr(result, ".jpeg") || strcasestr(result, ".png") || strcasestr(result, ".jpg"))
3697 sprintf(parsed_filename + EM_SAFE_STRLEN(parsed_filename), "%s", result);
3699 sprintf(parsed_filename + EM_SAFE_STRLEN(parsed_filename), "%s%s", result, ".jpeg");
3701 EM_DEBUG_LOG(">>> FileName [ %s ] ", result);
3703 EM_DEBUG_FUNC_END("parsed_filename [%s] ", parsed_filename);
3704 return parsed_filename;
3707 #define CONTENT_TYPE_STRING_IN_MIME_HEAEDER "Content-Type:"
3709 INTERNAL_FUNC int emcore_get_content_type_from_mime_string(char *input_mime_string, char **output_content_type)
3711 EM_DEBUG_FUNC_BEGIN("input_mime_string [%p], output_content_type [%p]", input_mime_string, output_content_type);
3713 int err = EMAIL_ERROR_NONE;
3714 int temp_mime_header_string_length = 0;
3715 char result_content_type[256] = { 0, };
3716 char *temp_mime_header_string = NULL;
3717 char *temp_content_type_start = NULL;
3718 char *temp_content_type_end = NULL;
3720 if(input_mime_string == NULL || output_content_type == NULL) {
3721 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
3722 err = EMAIL_ERROR_INVALID_PARAM;
3726 temp_mime_header_string_length = EM_SAFE_STRLEN(input_mime_string);
3727 temp_mime_header_string = input_mime_string;
3729 EM_DEBUG_LOG("temp_mime_header_string [%s]", temp_mime_header_string);
3731 temp_content_type_start = strcasestr(temp_mime_header_string, CONTENT_TYPE_STRING_IN_MIME_HEAEDER);
3733 if(temp_content_type_start == NULL) {
3734 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_DATA");
3735 err = EMAIL_ERROR_INVALID_DATA;
3739 temp_content_type_start += EM_SAFE_STRLEN(CONTENT_TYPE_STRING_IN_MIME_HEAEDER);
3740 temp_content_type_end = temp_content_type_start;
3742 while(temp_content_type_end && temp_content_type_end < (temp_mime_header_string + temp_mime_header_string_length) && *temp_content_type_end != ';')
3743 temp_content_type_end++;
3745 if(temp_content_type_end && *temp_content_type_end == ';') {
3746 if(temp_content_type_end - temp_content_type_start < 256) {
3747 memcpy(result_content_type, temp_content_type_start, temp_content_type_end - temp_content_type_start);
3748 EM_DEBUG_LOG("result_content_type [%s]", result_content_type);
3749 *output_content_type = EM_SAFE_STRDUP(result_content_type);
3750 em_trim_left(*output_content_type);
3754 EM_DEBUG_EXCEPTION("temp_content_type_end - temp_content_type_start [%d]", temp_content_type_end - temp_content_type_start);
3755 err = EMAIL_ERROR_DATA_TOO_LONG;
3763 EM_DEBUG_FUNC_END("err [%d]", err);
3767 #define SUBTYPE_STRING_LENGTH 128
3769 INTERNAL_FUNC int emcore_get_content_type_from_mail_bodystruct(BODY *input_body, int input_buffer_length, char *output_content_type)
3771 EM_DEBUG_FUNC_BEGIN("input_body [%p], input_buffer_length [%d], output_content_type [%p]", input_body, input_buffer_length, output_content_type);
3772 int err = EMAIL_ERROR_NONE;
3773 char subtype_string[SUBTYPE_STRING_LENGTH] = { 0 , };
3775 if(input_body == NULL || output_content_type == NULL || input_buffer_length == 0) {
3776 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
3777 err = EMAIL_ERROR_INVALID_PARAM;
3781 EM_SAFE_STRNCPY(subtype_string, input_body->subtype, SUBTYPE_STRING_LENGTH-1); /* prevent 21983 */
3782 em_lower_string(subtype_string);
3784 switch(input_body->type) {
3786 SNPRINTF(output_content_type, input_buffer_length, "text/%s", subtype_string);
3788 case TYPEMULTIPART :
3789 SNPRINTF(output_content_type, input_buffer_length, "multipart/%s", subtype_string);
3792 SNPRINTF(output_content_type, input_buffer_length, "message/%s", subtype_string);
3794 case TYPEAPPLICATION :
3795 SNPRINTF(output_content_type, input_buffer_length, "application/%s", subtype_string);
3798 SNPRINTF(output_content_type, input_buffer_length, "audio/%s", subtype_string);
3801 SNPRINTF(output_content_type, input_buffer_length, "image/%s", subtype_string);
3804 SNPRINTF(output_content_type, input_buffer_length, "video/%s", subtype_string);
3807 SNPRINTF(output_content_type, input_buffer_length, "model/%s", subtype_string);
3810 SNPRINTF(output_content_type, input_buffer_length, "other/%s", subtype_string);
3813 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
3814 err = EMAIL_ERROR_INVALID_PARAM;
3819 EM_DEBUG_LOG("output_content_type [%s]", output_content_type);
3823 EM_DEBUG_FUNC_END("err [%d]", err);
3827 INTERNAL_FUNC int emcore_get_attribute_value_of_body_part(PARAMETER *input_param, char *atribute_name, char *output_value, int output_buffer_length, int with_rfc2047_text, int *err_code)
3829 EM_DEBUG_FUNC_BEGIN("input_param [%p], atribute_name [%s], output_buffer_length [%d], with_rfc2047_text [%d]", input_param, atribute_name, output_buffer_length, with_rfc2047_text);
3830 PARAMETER *temp_param = input_param;
3831 char *decoded_value = NULL, *result_value = NULL;
3832 int ret = false, err = EMAIL_ERROR_NONE;
3835 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
3836 err = EMAIL_ERROR_INVALID_PARAM;
3840 memset(output_value, 0, output_buffer_length);
3842 while (temp_param) {
3843 EM_DEBUG_LOG("temp_param->attribute [%s]", temp_param->attribute);
3844 if (!strcasecmp(temp_param->attribute, atribute_name)) {
3845 EM_DEBUG_LOG("temp_param->value [%s]", temp_param->value);
3846 if (temp_param->value) {
3847 if (with_rfc2047_text) {
3848 decoded_value = emcore_decode_rfc2047_text(temp_param->value, &err);
3850 result_value = decoded_value;
3852 result_value = decoded_value;
3855 result_value = temp_param->value;
3858 EM_DEBUG_EXCEPTION("EMAIL_ERROR_DATA_NOT_FOUND");
3859 err = EMAIL_ERROR_DATA_NOT_FOUND;
3862 EM_DEBUG_LOG("result_value [%s]", result_value);
3864 if(output_buffer_length > EM_SAFE_STRLEN(result_value)) {
3865 strncpy(output_value, result_value, output_buffer_length);
3866 output_value[EM_SAFE_STRLEN(result_value)] = NULL_CHAR;
3870 EM_DEBUG_EXCEPTION("buffer is too short");
3871 err = EMAIL_ERROR_DATA_TOO_LONG;
3878 temp_param = temp_param->next;
3882 EM_SAFE_FREE(decoded_value);
3887 EM_DEBUG_FUNC_END("ret [%d]", ret);
3893 *download body part of imap mail (body-text and attachment)
3895 static int emcore_get_body_part_imap(MAILSTREAM *stream, int account_id, int mail_id, int msg_uid, BODY *body, struct _m_content_info *cnt_info, int *err_code)
3897 EM_DEBUG_FUNC_BEGIN("stream[%p], msg_uid[%d], body[%p], cnt_info[%p], err_code[%p]", stream, msg_uid, body, cnt_info, err_code);
3899 int err = EMAIL_ERROR_NONE, ret = -1;
3900 struct attachment_info **ai;
3901 struct attachment_info *prev_ai = NULL;
3902 struct attachment_info *next_ai = NULL;
3903 char *savefile = NULL;
3904 char *o_data = NULL;
3905 char filename[MAX_PATH + 1] = { 0, };
3906 char *decoded_filename = NULL;
3907 int is_attachment = 0;
3909 char *filename_temp = NULL;
3910 char charset_value_buffer[512] = { 0, };
3911 char content_type_buffer[512] = { 0, };
3916 char *sparep = NULL;
3917 unsigned short encode = 0;
3918 int section_plain = 0;
3919 int section_html = 0;
3920 int is_pbd = (account_id == 0 && mail_id == 0) ? true : false;
3923 EM_DEBUG_LOG("Grab Type [ %d ] ", cnt_info->grab_type);
3926 if (body->type > TYPEOTHER) { /* unknown type */
3927 EM_DEBUG_EXCEPTION("Unknown type.");
3928 err = EMAIL_ERROR_NOT_SUPPORTED;
3932 if (NULL == body->subtype) {
3933 EM_DEBUG_LOG("body->subtype is null. "); /* not exceptional case */
3934 if (err_code != NULL)
3935 *err_code = EMAIL_ERROR_INVALID_PARAM;
3940 if (!emcore_get_temp_file_name(&o_data, &err) || !o_data) {
3941 EM_DEBUG_EXCEPTION("emcore_get_temp_file_name failed [%d]", err);
3942 if (err_code != NULL)
3948 if (body->subtype[0] == 'P') { /* Sub type is PLAIN_TEX */
3949 if (cnt_info->text.plain != NULL)
3950 EM_SAFE_FREE(o_data);
3953 if (body->type == TYPETEXT && body->subtype &&
3954 (!body->disposition.type || (body->disposition.type && (body->disposition.type[0] == 'i' || body->disposition.type[0] == 'I')))) {
3955 if (body->subtype[0] == 'H') /* HTM */
3956 cnt_info->text.html = o_data;
3958 cnt_info->text.plain = o_data;
3960 memset(charset_value_buffer, 0, 512);
3962 if (emcore_get_attribute_value_of_body_part(body->parameter, "CHARSET", charset_value_buffer, 512, true, &err)) {
3963 cnt_info->text.plain_charset = EM_SAFE_STRDUP(charset_value_buffer);
3964 EM_DEBUG_LOG(">>>>> CHARSET [%s] ", filename);
3969 if ((body->id) && EM_SAFE_STRLEN(body->id) > 1) { /* if Content-ID or Content-Location exists, it is inline contents */
3970 EM_DEBUG_LOG("body->id exist");
3972 /* Get actual name of file - fix for inline images to be stored with actual names and not .jpeg */
3973 if (body->parameter) {
3974 PARAMETER *param1 = body->parameter;
3976 EM_DEBUG_LOG("param1->attribute - %s ", param1->attribute);
3977 if (!strcasecmp(param1->attribute, "NAME")) { /* attribute is "NAME" */
3978 char *extcheck = NULL;
3980 if (param1->value) {
3981 decoded_filename = emcore_decode_rfc2047_text(param1->value, &err);
3982 strncpy(filename, decoded_filename, MAX_PATH);
3983 EM_SAFE_FREE(decoded_filename);
3985 EM_DEBUG_LOG(">>>>> FILENAME [%s] ", filename);
3986 extcheck = strchr(filename, '.');
3989 EM_DEBUG_LOG(">>>> Extension Exist in the Attachment [ %s ] ", extcheck);
3990 else /* No extension attached , So add the Extension based on the subtyp */ {
3991 if (body->subtype) {
3992 strcat(filename, ".");
3993 strcat(filename, body->subtype);
3994 EM_DEBUG_LOG(">>>>> FILENAME Identified the Extension [%s] ", filename);
3997 EM_DEBUG_EXCEPTION("UnKnown Extesnsion : _ (");
4003 param1 = param1->next;
4007 else if (body->disposition.type) {
4008 PARAMETER *param = body->disposition.parameter;
4011 EM_DEBUG_LOG(">>>>> body->disposition.parameter->attribute [ %s ] ", param->attribute);
4012 EM_DEBUG_LOG(">>>>> body->disposition.parameter->value [ %s ] ", param->value);
4014 /* attribute is "filename" */
4015 if (!strcasecmp(param->attribute, "filename")) {
4016 decoded_filename = emcore_decode_rfc2047_text(param->value, &err);
4017 strncpy(filename, decoded_filename, MAX_PATH);
4018 EM_SAFE_FREE(decoded_filename);
4019 EM_DEBUG_LOG(">>>>> FILENAME [%s] ", filename);
4023 param = param->next;
4027 if ((body->id[0] == '<'))
4028 SNPRINTF(filename, MAX_PATH, "%s", body->id+1);
4030 SNPRINTF(filename, MAX_PATH, "%s", body->id);
4032 len = EM_SAFE_STRLEN(filename);
4034 if ((len > 1) && (filename[len-1] == '>'))
4035 filename[len-1] = '\0';
4037 /* is_attachment = 1; */
4040 else if (body->location) {
4041 EM_DEBUG_LOG("body->location exist");
4043 decoded_filename = emcore_decode_rfc2047_text(body->location, &err);
4044 strncpy(filename, decoded_filename, MAX_PATH);
4045 EM_SAFE_FREE(decoded_filename);
4046 EM_DEBUG_LOG("body->location [%s]", body->location);
4048 else if (is_pbd && (strncmp(body->subtype, "RFC822", strlen("RFC822")) == 0) && (cnt_info->grab_type == 0 || (cnt_info->grab_type & GRAB_TYPE_ATTACHMENT))) {
4049 EM_DEBUG_LOG("Beause subtype is RFC822. This is ttachment");
4052 if (cnt_info->grab_type == 0) {
4053 if ((body->nested.msg != NULL) && (body->nested.msg->env != NULL) && (body->nested.msg->env->subject != NULL)) {
4054 decoded_filename = emcore_decode_rfc2047_text(body->nested.msg->env->subject, &err);
4055 strncpy(filename, decoded_filename, MAX_PATH);
4056 EM_SAFE_FREE(decoded_filename);
4059 strncpy(filename, "Unknown <message/rfc822>", MAX_PATH);
4061 else if (cnt_info->grab_type & GRAB_TYPE_ATTACHMENT) {
4062 BODY *temp_body = NULL;
4063 if (body->nested.msg->env->subject != NULL) {
4065 int subject_count = 0;
4066 if (g_str_has_prefix(body->nested.msg->env->subject, "= ? ") && g_str_has_suffix(body->nested.msg->env->subject, " ? = "))
4067 strncpy(filename, "unknown", MAX_PATH);
4069 for (subject_count = 0; body->nested.msg->env->subject[subject_count] != '\0' ; subject_count++) {
4070 if (body->nested.msg->env->subject[subject_count] != ':' &&
4071 body->nested.msg->env->subject[subject_count] != ';' &&
4072 body->nested.msg->env->subject[subject_count] != '*' &&
4073 body->nested.msg->env->subject[subject_count] != '?' &&
4074 body->nested.msg->env->subject[subject_count] != '\"' &&
4075 body->nested.msg->env->subject[subject_count] != '<' &&
4076 body->nested.msg->env->subject[subject_count] != '>' &&
4077 body->nested.msg->env->subject[subject_count] != '|' &&
4078 body->nested.msg->env->subject[subject_count] != '/') {
4079 filename[i] = body->nested.msg->env->subject[subject_count];
4088 strncpy(filename, "Unknown", MAX_PATH);
4090 body = ((MESSAGE *)body->nested.msg)->body;
4091 part = body->nested.part;
4093 if ((body->subtype[0] == 'P') || (body->subtype[0] == 'H'))
4095 else if (part != NULL) {
4096 temp_body = &(part->body);
4097 if ((temp_body->subtype[0] == 'P' || temp_body->subtype[0] == 'H') && part->next != NULL) {
4099 temp_body = &(part->body);
4104 if (temp_body->subtype[0] == 'P')
4106 else if (temp_body->subtype[0] == 'H')
4109 sparep = temp_body->sparep;
4110 encode = temp_body->encoding;
4115 else if (body->disposition.type) /* if disposition exists, get filename from disposition parameter */ { /* "attachment" or "inline" or etc.. */
4116 EM_DEBUG_LOG("body->disposition.type exist");
4119 if (emcore_get_attribute_value_of_body_part(body->disposition.parameter, "filename", filename, MAX_PATH, true, &err))
4120 EM_DEBUG_LOG(">>>>> FILENAME [%s] ", filename);
4122 if (!*filename) { /* If the part has no filename, it may be report ms */
4123 if ((body->disposition.type[0] == 'i' || body->disposition.type[0] == 'I') && body->parameter && body->parameter->attribute && strcasecmp(body->parameter->attribute, "NAME"))
4125 else if (body->parameter) /* Fix for the MMS attachment File name as unknown */ {
4126 char *extcheck = NULL;
4128 if (emcore_get_attribute_value_of_body_part(body->parameter, "NAME", filename, MAX_PATH, true, &err))
4129 EM_DEBUG_LOG("NAME [%s] ", filename);
4131 extcheck = strchr(filename, '.');
4134 EM_DEBUG_LOG(">>>> Extension Exist in the Attachment [ %s ] ", extcheck);
4135 else { /* No extension attached , So add the Extension based on the subtype */
4136 if (body->subtype) {
4137 if (EM_SAFE_STRLEN(filename) + EM_SAFE_STRLEN(body->subtype) + 1 < MAX_PATH) {
4138 strcat(filename, ".");
4139 strcat(filename, body->subtype);
4141 EM_DEBUG_LOG(">>>>> FILENAME Identified the Extension [%s] ", filename);
4144 EM_DEBUG_EXCEPTION("UnKnown Extesnsion : _ (");
4149 strncpy(filename, "unknown", MAX_PATH);
4152 if ((body->disposition.type[0] == 'i' || body->disposition.type[0] == 'I'))
4157 /* if (!is_pbd) */ {
4158 EM_DEBUG_LOG("filename [%s]", filename);
4160 decoded_filename = emcore_decode_rfc2047_text(filename, &err);
4161 strncpy(filename, decoded_filename, MAX_PATH);
4162 EM_SAFE_FREE(decoded_filename);
4163 filename_temp = em_parse_filename(filename);
4164 if (filename_temp) {
4165 strncpy(filename, filename_temp, MAX_PATH);
4166 EM_DEBUG_LOG("filename [%s]", filename);
4170 EM_DEBUG_LOG("is_attachment [%d]", is_attachment);
4172 if (!is_attachment) { /* Text or RFC822 Message */
4173 EM_DEBUG_LOG("Multipart is not attachment, body->type = %d", body->type);
4174 if ((cnt_info->grab_type & GRAB_TYPE_TEXT) && (body->type == TYPEMESSAGE || body->type == TYPETEXT || body->type == TYPEIMAGE)) {
4177 else { /* fetch body */
4178 if (!emcore_get_temp_file_name(&o_data, &err)) {
4179 EM_DEBUG_EXCEPTION("emcore_get_temp_file_name failed [%d]", err);
4183 if (!imap_mail_write_body_to_file(stream, account_id, mail_id, 0, o_data, msg_uid, body->sparep, body->encoding, &o_data_len, body->subtype, &err)) {
4184 EM_DEBUG_EXCEPTION("imap_mail_write_body_to_file failed [%d]", err);
4185 if(err == EMAIL_ERROR_INVALID_STREAM) {
4186 email_session_t *session = NULL;
4187 emcore_get_current_session(&session);
4188 err = session->error;
4195 switch (body->type) {
4197 EM_DEBUG_LOG("TYPETEXT");
4198 if (body->subtype[0] == 'H')
4199 cnt_info->text.html = o_data;
4201 cnt_info->text.plain = o_data;
4202 memset(charset_value_buffer, 0, 512);
4203 if (emcore_get_attribute_value_of_body_part(body->parameter, "CHARSET", charset_value_buffer, 512, true, &err))
4204 cnt_info->text.plain_charset = EM_SAFE_STRDUP(charset_value_buffer);
4208 case TYPEAPPLICATION:
4211 /* Inline Content - suspect of crash on partial body download */
4213 EM_DEBUG_LOG("TYPEIMAGE or TYPEAPPLICATION : inline content");
4214 ai = &(cnt_info->file);
4216 dec_len = body->size.bytes;
4217 if ((cnt_info->grab_type & GRAB_TYPE_ATTACHMENT) &&
4218 (cnt_info->grab_type & GRAB_TYPE_TEXT)) { /* it is 'download all */
4219 only_body_download = false;
4220 cnt_info->file_no = 1;
4223 /* add attachment info to content info */
4224 if (!(*ai = em_malloc(sizeof(struct attachment_info)))) {
4225 EM_DEBUG_EXCEPTION("em_malloc failed...");
4226 if (err_code != NULL)
4227 *err_code = EMAIL_ERROR_OUT_OF_MEMORY;
4231 if (((body->id) || (body->location)) && body->type == TYPEIMAGE)
4232 (*ai)->type = 1; /* inline */
4234 (*ai)->type = 2; /* attachment */
4236 (*ai)->name = EM_SAFE_STRDUP(filename);
4237 (*ai)->size = body->size.bytes;
4238 (*ai)->save = o_data;
4239 (*ai)->content_id = EM_SAFE_STRDUP(body->id);
4241 memset(content_type_buffer, 0, 512);
4242 if ( (err = emcore_get_content_type_from_mail_bodystruct(body, 512, content_type_buffer) ) == EMAIL_ERROR_NONE)
4243 (*ai)->attachment_mime_type = EM_SAFE_STRDUP(content_type_buffer);
4245 EM_DEBUG_LOG("name[%s], size[%d], save[%s], content_id[%s], content_type_buffer [%s]", cnt_info->file->name, cnt_info->file->size, cnt_info->file->save, content_type_buffer);
4246 #ifdef __ATTACHMENT_OPTI__
4247 (*ai)->encoding = body->encoding;
4249 (*ai)->section = EM_SAFE_STRDUP(body->sparep);
4250 EM_DEBUG_LOG(" Encoding - %d Section No - %s ", (*ai)->encoding, (*ai)->section);
4255 case TYPEMESSAGE: /* RFC822 Message */
4256 EM_DEBUG_EXCEPTION("MESSAGE/RFC822");
4257 err = EMAIL_ERROR_NOT_SUPPORTED;
4261 EM_DEBUG_EXCEPTION("Unknown type. body->type [%d]", body->type);
4262 err = EMAIL_ERROR_NOT_SUPPORTED;
4266 stream->text.data = NULL; /* ? ? ? ? ? ? ? ? */
4268 else { /* Attachment */
4271 ai = &cnt_info->file;
4272 EM_DEBUG_LOG(" ai - %p ", (*ai));
4274 if ((body->id) || (body->location)) {
4275 /* For Inline content append to the end */
4276 for (i = 1; *ai; ai = &(*ai)->next)
4279 else { /* For attachment - search till Inline content found and insert before inline */
4280 for (i = 1; *ai; ai = &(*ai)->next) {
4281 if ((*ai)->type == 1) {
4282 /* Means inline image */
4283 EM_DEBUG_LOG("Found Inline Content ");
4292 EM_DEBUG_LOG("i - %d next_ai - %p prev_ai - %p", i, next_ai, prev_ai);
4294 if ((cnt_info->grab_type & GRAB_TYPE_ATTACHMENT) &&
4295 (cnt_info->grab_type & GRAB_TYPE_TEXT)) { /* it is 'download all */
4296 EM_DEBUG_LOG("Download All");
4297 only_body_download = false;
4298 cnt_info->file_no = 1;
4301 /* meaningless code */
4302 dec_len = body->size.bytes;
4305 EM_DEBUG_LOG("BODY ID [ %s ]", body->id);
4307 EM_DEBUG_LOG("BODY ID IS NULL");
4309 EM_DEBUG_LOG("i : %d, cnt_info->file_no : %d", i, cnt_info->file_no);
4312 ((cnt_info->grab_type & GRAB_TYPE_ATTACHMENT) && i == cnt_info->file_no) || /* Is it correct attachment */
4313 (((body->id) || (body->location)) && (cnt_info->grab_type & GRAB_TYPE_TEXT)) /* Is it inline contents */
4315 /* fetch attachment */
4316 EM_DEBUG_LOG("attachment (enc) : %s %ld bytes", filename, body->size.bytes);
4317 EM_DEBUG_LOG(">>>>> ONLY BODY DOWNLOAD [ %d ] ", only_body_download);
4319 if (only_body_download == false) {
4320 if (!emcore_get_temp_file_name(&savefile, &err)) {
4321 EM_DEBUG_EXCEPTION("emcore_get_temp_file_name failed [%d]", err);
4326 if (!imap_mail_write_body_to_file(stream, account_id, mail_id, cnt_info->file_no, savefile, msg_uid, body->sparep, body->encoding, &dec_len, body->subtype, &err)) {
4327 EM_DEBUG_EXCEPTION("imap_mail_write_body_to_file failed [%d]", err);
4334 EM_DEBUG_LOG("attachment (dec) : %s %d bytes", filename, dec_len);
4336 /* add attachment info to content inf */
4337 if (!(*ai = em_malloc(sizeof(struct attachment_info)))) {
4338 EM_DEBUG_EXCEPTION("em_malloc failed...");
4339 err = EMAIL_ERROR_OUT_OF_MEMORY;
4343 if ((body->id) || (body->location))
4349 if (savefile != NULL) {
4350 if (section_plain == 1)
4351 strcat(filename, ".txt");
4352 if (section_html == 1)
4353 strcat(filename, ".html");
4358 (*ai)->name = EM_SAFE_STRDUP(filename);
4359 (*ai)->size = dec_len;
4360 (*ai)->save = savefile;
4361 (*ai)->content_id = EM_SAFE_STRDUP(body->id);
4363 memset(content_type_buffer, 0, 512);
4364 if ( (err = emcore_get_content_type_from_mail_bodystruct(body, 512, content_type_buffer) ) == EMAIL_ERROR_NONE)
4365 (*ai)->attachment_mime_type = EM_SAFE_STRDUP(content_type_buffer);
4366 #ifdef __ATTACHMENT_OPTI__
4367 (*ai)->encoding = body->encoding;
4369 (*ai)->section = EM_SAFE_STRDUP(body->sparep);
4371 EM_DEBUG_LOG(" Encoding - %d Section No - %s ", (*ai)->encoding, (*ai)->section);
4373 if (body->type == TYPEAPPLICATION) {
4374 if (!strcasecmp(body->subtype, MIME_SUBTYPE_DRM_OBJECT))
4375 (*ai)->drm = EMAIL_ATTACHMENT_DRM_OBJECT;
4376 else if (!strcasecmp(body->subtype, MIME_SUBTYPE_DRM_RIGHTS))
4377 (*ai)->drm = EMAIL_ATTACHMENT_DRM_RIGHTS;
4378 else if (!strcasecmp(body->subtype, MIME_SUBTYPE_DRM_DCF))
4379 (*ai)->drm = EMAIL_ATTACHMENT_DRM_DCF;
4382 /* All inline images information are stored at the end of list */
4383 if ((*ai)->type != 1 && next_ai != NULL) {
4384 /* Means next_ai points to the inline attachment info structure */
4385 if (prev_ai == NULL) {
4386 /* First node is inline attachment */
4387 (*ai)->next = next_ai;
4388 cnt_info->file = (*ai);
4391 prev_ai->next = (*ai);
4392 (*ai)->next = next_ai;
4401 EM_DEBUG_FUNC_END("ret [%d]", ret);
4404 /* get body-part in nested part */
4406 static int emcore_get_allnested_part(MAILSTREAM *stream, int account_id, int mail_id, int msg_uid, BODY *body, struct _m_content_info *cnt_info, int *err_code)
4408 EM_DEBUG_FUNC_BEGIN("stream[%p], msg_uid[%d], body[%p], cnt_info[%p], err_code[%p]", stream, msg_uid, body, cnt_info, err_code);
4409 PART *part_child = body->nested.part;
4411 while (part_child) {
4412 if (emcore_get_body(stream, account_id, mail_id, msg_uid, &part_child->body, cnt_info, err_code) < 0)
4415 part_child = part_child->next;
4418 EM_DEBUG_FUNC_END();
4422 /* get body-part in alternative multiple part */
4423 static int emcore_get_alternative_multi_part(MAILSTREAM *stream, int account_id, int mail_id, int msg_uid, BODY *body, struct _m_content_info *cnt_info, int *err_code)
4425 EM_DEBUG_FUNC_BEGIN("stream[%p], msg_uid[%d], body[%p], cnt_info[%p], err_code[%p]", stream, msg_uid, body, cnt_info, err_code);
4427 PART *part_child = body->nested.part;
4429 /* find the best sub part we can show */
4430 while (part_child) {
4431 if (emcore_get_body(stream, account_id, mail_id, msg_uid, &part_child->body, cnt_info, err_code) < 0)
4434 part_child = part_child->next;
4436 EM_DEBUG_FUNC_END();
4440 /* get body part in signed multiple part */
4441 static int emcore_get_signed_multi_part(MAILSTREAM *stream, int account_id, int mail_id, int msg_uid, BODY *body, struct _m_content_info *cnt_info, int *err_code)
4443 EM_DEBUG_FUNC_BEGIN("stream[%p], msg_uid[%d], body[%p], cnt_info[%p], err_code[%p]", stream, msg_uid, body, cnt_info, err_code);
4445 PART *part_child = body->nested.part;
4447 /* find the best sub part we can show */
4448 while (part_child) {
4449 if (emcore_get_body(stream, account_id, mail_id, msg_uid, &part_child->body, cnt_info, err_code) < 0)
4452 part_child = part_child->next;
4455 EM_DEBUG_FUNC_END();
4459 /* get body part in encrypted multiple part */
4460 static int emcore_get_encrypted_multi_part(MAILSTREAM *stream, int account_id, int mail_id, int msg_uid, BODY *body, struct _m_content_info *cnt_info, int *err_code)
4462 EM_DEBUG_FUNC_BEGIN("stream[%p], msg_uid[%d], body[%p], cnt_info[%p], err_code[%p]", stream, msg_uid, body, cnt_info, err_code);
4463 EM_DEBUG_FUNC_END();
4467 /* get body part in multiple part */
4468 static int emcore_get_multi_part(MAILSTREAM *stream, int account_id, int mail_id, int msg_uid, BODY *body, struct _m_content_info *cnt_info, int *err_code)
4470 EM_DEBUG_FUNC_BEGIN("stream[%p], msg_uid[%d], body[%p], cnt_info[%p], err_code[%p]", stream, msg_uid, body, cnt_info, err_code);
4473 EM_DEBUG_EXCEPTION("Invalid Parameter.");
4475 *err_code = EMAIL_ERROR_INVALID_PARAM;
4479 switch (body->subtype[0]) {
4480 case 'A': /* ALTERNATIVE */
4481 EM_DEBUG_LOG("body->subtype[0] = ALTERNATIVE");
4482 return emcore_get_alternative_multi_part(stream, account_id, mail_id, msg_uid, body, cnt_info, err_code);
4484 case 'S': /* SIGNED */
4485 EM_DEBUG_LOG("body->subtype[0] = SIGNED");
4486 return emcore_get_signed_multi_part(stream, account_id, mail_id, msg_uid, body, cnt_info, err_code);
4488 case 'E': /* ENCRYPTED */
4489 EM_DEBUG_LOG("body->subtype[0] = ENCRYPTED");
4490 return emcore_get_encrypted_multi_part(stream, account_id, mail_id, msg_uid, body, cnt_info, err_code);
4492 default: /* process all unknown as MIXED (according to the RFC 2047) */
4493 EM_DEBUG_LOG("body->subtype[0] = [%c].", body->subtype[0]);
4494 return emcore_get_allnested_part(stream, account_id, mail_id, msg_uid, body, cnt_info, err_code);
4496 /* Delete the dead code */
4499 /* get body data by body structure */
4500 /* if POP3, ignored */
4501 INTERNAL_FUNC int emcore_get_body(MAILSTREAM *stream, int account_id, int mail_id, int msg_uid, BODY *body, struct _m_content_info *cnt_info, int *err_code)
4503 EM_DEBUG_FUNC_BEGIN("stream[%p], msg_uid[%d], body[%p], cnt_info[%p], err_code[%p]", stream, msg_uid, body, cnt_info, err_code);
4505 if (!stream || !body || !cnt_info) {
4506 EM_DEBUG_EXCEPTION("Invalid parameter");
4508 if (err_code != NULL)
4509 *err_code = EMAIL_ERROR_INVALID_PARAM;
4513 EM_DEBUG_LOG("body->type [%d]", body->type);
4515 switch (body->type) {
4517 return emcore_get_multi_part(stream, account_id, mail_id, msg_uid, body, cnt_info, err_code);
4519 case TYPEMESSAGE: /* not support */
4520 if (strcasecmp(body->subtype, "RFC822") == 0)
4521 return emcore_get_body_part_imap(stream, account_id, mail_id, msg_uid, body, cnt_info, err_code);
4525 case TYPEAPPLICATION:
4531 /* exactly, get a pure body part (text and attachment */
4532 return emcore_get_body_part_imap(stream, account_id, mail_id, msg_uid, body, cnt_info, err_code);
4537 EM_DEBUG_FUNC_END();
4541 /* get body structure */
4542 INTERNAL_FUNC int emcore_get_body_structure(MAILSTREAM *stream, int msg_uid, BODY **body, int *err_code)
4544 EM_DEBUG_FUNC_BEGIN("stream[%p], msg_uid[%d], body[%p], err_code[%p]", stream, msg_uid, body, err_code);
4546 EM_IF_NULL_RETURN_VALUE(stream, false);
4547 EM_IF_NULL_RETURN_VALUE(body, false);
4549 #ifdef __FEATURE_HEADER_OPTIMIZATION__
4550 ENVELOPE *env = mail_fetch_structure(stream, msg_uid, body, FT_UID | FT_PEEK | FT_NOLOOKAHEAD, 1);
4552 ENVELOPE *env = mail_fetch_structure(stream, msg_uid, body, FT_UID | FT_PEEK | FT_NOLOOKAHEAD);
4556 *err_code = EMAIL_ERROR_MAIL_NOT_FOUND_ON_SERVER;
4557 EM_DEBUG_EXCEPTION("mail_fetch_structure failed");
4561 #ifdef FEATURE_CORE_DEBUG
4562 _print_body(*body, true); /* shasikala.p@partner.samsung.com */
4564 EM_DEBUG_FUNC_END();
4568 int emcore_set_fetch_part_section(BODY *body, char *section_pfx, int section_subno, int enable_inline_list, int *total_mail_size, int *err_code);
4570 /* set body section to be fetched */
4571 INTERNAL_FUNC int emcore_set_fetch_body_section(BODY *body, int enable_inline_list, int *total_mail_size, int *err_code)
4573 EM_DEBUG_FUNC_BEGIN("body[%p], err_code[%p]", body, err_code);
4576 EM_DEBUG_EXCEPTION("body [%p]", body);
4577 if (err_code != NULL)
4578 *err_code = EMAIL_ERROR_INVALID_PARAM;
4582 // body->id = cpystr("1"); /* top level body */
4583 EM_DEBUG_LOG("body->id : [%s]", body->id);
4586 EM_SAFE_FREE(g_inline_list);
4587 emcore_set_fetch_part_section(body, (char *)NULL, 0, enable_inline_list, total_mail_size, err_code);
4589 if (body && body->id)
4590 EM_DEBUG_LOG(">>>>> FILE NAME [%s] ", body->id);
4592 EM_DEBUG_LOG(">>>>> BODY NULL ");
4594 EM_DEBUG_FUNC_END();
4598 /* set part section of body to be fetched */
4599 int emcore_set_fetch_part_section(BODY *body, char *section_pfx, int section_subno, int enable_inline_list, int *total_mail_size, int *err_code)
4601 EM_DEBUG_FUNC_BEGIN("body[%p], section_pfx[%s], section_subno[%d], err_code[%p]", body, section_pfx, section_subno, err_code);
4604 char section[64] = {0x00, };
4606 /* multipart doesn't have a row to itself */
4607 if (body->type == TYPEMULTIPART) {
4608 /* if not first time, extend prefix */
4610 SNPRINTF(section, sizeof(section), "%s%d.", section_pfx, ++section_subno);
4616 for (section_subno = 0, part = body->nested.part; part; part = part->next)
4617 emcore_set_fetch_part_section(&part->body, section, section_subno++, enable_inline_list, total_mail_size, err_code);
4620 if (!section_pfx) /* dummy prefix if top level */
4623 SNPRINTF(section, sizeof(section), "%s%d", section_pfx, ++section_subno);
4625 if (enable_inline_list && ((body->disposition.type && (body->disposition.type[0] == 'i' || body->disposition.type[0] == 'I')) ||
4626 (!body->disposition.type && body->id))) {
4628 temp = realloc(g_inline_list, sizeof(BODY *) *(g_inline_count + 1));
4630 memset(temp+g_inline_count, 0x00, sizeof(BODY *));
4631 g_inline_list = temp;
4632 g_inline_list[g_inline_count] = body;
4637 EM_DEBUG_EXCEPTION("realloc fails");
4640 EM_DEBUG_LOG("Update g_inline_list with inline count [%d]", g_inline_count);
4643 /* if ((total_mail_size != NULL) && !(body->disposition.type && (body->disposition.type[0] == 'a' || body->disposition.type[0] == 'A')) */
4644 if (total_mail_size != NULL) {
4645 *total_mail_size = *total_mail_size + (int)body->size.bytes;
4646 EM_DEBUG_LOG("body->size.bytes [%d]", body->size.bytes);
4649 /* encapsulated message ? */
4650 if ((body->type == TYPEMESSAGE) && !strcasecmp(body->subtype, "RFC822") && (body = ((MESSAGE *)body->nested.msg)->body)) {
4651 if (body->type == TYPEMULTIPART) {
4653 emcore_set_fetch_part_section(body, section, section_subno-1, enable_inline_list, total_mail_size, err_code);
4655 else { /* build encapsulation prefi */
4656 SNPRINTF(section, sizeof(section), "%s%d.", section_pfx, section_subno);
4657 emcore_set_fetch_part_section(body, section, 0, enable_inline_list, total_mail_size, err_code);
4661 /* set body section */
4663 body->sparep = cpystr(section);
4666 EM_DEBUG_FUNC_END();
4671 static void parse_file_path_to_filename(char *src_string, char **out_string)
4674 char *filepath = NULL;
4679 filepath = EM_SAFE_STRDUP(src_string);
4680 token = strtok_r(filepath, "/", &str);
4685 } while ((token = strtok_r(NULL , "/", &str)));
4687 *out_string = EM_SAFE_STRDUP(prev1);
4688 EM_SAFE_FREE(filepath);
4691 static char *emcore_decode_rfc2047_word(char *encoded_word, int *err_code)
4693 EM_DEBUG_FUNC_BEGIN("encoded_word[%s], err_code[%p]", encoded_word, err_code);
4695 int err = EMAIL_ERROR_NONE;
4696 int base64_encoded = false, length = 0;
4697 SIZEDTEXT src = { NULL, 0 };
4698 SIZEDTEXT dst = { NULL, 0 };
4699 gchar *charset = NULL, *encoded_text = NULL;
4700 char *decoded_text = NULL, *decoded_word = NULL;
4701 char *current = NULL, *start = NULL, *end = NULL;
4702 char *buffer = (char*) em_malloc(EM_SAFE_STRLEN(encoded_word) * 2 + 1);
4704 if (buffer == NULL) {
4705 EM_DEBUG_EXCEPTION("Memory allocation fail");
4706 err = EMAIL_ERROR_OUT_OF_MEMORY;
4712 /* encoding format : =?charset?encoding?encoded-text ?= */
4713 /* charset : UTF-8, EUC-KR, ... */
4714 /* encoding : b/B (BASE64), q/Q (QUOTED-PRINTABLE) */
4715 current = encoded_word;
4717 while (*current != NULL_CHAR) {
4719 start = strstr(current, "=?"); /* start of encoding */
4720 end = strstr(current, "?="); /* end of encoding */
4722 #ifdef FEATURE_CORE_DEBUG
4723 EM_DEBUG_LOG("current[%p][%s], start[%p][%s], end[%p][%s]", current, current, start, start, end, end);
4725 if (start != NULL) {
4726 if (current != start) { /* copy the string between current and start to buffer */
4727 strncat(buffer, current, start - current);
4729 #ifdef FEATURE_CORE_DEBUG
4730 EM_DEBUG_LOG("1 - Buffer[%s]", buffer);
4734 if (end) { /* decode text between start and end */
4735 char *p = strstr(start, "?b?");
4737 if (p || (p = strstr(start, "?B?"))) /* BASE64 */
4738 base64_encoded = true;
4740 p = strstr(start, "?q?");
4742 if (p || (p = strstr(start, "?Q?"))) /* QUOTED-PRINTABLE */
4743 base64_encoded = false;
4745 EM_DEBUG_EXCEPTION("unknown encoding found...");
4747 err = EMAIL_ERROR_UNKNOWN;
4752 if (base64_encoded) { /* BASE64 */
4753 charset = g_strndup(start + 2, p - (start + 2));
4754 encoded_text = g_strndup(p + 3, end - (p + 3));
4756 else { /* QUOTED-PRINTABLE */
4757 charset = g_strndup(start + 2, p - (start + 2));
4758 if (*(p+3) == '=') { /* encoded text might start with '='. ex) '?Q?=E0' */
4759 end = strstr(p+3, "?="); /* find new end flag */
4761 encoded_text = g_strndup(p + 3, end - (p + 3));
4763 else { /* end flag is not found */
4764 EM_DEBUG_EXCEPTION("emcore_decode_rfc2047_word decoding error : '?=' is not found...");
4766 err = EMAIL_ERROR_UNKNOWN;
4771 encoded_text = g_strndup(p + 3, end - (p + 3));
4775 #ifdef FEATURE_CORE_DEBUG
4776 EM_DEBUG_LOG("\t >>>>>>>>>>>>>>> CHARSET[%s]", charset);
4777 EM_DEBUG_LOG("\t >>>>>>>>>>>>>>> ENCODED_TEXT[%s]", encoded_text);
4780 unsigned long len = 0;
4781 if (encoded_text != NULL) {
4782 if (base64_encoded == true) {
4783 if (!(decoded_text = (char *)rfc822_base64((unsigned char *)encoded_text, EM_SAFE_STRLEN(encoded_text), &len))) {
4784 EM_DEBUG_EXCEPTION("rfc822_base64 falied...");
4789 g_strdelimit(encoded_text, "_", ' ');
4791 if (!(decoded_text = (char *)rfc822_qprint((unsigned char *)encoded_text, EM_SAFE_STRLEN(encoded_text), &len))) {
4792 EM_DEBUG_EXCEPTION("rfc822_base64 falied...");
4797 src.data = (unsigned char *)decoded_text;
4798 src.size = EM_SAFE_STRLEN(decoded_text);
4800 if (!utf8_text(&src, charset, &dst, 0)) {
4801 EM_DEBUG_EXCEPTION("utf8_text falied...");
4803 strncat(buffer, (char *)src.data, src.size); /* Eventhough failed to decode, downloading should go on. Kyuho Jo */
4806 strncat(buffer, (char *)dst.data, dst.size);
4808 #ifdef FEATURE_CORE_DEBUG
4809 EM_DEBUG_LOG("2 - Buffer[%s]", buffer);
4812 /* free all of the temp variables */
4813 if (dst.data != NULL && dst.data != src.data)
4814 EM_SAFE_FREE(dst.data);
4816 EM_SAFE_FREE(decoded_text);
4818 g_free(encoded_text);
4819 encoded_text = NULL;
4821 if (charset != NULL) {
4826 current = end + 2; /* skip '?=' */
4829 /* unencoded text */
4830 length = EM_SAFE_STRLEN(start);
4831 strncat(buffer, start, length);
4832 current = start + length;
4833 #ifdef FEATURE_CORE_DEBUG
4834 EM_DEBUG_LOG("3 - Buffer[%s]", buffer);
4839 /* unencoded text */
4840 length = EM_SAFE_STRLEN(current);
4841 strncat(buffer, current, length);
4842 current = current + length;
4843 #ifdef FEATURE_CORE_DEBUG
4844 EM_DEBUG_LOG("4 - Buffer[%s]", buffer);
4849 decoded_word = EM_SAFE_STRDUP(buffer);
4851 #ifdef FEATURE_CORE_DEBUG
4852 EM_DEBUG_LOG(">>>>>>>>>>>>>>> DECODED_WORD[%s]", decoded_word);
4856 if (dst.data != NULL && dst.data != src.data)
4857 EM_SAFE_FREE(dst.data);
4858 EM_SAFE_FREE(decoded_text);
4859 EM_SAFE_FREE(buffer);
4861 if (encoded_text != NULL)
4862 g_free(encoded_text);
4863 if (charset != NULL)
4866 if (err_code != NULL)
4869 EM_DEBUG_FUNC_END();
4870 return decoded_word;
4873 INTERNAL_FUNC char *emcore_decode_rfc2047_text(char *rfc2047_text, int *err_code)
4875 EM_DEBUG_FUNC_BEGIN("rfc2047_text[%s], err_code[%p]", rfc2047_text, err_code);
4878 int err = EMAIL_ERROR_NONE;
4880 if (!rfc2047_text) {
4881 EM_DEBUG_EXCEPTION("rfc2047_text[%p]", rfc2047_text);
4882 if (err_code != NULL)
4883 *err_code = EMAIL_ERROR_INVALID_PARAM;
4889 gchar **encoded_words = g_strsplit_set(rfc2047_text, " \t\r\n", -1);
4890 gchar **decoded_words = g_new0(char *, g_strv_length(encoded_words) + 1);
4892 /* EM_DEBUG_LOG("g_strv_length(encoded_words) [%d]", g_strv_length(encoded_words)); */
4894 if (encoded_words != NULL) {
4897 while (encoded_words[i] != NULL) {
4898 if (!(decoded_words[i] = emcore_decode_rfc2047_word(encoded_words[i], &err))) {
4899 EM_DEBUG_EXCEPTION("emcore_decode_rfc2047_word falied [%d]", err);
4905 text = g_strjoinv(" ", decoded_words);
4908 text = EM_SAFE_STRDUP(rfc2047_text);
4910 #ifdef FEATURE_CORE_DEBUG
4911 EM_DEBUG_LOG(">>>>>>>>>>>>>>>>> TEXT[%s]", text);
4912 #endif /* FEATURE_CORE_DEBUG */
4917 g_strfreev(decoded_words);
4918 g_strfreev(encoded_words);
4920 if (err_code != NULL)
4922 EM_DEBUG_FUNC_END();
4926 INTERNAL_FUNC int emcore_make_mail_data_from_mime_data(struct _m_mesg *mmsg, struct _m_content_info *cnt_info, email_mail_data_t **output_mail_data, email_attachment_data_t **output_attachment_data, int *output_attachment_count, int *err_code)
4928 EM_DEBUG_FUNC_BEGIN();
4930 int err = EMAIL_ERROR_NONE;
4931 int local_attachment_count = 0;
4932 int local_inline_content_count = 0;
4933 int attachment_num = 0;
4935 int eml_mail_id = 0;
4937 char html_body[MAX_PATH] = {0, };
4938 struct tm temp_time_info;
4940 struct attachment_info *ai = NULL;
4941 char *encoded_subject = NULL;
4942 email_attachment_data_t *attachment = NULL;
4943 email_mail_data_t *p_mail_data = NULL;
4944 MESSAGECACHE mail_cache_element = {0, };
4946 if (!mmsg || !cnt_info || !output_mail_data || !output_attachment_data) {
4947 EM_DEBUG_EXCEPTION("Invalid parameter");
4948 err = EMAIL_ERROR_INVALID_PARAM;
4952 p_mail_data = (email_mail_data_t *)em_malloc(sizeof(email_mail_data_t));
4953 if (p_mail_data == NULL) {
4954 EM_DEBUG_EXCEPTION("em_malloc failed");
4955 err = EMAIL_ERROR_OUT_OF_MEMORY;
4959 memset(&mail_cache_element, 0x00, sizeof(MESSAGECACHE));
4960 memset((void *)&temp_time_info, 0, sizeof(struct tm));
4962 /* Create rand mail id of eml */
4963 gettimeofday(&tv, NULL);
4965 eml_mail_id = rand();
4967 p_mail_data->mail_id = eml_mail_id;
4968 p_mail_data->account_id = EML_FOLDER;
4970 if (mmsg->rfc822header->date)
4971 mail_parse_date(&mail_cache_element, (unsigned char *)mmsg->rfc822header->date);
4973 temp_time_info.tm_sec = mail_cache_element.seconds;
4974 temp_time_info.tm_min = mail_cache_element.minutes - mail_cache_element.zminutes;
4975 temp_time_info.tm_hour = mail_cache_element.hours - mail_cache_element.zhours;
4977 if (mail_cache_element.hours - mail_cache_element.zhours < 0) {
4978 temp_time_info.tm_mday = mail_cache_element.day - 1;
4979 temp_time_info.tm_hour += 24;
4981 temp_time_info.tm_mday = mail_cache_element.day;
4983 temp_time_info.tm_mon = mail_cache_element.month - 1;
4984 temp_time_info.tm_year = mail_cache_element.year + 70;
4986 encoded_subject = emcore_decode_rfc2047_text(mmsg->rfc822header->subject, NULL);
4988 p_mail_data->date_time = timegm(&temp_time_info);
4989 p_mail_data->full_address_return = EM_SAFE_STRDUP(mmsg->rfc822header->return_path);
4990 p_mail_data->email_address_recipient = EM_SAFE_STRDUP(mmsg->rfc822header->received);
4991 p_mail_data->full_address_from = EM_SAFE_STRDUP(mmsg->rfc822header->from);
4992 p_mail_data->subject = EM_SAFE_STRDUP(encoded_subject);
4993 p_mail_data->email_address_sender = EM_SAFE_STRDUP(mmsg->rfc822header->sender);
4994 p_mail_data->full_address_to = EM_SAFE_STRDUP(mmsg->rfc822header->to);
4995 p_mail_data->full_address_cc = EM_SAFE_STRDUP(mmsg->rfc822header->cc);
4996 p_mail_data->full_address_bcc = EM_SAFE_STRDUP(mmsg->rfc822header->bcc);
4997 p_mail_data->full_address_reply = EM_SAFE_STRDUP(mmsg->rfc822header->reply_to);
4998 p_mail_data->body_download_status = EMAIL_BODY_DOWNLOAD_STATUS_FULLY_DOWNLOADED;
5000 EM_DEBUG_LOG("cnt_info->text.plain [%s], cnt_info->text.html [%s]", cnt_info->text.plain, cnt_info->text.html);
5002 if (cnt_info->text.plain) {
5003 EM_DEBUG_LOG("cnt_info->text.plain [%s]", cnt_info->text.plain);
5004 if (!emstorage_create_dir(EML_FOLDER, eml_mail_id, 0, &err)) {
5005 EM_DEBUG_EXCEPTION("emstorage_create_dir failed [%d]", err);
5009 if (!emstorage_get_save_name(EML_FOLDER, eml_mail_id, 0, cnt_info->text.plain_charset ? cnt_info->text.plain_charset : UNKNOWN_CHARSET_PLAIN_TEXT_FILE, buf, &err)) {
5010 EM_DEBUG_EXCEPTION("emstorage_get_save_name failed [%d]", err);
5014 if (!emstorage_move_file(cnt_info->text.plain, buf, false, &err)) {
5015 EM_DEBUG_EXCEPTION("emstorage_move_file failed [%d]", err);
5019 p_mail_data->file_path_plain = EM_SAFE_STRDUP(buf);
5020 EM_DEBUG_LOG("mail_data->file_path_plain [%s]", p_mail_data->file_path_plain);
5023 if (cnt_info->text.html) {
5024 if (!emstorage_create_dir(EML_FOLDER, eml_mail_id, 0, &err)) {
5025 EM_DEBUG_EXCEPTION("emstorage_create_dir failed [%d]", err);
5029 if (cnt_info->text.plain_charset != NULL) {
5030 SNPRINTF(html_body, MAX_PATH, "%s%s", cnt_info->text.plain_charset, HTML_EXTENSION_STRING);
5033 strcpy(html_body, UNKNOWN_CHARSET_HTML_TEXT_FILE);
5037 if (!emstorage_get_save_name(EML_FOLDER, eml_mail_id, 0, html_body, buf, &err)) {
5038 EM_DEBUG_EXCEPTION("emstorage_get_save_name failed [%d]", err);
5042 if (!emstorage_move_file(cnt_info->text.html, buf, false, &err)) {
5043 EM_DEBUG_EXCEPTION("emstorage_move_file failed [%d]", err);
5046 p_mail_data->file_path_html = EM_SAFE_STRDUP(buf);
5050 for (ai = cnt_info->file; ai; ai = ai->next, attachment_num++) {}
5051 EM_DEBUG_LOG("attachment_num : [%d]", attachment_num);
5053 if (attachment_num > 0) {
5054 attachment = (email_attachment_data_t *)em_malloc(sizeof(email_attachment_data_t) * attachment_num);
5055 if (attachment == NULL) {
5056 EM_DEBUG_EXCEPTION("em_malloc failed");
5057 err = EMAIL_ERROR_OUT_OF_MEMORY;
5061 for (ai = cnt_info->file; ai; ai = ai->next, i++) {
5062 attachment[i].attachment_id = 0;
5063 attachment[i].attachment_size = ai->size;
5064 attachment[i].attachment_name = EM_SAFE_STRDUP(ai->name);
5065 attachment[i].drm_status = ai->drm;
5066 attachment[i].save_status = 0;
5067 attachment[i].inline_content_status = ai->type == 1;
5068 attachment[i].attachment_mime_type = ai->attachment_mime_type;
5069 #ifdef __ATTACHMENT_OPTI__
5070 attachment[i].encoding = ai->encoding;
5071 attachment[i].section = ai->section;
5073 EM_DEBUG_LOG("attachment[%d].attachment_id[%d]", i, attachment[i].attachment_id);
5074 EM_DEBUG_LOG("attachment[%d].attachment_size[%d]", i, attachment[i].attachment_size);
5075 EM_DEBUG_LOG("attachment[%d].attachment_name[%s]", i, attachment[i].attachment_name);
5076 EM_DEBUG_LOG("attachment[%d].drm_status[%d]", i, attachment[i].drm_status);
5077 EM_DEBUG_LOG("attachment[%d].inline_content_status[%d]", i, attachment[i].inline_content_status);
5080 local_inline_content_count ++;
5081 local_attachment_count++;
5084 attachment[i].save_status = 1;
5085 if (ai->type == 1) { /* it is inline content */
5086 if (!emstorage_create_dir(EML_FOLDER, eml_mail_id, 0, &err)) {
5087 EM_DEBUG_EXCEPTION("emstorage_create_dir failed [%d]", err);
5090 if (!emstorage_get_save_name(EML_FOLDER, eml_mail_id, 0, attachment[i].attachment_name, buf, &err)) {
5091 EM_DEBUG_EXCEPTION("emstorage_get_save_name failed [%d]", err);
5096 if (!emstorage_create_dir(EML_FOLDER, eml_mail_id, i, &err)) {
5097 EM_DEBUG_EXCEPTION("emstorage_create_dir failed [%d]", err);
5101 if (!emstorage_get_save_name(EML_FOLDER, eml_mail_id, i, attachment[i].attachment_name, buf, &err)) {
5102 EM_DEBUG_EXCEPTION("emstorage_get_save_name failed [%d]", err);
5107 if (!emstorage_move_file(ai->save, buf, false, &err)) {
5108 EM_DEBUG_EXCEPTION("emstorage_move_file failed [%d]", err);
5110 /* delete all created files. */
5111 if (!emstorage_get_save_name(EML_FOLDER, eml_mail_id, 0, NULL, buf, NULL)) {
5112 EM_DEBUG_EXCEPTION("emstorage_get_save_name failed...");
5113 /* goto FINISH_OFF; */
5116 if (!emstorage_delete_dir(buf, NULL)) {
5117 EM_DEBUG_EXCEPTION("emstorage_delete_dir failed...");
5118 /* goto FINISH_OFF; */
5125 attachment[i].attachment_path = EM_SAFE_STRDUP(buf);
5129 EM_DEBUG_LOG("attachment[%d].attachment_path[%s]", i, attachment[i].attachment_path);
5132 EM_DEBUG_LOG("Check #1");
5134 p_mail_data->attachment_count = local_attachment_count;
5135 p_mail_data->inline_content_count = local_inline_content_count;
5137 eml_data_count += 1;
5143 if (output_mail_data)
5144 *output_mail_data = p_mail_data;
5146 if (output_attachment_data)
5147 *output_attachment_data = attachment;
5149 if (output_attachment_count)
5150 *output_attachment_count = local_attachment_count;
5153 emcore_free_mail_data(p_mail_data);
5154 EM_SAFE_FREE(p_mail_data);
5158 emcore_free_attachment_data(&attachment, attachment_num, NULL);
5161 EM_SAFE_FREE(encoded_subject);
5166 EM_DEBUG_FUNC_END("ret : [%d]", ret);
5170 INTERNAL_FUNC int emcore_parse_mime_file_to_mail(char *eml_file_path, email_mail_data_t **output_mail_data, email_attachment_data_t **output_attachment_data, int *output_attachment_count, int *err_code)
5172 EM_DEBUG_FUNC_BEGIN("eml_file_path : [%s], output_mail_data : [%p]", eml_file_path, output_mail_data);
5174 int err = EMAIL_ERROR_NONE;
5177 FILE *eml_fp = NULL;
5178 struct _m_content_info *cnt_info = NULL;
5179 struct _m_mesg *mmsg = NULL;
5182 if (!eml_file_path || !output_mail_data || !output_attachment_data || !output_attachment_count) {
5183 EM_DEBUG_EXCEPTION("Invalid paramter");
5184 err = EMAIL_ERROR_INVALID_PARAM;
5188 cnt_info = (struct _m_content_info *)em_malloc(sizeof(struct _m_content_info));
5189 if (cnt_info == NULL) {
5190 EM_DEBUG_EXCEPTION("em_malloc failed...");
5191 err = EMAIL_ERROR_OUT_OF_MEMORY;
5195 cnt_info->grab_type = GRAB_TYPE_TEXT | GRAB_TYPE_ATTACHMENT;
5197 mmsg = (struct _m_mesg *)em_malloc(sizeof(struct _m_mesg));
5199 EM_DEBUG_EXCEPTION("em_malloc failed");
5200 err = EMAIL_ERROR_OUT_OF_MEMORY;
5204 eml_fp = fopen(eml_file_path, "r");
5205 if (eml_fp == NULL) {
5206 EM_DEBUG_EXCEPTION("file open failed");
5207 err = EMAIL_ERROR_ON_PARSING;
5211 if (!emcore_mime_parse_header(eml_fp, is_file, &mmsg->rfc822header, &mmsg->header, &err)) {
5212 EM_DEBUG_EXCEPTION("emcore_mime_parse_header failed : [%d]", err);
5216 if (!mmsg->header->part_header) {
5217 EM_DEBUG_EXCEPTION("Invalid eml format");
5218 err = EMAIL_ERROR_INVALID_DATA;
5222 if (!emcore_mime_parse_body(eml_fp, is_file, mmsg, cnt_info, NULL, &err)) {
5223 EM_DEBUG_EXCEPTION("emcore_mime_parse_body failed : [%d]", err);
5227 if (!emcore_make_mail_data_from_mime_data(mmsg, cnt_info, output_mail_data, output_attachment_data, output_attachment_count, &err)) {
5228 EM_DEBUG_EXCEPTION("emcore_make_mail_tbl_data_from_mime failed : [%d]", err);
5241 emcore_mime_free_mime(mmsg);
5244 emcore_free_content_info(cnt_info);
5249 EM_DEBUG_FUNC_END("err : %d", err);
5253 INTERNAL_FUNC int emcore_delete_parsed_data(email_mail_data_t *input_mail_data, int *err_code)
5255 EM_DEBUG_FUNC_BEGIN("input_mail_data : [%p]", input_mail_data);
5256 int err = EMAIL_ERROR_NONE;
5260 if (!input_mail_data) {
5261 EM_DEBUG_EXCEPTION("Invliad parameter");
5262 err = EMAIL_ERROR_INVALID_PARAM;
5266 if ((input_mail_data->account_id != EML_FOLDER) && (!input_mail_data->mail_id)) {
5267 EM_DEBUG_EXCEPTION("Invliad parameter: account_id[%d], mail_id[%d]", input_mail_data->account_id, input_mail_data->mail_id);
5268 err = EMAIL_ERROR_INVALID_PARAM;
5272 eml_data_count = eml_data_count - 1;
5274 if (eml_data_count == 0) {
5275 SNPRINTF(buf, sizeof(buf), "%s%s%d", MAILHOME, DIR_SEPERATOR, input_mail_data->account_id);
5277 SNPRINTF(buf, sizeof(buf), "%s%s%d%s%d", MAILHOME, DIR_SEPERATOR, input_mail_data->account_id, DIR_SEPERATOR, input_mail_data->mail_id);
5280 EM_DEBUG_LOG("Directory : [%s]", buf);
5282 if (!emstorage_delete_dir(buf, &err)) {
5283 EM_DEBUG_EXCEPTION("emstorage_delete_dir failed");
5297 INTERNAL_FUNC int emcore_get_mime_entity(char *mime_path, char **output_path, int *err_code)
5299 EM_DEBUG_FUNC_BEGIN("mime_path : [%s], output_path : [%p]", mime_path, *output_path);
5301 int err = EMAIL_ERROR_NONE;
5304 long start_mime_entity = 0;
5305 long end_mime_entity = 0;
5306 char buf[MIME_LINE_LEN] = {0x00, };
5307 char *mime_entity_path = NULL;
5308 char *content_type = NULL;
5309 char boundary[BOUNDARY_LEN] = {0x00,};
5310 char *boundary_string = NULL;
5311 char *p_mime_entity = NULL;
5312 FILE *fp_read = NULL;
5313 FILE *fp_write = NULL;
5314 struct _m_mesg *mmsg = NULL;
5317 EM_DEBUG_EXCEPTION("Invalid parameter");
5318 err = EMAIL_ERROR_INVALID_PARAM;
5322 /* Get the header info */
5323 mmsg = (struct _m_mesg *)em_malloc(sizeof(struct _m_mesg));
5325 EM_DEBUG_EXCEPTION("em_malloc failed");
5326 err = EMAIL_ERROR_OUT_OF_MEMORY;
5330 fp_read = fopen(mime_path, "r");
5331 if (fp_read == NULL) {
5332 EM_DEBUG_EXCEPTION("File open(read) is failed : filename [%s]", mime_path);
5333 err = EMAIL_ERROR_SYSTEM_FAILURE;
5337 if (!emcore_mime_parse_header(fp_read, is_file, &mmsg->rfc822header, &mmsg->header, &err)) {
5338 EM_DEBUG_EXCEPTION("emcore_mime_parse_header failed : [%d]", err);
5342 /* Parsing the mime header */
5343 content_type = emcore_mime_get_header_value(mmsg->header->part_header, CONTENT_TYPE, NULL);
5344 EM_DEBUG_LOG("Content_type : [%s]", content_type);
5345 if (strcasestr(content_type, "signed") == NULL) {
5346 EM_DEBUG_EXCEPTION("Invalid parameter : No signed mail");
5347 err = EMAIL_ERROR_INVALID_PARAM;
5351 /* Create mime_entity file */
5352 if (!emcore_get_temp_file_name(&mime_entity_path, &err)) {
5353 EM_DEBUG_EXCEPTION("emcore_get_temp_file_name failed[%d]", err);
5356 EM_DEBUG_LOG("mime_entity_path = %s", mime_entity_path);
5358 fp_write = fopen(mime_entity_path, "w");
5359 if (fp_write == NULL) {
5360 EM_DEBUG_EXCEPTION("File open(write) is failed : filename [%s]", mime_entity_path);
5361 err = EMAIL_ERROR_SYSTEM_FAILURE;
5365 boundary_string = emcore_mime_get_header_value(mmsg->header->part_header, CONTENT_BOUNDARY, NULL);
5366 SNPRINTF(boundary, BOUNDARY_LEN, "--%s%s", boundary_string, CRLF_STRING);
5369 if (!emcore_get_line_from_file((void *)fp_read, buf, MIME_LINE_LEN, &err)) {
5370 EM_DEBUG_EXCEPTION("emcore_mime_get_line_from_file failed [%d]", err);
5371 EM_DEBUG_LOG("this mail is partial body");
5372 err = EMAIL_ERROR_INVALID_MAIL;
5376 if (!strcmp(buf, boundary)) {
5379 start_mime_entity = ftell(fp_read);
5380 if( start_mime_entity < 0 ) { /*prevent 24473*/
5381 EM_DEBUG_EXCEPTION("ftell failed [%s]", EM_STRERROR(errno));
5384 } else if (search == 2) {
5385 end_mime_entity = ftell(fp_read);
5386 if( end_mime_entity < 0 ) { /*prevent 24473*/
5387 EM_DEBUG_EXCEPTION("ftell failed [%s]", EM_STRERROR(errno));
5395 p_mime_entity = em_malloc(end_mime_entity - start_mime_entity);
5396 if (p_mime_entity == NULL) {
5397 EM_DEBUG_EXCEPTION("em_malloc failed");
5398 err = EMAIL_ERROR_OUT_OF_MEMORY;
5402 if (fseek(fp_read, start_mime_entity, SEEK_SET) < 0) {
5403 EM_DEBUG_EXCEPTION("fseek failed");
5404 err = EMAIL_ERROR_SYSTEM_FAILURE;
5408 /* +2 : CRLF line */
5409 if ((ret = fread(p_mime_entity, 1, end_mime_entity - (start_mime_entity + EM_SAFE_STRLEN(boundary) + 2), fp_read)) < 0) {
5410 EM_DEBUG_EXCEPTION("fread failed");
5411 err = EMAIL_ERROR_SYSTEM_FAILURE;
5415 fprintf(fp_write, "%s", p_mime_entity);
5428 emcore_mime_free_mime(mmsg);
5431 *output_path = mime_entity_path;
5436 EM_SAFE_FREE(p_mime_entity);
5438 EM_DEBUG_FUNC_END();
5442 int emcore_decode_body_text_from_file(FILE *stream, char *boundary_str, int encoding, int mode, int is_text, int fd, char **holder, int *end_of_parsing, int *size)
5444 EM_DEBUG_FUNC_BEGIN();
5445 int error = EMAIL_ERROR_NONE;
5446 int start_location = 0;
5447 int end_location = 0;
5449 int partial_body = 0;
5451 char boundary[BOUNDARY_LEN] = {0x00, };
5452 char boundary_end[BOUNDARY_LEN] = {0x00, };
5453 char buf[MIME_LINE_LEN] = {0x00, };
5455 int modified_body_size = 0;
5456 char *modified_body = NULL;
5459 /* if there boundary, this content is from current line to ending boundary */
5460 memset(boundary, 0x00, BOUNDARY_LEN);
5461 memset(boundary_end, 0x00, BOUNDARY_LEN);
5463 SNPRINTF(boundary, BOUNDARY_LEN, "--%s%s", boundary_str, CRLF_STRING);
5464 SNPRINTF(boundary_end, BOUNDARY_LEN, "--%s%s", boundary_str, "--\r\n");
5467 start_location = ftell(stream);
5470 if (!emcore_get_line_from_file(stream, buf, MIME_LINE_LEN, &error)) {
5471 if (error != EMAIL_ERROR_NO_MORE_DATA) {
5472 EM_DEBUG_EXCEPTION("emcore_get_line_from_file failed");
5473 error = EMAIL_ERROR_SYSTEM_FAILURE;
5478 *end_of_parsing = 1;
5483 if (!strcmp(buf, boundary)) { /* the other part started. the parsing of other part will be started */
5484 *end_of_parsing = 0;
5487 else if (!strcmp(buf, boundary_end)) { /* if ending boundary, the parsing of other multipart will be started */
5488 *end_of_parsing = 1;
5494 end_location = ftell(stream);
5497 p_size = end_location - start_location;
5499 p_size = end_location - start_location - EM_SAFE_STRLEN(buf);
5501 body = em_malloc(p_size + 1);
5503 EM_DEBUG_EXCEPTION("em_malloc failed");
5504 error = EMAIL_ERROR_OUT_OF_MEMORY;
5508 fseek(stream, start_location, SEEK_SET);
5509 if (fread(body, sizeof(char), p_size, stream) != p_size) {
5510 EM_DEBUG_EXCEPTION("fread failed");
5511 error = EMAIL_ERROR_SYSTEM_FAILURE;
5515 if (mode > SAVE_TYPE_SIZE) { /* decode content */
5516 emcore_decode_body_text(body, p_size, encoding, &dec_len, &error);
5519 modified_body = em_replace_all_string(body, "cid:", "");
5521 modified_body_size = EM_SAFE_STRLEN(modified_body);
5524 if (modified_body == NULL) {
5525 modified_body = body;
5526 modified_body_size = dec_len;
5529 if (mode == SAVE_TYPE_BUFFER) { /* save content to buffer */
5530 *holder = EM_SAFE_STRDUP(modified_body);
5531 } else if (mode == SAVE_TYPE_FILE) { /* save content to file */
5532 if (write(fd, modified_body, modified_body_size) != modified_body_size) {
5533 EM_DEBUG_EXCEPTION("write failed");
5534 error = EMAIL_ERROR_SYSTEM_FAILURE;
5540 fseek((FILE *)stream, end_location, SEEK_SET);
5544 EM_SAFE_FREE(modified_body);
5548 int emcore_decode_body_text_from_sock(void *stream, char *boundary_str, int encoding, int mode, int is_text, int fd, char **holder, int *end_of_parsing, int *size)
5550 EM_DEBUG_FUNC_BEGIN();
5551 int error = EMAIL_ERROR_NONE;
5554 char boundary[BOUNDARY_LEN] = {0x00, };
5555 char boundary_end[BOUNDARY_LEN] = {0x00, };
5556 char buf[MIME_LINE_LEN] = {0x00, };
5557 char *result_buffer = NULL;
5558 int result_buffer_size = 0;
5562 /* if there boundary, this content is from current line to ending boundary */
5563 memset(boundary, 0x00, BOUNDARY_LEN);
5564 memset(boundary_end, 0x00, BOUNDARY_LEN);
5566 SNPRINTF(boundary, BOUNDARY_LEN, "--%s%s", boundary_str, CRLF_STRING);
5567 SNPRINTF(boundary_end, BOUNDARY_LEN, "--%s%s", boundary_str, "--\r\n");
5571 if (!emcore_check_thread_status()) {
5572 EM_DEBUG_EXCEPTION("EMAIL_ERROR_CANCELLED");
5573 error = EMAIL_ERROR_CANCELLED;
5577 if (!emcore_mime_get_line_from_sock(stream, buf, MIME_LINE_LEN, &error)) {
5578 if (error != EMAIL_ERROR_NO_MORE_DATA) {
5579 EM_DEBUG_EXCEPTION("emcore_mime_get_line_from_sock failed");
5580 error = EMAIL_ERROR_SYSTEM_FAILURE;
5584 EM_DEBUG_LOG("This mail is partial body");
5586 *end_of_parsing = 1;
5588 error = EMAIL_ERROR_NONE;
5594 if (!strcmp(buf, boundary)) { /* the other part started. the parsing of other part will be started */
5595 *end_of_parsing = 0;
5598 else if (!strcmp(buf, boundary_end)) { /* if ending boundary, the parsing of other multipart will be started */
5599 *end_of_parsing = 1;
5604 /* parsing string started by '.' in POP3 */
5605 if ((buf[0] == '.' && buf[1] == '.') && (encoding == ENCQUOTEDPRINTABLE || encoding == ENC7BIT)) {
5606 strncpy(buf, buf+1, MIME_LINE_LEN-1);
5607 buf[EM_SAFE_STRLEN(buf)] = NULL_CHAR;
5610 if (encoding == ENCBASE64) {
5611 if (EM_SAFE_STRLEN(buf) >= 2)
5612 buf[EM_SAFE_STRLEN(buf)-2] = NULL_CHAR;
5613 } else if (encoding == ENCQUOTEDPRINTABLE) {
5614 /* if (strcmp(buf, CRLF_STRING) == 0 */
5618 dec_len = EM_SAFE_STRLEN(buf);
5620 if (mode > SAVE_TYPE_SIZE) { /* decode content */
5621 emcore_decode_body_text(buf, dec_len, encoding, &dec_len, &error);
5624 result_buffer = em_replace_string(buf, "cid:", "");
5626 result_buffer_size = EM_SAFE_STRLEN(result_buffer);
5629 if (result_buffer == NULL) {
5630 result_buffer = buf;
5631 result_buffer_size = dec_len;
5634 if (mode == SAVE_TYPE_BUFFER) { /* save content to buffer */
5635 pTemp = realloc(*holder, sz + result_buffer_size + 2);
5637 EM_DEBUG_EXCEPTION("realloc failed...");
5638 error = EMAIL_ERROR_OUT_OF_MEMORY;
5640 EM_SAFE_FREE(*holder);
5641 EM_SAFE_FREE(result_buffer);
5647 memcpy(*holder + sz, result_buffer, result_buffer_size);
5648 (*holder)[sz + EM_SAFE_STRLEN(result_buffer) + 1] = NULL_CHAR;
5649 } else if (mode == SAVE_TYPE_FILE) { /* save content to file */
5650 if (write(fd, result_buffer, result_buffer_size) != result_buffer_size) {
5651 if (is_text && (result_buffer != buf))
5652 EM_SAFE_FREE(result_buffer);
5653 EM_DEBUG_EXCEPTION("write failed");
5654 error = EMAIL_ERROR_SYSTEM_FAILURE;
5659 if (is_text && (result_buffer != buf))
5660 EM_SAFE_FREE(result_buffer);
5661 result_buffer = NULL;
5668 if (error == EMAIL_ERROR_NONE) {
5673 EM_DEBUG_FUNC_END("error [%d], sz[%d]", error, sz);