apply removal of mailbox_name field
[platform/core/messaging/email-service.git] / email-core / email-core-smtp.c
1 /*
2 *  email-service
3 *
4 * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
5 *
6 * Contact: Kyuho Jo <kyuho.jo@samsung.com>, Sunghyun Kwon <sh0701.kwon@samsung.com>
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 *
20 */
21
22 #include <stdio.h>
23 #include <string.h>
24 #include <stdlib.h>
25 #include <fcntl.h>
26 #include <sys/types.h>
27 #include <sys/stat.h>
28 #include <time.h>
29 #include <unistd.h>
30 #include <glib.h>
31 #include <alarm.h>
32
33 #include "email-internal-types.h"
34 #include "c-client.h"
35 #include "email-core-global.h"
36 #include "email-core-utils.h"
37 #include "email-storage.h"
38 #include "email-core-api.h"
39 #include "email-core-smtp.h"
40 #include "email-core-event.h"
41 #include "email-core-mailbox.h"
42 #include "email-core-mail.h"
43 #include "email-core-mime.h"
44 #include "email-core-smime.h"
45 #include "email-core-account.h"
46 #include "email-core-imap-mailbox.h"
47 #include "email-core-mailbox-sync.h"
48 #include "email-core-signal.h"
49 #include "email-core-alarm.h"
50 #include "email-utilities.h"
51 #include "email-convert.h"
52 #include "email-debug-log.h"
53
54 #undef min
55
56
57
58 #ifdef __FEATURE_SUPPORT_REPORT_MAIL__
59 static int emcore_get_report_mail_body(ENVELOPE *envelope, BODY **multipart_body, int *err_code);
60 #endif
61 static int emcore_make_envelope_from_mail(emstorage_mail_tbl_t *input_mail_tbl_data, ENVELOPE **output_envelope);
62 static int emcore_send_mail_smtp(SENDSTREAM *stream, ENVELOPE *env, char *data_file, int account_id, int mail_id,  int *err_code);
63
64 /* Functions from uw-imap-toolkit */
65 /* extern void *fs_get(size_t size); */
66 extern void rfc822_date(char *date);
67 extern long smtp_send(SENDSTREAM *stream, char *command, char *args);
68 extern long smtp_rcpt(SENDSTREAM *stream, ADDRESS *adr, long* error);
69
70 #ifndef __FEATURE_SEND_OPTMIZATION__
71 extern long smtp_soutr(void *stream, char *s);
72 #endif
73
74 #ifdef __FEATURE_SEND_OPTMIZATION__
75 extern long smtp_soutr_test(void *stream, char *s);
76 #endif
77
78
79
80
81 void mail_send_notify(email_send_status_t status, int total, int sent, int account_id, int mail_id,  int err_code)
82 {
83         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);
84
85         switch (status) {
86                 case EMAIL_SEND_CONNECTION_FAIL:
87                 case EMAIL_SEND_FINISH:
88                 case EMAIL_SEND_FAIL:
89                         break;
90
91                 case EMAIL_SEND_PROGRESS:
92                 default:
93                         break;
94         }
95         emcore_execute_event_callback(EMAIL_ACTION_SEND_MAIL, total, sent, status, account_id, mail_id, -1, err_code);
96         EM_DEBUG_FUNC_END();
97 }
98
99 /* ------ rfc822 handle ---------------------------------------------------*/
100 long buf_flush(void *stream, char *string)
101 {
102         EM_DEBUG_FUNC_BEGIN("stream[%p], string[%s]", stream, string);
103         EM_DEBUG_FUNC_END();
104         return 1;
105 }
106
107
108 #define RFC822_READ_BLOCK_SIZE    1024
109 #define RFC822_STRING_BUFFER_SIZE 1536
110
111 static char *emcore_find_img_tag(char *source_string)
112 {
113         EM_DEBUG_FUNC_BEGIN("source_string[%p]", source_string);
114
115         int cur = 0, string_length;
116         if (!source_string)
117                 return false;
118
119         string_length = EM_SAFE_STRLEN(source_string);
120
121         for (cur = 0; cur < string_length; cur++) {
122                 if (source_string[cur] == 'I' || source_string[cur] == 'i') {
123                         cur++;
124                         if (source_string[cur] == 'M' || source_string[cur] == 'm') {
125                                 cur++;
126                                 if (source_string[cur] == 'G' || source_string[cur] == 'g') {
127                                         EM_DEBUG_FUNC_END("%s", source_string + cur - 2);
128                                         return source_string + cur - 2;
129                                 }
130                         }
131                 }
132         }
133         EM_DEBUG_FUNC_END("Can't find");
134         return NULL;
135 }
136
137 #define CONTENT_ID_BUFFER_SIZE 512
138 static char *emcore_replace_inline_image_path_with_content_id(char *source_string, BODY *html_body, int *err_code)
139 {
140         EM_DEBUG_FUNC_BEGIN("source_string[%p], html_body[%p], err_code[%p]", source_string, html_body, err_code);
141
142         int  err = EMAIL_ERROR_NONE;
143         char content_id_buffer[CONTENT_ID_BUFFER_SIZE], file_name_buffer[512], new_string[512], *result_string = NULL, *input_string = NULL;
144         BODY *cur_body = NULL;
145         PART *cur_part = NULL;
146
147         if (!source_string || !html_body) {
148                 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
149                 err = EMAIL_ERROR_INVALID_PARAM;
150                 goto FINISH_OFF;
151         }
152
153         input_string = EM_SAFE_STRDUP(source_string);
154
155         cur_part = html_body->nested.part;
156
157         while (cur_part) {
158                 cur_body = &(cur_part->body);
159                 result_string = NULL; /*prevent 37865*/
160                 if (cur_body) {
161                         EM_DEBUG_LOG("Has body. id[%s]", cur_body->disposition.type);
162                         if (cur_body->disposition.type && cur_body->disposition.type[0] == 'i') {   /*  Is inline content? */
163                                 EM_DEBUG_LOG("Has inline content");
164                                 memset(content_id_buffer, 0, CONTENT_ID_BUFFER_SIZE);
165                                 if (cur_body->id) {
166                                         EM_SAFE_STRNCPY(content_id_buffer, cur_body->id + 1, CONTENT_ID_BUFFER_SIZE - 1); /*  Removing <, > */
167                                         /* prevent 34413 */
168                                         char *last_bracket = rindex(content_id_buffer, '>');
169                                         *last_bracket = NULL_CHAR;
170
171                                         /* if (emcore_get_attribute_value_of_body_part(cur_body->parameter, "name", file_name_buffer, CONTENT_ID_BUFFER_SIZE, false, &err)) { */
172                                         if (emcore_get_attribute_value_of_body_part(cur_body->parameter, "name", file_name_buffer, CONTENT_ID_BUFFER_SIZE, true, &err)) {
173                                                 EM_DEBUG_LOG("Content-ID[%s], filename[%s]", content_id_buffer, file_name_buffer);
174                                                 SNPRINTF(new_string, CONTENT_ID_BUFFER_SIZE, "cid:%s", content_id_buffer);
175                                                 result_string = em_replace_string(input_string, file_name_buffer, new_string);
176                                         }
177                                 }
178                         }
179                 }
180                 if (result_string) {
181                         EM_SAFE_FREE(input_string);
182                         input_string = result_string;
183                 }
184                 cur_part = cur_part->next;
185         }
186
187         if (input_string)
188                 result_string = EM_SAFE_STRDUP(input_string);
189 FINISH_OFF:
190
191         EM_SAFE_FREE(input_string);
192         if (err_code)
193                 *err_code = err;
194
195         EM_DEBUG_FUNC_END("ret[%s]", result_string);
196         return result_string;
197 }
198
199 static int emcore_write_body(BODY *body, BODY *html_body, FILE *fp, int *err_code)
200 {
201         EM_DEBUG_FUNC_BEGIN("fp[%d]", fp);
202         char *file_path = NULL;
203         char buf[RFC822_STRING_BUFFER_SIZE + 1];
204         char *img_tag_pos = NULL;
205         char *p = NULL;
206         char *replaced_string = NULL;
207         int fd, nread, nwrite, error = EMAIL_ERROR_NONE;
208         unsigned long len;
209
210         file_path = body->sparep;
211
212         if (!file_path || EM_SAFE_STRLEN(file_path) == 0)  {
213                 EM_DEBUG_LOG("There is no file path");
214                 switch (body->encoding)  {
215                         case 0:
216                                 break;
217                         default:
218                                 p = cpystr((const char *)body->contents.text.data);
219                                 len = body->contents.text.size;
220                                 break;
221                 }
222
223                 if (p)  {
224                         EM_DEBUG_LOG("p[%s]", p);
225                         fprintf(fp, "%s"CRLF_STRING CRLF_STRING, p);
226                         EM_SAFE_FREE(p);
227                 }
228
229                 EM_SAFE_FREE(body->sparep);
230                 EM_DEBUG_FUNC_END();
231                 return true;
232         }
233
234         EM_DEBUG_LOG("Opening a file[%s]", file_path);
235         fd = open(file_path, O_RDONLY);
236
237         if (fd < 0) {
238                 EM_DEBUG_EXCEPTION("open(\"%s\") failed...", file_path);
239                 return false;
240         }
241
242         while (1) {
243                 memset(&buf, 0x00, RFC822_STRING_BUFFER_SIZE + 1);
244                 nread = read(fd, buf, (body->encoding == ENCBASE64 ? 57 : RFC822_READ_BLOCK_SIZE - 2));
245
246                 if (nread <= 0)  {
247                         EM_DEBUG_LOG("Can't read anymore : nread[%d]", nread);
248                         break;
249                 }
250
251                 p = NULL;
252                 len = nread;
253
254                 /* EM_DEBUG_LOG("body->type[%d], body->subtype[%c]", body->type, body->subtype[0]); */
255
256                 if (body->type == TYPETEXT && (body->subtype && (body->subtype[0] == 'H' || body->subtype[0] == 'h'))) {
257                         EM_DEBUG_LOG("HTML Part");
258                         img_tag_pos = emcore_find_img_tag(buf);
259
260                         if (img_tag_pos) {
261                                 replaced_string = emcore_replace_inline_image_path_with_content_id(buf, html_body, &error);
262                                 if (replaced_string) {
263                                         EM_DEBUG_LOG("emcore_replace_inline_image_path_with_content_id succeeded");
264                                         strcpy(buf, replaced_string);
265                                         nread = len = EM_SAFE_STRLEN(buf);
266                                         EM_DEBUG_LOG("buf[%s], nread[%d], len[%d]", buf, nread, len);
267                                 }
268                                 else
269                                         EM_DEBUG_LOG("emcore_replace_inline_image_path_with_content_id failed[%d]", error);
270                         }
271                 }
272                 /* EM_DEBUG_LOG("body->encoding[%d]", body->encoding); */
273 //              if (body->subtype[0] != 'S' || body->subtype[0] != 's') {
274                 switch (body->encoding)  {
275                         case ENCQUOTEDPRINTABLE:
276                                 p = (char *)rfc822_8bit((unsigned char *)buf, (unsigned long)nread, (unsigned long *)&len);
277                                 break;
278                         case ENCBASE64:
279                                 p = (char *)rfc822_binary((void *)buf, (unsigned long)nread, (unsigned long *)&len);
280                                 break;
281                         default:
282                                 buf[len] = '\0';
283                                 break;
284                 }
285 //              }
286
287                 nwrite = fprintf(fp, "%s", (p ? p : buf));
288                 if (nwrite != len)  {
289                         fclose(fp);
290                         close(fd);
291                         EM_SAFE_FREE(p);
292                         EM_DEBUG_EXCEPTION("fprintf failed nwrite[%d], len[%d]", nwrite, len);
293                         return false;
294                 }
295                 EM_SAFE_FREE(p);
296         }
297
298         if (body->encoding == ENCQUOTEDPRINTABLE || body->encoding == ENCBASE64)
299                 fprintf(fp, CRLF_STRING);
300
301         fprintf(fp, CRLF_STRING);
302
303         if (body->sparep)  {
304                 free(body->sparep);
305                 body->sparep = NULL;
306         }
307
308         close(fd);
309
310         EM_DEBUG_FUNC_END();
311         return true;
312 }
313
314 static int emcore_write_rfc822_body(BODY *body, BODY *html_body, FILE *fp, int *err_code)
315 {
316         EM_DEBUG_FUNC_BEGIN("body[%p], html_body[%p], fp[%p], err_code[%p]", body, html_body, fp, err_code);
317
318         PARAMETER *param = NULL;
319         PART *part = NULL;
320         char *p = NULL, *bndry = NULL, buf[1025];
321         int error = EMAIL_ERROR_NONE;
322
323         switch (body->type)  {
324                 case TYPEMULTIPART:
325                         EM_DEBUG_LOG("body->type = TYPEMULTIPART");
326                         part = body->nested.part;
327
328                         for (param = body->parameter; param; param = param->next)  {
329                                 if (strcasecmp(param->attribute, "BOUNDARY") == 0) {
330                                         bndry = param->value;
331                                         break;
332                                 }
333                         }
334
335                         do  {
336                                 p = buf; p[0] = '\0';
337
338                                 rfc822_write_body_header(&p, &part->body);
339
340                                 fprintf(fp, "--%s"CRLF_STRING, bndry);
341                                 if (body->subtype[0] == 'S' || body->subtype[0] == 's') {
342                                         if (!emcore_write_body(body, html_body, fp, &error)) {
343                                                 EM_DEBUG_EXCEPTION("emcore_write_body failed : [%d]", error);
344                                                 return false;
345                                         }
346                                         fprintf(fp, "--%s"CRLF_STRING, bndry);
347                                 }
348
349                                 fprintf(fp, "%s"CRLF_STRING, buf);
350
351                                 emcore_write_rfc822_body(&part->body, html_body, fp, err_code);
352                         } while ((part = part->next));
353
354                         fprintf(fp, "--%s--"CRLF_STRING, bndry);
355                         break;
356
357                 default:  {
358                         EM_DEBUG_LOG("body->type is not TYPEMULTIPART");
359
360                         if (!emcore_write_body(body, html_body, fp, &error)) {
361                                 EM_DEBUG_EXCEPTION("emcore_write_body failed : [%d]", error);
362                                 return false;
363                         }
364
365                         break;
366                 }       /*  default: */
367         }
368         EM_DEBUG_FUNC_END();
369         return true;
370 }
371
372 static int emcore_write_rfc822(ENVELOPE *env, BODY *body, BODY *html_body, email_mail_priority_t input_priority, email_mail_report_t input_report_flag, char **data, int *err_code)
373 {
374         EM_DEBUG_FUNC_BEGIN("env[%p], body[%p], data[%p], err_code[%p]", env, body, data, err_code);
375
376         int ret = false;
377         int error = EMAIL_ERROR_NONE;
378
379         FILE *fp = NULL;
380         char *fname = NULL;
381         char *p = NULL;
382         size_t p_len = 0;
383
384         if (!env || !data)  {
385                 EM_DEBUG_EXCEPTION("Invalid Parameters");
386                 error = EMAIL_ERROR_INVALID_PARAM;
387                 goto FINISH_OFF;
388         }
389
390         srand(time(NULL));
391
392         rfc822_encode_body_7bit(env, body); /*  if contents.text.data isn't NULL, the data will be encoded. */
393
394         /*  FIXME : create memory map for this file */
395         p_len = (env->subject ? EM_SAFE_STRLEN(env->subject) : 0) + 8192;
396
397         if (!(p = em_malloc(p_len)))  {         /* (env->subject ? EM_SAFE_STRLEN(env->subject) : 0) + 8192))) */
398                 EM_DEBUG_EXCEPTION(" malloc failed...");
399                 error = EMAIL_ERROR_OUT_OF_MEMORY;
400                 goto FINISH_OFF;
401         }
402
403
404         RFC822BUFFER buf;
405
406         /* write at start of buffer */
407         buf.end = (buf.beg = buf.cur = p) + p_len - 1;
408         /* buf.f = NIL; */
409         buf.f = buf_flush;
410         buf.s = NIL;
411
412         /*  rfc822_output_header(&buf, env, body, NIL, T); */           /*  including BCC  */
413         rfc822_output_header(&buf, env, body, NIL, NIL);                /*  Excluding BCC */
414
415         *buf.cur = '\0';                /* tie off buffer */
416         {
417                 gchar **tokens = g_strsplit(p, "CHARSET=X-UNKNOWN", 2);
418
419                 if (g_strv_length(tokens) > 1)  {
420                         gchar *charset;
421
422                         if (body->sparep) {
423                                 charset = g_path_get_basename(body->sparep);
424                                 char *pHtml = NULL;
425                                 if (charset != NULL) {
426                                         if ((pHtml = strstr(charset, ".htm")) != NULL)
427                                                 charset[pHtml-charset] = '\0';
428                                 }
429
430                                 SNPRINTF(p, p_len, "%sCHARSET=%s%s", tokens[0], charset, tokens[1]);
431                                 g_free(charset);
432                         }
433                         else
434                                 EM_DEBUG_EXCEPTION("body->sparep is NULL");
435                 }
436
437                 g_strfreev(tokens);
438         } {
439                 gchar **tokens = g_strsplit(p, "To: undisclosed recipients: ;\015\012", 2);
440                 if (g_strv_length(tokens) > 1)
441                         SNPRINTF(p, p_len, "%s%s", tokens[0], tokens[1]);
442                 g_strfreev(tokens);
443         }
444
445
446         EM_DEBUG_LOG(" =============================================================================== "
447                 LF_STRING"%s"LF_STRING
448                 " =============================================================================== ", p);
449
450         if (EM_SAFE_STRLEN(p) > 2)
451                 *(p + EM_SAFE_STRLEN(p) - 2) = '\0';
452
453
454         if (input_report_flag)  {
455                 char buf[512] = {0x00, };
456
457                 if(input_report_flag & EMAIL_MAIL_REPORT_DSN) {
458                         /*  DSN (delivery status) */
459                         /*  change content-type */
460                         /*  Content-Type: multipart/report; */
461                         /*              report-type= delivery-status; */
462                         /*              boundary="----=_NextPart_000_004F_01C76EFF.54275C50" */
463                 }
464
465                 if(input_report_flag & EMAIL_MAIL_REPORT_MDN) {
466                         /*  MDN (read receipt) */
467                         /*  Content-Type: multipart/report; */
468                         /*              report-type= disposition-notification; */
469                         /*              boundary="----=_NextPart_000_004F_01C76EFF.54275C50" */
470                 }
471
472                 if(input_report_flag & EMAIL_MAIL_REQUEST_MDN) {
473                         /*  require read status */
474                         rfc822_address(buf, env->from);
475                         if (EM_SAFE_STRLEN(buf))
476                                 SNPRINTF(p + EM_SAFE_STRLEN(p), p_len-(EM_SAFE_STRLEN(p)), "Disposition-Notification-To: %s"CRLF_STRING, buf);
477                 }
478         }
479
480         if (input_priority)  {          /*  priority (1:high 3:normal 5:low) */
481                 SNPRINTF(p + EM_SAFE_STRLEN(p), p_len-(EM_SAFE_STRLEN(p)), "X-Priority: %d"CRLF_STRING, input_priority);
482
483                 switch (input_priority)  {
484                         case EMAIL_MAIL_PRIORITY_HIGH:
485                                 SNPRINTF(p + EM_SAFE_STRLEN(p), p_len-(EM_SAFE_STRLEN(p)), "X-MSMail-Priority: HIgh"CRLF_STRING);
486                                 break;
487                         case EMAIL_MAIL_PRIORITY_NORMAL:
488                                 SNPRINTF(p + EM_SAFE_STRLEN(p), p_len-(EM_SAFE_STRLEN(p)), "X-MSMail-Priority: Normal"CRLF_STRING);
489                                 break;
490                         case EMAIL_MAIL_PRIORITY_LOW:
491                                 SNPRINTF(p + EM_SAFE_STRLEN(p), p_len-(EM_SAFE_STRLEN(p)), "X-MSMail-Priority: Low"CRLF_STRING);
492                                 break;
493                 }
494         }
495
496         SNPRINTF(p + EM_SAFE_STRLEN(p), p_len-(EM_SAFE_STRLEN(p)), CRLF_STRING);
497
498         if (!emcore_get_temp_file_name(&fname, &error))  {
499                 EM_DEBUG_EXCEPTION(" emcore_get_temp_file_name failed[%d]", error);
500                 goto FINISH_OFF;
501         }
502
503         if (!(fp = fopen(fname, "w+")))  {
504                 EM_DEBUG_EXCEPTION("fopen failed[%s]", fname);
505                 error = EMAIL_ERROR_SYSTEM_FAILURE;
506                 goto FINISH_OFF;
507         }
508
509         fprintf(fp, "%s", p);
510
511         if (body)  {
512                 if (!emcore_write_rfc822_body(body, html_body, fp, &error))  {
513                         EM_DEBUG_EXCEPTION("emcore_write_rfc822_body failed[%d]", error);
514                         goto FINISH_OFF;
515                 }
516         }
517
518         ret = true;
519
520
521 FINISH_OFF:
522         if (fp != NULL)
523                 fclose(fp);
524
525 #ifdef USE_SYNC_LOG_FILE
526         emstorage_copy_file(fname, "/tmp/phone2pc.eml", false, NULL);
527 #endif
528
529         if (ret == true)
530                 *data = fname;
531         else if (fname != NULL)  {
532                 remove(fname);
533                 EM_SAFE_FREE(fname);
534         }
535
536         EM_SAFE_FREE(p);
537
538         if (err_code != NULL)
539                 *err_code = error;
540         EM_DEBUG_FUNC_END();
541         return ret;
542 }
543
544 INTERNAL_FUNC int emcore_add_mail(email_mail_data_t *input_mail_data, email_attachment_data_t *input_attachment_data_list, int input_attachment_count, email_meeting_request_t *input_meeting_request, int input_from_eas)
545 {
546         EM_DEBUG_FUNC_BEGIN("input_mail_data[%p], input_attachment_data_list [%p], input_attachment_count [%d], input_meeting_request [%p], input_from_eas[%d]", input_mail_data, input_attachment_data_list, input_attachment_count, input_meeting_request, input_from_eas);
547
548         int err = EMAIL_ERROR_NONE;
549         int attachment_id = 0, thread_id = -1, thread_item_count = 0, latest_mail_id_in_thread = -1;
550         int i = 0, rule_len, rule_matched = -1, local_attachment_count = 0, local_inline_content_count = 0;
551         int mailbox_id_spam = 0, mailbox_id_target = 0;
552         char *ext = NULL;
553         char name_buf[MAX_PATH] = {0x00, };
554         char *body_text_file_name = NULL;
555
556         int attachment_count = 0;
557         email_mail_data_t *mail_data = NULL;
558         email_attachment_data_t *attachment_data_list = NULL;
559         emstorage_mail_tbl_t    *converted_mail_tbl = NULL;
560         emstorage_mailbox_tbl_t *mailbox_tbl = NULL;
561         emstorage_attachment_tbl_t attachment_tbl = { 0 };
562         emstorage_account_tbl_t *account_tbl_item = NULL;
563         emstorage_rule_tbl_t *rule = NULL;
564         struct stat st_buf = { 0 };
565         char mailbox_id_param_string[10] = {0,};
566
567         /* Validating parameters */
568         if (!input_mail_data || !(input_mail_data->account_id) || !(input_mail_data->mailbox_id))  {
569                 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
570                 err = EMAIL_ERROR_INVALID_PARAM;
571                 goto FINISH_OFF;
572         }
573
574         if (emcore_is_storage_full(&err) == true) {
575                 EM_DEBUG_EXCEPTION("Storage is full");
576                 goto FINISH_OFF;
577         }
578
579         if (!emstorage_get_account_by_id(input_mail_data->account_id, EMAIL_ACC_GET_OPT_DEFAULT | EMAIL_ACC_GET_OPT_OPTIONS, &account_tbl_item, true, &err)) {
580                 EM_DEBUG_EXCEPTION("emstorage_get_account_by_id failed. account_id[%d] err[%d]", input_mail_data->account_id, err);
581                 err = EMAIL_ERROR_INVALID_ACCOUNT;
582                 goto FINISH_OFF;
583         }
584
585         if (input_from_eas == 0 && input_mail_data->smime_type && input_mail_data->mailbox_type != EMAIL_MAILBOX_TYPE_DRAFT) {
586                 if (!emcore_convert_mail_data_to_smime_data(account_tbl_item, input_mail_data, input_attachment_data_list, input_attachment_count, &mail_data, &attachment_data_list, &attachment_count)) {
587                         EM_DEBUG_EXCEPTION("S/MIME failed");
588                         goto FINISH_OFF;
589                 }
590         } else {
591                 mail_data = input_mail_data;
592                 attachment_data_list = input_attachment_data_list;
593                 attachment_count = input_attachment_count;
594         }
595
596         mailbox_id_target = mail_data->mailbox_id;
597
598         if (input_from_eas == 0 &&
599                         !(input_mail_data->message_class & EMAIL_MESSAGE_CLASS_SMART_REPLY) &&
600                         !(input_mail_data->message_class & EMAIL_MESSAGE_CLASS_SMART_FORWARD) ) {
601                 if (mail_data->file_path_plain)  {
602                         if (stat(mail_data->file_path_plain, &st_buf) < 0)  {
603                                 EM_DEBUG_EXCEPTION("mail_data->file_path_plain, stat(\"%s\") failed...", mail_data->file_path_plain);
604                                 err = EMAIL_ERROR_INVALID_MAIL;
605                                 goto FINISH_OFF;
606                         }
607                 }
608
609                 if (mail_data->file_path_html)  {
610                         if (stat(mail_data->file_path_html, &st_buf) < 0)  {
611                                 EM_DEBUG_EXCEPTION("mail_data->file_path_html, stat(\"%s\") failed...", mail_data->file_path_html);
612                                 err = EMAIL_ERROR_INVALID_MAIL;
613                                 goto FINISH_OFF;
614                         }
615                 }
616
617                 if (attachment_count && attachment_data_list)  {
618                         for (i = 0; i < attachment_count; i++)  {
619                                 if (attachment_data_list[i].save_status) {
620                                         if (!attachment_data_list[i].attachment_path || stat(attachment_data_list[i].attachment_path, &st_buf) < 0)  {
621                                                 EM_DEBUG_EXCEPTION("stat(\"%s\") failed...", attachment_data_list[i].attachment_path);
622                                                 err = EMAIL_ERROR_INVALID_ATTACHMENT;
623                                                 goto FINISH_OFF;
624                                         }
625                                 }
626                         }
627                 }
628
629                 if (!input_mail_data->full_address_from)
630                         input_mail_data->full_address_from = EM_SAFE_STRDUP(account_tbl_item->user_email_address);
631
632                 /* check for email_address validation */
633                 if (!em_verify_email_address_of_mail_data(mail_data, false, &err)) {
634                         EM_DEBUG_EXCEPTION("em_verify_email_address_of_mail_data failed [%d]", err);
635                         goto FINISH_OFF;
636                 }
637
638                 if (mail_data->report_status & EMAIL_MAIL_REPORT_MDN)  {
639                         /* check read-report mail */
640                         if(!mail_data->full_address_to) { /* A report mail should have 'to' address */
641                                 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
642                                 err = EMAIL_ERROR_INVALID_PARAM;
643                                 goto FINISH_OFF;
644                         }
645                         /* Create report mail body */
646                         /*
647                         if (!emcore_make_rfc822_file_from_mail(mail_src, NULL, NULL, NULL, &err))  {
648                                 EM_DEBUG_EXCEPTION("emcore_make_rfc822_file_from_mail failed [%d]", err);
649                                 goto FINISH_OFF;
650                         }
651                         */
652                 }
653         }
654         else {  /*  For Spam handling */
655                 email_option_t *opt = &account_tbl_item->options;
656                 EM_DEBUG_LOG("block_address [%d], block_subject [%d]", opt->block_address, opt->block_subject);
657
658                 if (opt->block_address || opt->block_subject)  {
659                         int is_completed = false;
660                         int type = 0;
661
662                         if (!opt->block_address)
663                                 type = EMAIL_FILTER_SUBJECT;
664                         else if (!opt->block_subject)
665                                 type = EMAIL_FILTER_FROM;
666
667                         if (!emstorage_get_rule(ALL_ACCOUNT, type, 0, &rule_len, &is_completed, &rule, true, &err) || !rule)
668                                 EM_DEBUG_LOG("No proper rules. emstorage_get_rule returns [%d]", err);
669                 }
670
671                 if (rule) {
672                         if (!emstorage_get_mailbox_id_by_mailbox_type(mail_data->account_id, EMAIL_MAILBOX_TYPE_SPAMBOX, &mailbox_id_spam, false, &err))  {
673                                 EM_DEBUG_EXCEPTION("emstorage_get_mailbox_name_by_mailbox_type failed [%d]", err);
674                                 mailbox_id_spam = 0;
675                         }
676
677                         if (mailbox_id_spam && !emcore_check_rule(mail_data->full_address_from, mail_data->subject, rule, rule_len, &rule_matched, &err))  {
678                                 EM_DEBUG_EXCEPTION("emcore_check_rule failed [%d]", err);
679                                 goto FINISH_OFF;
680                         }
681                 }
682
683                 if (rule_matched >= 0 && mailbox_id_spam)
684                         mailbox_id_target = mailbox_id_spam;
685         }
686
687         if ((err = emstorage_get_mailbox_by_id(mailbox_id_target, (emstorage_mailbox_tbl_t**)&mailbox_tbl)) != EMAIL_ERROR_NONE) {
688                 EM_DEBUG_EXCEPTION("emstorage_get_mailbox_by_id failed [%d]", err);
689                 goto FINISH_OFF;
690         }
691
692         if (!emstorage_increase_mail_id(&mail_data->mail_id, true, &err)) {
693                 EM_DEBUG_EXCEPTION("emstorage_increase_mail_id failed [%d]", err);
694                 goto FINISH_OFF;
695         }
696
697         EM_DEBUG_LOG("mail_data->mail_size [%d]", mail_data->mail_size);
698
699         if(mail_data->mail_size == 0)
700                 emcore_calc_mail_size(mail_data, attachment_data_list, attachment_count, &(mail_data->mail_size)); /*  Getting file size before file moved.  */
701
702         EM_DEBUG_LOG("input_from_eas [%d] mail_data->body_download_status [%d]", input_from_eas, mail_data->body_download_status);
703
704         if (input_from_eas == 0|| mail_data->body_download_status) {
705                 if (!emstorage_create_dir(mail_data->account_id, mail_data->mail_id, 0, &err))  {
706                         EM_DEBUG_EXCEPTION("emstorage_create_dir failed [%d]", err);
707                         goto FINISH_OFF;
708                 }
709
710                 if (mail_data->file_path_plain) {
711                         EM_DEBUG_LOG("mail_data->file_path_plain [%s]", mail_data->file_path_plain);
712                         /* EM_SAFE_STRNCPY(body_text_file_name, "UTF-8", MAX_PATH); */
713
714                         if ( (err = em_get_file_name_from_file_path(mail_data->file_path_plain, &body_text_file_name)) != EMAIL_ERROR_NONE) {
715                                 EM_DEBUG_EXCEPTION("em_get_file_name_from_file_path failed [%d]", err);
716                                 err = EMAIL_ERROR_INVALID_FILE_PATH;
717                                 goto FINISH_OFF;
718                         }
719
720                         /*
721                         if (input_from_eas)
722                                 EM_SAFE_STRNCPY(body_text_file_name, UNKNOWN_CHARSET_PLAIN_TEXT_FILE, MAX_PATH);
723                         else
724                                 EM_SAFE_STRNCPY(body_text_file_name, "UTF-8", MAX_PATH);
725                         */
726
727                         if (!emstorage_get_save_name(mail_data->account_id, mail_data->mail_id, 0, body_text_file_name, name_buf, &err))  {
728                                 EM_DEBUG_EXCEPTION("emstorage_get_save_name failed [%d]", err);
729                                 goto FINISH_OFF;
730                         }
731
732                         if (!emstorage_move_file(mail_data->file_path_plain, name_buf, input_from_eas, &err)) {
733                                 EM_DEBUG_EXCEPTION("emstorage_move_file failed [%d]", err);
734                                 goto FINISH_OFF;
735                         }
736                         if (mail_data->body_download_status == EMAIL_BODY_DOWNLOAD_STATUS_NONE)
737                                 mail_data->body_download_status = EMAIL_BODY_DOWNLOAD_STATUS_FULLY_DOWNLOADED;
738
739                         EM_SAFE_FREE(mail_data->file_path_plain);
740                         mail_data->file_path_plain = EM_SAFE_STRDUP(name_buf);
741                 }
742
743                 if (mail_data->file_path_html) {
744                         EM_DEBUG_LOG("mail_data->file_path_html [%s]", mail_data->file_path_html);
745                         /* EM_SAFE_STRNCPY(body_text_file_name, "UTF-8.htm", MAX_PATH); */
746
747                         EM_SAFE_FREE(body_text_file_name);
748
749                         if ( (err = em_get_file_name_from_file_path(mail_data->file_path_html, &body_text_file_name)) != EMAIL_ERROR_NONE) {
750                                 EM_DEBUG_EXCEPTION("em_get_file_name_from_file_path failed [%d]", err);
751                                 err = EMAIL_ERROR_INVALID_FILE_PATH;
752                                 goto FINISH_OFF;
753                         }
754                         /*
755                         if (input_from_eas)
756                                 EM_SAFE_STRNCPY(body_text_file_name, UNKNOWN_CHARSET_HTML_TEXT_FILE, MAX_PATH);
757                         else
758                                 EM_SAFE_STRNCPY(body_text_file_name, "UTF-8.htm", MAX_PATH);
759                         */
760
761                         if (!emstorage_get_save_name(mail_data->account_id, mail_data->mail_id, 0, body_text_file_name, name_buf, &err))  {
762                                 EM_DEBUG_EXCEPTION("emstorage_get_save_name failed [%d]", err);
763                                 goto FINISH_OFF;
764                         }
765
766                         if (!emstorage_move_file(mail_data->file_path_html, name_buf, input_from_eas, &err))  {
767                                 EM_DEBUG_EXCEPTION("emstorage_move_file failed [%d]", err);
768                                 goto FINISH_OFF;
769                         }
770
771                         if (mail_data->body_download_status == EMAIL_BODY_DOWNLOAD_STATUS_NONE)
772                                 mail_data->body_download_status = EMAIL_BODY_DOWNLOAD_STATUS_FULLY_DOWNLOADED;
773
774                         EM_SAFE_FREE(mail_data->file_path_html);
775                         mail_data->file_path_html = EM_SAFE_STRDUP(name_buf);
776                 }
777         }
778
779         if (mail_data->file_path_mime_entity) {
780                 EM_DEBUG_LOG("mail_data->file_path_mime_entity [%s]", mail_data->file_path_mime_entity);
781
782                 if (!emstorage_get_save_name(mail_data->account_id, mail_data->mail_id, 0, "mime_entity", name_buf, &err)) {
783                         EM_DEBUG_EXCEPTION("emstorage_get_save_name failed [%d]", err);
784                         goto FINISH_OFF;
785                 }
786
787                 if (!emstorage_move_file(mail_data->file_path_mime_entity, name_buf, input_from_eas, &err)) {
788                         EM_DEBUG_EXCEPTION("emstorage_move_file failed [%d]", err);
789                         goto FINISH_OFF;
790                 }
791
792                 EM_SAFE_FREE(mail_data->file_path_mime_entity);
793                 mail_data->file_path_mime_entity = EM_SAFE_STRDUP(name_buf);
794         }
795
796         if (!mail_data->date_time)  {
797                 /* time isn't set */
798                 mail_data->date_time = time(NULL);
799         }
800
801
802         mail_data->mailbox_id           = mailbox_id_target;
803         mail_data->mailbox_type         = mailbox_tbl->mailbox_type;
804         mail_data->server_mail_status   = !input_from_eas;
805         mail_data->save_status          = EMAIL_MAIL_STATUS_SAVED;
806
807         /*  Getting attachment count */
808         for (i = 0; i < attachment_count; i++) {
809                 if (attachment_data_list[i].inline_content_status== 1)
810                         local_inline_content_count++;
811                 local_attachment_count++;
812         }
813
814         mail_data->inline_content_count = local_inline_content_count;
815         mail_data->attachment_count     = local_attachment_count;
816
817         EM_DEBUG_LOG("inline_content_count   [%d]", local_inline_content_count);
818         EM_DEBUG_LOG("attachment_count [%d]", local_attachment_count);
819
820         EM_DEBUG_LOG("preview_text[%p]", mail_data->preview_text);
821         if (mail_data->preview_text == NULL) {
822                 if ( (err = emcore_get_preview_text_from_file(mail_data->file_path_plain, mail_data->file_path_html, MAX_PREVIEW_TEXT_LENGTH, &(mail_data->preview_text))) != EMAIL_ERROR_NONE) {
823                         EM_DEBUG_EXCEPTION("emcore_get_preview_text_from_file failed[%d]", err);
824
825                         if (err != EMAIL_ERROR_EMPTY_FILE)
826                                 goto FINISH_OFF;
827                 }
828         }
829
830         if (!em_convert_mail_data_to_mail_tbl(mail_data, 1, &converted_mail_tbl, &err)) {
831                 EM_DEBUG_EXCEPTION("em_convert_mail_data_to_mail_tbl failed [%d]", err);
832                 goto FINISH_OFF;
833         }
834
835         converted_mail_tbl->mailbox_id        = mailbox_tbl->mailbox_id;
836
837         /* Fill address information */
838         emcore_fill_address_information_of_mail_tbl(converted_mail_tbl);
839
840         /* Fill thread id */
841         if(mail_data->thread_id == 0) {
842                 if (emstorage_get_thread_id_of_thread_mails(converted_mail_tbl, &thread_id, &latest_mail_id_in_thread, &thread_item_count) != EMAIL_ERROR_NONE)
843                         EM_DEBUG_LOG(" emstorage_get_thread_id_of_thread_mails is failed");
844
845                 if (thread_id == -1) {
846                         converted_mail_tbl->thread_id         = mail_data->mail_id;
847                         converted_mail_tbl->thread_item_count = thread_item_count = 1;
848                 }
849                 else  {
850                         converted_mail_tbl->thread_id         = thread_id;
851                         thread_item_count++;
852                 }
853         }
854         else {
855                 thread_item_count                         = 2;
856         }
857
858         mail_data->thread_id = converted_mail_tbl->thread_id;
859
860         emstorage_begin_transaction(NULL, NULL, NULL);
861
862         /*  insert mail to mail table */
863         if (!emstorage_add_mail(converted_mail_tbl, 0, false, &err))  {
864                 EM_DEBUG_EXCEPTION("emstorage_add_mail failed [%d]", err);
865                 /*  ROLLBACK TRANSACTION; */
866                 emstorage_rollback_transaction(NULL, NULL, NULL);
867
868                 goto FINISH_OFF;
869         }
870
871         /* Update thread information */
872         EM_DEBUG_LOG("thread_item_count [%d]", thread_item_count);
873
874         if (thread_item_count > 1) {
875                 if (!emstorage_update_latest_thread_mail(mail_data->account_id, converted_mail_tbl->thread_id, 0, 0, false, &err)) {
876                         EM_DEBUG_EXCEPTION("emstorage_update_latest_thread_mail failed [%d]", err);
877                         emstorage_rollback_transaction(NULL, NULL, NULL);
878
879                         goto FINISH_OFF;
880                 }
881         }
882
883         /*  Insert attachment information to DB */
884
885         for (i = 0; i < attachment_count; i++) {
886                 if (attachment_data_list[i].attachment_size == 0) {
887                         /* set attachment size */
888                         if(attachment_data_list[i].attachment_path && stat(attachment_data_list[i].attachment_path, &st_buf) < 0)
889                                 attachment_data_list[i].attachment_size = st_buf.st_size;
890                 }
891
892                 if (!attachment_data_list[i].inline_content_status) {
893                         if (!emstorage_get_new_attachment_no(&attachment_id, &err)) {
894                                 EM_DEBUG_EXCEPTION("emstorage_get_new_attachment_no failed [%d]", err);
895                                 emstorage_rollback_transaction(NULL, NULL, NULL);
896                                 goto FINISH_OFF;
897                         }
898                 }
899
900                 if (!emstorage_create_dir(mail_data->account_id, mail_data->mail_id, attachment_data_list[i].inline_content_status ? 0  :  attachment_id, &err))  {
901                         EM_DEBUG_EXCEPTION("emstorage_create_dir failed [%d]", err);
902                         emstorage_rollback_transaction(NULL, NULL, NULL);
903                         goto FINISH_OFF;
904                 }
905
906                 if (!emstorage_get_save_name(mail_data->account_id, mail_data->mail_id, attachment_data_list[i].inline_content_status ? 0  :  attachment_id, attachment_data_list[i].attachment_name, name_buf, &err))  {
907                         EM_DEBUG_EXCEPTION("emstorage_get_save_name failed [%d]", err);
908                         emstorage_rollback_transaction(NULL, NULL, NULL);
909                         goto FINISH_OFF;
910                 }
911                 /* if (input_from_eas == 0 || attachment_data_list[i].save_status) { */
912                 if (attachment_data_list[i].save_status) {
913                         if (!emstorage_copy_file(attachment_data_list[i].attachment_path, name_buf, input_from_eas, &err))  {
914                                 EM_DEBUG_EXCEPTION("emstorage_copy_file failed [%d]", err);
915                                 emstorage_rollback_transaction(NULL, NULL, NULL);
916                                 goto FINISH_OFF;
917                         }
918
919                         if ((ext = strrchr(attachment_data_list[i].attachment_name, '.'))) {
920                                 if (!strncmp(ext, ".vcs", strlen(".vcs")))
921                                         remove(attachment_data_list[i].attachment_path);
922                                 else if (!strncmp(ext, ".vcf", strlen(".vcf")))
923                                         remove(attachment_data_list[i].attachment_path);
924                                 else if (!strncmp(ext, ".vnt", strlen(".vnt")))
925                                         remove(attachment_data_list[i].attachment_path);
926                         }
927                 }
928
929                 memset(&attachment_tbl, 0, sizeof(emstorage_attachment_tbl_t));
930                 attachment_tbl.attachment_name                  = attachment_data_list[i].attachment_name;
931                 attachment_tbl.attachment_path                  = name_buf;
932                 attachment_tbl.attachment_size                  = attachment_data_list[i].attachment_size;
933                 attachment_tbl.mail_id                          = mail_data->mail_id;
934                 attachment_tbl.account_id                       = mail_data->account_id;
935                 attachment_tbl.mailbox_id                       = mail_data->mailbox_id;
936                 attachment_tbl.attachment_save_status           = attachment_data_list[i].save_status;
937                 attachment_tbl.attachment_drm_type              = attachment_data_list[i].drm_status;
938                 attachment_tbl.attachment_inline_content_status = attachment_data_list[i].inline_content_status;
939
940                 if (!emstorage_add_attachment(&attachment_tbl, 0, false, &err))  {
941                         EM_DEBUG_EXCEPTION("emstorage_add_attachment failed [%d]", err);
942                         emstorage_rollback_transaction(NULL, NULL, NULL);
943
944                         goto FINISH_OFF;
945                 }
946                 attachment_data_list[i].attachment_id = attachment_tbl.attachment_id;
947         }
948
949 #ifdef __FEATURE_BODY_SEARCH__
950         /* Insert mail_text to DB */
951         char *stripped_text = NULL;
952         if (!emcore_strip_mail_body_from_file(converted_mail_tbl, &stripped_text, &err) || stripped_text == NULL) {
953                 EM_DEBUG_EXCEPTION("emcore_strip_mail_body_from_file failed [%d]", err);
954         }
955
956         if (!emcore_add_mail_text(mailbox_tbl, converted_mail_tbl, stripped_text, &err)) {
957                 EM_DEBUG_EXCEPTION("emcore_add_mail_text failed [%d]", err);
958                 emstorage_rollback_transaction(NULL, NULL, NULL);
959                 goto FINISH_OFF;
960         }
961 #endif
962
963         /*  Insert Meeting request to DB */
964         if (mail_data->meeting_request_status == EMAIL_MAIL_TYPE_MEETING_REQUEST
965                 || mail_data->meeting_request_status == EMAIL_MAIL_TYPE_MEETING_RESPONSE
966                 || mail_data->meeting_request_status == EMAIL_MAIL_TYPE_MEETING_ORIGINATINGREQUEST) {
967                 EM_DEBUG_LOG("This mail has the meeting request");
968                 input_meeting_request->mail_id = mail_data->mail_id;
969                 if (!emstorage_add_meeting_request(mail_data->account_id, mailbox_tbl->mailbox_id, input_meeting_request, false, &err))  {
970                         EM_DEBUG_EXCEPTION("emstorage_add_meeting_request failed [%d]", err);
971
972                         goto FINISH_OFF;
973                 }
974         }
975
976         emstorage_commit_transaction(NULL, NULL, NULL);
977
978         SNPRINTF(mailbox_id_param_string, 10, "%d", mailbox_tbl->mailbox_id);
979         if (!emcore_notify_storage_event(NOTI_MAIL_ADD, converted_mail_tbl->account_id, converted_mail_tbl->mail_id, mailbox_id_param_string, converted_mail_tbl->thread_id))
980                 EM_DEBUG_LOG("emcore_notify_storage_event [NOTI_MAIL_ADD] failed.");
981
982         if (account_tbl_item->incoming_server_type != EMAIL_SERVER_TYPE_ACTIVE_SYNC) {
983                 if (!emcore_remove_overflowed_mails(mailbox_tbl, &err)) {
984                         if (err == EMAIL_ERROR_MAIL_NOT_FOUND || err == EMAIL_ERROR_NOT_SUPPORTED)
985                                 err = EMAIL_ERROR_NONE;
986                         else
987                                 EM_DEBUG_LOG("emcore_remove_overflowed_mails failed [%d]", err);
988                 }
989         }
990
991         if ( input_from_eas && (mail_data->flags_seen_field == 0)
992                                 && mail_data->mailbox_type != EMAIL_MAILBOX_TYPE_TRASH
993                                 && mail_data->mailbox_type != EMAIL_MAILBOX_TYPE_SPAMBOX) {
994                 if ((err = emcore_update_sync_status_of_account(mail_data->account_id, SET_TYPE_SET, SYNC_STATUS_SYNCING | SYNC_STATUS_HAVE_NEW_MAILS)) != EMAIL_ERROR_NONE)
995                                 EM_DEBUG_LOG("emcore_update_sync_status_of_account failed [%d]", err);
996 //              emcore_add_notification_for_unread_mail(converted_mail_tbl);
997                 emcore_display_unread_in_badge();
998         }
999
1000 FINISH_OFF:
1001
1002         EM_SAFE_FREE(body_text_file_name);
1003
1004 #ifdef __FEATURE_BODY_SEARCH__
1005         EM_SAFE_FREE(stripped_text);
1006 #endif
1007
1008         if (account_tbl_item)
1009                 emstorage_free_account(&account_tbl_item, 1, NULL);
1010
1011         if (mailbox_tbl)
1012                 emstorage_free_mailbox(&mailbox_tbl, 1, NULL);
1013
1014         if (converted_mail_tbl)
1015                 emstorage_free_mail(&converted_mail_tbl, 1, NULL);
1016
1017         EM_DEBUG_FUNC_END();
1018         return err;
1019 }
1020
1021 INTERNAL_FUNC int emcore_add_read_receipt(int input_read_mail_id, int *output_receipt_mail_id)
1022 {
1023         EM_DEBUG_FUNC_BEGIN("input_read_mail_id [%d], output_receipt_mail_id [%p]", input_read_mail_id, output_receipt_mail_id);
1024         int                      err = EMAIL_ERROR_NONE;
1025         int                      attachment_count = 0;
1026         ENVELOPE                *envelope = NULL;
1027         email_mail_data_t       *read_mail_data = NULL;
1028         email_mail_data_t       *receipt_mail_data = NULL;
1029         emstorage_mail_tbl_t    *receipt_mail_tbl_data = NULL;
1030         email_attachment_data_t *attachment_data = NULL;
1031         emstorage_mailbox_tbl_t *mailbox_tbl = NULL;
1032         BODY                    *root_body = NULL;
1033
1034         if( (err = emcore_get_mail_data(input_read_mail_id, &read_mail_data)) != EMAIL_ERROR_NONE) {
1035                 EM_DEBUG_EXCEPTION("emcore_get_mail_data failed [%d]", err);
1036                 goto FINISH_OFF;
1037         }
1038
1039         receipt_mail_data = em_malloc(sizeof(email_mail_data_t));
1040
1041         if (!receipt_mail_data)  {
1042                 EM_DEBUG_EXCEPTION("em_malloc failed...");
1043                 err = EMAIL_ERROR_OUT_OF_MEMORY;
1044                 goto FINISH_OFF;
1045         }
1046
1047         memcpy(receipt_mail_data, read_mail_data, sizeof(email_mail_data_t));
1048
1049         receipt_mail_data->full_address_to = EM_SAFE_STRDUP(read_mail_data->full_address_from);
1050         receipt_mail_data->message_id      = EM_SAFE_STRDUP(read_mail_data->message_id);
1051
1052         if (read_mail_data->subject)  {
1053                 receipt_mail_data->subject = em_malloc(EM_SAFE_STRLEN(read_mail_data->subject) + 7);
1054                 if (!(receipt_mail_data->subject))  {
1055                         EM_DEBUG_EXCEPTION("em_malloc failed...");
1056                         err = EMAIL_ERROR_OUT_OF_MEMORY;
1057                         goto FINISH_OFF;
1058                 }
1059
1060                 SNPRINTF(receipt_mail_data->subject, EM_SAFE_STRLEN(read_mail_data->subject) + 7,  "Read: %s", read_mail_data->subject);
1061         }
1062
1063         if (!emstorage_get_mailbox_by_mailbox_type(receipt_mail_data->account_id, EMAIL_MAILBOX_TYPE_OUTBOX, &mailbox_tbl, true, &err))  {
1064                 EM_DEBUG_EXCEPTION("emstorage_get_mailbox_name_by_mailbox_type failed [%d]", err);
1065                 goto FINISH_OFF;
1066         }
1067
1068         receipt_mail_data->mailbox_id           = mailbox_tbl->mailbox_id;
1069         receipt_mail_data->mailbox_type         = EMAIL_MAILBOX_TYPE_OUTBOX;
1070         receipt_mail_data->file_path_html       = NULL;
1071         receipt_mail_data->flags_draft_field    = 1;
1072         receipt_mail_data->body_download_status = 1;
1073         receipt_mail_data->save_status          = (unsigned char)EMAIL_MAIL_STATUS_SENDING;
1074         receipt_mail_data->report_status        = (unsigned char)EMAIL_MAIL_REPORT_MDN;
1075
1076         if (!em_convert_mail_data_to_mail_tbl(receipt_mail_data, 1, &receipt_mail_tbl_data, &err)) {
1077                 EM_DEBUG_EXCEPTION("em_convert_mail_data_to_mail_tbl failed [%d]", err);
1078                 goto FINISH_OFF;
1079         }
1080
1081         if ( (err = emcore_make_envelope_from_mail(receipt_mail_tbl_data, &envelope)) != EMAIL_ERROR_NONE) {
1082                 EM_DEBUG_EXCEPTION("emcore_make_envelope_from_mail failed [%d]", err);
1083                 goto FINISH_OFF;
1084         }
1085
1086         envelope->references = EM_SAFE_STRDUP(read_mail_data->message_id);
1087
1088         if (!emcore_get_report_mail_body(envelope, &root_body, &err))  {
1089                 EM_DEBUG_EXCEPTION("emcore_get_report_mail_body failed [%d]", err);
1090                 goto FINISH_OFF;
1091         }
1092
1093         receipt_mail_data->file_path_plain  = EM_SAFE_STRDUP(root_body->nested.part->body.sparep);
1094
1095         /* Report attachment */
1096         /* Final-Recipient :  rfc822;digipop@gmail.com
1097            Original-Message-ID:  <r97a77ag0jdhkvvxke58u9i5.1345611508570@email.android.com>
1098            Disposition :  manual-action/MDN-sent-manually; displayed */
1099
1100         /*
1101         receipt_mail_data->attachment_count = 1;
1102         attachment_count                    = 1;
1103
1104         attachment_data = em_malloc(sizeof(email_attachment_data_t));
1105         if (!attachment_data)  {
1106                 EM_DEBUG_EXCEPTION("em_malloc failed...");
1107                 err = EMAIL_ERROR_OUT_OF_MEMORY;
1108                 goto FINISH_OFF;
1109         }
1110
1111         attachment_data->save_status     = 1;
1112         attachment_data->attachment_path = EM_SAFE_STRDUP(root_body->nested.part->next->body.sparep);
1113
1114         if (!emcore_get_file_name(attachment_data->attachment_path, &p, &err))  {
1115                 EM_DEBUG_EXCEPTION("emcore_get_file_name failed [%d]", err);
1116                 goto FINISH_OFF;
1117         }
1118
1119         attachment_data->attachment_name = cpystr(p);
1120         */
1121
1122         if ( (err = emcore_add_mail(receipt_mail_data, attachment_data, attachment_count, NULL, 0)) != EMAIL_ERROR_NONE) {
1123                 EM_DEBUG_EXCEPTION("emcore_add_mail failed [%d]", err);
1124                 goto FINISH_OFF;
1125         }
1126
1127         *output_receipt_mail_id = receipt_mail_data->mail_id;
1128
1129 FINISH_OFF:
1130         if(receipt_mail_data) {
1131                 EM_SAFE_FREE(receipt_mail_data->full_address_to);
1132                 EM_SAFE_FREE(receipt_mail_data->message_id);
1133                 EM_SAFE_FREE(receipt_mail_data->subject);
1134                 EM_SAFE_FREE(receipt_mail_data);
1135         }
1136
1137         if(mailbox_tbl)
1138                 emstorage_free_mailbox(&mailbox_tbl, 1, NULL);
1139
1140         if(read_mail_data)
1141                 emcore_free_mail_data_list(&read_mail_data, 1);
1142
1143         if(attachment_data)
1144                 emcore_free_attachment_data(&attachment_data, 1, NULL);
1145
1146         if(receipt_mail_tbl_data)
1147                 emstorage_free_mail(&receipt_mail_tbl_data, 1, NULL);
1148
1149         EM_DEBUG_FUNC_END("err [%d]", err);
1150         return err;
1151 }
1152
1153 INTERNAL_FUNC int emcore_add_meeting_request(int account_id, int input_mailbox_id, email_meeting_request_t *meeting_req, int *err_code)
1154 {
1155         EM_DEBUG_FUNC_BEGIN("account_id[%d], input_mailbox_id[%d], meeting_req[%p], err_code[%p]", account_id, input_mailbox_id, meeting_req, err_code);
1156         int ret = false;
1157         int err = EMAIL_ERROR_NONE;
1158
1159         if (!meeting_req || meeting_req->mail_id <= 0) {
1160                 if (meeting_req)
1161                         EM_DEBUG_EXCEPTION("mail_id[%d]", meeting_req->mail_id);
1162
1163                 err = EMAIL_ERROR_INVALID_PARAM;
1164                 goto FINISH_OFF;
1165         }
1166
1167         if (!emstorage_add_meeting_request(account_id, input_mailbox_id, meeting_req, 1, &err))  {
1168                 EM_DEBUG_EXCEPTION(" emstorage_add_meeting_request failed [%d]", err);
1169
1170                 goto FINISH_OFF;
1171         }
1172
1173         ret = true;
1174
1175 FINISH_OFF:
1176
1177         if (err_code)
1178                 *err_code = err;
1179
1180         EM_DEBUG_FUNC_END();
1181         return ret;
1182 }
1183
1184 /*  send a mail */
1185 INTERNAL_FUNC int emcore_send_mail(int mail_id, int *err_code)
1186 {
1187         EM_DEBUG_FUNC_BEGIN("mail_id[%d], err_code[%p]", mail_id, err_code);
1188         EM_PROFILE_BEGIN(profile_emcore_send_mail);
1189         int ret = false;
1190         int err = EMAIL_ERROR_NONE, err2 = EMAIL_ERROR_NONE;
1191         int status = EMAIL_SEND_FAIL;
1192         int attachment_tbl_count = 0;
1193         int i = 0;
1194         int account_id = 0;
1195         SENDSTREAM *stream = NULL;
1196         ENVELOPE *envelope = NULL;
1197         sslstart_t stls = NULL;
1198         emstorage_mail_tbl_t       *mail_tbl_data = NULL;
1199         emstorage_attachment_tbl_t *attachment_tbl_data = NULL;
1200         email_account_t *ref_account = NULL;
1201         email_option_t *opt = NULL;
1202         void *tmp_stream = NULL;
1203         char *fpath = NULL;
1204         int sent_box = 0;
1205         emstorage_mailbox_tbl_t* local_mailbox = NULL;
1206         int dst_mailbox_id = 0;
1207
1208         if (!mail_id)  {
1209                 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
1210                 err = EMAIL_ERROR_INVALID_PARAM;
1211                 goto FINISH_OFF;
1212         }
1213
1214         /*  get mail to send */
1215         if (!emstorage_get_mail_by_id(mail_id, &mail_tbl_data, false, &err) || err != EMAIL_ERROR_NONE) {
1216                 EM_DEBUG_EXCEPTION("emstorage_get_mail_by_id failed [%d]", err);
1217                 goto FINISH_OFF;
1218         }
1219
1220         account_id = mail_tbl_data->account_id;
1221
1222         if (!(ref_account = emcore_get_account_reference(account_id))) {
1223                 EM_DEBUG_EXCEPTION("emcore_get_account_reference failed [%d]", account_id);
1224                 err = EMAIL_ERROR_INVALID_ACCOUNT;
1225                 goto FINISH_OFF;
1226         }
1227
1228         if ((err = emstorage_get_attachment_list(mail_id, false, &attachment_tbl_data, &attachment_tbl_count)) != EMAIL_ERROR_NONE) {
1229                 EM_DEBUG_EXCEPTION("emstorage_get_attachment_list failed [%d]", err);
1230                 goto FINISH_OFF;
1231         }
1232
1233         if (!emcore_check_send_mail_thread_status()) {
1234                 EM_DEBUG_EXCEPTION("emcore_check_send_mail_thread_status failed...");
1235                 err = EMAIL_ERROR_CANCELLED;
1236                 goto FINISH_OFF;
1237         }
1238
1239         if ((!mail_tbl_data->full_address_to) && (!mail_tbl_data->full_address_cc) && (!mail_tbl_data->full_address_bcc)) {
1240                 err = EMAIL_ERROR_NO_RECIPIENT;
1241                 EM_DEBUG_EXCEPTION("No Recipient information [%d]", err);
1242                 goto FINISH_OFF;
1243         }
1244         else {
1245                 if ((err = em_verify_email_address_of_mail_tbl(mail_tbl_data, false)) != EMAIL_ERROR_NONE) {
1246                         err = EMAIL_ERROR_INVALID_ADDRESS;
1247                         EM_DEBUG_EXCEPTION("em_verify_email_address_of_mail_tbl failed [%d]", err);
1248                         goto FINISH_OFF;
1249                 }
1250         }
1251
1252         if (!emcore_check_send_mail_thread_status()) {
1253                 EM_DEBUG_EXCEPTION("emcore_check_send_mail_thread_status failed...");
1254                 err = EMAIL_ERROR_CANCELLED;
1255                 goto FINISH_OFF;
1256         }
1257
1258         opt = &(ref_account->options);
1259
1260 #ifdef __FEATURE_SUPPORT_VALIDATION_SYSTEM__
1261         EM_VALIDATION_SYSTEM_LOG("INFO", mail_id, "Email Send Start, %s -> %s, success", mail_tbl_data->full_address_from, mail_tbl_data->full_address_to);
1262         for (i = 0; i < attachment_tbl_count; i++) {
1263                 if(attachment_tbl_data)
1264                         EM_VALIDATION_SYSTEM_LOG("FILE", mail_id, "[%s], %d", attachment_tbl_data[i].attachment_path, attachment_tbl_data[i].attachment_size);
1265         }
1266 #endif /* __FEATURE_SUPPORT_VALIDATION_SYSTEM__ */
1267
1268         /*Update status flag to DB*/
1269
1270         /*  get rfc822 data */
1271         if (!emcore_make_rfc822_file_from_mail(mail_tbl_data, attachment_tbl_data, attachment_tbl_count, &envelope, &fpath, opt, &err)) {
1272                 EM_DEBUG_EXCEPTION("emcore_make_rfc822_file_from_mail failed [%d]", err);
1273                 goto FINISH_OFF;
1274         }
1275
1276         if (!envelope || (!envelope->to && !envelope->cc && !envelope->bcc))  {
1277                 EM_DEBUG_EXCEPTION(" no recipients found...");
1278                 err = EMAIL_ERROR_NO_RECIPIENT;
1279                 goto FINISH_OFF;
1280         }
1281
1282         /*  if there is no security option, unset security. */
1283         if (!ref_account->outgoing_server_secure_connection)  {
1284                 stls = (sslstart_t)mail_parameters(NULL, GET_SSLSTART, NULL);
1285                 mail_parameters(NULL, SET_SSLSTART, NULL);
1286         }
1287
1288         if (!emcore_check_send_mail_thread_status()) {
1289                 EM_DEBUG_EXCEPTION("emcore_check_send_mail_thread_status failed...");
1290                 err = EMAIL_ERROR_CANCELLED;
1291                 goto FINISH_OFF;
1292         }
1293
1294         if (ref_account->pop_before_smtp != FALSE)  {
1295                 if (!emcore_connect_to_remote_mailbox(account_id, 0, (void **)&tmp_stream, &err))  {
1296                         EM_DEBUG_EXCEPTION(" POP before SMTP Authentication failed [%d]", err);
1297                         status = EMAIL_LIST_CONNECTION_FAIL;
1298                         if (err == EMAIL_ERROR_CONNECTION_BROKEN)
1299                                 err = EMAIL_ERROR_CANCELLED;
1300                         goto FINISH_OFF;
1301                 }
1302         }
1303         if (!emstorage_get_mailbox_by_mailbox_type(account_id, EMAIL_MAILBOX_TYPE_DRAFT, &local_mailbox, false, &err))  {
1304                 EM_DEBUG_EXCEPTION(" emstorage_get_mailbox_by_mailbox_type failed [%d]", err);
1305                 goto FINISH_OFF;
1306         }
1307         dst_mailbox_id = local_mailbox->mailbox_id;
1308         emstorage_free_mailbox(&local_mailbox, 1, NULL);
1309
1310
1311         if (!emcore_connect_to_remote_mailbox(account_id, EMAIL_CONNECT_FOR_SENDING, (void **)&tmp_stream, &err))  {
1312                 EM_DEBUG_EXCEPTION(" emcore_connect_to_remote_mailbox failed [%d]", err);
1313
1314                 if (err == EMAIL_ERROR_CONNECTION_BROKEN)
1315                         err = EMAIL_ERROR_CANCELLED;
1316                 status = EMAIL_SEND_CONNECTION_FAIL;
1317                 goto FINISH_OFF;
1318         }
1319
1320         stream = (SENDSTREAM *)tmp_stream;
1321
1322         if (!emcore_check_send_mail_thread_status()) {
1323                 EM_DEBUG_EXCEPTION(" emcore_check_send_mail_thread_status failed...");
1324                 err = EMAIL_ERROR_CANCELLED;
1325                 goto FINISH_OFF;
1326         }
1327
1328         /*  set request of delivery status. */
1329         EM_DEBUG_LOG("opt->req_delivery_receipt [%d]", opt->req_delivery_receipt);
1330         EM_DEBUG_LOG("mail_tbl_data->report_status [%d]", mail_tbl_data->report_status);
1331
1332         if (opt->req_delivery_receipt == EMAIL_OPTION_REQ_DELIVERY_RECEIPT_ON || (mail_tbl_data->report_status & EMAIL_MAIL_REQUEST_DSN))  {
1333                 EM_DEBUG_LOG("DSN is required.");
1334                 stream->protocol.esmtp.dsn.want = 1;
1335                 stream->protocol.esmtp.dsn.full = 0;
1336                 stream->protocol.esmtp.dsn.notify.failure = 1;
1337                 stream->protocol.esmtp.dsn.notify.success = 1;
1338         }
1339
1340         mail_tbl_data->save_status = EMAIL_MAIL_STATUS_SENDING;
1341
1342         /*Update status save_status to DB*/
1343         if (!emstorage_set_field_of_mails_with_integer_value(account_id, &mail_id, 1, "save_status", mail_tbl_data->save_status, false, &err))
1344                 EM_DEBUG_EXCEPTION("emstorage_set_field_of_mails_with_integer_value failed [%d]", err);
1345
1346         /*  send mail to server. */
1347         if (!emcore_send_mail_smtp(stream, envelope, fpath, account_id, mail_id, &err)) {
1348                 EM_DEBUG_EXCEPTION(" emcore_send_mail_smtp failed [%d]", err);
1349 #ifndef __FEATURE_MOVE_TO_OUTBOX_FIRST__
1350                 if (!emstorage_get_mailbox_by_mailbox_type(account_id, EMAIL_MAILBOX_TYPE_OUTBOX, &local_mailbox, false, &err))  {
1351                         EM_DEBUG_EXCEPTION("emstorage_get_mailbox_by_mailbox_type failed [%d]", err);
1352                         goto FINISH_OFF;
1353                 }
1354                 dst_mailbox_id = local_mailbox->mailbox_id;
1355                 emstorage_free_mailbox(&local_mailbox, 1, NULL);
1356
1357                 /*  unsent mail is moved to 'OUTBOX'. */
1358                 if (!emcore_move_mail(&mail_id, 1, dst_mailbox_id, EMAIL_MOVED_BY_COMMAND, 0, NULL))
1359                         EM_DEBUG_EXCEPTION(" emcore_mail_move falied...");
1360 #endif
1361                 goto FINISH_OFF;
1362         }
1363
1364         /*  sent mail is moved to 'SENT' box or deleted. */
1365         if (opt->keep_local_copy)  {
1366                 if (!emstorage_get_mailbox_by_mailbox_type(account_id, EMAIL_MAILBOX_TYPE_SENTBOX, &local_mailbox, true, &err))  {
1367                         EM_DEBUG_EXCEPTION("emstorage_get_mailbox_by_mailbox_type failed [%d]", err);
1368                         goto FINISH_OFF;
1369                 }
1370                 dst_mailbox_id = local_mailbox->mailbox_id;
1371
1372                 if (!emcore_move_mail(&mail_id, 1, dst_mailbox_id, EMAIL_MOVED_AFTER_SENDING, 0, &err))
1373                         EM_DEBUG_EXCEPTION(" emcore_mail_move falied [%d]", err);
1374 #ifdef __FEATURE_SYNC_CLIENT_TO_SERVER__
1375 #ifdef __FEATURE_LOCAL_ACTIVITY__
1376                 else if (ref_account->incoming_server_type == EMAIL_SERVER_TYPE_IMAP4) /* To be synced to Sent box only IMAP not for POP */ {
1377
1378                         emstorage_activity_tbl_t new_activity;
1379                         int activityid = 0;
1380
1381                         if (false == emcore_get_next_activity_id(&activityid, &err)) {
1382                                 EM_DEBUG_EXCEPTION(" emcore_get_next_activity_id Failed [%d] ", err);
1383                         }
1384
1385                         memset(&new_activity, 0x00, sizeof(emstorage_activity_tbl_t));
1386                         new_activity.activity_id  =  activityid;
1387                         new_activity.server_mailid = NULL;
1388                         new_activity.account_id = account_id;
1389                         new_activity.mail_id    = mail_id;
1390                         new_activity.activity_type = ACTIVITY_SAVEMAIL;
1391                         new_activity.dest_mbox  = NULL;
1392                         new_activity.src_mbox   = NULL;
1393
1394                         if (!emcore_add_activity(&new_activity, &err)) {
1395                                 EM_DEBUG_EXCEPTION(" emcore_add_activity Failed [%d] ", err);
1396                         }
1397
1398                         if (!emcore_move_mail_on_server(dest_mbox.account_id, dst_mailbox_id, &mail_id, 1, dest_mbox.name, &err)) {
1399                                 EM_DEBUG_EXCEPTION(" emcore_move_mail_on_server falied [%d]", err);
1400                         }
1401                         else {
1402                                 /* Remove ACTIVITY_SAVEMAIL activity */
1403                                 new_activity.activity_id  =  activityid;
1404                                 new_activity.activity_type = ACTIVITY_SAVEMAIL;
1405                                 new_activity.account_id = account_id;
1406                                 new_activity.mail_id    = mail_id;
1407                                 new_activity.dest_mbox  = NULL;
1408                                 new_activity.server_mailid = NULL;
1409                                 new_activity.src_mbox   = NULL;
1410
1411                                 if (!emcore_delete_activity(&new_activity, &err)) {
1412                                         EM_DEBUG_EXCEPTION(">>>>>>Local Activity [ACTIVITY_SAVEMAIL] [%d] ", err);
1413                                 }
1414                         }
1415                         sent_box = 1;
1416                 }
1417 #endif
1418 #endif
1419
1420                 if (ref_account->incoming_server_type == EMAIL_SERVER_TYPE_IMAP4) {
1421                         emstorage_mailbox_tbl_t* src_mailbox = NULL;
1422                         if (!emstorage_get_mailbox_by_mailbox_type(account_id, EMAIL_MAILBOX_TYPE_OUTBOX, &src_mailbox, true, &err))  {
1423                                 EM_DEBUG_EXCEPTION("emstorage_get_mailbox_by_mailbox_type failed [%d]", err);
1424                                 goto FINISH_OFF;
1425                         }
1426
1427                         if (src_mailbox->local_yn)
1428                                 emcore_sync_mail_from_client_to_server(mail_id);
1429                         else {
1430                                 if (!emcore_move_mail_on_server(account_id, src_mailbox->mailbox_id, &mail_id, 1, local_mailbox->mailbox_name, &err)) {
1431                                         EM_DEBUG_EXCEPTION(" emcore_move_mail_on_server falied [%d]", err);
1432                                 }
1433                         }
1434
1435                         emstorage_free_mailbox(&src_mailbox, 1, NULL);
1436                 }
1437
1438                 /* On Successful Mail sent remove the Draft flag */
1439                 mail_tbl_data->flags_draft_field = 0;
1440
1441                 if (!emstorage_set_field_of_mails_with_integer_value(account_id, &mail_id, 1, "flags_draft_field", mail_tbl_data->flags_draft_field, false, &err))
1442                         EM_DEBUG_EXCEPTION("Failed to modify extra flag [%d]", err);
1443
1444                 sent_box = 1;
1445         }
1446         else  {
1447                 if (!emcore_delete_mail(account_id, &mail_id, 1, EMAIL_DELETE_LOCALLY, EMAIL_DELETED_AFTER_SENDING, false, &err))
1448                         EM_DEBUG_EXCEPTION(" emcore_delete_mail failed [%d]", err);
1449         }
1450
1451         /* Set the phone log */
1452         if ((err = emcore_set_sent_contacts_log(mail_tbl_data)) != EMAIL_ERROR_NONE) {
1453                 EM_DEBUG_EXCEPTION("emcore_set_sent_contacts_log failed : [%d]", err);
1454         }
1455
1456         /*Update status save_status to DB*/
1457         mail_tbl_data->save_status = EMAIL_MAIL_STATUS_SENT;
1458         if (!emstorage_set_field_of_mails_with_integer_value(account_id, &mail_id, 1, "save_status", mail_tbl_data->save_status, false, &err))
1459                 EM_DEBUG_EXCEPTION("emstorage_set_field_of_mails_with_integer_value failed [%d]", err);
1460
1461         if (!emcore_delete_transaction_info_by_mailId(mail_id))
1462                 EM_DEBUG_EXCEPTION(" emcore_delete_transaction_info_by_mailId failed for mail_id[%d]", mail_id);
1463
1464         ret = true;
1465
1466 FINISH_OFF:
1467         if (ret == false && err != EMAIL_ERROR_INVALID_PARAM && mail_tbl_data)  {
1468                 if (err != EMAIL_ERROR_CANCELLED) {
1469                         mail_tbl_data->save_status = EMAIL_MAIL_STATUS_SEND_FAILURE;
1470                         if (!emstorage_set_field_of_mails_with_integer_value(account_id, &mail_id, 1, "save_status", mail_tbl_data->save_status, false, &err2))
1471                                 EM_DEBUG_EXCEPTION("emstorage_set_field_of_mails_with_integer_value failed [%d]", err2);
1472                 }
1473                 else {
1474                         if (EMAIL_MAIL_STATUS_SEND_CANCELED == mail_tbl_data->save_status)
1475                                 EM_DEBUG_LOG("EMAIL_MAIL_STATUS_SEND_CANCELED Already set for ");
1476                         else {
1477                                 mail_tbl_data->save_status = EMAIL_MAIL_STATUS_SEND_CANCELED;
1478                                 if (!emstorage_set_field_of_mails_with_integer_value(account_id, &mail_id, 1, "save_status", mail_tbl_data->save_status, false, &err2))
1479                                         EM_DEBUG_EXCEPTION("emstorage_set_field_of_mails_with_integer_value failed [%d]", err2);
1480                         }
1481                 }
1482         }
1483
1484         if (ref_account) {
1485                 emcore_free_account(ref_account);
1486                 EM_SAFE_FREE(ref_account);
1487         }
1488
1489 #ifndef __FEATURE_KEEP_CONNECTION__
1490         if (stream)
1491                 smtp_close(stream);
1492 #endif /* __FEATURE_KEEP_CONNECTION__ */
1493         if (stls)
1494                 mail_parameters(NULL, SET_SSLSTART, (void  *)stls);
1495
1496         if (attachment_tbl_data)
1497                 emstorage_free_attachment(&attachment_tbl_data, attachment_tbl_count, NULL);
1498
1499         if (envelope)
1500                 mail_free_envelope(&envelope);
1501
1502         if (fpath) {
1503                 EM_DEBUG_LOG("REMOVE TEMP FILE  :  %s", fpath);
1504                 remove(fpath);
1505                 free(fpath);
1506         }
1507
1508         if(local_mailbox)
1509                 emstorage_free_mailbox(&local_mailbox, 1, NULL);
1510
1511         if (ret == true) {
1512                 if (!emcore_notify_network_event(NOTI_SEND_FINISH, account_id, NULL, mail_id, 0))
1513                         EM_DEBUG_EXCEPTION("emcore_notify_network_event [NOTI_SEND_FINISH] Failed");
1514 #ifdef __FEATURE_SUPPORT_VALIDATION_SYSTEM__
1515                 if(mail_tbl_data)
1516                         EM_VALIDATION_SYSTEM_LOG("INFO", mail_id, "Email Send End, %s -> %s, success", mail_tbl_data->full_address_from, mail_tbl_data->full_address_to);
1517 #endif
1518         }
1519         else {
1520                 if (!emcore_notify_network_event(NOTI_SEND_FAIL, account_id, NULL, mail_id, err))
1521                         EM_DEBUG_EXCEPTION("emcore_notify_network_event [NOTI_SEND_FAIL] Failed");
1522 #ifdef __FEATURE_SUPPORT_VALIDATION_SYSTEM__
1523                 if(mail_tbl_data)
1524                 EM_VALIDATION_SYSTEM_LOG("INFO", mail_id, "Email Send End, %s -> %s, failed", mail_tbl_data->full_address_from, mail_tbl_data->full_address_to);
1525 #endif
1526                 emcore_show_user_message(mail_id, EMAIL_ACTION_SEND_MAIL, err);
1527         }
1528
1529         if (mail_tbl_data)
1530                 emstorage_free_mail(&mail_tbl_data, 1, NULL);
1531
1532         if (err_code != NULL)
1533                 *err_code = err;
1534         EM_PROFILE_END(profile_emcore_send_mail);
1535         EM_DEBUG_FUNC_END("ret [%d], err [%d]", ret, err);
1536         return ret;
1537 }
1538
1539 /*  send a saved all mails */
1540 INTERNAL_FUNC int emcore_send_saved_mail(int account_id, char *input_mailbox_name, int *err_code)
1541 {
1542         EM_DEBUG_FUNC_BEGIN("account_id[%d], input_mailbox_name[%p], err_code[%p]", account_id, input_mailbox_name, err_code);
1543
1544         int ret = false;
1545         int err = EMAIL_ERROR_NONE;
1546         int status = EMAIL_SEND_FAIL;
1547         int *mail_ids = NULL;
1548         int handle = 0;
1549         int i = 0;
1550         int total = 0;
1551         int attachment_tbl_count = 0;
1552         char *fpath = NULL;
1553         SENDSTREAM *stream = NULL;
1554         ENVELOPE *envelope = NULL;
1555         email_account_t *ref_account = NULL;
1556         emstorage_mail_tbl_t       *searched_mail_tbl_data = NULL;
1557         emstorage_attachment_tbl_t *attachment_tbl_data    = NULL;
1558         email_option_t *opt = NULL;
1559         sslstart_t      stls = NULL;
1560         void *tmp_stream = NULL;
1561         emstorage_mailbox_tbl_t* local_mailbox = NULL;
1562         int dst_mailbox_id = 0;
1563
1564         if (!account_id || !input_mailbox_name)  {
1565                 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
1566                 err = EMAIL_ERROR_INVALID_PARAM;
1567                 goto FINISH_OFF;
1568         }
1569
1570
1571         if (!(ref_account = emcore_get_account_reference(account_id)))  {
1572                 EM_DEBUG_EXCEPTION("emcore_get_account_reference failed [%d]", account_id);
1573                 err = EMAIL_ERROR_INVALID_ACCOUNT;
1574                 goto FINISH_OFF;
1575         }
1576
1577         FINISH_OFF_IF_CANCELED;
1578
1579         opt = &(ref_account->options);
1580
1581         /*  search mail. */
1582         if (!emstorage_mail_search_start(NULL, account_id, input_mailbox_name, 0, &handle, &total, true, &err))  {
1583                 EM_DEBUG_EXCEPTION("emstorage_mail_search_start failed [%d]", err);
1584                 goto FINISH_OFF;
1585         }
1586
1587         mail_ids = em_malloc(sizeof(int) * total);
1588         if (mail_ids == NULL) {
1589                 EM_DEBUG_EXCEPTION("malloc failed...");
1590                 err = EMAIL_ERROR_OUT_OF_MEMORY;
1591                 goto FINISH_OFF;
1592         }
1593
1594         for (i = 0; i < total ; i++) {
1595                 if (!emstorage_mail_search_result(handle, RETRIEVE_ID, (void **)&mail_ids[i], true, &err))  {
1596                         EM_DEBUG_EXCEPTION("emstorage_mail_search_result failed [%d]", err);
1597                         goto FINISH_OFF;
1598                 }
1599         }
1600
1601         if (!emstorage_mail_search_end(handle, true, &err)) {
1602                 EM_DEBUG_EXCEPTION("emstorage_mail_search_end failed [%d]", err);
1603                 goto FINISH_OFF;
1604         }
1605
1606         handle = 0;
1607
1608         mail_send_notify(EMAIL_SEND_PREPARE, 0, 0, account_id, mail_ids[total], err);
1609
1610         for (i = 0; i < total; i++) {
1611                 FINISH_OFF_IF_CANCELED;
1612
1613                 if (!emstorage_get_mail_by_id(mail_ids[i], &searched_mail_tbl_data, false, &err)) {
1614                         EM_DEBUG_EXCEPTION("emstorage_get_mail_by_id failed [%d]", err);
1615                         goto FINISH_OFF;
1616                 }
1617
1618                 /* Skip the mail canceled */
1619                 if (searched_mail_tbl_data->save_status == EMAIL_MAIL_STATUS_SEND_CANCELED)  {
1620                         EM_DEBUG_EXCEPTION("The mail was canceled. [%d]", mail_ids[i]);
1621                         emstorage_free_mail(&searched_mail_tbl_data, 1, &err);
1622                         searched_mail_tbl_data = NULL;
1623                         continue;
1624                 }
1625
1626                 if ( (err = emstorage_get_attachment_list(mail_ids[i], false, &attachment_tbl_data, &attachment_tbl_count)) != EMAIL_ERROR_NONE) {
1627                         EM_DEBUG_EXCEPTION("emstorage_get_attachment_list failed [%d]", err);
1628                         goto FINISH_OFF;
1629                 }
1630
1631                 /* check for email_address validation */
1632                 if ( (err = em_verify_email_address_of_mail_tbl(searched_mail_tbl_data, false)) != EMAIL_ERROR_NONE ) {
1633                         err = EMAIL_ERROR_INVALID_ADDRESS;
1634                         EM_DEBUG_EXCEPTION("em_verify_email_address_of_mail_tbl failed [%d]", err);
1635                         goto FINISH_OFF;
1636                 }
1637
1638                 searched_mail_tbl_data->save_status = EMAIL_MAIL_STATUS_SENDING;
1639
1640                 if (!emcore_make_rfc822_file_from_mail(searched_mail_tbl_data, attachment_tbl_data, attachment_tbl_count, &envelope, &fpath, opt, &err))  {
1641                         EM_DEBUG_EXCEPTION("emcore_make_rfc822_file_from_mail falied [%d]", err);
1642                         goto FINISH_OFF;
1643                 }
1644
1645                 FINISH_OFF_IF_CANCELED;
1646
1647                 /*  connect mail server. */
1648                 if (!stream) {
1649                         /*  if there no security option, unset security. */
1650                         if (!ref_account->outgoing_server_secure_connection) {
1651                                 stls = (sslstart_t)mail_parameters(NULL, GET_SSLSTART, NULL);
1652                                 mail_parameters(NULL, SET_SSLSTART, NULL);
1653                         }
1654
1655                         stream = NULL;
1656                         if (!emcore_connect_to_remote_mailbox(account_id, EMAIL_CONNECT_FOR_SENDING, &tmp_stream, &err) || !tmp_stream)  {
1657                                 EM_DEBUG_EXCEPTION("emcore_connect_to_remote_mailbox failed [%d]", err);
1658
1659                                 if (err == EMAIL_ERROR_CONNECTION_BROKEN)
1660                                         err = EMAIL_ERROR_CANCELLED;
1661
1662                                 status = EMAIL_SEND_CONNECTION_FAIL;
1663                                 goto FINISH_OFF;
1664                         }
1665
1666                         stream = (SENDSTREAM *)tmp_stream;
1667
1668                         FINISH_OFF_IF_CANCELED;
1669
1670                         mail_send_notify(EMAIL_SEND_CONNECTION_SUCCEED, 0, 0, account_id, mail_ids[i], err);
1671
1672                         /*  reqest of delivery status. */
1673                         if (opt && opt->req_delivery_receipt == EMAIL_OPTION_REQ_DELIVERY_RECEIPT_ON)  {
1674                                 stream->protocol.esmtp.dsn.want = 1;
1675                                 stream->protocol.esmtp.dsn.full = 0;
1676                                 stream->protocol.esmtp.dsn.notify.failure = 1;
1677                                 stream->protocol.esmtp.dsn.notify.success = 1;
1678                         }
1679
1680                         mail_send_notify(EMAIL_SEND_START, 0, 0, account_id, mail_ids[i], err);
1681                 }
1682
1683                 searched_mail_tbl_data->save_status = EMAIL_MAIL_STATUS_SENDING;
1684
1685                 /*  update mail status to sending. */
1686                 if (!emstorage_change_mail_field(mail_ids[i], UPDATE_EXTRA_FLAG, searched_mail_tbl_data, true, &err))  {
1687                         EM_DEBUG_EXCEPTION("emstorage_change_mail_field failed [%d]", err);
1688
1689                         goto FINISH_OFF;
1690                 }
1691
1692                 if (!emcore_send_mail_smtp(stream, envelope, fpath, account_id, mail_ids[i], &err))  {
1693                         EM_DEBUG_EXCEPTION("emcore_send_mail_smtp failed [%d]", err);
1694
1695                         searched_mail_tbl_data->save_status = EMAIL_MAIL_STATUS_SEND_FAILURE;
1696
1697                         /*  update mail status to failure. */
1698                         if (!emstorage_change_mail_field(mail_ids[i], UPDATE_EXTRA_FLAG, searched_mail_tbl_data, true, &err))
1699                                 EM_DEBUG_EXCEPTION("emstorage_change_mail_field failed [%d]", err);
1700
1701                         if (!emstorage_get_mailbox_by_mailbox_type(account_id, EMAIL_MAILBOX_TYPE_OUTBOX, &local_mailbox, true, &err))  {
1702                                 EM_DEBUG_EXCEPTION("emstorage_get_mailbox_by_mailbox_type failed [%d]", err);
1703                                 goto FINISH_OFF;
1704                         }
1705                         dst_mailbox_id = local_mailbox->mailbox_id;
1706
1707                         emcore_move_mail(&mail_ids[i], 1, dst_mailbox_id, EMAIL_MOVED_AFTER_SENDING, 0, NULL);
1708
1709                         if(local_mailbox)
1710                                 emstorage_free_mailbox(&local_mailbox, 1, NULL);
1711
1712                         goto FINISH_OFF;
1713                 }
1714
1715                 searched_mail_tbl_data->save_status = EMAIL_MAIL_STATUS_SENT;
1716
1717                 /*  update mail status to sent mail. */
1718                 if (!emstorage_change_mail_field(mail_ids[i], UPDATE_EXTRA_FLAG, searched_mail_tbl_data, true, &err))  {
1719                         EM_DEBUG_EXCEPTION("emstorage_change_mail_field failed [%d]", err);
1720                         goto FINISH_OFF;
1721                 }
1722
1723                 /*  sent mail is moved to 'SENT' box or deleted. */
1724                 if (opt->keep_local_copy)  {
1725                         if (!emstorage_get_mailbox_by_mailbox_type(account_id, EMAIL_MAILBOX_TYPE_SENTBOX, &local_mailbox, true, &err))  {
1726                                 EM_DEBUG_EXCEPTION("emstorage_get_mailbox_by_mailbox_type failed [%d]", err);
1727                                 goto FINISH_OFF;
1728                         }
1729                         dst_mailbox_id = local_mailbox->mailbox_id;
1730
1731                         if (!emcore_move_mail(&mail_ids[i], 1, dst_mailbox_id, EMAIL_MOVED_AFTER_SENDING, 0, &err))
1732                                 EM_DEBUG_EXCEPTION("emcore_mail_move falied [%d]", err);
1733
1734                         if(local_mailbox)
1735                                 emstorage_free_mailbox(&local_mailbox, 1, NULL);
1736                 }
1737                 else  {
1738                         if (!emcore_delete_mail(account_id, &mail_ids[i], 1, EMAIL_DELETE_LOCALLY, EMAIL_DELETED_AFTER_SENDING, false, &err))
1739                                 EM_DEBUG_EXCEPTION("emcore_delete_mail falied [%d]", err);
1740                 }
1741
1742                 /* Set the phone log */
1743                 if ((err = emcore_set_sent_contacts_log(searched_mail_tbl_data)) != EMAIL_ERROR_NONE) {
1744                         EM_DEBUG_EXCEPTION("emcore_set_sent_contacts_log failed : [%d]", err);
1745                 }
1746
1747                 if(searched_mail_tbl_data) {
1748                         emstorage_free_mail(&searched_mail_tbl_data, 1, NULL);
1749                         searched_mail_tbl_data = NULL;
1750                 }
1751
1752                 if(attachment_tbl_data)
1753                         emstorage_free_attachment(&attachment_tbl_data, attachment_tbl_count, NULL);
1754
1755                 mail_free_envelope(&envelope); envelope = NULL;
1756
1757                 if (fpath)  {
1758                         remove(fpath);
1759                         EM_SAFE_FREE(fpath);
1760                 }
1761         }
1762
1763
1764         ret = true;
1765
1766 FINISH_OFF:
1767
1768         if (ref_account) {
1769                 emcore_free_account(ref_account);
1770                 EM_SAFE_FREE(ref_account);
1771         }
1772
1773         if (stream)
1774                 smtp_close(stream);
1775
1776         if (stls)
1777                 mail_parameters(NIL, SET_SSLSTART, (void  *)stls);
1778
1779         if (envelope)
1780                 mail_free_envelope(&envelope);
1781
1782         if (handle)  {
1783                 if (!emstorage_mail_search_end(handle, true, &err))
1784                         EM_DEBUG_EXCEPTION("emstorage_mail_search_end failed [%d]", err);
1785         }
1786
1787         if (searched_mail_tbl_data)
1788                 emstorage_free_mail(&searched_mail_tbl_data, 1, NULL);
1789
1790         if(attachment_tbl_data)
1791                 emstorage_free_attachment(&attachment_tbl_data, attachment_tbl_count, NULL);
1792
1793         if (fpath)  {
1794                 remove(fpath);
1795                 EM_SAFE_FREE(fpath);
1796         }
1797
1798         if(local_mailbox)
1799                 emstorage_free_mailbox(&local_mailbox, 1, NULL);
1800
1801         if (ret == true)
1802                 mail_send_notify(EMAIL_SEND_FINISH, 0, 0, account_id, mail_ids[total], err);
1803         else {
1804                 if(mail_ids) /* prevent 34385 */
1805                         mail_send_notify(status, 0, 0, account_id, mail_ids[total], err);
1806                 emcore_show_user_message(account_id, EMAIL_ACTION_SEND_MAIL, err);
1807         }
1808
1809         EM_SAFE_FREE(mail_ids);
1810
1811         if (err_code != NULL)
1812                 *err_code = err;
1813
1814         return ret;
1815 }
1816
1817 static int emcore_send_mail_smtp(SENDSTREAM *stream, ENVELOPE *env, char *data_file, int account_id, int mail_id, int *err_code)
1818 {
1819         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);
1820         EM_PROFILE_BEGIN(profile_emcore_send_mail_smtp);
1821
1822         int ret = false;
1823         int err = EMAIL_ERROR_NONE;
1824         int recipients = 0;
1825         long total = 0, sent = 0, send_ret = 0, send_err = 0, sent_percent = 0, last_sent_percent = 0;
1826         char buf[2048] = { 0, };
1827         email_account_t *ref_account = NULL;
1828         FILE *fp = NULL;
1829
1830         if (!env || !env->from || (!env->to && !env->cc && !env->bcc)) {
1831                 if (env != NULL)
1832                         EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
1833                 err = EMAIL_ERROR_INVALID_PARAM;
1834                 goto FINISH_OFF;
1835         }
1836
1837         if (!env->from->mailbox || !env->from->host) {
1838                 EM_DEBUG_EXCEPTION("env->from->mailbox[%p], env->from->host[%p]", env->from->mailbox, env->from->host);
1839                 err = EMAIL_ERROR_INVALID_PARAM;
1840                 goto FINISH_OFF;
1841         }
1842
1843         if (!(ref_account = emcore_get_account_reference(account_id))) {
1844                 EM_DEBUG_EXCEPTION("emcore_get_account_reference failed [%d]", account_id);
1845                 err = EMAIL_ERROR_INVALID_ACCOUNT;
1846                 goto FINISH_OFF;
1847         }
1848
1849         EM_DEBUG_LOG("Modifying - MAIL FROM ");
1850         if (ref_account->user_email_address == NULL) {
1851                 EM_DEBUG_LOG("ref_account->user_email_address is null!!");
1852                 SNPRINTF(buf, sizeof(buf), "FROM:<%s@%s>", env->from->mailbox, env->from->host);
1853         }
1854         else
1855                 SNPRINTF(buf, sizeof(buf), "FROM:<%s>", ref_account->user_email_address);
1856
1857         /*  set DSN for ESMTP */
1858         if (stream->protocol.esmtp.ok) {
1859                 if (stream->protocol.esmtp.eightbit.ok && stream->protocol.esmtp.eightbit.want)
1860                         strncat (buf, " BODY=8BITMIME", sizeof(buf)-(EM_SAFE_STRLEN(buf)+1));
1861
1862                 EM_DEBUG_LOG("stream->protocol.esmtp.dsn.ok [%d]", stream->protocol.esmtp.dsn.ok);
1863
1864                 if (stream->protocol.esmtp.dsn.ok && stream->protocol.esmtp.dsn.want) {
1865                         EM_DEBUG_LOG("stream->protocol.esmtp.dsn.want is required");
1866                         strncat (buf, stream->protocol.esmtp.dsn.full ? " RET=FULL" : " RET=HDRS", sizeof(buf)-EM_SAFE_STRLEN(buf)-1);
1867                         if (stream->protocol.esmtp.dsn.envid)
1868                                 SNPRINTF (buf + EM_SAFE_STRLEN (buf), sizeof(buf)-(EM_SAFE_STRLEN(buf)), " ENVID=%.100s", stream->protocol.esmtp.dsn.envid);
1869                 }
1870                 else
1871                         EM_DEBUG_LOG("stream->protocol.esmtp.dsn.want is not required or DSN is not supported");
1872         }
1873
1874         EM_PROFILE_BEGIN(profile_prepare_and_head);
1875         send_ret = smtp_send(stream, "RSET", 0);
1876         EM_DEBUG_LOG("[SMTP] RSET --------> %s", stream->reply);
1877
1878         if (send_ret != SMTP_RESPONSE_OK) {
1879                 err = send_ret;
1880                 goto FINISH_OFF;
1881         }
1882
1883         send_ret = smtp_send(stream, "MAIL", buf);
1884         EM_DEBUG_LOG("[SMTP] MAIL %s --------> %s", buf, stream->reply);
1885
1886         switch (send_ret) {
1887                 case SMTP_RESPONSE_OK:
1888                         break;
1889
1890                 case SMTP_RESPONSE_WANT_AUTH  :
1891                 case SMTP_RESPONSE_WANT_AUTH2:
1892                         EM_DEBUG_EXCEPTION("SMTP error : authentication required...");
1893                         err = EMAIL_ERROR_AUTH_REQUIRED;
1894                         goto FINISH_OFF;
1895
1896                 case SMTP_RESPONSE_UNAVAIL:
1897                         EM_DEBUG_EXCEPTION("SMTP error : sending unavailable...");
1898                         err = EMAIL_ERROR_SMTP_SEND_FAILURE;
1899                         goto FINISH_OFF;
1900                 case SMTP_RESPONSE_CONNECTION_BROKEN:
1901                         EM_DEBUG_EXCEPTION("SMTP error : SMTP connection broken...");
1902                         err = EMAIL_ERROR_SMTP_SEND_FAILURE;
1903                         goto FINISH_OFF;
1904                 default:
1905                         EM_DEBUG_EXCEPTION("SMTP error : sending unavailable...");
1906                         err = EMAIL_ERROR_SMTP_SEND_FAILURE;
1907                         goto FINISH_OFF;
1908         }
1909
1910         if (env->to) {
1911                 send_ret = smtp_rcpt(stream, env->to, &send_err);
1912                 EM_DEBUG_LOG("[SMTP] RCPT TO : <%s@%s> ... --------> %s", env->to->mailbox, env->to->host, env->to->error ? env->to->error  :  stream->reply);
1913                 if (send_ret) {
1914                         err = stream->replycode;
1915                         goto FINISH_OFF;
1916                 }
1917
1918                 if (!send_err)
1919                         recipients++;
1920         }
1921
1922         if (env->cc) {
1923                 send_ret = smtp_rcpt(stream, env->cc, &send_err);
1924                 EM_DEBUG_LOG("[SMTP] RCPT TO : <%s@%s> ... --------> %s", env->cc->mailbox, env->cc->host, env->cc->error ? env->cc->error  :  stream->reply);
1925                 if (send_ret) {
1926                         err = stream->replycode;
1927                         goto FINISH_OFF;
1928                 }
1929
1930                 if (!send_err)
1931                         recipients++;
1932         }
1933
1934         if (env->bcc) {
1935                 send_ret = smtp_rcpt(stream, env->bcc, &send_err);
1936                 EM_DEBUG_LOG("[SMTP] RCPT TO : <%s@%s> ... --------> %s", env->bcc->mailbox, env->bcc->host, env->bcc->error ? env->bcc->error  :  stream->reply);
1937                 if (send_ret) {
1938                         err = stream->replycode;
1939                         goto FINISH_OFF;
1940                 }
1941
1942                 if (!send_err)
1943                         recipients++;
1944         }
1945
1946
1947         if (send_err) {
1948                 EM_DEBUG_EXCEPTION("One or more recipients failed...");
1949                 err = EMAIL_ERROR_INVALID_ADDRESS;
1950         }
1951
1952         if (!recipients) {
1953                 EM_DEBUG_EXCEPTION("No valid recipients...");
1954
1955                 switch (stream->replycode) {
1956                         case SMTP_RESPONSE_UNAVAIL:
1957                         case SMTP_RESPONSE_WANT_AUTH  :
1958                         case SMTP_RESPONSE_WANT_AUTH2:
1959                                 err = EMAIL_ERROR_AUTH_REQUIRED;
1960                                 break;
1961
1962                         default:
1963                                 err = EMAIL_ERROR_INVALID_ADDRESS;
1964                                 break;
1965                 }
1966                 goto FINISH_OFF;
1967         }
1968
1969         send_ret = smtp_send(stream, "DATA", 0);
1970         EM_DEBUG_LOG("[SMTP] DATA --------> %s", stream->reply);
1971         EM_PROFILE_END(profile_prepare_and_head);
1972
1973         if (send_ret != SMTP_RESPONSE_READY) {
1974                 err = send_ret;
1975                 goto FINISH_OFF;
1976         }
1977
1978         if (data_file) {
1979                 EM_PROFILE_BEGIN(profile_open_file);
1980                 if (!(fp = fopen(data_file, "r+"))) {
1981                         EM_DEBUG_EXCEPTION("fopen(\"%s\") failed...", data_file);
1982                         err = EMAIL_ERROR_SYSTEM_FAILURE;
1983                         goto FINISH_OFF;
1984                 }
1985                 EM_PROFILE_END(profile_open_file);
1986
1987
1988 #ifdef __FEATURE_SEND_OPTMIZATION__
1989         {
1990                 char *data = NULL;
1991                 int read_size, allocSize, dataSize, gMaxAllocSize = 40960; /*  40KB */
1992
1993                 fseek(fp, 0, SEEK_END);
1994                 total = ftell(fp);
1995                 fseek(fp, 0, SEEK_SET);
1996                 EM_DEBUG_LOG("total size [%d]", total);
1997
1998                 if (total < gMaxAllocSize)
1999                         allocSize = total + 1;
2000                 else
2001                         allocSize = gMaxAllocSize;
2002
2003                 EM_PROFILE_BEGIN(profile_allocation);
2004                 /* Allocate a buffer of max 2MB to read from file */
2005                 data = (char *)em_malloc(allocSize);
2006                 allocSize--;
2007                 EM_PROFILE_END(profile_allocation);
2008
2009                 if (NULL == data) {
2010                         err = EMAIL_ERROR_SMTP_SEND_FAILURE;
2011                         goto FINISH_OFF;
2012                 }
2013
2014                 while (total) {
2015                         if (total  < allocSize)
2016                                 dataSize = total;
2017                         else
2018                                 dataSize = allocSize;
2019
2020                         memset(data, 0x0, dataSize+1);
2021                         read_size = fread(data, sizeof (char), dataSize, fp);
2022
2023                         if (read_size != dataSize) {
2024                                 /* read fail. */
2025                                 EM_SAFE_FREE(data);
2026                                 EM_DEBUG_EXCEPTION("Read from file failed");
2027                                 err = EMAIL_ERROR_SMTP_SEND_FAILURE;
2028                                 goto FINISH_OFF;
2029                         }
2030                         sent += read_size;
2031
2032                         EM_DEBUG_LOG("before smtp_soutr_test");
2033                         if (!(send_ret = smtp_soutr_test(stream->netstream, data))) {
2034                                 EM_SAFE_FREE(data);
2035                                 EM_DEBUG_EXCEPTION("Failed to send the data ");
2036                                 err = EMAIL_ERROR_SMTP_SEND_FAILURE;
2037                                 goto FINISH_OFF;
2038                         }
2039                         else {
2040                                 sent_percent = (int) ((double)sent / (double)total * 100.0);
2041                                 if (last_sent_percent + 5 <= sent_percent) {
2042                                         if (!emcore_notify_network_event(NOTI_SEND_START, account_id, NULL, mail_id, sent_percent))
2043                                                 EM_DEBUG_EXCEPTION("emcore_notify_network_event [NOTI_SEND_START] Failed >>>>");
2044                                         last_sent_percent = sent_percent;
2045                                 }
2046                                 EM_DEBUG_LOG("Sent data Successfully. sent[%d] total[%d]", sent, total);
2047                         }
2048                         total -= dataSize;
2049                 }
2050
2051                 EM_SAFE_FREE(data);
2052         }
2053 #else
2054                 fseek(fp, 0, SEEK_END);
2055                 total = ftell(fp);
2056                 fseek(fp, 0, SEEK_SET);
2057
2058                 while (fgets(buf, 1024, fp)) {
2059 #ifdef FEATURE_SEND_DATA_DEBUG
2060                         EM_DEBUG_LOG("%s", buf);
2061 #endif
2062                         sent += EM_SAFE_STRLEN(buf);
2063
2064                         if (!(send_ret = smtp_soutr(stream->netstream, buf)))
2065                                 break;
2066                         /*  Sending Progress Notification */
2067                         sent_percent = (int) ((double)sent / (double)total * 100.0);
2068                         if (last_sent_percent + 5 <= sent_percent) {
2069                                 /* Disabled Temporary
2070                                 if (!emcore_notify_network_event(NOTI_SEND_START, account_id, NULL, mail_id, sent_percent))
2071                                         EM_DEBUG_EXCEPTION(" emcore_notify_network_event [NOTI_SEND_START] Failed >>>>");
2072                                 */
2073                                 last_sent_percent = sent_percent;
2074                         }
2075                 }
2076
2077 #endif
2078                 if (!send_ret) {
2079                         EM_DEBUG_EXCEPTION("smtp_soutr failed - %ld", send_ret);
2080                         err = EMAIL_ERROR_SMTP_SEND_FAILURE;
2081                         goto FINISH_OFF;
2082                 }
2083         }
2084
2085         send_ret = smtp_send(stream, ".", 0);
2086         EM_DEBUG_LOG("[SMTP] . --------> %s", stream->reply);
2087
2088         if (send_ret != SMTP_RESPONSE_OK) {
2089                 err = send_ret;
2090                 goto FINISH_OFF;
2091         }
2092
2093         ret = true;
2094
2095 FINISH_OFF:
2096         if (ret == false)
2097                 smtp_send(stream, "RSET", 0);
2098
2099         if (ref_account) {
2100                 emcore_free_account(ref_account);
2101                 EM_SAFE_FREE(ref_account);
2102         }
2103
2104         if (err_code)
2105                 *err_code = err;
2106
2107         if (fp)
2108                 fclose(fp);
2109         EM_PROFILE_END(profile_emcore_send_mail_smtp);
2110         EM_DEBUG_FUNC_END("ret [%d]", ret);
2111         return ret;
2112 }
2113
2114 /* ------ rfc822 handle --------------------------------------------------- */
2115 #define RANDOM_NUMBER_LENGTH 35
2116
2117 char *emcore_generate_content_id_string(const char *hostname, int *err)
2118 {
2119         EM_DEBUG_FUNC_BEGIN("hostname[%p]", hostname);
2120
2121         if (!hostname) {
2122                 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
2123                 if (err)
2124                         *err = EMAIL_ERROR_INVALID_PARAM;
2125                 return NULL;
2126         }
2127
2128         int cid_length = RANDOM_NUMBER_LENGTH + EM_SAFE_STRLEN(hostname) + 2, random_number_1, random_number_2, random_number_3, random_number_4;
2129         char *cid_string = NULL;
2130
2131         cid_string = malloc(cid_length);
2132
2133         if (!cid_string) {
2134                 if (err)
2135                         *err = EMAIL_ERROR_OUT_OF_MEMORY;
2136                 return NULL;
2137         }
2138
2139         memset(cid_string, 0, cid_length);
2140
2141         srand(time(NULL) + rand());
2142         random_number_1 = rand() * rand();
2143         random_number_2 = rand() * rand();
2144         random_number_3 = rand() * rand();
2145         random_number_4 = rand() * rand();
2146
2147         SNPRINTF(cid_string, cid_length, "<%08x%08x%08x%08x@%s>", random_number_1, random_number_2, random_number_3, random_number_4, hostname);
2148
2149         if (err)
2150                 *err = EMAIL_ERROR_NONE;
2151
2152         EM_DEBUG_FUNC_END("cid_string [%s]", cid_string);
2153         return cid_string;
2154 }
2155
2156
2157 /* ------ attach_part ----------------------------------------------------- */
2158 /*  data  :  if filename NULL, content data. */
2159 /*              else absolute path of file to be attached. */
2160 /*  data_len  :  length of data. if filename not NULL, ignored. */
2161 /*  file_name :  attahcment name. */
2162 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)
2163 {
2164         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);
2165
2166         int        ret = false;
2167         int        error = EMAIL_ERROR_NONE;
2168         int        has_special_character = 0;
2169         int        base64_file_name_length = 0;
2170         int        i= 0;
2171         gsize      bytes_read;
2172         gsize      bytes_written;
2173         char      *encoded_file_name = NULL;
2174         char      *extension = NULL;
2175         char      *base64_file_name = NULL;
2176         char      *result_file_name = NULL;
2177         char       content_disposition[100] = { 0, };
2178         PARAMETER *last_param = NULL;
2179         PARAMETER *param = NULL;
2180         PART      *last_part = NULL;
2181         PART      *part = NULL;
2182         SIZEDTEXT  source_text;
2183         GError    *glib_error = NULL;
2184         CHARSET   *result_charset = NULL;
2185
2186         if (!body)  {
2187                 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
2188                 error = EMAIL_ERROR_INVALID_PARAM;
2189                 goto FINISH_OFF;
2190         }
2191
2192         if (body->nested.part)  {
2193                 last_part = body->nested.part;
2194
2195                 if (last_part != NULL)  {
2196                         while (last_part->next)
2197                                 last_part = last_part->next;
2198                 }
2199         }
2200
2201         /*  PART */
2202         part = mail_newbody_part();
2203         if (part == NULL)  {
2204                 EM_DEBUG_EXCEPTION("mail_newbody_part failed...");
2205                 error = EMAIL_ERROR_OUT_OF_MEMORY;
2206                 goto FINISH_OFF;
2207         }
2208
2209         part->next = NULL;
2210
2211         if (last_part)
2212                 last_part->next = part;
2213         else
2214                 body->nested.part = part;
2215
2216         last_part = part;
2217
2218         /* set data..  */
2219         /* content_data = (unsigned char  *)fs_get(data_len + 1); */
2220         /* memcpy(content_data, data, data_len); */
2221         /* content_data[data_len] = 0; */
2222
2223         /* part->body.contents.text.data = content_data; */
2224         /* part->body.contents.text.size = data_len; */
2225
2226         if (filename)  {   /*  attachment */
2227                 source_text.data = (unsigned char*)filename;
2228                 source_text.size = EM_SAFE_STRLEN(filename);
2229
2230                 result_charset   = (CHARSET*)utf8_infercharset(&source_text);
2231
2232                 if(result_charset) {
2233                         EM_DEBUG_LOG("return_charset->name [%s]", result_charset->name);
2234                         encoded_file_name = (char*)g_convert (filename, -1, "UTF-8", result_charset->name, &bytes_read, &bytes_written, &glib_error);
2235                 }
2236                 else {
2237                         i = 0;
2238                         while(filename[i]) {
2239                                 if(filename[i++] & 0x80) {
2240                                         has_special_character = 1;
2241                                         break;
2242                                 }
2243                         }
2244                         EM_DEBUG_LOG("has_special_character [%d]", has_special_character);
2245                         if(has_special_character)
2246                                 encoded_file_name = (char*)g_convert (filename, -1, "UTF-8", "EUC-KR", &bytes_read, &bytes_written, &glib_error);
2247                 }
2248
2249                 EM_DEBUG_LOG("encoded_file_name [%s]", encoded_file_name);
2250
2251                 if(encoded_file_name == NULL)
2252                         encoded_file_name = strdup(filename);
2253
2254                 if(!em_encode_base64(encoded_file_name, EM_SAFE_STRLEN(encoded_file_name), &base64_file_name, (unsigned long*)&base64_file_name_length, &error)) {
2255                         EM_DEBUG_EXCEPTION("em_encode_base64 failed. error [%d]", error);
2256                         goto FINISH_OFF;
2257                 }
2258
2259                 result_file_name = em_replace_string(base64_file_name, "\015\012", "");
2260
2261                 EM_DEBUG_LOG("base64_file_name_length [%d]", base64_file_name_length);
2262
2263                 if(result_file_name) {
2264                         EM_SAFE_FREE(encoded_file_name);
2265                         encoded_file_name = em_malloc(EM_SAFE_STRLEN(result_file_name) + 15);
2266                         if(!encoded_file_name) {
2267                                 EM_DEBUG_EXCEPTION("em_malloc failed.");
2268                                 goto FINISH_OFF;
2269                         }
2270                         snprintf(encoded_file_name, EM_SAFE_STRLEN(result_file_name) + 15, "=?UTF-8?B?%s?=", result_file_name);
2271                         EM_DEBUG_LOG("encoded_file_name [%s]", encoded_file_name);
2272                 }
2273
2274                 extension = em_get_extension_from_file_path(filename, NULL);
2275
2276                 part->body.type = em_get_content_type_from_extension_string(extension, NULL);
2277                 if(part->body.type == TYPEIMAGE) {
2278                         part->body.subtype = strdup(extension);
2279                 } else if (part->body.type == TYPEPKCS7_SIGN) {
2280                         part->body.subtype = strdup("pkcs7-signature");
2281                         part->body.type = TYPEAPPLICATION;
2282                 } else if (part->body.type == TYPEPKCS7_MIME) {
2283                         part->body.subtype = strdup("pkcs7-mime");
2284                         part->body.type = TYPEAPPLICATION;
2285                 } else
2286                         part->body.subtype = strdup("octet-stream");
2287
2288                 part->body.encoding = ENCBINARY;
2289                 part->body.size.bytes = data_len;
2290
2291                 if (data)
2292                         part->body.sparep = EM_SAFE_STRDUP((char *)data); /*  file path */
2293                 else
2294                         part->body.sparep = NULL;
2295
2296                 SNPRINTF(content_disposition, sizeof(content_disposition), "%s", "attachment");
2297
2298                 part->body.disposition.type = cpystr(content_disposition);
2299
2300                 /*  BODY PARAMETER */
2301                 /*  another parameter or get parameter-list from this   function-parameter */
2302                 param = mail_newbody_parameter();
2303                 if (param == NULL)  {
2304                         EM_DEBUG_EXCEPTION("mail_newbody_parameter failed...");
2305                         error = EMAIL_ERROR_OUT_OF_MEMORY;
2306                         goto FINISH_OFF;
2307                 }
2308
2309                 param->attribute          = cpystr("name");
2310                 param->value              = cpystr(encoded_file_name);
2311                 param->next               = NULL;
2312                 last_param                = param;
2313                 last_part->body.parameter = last_param;
2314
2315                 if (is_inline) {
2316                         /*  CONTENT-ID */
2317                         part->body.id = emcore_generate_content_id_string("com.samsung.slp.email", &error);
2318                         part->body.type = TYPEIMAGE;
2319                         /*  EM_SAFE_FREE(part->body.subtype); */
2320                         /*  part->body.subtype = EM_SAFE_STRDUP(content_sub_type); */
2321                 }
2322
2323                 /*  DISPOSITION PARAMETER */
2324                 param = mail_newbody_parameter();
2325                 if (param == NULL)  {
2326                         EM_DEBUG_EXCEPTION("mail_newbody_parameter failed...");
2327                         error = EMAIL_ERROR_OUT_OF_MEMORY;
2328                         goto FINISH_OFF;
2329                 }
2330
2331                 param->attribute                      = cpystr("filename");
2332                 param->value                          = cpystr(encoded_file_name);
2333                 param->next                           = NULL;
2334                 last_param                            = param;
2335                 last_part->body.disposition.parameter = last_param;
2336
2337                 if (is_inline)
2338                         last_part->body.disposition.type = strdup("inline");
2339         }
2340         else  {
2341                 /*  text body (plain/html) */
2342                 part->body.type = TYPETEXT;
2343                 part->body.size.bytes = data_len;
2344
2345                 if (data)
2346                         part->body.sparep = EM_SAFE_STRDUP((char *)data); /*  file path */
2347                 else
2348                         part->body.sparep = NULL;
2349
2350
2351                 if (!content_sub_type)  {
2352                         /* Plain text body */
2353                         part->body.encoding = ENC8BIT;
2354                         part->body.subtype = cpystr("plain");
2355                         last_param = part->body.parameter;
2356
2357                         if (last_param != NULL)  {
2358                                 while (last_param->next)
2359                                         last_param = last_param->next;
2360                         }
2361
2362                         param = mail_newbody_parameter();
2363
2364                         if (param == NULL)  {
2365                                 EM_DEBUG_EXCEPTION("mail_newbody_parameter failed...");
2366                                 error = EMAIL_ERROR_OUT_OF_MEMORY;
2367                                 goto FINISH_OFF;
2368                         }
2369
2370                         param->attribute = cpystr("CHARSET");
2371
2372                         if (data != NULL) {
2373                                 gchar *extract_charset_plain = g_path_get_basename((const gchar *)data);
2374                                 if (extract_charset_plain != NULL && extract_charset_plain[0] != '\0')
2375                                         param->value = cpystr(extract_charset_plain);
2376                                 g_free(extract_charset_plain);
2377                         }
2378                         else
2379                                 param->value = cpystr("UTF-8");
2380
2381                         if(!param->value)
2382                                 param->value = cpystr("UTF-8");
2383
2384                         param->next = NULL;
2385
2386                         if (last_param != NULL)
2387                                 last_param->next = param;
2388                         else
2389                                 part->body.parameter = param;
2390                 }
2391                 else {
2392                         /* HTML text body */
2393                         part->body.encoding = ENC8BIT;
2394                         part->body.subtype  = cpystr(content_sub_type);
2395
2396                         last_param = part->body.parameter;
2397
2398                         if (last_param != NULL)  {
2399                                 while (last_param->next)
2400                                         last_param = last_param->next;
2401                         }
2402
2403                         param = mail_newbody_parameter();
2404
2405                         if (param == NULL)  {
2406                                 EM_DEBUG_EXCEPTION("mail_newbody_parameter failed...");
2407                                 error = EMAIL_ERROR_OUT_OF_MEMORY;
2408                                 goto FINISH_OFF;
2409                         }
2410
2411                         param->attribute = cpystr("CHARSET");
2412
2413                         char *pHtml = NULL;
2414                         if (data != NULL) {
2415                                 gchar *extract_charset = g_path_get_basename((const gchar *)data);
2416                                 if (extract_charset != NULL) {
2417                                         if ((pHtml = strstr(extract_charset, ".htm")) != NULL) {
2418                                                 extract_charset[pHtml-extract_charset] = '\0';
2419                                                 param->value = cpystr(extract_charset);
2420                                         }
2421                                 }
2422
2423                                 if(!param->value)
2424                                         param->value = cpystr("UTF-8");
2425
2426                                 EM_SAFE_FREE(extract_charset);
2427                         }
2428                         else
2429                                 param->value = cpystr("UTF-8");
2430                         param->next = NULL;
2431
2432                         if (last_param != NULL)
2433                                 last_param->next = param;
2434                         else
2435                                 part->body.parameter = param;
2436                 }
2437
2438                 /* NOTE : need to require this code. */
2439                 /* sprintf(content_disposition, "%s\0", "inline"); */
2440                 if (is_inline) {
2441                         SNPRINTF(content_disposition, sizeof(content_disposition), "%s", "inline");
2442                         part->body.disposition.type = cpystr(content_disposition);
2443                 }
2444         }
2445
2446         ret = true;
2447
2448 FINISH_OFF:
2449         EM_SAFE_FREE(encoded_file_name);
2450         EM_SAFE_FREE(result_file_name); /*prevent 26242*/
2451         EM_SAFE_FREE(base64_file_name);
2452         if (err_code != NULL)
2453                 *err_code = error;
2454         EM_DEBUG_FUNC_END();
2455         return ret;
2456 }
2457
2458 static PART *attach_mutipart_with_sub_type(BODY *parent_body, char *sub_type, int *err_code)
2459 {
2460         EM_DEBUG_FUNC_BEGIN("parent_body[%p], sub_type [%s], err_code[%p]", parent_body, sub_type, err_code);
2461
2462         int error = EMAIL_ERROR_NONE;
2463
2464         PART *tail_part_cur = NULL;
2465         PART *new_part = NULL;
2466
2467         if (!parent_body || !sub_type)  {
2468                 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
2469                 error = EMAIL_ERROR_INVALID_PARAM;
2470                 goto FINISH_OFF;
2471         }
2472
2473         if (parent_body->nested.part)  {
2474                 tail_part_cur = parent_body->nested.part;
2475
2476                 if (tail_part_cur != NULL)  {
2477                         while (tail_part_cur->next)
2478                                 tail_part_cur = tail_part_cur->next;
2479                 }
2480         }
2481
2482         new_part = mail_newbody_part();
2483
2484         if (new_part == NULL)  {
2485                 EM_DEBUG_EXCEPTION("EMAIL_ERROR_OUT_OF_MEMORY");
2486                 error = EMAIL_ERROR_OUT_OF_MEMORY;
2487                 goto FINISH_OFF;
2488
2489         }
2490
2491         new_part->next = NULL;
2492         new_part->body.type = TYPEMULTIPART;
2493         new_part->body.subtype = EM_SAFE_STRDUP(sub_type);
2494
2495         if (tail_part_cur)
2496                 tail_part_cur->next = new_part;
2497         else
2498                 parent_body->nested.part = new_part;
2499
2500 FINISH_OFF:
2501
2502         if (err_code)
2503                 *err_code = error;
2504
2505         EM_DEBUG_FUNC_END();
2506
2507         return new_part;
2508 }
2509 #ifdef __FEATURE_SUPPORT_REPORT_MAIL__
2510 static int attach_attachment_to_body(BODY **multipart_body, BODY *text_body, emstorage_attachment_tbl_t *input_attachment_tbl, int input_attachment_tbl_count, int *err_code)
2511 {
2512         EM_DEBUG_FUNC_BEGIN("multipart_body[%p], text_body[%p], input_attachment_tbl[%p], input_attachment_tbl_count [%d], err_code[%p]", multipart_body, text_body, input_attachment_tbl, input_attachment_tbl_count, err_code);
2513
2514         int ret = false;
2515         int i = 0;
2516         int error = EMAIL_ERROR_NONE;
2517         BODY *frame_body = NULL;
2518         /*  make multipart body(multipart frame_body..) .. that has not content..  */
2519
2520         if (!multipart_body || !text_body || !input_attachment_tbl) {
2521                 EM_DEBUG_EXCEPTION(" multipart_body[%p], text_body[%p], input_attachment_tbl[%p]", multipart_body, text_body, input_attachment_tbl);
2522                 error = EMAIL_ERROR_INVALID_PARAM;
2523                 goto FINISH_OFF;
2524         }
2525
2526         frame_body = mail_newbody();
2527         if (frame_body == NULL) {
2528                 EM_DEBUG_EXCEPTION("mail_newbody failed...");
2529                 error = EMAIL_ERROR_OUT_OF_MEMORY;
2530                 goto FINISH_OFF;
2531         }
2532
2533         frame_body->type = TYPEMULTIPART;
2534         frame_body->contents.text.data = NULL;
2535         frame_body->contents.text.size = 0;
2536         frame_body->size.bytes = 0;
2537
2538         /*  insert original text_body to frame_body.. */
2539         if (!attach_part(frame_body, text_body->sparep, 0, NULL, NULL, false, &error))  {
2540                 EM_DEBUG_EXCEPTION(" attach_part failed [%d]", error);
2541                 goto FINISH_OFF;
2542         }
2543
2544         /*  insert files..  */
2545         emstorage_attachment_tbl_t *temp_attachment_tbl = NULL;
2546         char *name = NULL;
2547         struct stat st_buf;
2548
2549         for(i = 0; i < input_attachment_tbl_count; i++) {
2550                 temp_attachment_tbl = input_attachment_tbl + i;
2551
2552                 EM_DEBUG_LOG("insert files - attachment id[%d]", temp_attachment_tbl->attachment_id);
2553
2554                 if (stat(temp_attachment_tbl->attachment_path, &st_buf) == 0)  {
2555                         if (!temp_attachment_tbl->attachment_name)  {
2556                                 if (!emcore_get_file_name(temp_attachment_tbl->attachment_path, &name, &error))  {
2557                                         EM_DEBUG_EXCEPTION("emcore_get_file_name failed [%d]", error);
2558                                         goto FINISH_OFF;
2559                                 }
2560                         }
2561                         else
2562                                 name = temp_attachment_tbl->attachment_name;
2563
2564                         if (!attach_part(frame_body, (unsigned char *)temp_attachment_tbl->attachment_path, 0, name, NULL, false, &error))  {
2565                                 EM_DEBUG_EXCEPTION("attach_part failed [%d]", error);
2566                                 goto FINISH_OFF;
2567                         }
2568                 }
2569         }
2570
2571         ret = true;
2572
2573 FINISH_OFF:
2574         if (ret == true)
2575                 *multipart_body = frame_body;
2576         else if (frame_body != NULL)
2577                 mail_free_body(&frame_body);
2578
2579         if (err_code != NULL)
2580                 *err_code = error;
2581         EM_DEBUG_FUNC_END();
2582         return ret;
2583 }
2584 #endif
2585 static char *emcore_encode_rfc2047_text(char *utf8_text, int *err_code)
2586 {
2587         EM_DEBUG_FUNC_BEGIN("utf8_text[%s], err_code[%p]", utf8_text, err_code);
2588
2589         if (utf8_text == NULL)  {
2590                 if (err_code != NULL)
2591                         *err_code = EMAIL_ERROR_INVALID_PARAM;
2592                 return NULL;
2593         }
2594
2595         gsize len = EM_SAFE_STRLEN(utf8_text);
2596
2597         EM_DEBUG_FUNC_END();
2598
2599         if (len > 0)
2600                 return g_strdup_printf("=?UTF-8?B?%s?=", g_base64_encode((const guchar  *)utf8_text, len));
2601         else
2602                 return strdup("");
2603 }
2604
2605 static void emcore_encode_rfc2047_address(ADDRESS *address, int *err_code)
2606 {
2607         EM_DEBUG_FUNC_BEGIN("address[%p], err_code[%p]", address, err_code);
2608
2609         while (address)  {
2610                 if (address->personal)  {
2611                         char *rfc2047_personal = emcore_encode_rfc2047_text(address->personal, err_code);
2612                         EM_SAFE_FREE(address->personal);
2613                         address->personal = rfc2047_personal;
2614                 }
2615                 address = address->next;
2616         }
2617         EM_DEBUG_FUNC_END();
2618 }
2619
2620 #define DATE_STR_LENGTH 100
2621
2622 static int emcore_make_envelope_from_mail(emstorage_mail_tbl_t *input_mail_tbl_data, ENVELOPE **output_envelope)
2623 {
2624         EM_DEBUG_FUNC_BEGIN("input_mail_tbl_data[%p], output_envelope[%p]", input_mail_tbl_data, output_envelope);
2625
2626         int     ret = false;
2627         int       error                   = EMAIL_ERROR_NONE;
2628         int       is_incomplete           = 0;
2629         char     *pAdd                    = NULL;
2630         ENVELOPE *envelope                = NULL;
2631         email_account_t *ref_account      = NULL;
2632
2633         if (!input_mail_tbl_data || !output_envelope)  {
2634                 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
2635                 error = EMAIL_ERROR_INVALID_PARAM;
2636                 return error; /* prevent 32729 */
2637         }
2638
2639         if ( (input_mail_tbl_data->report_status & EMAIL_MAIL_REPORT_MDN) != 0 && !input_mail_tbl_data->body_download_status) {
2640                 EM_DEBUG_EXCEPTION("input_mail_tbl_data->body_download_status[%p]", input_mail_tbl_data->body_download_status);
2641                 error = EMAIL_ERROR_INVALID_PARAM;
2642                 goto FINISH_OFF;
2643         }
2644
2645         if (!(envelope = mail_newenvelope()))  {
2646                 EM_DEBUG_EXCEPTION("mail_newenvelope failed...");
2647                 error = EMAIL_ERROR_OUT_OF_MEMORY;
2648                 goto FINISH_OFF;
2649         }
2650
2651         is_incomplete = input_mail_tbl_data->flags_draft_field || (input_mail_tbl_data->save_status == EMAIL_MAIL_STATUS_SENDING);
2652
2653         if (is_incomplete && (input_mail_tbl_data->account_id > 0))  {
2654                 ref_account = emcore_get_account_reference(input_mail_tbl_data->account_id);
2655                 if (!ref_account)  {
2656                         EM_DEBUG_EXCEPTION("emcore_get_account_reference failed [%d]", input_mail_tbl_data->account_id);
2657                         error = EMAIL_ERROR_INVALID_ACCOUNT;
2658                         goto FINISH_OFF;
2659                 }
2660
2661                 if (ref_account->user_email_address && ref_account->user_email_address[0] != '\0')  {
2662                         char *p = cpystr(ref_account->user_email_address);
2663
2664                         if (p == NULL)  {
2665                                 EM_DEBUG_EXCEPTION("cpystr failed...");
2666                                 error = EMAIL_ERROR_OUT_OF_MEMORY;
2667                                 goto FINISH_OFF;
2668                         }
2669
2670                         EM_DEBUG_LOG("Assign envelope->from");
2671
2672                         if (input_mail_tbl_data->full_address_from) {
2673                                 char *temp_address_string = NULL ;
2674                                 em_skip_whitespace(input_mail_tbl_data->full_address_from , &temp_address_string);
2675                                 EM_DEBUG_LOG("address[temp_address_string][%s]", temp_address_string);
2676                                 rfc822_parse_adrlist(&envelope->from, temp_address_string, NULL);
2677                                 EM_SAFE_FREE(temp_address_string);
2678                                 temp_address_string = NULL ;
2679                         }
2680                         else
2681                                 envelope->from = rfc822_parse_mailbox(&p, NULL);
2682
2683                         EM_SAFE_FREE(p);
2684                         if (!envelope->from) {
2685                                 EM_DEBUG_EXCEPTION("rfc822_parse_mailbox failed...");
2686                                 error = EMAIL_ERROR_INVALID_ADDRESS;
2687                                 goto FINISH_OFF;
2688                         }
2689                         else  {
2690                                 if (envelope->from->personal == NULL) {
2691                                         if (ref_account->options.display_name_from && ref_account->options.display_name_from[0] != '\0')
2692                                                 envelope->from->personal = cpystr(ref_account->options.display_name_from);
2693                                         else
2694                                                 envelope->from->personal =
2695                                                                 (ref_account->user_display_name && ref_account->user_display_name[0] != '\0') ?
2696                                                                 cpystr(ref_account->user_display_name)  :  NULL;
2697                                 }
2698                         }
2699                 }
2700
2701                 if (ref_account->return_address && ref_account->return_address[0] != '\0')  {
2702                         char *p = cpystr(ref_account->return_address);
2703
2704                         if (p == NULL)  {
2705                                 EM_DEBUG_EXCEPTION("cpystr failed...");
2706                                 error = EMAIL_ERROR_OUT_OF_MEMORY;
2707                                 goto FINISH_OFF;
2708                         }
2709                         envelope->return_path = rfc822_parse_mailbox(&p, NULL);
2710                         EM_SAFE_FREE(p);
2711                 }
2712         }
2713         else  {
2714                 if (!input_mail_tbl_data->full_address_from || !input_mail_tbl_data->full_address_to)  {
2715                         EM_DEBUG_EXCEPTION("input_mail_tbl_data->full_address_from[%p], input_mail_tbl_data->full_address_to[%p]", input_mail_tbl_data->full_address_from, input_mail_tbl_data->full_address_to);
2716                         error = EMAIL_ERROR_INVALID_MAIL;
2717                         goto FINISH_OFF;
2718                 }
2719
2720                 int i, j;
2721
2722                 if (input_mail_tbl_data->full_address_from)  {
2723                         for (i = 0, j = EM_SAFE_STRLEN(input_mail_tbl_data->full_address_from); i < j; i++)  {
2724                                 if (input_mail_tbl_data->full_address_from[i] == ';')
2725                                         input_mail_tbl_data->full_address_from[i] = ',';
2726                         }
2727                 }
2728
2729                 if (input_mail_tbl_data->full_address_return)  {
2730                         for (i = 0, j = EM_SAFE_STRLEN(input_mail_tbl_data->full_address_return); i < j; i++)  {
2731                                 if (input_mail_tbl_data->full_address_return[i] == ';')
2732                                         input_mail_tbl_data->full_address_return[i] = ',';
2733                         }
2734                 }
2735                 em_skip_whitespace(input_mail_tbl_data->full_address_from , &pAdd);
2736                 EM_DEBUG_LOG("address[pAdd][%s]", pAdd);
2737
2738                 rfc822_parse_adrlist(&envelope->from, pAdd, NULL);
2739                 EM_SAFE_FREE(pAdd);
2740                 pAdd = NULL;
2741
2742                 em_skip_whitespace(input_mail_tbl_data->full_address_return , &pAdd);
2743                 EM_DEBUG_LOG("address[pAdd][%s]", pAdd);
2744
2745                 rfc822_parse_adrlist(&envelope->return_path, pAdd, NULL);
2746                 EM_SAFE_FREE(pAdd);
2747                 pAdd = NULL;
2748         }
2749
2750         {
2751                 int i, j;
2752
2753                 if (input_mail_tbl_data->full_address_to)  {
2754                         for (i = 0, j = EM_SAFE_STRLEN(input_mail_tbl_data->full_address_to); i < j; i++)  {
2755                                 if (input_mail_tbl_data->full_address_to[i] == ';')
2756                                         input_mail_tbl_data->full_address_to[i] = ',';
2757                         }
2758                 }
2759
2760                 if (input_mail_tbl_data->full_address_cc)  {
2761                         for (i = 0, j = EM_SAFE_STRLEN(input_mail_tbl_data->full_address_cc); i < j; i++)  {
2762                                 if (input_mail_tbl_data->full_address_cc[i] == ';')
2763                                         input_mail_tbl_data->full_address_cc[i] = ',';
2764                         }
2765                 }
2766
2767                 if (input_mail_tbl_data->full_address_bcc)  {
2768                         for (i = 0, j = EM_SAFE_STRLEN(input_mail_tbl_data->full_address_bcc); i < j; i++)  {
2769                                 if (input_mail_tbl_data->full_address_bcc[i] == ';')
2770                                         input_mail_tbl_data->full_address_bcc[i] = ',';
2771                         }
2772                 }
2773         }
2774
2775         em_skip_whitespace(input_mail_tbl_data->full_address_to , &pAdd);
2776         EM_DEBUG_LOG("address[pAdd][%s]", pAdd);
2777
2778         rfc822_parse_adrlist(&envelope->to, pAdd, NULL);
2779         EM_SAFE_FREE(pAdd);
2780         pAdd = NULL ;
2781
2782         EM_DEBUG_LOG("address[input_mail_tbl_data->full_address_cc][%s]", input_mail_tbl_data->full_address_cc);
2783         em_skip_whitespace(input_mail_tbl_data->full_address_cc , &pAdd);
2784         EM_DEBUG_LOG("address[pAdd][%s]", pAdd);
2785
2786         rfc822_parse_adrlist(&envelope->cc, pAdd, NULL);
2787         EM_SAFE_FREE(pAdd);
2788         pAdd = NULL ;
2789
2790         em_skip_whitespace(input_mail_tbl_data->full_address_bcc , &pAdd);
2791         rfc822_parse_adrlist(&envelope->bcc, pAdd, NULL);
2792         EM_SAFE_FREE(pAdd);
2793                 pAdd = NULL ;
2794
2795         emcore_encode_rfc2047_address(envelope->return_path, &error);
2796         emcore_encode_rfc2047_address(envelope->from, &error);
2797         emcore_encode_rfc2047_address(envelope->sender, &error);
2798         emcore_encode_rfc2047_address(envelope->reply_to, &error);
2799         emcore_encode_rfc2047_address(envelope->to, &error);
2800         emcore_encode_rfc2047_address(envelope->cc, &error);
2801         emcore_encode_rfc2047_address(envelope->bcc, &error);
2802
2803         if (input_mail_tbl_data->subject)
2804                 envelope->subject = emcore_encode_rfc2047_text(input_mail_tbl_data->subject, &error);
2805
2806         char rfc822_date_string[DATE_STR_LENGTH] = { 0, };
2807         rfc822_date(rfc822_date_string);
2808
2809         if (!is_incomplete)  {
2810                 char  localtime_string[DATE_STR_LENGTH] = { 0, };
2811                 strftime(localtime_string, 128, "%a, %e %b %Y %H : %M : %S ", localtime(&input_mail_tbl_data->date_time));
2812                 /* append last 5byes("+0900") */
2813                 g_strlcat(localtime_string, rfc822_date_string + (EM_SAFE_STRLEN(rfc822_date_string) -  5), DATE_STR_LENGTH);
2814                 envelope->date = (unsigned char *)cpystr((const char *)localtime_string);
2815         }
2816         else {
2817                 envelope->date = (unsigned char *)cpystr((const char *)rfc822_date_string);
2818         }
2819
2820         ret = true;
2821
2822 FINISH_OFF:
2823
2824         if (ret)
2825                 *output_envelope = envelope;
2826         else {
2827                 mail_free_envelope(&envelope);
2828                 *output_envelope = NULL;
2829         }
2830
2831         if (ref_account) {
2832                 emcore_free_account(ref_account);
2833                 EM_SAFE_FREE(ref_account);
2834         }
2835
2836         EM_DEBUG_FUNC_END("error [%d]", error);
2837         return error;
2838 }
2839 /*  Description : Make RFC822 text file from mail_tbl data */
2840 /*  Parameters :  */
2841 /*                      input_mail_tbl_data :   */
2842 /*                      is_draft  :  this mail is draft mail. */
2843 /*                      file_path :  path of file that rfc822 data will be written to. */
2844 INTERNAL_FUNC int emcore_make_rfc822_file_from_mail(emstorage_mail_tbl_t *input_mail_tbl_data, emstorage_attachment_tbl_t *input_attachment_tbl, int input_attachment_count, ENVELOPE **env, char **file_path, email_option_t *sending_option, int *err_code)
2845 {
2846         EM_DEBUG_FUNC_BEGIN("input_mail_tbl_data[%p], env[%p], file_path[%p], sending_option[%p], err_code[%p]", input_mail_tbl_data, env, file_path, sending_option, err_code);
2847
2848         int       ret = false;
2849         int       error = EMAIL_ERROR_NONE;
2850         int       i = 0;
2851         ENVELOPE *envelope      = NULL;
2852         BODY     *text_body     = NULL;
2853         BODY     *html_body     = NULL;
2854         BODY     *root_body     = NULL;
2855         PART     *part_for_html = NULL;
2856         PARAMETER *param = NULL;
2857         PART     *part_for_text = NULL;
2858         char     *fname = NULL;
2859
2860         if (!input_mail_tbl_data)  {
2861                 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
2862                 error = EMAIL_ERROR_INVALID_PARAM;
2863                 goto FINISH_OFF;
2864         }
2865
2866         if ( (input_mail_tbl_data->report_status & EMAIL_MAIL_REPORT_MDN) != 0 && !input_mail_tbl_data->body_download_status) {
2867                 EM_DEBUG_EXCEPTION("input_mail_tbl_data->body_download_status[%p]", input_mail_tbl_data->body_download_status);
2868                 error = EMAIL_ERROR_INVALID_PARAM;
2869                 goto FINISH_OFF;
2870         }
2871
2872         if ( (error = emcore_make_envelope_from_mail(input_mail_tbl_data, &envelope)) != EMAIL_ERROR_NONE) {
2873                 EM_DEBUG_EXCEPTION("emcore_make_envelope_from_mail failed [%d]", error);
2874                 goto FINISH_OFF;
2875         }
2876
2877         EM_DEBUG_LOG("input_mail_tbl_data->file_path_plain[%s]", input_mail_tbl_data->file_path_plain);
2878         EM_DEBUG_LOG("input_mail_tbl_data->file_path_html[%s]", input_mail_tbl_data->file_path_html);
2879         EM_DEBUG_LOG("input_mail_tbl_data->file_path_mime_entity[%s]", input_mail_tbl_data->file_path_mime_entity);
2880         EM_DEBUG_LOG("input_mail_tbl_data->body->attachment_num[%d]", input_mail_tbl_data->attachment_count);
2881
2882         if ((input_mail_tbl_data->attachment_count > 0) || (input_mail_tbl_data->file_path_plain && input_mail_tbl_data->file_path_html))  {
2883                 EM_DEBUG_LOG("attachment_num [%d]", input_mail_tbl_data->attachment_count);
2884
2885                 root_body = mail_newbody();
2886
2887                 if (root_body == NULL)  {
2888                         EM_DEBUG_EXCEPTION("mail_newbody failed...");
2889                         error = EMAIL_ERROR_OUT_OF_MEMORY;
2890                         goto FINISH_OFF;
2891                 }
2892
2893                 param = mail_newbody_parameter();
2894
2895                 if (param == NULL) {
2896                         EM_DEBUG_EXCEPTION("mail_newbody_parameter failed...");
2897                         error = EMAIL_ERROR_OUT_OF_MEMORY;
2898                         goto FINISH_OFF;
2899                 }
2900
2901                 if (input_mail_tbl_data->smime_type == EMAIL_SMIME_NONE) {
2902
2903                         root_body->type               = TYPEMULTIPART;
2904                         root_body->subtype            = strdup("MIXED");
2905
2906                         mail_free_body_parameter(&param);
2907                         param = NULL;
2908
2909                 } else if (input_mail_tbl_data->smime_type == EMAIL_SMIME_SIGNED) {
2910                         PARAMETER *protocol_param     = mail_newbody_parameter();
2911
2912                         root_body->type               = TYPEMULTIPART;
2913                         root_body->subtype            = strdup("SIGNED");
2914
2915                         param->attribute       = cpystr("micalg");
2916                         switch (input_mail_tbl_data->digest_type) {
2917                         case DIGEST_TYPE_SHA1:
2918                                 param->value   = cpystr("sha1");
2919                                 break;
2920                         case DIGEST_TYPE_MD5:
2921                                 param->value   = cpystr("md5");
2922                                 break;
2923                         default:
2924                                 EM_DEBUG_EXCEPTION("Invalid digest type");
2925                                 break;
2926                         }
2927
2928                         protocol_param->attribute   = cpystr("protocol");
2929                         protocol_param->value       = cpystr("application/pkcs7-signature");
2930                         protocol_param->next        = NULL;
2931                         param->next                 = protocol_param;
2932
2933                         input_mail_tbl_data->file_path_plain = NULL;
2934                         input_mail_tbl_data->file_path_html = NULL;
2935
2936                         input_attachment_tbl = input_attachment_tbl + (input_attachment_count - 1);
2937
2938                         input_attachment_count = 1;
2939
2940                 } else {
2941
2942                         root_body->type    = TYPEAPPLICATION;
2943                         root_body->subtype = strdup("PKCS7-MIME");
2944
2945                         param->attribute = cpystr("name");
2946                         param->value = cpystr("smime.p7m");
2947                         param->next = NULL;
2948
2949                         input_mail_tbl_data->file_path_plain = NULL;
2950                         input_mail_tbl_data->file_path_html = NULL;
2951                         input_mail_tbl_data->file_path_mime_entity = NULL;
2952
2953                         input_attachment_count = 1;
2954                 }
2955
2956                 root_body->contents.text.data = NULL;
2957                 root_body->contents.text.size = 0;
2958                 root_body->size.bytes         = 0;
2959                 root_body->parameter          = param;
2960
2961                 if (input_mail_tbl_data->smime_type == EMAIL_SMIME_NONE && input_mail_tbl_data->file_path_plain && input_mail_tbl_data->file_path_html) {
2962                         part_for_text = attach_mutipart_with_sub_type(root_body, "ALTERNATIVE", &error);
2963
2964                         if (!part_for_text) {
2965                                 EM_DEBUG_EXCEPTION("attach_mutipart_with_sub_type [part_for_text] failed [%d]", error);
2966                                 goto FINISH_OFF;
2967                         }
2968
2969                         text_body = &part_for_text->body;
2970
2971                         if (input_mail_tbl_data->file_path_plain && EM_SAFE_STRLEN(input_mail_tbl_data->file_path_plain) > 0) {
2972                                 EM_DEBUG_LOG("file_path_plain[%s]", input_mail_tbl_data->file_path_plain);
2973                                 if (!attach_part(text_body, (unsigned char *)input_mail_tbl_data->file_path_plain, 0, NULL, NULL, false, &error)) {
2974                                         EM_DEBUG_EXCEPTION("attach_part failed [%d]", error);
2975                                         goto FINISH_OFF;
2976                                 }
2977                         }
2978
2979                         if (input_mail_tbl_data->file_path_html && EM_SAFE_STRLEN(input_mail_tbl_data->file_path_html) > 0) {
2980                                 EM_DEBUG_LOG("file_path_html[%s]", input_mail_tbl_data->file_path_html);
2981
2982                                 part_for_html = attach_mutipart_with_sub_type(text_body, "RELATED", &error);
2983                                 if (!part_for_html) {
2984                                         EM_DEBUG_EXCEPTION("attach_mutipart_with_sub_type [part_for_html] failed [%d]", error);
2985                                         goto FINISH_OFF;
2986                                 }
2987
2988                                 if (!attach_part(&(part_for_html->body) , (unsigned char *)input_mail_tbl_data->file_path_html, 0, NULL, "html", false, &error)) {
2989                                         EM_DEBUG_EXCEPTION("attach_part failed [%d]", error);
2990                                         goto FINISH_OFF;
2991                                 }
2992                         }
2993                 }
2994
2995                 if (input_mail_tbl_data->file_path_mime_entity && EM_SAFE_STRLEN(input_mail_tbl_data->file_path_mime_entity) > 0) {
2996                         EM_DEBUG_LOG("file_path_mime_entity[%s]", input_mail_tbl_data->file_path_mime_entity);
2997                         root_body->sparep = EM_SAFE_STRDUP(input_mail_tbl_data->file_path_mime_entity);
2998                 }
2999
3000                 if (input_attachment_tbl && input_attachment_count)  {
3001                         emstorage_attachment_tbl_t *temp_attachment_tbl = NULL;
3002                         char *name = NULL;
3003                         BODY *body_to_attach = NULL;
3004                         struct stat st_buf;
3005
3006                         for(i = 0; i < input_attachment_count; i++) {
3007                                 temp_attachment_tbl = input_attachment_tbl + i;
3008                                 EM_DEBUG_LOG("attachment_name[%s], attachment_path[%s]", temp_attachment_tbl->attachment_name, temp_attachment_tbl->attachment_path);
3009                                 if (stat(temp_attachment_tbl->attachment_path, &st_buf) == 0)  {
3010                                         if (!temp_attachment_tbl->attachment_name)  {
3011                                                 if (!emcore_get_file_name(temp_attachment_tbl->attachment_path, &name, &error))  {
3012                                                         EM_DEBUG_EXCEPTION("emcore_get_file_name failed [%d]", error);
3013                                                         continue;
3014                                                 }
3015                                         }
3016                                         else
3017                                                 name = temp_attachment_tbl->attachment_name;
3018
3019                                         EM_DEBUG_LOG("name[%s]", name);
3020
3021                                         if (temp_attachment_tbl->attachment_inline_content_status && part_for_html)
3022                                                 body_to_attach = &(part_for_html->body);
3023                                         else
3024                                                 body_to_attach = root_body;
3025
3026                                         if (!attach_part(body_to_attach, (unsigned char *)temp_attachment_tbl->attachment_path, 0, name, NULL, temp_attachment_tbl->attachment_inline_content_status, &error))  {
3027                                                 EM_DEBUG_EXCEPTION("attach_part failed [%d]", error);
3028                                                 continue;
3029                                         }
3030                                 }
3031                         }
3032                 }
3033                 text_body = NULL;
3034         }
3035         else {
3036                 text_body = mail_newbody();
3037
3038                 if (text_body == NULL)  {
3039                         EM_DEBUG_EXCEPTION("mail_newbody failed...");
3040
3041                         error = EMAIL_ERROR_OUT_OF_MEMORY;
3042                         goto FINISH_OFF;
3043                 }
3044
3045                 text_body->type = TYPETEXT;
3046                 text_body->encoding = ENC8BIT;
3047                 if (input_mail_tbl_data->file_path_plain || input_mail_tbl_data->file_path_html)
3048                         text_body->sparep = EM_SAFE_STRDUP(input_mail_tbl_data->file_path_plain ? input_mail_tbl_data->file_path_plain  :  input_mail_tbl_data->file_path_html);
3049                 else
3050                         text_body->sparep = NULL;
3051
3052                 if (input_mail_tbl_data->file_path_html != NULL && input_mail_tbl_data->file_path_html[0] != '\0')
3053                         text_body->subtype = strdup("html");
3054                 if (text_body->sparep)
3055                         text_body->size.bytes = EM_SAFE_STRLEN(text_body->sparep);
3056                 else
3057                         text_body->size.bytes = 0;
3058         }
3059
3060
3061         if (input_mail_tbl_data->report_status & EMAIL_MAIL_REPORT_MDN) {
3062                 /*  Report mail */
3063                 EM_DEBUG_LOG("REPORT MAIL");
3064                 envelope->references = cpystr(input_mail_tbl_data->message_id);
3065         }
3066
3067         if (file_path)  {
3068                 EM_DEBUG_LOG("write rfc822 : file_path[%p]", file_path);
3069
3070                 if (part_for_html)
3071                         html_body = &(part_for_html->body);
3072
3073                 if (!emcore_write_rfc822(envelope, root_body ? root_body : text_body, html_body, input_mail_tbl_data->priority, input_mail_tbl_data->report_status, &fname, &error))  {
3074                         EM_DEBUG_EXCEPTION("emcore_write_rfc822 failed [%d]", error);
3075                         goto FINISH_OFF;
3076                 }
3077
3078                 *file_path = fname;
3079         }
3080
3081         ret = true;
3082
3083 FINISH_OFF:
3084         if ((ret == true) && (env != NULL))
3085                 *env = envelope;
3086         else if (envelope != NULL)
3087                 mail_free_envelope(&envelope);
3088
3089         if (text_body != NULL)
3090                 mail_free_body(&text_body);
3091
3092         if (root_body != NULL)
3093                 mail_free_body(&root_body);
3094
3095         if (err_code != NULL)
3096                 *err_code = error;
3097
3098         EM_DEBUG_FUNC_END("ret [%d]", ret);
3099         return ret;
3100 }
3101
3102 INTERNAL_FUNC int emcore_make_rfc822_file(email_mail_data_t *input_mail_tbl_data, email_attachment_data_t *input_attachment_tbl, int input_attachment_count, char **file_path, int *err_code)
3103 {
3104         EM_DEBUG_FUNC_BEGIN("input_mail_tbl_data[%p], file_path[%p], err_code[%p]", input_mail_tbl_data, file_path, err_code);
3105
3106         int       ret                  = false;
3107         int       error                = EMAIL_ERROR_NONE;
3108         int       is_incomplete        = 0;
3109         int       i                    = 0;
3110         ENVELOPE *envelope             = NULL;
3111         BODY     *text_body            = NULL;
3112         BODY     *html_body            = NULL;
3113         BODY     *root_body            = NULL;
3114         PART     *part_for_html        = NULL;
3115         PART     *part_for_text        = NULL;
3116         char      temp_file_path_plain[512];
3117         char      temp_file_path_html[512];
3118         char     *pAdd                 = NULL;
3119         char     *fname                = NULL;
3120         emstorage_account_tbl_t *ref_account     = NULL;
3121
3122         if (!input_mail_tbl_data)  {
3123                 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
3124                 error = EMAIL_ERROR_INVALID_PARAM;
3125                 goto FINISH_OFF;
3126         }
3127
3128         if ( (input_mail_tbl_data->report_status & EMAIL_MAIL_REPORT_MDN) != 0 && !input_mail_tbl_data->body_download_status) {
3129                 EM_DEBUG_EXCEPTION("input_mail_tbl_data->body_download_status[%p]", input_mail_tbl_data->body_download_status);
3130                 error = EMAIL_ERROR_INVALID_PARAM;
3131                 goto FINISH_OFF;
3132         }
3133
3134         if (!emstorage_get_account_by_id(input_mail_tbl_data->account_id, GET_FULL_DATA_WITHOUT_PASSWORD, &ref_account, true, &error)) {
3135                 EM_DEBUG_EXCEPTION("emstorage_get_account_by_id failed : [%d]", error);
3136                 goto FINISH_OFF;
3137         }
3138
3139         if (!ref_account)  {
3140                 EM_DEBUG_EXCEPTION("emcore_get_account_reference failed [%d]", input_mail_tbl_data->account_id);
3141                 error = EMAIL_ERROR_INVALID_ACCOUNT;
3142                 goto FINISH_OFF;
3143         }
3144
3145         if (!(envelope = mail_newenvelope()))  {
3146                 EM_DEBUG_EXCEPTION("mail_newenvelope failed...");
3147                 error = EMAIL_ERROR_OUT_OF_MEMORY;
3148                 goto FINISH_OFF;
3149         }
3150
3151         is_incomplete = input_mail_tbl_data->flags_draft_field || (input_mail_tbl_data->save_status == EMAIL_MAIL_STATUS_SENDING);
3152
3153         if (is_incomplete)  {
3154                 if (ref_account->user_email_address && ref_account->user_email_address[0] != '\0')  {
3155                         char *p = cpystr(ref_account->user_email_address);
3156
3157                         if (p == NULL)  {
3158                                 EM_DEBUG_EXCEPTION("cpystr failed...");
3159                                 error = EMAIL_ERROR_OUT_OF_MEMORY;
3160                                 goto FINISH_OFF;
3161                         }
3162
3163                         EM_DEBUG_LOG("Assign envelop->from");
3164
3165                         if (input_mail_tbl_data->full_address_from) {
3166                                 char *temp_address_string = NULL ;
3167                                 em_skip_whitespace(input_mail_tbl_data->full_address_from , &temp_address_string);
3168                                 EM_DEBUG_LOG("address[temp_address_string][%s]", temp_address_string);
3169                                 rfc822_parse_adrlist(&envelope->from, temp_address_string, ref_account->outgoing_server_address);
3170                                 EM_SAFE_FREE(temp_address_string);
3171                                 temp_address_string = NULL ;
3172                         }
3173                         else
3174                                 envelope->from = rfc822_parse_mailbox(&p, NULL);
3175
3176                         EM_SAFE_FREE(p);
3177                         if (!envelope->from)  {
3178                                 EM_DEBUG_EXCEPTION("rfc822_parse_mailbox failed...");
3179                                 error = EMAIL_ERROR_INVALID_ADDRESS;
3180                                 goto FINISH_OFF;
3181                         }
3182                         else  {
3183
3184                                 if (envelope->from->personal == NULL) {
3185                                         envelope->from->personal =
3186                                                 (ref_account->user_display_name && ref_account->user_display_name[0] != '\0')?
3187                                                 cpystr(ref_account->user_display_name)  :  NULL;
3188                                 }
3189                         }
3190                 }
3191         }
3192
3193         if (ref_account->return_address && ref_account->return_address[0] != '\0')  {
3194                 char *p = cpystr(ref_account->return_address);
3195
3196                 if (p == NULL)  {
3197                         EM_DEBUG_EXCEPTION("cpystr failed...");
3198
3199                         error = EMAIL_ERROR_OUT_OF_MEMORY;
3200                         goto FINISH_OFF;
3201                 }
3202                 envelope->return_path = rfc822_parse_mailbox(&p, NULL);
3203                 EM_SAFE_FREE(p);
3204         }
3205         else  {
3206                 if (!input_mail_tbl_data->full_address_from || !input_mail_tbl_data->full_address_to)  {
3207                         EM_DEBUG_EXCEPTION("input_mail_tbl_data->full_address_from[%p], input_mail_tbl_data->full_address_to[%p]", input_mail_tbl_data->full_address_from, input_mail_tbl_data->full_address_to);
3208                         error = EMAIL_ERROR_INVALID_MAIL;
3209                         goto FINISH_OFF;
3210                 }
3211
3212                 int i, j;
3213
3214                 if (input_mail_tbl_data->full_address_from)  {
3215                         for (i = 0, j = EM_SAFE_STRLEN(input_mail_tbl_data->full_address_from); i < j; i++)  {
3216                                 if (input_mail_tbl_data->full_address_from[i] == ';')
3217                                         input_mail_tbl_data->full_address_from[i] = ',';
3218                         }
3219                 }
3220
3221                 if (input_mail_tbl_data->full_address_return)  {
3222                         for (i = 0, j = EM_SAFE_STRLEN(input_mail_tbl_data->full_address_return); i < j; i++)  {
3223                                 if (input_mail_tbl_data->full_address_return[i] == ';')
3224                                         input_mail_tbl_data->full_address_return[i] = ',';
3225                         }
3226                 }
3227                         em_skip_whitespace(input_mail_tbl_data->full_address_from , &pAdd);
3228                 EM_DEBUG_LOG("address[pAdd][%s]", pAdd);
3229
3230                 rfc822_parse_adrlist(&envelope->from, pAdd, ref_account->outgoing_server_address);
3231                 EM_SAFE_FREE(pAdd);
3232                         pAdd = NULL ;
3233
3234                 em_skip_whitespace(input_mail_tbl_data->full_address_return , &pAdd);
3235                 EM_DEBUG_LOG("address[pAdd][%s]", pAdd);
3236
3237                 rfc822_parse_adrlist(&envelope->return_path, pAdd, ref_account->outgoing_server_address);
3238                 EM_SAFE_FREE(pAdd);
3239                 pAdd = NULL ;
3240         }
3241
3242         {
3243                 int i, j;
3244
3245                 if (input_mail_tbl_data->full_address_to)  {
3246                         for (i = 0, j = EM_SAFE_STRLEN(input_mail_tbl_data->full_address_to); i < j; i++)  {
3247                                 if (input_mail_tbl_data->full_address_to[i] == ';')
3248                                         input_mail_tbl_data->full_address_to[i] = ',';
3249                         }
3250                 }
3251
3252                 if (input_mail_tbl_data->full_address_cc)  {
3253                         for (i = 0, j = EM_SAFE_STRLEN(input_mail_tbl_data->full_address_cc); i < j; i++)  {
3254                                 if (input_mail_tbl_data->full_address_cc[i] == ';')
3255                                         input_mail_tbl_data->full_address_cc[i] = ',';
3256                         }
3257                 }
3258
3259                 if (input_mail_tbl_data->full_address_bcc)  {
3260                         for (i = 0, j = EM_SAFE_STRLEN(input_mail_tbl_data->full_address_bcc); i < j; i++)  {
3261                                 if (input_mail_tbl_data->full_address_bcc[i] == ';')
3262                                         input_mail_tbl_data->full_address_bcc[i] = ',';
3263                         }
3264                 }
3265         }
3266
3267         em_skip_whitespace(input_mail_tbl_data->full_address_to , &pAdd);
3268         EM_DEBUG_LOG("address[pAdd][%s]", pAdd);
3269
3270         rfc822_parse_adrlist(&envelope->to, pAdd, ref_account->outgoing_server_address);
3271         EM_SAFE_FREE(pAdd);
3272         pAdd = NULL ;
3273
3274         EM_DEBUG_LOG("address[input_mail_tbl_data->full_address_cc][%s]", input_mail_tbl_data->full_address_cc);
3275         em_skip_whitespace(input_mail_tbl_data->full_address_cc , &pAdd);
3276         EM_DEBUG_LOG("address[pAdd][%s]", pAdd);
3277
3278         rfc822_parse_adrlist(&envelope->cc, pAdd, ref_account->outgoing_server_address);
3279         EM_SAFE_FREE(pAdd);
3280                 pAdd = NULL ;
3281
3282         em_skip_whitespace(input_mail_tbl_data->full_address_bcc , &pAdd);
3283         rfc822_parse_adrlist(&envelope->bcc, pAdd, ref_account->outgoing_server_address);
3284         EM_SAFE_FREE(pAdd);
3285                 pAdd = NULL ;
3286
3287         emcore_encode_rfc2047_address(envelope->return_path, &error);
3288         emcore_encode_rfc2047_address(envelope->from, &error);
3289         emcore_encode_rfc2047_address(envelope->sender, &error);
3290         emcore_encode_rfc2047_address(envelope->reply_to, &error);
3291         emcore_encode_rfc2047_address(envelope->to, &error);
3292         emcore_encode_rfc2047_address(envelope->cc, &error);
3293         emcore_encode_rfc2047_address(envelope->bcc, &error);
3294
3295         if (input_mail_tbl_data->subject)
3296                 envelope->subject = emcore_encode_rfc2047_text(input_mail_tbl_data->subject, &error);
3297
3298         char rfc822_date_string[DATE_STR_LENGTH] = { 0, };
3299         char localtime_string[DATE_STR_LENGTH] = {0, };
3300
3301         rfc822_date(rfc822_date_string);
3302
3303         if (!is_incomplete)  {
3304                 strftime(localtime_string, 128, "%a, %e %b %Y %H : %M : %S ", localtime(&input_mail_tbl_data->date_time));
3305                 /*  append last 5byes("+0900") */
3306                 g_strlcat(localtime_string, rfc822_date_string + (EM_SAFE_STRLEN(rfc822_date_string) -  5), DATE_STR_LENGTH);
3307                 envelope->date = (unsigned char *)cpystr((const char *)localtime_string);
3308         }
3309         else {
3310                 envelope->date = (unsigned char *)cpystr((const char *)rfc822_date_string);
3311         }
3312         /*  check report input_mail_tbl_data */
3313
3314         /* Non-report input_mail_tbl_data */
3315         EM_DEBUG_LOG("input_mail_tbl_data->file_path_plain[%s]", input_mail_tbl_data->file_path_plain);
3316         EM_DEBUG_LOG("input_mail_tbl_data->file_path_html[%s]", input_mail_tbl_data->file_path_html);
3317         EM_DEBUG_LOG("input_mail_tbl_data->body->attachment_num[%d]", input_mail_tbl_data->attachment_count);
3318
3319         if (input_mail_tbl_data->file_path_plain) {
3320                 memset(temp_file_path_plain, 0x00, sizeof(temp_file_path_plain));
3321                 SNPRINTF(temp_file_path_plain, sizeof(temp_file_path_plain), "%s%s%s", MAILTEMP, DIR_SEPERATOR, "UTF-8");
3322
3323                 if (!emstorage_copy_file(input_mail_tbl_data->file_path_plain, temp_file_path_plain, 0, &error)) {
3324                         EM_DEBUG_EXCEPTION("emstorage_copy_file failed : [%d]", error);
3325                         goto FINISH_OFF;
3326                 }
3327         }
3328
3329         if (input_mail_tbl_data->file_path_html) {
3330                 memset(temp_file_path_html, 0x00, sizeof(temp_file_path_html));
3331                 SNPRINTF(temp_file_path_html, sizeof(temp_file_path_html), "%s%s%s", MAILTEMP, DIR_SEPERATOR, "UTF-8.htm");
3332
3333                 if (!emstorage_copy_file(input_mail_tbl_data->file_path_html, temp_file_path_html, 0, &error)) {
3334                         EM_DEBUG_EXCEPTION("emstorage_copy_file failed : [%d]", error);
3335                         goto FINISH_OFF;
3336                 }
3337         }
3338
3339         if ((input_mail_tbl_data->attachment_count > 0) || (input_mail_tbl_data->file_path_plain && input_mail_tbl_data->file_path_html))  {
3340                 EM_DEBUG_LOG("attachment_num  :  %d", input_mail_tbl_data->attachment_count);
3341                 root_body = mail_newbody();
3342
3343                 if (root_body == NULL)  {
3344                         EM_DEBUG_EXCEPTION("mail_newbody failed...");
3345                         error = EMAIL_ERROR_OUT_OF_MEMORY;
3346                         goto FINISH_OFF;
3347                 }
3348
3349                 root_body->type               = TYPEMULTIPART;
3350                 root_body->subtype            = strdup("MIXED");
3351                 root_body->contents.text.data = NULL;
3352                 root_body->contents.text.size = 0;
3353                 root_body->size.bytes         = 0;
3354
3355                 part_for_text = attach_mutipart_with_sub_type(root_body, "ALTERNATIVE", &error);
3356
3357                 if (!part_for_text) {
3358                         EM_DEBUG_EXCEPTION("attach_mutipart_with_sub_type [part_for_text] failed [%d]", error);
3359                         goto FINISH_OFF;
3360                 }
3361
3362                 text_body = &part_for_text->body;
3363
3364                 if (input_mail_tbl_data->file_path_plain && EM_SAFE_STRLEN(input_mail_tbl_data->file_path_plain) > 0)  {
3365                         EM_DEBUG_LOG("file_path_plain[%s]", input_mail_tbl_data->file_path_plain);
3366                         if (!attach_part(text_body, (unsigned char *)temp_file_path_plain, 0, NULL, NULL, false, &error))  {
3367                                 EM_DEBUG_EXCEPTION("attach_part failed [%d]", error);
3368                                 goto FINISH_OFF;
3369                         }
3370                 }
3371
3372                 if (input_mail_tbl_data->file_path_html && EM_SAFE_STRLEN(input_mail_tbl_data->file_path_html) > 0)  {
3373                         EM_DEBUG_LOG("file_path_html[%s]", input_mail_tbl_data->file_path_html);
3374
3375                         part_for_html = attach_mutipart_with_sub_type(text_body, "RELATED", &error);
3376                         if (!part_for_html) {
3377                                 EM_DEBUG_EXCEPTION("attach_mutipart_with_sub_type [part_for_html] failed [%d]", error);
3378                                 goto FINISH_OFF;
3379                         }
3380
3381                         if (!attach_part(&(part_for_html->body) , (unsigned char *)temp_file_path_html, 0, NULL, "html", false, &error))  {
3382                                 EM_DEBUG_EXCEPTION("attach_part failed [%d]", error);
3383                                 goto FINISH_OFF;
3384                         }
3385                 }
3386
3387                 if (input_attachment_tbl && input_attachment_count)  {
3388                         email_attachment_data_t *temp_attachment_tbl = NULL;
3389                         char *name = NULL;
3390                         BODY *body_to_attach = NULL;
3391                         struct stat st_buf;
3392
3393                         for(i = 0; i < input_attachment_count; i++) {
3394                                 temp_attachment_tbl = input_attachment_tbl + i;
3395                                 EM_DEBUG_LOG("attachment_name[%s], attachment_path[%s]", temp_attachment_tbl->attachment_name, temp_attachment_tbl->attachment_path);
3396                                 if (stat(temp_attachment_tbl->attachment_path, &st_buf) == 0)  {
3397                                         if (!temp_attachment_tbl->attachment_name)  {
3398                                                 if (!emcore_get_file_name(temp_attachment_tbl->attachment_path, &name, &error))  {
3399                                                         EM_DEBUG_EXCEPTION("emcore_get_file_name failed [%d]", error);
3400                                                         continue;
3401                                                 }
3402                                         }
3403                                         else
3404                                                 name = temp_attachment_tbl->attachment_name;
3405                                         EM_DEBUG_LOG("name[%s]", name);
3406
3407                                         if (temp_attachment_tbl->inline_content_status && part_for_html)
3408                                                 body_to_attach = &(part_for_html->body);
3409                                         else
3410                                                 body_to_attach = root_body;
3411
3412                                         if (!attach_part(body_to_attach, (unsigned char *)temp_attachment_tbl->attachment_path, 0, name, NULL, temp_attachment_tbl->inline_content_status, &error))  {
3413                                                 EM_DEBUG_EXCEPTION("attach_part failed [%d]", error);
3414                                                 continue;
3415                                         }
3416                                 }
3417                         }
3418                 }
3419                 text_body = NULL;
3420         } else  {
3421                 text_body = mail_newbody();
3422
3423                 if (text_body == NULL)  {
3424                         EM_DEBUG_EXCEPTION("mail_newbody failed...");
3425
3426                         error = EMAIL_ERROR_OUT_OF_MEMORY;
3427                         goto FINISH_OFF;
3428                 }
3429
3430                 text_body->type = TYPETEXT;
3431                 text_body->encoding = ENC8BIT;
3432                 if (input_mail_tbl_data->file_path_plain || input_mail_tbl_data->file_path_html)
3433                         text_body->sparep = EM_SAFE_STRDUP(input_mail_tbl_data->file_path_plain ? temp_file_path_plain  :  temp_file_path_html);
3434                 else
3435                         text_body->sparep = NULL;
3436
3437                 if (input_mail_tbl_data->file_path_html != NULL && input_mail_tbl_data->file_path_html[0] != '\0')
3438                         text_body->subtype = strdup("html");
3439                 if (text_body->sparep)
3440                         text_body->size.bytes = EM_SAFE_STRLEN(text_body->sparep);
3441                 else
3442                         text_body->size.bytes = 0;
3443         }
3444
3445         if (file_path)  {
3446                 EM_DEBUG_LOG("write rfc822  :  file_path[%s]", file_path);
3447
3448                 if (part_for_html)
3449                         html_body = &(part_for_html->body);
3450
3451                 if (!emcore_write_rfc822(envelope, root_body ? root_body  :  text_body, html_body, input_mail_tbl_data->priority, input_mail_tbl_data->report_status, &fname, &error))  {
3452                         EM_DEBUG_EXCEPTION("emcore_write_rfc822 failed [%d]", error);
3453                         goto FINISH_OFF;
3454                 }
3455
3456                 *file_path = fname;
3457         }
3458
3459         if (EM_SAFE_STRLEN(temp_file_path_plain) > 0)  {
3460                 if (!emstorage_delete_file(temp_file_path_plain, &error))  {
3461                         EM_DEBUG_EXCEPTION("emstorage_delete_file failed [%d]", error);
3462                         goto FINISH_OFF;
3463                 }
3464         }
3465
3466         if (EM_SAFE_STRLEN(temp_file_path_html) > 0) {
3467                 if (!emstorage_delete_file(temp_file_path_html, &error))  {
3468                         EM_DEBUG_EXCEPTION("emstorage_delete_file failed [%d]", error);
3469                         goto FINISH_OFF;
3470                 }
3471         }
3472
3473         ret = true;
3474
3475 FINISH_OFF:
3476
3477         emstorage_free_account(&ref_account, 1, NULL);
3478
3479         if (envelope != NULL)
3480                 mail_free_envelope(&envelope);
3481
3482         if (text_body != NULL)
3483                 mail_free_body(&text_body);
3484
3485         if (root_body != NULL)
3486                 mail_free_body(&root_body);
3487
3488         if (err_code != NULL)
3489                 *err_code = error;
3490
3491         EM_DEBUG_FUNC_END("ret [%d]", ret);
3492         return ret;
3493 }
3494
3495 #ifdef __FEATURE_SUPPORT_REPORT_MAIL__
3496 static int emcore_get_report_mail_body(ENVELOPE *envelope, BODY **multipart_body, int *err_code)
3497 {
3498         EM_DEBUG_FUNC_BEGIN("envelope[%p], mulitpart_body[%p], err_code[%p]", envelope, multipart_body, err_code);
3499
3500         int ret = false;
3501         int err = EMAIL_ERROR_NONE;
3502
3503         BODY *m_body = NULL;
3504         BODY *p_body = NULL;
3505         BODY *text_body = NULL;
3506         PARAMETER *param = NULL;
3507         emstorage_attachment_tbl_t temp_attachment_tbl;
3508         FILE *fp = NULL;
3509         char *fname = NULL;
3510         char buf[512] = {0x00, };
3511         int sz = 0;
3512
3513         if (!envelope || !multipart_body)  {
3514                 EM_DEBUG_EXCEPTION(" envelope[%p], mulitpart_body[%p]", envelope, multipart_body);
3515                 err = EMAIL_ERROR_INVALID_PARAM;
3516                 goto FINISH_OFF;
3517         }
3518
3519         if (!(text_body = mail_newbody()))  {
3520                 EM_DEBUG_EXCEPTION(" mail_newbody failed...");
3521                 err = EMAIL_ERROR_OUT_OF_MEMORY;
3522                 goto FINISH_OFF;
3523         }
3524
3525         if (!emcore_get_temp_file_name(&fname, &err))  {
3526                 EM_DEBUG_EXCEPTION(" emcore_get_temp_file_name failed [%d]", err);
3527                 goto FINISH_OFF;
3528         }
3529
3530         if (!(fp = fopen(fname, "wb+")))  {
3531                 EM_DEBUG_EXCEPTION(" fopen failed - %s", fname);
3532                 err = EMAIL_ERROR_SYSTEM_FAILURE;
3533                 goto FINISH_OFF;
3534         }
3535
3536         if (!envelope->from || !envelope->from->mailbox || !envelope->from->host)  {
3537                 if (!envelope->from)
3538                         EM_DEBUG_EXCEPTION(" envelope->from[%p]", envelope->from);
3539                 else
3540                         EM_DEBUG_LOG(" envelope->from->mailbox[%p], envelope->from->host[%p]", envelope->from->mailbox, envelope->from->host);
3541
3542                 err = EMAIL_ERROR_INVALID_PARAM;
3543                 goto FINISH_OFF;
3544         }
3545
3546         /*
3547         if (envelope->from->personal)
3548                 SNPRINTF(buf, sizeof(buf), "%s <%s@%s>", envelope->from->personal, envelope->from->mailbox, envelope->from->host);
3549         else
3550         */
3551                 SNPRINTF(buf, sizeof(buf), "%s@%s", envelope->from->mailbox, envelope->from->host);
3552
3553         fprintf(fp, "Your message has been read by %s"CRLF_STRING, buf);
3554         fprintf(fp, "Date :  %s", envelope->date);
3555
3556         fclose(fp); fp = NULL;
3557
3558         if (!emcore_get_file_size(fname, &sz, &err))  {
3559                 EM_DEBUG_EXCEPTION(" emcore_get_file_size failed [%d]", err);
3560                 goto FINISH_OFF;
3561         }
3562
3563         text_body->type = TYPETEXT;
3564         text_body->encoding = ENC8BIT;
3565         text_body->sparep = EM_SAFE_STRDUP(fname);
3566         text_body->size.bytes = (unsigned long)sz;
3567
3568         if (!emcore_get_temp_file_name(&fname, &err))  {
3569                 EM_DEBUG_EXCEPTION(" emcore_get_temp_file_name failed [%d]", err);
3570                 goto FINISH_OFF;
3571         }
3572
3573         if (!(fp = fopen(fname, "wb+")))  {
3574                 EM_DEBUG_EXCEPTION(" fopen failed - %s", fname);
3575                 err = EMAIL_ERROR_SYSTEM_FAILURE;               /* EMAIL_ERROR_UNKNOWN; */
3576                 goto FINISH_OFF;
3577         }
3578
3579         if (!envelope->references)  {
3580                 EM_DEBUG_EXCEPTION(" envelope->references[%p]", envelope->references);
3581                 err = EMAIL_ERROR_INVALID_PARAM;
3582                 goto FINISH_OFF;
3583         }
3584
3585         fprintf(fp, "Final-Recipient :  rfc822;%s@%s\r", envelope->from->mailbox, envelope->from->host);
3586         fprintf(fp, "Original-Message-ID:  %s\r", envelope->references);
3587         fprintf(fp, "Disposition :  manual-action/MDN-sent-manually; displayed");
3588
3589         fclose(fp); fp = NULL;
3590
3591         memset(&temp_attachment_tbl, 0x00, sizeof(emstorage_attachment_tbl_t));
3592
3593         temp_attachment_tbl.attachment_path = EM_SAFE_STRDUP(fname);
3594
3595         if (!emcore_get_file_size(fname, &temp_attachment_tbl.attachment_size, &err))  {
3596                 EM_DEBUG_EXCEPTION(" emcore_get_file_size failed [%d]", err);
3597                 goto FINISH_OFF;
3598         }
3599
3600         if (!attach_attachment_to_body(&m_body, text_body, &temp_attachment_tbl, 1, &err))  {
3601                 EM_DEBUG_EXCEPTION(" attach_attachment_to_body failed [%d]", err);
3602                 goto FINISH_OFF;
3603         }
3604
3605         text_body->contents.text.data = NULL;
3606
3607         /*  change mail header */
3608
3609         /*  set content-type to multipart/report */
3610         m_body->subtype = strdup("report");
3611
3612         /*  set report-type parameter in content-type */
3613         param = em_malloc(sizeof(PARAMETER));
3614         if (!param)  {
3615                 EM_DEBUG_EXCEPTION(" malloc failed...");
3616                 err = EMAIL_ERROR_OUT_OF_MEMORY;
3617                 goto FINISH_OFF;
3618         }
3619
3620         param->attribute  = strdup("report-type");
3621         param->value      = strdup("disposition-notification");
3622         param->next       = m_body->parameter;
3623
3624         m_body->parameter = param;
3625
3626         /*  change body-header */
3627
3628         p_body = &m_body->nested.part->next->body;
3629
3630         /*  set content-type to message/disposition-notification */
3631         p_body->type      = TYPEMESSAGE;
3632         p_body->encoding  = ENC7BIT;
3633
3634         EM_SAFE_FREE(p_body->subtype);
3635
3636         p_body->subtype = strdup("disposition-notification");
3637
3638         /*  set parameter */
3639         mail_free_body_parameter(&p_body->parameter);
3640         mail_free_body_parameter(&p_body->disposition.parameter);
3641
3642         EM_SAFE_FREE(p_body->disposition.type);
3643
3644         p_body->disposition.type = strdup("inline");
3645
3646         ret = true;
3647
3648 FINISH_OFF:
3649         if ((ret == true) && (multipart_body != NULL))
3650                 *multipart_body = m_body;
3651         else if (m_body != NULL)
3652                 mail_free_body(&m_body);
3653
3654         if (text_body != NULL)
3655                 mail_free_body(&text_body);
3656
3657         if (fp != NULL)
3658                 fclose(fp);
3659
3660         EM_SAFE_FREE(fname);
3661
3662         if (err_code != NULL)
3663                 *err_code = err;
3664
3665         EM_DEBUG_FUNC_END("err [%d]", err);
3666         return ret;
3667 }
3668 #endif
3669
3670 INTERNAL_FUNC int emcore_get_body_buff(char *file_path, char **buff)
3671 {
3672         EM_DEBUG_FUNC_BEGIN();
3673
3674         FILE *r_fp = NULL;
3675         int read_size = 0;
3676         int ret = false;
3677         char *read_buff = NULL;
3678
3679
3680         if (file_path)
3681                 r_fp = fopen(file_path, "r");
3682
3683         if (!r_fp) {
3684                 EM_DEBUG_EXCEPTION(" Filename %s failed to open", file_path);
3685                 goto FINISH_OFF;
3686         }
3687
3688         struct stat stbuf;
3689         if (stat(file_path, &stbuf) == 0 && stbuf.st_size > 0) {
3690                 EM_DEBUG_LOG(" File Size [ %d ] ", stbuf.st_size);
3691                 read_buff = calloc((stbuf.st_size+ 1), sizeof(char));
3692                 read_size = fread(read_buff, 1, stbuf.st_size, r_fp);
3693                 read_buff[stbuf.st_size] = '\0';
3694         }
3695
3696         if (ferror(r_fp)) {
3697                 EM_DEBUG_EXCEPTION("file read failed - %s", file_path);
3698                 EM_SAFE_FREE(read_buff);
3699                 goto FINISH_OFF;
3700         }
3701         ret = true;
3702         *buff = read_buff;
3703
3704 FINISH_OFF:
3705         if (r_fp)
3706                 fclose(r_fp);
3707
3708         return ret;
3709 }
3710
3711 static int emcore_copy_attachment_from_original_mail(int input_original_mail_id, int input_target_mail_id)
3712 {
3713         EM_DEBUG_FUNC_BEGIN("input_original_mail_id[%d] input_target_mail_id[%d]", input_original_mail_id, input_target_mail_id);
3714         int err = EMAIL_ERROR_NONE;
3715         int i = 0, j = 0;
3716         int original_mail_attachment_count = 0;
3717         int target_mail_attachment_count = 0;
3718         int attachment_id = 0;
3719         char output_file_name[MAX_PATH] = { 0, };
3720         char output_file_path[MAX_PATH] = { 0, };
3721         emstorage_attachment_tbl_t *original_mail_attachment_array = NULL;
3722         emstorage_attachment_tbl_t *target_mail_attachment_array = NULL;
3723         emstorage_attachment_tbl_t *target_attach = NULL;
3724
3725         if((err = emstorage_get_attachment_list(input_original_mail_id, false, &original_mail_attachment_array, &original_mail_attachment_count)) != EMAIL_ERROR_NONE) {
3726                 EM_DEBUG_EXCEPTION("emstorage_get_attachment_list failed [%d]", err);
3727                 goto FINISH_OFF;
3728         }
3729
3730         if((err = emstorage_get_attachment_list(input_target_mail_id, false, &target_mail_attachment_array, &target_mail_attachment_count)) != EMAIL_ERROR_NONE) {
3731                 EM_DEBUG_EXCEPTION("emstorage_get_attachment_list failed [%d]", err);
3732                 goto FINISH_OFF;
3733         }
3734
3735         for(i = 0; i < original_mail_attachment_count; i++) {
3736                 for(j = 0; j < target_mail_attachment_count; j++) {
3737                         if(strcmp(original_mail_attachment_array[i].attachment_name, target_mail_attachment_array[j].attachment_name) == 0 ) {
3738                                 target_attach = target_mail_attachment_array + j;
3739
3740                                 /* If attachment is inline content, fild path should not include attachment id */
3741                                 if(target_attach->attachment_inline_content_status == 1)
3742                                         attachment_id = 0;
3743                                 else
3744                                         attachment_id = target_attach->attachment_id;
3745
3746                                 EM_DEBUG_LOG("attachment_inline_content_status [%d] attachment_id[%d]", target_attach->attachment_inline_content_status, attachment_id);
3747
3748                                 if(!emcore_save_mail_file(target_attach->account_id, target_attach->mail_id, attachment_id, original_mail_attachment_array[i].attachment_path, original_mail_attachment_array[i].attachment_name, output_file_path, &err)) {
3749                                         EM_DEBUG_EXCEPTION("emcore_save_mail_file failed [%d]", err);
3750                                         goto FINISH_OFF;
3751                                 }
3752
3753                                 EM_SAFE_FREE(target_attach->attachment_path);
3754                                 target_attach->attachment_path = EM_SAFE_STRDUP(output_file_path);
3755                                 target_attach->attachment_save_status = 1;
3756
3757                                 if(!emstorage_update_attachment(target_attach, false, &err)) {
3758                                         EM_DEBUG_EXCEPTION("emstorage_update_attachment failed [%d]", err);
3759                                         goto FINISH_OFF;
3760                                 }
3761                                 memset(output_file_path, 0, MAX_PATH);
3762                                 memset(output_file_name, 0, MAX_PATH);
3763                                 break;
3764                         }
3765                 }
3766         }
3767
3768 FINISH_OFF:
3769         if(original_mail_attachment_array)
3770                 emstorage_free_attachment(&original_mail_attachment_array, original_mail_attachment_count, NULL);
3771         if(target_mail_attachment_array)
3772                 emstorage_free_attachment(&target_mail_attachment_array, target_mail_attachment_count, NULL);
3773
3774
3775         EM_DEBUG_FUNC_END("err[%d]", err);
3776         return err;
3777 }
3778
3779 /*  send a mail */
3780 INTERNAL_FUNC int emcore_send_mail_with_downloading_attachment_of_original_mail(int input_mail_id)
3781 {
3782         EM_DEBUG_FUNC_BEGIN("input_mail_id[%d]", input_mail_id);
3783         int err = EMAIL_ERROR_NONE;
3784         int i = 0;
3785         int attachment_count = 0;
3786         email_mail_data_t *mail_to_be_sent = NULL;
3787         email_mail_data_t *original_mail = NULL;
3788         email_attachment_data_t *attachment_array = NULL;
3789
3790         /* Get mail data */
3791         if((err = emcore_get_mail_data(input_mail_id, &mail_to_be_sent)) != EMAIL_ERROR_NONE) {
3792                 EM_DEBUG_EXCEPTION("emcore_get_mail_data failed [%d]", err);
3793                 goto FINISH_OFF;
3794         }
3795
3796         if(mail_to_be_sent->reference_mail_id <= 0) {
3797                 err = EMAIL_ERROR_INVALID_REFERENCE_MAIL;
3798                 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_REFERENCE_MAIL");
3799                 goto FINISH_OFF;
3800         }
3801
3802         /* Get original mail data */
3803         if((err = emcore_get_mail_data(mail_to_be_sent->reference_mail_id, &original_mail)) != EMAIL_ERROR_NONE) {
3804                 EM_DEBUG_EXCEPTION("emcore_get_mail_data failed [%d]", err);
3805                 goto FINISH_OFF;
3806         }
3807
3808         /* Check necessity of download */
3809         if((err = emcore_get_attachment_data_list(original_mail->mail_id, &attachment_array, &attachment_count)) != EMAIL_ERROR_NONE) {
3810                 EM_DEBUG_EXCEPTION("emcore_get_attachment_data_list failed [%d]", err);
3811                 goto FINISH_OFF;
3812         }
3813
3814         /* If need be, download attachments */
3815         for(i = 0; i < attachment_count; i++) {
3816                 if(attachment_array[i].save_status != 1) {
3817                         if(!emcore_download_attachment(original_mail->account_id, original_mail->mail_id, i + 1, &err)) {
3818                                 EM_DEBUG_EXCEPTION("emcore_download_attachment failed [%d]", err);
3819                                 goto FINISH_OFF;
3820                         }
3821                 }
3822         }
3823
3824         /* Copy attachment to the mail to be sent */
3825         if((err = emcore_copy_attachment_from_original_mail(original_mail->mail_id, mail_to_be_sent->mail_id)) != EMAIL_ERROR_NONE) {
3826                 EM_DEBUG_EXCEPTION("emcore_download_attachment failed [%d]", err);
3827                 goto FINISH_OFF;
3828         }
3829
3830         /* Send the mail */
3831         if(!emcore_send_mail(mail_to_be_sent->mail_id, &err)) {
3832                 EM_DEBUG_EXCEPTION("emcore_send_mail failed [%d]", err);
3833                 goto FINISH_OFF;
3834         }
3835 FINISH_OFF:
3836
3837         if(attachment_array)
3838                 emcore_free_attachment_data(&attachment_array, attachment_count, NULL);
3839
3840         if(mail_to_be_sent) {
3841                 emcore_free_mail_data(mail_to_be_sent);
3842                 EM_SAFE_FREE(mail_to_be_sent);
3843         }
3844
3845         if(original_mail) {
3846                 emcore_free_mail_data(original_mail);
3847                 EM_SAFE_FREE(original_mail);
3848         }
3849
3850
3851         EM_DEBUG_FUNC_END("err [%d]", err);
3852         return err;
3853 }
3854
3855 /* Scheduled sending ------------------------------------------------ */
3856
3857
3858 static int emcore_sending_alarm_cb(int input_timer_id, void *user_parameter)
3859 {
3860         EM_DEBUG_FUNC_BEGIN("input_timer_id [%d] user_parameter [%p]", input_timer_id, user_parameter);
3861         int err = EMAIL_ERROR_NONE;
3862         int ret = 0;
3863         email_alarm_data_t *alarm_data = NULL;
3864
3865         if (((err = emcore_get_alarm_data_by_alarm_id(input_timer_id, &alarm_data)) != EMAIL_ERROR_NONE) || alarm_data == NULL) {
3866                 EM_DEBUG_EXCEPTION("emcore_get_alarm_data_by_alarm_id failed [%d]", err);
3867                 goto FINISH_OFF;
3868         }
3869
3870         /* send mail here */
3871         if(!emcore_send_mail(alarm_data->reference_id, &err)) {
3872                 EM_DEBUG_EXCEPTION("emcore_send_mail failed [%d]", ret);
3873                 goto FINISH_OFF;
3874         }
3875
3876         /* delete alarm info*/
3877         emcore_delete_alram_data_from_alarm_data_list(alarm_data);
3878
3879 FINISH_OFF:
3880
3881         EM_SAFE_FREE(alarm_data);
3882
3883         EM_DEBUG_FUNC_END("err [%d]", err);
3884         return err;
3885 }
3886
3887
3888 INTERNAL_FUNC int emcore_schedule_sending_mail(int input_mail_id, time_t input_time_to_send)
3889 {
3890         EM_DEBUG_FUNC_BEGIN("input_mail_id[%d] input_time_to_send[%d]", input_mail_id, input_time_to_send);
3891         int err = EMAIL_ERROR_NONE;
3892         emstorage_mail_tbl_t *mail_data = NULL;
3893
3894         /* get mail data */
3895         if (!emstorage_get_mail_by_id(input_mail_id, &mail_data, true, &err) || mail_data == NULL) {
3896                 EM_DEBUG_EXCEPTION("emstorage_get_mail_by_id failed [%d]", err);
3897                 goto FINISH_OFF;
3898         }
3899
3900         /* set save_status as EMAIL_MAIL_STATUS_SEND_SCHEDULED */
3901         if (!emstorage_set_field_of_mails_with_integer_value(mail_data->account_id, &(mail_data->mail_id), 1, "save_status", EMAIL_MAIL_STATUS_SEND_SCHEDULED, true, &err)) {
3902                 EM_DEBUG_EXCEPTION("emstorage_set_field_of_mails_with_integer_value failed [%d]", err);
3903                 goto FINISH_OFF;
3904         }
3905
3906         if (!emstorage_set_field_of_mails_with_integer_value(mail_data->account_id, &(mail_data->mail_id), 1, "scheduled_sending_time", input_time_to_send, true, &err)) {
3907                 EM_DEBUG_EXCEPTION("emstorage_set_field_of_mails_with_integer_value failed [%d]", err);
3908                 goto FINISH_OFF;
3909         }
3910
3911         /* add alarm */
3912         if ((err = emcore_add_alarm(input_time_to_send, EMAIL_ALARM_CLASS_SCHEDULED_SENDING, input_mail_id, emcore_sending_alarm_cb, NULL)) != EMAIL_ERROR_NONE) {
3913                 EM_DEBUG_EXCEPTION("emcore_add_alarm failed [%d]", err);
3914                 goto FINISH_OFF;
3915         }
3916
3917 FINISH_OFF:
3918         if(mail_data)
3919                 emstorage_free_mail(&mail_data, 1, NULL);
3920
3921         EM_DEBUG_FUNC_END("err [%d]", err);
3922         return err;
3923 }
3924 /* Scheduled sending ------------------------------------------------ */