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.
26 #include <sys/types.h>
29 #include "em-core-types.h"
31 #include "em-core-global.h"
32 #include "em-core-utils.h"
33 #include "em-storage.h"
34 #include "em-core-api.h"
35 #include "em-core-smtp.h"
36 #include "em-core-event.h"
37 #include "em-core-mailbox.h"
38 #include "em-core-mesg.h"
39 #include "em-core-mime.h"
40 #include "em-core-account.h"
41 #include "em-core-imap-mailbox.h"
42 #include "em-core-mailbox-sync.h"
43 #include "Msg_Convert.h"
47 #include "emf-dbglog.h"
50 /* Functions from uw-imap-toolkit */
51 /* extern void *fs_get(size_t size); */
52 extern void rfc822_date(char *date);
53 extern long smtp_soutr(void *stream, char *s);
54 extern long smtp_send(SENDSTREAM *stream, char *command, char *args);
55 extern long smtp_rcpt(SENDSTREAM *stream, ADDRESS *adr, long* error);
57 #ifdef __FEATURE_SEND_OPTMIZATION__
58 extern long smtp_soutr_test(void *stream, char *s);
62 static int em_core_mail_get_report_body(ENVELOPE *envelope, BODY **multipart_body, int *err_code);
63 static int em_core_mail_send_smtp(SENDSTREAM *stream, ENVELOPE *env, char *data_file, int account_id, int mail_id, int *err_code);
65 void mail_send_notify(emf_send_status_t status, int total, int sent, int account_id, int mail_id, int err_code)
67 EM_DEBUG_FUNC_BEGIN("status[%d], total[%d], sent[%d], account_id[%d], mail_id[%d], err_code[%d]", status, total, sent, account_id, mail_id, err_code);
70 case EMF_SEND_CONNECTION_FAIL:
75 case EMF_SEND_PROGRESS:
79 em_core_execute_event_callback(EMF_ACTION_SEND_MAIL, total, sent, status, account_id, mail_id, -1, err_code);
83 /* ------ rfc822 handle ---------------------------------------------------*/
84 long buf_flush(void *stream, char *string)
86 EM_DEBUG_FUNC_BEGIN("stream[%p], string[%s]", stream, string);
92 #define RFC822_READ_BLOCK_SIZE 1024
93 #define RFC822_STRING_BUFFER_SIZE 1536
95 static char *em_core_find_img_tag(char *source_string)
97 EM_DEBUG_FUNC_BEGIN("source_string[%p]", source_string);
99 int cur = 0, string_length;
103 string_length = strlen(source_string);
105 for (cur = 0; cur < string_length; cur++) {
106 if (source_string[cur] == 'I' || source_string[cur] == 'i') {
108 if (source_string[cur] == 'M' || source_string[cur] == 'm') {
110 if (source_string[cur] == 'G' || source_string[cur] == 'g') {
111 EM_DEBUG_FUNC_END("%s", source_string + cur - 2);
112 return source_string + cur - 2;
117 EM_DEBUG_FUNC_END("Can't find");
121 #define CONTENT_ID_BUFFER_SIZE 512
122 static char *em_core_replace_inline_image_path_with_content_id(char *source_string, BODY *html_body, int *err_code)
124 EM_DEBUG_FUNC_BEGIN("source_string[%p], html_body[%p], err_code[%p]", source_string, html_body, err_code);
126 int err = EMF_ERROR_NONE;
127 char content_id_buffer[CONTENT_ID_BUFFER_SIZE], file_name_buffer[512], new_string[512], *result_string = NULL, *input_string = NULL;
128 BODY *cur_body = NULL;
129 PART *cur_part = NULL;
131 if (!source_string || !html_body) {
132 EM_DEBUG_EXCEPTION("EMF_ERROR_INVALID_PARAM");
133 err = EMF_ERROR_INVALID_PARAM;
137 input_string = EM_SAFE_STRDUP(source_string);
139 cur_part = html_body->nested.part;
142 cur_body = &(cur_part->body);
144 EM_DEBUG_LOG("Has body. id[%s]", cur_body->disposition.type);
145 if (cur_body->disposition.type && cur_body->disposition.type[0] == 'i') { /* Is inline content? */
146 EM_DEBUG_LOG("Has inline content");
147 memset(content_id_buffer, 0, CONTENT_ID_BUFFER_SIZE);
149 EM_SAFE_STRNCPY(content_id_buffer, cur_body->id + 1, CONTENT_ID_BUFFER_SIZE - 1); /* Removing <, > */
150 content_id_buffer[strlen(content_id_buffer) - 1] = NULL_CHAR;
151 /* if (em_core_get_attribute_value_of_body_part(cur_body->parameter, "name", file_name_buffer, CONTENT_ID_BUFFER_SIZE, false, &err)) { */
152 if (em_core_get_attribute_value_of_body_part(cur_body->parameter, "name", file_name_buffer, CONTENT_ID_BUFFER_SIZE, true, &err)) {
153 EM_DEBUG_LOG("Content-ID[%s], filename[%s]", content_id_buffer, file_name_buffer);
154 SNPRINTF(new_string, CONTENT_ID_BUFFER_SIZE, "cid:%s", content_id_buffer);
155 result_string = em_core_replace_string(input_string, file_name_buffer, new_string);
157 EM_SAFE_FREE(input_string);
163 input_string = result_string;
164 cur_part = cur_part->next;
168 result_string = EM_SAFE_STRDUP(input_string);
171 EM_SAFE_FREE(input_string);
175 EM_DEBUG_FUNC_END("ret[%s]", result_string);
176 return result_string;
179 static int em_core_write_rfc822_body(BODY *body, BODY *html_body, FILE *fp, int *err_code)
181 EM_DEBUG_FUNC_BEGIN("body[%p], html_body[%p], fp[%p], err_code[%p]", body, html_body, fp, err_code);
183 PARAMETER *param = NULL;
185 char *p = NULL, *bndry = NULL, buf[1025], *replaced_string = NULL;
186 int fd, nread, nwrite, error = EMF_ERROR_NONE;
188 switch (body->type) {
190 EM_DEBUG_LOG("body->type = TYPEMULTIPART");
191 part = body->nested.part;
193 for (param = body->parameter; param; param = param->next) {
194 if (strcasecmp(param->attribute, "BOUNDARY") == 0) {
195 bndry = param->value;
201 p = buf; p[0] = '\0';
203 rfc822_write_body_header(&p, &part->body);
205 fprintf(fp, "--%s"CRLF_STRING, bndry);
206 fprintf(fp, "%s"CRLF_STRING, buf);
208 em_core_write_rfc822_body(&part->body, html_body, fp, err_code);
209 } while ((part = part->next));
211 fprintf(fp, "--%s--"CRLF_STRING, bndry);
215 EM_DEBUG_LOG("body->type is not TYPEMULTIPART");
217 char *file_path = body->sparep;
218 char buf[RFC822_STRING_BUFFER_SIZE + 1] = { 0, }, *img_tag_pos = NULL;
223 if (!file_path || strlen(file_path) == 0) {
224 EM_DEBUG_LOG("There is no file path");
225 switch (body->encoding) {
229 p = cpystr((const char *)body->contents.text.data);
230 len = body->contents.text.size;
235 EM_DEBUG_LOG("p[%s]", p);
236 fprintf(fp, "%s"CRLF_STRING CRLF_STRING, p);
240 EM_SAFE_FREE(body->sparep);
245 EM_DEBUG_LOG("Opening a file[%s]", file_path);
246 fd = open(file_path, O_RDONLY);
249 EM_DEBUG_EXCEPTION("open(\"%s\") failed...", file_path);
254 nread = read(fd, buf, (body->encoding == ENCBASE64 ? 57 : RFC822_READ_BLOCK_SIZE - 2));
269 /* EM_DEBUG_LOG("body->type[%d], body->subtype[%c]", body->type, body->subtype[0]); */
270 if (body->type == TYPETEXT && (body->subtype && (body->subtype[0] == 'H' || body->subtype[0] == 'h'))) {
271 EM_DEBUG_LOG("HTML Part");
272 img_tag_pos = em_core_find_img_tag(buf);
275 replaced_string = em_core_replace_inline_image_path_with_content_id(buf, html_body, &error);
276 if (replaced_string) {
277 EM_DEBUG_LOG("em_core_replace_inline_image_path_with_content_id succeeded");
278 strcpy(buf, replaced_string);
279 nread = len = strlen(buf);
280 EM_DEBUG_LOG("buf[%s], nread[%d], len[%d]", buf, nread, len);
283 EM_DEBUG_LOG("em_core_replace_inline_image_path_with_content_id failed[%d]", error);
287 switch (body->encoding) {
288 case ENCQUOTEDPRINTABLE:
289 p = (char *)rfc822_8bit((unsigned char *)buf, (unsigned long)nread, (unsigned long *)&len);
292 p = (char *)rfc822_binary((void *)buf, (unsigned long)nread, (unsigned long *)&len);
300 nwrite = fprintf(fp, "%s", (p ? p : buf));
306 EM_DEBUG_EXCEPTION("fprintf failed nwrite[%d], len[%d]", nwrite, len);
312 if (body->encoding == ENCQUOTEDPRINTABLE || body->encoding == ENCBASE64)
313 fprintf(fp, CRLF_STRING);
315 fprintf(fp, CRLF_STRING);
329 static int em_core_write_rfc822(ENVELOPE *env, BODY *body, BODY *html_body, emf_extra_flag_t flag, char **data, int *err_code)
331 EM_DEBUG_FUNC_BEGIN("env[%p], body[%p], data[%p], err_code[%p]", env, body, data, err_code);
334 int error = EMF_ERROR_NONE;
342 EM_DEBUG_EXCEPTION("Invalid Parameters");
343 error = EMF_ERROR_INVALID_PARAM;
349 rfc822_encode_body_7bit(env, body); /* if contents.text.data isn't NULL, the data will be encoded. */
351 /* FIXME : create memory map for this file */
352 p_len = (env->subject ? strlen(env->subject) : 0) + 8192;
354 if (!(p = em_core_malloc(p_len))) { /* (env->subject ? strlen(env->subject) : 0) + 8192))) */
355 EM_DEBUG_EXCEPTION(" malloc failed...");
356 error = EMF_ERROR_OUT_OF_MEMORY;
363 /* write at start of buffer */
364 buf.end = (buf.beg = buf.cur = p) + p_len - 1;
369 /* rfc822_output_header(&buf, env, body, NIL, T); */ /* including BCC */
370 rfc822_output_header(&buf, env, body, NIL, NIL); /* Excluding BCC */
372 *buf.cur = '\0'; /* tie off buffer */
374 gchar **tokens = g_strsplit(p, "CHARSET=X-UNKNOWN", 2);
376 if (g_strv_length(tokens) > 1) {
380 charset = g_path_get_basename(body->sparep);
382 if (charset != NULL) {
383 if ((pHtml = strstr(charset, ".htm")) != NULL)
384 charset[pHtml-charset] = '\0';
387 SNPRINTF(p, p_len, "%sCHARSET=%s%s", tokens[0], charset, tokens[1]);
391 EM_DEBUG_EXCEPTION("body->sparep is NULL");
396 gchar **tokens = g_strsplit(p, "To: undisclosed recipients: ;\015\012", 2);
397 if (g_strv_length(tokens) > 1)
398 SNPRINTF(p, p_len, "%s%s", tokens[0], tokens[1]);
403 EM_DEBUG_LOG(" =============================================================================== "
404 LF_STRING"%s"LF_STRING
405 " =============================================================================== ", p);
408 *(p + strlen(p) - 2) = '\0';
412 char buf[512] = {0x00, };
413 switch (flag.report) {
414 case EMF_MAIL_REPORT_DSN: /* DSN (delivery status) */
415 /* change content-type */
416 /* Content-Type: multipart/report; */
417 /* report-type= delivery-status; */
418 /* boundary="----=_NextPart_000_004F_01C76EFF.54275C50" */
421 case EMF_MAIL_REPORT_MDN: /* MDN (read receipt) */
422 /* Content-Type: multipart/report; */
423 /* report-type= disposition-notification; */
424 /* boundary="----=_NextPart_000_004F_01C76EFF.54275C50" */
427 case EMF_MAIL_REPORT_REQUEST: /* require read status */
428 rfc822_address(buf, env->from);
430 SNPRINTF(p + strlen(p), p_len-(strlen(p)), "Disposition-Notification-To: %s"CRLF_STRING, buf);
438 if (flag.priority) { /* priority (1:high 3:normal 5:low) */
439 SNPRINTF(p + strlen(p), p_len-(strlen(p)), "X-Priority: %d"CRLF_STRING, flag.priority);
441 switch (flag.priority) {
442 case EMF_MAIL_PRIORITY_HIGH:
443 SNPRINTF(p + strlen(p), p_len-(strlen(p)), "X-MSMail-Priority: HIgh"CRLF_STRING);
445 case EMF_MAIL_PRIORITY_NORMAL:
446 SNPRINTF(p + strlen(p), p_len-(strlen(p)), "X-MSMail-Priority: Normal"CRLF_STRING);
448 case EMF_MAIL_PRIORITY_LOW:
449 SNPRINTF(p + strlen(p), p_len-(strlen(p)), "X-MSMail-Priority: Low"CRLF_STRING);
454 SNPRINTF(p + strlen(p), p_len-(strlen(p)), CRLF_STRING);
456 if (!em_core_get_temp_file_name(&fname, &error)) {
457 EM_DEBUG_EXCEPTION(" em_core_get_temp_file_name failed[%d]", error);
461 if (!(fp = fopen(fname, "w+"))) {
462 EM_DEBUG_EXCEPTION("fopen failed[%s]", fname);
463 error = EMF_ERROR_SYSTEM_FAILURE;
467 fprintf(fp, "%s", p);
470 if (!em_core_write_rfc822_body(body, html_body, fp, &error)) {
471 EM_DEBUG_EXCEPTION("em_core_write_rfc822_body failed[%d]", error);
483 #ifdef USE_SYNC_LOG_FILE
484 em_storage_copy_file(fname, "/tmp/phone2pc.eml", false, NULL);
489 else if (fname != NULL) {
496 if (err_code != NULL)
502 static int em_core_set_current_time_to_mail_header(emf_mail_head_t *head, int *err)
504 EM_DEBUG_FUNC_BEGIN("head[%p], err [%p]", head, err);
506 int err_code = EMF_ERROR_NONE, ret = false;
507 time_t t = time(NULL);
508 struct tm *p_tm = NULL;
511 EM_DEBUG_EXCEPTION("EMF_ERROR_INVALID_PARAM");
512 err_code = EMF_ERROR_INVALID_PARAM;
519 EM_DEBUG_EXCEPTION("localtime failed...");
520 err_code = EMF_ERROR_SYSTEM_FAILURE;
524 head->datetime.year = p_tm->tm_year + 1900;
525 head->datetime.month = p_tm->tm_mon + 1;
526 head->datetime.day = p_tm->tm_mday;
527 head->datetime.hour = p_tm->tm_hour;
528 head->datetime.minute = p_tm->tm_min;
529 head->datetime.second = p_tm->tm_sec;
544 EXPORT_API int em_core_mail_save(int account_id, char *mailbox_name, emf_mail_t *mail_src, emf_meeting_request_t *meeting_req, int from_composer, int *err_code)
546 EM_DEBUG_FUNC_BEGIN("account_id[%d], mailbox_name[%p], mail_src[%p], from_composer[%d], err_code[%p]", account_id, mailbox_name, mail_src, from_composer, err_code);
548 int ret = false, err = EMF_ERROR_NONE;
549 int attachment_id = 0, mail_id = 0, thread_id = -1, thread_item_count = 0, latest_mail_id_in_thread = -1;
550 int rule_len, rule_matched = -1, local_attachment_count = 0, local_inline_content_count = 0;
551 char *ext = NULL, *mailbox_name_spam = NULL, *mailbox_name_target = NULL;
552 char name_buf[MAX_PATH] = {0x00, }, html_body[MAX_PATH] = {0x00, };
553 char datetime[DATETIME_LENGTH] = { 0, };
554 emf_mail_tbl_t *mail_table_data = NULL;
555 emf_mailbox_tbl_t *mailbox_tbl_data = NULL;
556 emf_attachment_info_t *atch = NULL;
557 emf_mail_account_tbl_t *account_tbl_item = NULL;
558 emf_mail_rule_tbl_t *rule = NULL;
559 emf_mail_attachment_tbl_t attachment_tbl = { 0 };
560 struct stat st_buf = { 0 };
562 /* Validating parameters */
564 if (!account_id || !mailbox_name || !mail_src || !mail_src->info || !mail_src->head) {
565 EM_DEBUG_EXCEPTION("EMF_ERROR_INVALID_PARAM");
566 err = EMF_ERROR_INVALID_PARAM;
570 if (!em_storage_get_account_by_id(account_id, EMF_ACC_GET_OPT_DEFAULT | EMF_ACC_GET_OPT_OPTIONS, &account_tbl_item, true, &err)) {
571 EM_DEBUG_EXCEPTION("em_storage_get_account_by_id failed. account_id[%d] err[%d]", account_id, err);
572 err = EMF_ERROR_INVALID_ACCOUNT;
577 if (!mail_src->head->from)
578 mail_src->head->from = EM_SAFE_STRDUP(account_tbl_item->email_addr);
580 /* check for email_address validation */
581 if (!em_core_verify_email_address_of_mail_header(mail_src->head, false, &err)) {
582 EM_DEBUG_EXCEPTION("em_core_verify_email_address_of_mail_header failed [%d]", err);
586 if (mail_src->info->extra_flags.report == EMF_MAIL_REPORT_MDN) {
587 /* check read-report mail */
588 if(!mail_src->head->to) { /* A report mail should have 'to' address */
589 EM_DEBUG_EXCEPTION("EMF_ERROR_INVALID_PARAM");
590 err = EMF_ERROR_INVALID_PARAM;
593 /* Create report mail body */
594 if (!em_core_mail_get_rfc822(mail_src, NULL, NULL, NULL, &err)) {
595 EM_DEBUG_EXCEPTION("em_core_mail_get_rfc822 failed [%d]", err);
600 mailbox_name_target = EM_SAFE_STRDUP(mailbox_name);
602 else { /* For Spam handling */
603 emf_option_t *opt = &account_tbl_item->options;
604 EM_DEBUG_LOG("block_address [%d], block_subject [%d]", opt->block_address, opt->block_subject);
606 if (opt->block_address || opt->block_subject) {
607 int is_completed = false;
610 if (!opt->block_address)
611 type = EMF_FILTER_SUBJECT;
612 else if (!opt->block_subject)
613 type = EMF_FILTER_FROM;
615 if (!em_storage_get_rule(ALL_ACCOUNT, type, 0, &rule_len, &is_completed, &rule, true, &err) || !rule)
616 EM_DEBUG_LOG("No proper rules. em_storage_get_rule returnes [%d]", err);
620 if (!em_storage_get_mailboxname_by_mailbox_type(account_id, EMF_MAILBOX_TYPE_SPAMBOX, &mailbox_name_spam, false, &err)) {
621 EM_DEBUG_EXCEPTION("em_storage_get_mailboxname_by_mailbox_type failed [%d]", err);
622 err = em_storage_get_emf_error_from_em_storage_error(err);
623 mailbox_name_spam = NULL;
626 if (mailbox_name_spam && !em_core_mail_check_rule(mail_src->head, rule, rule_len, &rule_matched, &err)) {
627 EM_DEBUG_EXCEPTION("em_core_mail_check_rule failed [%d]", err);
632 if (rule_matched >= 0 && mailbox_name_spam)
633 mailbox_name_target = EM_SAFE_STRDUP(mailbox_name_spam);
635 mailbox_name_target = EM_SAFE_STRDUP(mailbox_name);
638 if (!em_storage_get_mailbox_by_name(account_id, -1, mailbox_name_target, (emf_mailbox_tbl_t **)&mailbox_tbl_data, false, &err)) {
639 EM_DEBUG_EXCEPTION("em_storage_get_mailboxname_by_mailbox_type failed [%d]", err);
640 err = em_storage_get_emf_error_from_em_storage_error(err);
644 if (!em_storage_increase_mail_id(&mail_id, true, &err)) {
645 EM_DEBUG_EXCEPTION("em_storage_increase_mail_id failed [%d]", err);
649 mail_table_data = (emf_mail_tbl_t *)em_core_malloc(sizeof(emf_mail_tbl_t));
651 if(!mail_table_data) {
652 EM_DEBUG_EXCEPTION("em_core_malloc failed");
653 err = EMF_ERROR_OUT_OF_MEMORY;
657 mail_table_data->account_id = account_id;
658 mail_table_data->mail_id = mail_id;
659 mail_table_data->mailbox_name = EM_SAFE_STRDUP(mailbox_name_target);
660 mail_table_data->mail_size = mail_src->info->rfc822_size;
661 mail_table_data->server_mail_status = !from_composer;
662 mail_table_data->server_mail_id = EM_SAFE_STRDUP(mail_src->info->sid);
663 mail_table_data->full_address_from = EM_SAFE_STRDUP(mail_src->head->from);
664 mail_table_data->full_address_to = EM_SAFE_STRDUP(mail_src->head->to);
665 mail_table_data->full_address_cc = EM_SAFE_STRDUP(mail_src->head->cc);
666 mail_table_data->full_address_bcc = EM_SAFE_STRDUP(mail_src->head->bcc);
667 mail_table_data->full_address_reply = EM_SAFE_STRDUP(mail_src->head->reply_to);
668 mail_table_data->full_address_return = EM_SAFE_STRDUP(mail_src->head->return_path);
669 mail_table_data->subject = EM_SAFE_STRDUP(mail_src->head->subject);
670 mail_table_data->body_download_status = mail_src->info->extra_flags.text_download_yn;
671 mail_table_data->mailbox_type = mailbox_tbl_data->mailbox_type;
673 em_core_fill_address_information_of_mail_tbl(mail_table_data);
675 EM_DEBUG_LOG("mail_table_data->mail_size [%d]", mail_table_data->mail_size);
676 if(mail_table_data->mail_size == 0)
677 mail_table_data->mail_size = em_core_get_mail_size(mail_src, &err); /* Getting file size before file moved. */
679 if (mail_src->body) {
680 if (from_composer || mail_table_data->body_download_status) {
681 if (!em_storage_create_dir(account_id, mail_id, 0, &err)) {
682 EM_DEBUG_EXCEPTION("em_storage_create_dir failed [%d]", err);
686 if (mail_src->body->plain) {
687 EM_DEBUG_LOG("mail_src->body->plain [%s]", mail_src->body->plain);
688 if (!em_storage_get_save_name(account_id, mail_id, 0, mail_src->body->plain_charset ? mail_src->body->plain_charset : "UTF-8", name_buf, &err)) {
689 EM_DEBUG_EXCEPTION("em_storage_get_save_name failed [%d]", err);
693 if (!em_storage_move_file(mail_src->body->plain, name_buf, from_composer, &err)) {
694 EM_DEBUG_EXCEPTION("em_storage_move_file failed [%d]", err);
697 if (mail_table_data->body_download_status == 0)
698 mail_table_data->body_download_status = 1;
699 mail_table_data->file_path_plain = EM_SAFE_STRDUP(name_buf);
700 EM_SAFE_FREE(mail_src->body->plain);
701 mail_src->body->plain = EM_SAFE_STRDUP(name_buf);
704 if (mail_src->body->html) {
705 EM_DEBUG_LOG("mail_src->body->html [%s]", mail_src->body->html);
706 if (mail_src->body->plain_charset != NULL && mail_src->body->plain_charset[0] != NULL_CHAR) {
707 memcpy(html_body, mail_src->body->plain_charset, strlen(mail_src->body->plain_charset));
708 strcat(html_body, ".htm");
711 memcpy(html_body, "UTF-8.htm", strlen("UTF-8.htm"));
714 if (!em_storage_get_save_name(account_id, mail_id, 0, html_body, name_buf, &err)) {
715 EM_DEBUG_EXCEPTION("em_storage_get_save_name failed [%d]", err);
719 if (!em_storage_move_file(mail_src->body->html, name_buf, from_composer, &err)) {
720 EM_DEBUG_EXCEPTION("em_storage_move_file failed [%d]", err);
724 if (mail_table_data->body_download_status == EMF_BODY_DOWNLOAD_STATUS_NONE)
725 mail_table_data->body_download_status = EMF_BODY_DOWNLOAD_STATUS_FULLY_DOWNLOADED;
727 mail_table_data->file_path_html = EM_SAFE_STRDUP(name_buf);
728 EM_SAFE_FREE(mail_src->body->html);
729 mail_src->body->html = EM_SAFE_STRDUP(name_buf);
735 if (!mail_src->head->datetime.year && !mail_src->head->datetime.month && !mail_src->head->datetime.day) {
737 if(!em_core_set_current_time_to_mail_header(mail_src->head, &err)) {
738 EM_DEBUG_EXCEPTION("em_core_set_current_time_to_mail_header failed [%d]", err);
743 SNPRINTF(datetime, sizeof(datetime), "%04d%02d%02d%02d%02d%02d",
744 mail_src->head->datetime.year, mail_src->head->datetime.month, mail_src->head->datetime.day, mail_src->head->datetime.hour, mail_src->head->datetime.minute, mail_src->head->datetime.second);
746 mail_table_data->datetime = EM_SAFE_STRDUP(datetime);
747 mail_table_data->message_id = EM_SAFE_STRDUP(mail_src->head->mid);
749 if (mail_src->info) {
750 mail_src->info->flags.draft = 1;
751 if(!em_convert_mail_flag_to_mail_tbl(&(mail_src->info->flags), mail_table_data, &err)) {
752 EM_DEBUG_EXCEPTION("em_convert_mail_flag_to_mail_tbl failed [%d]", err);
755 mail_table_data->priority = mail_src->info->extra_flags.priority;
756 mail_table_data->lock_status = mail_src->info->extra_flags.lock;
757 mail_table_data->report_status = mail_src->info->extra_flags.report;
759 mail_table_data->save_status = EMF_MAIL_STATUS_SAVED;
761 mail_id = mail_table_data->mail_id;
762 mail_src->info->uid = mail_id;
764 mail_table_data->meeting_request_status = mail_src->info->is_meeting_request;
766 if(mail_src->info->thread_id == 0) {
767 if (em_storage_get_thread_id_of_thread_mails(mail_table_data, &thread_id, &latest_mail_id_in_thread, &thread_item_count) != EMF_ERROR_NONE)
768 EM_DEBUG_LOG(" em_storage_get_thread_id_of_thread_mails is failed");
770 if (thread_id == -1) {
771 mail_table_data->thread_id = mail_id;
772 mail_table_data->thread_item_count = thread_item_count = 1;
775 mail_table_data->thread_id = thread_id;
780 mail_table_data->thread_id = mail_src->info->thread_id;
781 thread_item_count = 2;
784 /* Getting attachment count */
786 atch = mail_src->body->attachment;
788 if (atch->inline_content)
789 local_inline_content_count++;
790 local_attachment_count++;
794 mail_table_data->inline_content_count = local_inline_content_count;
795 mail_table_data->attachment_count = local_attachment_count;
797 EM_DEBUG_LOG("inline_content_count [%d]", local_inline_content_count);
798 EM_DEBUG_LOG("attachment_count [%d]", local_attachment_count);
800 EM_DEBUG_LOG("preview_text[%p]", mail_table_data->preview_text);
801 if (mail_table_data->preview_text == NULL) {
802 if ( (err = em_core_get_preview_text_from_file(mail_table_data->file_path_plain, mail_table_data->file_path_html, MAX_PREVIEW_TEXT_LENGTH, &(mail_table_data->preview_text))) != EMF_ERROR_NONE) {
803 EM_DEBUG_EXCEPTION("em_core_get_preview_text_from_file failed[%d]", err);
808 em_storage_begin_transaction(NULL, NULL, NULL);
810 /* insert mail to mail table */
811 if (!em_storage_add_mail(mail_table_data, 0, false, &err)) {
812 EM_DEBUG_EXCEPTION("em_storage_add_mail failed [%d]", err);
813 /* ROLLBACK TRANSACTION; */
814 em_storage_rollback_transaction(NULL, NULL, NULL);
815 err = em_storage_get_emf_error_from_em_storage_error(err);
819 EM_DEBUG_LOG("thread_item_count [%d]", thread_item_count);
820 if (thread_item_count > 1) {
821 if (!em_storage_update_latest_thread_mail(mail_table_data->account_id, mail_table_data->thread_id, 0, 0, false, &err)) {
822 EM_DEBUG_EXCEPTION("em_storage_update_latest_thread_mail failed [%d]", err);
823 em_storage_rollback_transaction(NULL, NULL, NULL);
824 err = em_storage_get_emf_error_from_em_storage_error(err);
829 /* Insert attachment information to DB */
831 atch = mail_src->body->attachment;
832 EM_DEBUG_LOG("atch [%p]", atch);
834 if (from_composer && stat(atch->savename, &st_buf) < 0) {
839 if (!atch->inline_content) {
840 if (!em_storage_get_new_attachment_no(&attachment_id, &err)) {
841 EM_DEBUG_EXCEPTION("em_storage_get_new_attachment_no failed [%d]", err);
842 em_storage_rollback_transaction(NULL, NULL, NULL);
847 if (!em_storage_create_dir(account_id, mail_id, atch->inline_content ? 0 : attachment_id, &err)) {
848 EM_DEBUG_EXCEPTION("em_storage_create_dir failed [%d]", err);
849 em_storage_rollback_transaction(NULL, NULL, NULL);
853 if (!em_storage_get_save_name(account_id, mail_id, atch->inline_content ? 0 : attachment_id, atch->name, name_buf, &err)) {
854 EM_DEBUG_EXCEPTION("em_storage_get_save_name failed [%d]", err);
855 em_storage_rollback_transaction(NULL, NULL, NULL);
859 if (from_composer || atch->downloaded) {
860 if (!em_storage_copy_file(atch->savename, name_buf, from_composer, &err)) {
861 EM_DEBUG_EXCEPTION("em_storage_copy_file failed [%d]", err);
862 em_storage_rollback_transaction(NULL, NULL, NULL);
866 if ((ext = strrchr(atch->name, '.'))) {
867 if (!strncmp(ext, ".vcs", strlen(".vcs")))
868 remove(atch->savename);
869 else if (!strncmp(ext, ".vcf", strlen(".vcf")))
870 remove(atch->savename);
871 else if (!strncmp(ext, ".vnt", strlen(".vnt")))
872 remove(atch->savename);
876 memset(&attachment_tbl, 0x00, sizeof(emf_mail_attachment_tbl_t));
878 attachment_tbl.mail_id = mail_id;
879 attachment_tbl.account_id = account_id;
880 attachment_tbl.mailbox_name = mailbox_name_target;
881 attachment_tbl.file_yn = atch->downloaded;
882 attachment_tbl.flag2 = mail_src->body->attachment->drm;
883 attachment_tbl.attachment_name = atch->name;
884 attachment_tbl.attachment_path = name_buf;
885 attachment_tbl.flag3 = atch->inline_content;
887 attachment_tbl.attachment_size = st_buf.st_size;
889 attachment_tbl.attachment_size = atch->size;
891 if (!em_storage_add_attachment(&attachment_tbl, 0, false, &err)) {
892 EM_DEBUG_EXCEPTION("em_storage_add_attachment failed [%d]", err);
893 em_storage_rollback_transaction(NULL, NULL, NULL);
894 err = em_storage_get_emf_error_from_em_storage_error(err);
897 atch->attachment_id = attachment_tbl.attachment_id;
901 /* Insert Meeting request to DB */
902 if (mail_src->info->is_meeting_request == EMF_MAIL_TYPE_MEETING_REQUEST
903 || mail_src->info->is_meeting_request == EMF_MAIL_TYPE_MEETING_RESPONSE
904 || mail_src->info->is_meeting_request == EMF_MAIL_TYPE_MEETING_ORIGINATINGREQUEST) {
905 EM_DEBUG_LOG("This mail has the meeting request");
906 meeting_req->mail_id = mail_id;
907 if (!em_storage_add_meeting_request(account_id, mailbox_name_target, meeting_req, false, &err)) {
908 EM_DEBUG_EXCEPTION("em_storage_add_meeting_request failed [%d]", err);
909 err = em_storage_get_emf_error_from_em_storage_error(err);
914 em_storage_commit_transaction(NULL, NULL, NULL);
916 if (!em_storage_notify_storage_event(NOTI_MAIL_ADD, account_id, mail_id, mailbox_name_target, mail_table_data->thread_id))
917 EM_DEBUG_LOG("em_storage_notify_storage_event [NOTI_MAIL_ADD] failed.");
919 if (account_tbl_item->receiving_server_type != EMF_SERVER_TYPE_ACTIVE_SYNC) {
920 if (!em_core_mailbox_remove_overflowed_mails(mailbox_tbl_data, &err)) {
921 if (err == EM_STORAGE_ERROR_MAIL_NOT_FOUND || err == EMF_ERROR_NOT_SUPPORTED)
922 err = EMF_ERROR_NONE;
924 EM_DEBUG_LOG("em_core_mailbox_remove_overflowed_mails failed [%d]", err);
928 if ( !from_composer && (mail_src->info->flags.seen == 0)
929 && mail_table_data->mailbox_type != EMF_MAILBOX_TYPE_TRASH
930 && mail_table_data->mailbox_type != EMF_MAILBOX_TYPE_SPAMBOX) { /* 0x01 fSeen */
931 if (!em_storage_update_sync_status_of_account(account_id, SET_TYPE_SET, SYNC_STATUS_SYNCING | SYNC_STATUS_HAVE_NEW_MAILS, true, &err))
932 EM_DEBUG_LOG("em_storage_update_sync_status_of_account failed [%d]", err);
933 em_core_add_notification_for_unread_mail_by_mail_header(account_id, mail_id, mail_src->head);
934 em_core_check_unread_mail();
941 em_storage_free_mail(&mail_table_data, 1, NULL);
943 if (account_tbl_item)
944 em_storage_free_account(&account_tbl_item, 1, NULL);
946 if (mailbox_tbl_data)
947 em_storage_free_mailbox(&mailbox_tbl_data, 1, NULL);
949 EM_SAFE_FREE(mailbox_name_spam);
950 EM_SAFE_FREE(mailbox_name_target);
960 EXPORT_API int em_core_add_mail(emf_mail_data_t *input_mail_data, emf_attachment_data_t *input_attachment_data_list, int input_attachment_count, emf_meeting_request_t *input_meeting_request, int input_sync_server)
962 EM_DEBUG_FUNC_BEGIN("input_mail_data[%p], input_attachment_data_list [%p], input_attachment_count [%d], input_meeting_request [%p], input_sync_server[%d]", input_mail_data, input_attachment_data_list, input_attachment_count, input_meeting_request, input_sync_server);
964 int err = EMF_ERROR_NONE;
965 int attachment_id = 0, thread_id = -1, thread_item_count = 0, latest_mail_id_in_thread = -1;
966 int i = 0, rule_len, rule_matched = -1, local_attachment_count = 0, local_inline_content_count = 0;
967 char *ext = NULL, *mailbox_name_spam = NULL, *mailbox_name_target = NULL;
968 char name_buf[MAX_PATH] = {0x00, }, html_body[MAX_PATH] = {0x00, };
969 emf_mail_tbl_t *converted_mail_tbl = NULL;
970 emf_mailbox_tbl_t *mailbox_tbl = NULL;
971 emf_mail_attachment_tbl_t attachment_tbl = { 0 };
972 emf_mail_account_tbl_t *account_tbl_item = NULL;
973 emf_mail_rule_tbl_t *rule = NULL;
974 struct stat st_buf = { 0 };
976 /* Validating parameters */
978 if (!input_mail_data || !(input_mail_data->account_id) || !(input_mail_data->mailbox_name)) {
979 EM_DEBUG_EXCEPTION("EMF_ERROR_INVALID_PARAM");
980 err = EMF_ERROR_INVALID_PARAM;
984 if (!em_storage_get_account_by_id(input_mail_data->account_id, EMF_ACC_GET_OPT_DEFAULT | EMF_ACC_GET_OPT_OPTIONS, &account_tbl_item, true, &err)) {
985 EM_DEBUG_EXCEPTION("em_storage_get_account_by_id failed. account_id[%d] err[%d]", input_mail_data->account_id, err);
986 err = EMF_ERROR_INVALID_ACCOUNT;
990 if(input_sync_server) {
991 if (input_mail_data->file_path_plain) {
992 if (stat(input_mail_data->file_path_plain, &st_buf) < 0) {
993 EM_DEBUG_EXCEPTION("input_mail_data->file_path_plain, stat(\"%s\") failed...", input_mail_data->file_path_plain);
994 err = EMF_ERROR_INVALID_MAIL;
999 if (input_mail_data->file_path_html) {
1000 if (stat(input_mail_data->file_path_html, &st_buf) < 0) {
1001 EM_DEBUG_EXCEPTION("input_mail_data->file_path_html, stat(\"%s\") failed...", input_mail_data->file_path_html);
1002 err = EMF_ERROR_INVALID_MAIL;
1007 if (input_attachment_count && input_attachment_data_list) {
1008 for (i = 0; i < input_attachment_count; i++) {
1009 if (input_attachment_data_list[i].save_status) {
1010 if (!input_attachment_data_list[i].attachment_path || stat(input_attachment_data_list[i].attachment_path, &st_buf) < 0) {
1011 EM_DEBUG_EXCEPTION("stat(\"%s\") failed...", input_attachment_data_list[i].attachment_path);
1012 err = EMF_ERROR_INVALID_ATTACHMENT;
1020 if (input_sync_server) {
1021 if (!input_mail_data->full_address_from)
1022 input_mail_data->full_address_from = EM_SAFE_STRDUP(account_tbl_item->email_addr);
1024 /* check for email_address validation */
1025 if (!em_core_verify_email_address_of_mail_data(input_mail_data, false, &err)) {
1026 EM_DEBUG_EXCEPTION("em_core_verify_email_address_of_mail_data failed [%d]", err);
1030 if (input_mail_data->report_status == EMF_MAIL_REPORT_MDN) {
1031 /* check read-report mail */
1032 if(!input_mail_data->full_address_to) { /* A report mail should have 'to' address */
1033 EM_DEBUG_EXCEPTION("EMF_ERROR_INVALID_PARAM");
1034 err = EMF_ERROR_INVALID_PARAM;
1037 /* Create report mail body */
1039 if (!em_core_mail_get_rfc822(mail_src, NULL, NULL, NULL, &err)) {
1040 EM_DEBUG_EXCEPTION("em_core_mail_get_rfc822 failed [%d]", err);
1046 mailbox_name_target = EM_SAFE_STRDUP(input_mail_data->mailbox_name);
1048 else { /* For Spam handling */
1049 emf_option_t *opt = &account_tbl_item->options;
1050 EM_DEBUG_LOG("block_address [%d], block_subject [%d]", opt->block_address, opt->block_subject);
1052 if (opt->block_address || opt->block_subject) {
1053 int is_completed = false;
1056 if (!opt->block_address)
1057 type = EMF_FILTER_SUBJECT;
1058 else if (!opt->block_subject)
1059 type = EMF_FILTER_FROM;
1061 if (!em_storage_get_rule(ALL_ACCOUNT, type, 0, &rule_len, &is_completed, &rule, true, &err) || !rule)
1062 EM_DEBUG_LOG("No proper rules. em_storage_get_rule returns [%d]", err);
1066 if (!em_storage_get_mailboxname_by_mailbox_type(input_mail_data->account_id, EMF_MAILBOX_TYPE_SPAMBOX, &mailbox_name_spam, false, &err)) {
1067 EM_DEBUG_EXCEPTION("em_storage_get_mailboxname_by_mailbox_type failed [%d]", err);
1068 err = em_storage_get_emf_error_from_em_storage_error(err);
1069 mailbox_name_spam = NULL;
1073 if (mailbox_name_spam && !em_core_mail_check_rule(mail_src->head, rule, rule_len, &rule_matched, &err)) {
1074 EM_DEBUG_EXCEPTION("em_core_mail_check_rule failed [%d]", err);
1080 if (rule_matched >= 0 && mailbox_name_spam)
1081 mailbox_name_target = EM_SAFE_STRDUP(mailbox_name_spam);
1083 mailbox_name_target = EM_SAFE_STRDUP(input_mail_data->mailbox_name);
1086 if (!em_storage_get_mailbox_by_name(input_mail_data->account_id, -1, mailbox_name_target, (emf_mailbox_tbl_t **)&mailbox_tbl, false, &err)) {
1087 EM_DEBUG_EXCEPTION("em_storage_get_mailboxname_by_mailbox_type failed [%d]", err);
1088 err = em_storage_get_emf_error_from_em_storage_error(err);
1092 if (!em_storage_increase_mail_id(&input_mail_data->mail_id, true, &err)) {
1093 EM_DEBUG_EXCEPTION("em_storage_increase_mail_id failed [%d]", err);
1097 EM_DEBUG_LOG("input_mail_data->mail_size [%d]", input_mail_data->mail_size);
1099 if(input_mail_data->mail_size == 0)
1100 em_core_calc_mail_size(input_mail_data, input_attachment_data_list, input_attachment_count, &(input_mail_data->mail_size)); /* Getting file size before file moved. */
1102 if (input_sync_server || input_mail_data->body_download_status) {
1103 if (!em_storage_create_dir(input_mail_data->account_id, input_mail_data->mail_id, 0, &err)) {
1104 EM_DEBUG_EXCEPTION("em_storage_create_dir failed [%d]", err);
1108 if (input_mail_data->file_path_plain) {
1109 EM_DEBUG_LOG("input_mail_data->file_path_plain [%s]", input_mail_data->file_path_plain);
1110 /* if (!em_storage_get_save_name(account_id, mail_id, 0, input_mail_data->body->plain_charset ? input_mail_data->body->plain_charset : "UTF-8", name_buf, &err)) {*/
1111 if (!em_storage_get_save_name(input_mail_data->account_id, input_mail_data->mail_id, 0, "UTF-8", name_buf, &err)) {
1112 EM_DEBUG_EXCEPTION("em_storage_get_save_name failed [%d]", err);
1116 if (!em_storage_move_file(input_mail_data->file_path_plain, name_buf, input_sync_server, &err)) {
1117 EM_DEBUG_EXCEPTION("em_storage_move_file failed [%d]", err);
1120 if (input_mail_data->body_download_status == EMF_BODY_DOWNLOAD_STATUS_NONE)
1121 input_mail_data->body_download_status = EMF_BODY_DOWNLOAD_STATUS_FULLY_DOWNLOADED;
1123 EM_SAFE_FREE(input_mail_data->file_path_plain);
1124 input_mail_data->file_path_plain = EM_SAFE_STRDUP(name_buf);
1127 if (input_mail_data->file_path_html) {
1128 EM_DEBUG_LOG("input_mail_data->file_path_html [%s]", input_mail_data->file_path_html);
1129 memcpy(html_body, "UTF-8.htm", strlen("UTF-8.htm"));
1131 if (!em_storage_get_save_name(input_mail_data->account_id, input_mail_data->mail_id, 0, html_body, name_buf, &err)) {
1132 EM_DEBUG_EXCEPTION("em_storage_get_save_name failed [%d]", err);
1136 if (!em_storage_move_file(input_mail_data->file_path_html, name_buf, input_sync_server, &err)) {
1137 EM_DEBUG_EXCEPTION("em_storage_move_file failed [%d]", err);
1141 if (input_mail_data->body_download_status == EMF_BODY_DOWNLOAD_STATUS_NONE)
1142 input_mail_data->body_download_status = EMF_BODY_DOWNLOAD_STATUS_FULLY_DOWNLOADED;
1144 EM_SAFE_FREE(input_mail_data->file_path_html);
1145 input_mail_data->file_path_html = EM_SAFE_STRDUP(name_buf);
1150 if (!input_mail_data->datetime) {
1151 /* time isn't set */
1152 input_mail_data->datetime = em_core_get_current_time_string(&err);
1153 if(!input_mail_data->datetime) {
1154 EM_DEBUG_EXCEPTION("em_core_get_current_time_string failed [%d]", err);
1159 EM_SAFE_FREE(input_mail_data->mailbox_name);
1161 input_mail_data->mailbox_name = EM_SAFE_STRDUP(mailbox_name_target);
1162 input_mail_data->mailbox_type = mailbox_tbl->mailbox_type;
1163 input_mail_data->server_mail_status = !input_sync_server;
1164 input_mail_data->save_status = EMF_MAIL_STATUS_SAVED;
1166 /* Getting attachment count */
1167 for (i = 0; i < input_attachment_count; i++) {
1168 if (input_attachment_data_list[i].inline_content_status== 1)
1169 local_inline_content_count++;
1170 local_attachment_count++;
1173 input_mail_data->inline_content_count = local_inline_content_count;
1174 input_mail_data->attachment_count = local_attachment_count;
1176 EM_DEBUG_LOG("inline_content_count [%d]", local_inline_content_count);
1177 EM_DEBUG_LOG("input_attachment_count [%d]", local_attachment_count);
1179 EM_DEBUG_LOG("preview_text[%p]", input_mail_data->preview_text);
1180 if (input_mail_data->preview_text == NULL) {
1181 if ( (err = em_core_get_preview_text_from_file(input_mail_data->file_path_plain, input_mail_data->file_path_html, MAX_PREVIEW_TEXT_LENGTH, &(input_mail_data->preview_text))) != EMF_ERROR_NONE) {
1182 EM_DEBUG_EXCEPTION("em_core_get_preview_text_from_file failed[%d]", err);
1187 if (!em_convert_mail_data_to_mail_tbl(input_mail_data, 1, &converted_mail_tbl, &err)) {
1188 EM_DEBUG_EXCEPTION("em_convert_mail_data_to_mail_tbl failed [%d]", err);
1192 /* Fill address information */
1193 em_core_fill_address_information_of_mail_tbl(converted_mail_tbl);
1195 /* Fill thread id */
1196 if(input_mail_data->thread_id == 0) {
1197 if (em_storage_get_thread_id_of_thread_mails(converted_mail_tbl, &thread_id, &latest_mail_id_in_thread, &thread_item_count) != EMF_ERROR_NONE)
1198 EM_DEBUG_LOG(" em_storage_get_thread_id_of_thread_mails is failed");
1200 if (thread_id == -1) {
1201 converted_mail_tbl->thread_id = input_mail_data->mail_id;
1202 converted_mail_tbl->thread_item_count = thread_item_count = 1;
1205 converted_mail_tbl->thread_id = thread_id;
1206 thread_item_count++;
1210 thread_item_count = 2;
1213 em_storage_begin_transaction(NULL, NULL, NULL);
1215 /* insert mail to mail table */
1216 if (!em_storage_add_mail(converted_mail_tbl, 0, false, &err)) {
1217 EM_DEBUG_EXCEPTION("em_storage_add_mail failed [%d]", err);
1218 /* ROLLBACK TRANSACTION; */
1219 em_storage_rollback_transaction(NULL, NULL, NULL);
1220 err = em_storage_get_emf_error_from_em_storage_error(err);
1224 /* Update thread information */
1225 EM_DEBUG_LOG("thread_item_count [%d]", thread_item_count);
1227 if (thread_item_count > 1) {
1228 if (!em_storage_update_latest_thread_mail(input_mail_data->account_id, converted_mail_tbl->thread_id, 0, 0, false, &err)) {
1229 EM_DEBUG_EXCEPTION("em_storage_update_latest_thread_mail failed [%d]", err);
1230 em_storage_rollback_transaction(NULL, NULL, NULL);
1231 err = em_storage_get_emf_error_from_em_storage_error(err);
1236 /* Insert attachment information to DB */
1238 for (i = 0; i < input_attachment_count; i++) {
1239 if (input_attachment_data_list[i].attachment_size == 0) {
1240 /* set attachment size */
1241 if(input_attachment_data_list[i].attachment_path && stat(input_attachment_data_list[i].attachment_path, &st_buf) < 0)
1242 input_attachment_data_list[i].attachment_size = st_buf.st_size;
1245 if (!input_attachment_data_list[i].inline_content_status) {
1246 if (!em_storage_get_new_attachment_no(&attachment_id, &err)) {
1247 EM_DEBUG_EXCEPTION("em_storage_get_new_attachment_no failed [%d]", err);
1248 em_storage_rollback_transaction(NULL, NULL, NULL);
1253 if (!em_storage_create_dir(input_mail_data->account_id, input_mail_data->mail_id, input_attachment_data_list[i].inline_content_status ? 0 : attachment_id, &err)) {
1254 EM_DEBUG_EXCEPTION("em_storage_create_dir failed [%d]", err);
1255 em_storage_rollback_transaction(NULL, NULL, NULL);
1259 if (!em_storage_get_save_name(input_mail_data->account_id, input_mail_data->mail_id, input_attachment_data_list[i].inline_content_status ? 0 : attachment_id, input_attachment_data_list[i].attachment_name, name_buf, &err)) {
1260 EM_DEBUG_EXCEPTION("em_storage_get_save_name failed [%d]", err);
1261 em_storage_rollback_transaction(NULL, NULL, NULL);
1265 if (input_sync_server || input_attachment_data_list[i].save_status) {
1266 if (!em_storage_copy_file(input_attachment_data_list[i].attachment_path, name_buf, input_sync_server, &err)) {
1267 EM_DEBUG_EXCEPTION("em_storage_copy_file failed [%d]", err);
1268 em_storage_rollback_transaction(NULL, NULL, NULL);
1272 if ((ext = strrchr(input_attachment_data_list[i].attachment_name, '.'))) {
1273 if (!strncmp(ext, ".vcs", strlen(".vcs")))
1274 remove(input_attachment_data_list[i].attachment_path);
1275 else if (!strncmp(ext, ".vcf", strlen(".vcf")))
1276 remove(input_attachment_data_list[i].attachment_path);
1277 else if (!strncmp(ext, ".vnt", strlen(".vnt")))
1278 remove(input_attachment_data_list[i].attachment_path);
1282 memset(&attachment_tbl, 0, sizeof(emf_mail_attachment_tbl_t));
1283 attachment_tbl.attachment_name = input_attachment_data_list[i].attachment_name;
1284 attachment_tbl.attachment_path = name_buf;
1285 attachment_tbl.attachment_size = input_attachment_data_list[i].attachment_size;
1286 attachment_tbl.mail_id = input_mail_data->mail_id;
1287 attachment_tbl.account_id = input_mail_data->account_id;
1288 attachment_tbl.mailbox_name = input_mail_data->mailbox_name;
1289 attachment_tbl.file_yn = input_attachment_data_list[i].save_status;
1290 attachment_tbl.flag2 = input_attachment_data_list[i].drm_status;
1291 attachment_tbl.flag3 = input_attachment_data_list[i].inline_content_status;
1293 if (!em_storage_add_attachment(&attachment_tbl, 0, false, &err)) {
1294 EM_DEBUG_EXCEPTION("em_storage_add_attachment failed [%d]", err);
1295 em_storage_rollback_transaction(NULL, NULL, NULL);
1296 err = em_storage_get_emf_error_from_em_storage_error(err);
1299 input_attachment_data_list[i].attachment_id = attachment_tbl.attachment_id;
1302 /* Insert Meeting request to DB */
1303 if (input_mail_data->meeting_request_status == EMF_MAIL_TYPE_MEETING_REQUEST
1304 || input_mail_data->meeting_request_status == EMF_MAIL_TYPE_MEETING_RESPONSE
1305 || input_mail_data->meeting_request_status == EMF_MAIL_TYPE_MEETING_ORIGINATINGREQUEST) {
1306 EM_DEBUG_LOG("This mail has the meeting request");
1307 input_meeting_request->mail_id = input_mail_data->mail_id;
1308 if (!em_storage_add_meeting_request(input_mail_data->account_id, mailbox_name_target, input_meeting_request, false, &err)) {
1309 EM_DEBUG_EXCEPTION("em_storage_add_meeting_request failed [%d]", err);
1310 err = em_storage_get_emf_error_from_em_storage_error(err);
1315 em_storage_commit_transaction(NULL, NULL, NULL);
1317 if (!em_storage_notify_storage_event(NOTI_MAIL_ADD, converted_mail_tbl->account_id, converted_mail_tbl->mail_id, mailbox_name_target, converted_mail_tbl->thread_id))
1318 EM_DEBUG_LOG("em_storage_notify_storage_event [NOTI_MAIL_ADD] failed.");
1320 if (account_tbl_item->receiving_server_type != EMF_SERVER_TYPE_ACTIVE_SYNC) {
1321 if (!em_core_mailbox_remove_overflowed_mails(mailbox_tbl, &err)) {
1322 if (err == EM_STORAGE_ERROR_MAIL_NOT_FOUND || err == EMF_ERROR_NOT_SUPPORTED)
1323 err = EMF_ERROR_NONE;
1325 EM_DEBUG_LOG("em_core_mailbox_remove_overflowed_mails failed [%d]", err);
1329 if ( !input_sync_server && (input_mail_data->flags_seen_field == 0)
1330 && input_mail_data->mailbox_type != EMF_MAILBOX_TYPE_TRASH
1331 && input_mail_data->mailbox_type != EMF_MAILBOX_TYPE_SPAMBOX) {
1332 if (!em_storage_update_sync_status_of_account(input_mail_data->account_id, SET_TYPE_SET, SYNC_STATUS_SYNCING | SYNC_STATUS_HAVE_NEW_MAILS, true, &err))
1333 EM_DEBUG_LOG("em_storage_update_sync_status_of_account failed [%d]", err);
1334 em_core_add_notification_for_unread_mail(input_mail_data);
1335 em_core_check_unread_mail();
1339 if (account_tbl_item)
1340 em_storage_free_account(&account_tbl_item, 1, NULL);
1343 em_storage_free_mailbox(&mailbox_tbl, 1, NULL);
1345 if (converted_mail_tbl)
1346 em_storage_free_mail(&converted_mail_tbl, 1, NULL);
1348 EM_SAFE_FREE(mailbox_name_spam);
1349 EM_SAFE_FREE(mailbox_name_target);
1351 EM_DEBUG_FUNC_END();
1356 em_core_mail_add_meeting_request(int account_id, char *mailbox_name, emf_meeting_request_t *meeting_req, int *err_code)
1358 EM_DEBUG_FUNC_BEGIN("account_id[%d], mailbox_name[%s], meeting_req[%p], err_code[%p]", account_id, mailbox_name, meeting_req, err_code);
1360 int err = EMF_ERROR_NONE;
1362 if (!meeting_req || meeting_req->mail_id <= 0) {
1364 EM_DEBUG_EXCEPTION("mail_id[%d]", meeting_req->mail_id);
1366 err = EMF_ERROR_INVALID_PARAM;
1370 if (!em_storage_add_meeting_request(account_id, mailbox_name, meeting_req, 1, &err)) {
1371 EM_DEBUG_EXCEPTION(" em_storage_add_meeting_request failed [%d]", err);
1372 err = em_storage_get_emf_error_from_em_storage_error(err);
1383 EM_DEBUG_FUNC_END();
1387 /* send a message (not saved) */
1388 EXPORT_API int em_core_mail_send(int account_id, char *input_mailbox_name, int mail_id, emf_option_t *sending_option, int *err_code)
1390 EM_DEBUG_FUNC_BEGIN("account_id[%d], input_mailbox_name[%s], mail_id[%d], sending_option[%p], err_code[%p]", account_id, input_mailbox_name, mail_id, sending_option, err_code);
1391 EM_PROFILE_BEGIN(profile_em_core_mail_send);
1393 int err = EMF_ERROR_NONE, err2 = EMF_ERROR_NONE;
1394 int status = EMF_SEND_FAIL;
1396 SENDSTREAM *stream = NULL;
1397 ENVELOPE *envelope = NULL;
1398 sslstart_t stls = NULL;
1399 emf_mail_t *mail = NULL;
1400 emf_account_t *ref_account = NULL;
1401 emf_option_t *opt = NULL;
1402 emf_mailbox_t dest_mbox = {0};
1403 void *tmp_stream = NULL;
1406 char *mailbox_name = NULL;
1408 if (!account_id || !mail_id) {
1409 EM_DEBUG_EXCEPTION("EMF_ERROR_INVALID_PARAM");
1410 err = EMF_ERROR_INVALID_PARAM;
1414 if (!(ref_account = em_core_get_account_reference(account_id))) {
1415 EM_DEBUG_EXCEPTION("em_core_get_account_reference failed [%d]", account_id);
1416 err = EMF_ERROR_INVALID_ACCOUNT;
1420 /* get mail to send */
1421 if (!em_core_mail_get_mail(mail_id, &mail, &err)) {
1422 EM_DEBUG_EXCEPTION("em_core_mail_get_mail failed [%d]", err);
1426 if (!em_core_check_send_mail_thread_status()) {
1427 EM_DEBUG_EXCEPTION("em_core_check_send_mail_thread_status failed...");
1428 err = EMF_ERROR_CANCELLED;
1432 if ((!mail->head->to) && (!mail->head->cc) && (!mail->head->bcc)) {
1433 err = EMF_ERROR_NO_RECIPIENT;
1434 EM_DEBUG_EXCEPTION("No Recipient information [%d]", err);
1438 if (!em_core_verify_email_address_of_mail_header(mail->head, false, &err)) {
1439 err = EMF_ERROR_INVALID_ADDRESS;
1440 EM_DEBUG_EXCEPTION("em_core_verify_email_address_of_mail_header failed [%d]", err);
1446 mail->info->account_id = account_id;
1448 if (!em_core_check_send_mail_thread_status()) {
1449 EM_DEBUG_EXCEPTION("em_core_check_send_mail_thread_status failed...");
1450 err = EMF_ERROR_CANCELLED;
1454 if (sending_option != NULL)
1455 opt = sending_option;
1457 opt = em_core_get_option(&err);
1460 /*Update status flag to DB*/
1462 /* get rfc822 data */
1463 if (!em_core_mail_get_rfc822(mail, &envelope, &fpath, opt, &err)) {
1464 EM_DEBUG_EXCEPTION("em_core_mail_get_rfc822 failed [%d]", err);
1468 if (!envelope || (!envelope->to && !envelope->cc && !envelope->bcc)) {
1469 EM_DEBUG_EXCEPTION(" no recipients found...");
1471 err = EMF_ERROR_NO_RECIPIENT;
1475 /* if there is no security option, unset security. */
1476 if (!ref_account->sending_security) {
1477 stls = (sslstart_t)mail_parameters(NULL, GET_SSLSTART, NULL);
1478 mail_parameters(NULL, SET_SSLSTART, NULL);
1481 if (!em_core_check_send_mail_thread_status()) {
1482 EM_DEBUG_EXCEPTION("em_core_check_send_mail_thread_status failed...");
1483 err = EMF_ERROR_CANCELLED;
1487 if (ref_account->pop_before_smtp != FALSE) {
1488 if (!em_core_mailbox_open(account_id, NULL, (void **)&tmp_stream, &err)) {
1489 EM_DEBUG_EXCEPTION(" POP before SMTP Authentication failed [%d]", err);
1490 status = EMF_LIST_CONNECTION_FAIL;
1491 if (err == EMF_ERROR_CONNECTION_BROKEN)
1492 err = EMF_ERROR_CANCELLED;
1498 if (!em_storage_get_mailboxname_by_mailbox_type(account_id, EMF_MAILBOX_TYPE_DRAFT, &mailbox_name, false, &err)) {
1499 EM_DEBUG_EXCEPTION(" em_storage_get_mailboxname_by_mailbox_type failed [%d]", err);
1500 err = em_storage_get_emf_error_from_em_storage_error(err);
1504 if (!em_core_mailbox_open(account_id, (char *)ENCODED_PATH_SMTP, (void **)&tmp_stream, &err)) {
1505 EM_DEBUG_EXCEPTION(" em_core_mailbox_open failed [%d]", err);
1507 if (err == EMF_ERROR_CONNECTION_BROKEN)
1508 err = EMF_ERROR_CANCELLED;
1510 status = EMF_SEND_CONNECTION_FAIL;
1514 stream = (SENDSTREAM *)tmp_stream;
1516 if (!em_core_check_send_mail_thread_status()) {
1517 EM_DEBUG_EXCEPTION(" em_core_check_send_mail_thread_status failed...");
1518 err = EMF_ERROR_CANCELLED;
1522 /* set request of delivery status. */
1523 if (opt->req_delivery_receipt == EMF_OPTION_REQ_DELIVERY_RECEIPT_ON) {
1524 stream->protocol.esmtp.dsn.want = 1;
1525 stream->protocol.esmtp.dsn.full = 0;
1526 stream->protocol.esmtp.dsn.notify.failure = 1;
1527 stream->protocol.esmtp.dsn.notify.success = 1;
1528 EM_DEBUG_LOG("opt->req_delivery_receipt == EMF_OPTION_REQ_DELIVERY_RECEIPT_ON");
1531 mail->info->extra_flags.status = EMF_MAIL_STATUS_SENDING;
1533 /*Update status flag to DB*/
1534 if (!em_core_mail_modify_extra_flag(mail_id, mail->info->extra_flags, &err))
1535 EM_DEBUG_EXCEPTION("Failed to modify extra flag [%d]", err);
1537 /* send mail to server. */
1538 if (!em_core_mail_send_smtp(stream, envelope, fpath, account_id, mail_id, &err)) {
1539 EM_DEBUG_EXCEPTION(" em_core_mail_send_smtp failed [%d]", err);
1542 #ifndef __FEATURE_MOVE_TO_OUTBOX_FIRST__
1543 EM_SAFE_FREE(mailbox_name);
1544 if (!em_storage_get_mailboxname_by_mailbox_type(account_id, EMF_MAILBOX_TYPE_OUTBOX, &mailbox_name, false, &err)) {
1545 EM_DEBUG_EXCEPTION(" em_storage_get_mailboxname_by_mailbox_type failed [%d]", err);
1546 err = em_storage_get_emf_error_from_em_storage_error(err);
1549 dest_mbox.name = mailbox_name;
1550 dest_mbox.account_id = account_id;
1552 /* unsent mail is moved to 'OUTBOX'. */
1553 if (!em_core_mail_move(&mail_id, 1, dest_mbox.name, EMF_MOVED_BY_COMMAND, 0, NULL))
1554 EM_DEBUG_EXCEPTION(" em_core_mail_move falied...");
1561 /* sent mail is moved to 'SENT' box or deleted. */
1562 if (opt->keep_local_copy) {
1563 EM_SAFE_FREE(mailbox_name);
1565 if (!em_storage_get_mailboxname_by_mailbox_type(account_id, EMF_MAILBOX_TYPE_SENTBOX, &mailbox_name, false, &err)) {
1566 EM_DEBUG_EXCEPTION(" em_storage_get_mailboxname_by_mailbox_type failed [%d]", err);
1567 err = em_storage_get_emf_error_from_em_storage_error(err);
1570 dest_mbox.name = mailbox_name;
1571 dest_mbox.account_id = account_id;
1573 if (!em_core_mail_move(&mail_id, 1, dest_mbox.name, EMF_MOVED_AFTER_SENDING, 0, &err))
1574 EM_DEBUG_EXCEPTION(" em_core_mail_move falied [%d]", err);
1575 #ifdef __FEATURE_SYNC_CLIENT_TO_SERVER__
1576 #ifdef __LOCAL_ACTIVITY__
1577 else if (ref_account->receiving_server_type == EMF_SERVER_TYPE_IMAP4) /* To be synced to Sent box only IMAP not for POP */ {
1579 emf_activity_tbl_t new_activity;
1582 if (false == em_core_get_next_activity_id(&activityid, &err)) {
1583 EM_DEBUG_EXCEPTION(" em_core_get_next_activity_id Failed [%d] ", err);
1586 memset(&new_activity, 0x00, sizeof(emf_activity_tbl_t));
1587 new_activity.activity_id = activityid;
1588 new_activity.server_mailid = NULL;
1589 new_activity.account_id = account_id;
1590 new_activity.mail_id = mail_id;
1591 new_activity.activity_type = ACTIVITY_SAVEMAIL;
1592 new_activity.dest_mbox = NULL;
1593 new_activity.src_mbox = NULL;
1595 if (!em_core_activity_add(&new_activity, &err)) {
1596 EM_DEBUG_EXCEPTION(" em_core_activity_add Failed [%d] ", err);
1599 if (!em_core_mail_move_from_server(dest_mbox.account_id, mailbox_name, &mail_id, 1, dest_mbox.name, &err)) {
1600 EM_DEBUG_EXCEPTION(" em_core_mail_move_from_server falied [%d]", err);
1603 /* Remove ACTIVITY_SAVEMAIL activity */
1604 new_activity.activity_id = activityid;
1605 new_activity.activity_type = ACTIVITY_SAVEMAIL;
1606 new_activity.account_id = account_id;
1607 new_activity.mail_id = mail_id;
1608 new_activity.dest_mbox = NULL;
1609 new_activity.server_mailid = NULL;
1610 new_activity.src_mbox = NULL;
1612 if (!em_core_activity_delete(&new_activity, &err)) {
1613 EM_DEBUG_EXCEPTION(">>>>>>Local Activity [ACTIVITY_SAVEMAIL] [%d] ", err);
1621 /* On Successful Mail sent remove the Draft flag */
1622 emf_mail_flag_t update_flag;
1624 memcpy(&update_flag, &(mail->info->flags), sizeof(emf_mail_flag_t));
1626 memset(&update_flag, 0x00, sizeof(emf_mail_flag_t));
1627 update_flag.draft = 0;
1628 int sticky_flag = 1;
1629 if (!em_core_mail_modify_flag(mail_id, update_flag, sticky_flag, &err))
1630 EM_DEBUG_EXCEPTION(" Flag Modification Failed [ %d] ", err);
1634 if (!em_core_mail_delete(account_id, &mail_id, 1, 0, EMF_DELETED_AFTER_SENDING, false, &err))
1635 EM_DEBUG_EXCEPTION(" em_core_mail_delete failed [%d]", err);
1638 /*Update status flag to DB*/
1639 mail->info->extra_flags.status = EMF_MAIL_STATUS_SENT;
1640 if (!em_core_mail_modify_extra_flag(mail_id, mail->info->extra_flags, &err))
1641 EM_DEBUG_EXCEPTION("Failed to modify extra flag [%d]", err);
1642 /*Update status flag to DB*/
1643 if (!em_core_delete_transaction_info_by_mailId(mail_id))
1644 EM_DEBUG_EXCEPTION(" em_core_delete_transaction_info_by_mailId failed for mail_id[%d]", mail_id);
1649 if (ret == false && err != EMF_ERROR_INVALID_PARAM && mail) {
1650 if (err != EMF_ERROR_CANCELLED) {
1651 mail->info->extra_flags.status = EMF_MAIL_STATUS_SEND_FAILURE;
1652 if (!em_core_mail_modify_extra_flag(mail_id, mail->info->extra_flags, &err2))
1653 EM_DEBUG_EXCEPTION("Failed to modify extra flag [%d]", err2);
1656 if (EMF_MAIL_STATUS_SEND_CANCELED == mail->info->extra_flags.status)
1657 EM_DEBUG_LOG("EMF_MAIL_STATUS_SEND_CANCELED Already set for ");
1659 mail->info->extra_flags.status = EMF_MAIL_STATUS_SEND_CANCELED;
1660 if (!em_core_mail_modify_extra_flag(mail_id, mail->info->extra_flags, &err2))
1661 EM_DEBUG_EXCEPTION("Failed to modify extra flag [%d]", err2);
1666 #ifndef __FEATURE_KEEP_CONNECTION__
1669 #endif /* __FEATURE_KEEP_CONNECTION__ */
1671 mail_parameters(NULL, SET_SSLSTART, (void *)stls);
1673 em_core_mail_free(&mail, 1, NULL);
1675 mail_free_envelope(&envelope);
1678 EM_DEBUG_LOG("REMOVE TEMP FILE : %s", fpath);
1684 if (!em_storage_notify_network_event(NOTI_SEND_FINISH, account_id, NULL, mail_id, 0))
1685 EM_DEBUG_EXCEPTION("em_storage_notify_network_event [NOTI_SEND_FINISH] Failed");
1688 if (!em_storage_notify_network_event(NOTI_SEND_FAIL, account_id, NULL, mail_id, err))
1689 EM_DEBUG_EXCEPTION("em_storage_notify_network_event [NOTI_SEND_FAIL] Failed");
1690 em_core_show_popup(mail_id, EMF_ACTION_SEND_MAIL, err);
1693 EM_SAFE_FREE(mailbox_name);
1695 if (err_code != NULL)
1697 EM_PROFILE_END(profile_em_core_mail_send);
1698 EM_DEBUG_FUNC_END("ret [%d], err [%d]", ret, err);
1702 /* send a saved message */
1703 EXPORT_API int em_core_mail_send_saved(int account_id, char *input_mailbox_name, emf_option_t *sending_option, int *err_code)
1705 EM_DEBUG_FUNC_BEGIN("account_id[%d], input_mailbox_name[%p], sending_option[%p], err_code[%p]", account_id, input_mailbox_name, sending_option, err_code);
1708 int err = EMF_ERROR_NONE;
1709 int status = EMF_SEND_FAIL;
1711 SENDSTREAM *stream = NULL;
1712 ENVELOPE *envelope = NULL;
1713 emf_mailbox_t dest_mbox = {0};
1714 emf_mail_t *mail = NULL;
1715 emf_account_t *ref_account = NULL;
1716 emf_mail_tbl_t mail_table_data = {0};
1717 emf_option_t *opt = NULL;
1718 sslstart_t stls = NULL;
1719 void *tmp_stream = NULL;
1726 char *mailbox_name = NULL;
1728 if (!account_id || !input_mailbox_name) {
1729 EM_DEBUG_EXCEPTION("EMF_ERROR_INVALID_PARAM");
1730 err = EMF_ERROR_INVALID_PARAM;
1734 mail_send_notify(EMF_SEND_PREPARE, 0, 0, account_id, mail_id, err);
1736 if (!(ref_account = em_core_get_account_reference(account_id))) {
1737 EM_DEBUG_EXCEPTION("em_core_get_account_reference failed [%d]", account_id);
1738 err = EMF_ERROR_INVALID_ACCOUNT;
1742 FINISH_OFF_IF_CANCELED;
1745 opt = sending_option;
1747 opt = em_core_get_option(&err);
1750 if (!em_storage_mail_search_start(NULL, account_id, input_mailbox_name, 0, &handle, &total, true, &err)) {
1751 EM_DEBUG_EXCEPTION("em_storage_mail_search_start failed [%d]", err);
1752 err = em_storage_get_emf_error_from_em_storage_error(err);
1756 while (i++ < total) {
1757 FINISH_OFF_IF_CANCELED;
1760 if (!em_storage_mail_search_result(handle, RETRIEVE_ID, (void **)&p, true, &err)) {
1761 EM_DEBUG_EXCEPTION("em_storage_mail_search_result failed [%d]", err);
1762 err = em_storage_get_emf_error_from_em_storage_error(err);
1768 if (!em_core_mail_get_mail(mail_id, &mail, &err)) {
1769 EM_DEBUG_EXCEPTION("em_core_mail_get_mail failed [%d]", err);
1773 /* check for email_address validation */
1774 if (!em_core_verify_email_address_of_mail_header(mail->head, false, &err)) {
1775 EM_DEBUG_EXCEPTION("em_core_verify_email_address_of_mail_header failed [%d]", err);
1779 /* check that this mail was saved in offline-mode. */
1780 if (mail->info->extra_flags.status != EMF_MAIL_STATUS_SAVED_OFFLINE) {
1781 EM_DEBUG_EXCEPTION(" mail was not saved in offline mode...");
1782 em_core_mail_free(&mail, 1, &err); mail = NULL;
1786 if(!em_convert_mail_flag_to_mail_tbl(&(mail->info->flags), &mail_table_data, &err)) {
1787 EM_DEBUG_EXCEPTION("em_convert_mail_flag_to_mail_tbl failed [%d]", err);
1791 mail_table_data.save_status = mail->info->extra_flags.status;
1792 mail_table_data.lock_status = mail->info->extra_flags.lock;
1793 mail_table_data.priority = mail->info->extra_flags.priority;
1794 mail_table_data.report_status = mail->info->extra_flags.report;
1796 mail->info->extra_flags.status = EMF_MAIL_STATUS_SENDING;
1798 if (!em_core_mail_get_rfc822(mail, &envelope, &fpath, opt, &err)) {
1799 EM_DEBUG_EXCEPTION("em_core_mail_get_rfc822 falied [%d]", err);
1803 FINISH_OFF_IF_CANCELED;
1805 /* connect mail server. */
1807 /* if there no security option, unset security. */
1808 if (!ref_account->sending_security) {
1809 stls = (sslstart_t)mail_parameters(NULL, GET_SSLSTART, NULL);
1810 mail_parameters(NULL, SET_SSLSTART, NULL);
1814 if (!em_core_mailbox_open(account_id, (char *)ENCODED_PATH_SMTP, &tmp_stream, &err) || !tmp_stream) {
1815 EM_DEBUG_EXCEPTION("em_core_mailbox_open failed [%d]", err);
1817 if (err == EMF_ERROR_CONNECTION_BROKEN)
1818 err = EMF_ERROR_CANCELLED;
1820 status = EMF_SEND_CONNECTION_FAIL;
1824 stream = (SENDSTREAM *)tmp_stream;
1826 FINISH_OFF_IF_CANCELED;
1828 mail_send_notify(EMF_SEND_CONNECTION_SUCCEED, 0, 0, account_id, mail_id, err);
1830 /* reqest of delivery status. */
1831 if (opt && opt->req_delivery_receipt == EMF_OPTION_REQ_DELIVERY_RECEIPT_ON) {
1832 stream->protocol.esmtp.dsn.want = 1;
1833 stream->protocol.esmtp.dsn.full = 0;
1834 stream->protocol.esmtp.dsn.notify.failure = 1;
1835 stream->protocol.esmtp.dsn.notify.success = 1;
1838 mail_send_notify(EMF_SEND_START, 0, 0, account_id, mail_id, err);
1841 mail_table_data.save_status = EMF_MAIL_STATUS_SENDING;
1843 /* update mail status to sending. */
1844 if (!em_storage_change_mail_field(mail_id, UPDATE_EXTRA_FLAG, &mail_table_data, true, &err)) {
1845 EM_DEBUG_EXCEPTION("em_storage_change_mail_field failed [%d]", err);
1846 err = em_storage_get_emf_error_from_em_storage_error(err);
1850 if (!em_core_mail_send_smtp(stream, envelope, fpath, account_id, mail_id, &err)) {
1851 EM_DEBUG_EXCEPTION("em_core_mail_send_smtp failed [%d]", err);
1853 mail_table_data.save_status = EMF_MAIL_STATUS_SEND_FAILURE;
1855 /* update mail status to failure. */
1856 if (!em_storage_change_mail_field(mail_id, UPDATE_EXTRA_FLAG, &mail_table_data, true, &err))
1857 EM_DEBUG_EXCEPTION("em_storage_change_mail_field failed [%d]", err);
1859 if (!em_storage_get_mailboxname_by_mailbox_type(account_id, EMF_MAILBOX_TYPE_OUTBOX, &mailbox_name, false, &err)) {
1860 EM_DEBUG_EXCEPTION("em_storage_get_mailboxname_by_mailbox_type failed [%d]", err);
1861 err = em_storage_get_emf_error_from_em_storage_error(err);
1864 dest_mbox.name = mailbox_name;
1865 dest_mbox.account_id = account_id;
1867 em_core_mail_move(&mail_id, 1, dest_mbox.name, EMF_MOVED_AFTER_SENDING, 0, NULL);
1872 mail_table_data.save_status = EMF_MAIL_STATUS_SENT;
1874 /* update mail status to sent mail. */
1875 if (!em_storage_change_mail_field(mail_id, UPDATE_EXTRA_FLAG, &mail_table_data, true, &err)) {
1876 EM_DEBUG_EXCEPTION("em_storage_change_mail_field failed [%d]", err);
1877 err = em_storage_get_emf_error_from_em_storage_error(err);
1881 /* sent mail is moved to 'SENT' box or deleted. */
1882 if (opt->keep_local_copy) {
1883 EM_SAFE_FREE(mailbox_name);
1884 if (!em_storage_get_mailboxname_by_mailbox_type(account_id, EMF_MAILBOX_TYPE_SENTBOX, &mailbox_name, false, &err)) {
1885 EM_DEBUG_EXCEPTION("em_storage_get_mailboxname_by_mailbox_type failed [%d]", err);
1886 err = em_storage_get_emf_error_from_em_storage_error(err);
1889 dest_mbox.name = mailbox_name;
1890 dest_mbox.account_id = account_id;
1892 if (!em_core_mail_move(&mail_id, 1, dest_mbox.name, EMF_MOVED_AFTER_SENDING, 0, &err))
1893 EM_DEBUG_EXCEPTION("em_core_mail_move falied [%d]", err);
1896 if (!em_core_mail_delete(account_id, &mail_id, 1, 0, EMF_DELETED_AFTER_SENDING, false, &err))
1897 EM_DEBUG_EXCEPTION("em_core_mail_delete falied [%d]", err);
1900 em_core_mail_free(&mail, 1, NULL); mail = NULL;
1901 mail_free_envelope(&envelope); envelope = NULL;
1905 EM_SAFE_FREE(fpath);
1917 mail_parameters(NIL, SET_SSLSTART, (void *)stls);
1920 mail_free_envelope(&envelope);
1923 if (!em_storage_mail_search_end(handle, true, &err))
1924 EM_DEBUG_EXCEPTION("em_storage_mail_search_end failed [%d]", err);
1928 em_core_mail_free(&mail, 1, NULL);
1932 EM_SAFE_FREE(fpath);
1935 EM_SAFE_FREE(mailbox_name);
1938 mail_send_notify(EMF_SEND_FINISH, 0, 0, account_id, mail_id, err);
1940 mail_send_notify(status, 0, 0, account_id, mail_id, err);
1941 em_core_show_popup(account_id, EMF_ACTION_SEND_MAIL, err);
1944 if (err_code != NULL)
1950 static int em_core_mail_send_smtp(SENDSTREAM *stream, ENVELOPE *env, char *data_file, int account_id, int mail_id, int *err_code)
1952 EM_DEBUG_FUNC_BEGIN("stream[%p], env[%p], data_file[%s], account_id[%d], mail_id[%d], err_code[%p]", stream, env, data_file, account_id, mail_id, err_code);
1953 EM_PROFILE_BEGIN(profile_em_core_mail_send_smtp);
1956 int err = EMF_ERROR_NONE;
1958 long total = 0, sent = 0, send_ret = 0, send_err = 0, sent_percent = 0, last_sent_percent = 0;
1959 char buf[2048] = { 0, };
1960 emf_account_t *ref_account = NULL;
1963 if (!env || !env->from || (!env->to && !env->cc && !env->bcc)) {
1965 EM_DEBUG_EXCEPTION("EMF_ERROR_INVALID_PARAM");
1966 err = EMF_ERROR_INVALID_PARAM;
1970 if (!env->from->mailbox || !env->from->host) {
1971 EM_DEBUG_EXCEPTION("env->from->mailbox[%p], env->from->host[%p]", env->from->mailbox, env->from->host);
1972 err = EMF_ERROR_INVALID_PARAM;
1976 if (!(ref_account = em_core_get_account_reference(account_id))) {
1977 EM_DEBUG_EXCEPTION("em_core_get_account_reference failed [%d]", account_id);
1978 err = EMF_ERROR_INVALID_ACCOUNT;
1982 EM_DEBUG_LOG("Modifying - MAIL FROM ");
1983 if (ref_account->email_addr == NULL) {
1984 EM_DEBUG_LOG("ref_account->email_addr is null!!");
1985 SNPRINTF(buf, sizeof(buf), "FROM:<%s@%s>", env->from->mailbox, env->from->host);
1988 SNPRINTF(buf, sizeof(buf), "FROM:<%s>", ref_account->email_addr);
1990 /* set DSN for ESMTP */
1991 if (stream->protocol.esmtp.ok) {
1992 if (stream->protocol.esmtp.eightbit.ok && stream->protocol.esmtp.eightbit.want)
1993 strncat (buf, " BODY=8BITMIME", sizeof(buf)-(strlen(buf)+1));
1995 if (stream->protocol.esmtp.dsn.ok && stream->protocol.esmtp.dsn.want) {
1996 EM_DEBUG_LOG("stream->protocol.esmtp.dsn.want is required");
1997 strncat (buf, stream->protocol.esmtp.dsn.full ? " RET=FULL" : " RET=HDRS", sizeof(buf)-strlen(buf)-1);
1998 if (stream->protocol.esmtp.dsn.envid)
1999 SNPRINTF (buf + strlen (buf), sizeof(buf)-(strlen(buf)), " ENVID=%.100s", stream->protocol.esmtp.dsn.envid);
2002 EM_DEBUG_LOG("stream->protocol.esmtp.dsn.want is not required");
2005 EM_PROFILE_BEGIN(profile_prepare_and_head);
2006 send_ret = smtp_send(stream, "RSET", 0);
2007 EM_DEBUG_LOG("[SMTP] RSET --------> %s", stream->reply);
2009 if (send_ret != SMTP_RESPONSE_OK) {
2014 send_ret = smtp_send(stream, "MAIL", buf);
2015 EM_DEBUG_LOG("[SMTP] MAIL %s --------> %s", buf, stream->reply);
2018 case SMTP_RESPONSE_OK:
2021 case SMTP_RESPONSE_WANT_AUTH :
2022 case SMTP_RESPONSE_WANT_AUTH2:
2023 EM_DEBUG_EXCEPTION("SMTP error : authentication required...");
2024 err = EMF_ERROR_AUTHENTICATE;
2027 case SMTP_RESPONSE_UNAVAIL:
2028 EM_DEBUG_EXCEPTION("SMTP error : mailbox unavailable...");
2029 err = EMF_ERROR_MAILBOX_FAILURE;
2038 send_ret = smtp_rcpt(stream, env->to, &send_err);
2039 EM_DEBUG_LOG("[SMTP] RCPT TO : <%s@%s> ... --------> %s", env->to->mailbox, env->to->host, env->to->error ? env->to->error : stream->reply);
2041 err = stream->replycode;
2050 send_ret = smtp_rcpt(stream, env->cc, &send_err);
2051 EM_DEBUG_LOG("[SMTP] RCPT TO : <%s@%s> ... --------> %s", env->cc->mailbox, env->cc->host, env->cc->error ? env->cc->error : stream->reply);
2053 err = stream->replycode;
2062 send_ret = smtp_rcpt(stream, env->bcc, &send_err);
2063 EM_DEBUG_LOG("[SMTP] RCPT TO : <%s@%s> ... --------> %s", env->bcc->mailbox, env->bcc->host, env->bcc->error ? env->bcc->error : stream->reply);
2065 err = stream->replycode;
2075 EM_DEBUG_EXCEPTION("One or more recipients failed...");
2076 err = EMF_ERROR_INVALID_ADDRESS;
2080 EM_DEBUG_EXCEPTION("No valid recipients...");
2082 switch (stream->replycode) {
2083 case SMTP_RESPONSE_UNAVAIL:
2084 case SMTP_RESPONSE_WANT_AUTH :
2085 case SMTP_RESPONSE_WANT_AUTH2:
2086 err = EMF_ERROR_AUTH_REQUIRED;
2090 err = EMF_ERROR_INVALID_ADDRESS;
2096 send_ret = smtp_send(stream, "DATA", 0);
2097 EM_DEBUG_LOG("[SMTP] DATA --------> %s", stream->reply);
2098 EM_PROFILE_END(profile_prepare_and_head);
2100 if (send_ret != SMTP_RESPONSE_READY) {
2106 EM_PROFILE_BEGIN(profile_open_file);
2107 if (!(fp = fopen(data_file, "r+"))) {
2108 EM_DEBUG_EXCEPTION("fopen(\"%s\") failed...", data_file);
2109 err = EMF_ERROR_SYSTEM_FAILURE;
2112 EM_PROFILE_END(profile_open_file);
2115 #ifdef __FEATURE_SEND_OPTMIZATION__
2118 int read_size, allocSize, dataSize, gMaxAllocSize = 40960; /* 40KB */
2120 fseek(fp, 0, SEEK_END);
2122 fseek(fp, 0, SEEK_SET);
2123 EM_DEBUG_LOG("total size [%d]", total);
2125 if (total < gMaxAllocSize)
2126 allocSize = total + 1;
2128 allocSize = gMaxAllocSize;
2130 EM_PROFILE_BEGIN(profile_allocation);
2131 /* Allocate a buffer of max 2MB to read from file */
2132 data = (char *)em_core_malloc(allocSize);
2134 EM_PROFILE_END(profile_allocation);
2137 err = EMF_ERROR_SMTP_SEND_FAILURE;
2142 if (total < allocSize)
2145 dataSize = allocSize;
2147 memset(data, 0x0, dataSize+1);
2148 read_size = fread(data, sizeof (char), dataSize, fp);
2150 if (read_size != dataSize) {
2153 EM_DEBUG_EXCEPTION("Read from file failed");
2154 err = EMF_ERROR_SMTP_SEND_FAILURE;
2159 EM_DEBUG_LOG("before smtp_soutr_test");
2160 if (!(send_ret = smtp_soutr_test(stream->netstream, data))) {
2162 EM_DEBUG_EXCEPTION("Failed to send the data ");
2163 err = EMF_ERROR_SMTP_SEND_FAILURE;
2167 sent_percent = (int) ((double)sent / (double)total * 100.0);
2168 if (last_sent_percent + 5 <= sent_percent) {
2169 if (!em_storage_notify_network_event(NOTI_SEND_START, account_id, NULL, mail_id, sent_percent))
2170 EM_DEBUG_EXCEPTION("em_storage_notify_network_event [NOTI_SEND_START] Failed >>>>");
2171 last_sent_percent = sent_percent;
2173 EM_DEBUG_LOG("Sent data Successfully. sent[%d] total[%d]", sent, total);
2181 fseek(fp, 0, SEEK_END);
2183 fseek(fp, 0, SEEK_SET);
2185 while (fgets(buf, 1024, fp)) {
2186 #ifdef FEATURE_SEND_DATA_DEBUG
2187 EM_DEBUG_LOG("%s", buf);
2189 sent += strlen(buf);
2191 if (!(send_ret = smtp_soutr(stream->netstream, buf)))
2193 /* Sending Progress Notification */
2194 sent_percent = (int) ((double)sent / (double)total * 100.0);
2195 if (last_sent_percent + 5 <= sent_percent) {
2196 /* Disabled Temporary
2197 if (!em_storage_notify_network_event(NOTI_SEND_START, account_id, NULL, mail_id, sent_percent))
2198 EM_DEBUG_EXCEPTION(" em_storage_notify_network_event [NOTI_SEND_START] Failed >>>>");
2200 last_sent_percent = sent_percent;
2206 EM_DEBUG_EXCEPTION("smtp_soutr failed - %ld", send_ret);
2207 err = EMF_ERROR_SMTP_SEND_FAILURE;
2212 send_ret = smtp_send(stream, ".", 0);
2213 EM_DEBUG_LOG("[SMTP] . --------> %s", stream->reply);
2215 if (send_ret != SMTP_RESPONSE_OK) {
2224 smtp_send(stream, "RSET", 0);
2231 EM_PROFILE_END(profile_em_core_mail_send_smtp);
2232 EM_DEBUG_FUNC_END("ret [%d]", ret);
2236 /* ------ rfc822 handle --------------------------------------------------- */
2237 #define RANDOM_NUMBER_LENGTH 35
2239 char *em_core_generate_content_id_string(const char *hostname, int *err)
2241 EM_DEBUG_FUNC_BEGIN("hostname[%p]", hostname);
2244 EM_DEBUG_EXCEPTION("EMF_ERROR_INVALID_PARAM");
2246 *err = EMF_ERROR_INVALID_PARAM;
2250 int cid_length = RANDOM_NUMBER_LENGTH + strlen(hostname) + 2, random_number_1, random_number_2, random_number_3, random_number_4;
2251 char *cid_string = NULL;
2253 cid_string = malloc(cid_length);
2257 *err = EMF_ERROR_OUT_OF_MEMORY;
2261 memset(cid_string, 0, cid_length);
2263 srand(time(NULL) + rand());
2264 random_number_1 = rand() * rand();
2265 random_number_2 = rand() * rand();
2266 random_number_3 = rand() * rand();
2267 random_number_4 = rand() * rand();
2269 SNPRINTF(cid_string, cid_length, "<%08x%08x%08x%08x@%s>", random_number_1, random_number_2, random_number_3, random_number_4, hostname);
2272 *err = EMF_ERROR_NONE;
2274 EM_DEBUG_FUNC_END("cid_string [%s]", cid_string);
2279 /* ------ attach_part ----------------------------------------------------- */
2280 /* data : if filename NULL, content data. */
2281 /* else absolute path of file to be attached. */
2282 /* data_len : length of data. if filename not NULL, ignored. */
2283 /* file_name : attahcment name. */
2284 static int attach_part(BODY *body, const unsigned char *data, int data_len, char *filename, char *content_sub_type, int is_inline, int *err_code)
2286 EM_DEBUG_FUNC_BEGIN("body[%p], data[%s], data_len[%d], filename[%s], content_sub_type[%s], err_code[%p]", body, data, data_len, filename, content_sub_type, err_code);
2289 int error = EMF_ERROR_NONE;
2290 int has_special_character = 0;
2291 int base64_file_name_length = 0;
2294 gsize bytes_written;
2295 char *encoded_file_name = NULL;
2296 char *extension = NULL;
2297 char *base64_file_name = NULL;
2298 char *result_file_name = NULL;
2299 char content_disposition[100] = { 0, };
2300 PARAMETER *last_param = NULL;
2301 PARAMETER *param = NULL;
2302 PART *last_part = NULL;
2304 SIZEDTEXT source_text;
2305 GError *glib_error = NULL;
2306 CHARSET *result_charset = NULL;
2309 EM_DEBUG_EXCEPTION("EMF_ERROR_INVALID_PARAM");
2310 error = EMF_ERROR_INVALID_PARAM;
2314 if (body->nested.part) {
2315 last_part = body->nested.part;
2317 if (last_part != NULL) {
2318 while (last_part->next)
2319 last_part = last_part->next;
2324 part = mail_newbody_part();
2326 EM_DEBUG_EXCEPTION("mail_newbody_part failed...");
2327 error = EMF_ERROR_OUT_OF_MEMORY;
2334 last_part->next = part;
2336 body->nested.part = part;
2341 /* content_data = (unsigned char *)fs_get(data_len + 1); */
2342 /* memcpy(content_data, data, data_len); */
2343 /* content_data[data_len] = 0; */
2345 /* part->body.contents.text.data = content_data; */
2346 /* part->body.contents.text.size = data_len; */
2348 if (filename) { /* attachment */
2349 source_text.data = (unsigned char*)filename;
2350 source_text.size = strlen(filename);
2352 result_charset = (CHARSET*)utf8_infercharset(&source_text);
2354 if(result_charset) {
2355 EM_DEBUG_LOG("return_charset->name [%s]", result_charset->name);
2356 encoded_file_name = (char*)g_convert (filename, -1, "UTF-8", result_charset->name, &bytes_read, &bytes_written, &glib_error);
2360 while(filename[i]) {
2361 if(filename[i++] & 0x80) {
2362 has_special_character = 1;
2366 EM_DEBUG_LOG("has_special_character [%d]", has_special_character);
2367 if(has_special_character)
2368 encoded_file_name = (char*)g_convert (filename, -1, "UTF-8", "EUC-KR", &bytes_read, &bytes_written, &glib_error);
2371 EM_DEBUG_LOG("encoded_file_name [%s]", encoded_file_name);
2373 if(encoded_file_name == NULL)
2374 encoded_file_name = strdup(filename);
2376 if(!em_core_encode_base64(encoded_file_name, strlen(encoded_file_name), &base64_file_name, (unsigned long*)&base64_file_name_length, &error)) {
2377 EM_DEBUG_EXCEPTION("em_core_encode_base64 failed. error [%d]", error);
2381 result_file_name = em_core_replace_string(base64_file_name, "\015\012", "");
2383 EM_DEBUG_LOG("base64_file_name_length [%d]", base64_file_name_length);
2385 if(result_file_name) {
2386 EM_SAFE_FREE(encoded_file_name);
2387 encoded_file_name = em_core_malloc(strlen(result_file_name) + 15);
2388 if(!encoded_file_name) {
2389 EM_DEBUG_EXCEPTION("em_core_malloc failed.");
2392 snprintf(encoded_file_name, strlen(result_file_name) + 15, "=?UTF-8?B?%s?=", result_file_name);
2393 EM_DEBUG_LOG("encoded_file_name [%s]", encoded_file_name);
2396 extension = em_core_get_extension_from_file_path(filename, NULL);
2398 part->body.type = em_core_get_content_type(extension, NULL);
2399 if(part->body.type == TYPEIMAGE)
2400 part->body.subtype = strdup(extension);
2402 part->body.subtype = cpystr("octet-stream");
2404 part->body.encoding = ENCBINARY;
2405 part->body.size.bytes = data_len;
2408 part->body.sparep = EM_SAFE_STRDUP((char *)data); /* file path */
2410 part->body.sparep = NULL;
2412 SNPRINTF(content_disposition, sizeof(content_disposition), "%s", "attachment");
2414 part->body.disposition.type = cpystr(content_disposition);
2416 /* BODY PARAMETER */
2417 /* another parameter or get parameter-list from this function-parameter */
2418 param = mail_newbody_parameter();
2419 if (param == NULL) {
2420 EM_DEBUG_EXCEPTION("mail_newbody_parameter failed...");
2421 error = EMF_ERROR_OUT_OF_MEMORY;
2425 param->attribute = cpystr("name");
2426 param->value = cpystr(encoded_file_name);
2429 last_part->body.parameter = last_param;
2433 part->body.id = em_core_generate_content_id_string("com.samsung.slp.email", &error);
2434 part->body.type = TYPEIMAGE;
2435 /* EM_SAFE_FREE(part->body.subtype); */
2436 /* part->body.subtype = EM_SAFE_STRDUP(content_sub_type); */
2439 /* DISPOSITION PARAMETER */
2440 param = mail_newbody_parameter();
2441 if (param == NULL) {
2442 EM_DEBUG_EXCEPTION("mail_newbody_parameter failed...");
2443 error = EMF_ERROR_OUT_OF_MEMORY;
2447 param->attribute = cpystr("filename");
2448 param->value = cpystr(encoded_file_name);
2451 last_part->body.disposition.parameter = last_param;
2454 last_part->body.disposition.type = EM_SAFE_STRDUP("inline");
2457 /* text body (plain/html) */
2458 part->body.type = TYPETEXT;
2460 part->body.size.bytes = data_len;
2462 part->body.sparep = EM_SAFE_STRDUP((char *)data); /* file path */
2464 part->body.sparep = NULL;
2467 if (!content_sub_type) {
2468 /* Plain text body */
2469 part->body.encoding = ENC8BIT;
2470 part->body.subtype = cpystr("plain");
2471 last_param = part->body.parameter;
2473 if (last_param != NULL) {
2474 while (last_param->next)
2475 last_param = last_param->next;
2478 param = mail_newbody_parameter();
2480 if (param == NULL) {
2481 EM_DEBUG_EXCEPTION("mail_newbody_parameter failed...");
2482 error = EMF_ERROR_OUT_OF_MEMORY;
2486 param->attribute = cpystr("CHARSET");
2489 gchar *extract_charset_plain = g_path_get_basename((const gchar *)data);
2490 if (extract_charset_plain != NULL && extract_charset_plain[0] != '\0')
2491 param->value = cpystr(extract_charset_plain);
2492 g_free(extract_charset_plain);
2495 param->value = cpystr("UTF-8");
2498 param->value = cpystr("UTF-8");
2502 if (last_param != NULL)
2503 last_param->next = param;
2505 part->body.parameter = param;
2508 /* HTML text body */
2509 part->body.encoding = ENC8BIT;
2510 part->body.subtype = cpystr(content_sub_type);
2512 last_param = part->body.parameter;
2514 if (last_param != NULL) {
2515 while (last_param->next)
2516 last_param = last_param->next;
2519 param = mail_newbody_parameter();
2521 if (param == NULL) {
2522 EM_DEBUG_EXCEPTION("mail_newbody_parameter failed...");
2523 error = EMF_ERROR_OUT_OF_MEMORY;
2527 param->attribute = cpystr("CHARSET");
2531 gchar *extract_charset = g_path_get_basename((const gchar *)data);
2532 if (extract_charset != NULL) {
2533 if ((pHtml = strstr(extract_charset, ".htm")) != NULL) {
2534 extract_charset[pHtml-extract_charset] = '\0';
2535 param->value = cpystr(extract_charset);
2540 param->value = cpystr("UTF-8");
2542 EM_SAFE_FREE(extract_charset);
2545 param->value = cpystr("UTF-8");
2548 if (last_param != NULL)
2549 last_param->next = param;
2551 part->body.parameter = param;
2554 /* NOTE : need to require this code. */
2555 /* sprintf(content_disposition, "%s\0", "inline"); */
2557 SNPRINTF(content_disposition, sizeof(content_disposition), "%s", "inline");
2558 part->body.disposition.type = cpystr(content_disposition);
2565 EM_SAFE_FREE(encoded_file_name);
2566 EM_SAFE_FREE(base64_file_name);
2567 if (err_code != NULL)
2569 EM_DEBUG_FUNC_END();
2573 static PART *attach_mutipart_with_sub_type(BODY *parent_body, char *sub_type, int *err_code)
2575 EM_DEBUG_FUNC_BEGIN("parent_body[%p], sub_type [%s], err_code[%p]", parent_body, sub_type, err_code);
2577 int error = EMF_ERROR_NONE;
2579 PART *tail_part_cur = NULL;
2580 PART *new_part = NULL;
2582 if (!parent_body || !sub_type) {
2583 EM_DEBUG_EXCEPTION("EMF_ERROR_INVALID_PARAM");
2584 error = EMF_ERROR_INVALID_PARAM;
2588 if (parent_body->nested.part) {
2589 tail_part_cur = parent_body->nested.part;
2591 if (tail_part_cur != NULL) {
2592 while (tail_part_cur->next)
2593 tail_part_cur = tail_part_cur->next;
2597 new_part = mail_newbody_part();
2599 if (new_part == NULL) {
2600 EM_DEBUG_EXCEPTION("EMF_ERROR_OUT_OF_MEMORY");
2601 error = EMF_ERROR_OUT_OF_MEMORY;
2606 new_part->next = NULL;
2607 new_part->body.type = TYPEMULTIPART;
2608 new_part->body.subtype = EM_SAFE_STRDUP(sub_type);
2611 tail_part_cur->next = new_part;
2613 parent_body->nested.part = new_part;
2620 EM_DEBUG_FUNC_END();
2625 static int attach_attachment_to_body(BODY **multipart_body, BODY *text_body, emf_attachment_info_t *atch, int *err_code)
2627 EM_DEBUG_FUNC_BEGIN("multipart_body[%p], text_body[%p], atch[%p], err_code[%p]", multipart_body, text_body, atch, err_code);
2630 int error = EMF_ERROR_NONE;
2631 BODY *frame_body = NULL;
2632 /* make multipart body(multipart frame_body..) .. that has not content.. */
2634 if (!multipart_body || !text_body || !atch) {
2635 EM_DEBUG_EXCEPTION(" multipart_body[%p], text_body[%p], atch[%p]", multipart_body, text_body, atch);
2636 error = EMF_ERROR_INVALID_PARAM;
2640 frame_body = mail_newbody();
2641 if (frame_body == NULL) {
2642 EM_DEBUG_EXCEPTION("mail_newbody failed...");
2643 error = EMF_ERROR_OUT_OF_MEMORY;
2647 frame_body->type = TYPEMULTIPART;
2648 frame_body->contents.text.data = NULL;
2649 frame_body->contents.text.size = 0;
2650 frame_body->size.bytes = 0;
2652 /* insert original text_body to frame_body.. */
2653 if (!attach_part(frame_body, text_body->sparep, 0, NULL, NULL, false, &error)) {
2654 EM_DEBUG_EXCEPTION(" attach_part failed [%d]", error);
2658 /* insert files.. */
2659 emf_attachment_info_t *p = atch;
2664 EM_DEBUG_LOG("insert files - attachment id[%d]", p->attachment_id);
2665 if (stat(p->savename, &st_buf) == 0) {
2667 if (!em_core_get_file_name(p->savename, &name, &error)) {
2668 EM_DEBUG_EXCEPTION("em_core_get_file_name failed [%d]", error);
2675 if (!attach_part(frame_body, (unsigned char *)p->savename, 0, name, NULL, false, &error)) {
2676 EM_DEBUG_EXCEPTION("attach_part failed [%d]", error);
2688 *multipart_body = frame_body;
2689 else if (frame_body != NULL)
2690 mail_free_body(&frame_body);
2692 if (err_code != NULL)
2694 EM_DEBUG_FUNC_END();
2698 static char *em_core_encode_rfc2047_text(char *utf8_text, int *err_code)
2700 EM_DEBUG_FUNC_BEGIN("utf8_text[%s], err_code[%p]", utf8_text, err_code);
2702 if (utf8_text == NULL) {
2703 if (err_code != NULL)
2704 *err_code = EMF_ERROR_INVALID_PARAM;
2708 gsize len = strlen(utf8_text);
2710 EM_DEBUG_FUNC_END();
2713 return g_strdup_printf("=?UTF-8?B?%s?=", g_base64_encode((const guchar *)utf8_text, len));
2715 return EM_SAFE_STRDUP("");
2718 static void em_core_encode_rfc2047_address(ADDRESS *address, int *err_code)
2720 EM_DEBUG_FUNC_BEGIN("address[%p], err_code[%p]", address, err_code);
2723 if (address->personal) {
2724 char *rfc2047_personal = em_core_encode_rfc2047_text(address->personal, err_code);
2725 EM_SAFE_FREE(address->personal);
2726 address->personal = rfc2047_personal;
2728 address = address->next;
2730 EM_DEBUG_FUNC_END();
2733 #define DATE_STR_LENGTH 100
2734 /* Description : send mail to network(and save to sent-mailbox) or draft-mailbox, */
2737 /* is_draft : this mail is draft mail. */
2738 /* file_path : path of file that rfc822 data will be written to. */
2739 EXPORT_API int em_core_mail_get_rfc822(emf_mail_t *mail, ENVELOPE **env, char **file_path, emf_option_t *sending_option, int *err_code)
2741 EM_DEBUG_FUNC_BEGIN("mail[%p], env[%p], file_path[%p], sending_option[%p], err_code[%p]", mail, env, file_path, sending_option, err_code);
2744 int error = EMF_ERROR_NONE;
2746 ENVELOPE *envelope = NULL;
2747 BODY *text_body = NULL, *html_body = NULL;
2748 BODY *root_body = NULL;
2749 PART *part_for_html = NULL, *part_for_text = NULL;
2750 emf_extra_flag_t extra_flag;
2752 int is_incomplete = 0;
2753 emf_account_t *ref_account = NULL;
2756 if (!mail || !mail->info || !mail->head) {
2758 EM_DEBUG_EXCEPTION("mail->info[%p], mail->head[%p]", mail->info, mail->head);
2760 error = EMF_ERROR_INVALID_PARAM;
2764 if (mail->info->extra_flags.report != EMF_MAIL_REPORT_MDN && !mail->body) {
2765 EM_DEBUG_EXCEPTION("mail->body[%p]", mail->body);
2766 error = EMF_ERROR_INVALID_PARAM;
2771 ref_account = em_core_get_account_reference(mail->info->account_id);
2773 EM_DEBUG_EXCEPTION("em_core_get_account_reference failed [%d]", mail->info->account_id);
2774 error = EMF_ERROR_INVALID_ACCOUNT;
2778 if (!(envelope = mail_newenvelope())) {
2779 EM_DEBUG_EXCEPTION("mail_newenvelope failed...");
2780 error = EMF_ERROR_OUT_OF_MEMORY;
2784 is_incomplete = mail->info->flags.draft || (mail->info->extra_flags.status == EMF_MAIL_STATUS_SENDING);/* 4 */
2786 if (is_incomplete) {
2787 if (ref_account->email_addr && ref_account->email_addr[0] != '\0') {
2788 char *p = cpystr(ref_account->email_addr);
2791 EM_DEBUG_EXCEPTION("cpystr failed...");
2792 error = EMF_ERROR_OUT_OF_MEMORY;
2796 EM_DEBUG_LOG("Assign envelop->from");
2797 if (mail->head && mail->head->from) {
2799 em_core_skip_whitespace(mail->head->from , &pAdd);
2800 EM_DEBUG_LOG("address[pAdd][%s]", pAdd);
2802 rfc822_parse_adrlist(&envelope->from, pAdd, ref_account->sending_server_addr);
2807 envelope->from = rfc822_parse_mailbox(&p, NULL);
2811 if (!envelope->from) {
2812 EM_DEBUG_EXCEPTION("rfc822_parse_mailbox failed...");
2814 error = EMF_ERROR_INVALID_ADDRESS;
2819 if (envelope->from->personal == NULL) {
2820 if (sending_option && sending_option->display_name_from && sending_option->display_name_from[0] != '\0')
2821 envelope->from->personal = cpystr(sending_option->display_name_from);
2823 envelope->from->personal = (ref_account->display_name && ref_account->display_name[0] != '\0') ? cpystr(ref_account->display_name) : NULL;
2828 if (ref_account->return_addr && ref_account->return_addr[0] != '\0') {
2829 char *p = cpystr(ref_account->return_addr);
2832 EM_DEBUG_EXCEPTION("cpystr failed...");
2834 error = EMF_ERROR_OUT_OF_MEMORY;
2837 envelope->return_path = rfc822_parse_mailbox(&p, NULL);
2842 if (!mail->head->from || !mail->head->to) {
2843 EM_DEBUG_EXCEPTION("mail->head->from[%p], mail->head->to[%p]", mail->head->from, mail->head->to);
2844 error = EMF_ERROR_INVALID_MAIL;
2850 if (mail->head->from) {
2851 for (i = 0, j = strlen(mail->head->from); i < j; i++) {
2852 if (mail->head->from[i] == ';')
2853 mail->head->from[i] = ',';
2857 if (mail->head->return_path) {
2858 for (i = 0, j = strlen(mail->head->return_path); i < j; i++) {
2859 if (mail->head->return_path[i] == ';')
2860 mail->head->return_path[i] = ',';
2863 em_core_skip_whitespace(mail->head->from , &pAdd);
2864 EM_DEBUG_LOG("address[pAdd][%s]", pAdd);
2866 rfc822_parse_adrlist(&envelope->from, pAdd, ref_account->sending_server_addr);
2870 em_core_skip_whitespace(mail->head->return_path , &pAdd);
2871 EM_DEBUG_LOG("address[pAdd][%s]", pAdd);
2873 rfc822_parse_adrlist(&envelope->return_path, pAdd, ref_account->sending_server_addr);
2881 if (mail->head->to) {
2882 for (i = 0, j = strlen(mail->head->to); i < j; i++) {
2883 if (mail->head->to[i] == ';')
2884 mail->head->to[i] = ',';
2888 if (mail->head->cc) {
2889 for (i = 0, j = strlen(mail->head->cc); i < j; i++) {
2890 if (mail->head->cc[i] == ';')
2891 mail->head->cc[i] = ',';
2895 if (mail->head->bcc) {
2896 for (i = 0, j = strlen(mail->head->bcc); i < j; i++) {
2897 if (mail->head->bcc[i] == ';')
2898 mail->head->bcc[i] = ',';
2903 em_core_skip_whitespace(mail->head->to , &pAdd);
2904 EM_DEBUG_LOG("address[pAdd][%s]", pAdd);
2906 rfc822_parse_adrlist(&envelope->to, pAdd, ref_account->sending_server_addr);
2910 EM_DEBUG_LOG("address[mail->head->cc][%s]", mail->head->cc);
2911 em_core_skip_whitespace(mail->head->cc , &pAdd);
2912 EM_DEBUG_LOG("address[pAdd][%s]", pAdd);
2914 rfc822_parse_adrlist(&envelope->cc, pAdd, ref_account->sending_server_addr);
2918 em_core_skip_whitespace(mail->head->bcc , &pAdd);
2919 rfc822_parse_adrlist(&envelope->bcc, pAdd, ref_account->sending_server_addr);
2923 em_core_encode_rfc2047_address(envelope->return_path, &error);
2924 em_core_encode_rfc2047_address(envelope->from, &error);
2925 em_core_encode_rfc2047_address(envelope->sender, &error);
2926 em_core_encode_rfc2047_address(envelope->reply_to, &error);
2927 em_core_encode_rfc2047_address(envelope->to, &error);
2928 em_core_encode_rfc2047_address(envelope->cc, &error);
2929 em_core_encode_rfc2047_address(envelope->bcc, &error);
2931 if (mail->head->subject)
2932 envelope->subject = em_core_encode_rfc2047_text(mail->head->subject, &error);
2934 char date_str[DATE_STR_LENGTH + 1] = { 0, };
2936 rfc822_date(date_str);
2938 if (!is_incomplete) {
2941 /* modified by stonyroot - prevent issue */
2942 memset(&tm1, 0x00, sizeof(tm1));
2944 tm1.tm_year = mail->head->datetime.year - 1900;
2945 tm1.tm_mon = mail->head->datetime.month - 1;
2946 tm1.tm_mday = mail->head->datetime.day;
2947 tm1.tm_hour = mail->head->datetime.hour;
2948 tm1.tm_min = mail->head->datetime.minute;
2949 tm1.tm_sec = mail->head->datetime.second;
2952 time_t t = mktime(&tm1);
2954 char buf[256] = {0, };
2957 strftime(buf, 128, "%a, %e %b %Y %H : %M : %S ", localtime(&t));
2959 strftime(buf, 128, "%a, %e %b %Y %H : %M : %S ", (const struct tm *)&tm1);
2960 /* append last 5byes("+0900") */
2961 strncat(buf, date_str + (strlen(date_str) - 5), DATE_STR_LENGTH);
2962 strncpy(date_str, buf, DATE_STR_LENGTH);
2965 envelope->date = (unsigned char *)cpystr((const char *)date_str);
2967 memcpy(&extra_flag, &mail->info->extra_flags, sizeof(emf_extra_flag_t));
2969 /* check report mail */
2970 if (mail->info->extra_flags.report != EMF_MAIL_REPORT_MDN) {
2971 /* Non-report mail */
2972 EM_DEBUG_LOG("mail->body->plain[%s]", mail->body->plain);
2973 EM_DEBUG_LOG("mail->body->html[%s]", mail->body->html);
2974 EM_DEBUG_LOG("mail->body->attachment_num[%d]", mail->body->attachment_num);
2977 if ((mail->body->attachment_num > 0) || (mail->body->plain && mail->body->html)) {
2978 EM_DEBUG_LOG("attachment_num : %d", mail->body->attachment_num);
2979 root_body = mail_newbody();
2981 if (root_body == NULL) {
2982 EM_DEBUG_EXCEPTION("mail_newbody failed...");
2983 error = EMF_ERROR_OUT_OF_MEMORY;
2987 root_body->type = TYPEMULTIPART;
2988 root_body->subtype = EM_SAFE_STRDUP("MIXED");
2989 root_body->contents.text.data = NULL;
2990 root_body->contents.text.size = 0;
2991 root_body->size.bytes = 0;
2993 part_for_text = attach_mutipart_with_sub_type(root_body, "ALTERNATIVE", &error);
2995 if (!part_for_text) {
2996 EM_DEBUG_EXCEPTION("attach_mutipart_with_sub_type [part_for_text] failed [%d]", error);
3000 text_body = &part_for_text->body;
3002 if (mail->body->plain && strlen(mail->body->plain) > 0) {
3003 EM_DEBUG_LOG("body->plain[%s]", mail->body->plain);
3004 if (!attach_part(text_body, (unsigned char *)mail->body->plain, 0, NULL, NULL, false, &error)) {
3005 EM_DEBUG_EXCEPTION("attach_part failed [%d]", error);
3010 if (mail->body->html && strlen(mail->body->html) > 0) {
3011 EM_DEBUG_LOG("body->html[%s]", mail->body->html);
3013 part_for_html = attach_mutipart_with_sub_type(text_body, "RELATED", &error);
3014 if (!part_for_html) {
3015 EM_DEBUG_EXCEPTION("attach_mutipart_with_sub_type [part_for_html] failed [%d]", error);
3019 if (!attach_part(&(part_for_html->body) , (unsigned char *)mail->body->html, 0, NULL, "html", false, &error)) {
3020 EM_DEBUG_EXCEPTION("attach_part failed [%d]", error);
3024 if (mail->body->plain) {
3025 EM_SAFE_FREE(part_for_text->subtype);
3026 part_for_text->subtype = EM_SAFE_STRDUP("ALTERNATIVE");
3031 if (mail->body->attachment) {
3032 emf_attachment_info_t *atch = mail->body->attachment;
3034 BODY *body_to_attach = NULL;
3038 EM_DEBUG_LOG("atch->savename[%s], atch->name[%s]", atch->savename, atch->name);
3039 if (stat(atch->savename, &st_buf) == 0) {
3040 EM_DEBUG_LOG("atch->name[%s]", atch->name);
3042 if (!em_core_get_file_name(atch->savename, &name, &error)) {
3043 EM_DEBUG_EXCEPTION("em_core_get_file_name failed [%d]", error);
3049 EM_DEBUG_LOG("name[%s]", name);
3051 if (atch->inline_content && part_for_html)
3052 body_to_attach = &(part_for_html->body);
3054 body_to_attach = root_body;
3056 if (!attach_part(body_to_attach, (unsigned char *)atch->savename, 0, name, NULL, atch->inline_content, &error)) {
3057 EM_DEBUG_EXCEPTION("attach_part failed [%d]", error);
3070 text_body = mail_newbody();
3072 if (text_body == NULL) {
3073 EM_DEBUG_EXCEPTION("mail_newbody failed...");
3075 error = EMF_ERROR_OUT_OF_MEMORY;
3079 text_body->type = TYPETEXT;
3080 text_body->encoding = ENC8BIT;
3081 if (mail->body->plain || mail->body->html)
3082 text_body->sparep = EM_SAFE_STRDUP(mail->body->plain ? mail->body->plain : mail->body->html);
3084 text_body->sparep = NULL;
3086 if (mail->body->html != NULL && mail->body->html[0] != '\0')
3087 text_body->subtype = EM_SAFE_STRDUP("html");
3088 if (text_body->sparep)
3089 text_body->size.bytes = strlen(text_body->sparep);
3091 text_body->size.bytes = 0;
3094 else { /* Report mail */
3095 EM_DEBUG_LOG("REPORT MAIL");
3096 envelope->references = cpystr(mail->head->mid);
3098 if (em_core_mail_get_report_body(envelope, &root_body, &error)) {
3100 mail->body = em_core_malloc(sizeof(emf_mail_body_t));
3102 EM_DEBUG_EXCEPTION("malloc failed...");
3103 error = EMF_ERROR_OUT_OF_MEMORY;
3107 mail->body->plain = EM_SAFE_STRDUP(root_body->nested.part->body.sparep);
3108 mail->body->attachment_num = 1;
3110 mail->body->attachment = em_core_malloc(sizeof(emf_attachment_info_t));
3111 if (!mail->body->attachment) {
3112 EM_DEBUG_EXCEPTION("malloc failed...");
3113 EM_SAFE_FREE(mail->body->plain);
3114 error = EMF_ERROR_OUT_OF_MEMORY;
3118 mail->body->attachment->downloaded = 1;
3119 mail->body->attachment->savename = EM_SAFE_STRDUP(root_body->nested.part->next->body.sparep);
3123 if (!em_core_get_file_name(mail->body->attachment->savename, &p, &error)) {
3124 EM_DEBUG_EXCEPTION("em_core_get_file_name failed [%d]", error);
3128 mail->body->attachment->name = cpystr(p);
3135 EM_DEBUG_LOG("write rfc822 : file_path[%s]", file_path);
3138 html_body = &(part_for_html->body);
3140 if (!em_core_write_rfc822(envelope, root_body ? root_body : text_body, html_body, extra_flag, &fname, &error)) {
3141 EM_DEBUG_EXCEPTION("em_core_write_rfc822 failed [%d]", error);
3151 if ((ret == true) && (env != NULL))
3153 else if (envelope != NULL)
3154 mail_free_envelope(&envelope);
3156 if (text_body != NULL)
3157 mail_free_body(&text_body);
3159 if (root_body != NULL)
3160 mail_free_body(&root_body);
3162 if (err_code != NULL)
3164 EM_DEBUG_FUNC_END("ret [%d]", ret);
3168 static int em_core_mail_get_report_body(ENVELOPE *envelope, BODY **multipart_body, int *err_code)
3170 EM_DEBUG_FUNC_BEGIN("envelope[%p], mulitpart_body[%p], err_code[%p]", envelope, multipart_body, err_code);
3173 int err = EMF_ERROR_NONE;
3175 BODY *m_body = NULL;
3176 BODY *p_body = NULL;
3177 BODY *text_body = NULL;
3178 PARAMETER *param = NULL;
3179 emf_attachment_info_t atch;
3182 char buf[512] = {0x00, };
3185 if (!envelope || !multipart_body) {
3186 EM_DEBUG_EXCEPTION(" envelope[%p], mulitpart_body[%p]", envelope, multipart_body);
3187 err = EMF_ERROR_INVALID_PARAM;
3191 if (!(text_body = mail_newbody())) {
3192 EM_DEBUG_EXCEPTION(" mail_newbody failed...");
3193 err = EMF_ERROR_OUT_OF_MEMORY;
3197 if (!em_core_get_temp_file_name(&fname, &err)) {
3198 EM_DEBUG_EXCEPTION(" em_core_get_temp_file_name failed [%d]", err);
3202 if (!(fp = fopen(fname, "wb+"))) {
3203 EM_DEBUG_EXCEPTION(" fopen failed - %s", fname);
3204 err = EMF_ERROR_SYSTEM_FAILURE; /* EMF_ERROR_UNKNOWN; */
3208 if (!envelope->from || !envelope->from->mailbox || !envelope->from->host) {
3209 if (!envelope->from)
3210 EM_DEBUG_EXCEPTION(" envelope->from[%p]", envelope->from);
3212 EM_DEBUG_LOG(" envelope->from->mailbox[%p], envelope->from->host[%p]", envelope->from->mailbox, envelope->from->host);
3214 err = EMF_ERROR_INVALID_PARAM;
3218 if (envelope->from->personal)
3219 SNPRINTF(buf, sizeof(buf), "%s <%s@%s>", envelope->from->personal, envelope->from->mailbox, envelope->from->host);
3221 SNPRINTF(buf, sizeof(buf), "%s@%s", envelope->from->mailbox, envelope->from->host);
3223 fprintf(fp, "Your message has been read by %s"CRLF_STRING, buf);
3224 fprintf(fp, "Date : %s", envelope->date);
3226 fclose(fp); fp = NULL;
3228 if (!em_core_get_file_size(fname, &sz, &err)) {
3229 EM_DEBUG_EXCEPTION(" em_core_get_file_size failed [%d]", err);
3233 text_body->type = TYPETEXT;
3234 text_body->encoding = ENC8BIT;
3235 text_body->sparep = fname;
3236 text_body->size.bytes = (unsigned long)sz;
3238 if (!em_core_get_temp_file_name(&fname, &err)) {
3239 EM_DEBUG_EXCEPTION(" em_core_get_temp_file_name failed [%d]", err);
3243 if (!(fp = fopen(fname, "wb+"))) {
3244 EM_DEBUG_EXCEPTION(" fopen failed - %s", fname);
3245 err = EMF_ERROR_SYSTEM_FAILURE; /* EMF_ERROR_UNKNOWN; */
3249 if (!envelope->references) {
3250 EM_DEBUG_EXCEPTION(" envelope->references[%p]", envelope->references);
3251 err = EMF_ERROR_INVALID_PARAM;
3255 fprintf(fp, "Final-Recipient : rfc822;%s@%s\r", envelope->from->mailbox, envelope->from->host);
3256 fprintf(fp, "Original-Message-ID: %s\r", envelope->references);
3257 fprintf(fp, "Disposition : manual-action/MDN-sent-manually; displayed");
3259 fclose(fp); fp = NULL;
3261 memset(&atch, 0x00, sizeof(atch));
3263 atch.savename = fname;
3265 if (!em_core_get_file_size(fname, &atch.size, &err)) {
3266 EM_DEBUG_EXCEPTION(" em_core_get_file_size failed [%d]", err);
3270 if (!attach_attachment_to_body(&m_body, text_body, &atch, &err)) {
3271 EM_DEBUG_EXCEPTION(" attach_attachment_to_body failed [%d]", err);
3275 text_body->contents.text.data = NULL;
3277 /* change mail header */
3279 /* set content-type to multipart/report */
3280 m_body->subtype = EM_SAFE_STRDUP("report");
3282 /* set report-type parameter in content-type */
3283 param = em_core_malloc(sizeof(PARAMETER));
3285 EM_DEBUG_EXCEPTION(" malloc failed...");
3286 err = EMF_ERROR_OUT_OF_MEMORY;
3290 param->attribute = EM_SAFE_STRDUP("report-type");
3291 param->value = EM_SAFE_STRDUP("disposition-notification");
3292 param->next = m_body->parameter;
3294 m_body->parameter = param;
3296 /* change body-header */
3298 p_body = &m_body->nested.part->next->body;
3300 /* set content-type to message/disposition-notification */
3301 p_body->type = TYPEMESSAGE;
3302 p_body->encoding = ENC7BIT;
3304 EM_SAFE_FREE(p_body->subtype);
3306 p_body->subtype = EM_SAFE_STRDUP("disposition-notification");
3309 mail_free_body_parameter(&p_body->parameter);
3310 mail_free_body_parameter(&p_body->disposition.parameter);
3312 EM_SAFE_FREE(p_body->disposition.type);
3314 p_body->disposition.type = EM_SAFE_STRDUP("inline");
3319 if ((ret == true) && (multipart_body != NULL))
3320 *multipart_body = m_body;
3321 else if (m_body != NULL)
3322 mail_free_body(&m_body);
3324 if (text_body != NULL)
3325 mail_free_body(&text_body);
3330 EM_SAFE_FREE(fname);
3332 if (err_code != NULL)
3338 EXPORT_API int em_core_get_body_buff(char *file_path, char **buff)
3340 EM_DEBUG_FUNC_BEGIN();
3345 char *read_buff = NULL;
3349 r_fp = fopen(file_path, "r");
3352 EM_DEBUG_EXCEPTION(" Filename %s failed to open", file_path);
3358 stat(file_path, &stbuf);
3359 EM_DEBUG_LOG(" File Size [ %d ] ", stbuf.st_size);
3360 read_buff = calloc(1, (stbuf.st_size+ 1));
3361 read_size = fread(read_buff, 1, stbuf.st_size, r_fp);
3362 read_buff[stbuf.st_size] = '\0';
3365 EM_DEBUG_EXCEPTION("file read failed - %s", file_path);
3366 EM_SAFE_FREE(read_buff);
3375 if (r_fp) /* Prevent Defect - 17424 */
3381 EXPORT_API int em_core_mail_get_envelope_body_struct(emf_mail_t *mail,
3384 BODY **multipart_body,
3387 EM_DEBUG_FUNC_BEGIN("mail[%p], env[%p], text_body[%p], multipart_body[%p], err_code[%p]", mail, env, text_body, multipart_body, err_code);
3390 int error = EMF_ERROR_NONE;
3391 ENVELOPE *envelope = NULL;
3392 BODY *txt_body = NULL;
3393 BODY *multi_part_body = NULL;
3394 emf_extra_flag_t extra_flag;
3395 int is_incomplete = 0;
3396 emf_account_t *ref_account = NULL;
3399 if (!mail || !mail->info || !mail->head || !mail->body) {
3400 EM_DEBUG_EXCEPTION("EMF_ERROR_INVALID_PARAM");
3401 error = EMF_ERROR_INVALID_PARAM;
3405 ref_account = em_core_get_account_reference(mail->info->account_id);
3408 EM_DEBUG_EXCEPTION(" em_core_get_account_reference failed [%d]", mail->info->account_id);
3409 error = EMF_ERROR_INVALID_ACCOUNT;
3413 if (!(envelope = mail_newenvelope())) {
3414 EM_DEBUG_EXCEPTION(" mail_newenvelope failed...");
3415 error = EMF_ERROR_OUT_OF_MEMORY;
3419 EM_DEBUG_LOG(" mail_newenvelope created...");
3420 is_incomplete = mail->info->flags.draft || mail->info->extra_flags.status == EMF_MAIL_STATUS_SENDING;/* 4; */
3421 if (is_incomplete) {
3422 if (ref_account->email_addr) {
3423 char *p = EM_SAFE_STRDUP(ref_account->email_addr);
3425 envelope->from = rfc822_parse_mailbox(&p, NULL);
3426 /* mailbox = user id; host = mail-server-addr; */
3427 if (!envelope->from) {
3428 EM_DEBUG_EXCEPTION("rfc822_parse_mailbox failed...");
3429 error = EMF_ERROR_INVALID_ADDRESS;
3433 envelope->from->personal = ref_account->display_name ? cpystr(ref_account->display_name) : NULL;
3437 if (ref_account->return_addr) {
3438 char *p = EM_SAFE_STRDUP(ref_account->return_addr);
3439 envelope->return_path = rfc822_parse_mailbox(&p, NULL);
3443 if (!mail->head->from || !mail->head->to) {
3444 EM_DEBUG_EXCEPTION(" mail->head->from[%p], mail->head->to[%p]", mail->head->from, mail->head->to);
3445 error = EMF_ERROR_INVALID_MAIL;
3449 em_core_skip_whitespace(mail->head->from , &pAdd);
3450 EM_DEBUG_LOG("address[pAdd][%s]", pAdd);
3452 rfc822_parse_adrlist(&envelope->from, pAdd, ref_account->sending_server_addr);
3456 em_core_skip_whitespace(mail->head->return_path , &pAdd);
3457 EM_DEBUG_LOG("address[pAdd][%s]", pAdd);
3458 rfc822_parse_adrlist(&envelope->return_path, pAdd, ref_account->sending_server_addr);
3466 if (mail->head->to) {
3467 for (i = 0, j = strlen(mail->head->to); i < j; i++) {
3468 if (mail->head->to[i] == ';')
3469 mail->head->to[i] = ',';
3473 if (mail->head->cc) {
3474 for (i = 0, j = strlen(mail->head->cc); i < j; i++) {
3475 if (mail->head->cc[i] == ';')
3476 mail->head->cc[i] = ',';
3480 if (mail->head->bcc) {
3481 for (i = 0, j = strlen(mail->head->bcc); i < j; i++) {
3482 if (mail->head->bcc[i] == ';')
3483 mail->head->bcc[i] = ',';
3488 em_core_skip_whitespace(mail->head->to , &pAdd);
3489 EM_DEBUG_LOG("address[pAdd][%s]", pAdd);
3491 rfc822_parse_adrlist(&envelope->to, pAdd, ref_account->sending_server_addr);
3495 em_core_skip_whitespace(mail->head->cc , &pAdd);
3497 rfc822_parse_adrlist(&envelope->cc, pAdd, ref_account->sending_server_addr);
3501 em_core_skip_whitespace(mail->head->bcc , &pAdd);
3502 EM_DEBUG_LOG("address[pAdd][%s]", pAdd);
3503 rfc822_parse_adrlist(&envelope->bcc, pAdd, ref_account->sending_server_addr);
3506 em_core_encode_rfc2047_address(envelope->return_path, &error);
3507 em_core_encode_rfc2047_address(envelope->from, &error);
3508 em_core_encode_rfc2047_address(envelope->sender, &error);
3509 em_core_encode_rfc2047_address(envelope->reply_to, &error);
3510 em_core_encode_rfc2047_address(envelope->to, &error);
3511 em_core_encode_rfc2047_address(envelope->cc, &error);
3512 em_core_encode_rfc2047_address(envelope->bcc, &error);
3515 if (mail->head->subject)
3516 envelope->subject = em_core_encode_rfc2047_text(mail->head->subject, &error);
3518 char date_str[DATE_STR_LENGTH] = { 0, };
3520 rfc822_date(date_str);
3522 if (!is_incomplete) {
3525 /* modified by stonyroot - prevent issue */
3526 memset(&tm1, 0x00, sizeof(tm1));
3528 tm1.tm_year = mail->head->datetime.year - 1900;
3529 tm1.tm_mon = mail->head->datetime.month - 1;
3530 tm1.tm_mday = mail->head->datetime.day;
3531 tm1.tm_hour = mail->head->datetime.hour;
3532 tm1.tm_min = mail->head->datetime.minute;
3533 tm1.tm_sec = mail->head->datetime.second;
3536 time_t t = mktime(&tm1);
3538 char buf[256] = {0x00, };
3541 strftime(buf, 128, "%a, %e %b %Y %H : %M : %S ", localtime(&t));
3543 strftime(buf, 128, "%a, %e %b %Y %H : %M : %S ", (const struct tm *)&tm1);
3545 /* append last 5byes("+0900") */
3546 strncat(buf, date_str + (strlen(date_str) - 5), sizeof(buf) - 1);
3547 strncpy(date_str, buf, DATE_STR_LENGTH - 1);
3550 envelope->date = (unsigned char *)cpystr((const char *)date_str);
3552 memcpy(&extra_flag, &mail->info->extra_flags, sizeof(emf_extra_flag_t));
3554 /* check report mail */
3555 if (mail->info->extra_flags.report != EMF_MAIL_REPORT_MDN) {
3556 txt_body = mail_newbody();
3557 if (txt_body == NULL) {
3558 EM_DEBUG_EXCEPTION(" mail_newbody failed...");
3560 error = EMF_ERROR_OUT_OF_MEMORY;
3564 txt_body->type = TYPETEXT;
3565 txt_body->encoding = ENC8BIT;
3566 if (mail->body && mail->body->plain) {
3567 if (mail->body->plain)
3568 txt_body->sparep = EM_SAFE_STRDUP(mail->body->plain);
3570 txt_body->sparep = NULL;
3572 txt_body->size.bytes = (int)strlen(mail->body->plain);
3576 if (mail->body->attachment) {
3577 if (!attach_attachment_to_body(&multi_part_body, txt_body, mail->body->attachment, &error)) {
3578 EM_DEBUG_EXCEPTION("attach_attachment_to_body failed [%d]", error);
3584 else { /* Report mail */
3585 if (mail->head || mail->head->mid)
3586 envelope->references = cpystr(mail->head->mid);
3587 if (em_core_mail_get_report_body(envelope, &multi_part_body, &error)) {
3589 mail->body = em_core_malloc(sizeof(emf_mail_body_t));
3591 EM_DEBUG_EXCEPTION("malloc failed...");
3593 error = EMF_ERROR_OUT_OF_MEMORY;
3597 mail->body->plain = EM_SAFE_STRDUP(multi_part_body->nested.part->body.sparep);
3598 mail->body->attachment_num = 1;
3600 mail->body->attachment = em_core_malloc(sizeof(emf_attachment_info_t));
3601 if (!mail->body->attachment) {
3602 EM_DEBUG_EXCEPTION("malloc failed...");
3604 EM_SAFE_FREE(mail->body->plain);
3605 error = EMF_ERROR_OUT_OF_MEMORY;
3609 mail->body->attachment->downloaded = 1;
3610 mail->body->attachment->savename = EM_SAFE_STRDUP(multi_part_body->nested.part->next->body.sparep);
3613 if (!em_core_get_file_name(mail->body->attachment->savename, &p, &error)) {
3614 EM_DEBUG_EXCEPTION("em_core_get_file_name failed [%d]", error);
3619 mail->body->attachment->name = cpystr(p);
3629 if (txt_body != NULL)
3630 *text_body = txt_body;
3631 if (multi_part_body != NULL)
3632 *multipart_body = multi_part_body;
3635 if (envelope != NULL)
3636 mail_free_envelope(&envelope);
3637 if (txt_body != NULL)
3638 mail_free_body(&txt_body);
3639 if (multi_part_body != NULL)
3640 mail_free_body(&multi_part_body);
3643 if (err_code != NULL)