Coverity issue fixes for email service
[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 <glib/gstdio.h>
32 #include <alarm.h>
33 #include <dlfcn.h>
34 #include <ctype.h>
35 #include <sys/shm.h>
36
37 #include "email-internal-types.h"
38 #include "c-client.h"
39 #include "email-daemon.h"
40 #include "email-core-global.h"
41 #include "email-core-utils.h"
42 #include "email-storage.h"
43 #include "email-core-smtp.h"
44 #include "email-core-event.h"
45 #include "email-core-mailbox.h"
46 #include "email-core-mail.h"
47 #include "email-core-mime.h"
48 #include "email-core-smime.h"
49 #include "email-core-account.h"
50 #include "email-core-imap-mailbox.h"
51 #include "email-core-mailbox-sync.h"
52 #include "email-core-signal.h"
53 #include "email-core-alarm.h"
54 #include "email-utilities.h"
55 #include "email-convert.h"
56 #include "email-debug-log.h"
57 #include "email-core-gmime.h"
58 #include "email-core-container.h"
59 #include "email-network.h"
60
61 #undef min
62
63
64
65 #ifdef __FEATURE_SUPPORT_REPORT_MAIL__
66 static int emcore_get_report_mail_body(char *multi_user_name, ENVELOPE *envelope, BODY **multipart_body, int *err_code);
67 #endif
68 static int emcore_make_envelope_from_mail(char *multi_user_name, emstorage_mail_tbl_t *input_mail_tbl_data, ENVELOPE **output_envelope);
69 static int emcore_send_mail_smtp(char *multi_user_name, SENDSTREAM *stream, ENVELOPE *env, char *data_file, int account_id, int mail_id,  int *err_code);
70 char *emcore_generate_content_id_string(const char *hostname, int *err);
71
72 /* Functions from uw-imap-toolkit */
73 /* extern void *fs_get(size_t size); */
74 extern void rfc822_date(char *date);
75 extern long smtp_send(SENDSTREAM *stream, char *command, char *args);
76 extern long smtp_rcpt(SENDSTREAM *stream, ADDRESS *adr, long* error);
77
78 #ifndef __FEATURE_SEND_OPTMIZATION__
79 extern long smtp_soutr(void *stream, char *s);
80 #endif
81
82 #ifdef __FEATURE_SEND_OPTMIZATION__
83 extern long smtp_soutr_test(void *stream, char *s);
84 #endif
85
86
87
88
89 void mail_send_notify(email_send_status_t status, int total, int sent, int account_id, int mail_id,  int err_code)
90 {
91         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);
92
93         switch (status) {
94         case EMAIL_SEND_CONNECTION_FAIL:
95         case EMAIL_SEND_FINISH:
96         case EMAIL_SEND_FAIL:
97                 break;
98
99         case EMAIL_SEND_PROGRESS:
100         default:
101                 break;
102         }
103         emcore_execute_event_callback(EMAIL_ACTION_SEND_MAIL, total, sent, status, account_id, mail_id, -1, err_code);
104         EM_DEBUG_FUNC_END();
105 }
106
107 /* ------ rfc822 handle ---------------------------------------------------*/
108 long buf_flush(void *stream, char *string)
109 {
110         EM_DEBUG_FUNC_BEGIN("stream[%p], string[%s]", stream, string);
111         EM_DEBUG_FUNC_END();
112         return 1;
113 }
114
115
116 #define RFC822_READ_BLOCK_SIZE    1024
117 #define RFC822_STRING_BUFFER_SIZE 1536
118
119 static char *emcore_find_img_tag(char *source_string)
120 {
121         EM_DEBUG_FUNC_BEGIN("source_string[%p]", source_string);
122
123         int cur = 0, string_length;
124         if (!source_string)
125                 return false;
126
127         string_length = EM_SAFE_STRLEN(source_string);
128
129         for (cur = 0; cur < string_length; cur++) {
130                 if (source_string[cur] == 'I' || source_string[cur] == 'i') {
131                         cur++;
132                         if (source_string[cur] == 'M' || source_string[cur] == 'm') {
133                                 cur++;
134                                 if (source_string[cur] == 'G' || source_string[cur] == 'g') {
135                                         EM_DEBUG_FUNC_END_SEC("%s", source_string + cur - 2);
136                                         return source_string + cur - 2;
137                                 }
138                         }
139                 }
140         }
141         EM_DEBUG_FUNC_END("Can't find");
142         return NULL;
143 }
144
145 #define CONTENT_ID_BUFFER_SIZE 512
146 static char *emcore_replace_inline_image_path_with_content_id(char *source_string, BODY *root_body, int *err_code)
147 {
148         EM_DEBUG_FUNC_BEGIN("source_string[%p], root_body[%p], err_code[%p]", source_string, root_body, err_code);
149
150         int  err = EMAIL_ERROR_NONE;
151         char content_id_buffer[CONTENT_ID_BUFFER_SIZE] = {0,};
152         char file_name_buffer[512] = {0,};
153         char old_string[512] = {0,};
154         char new_string[512] = {0,};
155         char *result_string = NULL;
156         char *input_string = NULL;
157         BODY *cur_body = NULL;
158         PART *cur_part = NULL;
159
160         if (!source_string || !root_body) {
161                 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM [%p] [%p]", source_string, root_body);
162                 err = EMAIL_ERROR_INVALID_PARAM;
163                 goto FINISH_OFF;
164         }
165
166         input_string = EM_SAFE_STRDUP(source_string);
167
168         cur_body = root_body;
169         if (root_body->type != TYPEMULTIPART) {
170                 EM_DEBUG_LOG("The body is not multipart : type[%d]", root_body->type);
171                 goto FINISH_OFF;
172         }
173
174         do {
175                 cur_part = cur_body->nested.part;
176
177                 if (strcasecmp(cur_body->subtype, "RELATED") == 0) {
178                         EM_DEBUG_LOG("Related part");
179                         while (cur_part) {
180                                 cur_body = &(cur_part->body);
181
182                                 /* Is inline content? */
183                                 if (cur_body->disposition.type && cur_body->disposition.type[0] == 'i') {
184                                         EM_DEBUG_LOG("Has inline content");
185                                         memset(content_id_buffer, 0, CONTENT_ID_BUFFER_SIZE);
186                                         if (cur_body->id) {
187                                                 EM_SAFE_STRNCPY(content_id_buffer, cur_body->id + 1, CONTENT_ID_BUFFER_SIZE - 1); /*  Removing <, > */
188                                                 /* prevent 34413 */
189                                                 char *last_bracket = rindex(content_id_buffer, '>');
190                                                 if (last_bracket)
191                                                         *last_bracket = NULL_CHAR;
192
193                                                 /* if (emcore_get_attribute_value_of_body_part(cur_body->parameter, "name", file_name_buffer, CONTENT_ID_BUFFER_SIZE, false, &err)) { */
194                                                 if (emcore_get_attribute_value_of_body_part(cur_body->parameter, "name", file_name_buffer, CONTENT_ID_BUFFER_SIZE, true, &err)) {
195                                                         EM_DEBUG_LOG_SEC("Content-ID[%s], filename[%s]", content_id_buffer, file_name_buffer);
196                                                         SNPRINTF(new_string, CONTENT_ID_BUFFER_SIZE, "\"cid:%s\"", content_id_buffer);
197                                                         SNPRINTF(old_string, CONTENT_ID_BUFFER_SIZE, "\"%s\"", file_name_buffer);
198                                                         result_string = em_replace_string(input_string, old_string, new_string);
199                                                 }
200                                         }
201                                 }
202
203                                 if (result_string) {
204                                         EM_SAFE_FREE(input_string);
205                                         input_string = result_string;
206                                         result_string = NULL; /* prevent 34868 */
207                                 }
208
209                                 cur_part = cur_part->next;
210                         }
211                 }
212
213                 if (cur_part)
214                         cur_body = &(cur_part->body);
215                 else
216                         cur_body = NULL;
217
218         } while (cur_body);
219
220         if (input_string)
221                 result_string = EM_SAFE_STRDUP(input_string);
222 FINISH_OFF:
223
224         EM_SAFE_FREE(input_string);
225         if (err_code)
226                 *err_code = err;
227
228         EM_DEBUG_FUNC_END("ret[%s]", result_string);
229         return result_string;
230 }
231
232 static int emcore_write_body(BODY *body, BODY *root_body, FILE *fp)
233 {
234         EM_DEBUG_FUNC_BEGIN("fp[%d]", fp);
235         char *file_path = NULL;
236         char buf[RFC822_STRING_BUFFER_SIZE + 1] = {0};
237         char *img_tag_pos = NULL;
238         char *p = NULL;
239         char *replaced_string = NULL;
240         int fd = 0;
241         int nread = 0;
242         int nwrite = 0;
243         int error = EMAIL_ERROR_NONE;
244         unsigned long len;
245         char *tmp_p = NULL;
246         char *tmp_file_path = NULL;
247         FILE *fp_html = NULL;
248         FILE *fp_write = NULL;
249         char *full_buf = NULL;
250
251         file_path = body->sparep;
252         if (!file_path || EM_SAFE_STRLEN(file_path) == 0) {
253                 EM_DEBUG_LOG("There is no file path");
254                 switch (body->encoding) {
255                 case 0:
256                 default:
257                         p = cpystr((const char *)body->contents.text.data);
258                         len = body->contents.text.size;
259                         break;
260                 }
261
262                 if (p) {
263                         EM_DEBUG_LOG("p[%s]", p);
264                         fprintf(fp, "%s"CRLF_STRING CRLF_STRING, p);
265                         EM_SAFE_FREE(p);
266                 }
267
268                 EM_SAFE_FREE(body->sparep);
269                 EM_DEBUG_FUNC_END();
270                 return error;
271         }
272
273         if (body->type == TYPETEXT && body->subtype && toupper(body->subtype[0]) == 'H') {
274                 EM_DEBUG_LOG("HTML Part");
275
276                 struct stat st_buf;
277                 unsigned int byte_read = 0;
278
279                 if (stat(file_path, &st_buf) < 0) {
280                         EM_DEBUG_EXCEPTION("stat [%s] error [%d]", file_path, errno);
281                         error = EMAIL_ERROR_FILE ;
282                         goto FINISH_OFF;
283                 }
284
285                 error = em_fopen(file_path, "r", &fp_html);
286                 if (error != EMAIL_ERROR_NONE) {
287                         EM_DEBUG_EXCEPTION("em_fopen [%s] error [%d] ", file_path, error);
288                         goto FINISH_OFF;
289                 }
290
291                 if (S_ISREG(st_buf.st_mode) && st_buf.st_size == 0) {
292                         EM_DEBUG_LOG("file_path[%s] is empty size", file_path);
293                         error = EMAIL_ERROR_FILE ;
294                         goto FINISH_OFF;
295                 }
296
297                 if (!(full_buf = (char*) em_malloc(sizeof(char) * (st_buf.st_size + 1)))) {
298                         EM_DEBUG_EXCEPTION("em_mallocfailed");
299                         error = EMAIL_ERROR_OUT_OF_MEMORY;
300                         goto FINISH_OFF;
301                 }
302
303                 byte_read = fread(full_buf, sizeof(char), st_buf.st_size, fp_html);
304
305                 if (byte_read <= 0) {
306                         EM_SAFE_FREE(full_buf);
307                         if (ferror(fp_html)) {
308                                 EM_DEBUG_EXCEPTION("fread [%s] error [%d]", file_path, errno);
309                                 error = EMAIL_ERROR_FILE ;
310                                 goto FINISH_OFF;
311                         }
312                 } else {
313                         full_buf[byte_read] = '\0';
314                         EM_DEBUG_LOG_DEV("==================================================");
315                         EM_DEBUG_LOG_DEV("fread : %s", full_buf);
316                         EM_DEBUG_LOG_DEV("==================================================");
317
318                         img_tag_pos = emcore_find_img_tag(full_buf);
319
320                         if (img_tag_pos) {
321                                 replaced_string = emcore_replace_inline_image_path_with_content_id(full_buf, root_body, &error);
322                                 if (replaced_string) {
323                                         EM_DEBUG_LOG("emcore_replace_inline_image_path_with_content_id succeeded");
324                                         EM_DEBUG_LOG_DEV("==================================================");
325                                         EM_DEBUG_LOG_DEV("replaced_string : %s", replaced_string);
326                                         EM_DEBUG_LOG_DEV("==================================================");
327
328                                         if (!emcore_get_temp_file_name(&tmp_file_path, &error)) {
329                                                 EM_DEBUG_EXCEPTION(" em_core_get_temp_file_name failed[%d]", error);
330                                                 goto FINISH_OFF;
331                                         }
332                                         EM_DEBUG_LOG_DEV("tmp file path : %s", tmp_file_path);
333
334                                         error = em_fopen(tmp_file_path, "w", &fp_write);
335                                         if (error != EMAIL_ERROR_NONE) {
336                                                 EM_DEBUG_EXCEPTION_SEC("em_fopen [%s] error [%d]", tmp_file_path, error);
337                                                 goto FINISH_OFF;
338                                         }
339
340                                         if (fseek(fp_write, 0, SEEK_SET) < 0) {
341                                                 EM_DEBUG_EXCEPTION("fseekfailed : error [%d]", errno);
342                                                 error = EMAIL_ERROR_FILE;
343                                                 goto FINISH_OFF;
344                                         }
345
346                                         if (fprintf(fp_write, "%s", replaced_string) <= 0) {
347                                                 EM_DEBUG_EXCEPTION("fprintf failed : error [%d]", errno);
348                                                 error = EMAIL_ERROR_FILE;
349                                                 goto FINISH_OFF;
350                                         }
351
352                                         file_path = tmp_file_path;
353                                         fclose(fp_write);
354                                         fp_write = NULL;
355                                 }
356                         }
357                 }
358         }
359
360         EM_DEBUG_LOG_DEV("Opening a file[%s]", file_path);
361
362         error = em_open(file_path, O_RDONLY, 0, &fd);
363         if (error != EMAIL_ERROR_NONE) {
364                 EM_DEBUG_EXCEPTION_SEC("open[%s] error [%d]", file_path, error);
365                 goto FINISH_OFF;
366         }
367
368         while (1) {
369                 EM_SAFE_FREE(p);
370                 memset(&buf, 0x00, RFC822_STRING_BUFFER_SIZE + 1);
371                 nread = read(fd, buf, (body->encoding == ENCBASE64 ? 57 : RFC822_READ_BLOCK_SIZE - 2));
372
373                 if (nread == 0) {
374                         EM_DEBUG_LOG_DEV("Can't read anymore : nread[%d]", nread);
375                         break;
376                 } else if (nread < 0) {
377                         EM_DEBUG_EXCEPTION("read [%s] error [%d]", file_path, errno);
378                         error = EMAIL_ERROR_FILE;
379                         break;
380                 }
381
382                 len = nread;
383
384                 /* EM_DEBUG_LOG("body->encoding[%d]", body->encoding); */
385                 switch (body->encoding) {
386                 case ENCQUOTEDPRINTABLE:
387                         p = (char *)rfc822_8bit((unsigned char *)buf, (unsigned long)nread, (unsigned long *)&len);
388                         break;
389                 case ENCBASE64:
390                         tmp_p = g_base64_encode((guchar *)buf, (gsize)nread);
391                         p = g_strconcat(tmp_p, "\r\n", NULL);
392                         EM_SAFE_FREE(tmp_p);
393                         len = EM_SAFE_STRLEN(p);
394                         break;
395                 }
396
397                 //prepend additional dot to the string start with dot
398                 if (p && p[0] == '.') {
399                         tmp_p = g_strdup(p);
400                         EM_SAFE_FREE(p);
401                         p = g_strconcat(".", tmp_p, NULL);
402                         EM_SAFE_FREE(tmp_p);
403                 }
404
405                 if (!p && buf[0] == '.')
406                         p = g_strconcat(".", buf, NULL);
407
408                 len = EM_SAFE_STRLEN((p ? p : buf));
409                 EM_DEBUG_LOG_DEV("line[%s]", (p ? p : buf));
410
411                 nwrite = fprintf(fp, "%s", (p ? p : buf));
412                 if (nwrite != len) {
413                         EM_DEBUG_EXCEPTION("fprintf error: nwrite[%d] len[%lu] error[%d]", nwrite, len, errno);
414                         error = EMAIL_ERROR_FILE ;
415                         goto FINISH_OFF;
416                 }
417         }
418
419         if (body->encoding == ENCQUOTEDPRINTABLE || body->encoding == ENCBASE64)
420                 fprintf(fp, CRLF_STRING);
421
422 FINISH_OFF: /* prevent 34226 */
423
424         /* cleanup local vars */
425         EM_SAFE_FREE(body->sparep);
426         EM_SAFE_CLOSE(fd); /*prevent 34498*/
427         EM_SAFE_FREE(p);
428         if (tmp_file_path) {
429                 if (g_remove(tmp_file_path) != 0)
430                         EM_DEBUG_EXCEPTION(" Fail to remove tmp_file_path \n");
431         }
432         EM_SAFE_FREE(tmp_file_path);
433         if (fp_html)
434                 fclose(fp_html);
435         if (fp_write)
436                 fclose(fp_write);
437         EM_SAFE_FREE(full_buf);
438         EM_SAFE_FREE(replaced_string);
439         EM_DEBUG_FUNC_END();
440         return error;
441 }
442
443 static int emcore_write_rfc822_body(BODY *body, BODY *root_body, FILE *fp, int *err_code)
444 {
445         EM_DEBUG_FUNC_BEGIN("body[%p], fp[%p], err_code[%p]", body, fp, err_code);
446
447         PARAMETER *param = NULL;
448         PART *part = NULL;
449         char *p = NULL, *bndry = NULL, buf[SENDBUFLEN];
450         int error = EMAIL_ERROR_NONE;
451
452         switch (body->type) {
453         case TYPEMULTIPART:
454                 EM_DEBUG_LOG_DEV("body->type = TYPEMULTIPART");
455
456                 part = body->nested.part;
457
458                 for (param = body->parameter; param; param = param->next) {
459                         if (strcasecmp(param->attribute, "BOUNDARY") == 0) {
460                                 bndry = param->value;
461                                 break;
462                         }
463                 }
464
465                 do {
466                         p = buf; p[0] = '\0';
467
468                         rfc822_write_body_header(&p, &part->body);
469
470                         fprintf(fp, CRLF_STRING"--%s"CRLF_STRING, bndry);
471                         if (body->subtype && (body->subtype[0] == 'S' || body->subtype[0] == 's')) {
472                                 if ((error = emcore_write_body(body, root_body, fp)) != EMAIL_ERROR_NONE) {
473                                         EM_DEBUG_EXCEPTION("emcore_write_body failed : [%d]", error);
474                                         return false;
475                                 }
476                                 fprintf(fp, CRLF_STRING"--%s"CRLF_STRING, bndry);
477                         }
478
479                         fprintf(fp, "%s", buf);
480                         emcore_write_rfc822_body(&part->body, root_body, fp, err_code);
481
482                 } while ((part = part->next));
483
484                 fprintf(fp, CRLF_STRING"--%s--"CRLF_STRING, bndry);
485                 break;
486
487         default:
488                 EM_DEBUG_LOG_DEV("body->type is not TYPEMULTIPART");
489
490                 fprintf(fp, CRLF_STRING);
491                 if ((error = emcore_write_body(body, root_body, fp)) != EMAIL_ERROR_NONE) {
492                         EM_DEBUG_EXCEPTION("emcore_write_body failed : [%d]", error);
493                         return false;
494                 }
495
496                 break;
497         }
498         EM_DEBUG_FUNC_END();
499         return true;
500 }
501
502 static int emcore_write_rfc822(ENVELOPE *env, BODY *body, email_mail_priority_t input_priority,
503                 email_mail_report_t input_report_flag, char **data)
504 {
505         EM_DEBUG_FUNC_BEGIN("env[%p], body[%p], data[%p]", env, body, data);
506
507         int error = EMAIL_ERROR_NONE;
508         FILE *fp = NULL;
509         char *fname = NULL;
510         int file_exist = 0;
511         char  *header_buffer = NULL;
512         size_t header_buffer_lenth = 0;
513         RFC822BUFFER buf;
514         int  address_count = 0;
515         ADDRESS *index = NULL;
516
517         if (!env || !data) {
518                 EM_DEBUG_EXCEPTION("Invalid Parameters");
519                 error = EMAIL_ERROR_INVALID_PARAM;
520                 goto FINISH_OFF;
521         }
522
523         srand(time(NULL));
524
525         rfc822_encode_body_7bit(env, body); /*  if contents.text.data isn't NULL, the data will be encoded. */
526
527         index = env->to;
528         while (index) {
529                 address_count++;
530                 index = index->next;
531         }
532
533         index = env->cc;
534         while (index) {
535                 address_count++;
536                 index = index->next;
537         }
538
539         header_buffer_lenth = (env->subject ? EM_SAFE_STRLEN(env->subject) : 0);
540         header_buffer_lenth += address_count * MAX_EMAIL_ADDRESS_LENGTH;
541         header_buffer_lenth += 8192;
542
543         EM_DEBUG_LOG("header_buffer_lenth [%zu]", header_buffer_lenth);
544
545         if (!(header_buffer = em_malloc(header_buffer_lenth))) {
546                 EM_DEBUG_EXCEPTION(" malloc failed...");
547                 error = EMAIL_ERROR_OUT_OF_MEMORY;
548                 goto FINISH_OFF;
549         }
550
551         /* write at start of buffer */
552         buf.beg = buf.cur = header_buffer;
553         buf.end = header_buffer + header_buffer_lenth - 1;
554         buf.f   = buf_flush;
555         buf.s   = NULL;
556
557         /*  rfc822_output_header(&buf, env, body, NIL, T); */           /*  including BCC  */
558         rfc822_output_header(&buf, env, body, NIL, NIL);                /*  Excluding BCC */
559
560         EM_DEBUG_LOG("header_buffer [%zu]", strlen(header_buffer));
561         {
562                 gchar **tokens = g_strsplit(header_buffer, "CHARSET=X-UNKNOWN", 2);
563
564                 if (g_strv_length(tokens) > 1) {
565                         gchar *charset;
566
567                         if (body->sparep) {
568                                 charset = g_path_get_basename(body->sparep);
569                                 char *pHtml = NULL;
570                                 if (charset != NULL) {
571                                         if ((pHtml = strstr(charset, ".htm")) != NULL)
572                                                 charset[pHtml-charset] = '\0';
573                                 }
574
575                                 SNPRINTF(header_buffer, header_buffer_lenth, "%sCHARSET=%s%s", tokens[0], charset, tokens[1]);
576                                 g_free(charset);
577                         } else
578                                 EM_DEBUG_EXCEPTION("body->sparep is NULL");
579                 }
580
581                 g_strfreev(tokens);
582         }
583
584         {
585                 gchar **tokens = g_strsplit(header_buffer, "To: undisclosed recipients: ;\015\012", 2);
586                 if (g_strv_length(tokens) > 1)
587                         SNPRINTF(header_buffer, header_buffer_lenth, "%s%s", tokens[0], tokens[1]);
588                 g_strfreev(tokens);
589         }
590
591         EM_DEBUG_LOG_DEV(" =============================================================================== "
592                         LF_STRING"%s"LF_STRING
593                         " =============================================================================== ", header_buffer);
594
595         if (EM_SAFE_STRLEN(header_buffer) > 2)
596                 *(header_buffer + EM_SAFE_STRLEN(header_buffer) - 2) = '\0';
597
598         if (input_report_flag) {
599                 char string_buf[512] = {0x00, };
600
601                 if (input_report_flag & EMAIL_MAIL_REPORT_DSN) {
602                         /*  DSN (delivery status) */
603                         /*  change content-type */
604                         /*  Content-Type: multipart/report; */
605                         /*      report-type= delivery-status; */
606                         /*      boundary="----=_NextPart_000_004F_01C76EFF.54275C50" */
607                 }
608
609                 if (input_report_flag & EMAIL_MAIL_REPORT_MDN) {
610                         /*  MDN (read receipt) */
611                         /*  Content-Type: multipart/report; */
612                         /*      report-type= disposition-notification; */
613                         /*      boundary="----=_NextPart_000_004F_01C76EFF.54275C50" */
614                 }
615
616                 if (input_report_flag & EMAIL_MAIL_REQUEST_MDN) {
617                         /*  require read status */
618                         rfc822_address(string_buf, env->from);
619                         if (EM_SAFE_STRLEN(string_buf))
620                                 SNPRINTF(header_buffer + EM_SAFE_STRLEN(header_buffer), header_buffer_lenth - EM_SAFE_STRLEN(header_buffer), "Disposition-Notification-To: %s"CRLF_STRING, string_buf);
621                 }
622         }
623
624         if (input_priority > 0) {               /*  priority (1:high 3:normal 5:low) */
625                 SNPRINTF(header_buffer + EM_SAFE_STRLEN(header_buffer), header_buffer_lenth-(EM_SAFE_STRLEN(header_buffer)), "X-Priority: %d"CRLF_STRING, input_priority);
626
627                 switch (input_priority) {
628                 case EMAIL_MAIL_PRIORITY_HIGH:
629                         SNPRINTF(header_buffer + EM_SAFE_STRLEN(header_buffer), header_buffer_lenth-(EM_SAFE_STRLEN(header_buffer)), "X-MSMail-Priority: High"CRLF_STRING);
630                         break;
631                 case EMAIL_MAIL_PRIORITY_NORMAL:
632                         SNPRINTF(header_buffer + EM_SAFE_STRLEN(header_buffer), header_buffer_lenth-(EM_SAFE_STRLEN(header_buffer)), "X-MSMail-Priority: Normal"CRLF_STRING);
633                         break;
634                 case EMAIL_MAIL_PRIORITY_LOW:
635                         SNPRINTF(header_buffer + EM_SAFE_STRLEN(header_buffer), header_buffer_lenth-(EM_SAFE_STRLEN(header_buffer)), "X-MSMail-Priority: Low"CRLF_STRING);
636                         break;
637                 }
638         }
639
640         //      SNPRINTF(header_buffer + EM_SAFE_STRLEN(header_buffer), header_buffer_lenth-(EM_SAFE_STRLEN(header_buffer)), CRLF_STRING);
641         if (data && EM_SAFE_STRLEN(*data) > 0) {
642                 fname = EM_SAFE_STRDUP(*data);
643                 file_exist = 1;
644         } else {
645                 if (!emcore_get_temp_file_name(&fname, &error)) {
646                         EM_DEBUG_EXCEPTION(" emcore_get_temp_file_name failed[%d]", error);
647                         goto FINISH_OFF;
648                 }
649         }
650
651         error = em_fopen(fname, "w+", &fp);
652         if (error != EMAIL_ERROR_NONE) {
653                 EM_DEBUG_EXCEPTION("em_fopen failed[%s] [%d]", fname, error);
654                 goto FINISH_OFF;
655         }
656
657         fprintf(fp, "%s", header_buffer);
658
659         if (body) {
660                 if (!emcore_write_rfc822_body(body, body, fp, &error)) {
661                         EM_DEBUG_EXCEPTION("emcore_write_rfc822_body failed[%d]", error);
662                         goto FINISH_OFF;
663                 }
664         }
665
666 FINISH_OFF:
667         if (fp != NULL)
668                 fclose(fp);
669
670 #ifdef USE_SYNC_LOG_FILE
671         emstorage_copy_file(fname, "/tmp/phone2pc.eml", false, NULL);
672 #endif
673
674         if (error == EMAIL_ERROR_NONE) {
675                 if (!file_exist)
676                         *data = EM_SAFE_STRDUP(fname);
677         } else if (fname != NULL) {
678                 if (remove(fname) != 0)
679                         EM_DEBUG_EXCEPTION("Fail to remove fname \n");
680         }
681
682         EM_SAFE_FREE(fname);
683         EM_SAFE_FREE(header_buffer);
684
685         EM_DEBUG_FUNC_END();
686         return error;
687 }
688
689 INTERNAL_FUNC int emcore_add_mail(char *multi_user_name, 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, int move_flag)
690 {
691         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);
692
693         /* IF an account is being deleted, there is no need to add the mail of the account */
694         int shmid;
695         extern key_t del_account_key; /* in emcore_delete_account */
696         int *del_account_id = NULL;
697         /* get the segment.*/
698
699         if ((shmid = shmget(del_account_key, sizeof(int), 0666)) != -1) {
700                 /* attach the segment to current process space */
701                 if ((del_account_id = (int *)shmat(shmid, NULL, 0)) != (int *)-1) {
702                         /* compare two account ids */
703                         EM_DEBUG_LOG("del_id[%d] account_id[%d]", *del_account_id, input_mail_data->account_id);
704                         if (*del_account_id == input_mail_data->account_id) {
705                                 EM_DEBUG_LOG("SKIP adding mail: the account is being deleted");
706                                 return EMAIL_ERROR_ACCOUNT_NOT_FOUND;
707                         }
708                 }
709         }
710
711         EM_DEBUG_LOG("read del_id[%d], account_id [%d]", (del_account_id ? *del_account_id : -100), input_mail_data->account_id);
712
713         int err = EMAIL_ERROR_NONE;
714         int attachment_id = 0, thread_id = -1, thread_item_count = 0, latest_mail_id_in_thread = -1;
715         int i = 0, rule_len, priority_sender = 0, blocked = 0, local_attachment_count = 0, local_inline_content_count = 0;
716         int mailbox_id_spam = 0, mailbox_id_target = 0;
717         int mail_smime_flag = 0;
718         char name_buf[MAX_PATH] = {0x00, };
719         char path_buf[MAX_PATH] = {0, };
720         char *body_text_file_name = NULL;
721         char *dl_error = NULL;
722         void *dl_handle = NULL;
723         int (*convert_mail_data_to_smime)(char*, emstorage_account_tbl_t*, email_mail_data_t*, email_attachment_data_t*, int, email_mail_data_t**, email_attachment_data_t**, int*);
724
725         int attachment_count = 0;
726         email_mail_data_t *mail_data = NULL;
727         email_attachment_data_t *attachment_data_list = NULL;
728         emstorage_mail_tbl_t    *converted_mail_tbl = NULL;
729         emstorage_mailbox_tbl_t *mailbox_tbl = NULL;
730         emstorage_attachment_tbl_t attachment_tbl = { 0 };
731         emstorage_account_tbl_t *account_tbl_item = NULL;
732         emstorage_rule_tbl_t *rule = NULL;
733         struct stat st_buf = { 0 };
734         char mailbox_id_param_string[10] = {0,};
735         char errno_buf[ERRNO_BUF_SIZE] = {0};
736         int updated_thread_id = 0;
737         char *prefix_path = NULL;
738         char real_file_path[MAX_PATH] = {0};
739
740 #ifdef __FEATURE_BODY_SEARCH__
741         char *stripped_text = NULL;
742 #endif
743
744         /* Validating parameters */
745         if (!input_mail_data || !(input_mail_data->account_id) || !(input_mail_data->mailbox_id)) {
746                 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
747                 err = EMAIL_ERROR_INVALID_PARAM;
748                 goto FINISH_OFF;
749         }
750
751         if ((err = emcore_is_storage_full()) == EMAIL_ERROR_MAIL_MEMORY_FULL) {
752                 EM_DEBUG_EXCEPTION("Storage is full");
753                 goto FINISH_OFF;
754         }
755
756         if (!emstorage_get_account_by_id(multi_user_name, input_mail_data->account_id, EMAIL_ACC_GET_OPT_DEFAULT | EMAIL_ACC_GET_OPT_OPTIONS, &account_tbl_item, true, &err)) {
757                 EM_DEBUG_EXCEPTION("emstorage_get_account_by_id failed. account_id[%d] err[%d]", input_mail_data->account_id, err);
758                 err = EMAIL_ERROR_INVALID_ACCOUNT;
759                 goto FINISH_OFF;
760         }
761
762         if (input_from_eas == 0 && input_mail_data->smime_type && input_mail_data->mailbox_type != EMAIL_MAILBOX_TYPE_DRAFT) {
763                 dl_handle = dlopen("libemail-smime-api.so.1", RTLD_LAZY);
764                 if (!dl_handle) {
765                         EM_DEBUG_EXCEPTION("Open failed : [%p]", dl_handle);
766                         err = EMAIL_ERROR_INVALID_PATH;
767                         goto FINISH_OFF;
768                 }
769
770                 dlerror();
771                 convert_mail_data_to_smime = dlsym(dl_handle, "emcore_convert_mail_data_to_smime_data");
772                 if ((dl_error = dlerror()) != NULL) {
773                         EM_DEBUG_EXCEPTION("Symbol open failed [%d]", err);
774                         err = EMAIL_ERROR_SYSTEM_FAILURE;
775                         goto FINISH_OFF;
776                 }
777
778                 if ((err = convert_mail_data_to_smime(multi_user_name, account_tbl_item, input_mail_data, input_attachment_data_list, input_attachment_count, &mail_data, &attachment_data_list, &attachment_count)) != EMAIL_ERROR_NONE) {
779                         EM_DEBUG_EXCEPTION("S/MIME failed");
780                         goto FINISH_OFF;
781                 }
782
783                 mail_smime_flag = 1;
784         } else {
785                 mail_data = input_mail_data;
786                 attachment_data_list = input_attachment_data_list;
787                 attachment_count = input_attachment_count;
788         }
789
790         mailbox_id_target = mail_data->mailbox_id;
791
792         if (EM_SAFE_STRLEN(multi_user_name) > 0) {
793                 err = emcore_get_container_path(multi_user_name, &prefix_path);
794                 if (err != EMAIL_ERROR_NONE) {
795                         EM_DEBUG_EXCEPTION("emcore_get_container_path failed : [%d]", err);
796                         goto FINISH_OFF;
797                 }
798         } else {
799                 prefix_path = strdup("");
800         }
801
802         if (input_from_eas == 0 &&
803                         !(input_mail_data->message_class & EMAIL_MESSAGE_CLASS_SMART_REPLY) &&
804                         !(input_mail_data->message_class & EMAIL_MESSAGE_CLASS_SMART_FORWARD)) {
805                 if (mail_data->file_path_plain) {
806                         memset(real_file_path, 0x00, sizeof(real_file_path));
807                         SNPRINTF(real_file_path, sizeof(real_file_path), "%s%s", prefix_path, mail_data->file_path_plain);
808
809                         if (stat(real_file_path, &st_buf) < 0) {
810                                 EM_DEBUG_EXCEPTION_SEC("mail_data->file_path_plain, stat(\"%s\") failed...", mail_data->file_path_plain);
811                                 EM_DEBUG_EXCEPTION("%s", EM_STRERROR(errno_buf));
812                                 err = EMAIL_ERROR_INVALID_MAIL;
813                                 goto FINISH_OFF;
814                         }
815                 }
816
817                 if (mail_data->file_path_html) {
818                         memset(real_file_path, 0x00, sizeof(real_file_path));
819                         SNPRINTF(real_file_path, sizeof(real_file_path), "%s%s", prefix_path, mail_data->file_path_html);
820
821                         if (stat(real_file_path, &st_buf) < 0) {
822                                 EM_DEBUG_EXCEPTION_SEC("mail_data->file_path_html, stat(\"%s\") failed...", mail_data->file_path_html);
823                                 EM_DEBUG_EXCEPTION("%s", EM_STRERROR(errno_buf));
824                                 err = EMAIL_ERROR_INVALID_MAIL;
825                                 goto FINISH_OFF;
826                         }
827                 }
828
829                 if (attachment_count && attachment_data_list) {
830                         for (i = 0; i < attachment_count; i++) {
831                                 if (attachment_data_list[i].save_status) {
832                                         memset(real_file_path, 0x00, sizeof(real_file_path));
833                                         SNPRINTF(real_file_path, sizeof(real_file_path), "%s%s", prefix_path, attachment_data_list[i].attachment_path);
834
835                                         if (!attachment_data_list[i].attachment_path || stat(real_file_path, &st_buf) < 0) {
836                                                 EM_DEBUG_EXCEPTION("stat(\"%s\") failed...", attachment_data_list[i].attachment_path);
837                                                 err = EMAIL_ERROR_INVALID_ATTACHMENT;
838                                                 goto FINISH_OFF;
839                                         }
840                                 }
841                         }
842                 }
843
844                 if (!input_mail_data->full_address_from)
845                         input_mail_data->full_address_from = EM_SAFE_STRDUP(account_tbl_item->user_email_address);
846
847                 /* check for email_address validation */
848                 if ((err = em_verify_email_address_of_mail_data(mail_data)) != EMAIL_ERROR_NONE) {
849                         EM_DEBUG_EXCEPTION("em_verify_email_address_of_mail_data failed [%d]", err);
850                         goto FINISH_OFF;
851                 }
852
853                 if (mail_data->report_status & EMAIL_MAIL_REPORT_MDN) {
854                         /* check read-report mail */
855                         if (!mail_data->full_address_to) { /* A report mail should have 'to' address */
856                                 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
857                                 err = EMAIL_ERROR_INVALID_PARAM;
858                                 goto FINISH_OFF;
859                         }
860                         /* Create report mail body */
861                         /*
862                            if (!emcore_make_rfc822_file_from_mail(multi_user_name, mail_src, NULL, NULL, NULL, &err)) {
863                            EM_DEBUG_EXCEPTION("emcore_make_rfc822_file_from_mail failed [%d]", err);
864                            goto FINISH_OFF;
865                            }
866                            */
867                 }
868         } else {        /*  For Spam handling */
869                 email_option_t *opt = &account_tbl_item->options;
870                 EM_DEBUG_LOG_SEC("block_address [%d], block_subject [%d]", opt->block_address, opt->block_subject);
871
872                 /* For eas moving from spambox to other mailbox */
873                 if (mail_data->save_status != EMAIL_MAIL_STATUS_SAVED) {
874                         if (opt->block_address || opt->block_subject) {
875                                 int is_completed = false;
876                                 int type = 0;
877
878                                 if (!opt->block_address)
879                                         type = EMAIL_FILTER_SUBJECT;
880                                 else if (!opt->block_subject)
881                                         type = EMAIL_FILTER_FROM;
882
883                                 if (!emstorage_get_rule(multi_user_name, ALL_ACCOUNT, type, 0, &rule_len, &is_completed, &rule, true, &err) || !rule)
884                                         EM_DEBUG_LOG("No proper rules. emstorage_get_rule returns [%d]", err);
885
886                                 if (rule
887                                                 && !emcore_check_rule(mail_data->full_address_from, mail_data->subject, rule, rule_len, &priority_sender, &blocked, &err)) {
888                                         EM_DEBUG_EXCEPTION("emcore_check_rule failed [%d]", err);
889                                 }
890
891                                 if (priority_sender)
892                                         mail_data->tag_id = PRIORITY_SENDER_TAG_ID;
893
894                                 if (blocked && (mail_data->mailbox_type == EMAIL_MAILBOX_TYPE_INBOX)) {
895                                         EM_DEBUG_LOG("mail[%d] added to spambox", mail_data->mail_id);
896                                         if (!emstorage_get_mailbox_id_by_mailbox_type(multi_user_name, mail_data->account_id, EMAIL_MAILBOX_TYPE_SPAMBOX, &mailbox_id_spam, false, &err)) {
897                                                 EM_DEBUG_EXCEPTION("emstorage_get_mailbox_name_by_mailbox_type failed [%d]", err);
898                                                 mailbox_id_spam = 0;
899                                         }
900
901                                         if (mailbox_id_spam)
902                                                 mailbox_id_target = mailbox_id_spam;
903                                 }
904                         }
905                 }
906         }
907
908         if ((err = emstorage_get_mailbox_by_id(multi_user_name, mailbox_id_target, (emstorage_mailbox_tbl_t**)&mailbox_tbl)) != EMAIL_ERROR_NONE) {
909                 EM_DEBUG_EXCEPTION("emstorage_get_mailbox_by_id failed [%d]", err);
910                 goto FINISH_OFF;
911         }
912
913         if (!emstorage_increase_mail_id(multi_user_name, &mail_data->mail_id, true, &err)) {
914                 EM_DEBUG_EXCEPTION("emstorage_increase_mail_id failed [%d]", err);
915                 goto FINISH_OFF;
916         }
917
918         EM_DEBUG_LOG("mail_data->mail_size [%d]", mail_data->mail_size);
919
920         if (mail_data->mail_size == 0)
921                 emcore_calc_mail_size(multi_user_name, mail_data, attachment_data_list, attachment_count, &(mail_data->mail_size)); /*  Getting file size before file moved.  */
922
923         EM_DEBUG_LOG("input_from_eas [%d] mail_data->body_download_status [%d]", input_from_eas, mail_data->body_download_status);
924
925         if (input_from_eas == 0 || mail_data->body_download_status) {
926                 if (!emstorage_create_dir(multi_user_name, mail_data->account_id, mail_data->mail_id, 0, &err)) {
927                         EM_DEBUG_EXCEPTION("emstorage_create_dir failed [%d]", err);
928                         goto FINISH_OFF;
929                 }
930
931                 if (mail_data->file_path_plain) {
932                         memset(name_buf, 0x00, sizeof(name_buf));
933                         memset(path_buf, 0x00, sizeof(path_buf));
934                         memset(real_file_path, 0x00, sizeof(real_file_path));
935                         SNPRINTF(real_file_path, sizeof(real_file_path), "%s%s", prefix_path, mail_data->file_path_plain);
936
937                         EM_DEBUG_LOG_SEC("mail_data->file_path_plain [%s]", mail_data->file_path_plain);
938                         /* EM_SAFE_STRNCPY(body_text_file_name, "UTF-8", MAX_PATH); */
939
940                         if ((err = em_get_file_name_from_file_path(real_file_path, &body_text_file_name)) != EMAIL_ERROR_NONE) {
941                                 EM_DEBUG_EXCEPTION("em_get_file_name_from_file_path failed [%d]", err);
942                                 err = EMAIL_ERROR_INVALID_FILE_PATH;
943                                 goto FINISH_OFF;
944                         }
945
946                         /*
947                            if (input_from_eas)
948                            EM_SAFE_STRNCPY(body_text_file_name, UNKNOWN_CHARSET_PLAIN_TEXT_FILE, MAX_PATH);
949                            else
950                            EM_SAFE_STRNCPY(body_text_file_name, "UTF-8", MAX_PATH);
951                            */
952
953                         if (!emstorage_get_save_name(multi_user_name, mail_data->account_id, mail_data->mail_id,
954                                                 0, body_text_file_name, name_buf, path_buf,
955                                                 sizeof(path_buf), &err)) {
956                                 EM_DEBUG_EXCEPTION("emstorage_get_save_name failed [%d]", err);
957                                 goto FINISH_OFF;
958                         }
959
960                         if (!emstorage_move_file(real_file_path, name_buf, input_from_eas, &err)) {
961                                 EM_DEBUG_EXCEPTION("emstorage_move_file failed [%d]", err);
962                                 goto FINISH_OFF;
963                         }
964                         if (!mail_data->body_download_status)
965                                 mail_data->body_download_status = EMAIL_BODY_DOWNLOAD_STATUS_FULLY_DOWNLOADED;
966
967                         EM_SAFE_FREE(mail_data->file_path_plain);
968                         mail_data->file_path_plain = EM_SAFE_STRDUP(path_buf);
969                 }
970
971                 if (mail_data->file_path_html) {
972                         memset(name_buf, 0x00, sizeof(name_buf));
973                         memset(path_buf, 0x00, sizeof(path_buf));
974                         memset(real_file_path, 0x00, sizeof(real_file_path));
975                         SNPRINTF(real_file_path, sizeof(real_file_path), "%s%s", prefix_path, mail_data->file_path_html);
976
977                         EM_DEBUG_LOG_SEC("mail_data->file_path_html [%s]", mail_data->file_path_html);
978                         /* EM_SAFE_STRNCPY(body_text_file_name, "UTF-8.htm", MAX_PATH); */
979
980                         EM_SAFE_FREE(body_text_file_name);
981
982                         if ((err = em_get_file_name_from_file_path(real_file_path, &body_text_file_name)) != EMAIL_ERROR_NONE) {
983                                 EM_DEBUG_EXCEPTION("em_get_file_name_from_file_path failed [%d]", err);
984                                 err = EMAIL_ERROR_INVALID_FILE_PATH;
985                                 goto FINISH_OFF;
986                         }
987                         /*
988                            if (input_from_eas)
989                            EM_SAFE_STRNCPY(body_text_file_name, UNKNOWN_CHARSET_HTML_TEXT_FILE, MAX_PATH);
990                            else
991                            EM_SAFE_STRNCPY(body_text_file_name, "UTF-8.htm", MAX_PATH);
992                            */
993
994                         if (!emstorage_get_save_name(multi_user_name, mail_data->account_id, mail_data->mail_id,
995                                                 0, body_text_file_name, name_buf, path_buf,
996                                                 sizeof(path_buf), &err)) {
997                                 EM_DEBUG_EXCEPTION("emstorage_get_save_name failed [%d]", err);
998                                 goto FINISH_OFF;
999                         }
1000
1001                         if (!emstorage_move_file(real_file_path, name_buf, input_from_eas, &err)) {
1002                                 EM_DEBUG_EXCEPTION("emstorage_move_file failed [%d]", err);
1003                                 goto FINISH_OFF;
1004                         }
1005
1006                         if (!mail_data->body_download_status)
1007                                 mail_data->body_download_status = EMAIL_BODY_DOWNLOAD_STATUS_FULLY_DOWNLOADED;
1008
1009                         EM_SAFE_FREE(mail_data->file_path_html);
1010                         mail_data->file_path_html = EM_SAFE_STRDUP(path_buf);
1011                 }
1012         }
1013
1014         if (mail_data->file_path_mime_entity) {
1015                 memset(name_buf, 0x00, sizeof(name_buf));
1016                 memset(path_buf, 0x00, sizeof(path_buf));
1017                 memset(real_file_path, 0x00, sizeof(real_file_path));
1018                 SNPRINTF(real_file_path, sizeof(real_file_path), "%s%s", prefix_path, mail_data->file_path_mime_entity);
1019
1020                 EM_DEBUG_LOG_SEC("mail_data->file_path_mime_entity [%s]", mail_data->file_path_mime_entity);
1021
1022                 if (!emstorage_get_save_name(multi_user_name, mail_data->account_id, mail_data->mail_id,
1023                                         0, "mime_entity", name_buf, path_buf,
1024                                         sizeof(path_buf), &err)) {
1025                         EM_DEBUG_EXCEPTION("emstorage_get_save_name failed [%d]", err);
1026                         goto FINISH_OFF;
1027                 }
1028
1029                 if (!emstorage_move_file(real_file_path, name_buf, input_from_eas, &err)) {
1030                         EM_DEBUG_EXCEPTION("emstorage_move_file failed [%d]", err);
1031                         goto FINISH_OFF;
1032                 }
1033
1034                 EM_SAFE_FREE(mail_data->file_path_mime_entity);
1035                 mail_data->file_path_mime_entity = EM_SAFE_STRDUP(path_buf);
1036         }
1037
1038         if (!mail_data->date_time) {
1039                 /* time isn't set */
1040                 mail_data->date_time = time(NULL);
1041         }
1042
1043         /* Generate message_id */
1044         if (!input_from_eas) {
1045                 mail_data->message_id     = emcore_generate_content_id_string("org.tizen.email", NULL);
1046                 mail_data->server_mail_id = strdup("0");
1047         }
1048
1049         mail_data->mailbox_id           = mailbox_id_target;
1050         mail_data->mailbox_type         = mailbox_tbl->mailbox_type;
1051         mail_data->server_mail_status   = !input_from_eas;
1052         if (mail_data->save_status == EMAIL_MAIL_STATUS_NONE)
1053                 mail_data->save_status      = EMAIL_MAIL_STATUS_SAVED;
1054
1055         /*  Getting attachment count */
1056         for (i = 0; i < attachment_count; i++) {
1057                 if (attachment_data_list[i].inline_content_status == 1)
1058                         local_inline_content_count++;
1059                 else
1060                         local_attachment_count++;
1061         }
1062
1063         mail_data->inline_content_count = local_inline_content_count;
1064         mail_data->attachment_count     = local_attachment_count;
1065
1066         EM_DEBUG_LOG("inline_content_count   [%d]", local_inline_content_count);
1067         EM_DEBUG_LOG("attachment_count [%d]", local_attachment_count);
1068
1069         EM_DEBUG_LOG("preview_text[%p]", mail_data->preview_text);
1070         if (mail_data->preview_text == NULL) {
1071                 if ((err = emcore_get_preview_text_from_file(multi_user_name,
1072                                                 mail_data->file_path_plain,
1073                                                 mail_data->file_path_html,
1074                                                 MAX_PREVIEW_TEXT_LENGTH,
1075                                                 &(mail_data->preview_text))) != EMAIL_ERROR_NONE) {
1076                         EM_DEBUG_EXCEPTION("emcore_get_preview_text_from_file failed[%d]", err);
1077
1078                         if (err != EMAIL_ERROR_EMPTY_FILE)
1079                                 goto FINISH_OFF;
1080                 }
1081         }
1082
1083         if (!em_convert_mail_data_to_mail_tbl(mail_data, 1, &converted_mail_tbl, &err)) {
1084                 EM_DEBUG_EXCEPTION("em_convert_mail_data_to_mail_tbl failed [%d]", err);
1085                 goto FINISH_OFF;
1086         }
1087
1088         converted_mail_tbl->mailbox_id        = mailbox_tbl->mailbox_id;
1089
1090         /* Fill address information */
1091         emcore_fill_address_information_of_mail_tbl(multi_user_name, converted_mail_tbl);
1092
1093         /* Fill thread id */
1094         if (mail_data->thread_id == 0) {
1095                 if (emstorage_get_thread_id_of_thread_mails(multi_user_name, converted_mail_tbl, &thread_id, &latest_mail_id_in_thread, &thread_item_count) != EMAIL_ERROR_NONE)
1096                         EM_DEBUG_LOG(" emstorage_get_thread_id_of_thread_mails is failed");
1097
1098                 if (thread_id == -1) {
1099                         converted_mail_tbl->thread_id         = mail_data->mail_id;
1100                         converted_mail_tbl->thread_item_count = thread_item_count = 1;
1101                 } else {
1102                         converted_mail_tbl->thread_id         = thread_id;
1103                         thread_item_count++;
1104                 }
1105         } else {
1106                 thread_item_count                         = 2;
1107         }
1108
1109         mail_data->thread_id = converted_mail_tbl->thread_id;
1110         converted_mail_tbl->user_name = EM_SAFE_STRDUP(account_tbl_item->user_name);
1111
1112         if (!emstorage_begin_transaction(multi_user_name, NULL, NULL, NULL)) {
1113                 EM_DEBUG_EXCEPTION("emstorage_begin_transaction failed");
1114                 goto FINISH_OFF;
1115         }
1116
1117         /*  insert mail to mail table */
1118         if (!emstorage_add_mail(multi_user_name, converted_mail_tbl, 0, false, &err)) {
1119                 EM_DEBUG_EXCEPTION("emstorage_add_mail failed [%d]", err);
1120                 /*  ROLLBACK TRANSACTION; */
1121                 emstorage_rollback_transaction(multi_user_name, NULL, NULL, NULL);
1122                 goto FINISH_OFF;
1123         }
1124
1125         /* Update thread information */
1126         EM_DEBUG_LOG("thread_item_count [%d]", thread_item_count);
1127
1128         if (thread_item_count > 1) {
1129                 if (!emstorage_update_latest_thread_mail(multi_user_name,
1130                                         mail_data->account_id,
1131                                         mail_data->mailbox_id,
1132                                         mail_data->mailbox_type,
1133                                         converted_mail_tbl->thread_id,
1134                                         &updated_thread_id,
1135                                         0,
1136                                         0,
1137                                         NOTI_THREAD_ID_CHANGED_BY_ADD,
1138                                         false,
1139                                         &err)) {
1140                         EM_DEBUG_EXCEPTION("emstorage_update_latest_thread_mail failed [%d]", err);
1141                         emstorage_rollback_transaction(multi_user_name, NULL, NULL, NULL);
1142                         goto FINISH_OFF;
1143                 }
1144
1145                 if (updated_thread_id > 0)
1146                         input_mail_data->thread_id = updated_thread_id;
1147         }
1148
1149         /*  Insert attachment information to DB */
1150
1151         for (i = 0; i < attachment_count; i++) {
1152                 memset(name_buf, 0x00, sizeof(name_buf));
1153                 memset(path_buf, 0x00, sizeof(path_buf));
1154
1155                 /* set attachment size */
1156                 memset(real_file_path, 0x00, sizeof(real_file_path));
1157                 SNPRINTF(real_file_path, sizeof(real_file_path), "%s%s", prefix_path, attachment_data_list[i].attachment_path);
1158
1159                 if (attachment_data_list[i].attachment_size == 0) {
1160                         if (attachment_data_list[i].attachment_path && stat(real_file_path, &st_buf) < 0)
1161                                 attachment_data_list[i].attachment_size = st_buf.st_size;
1162                 }
1163
1164                 if (!attachment_data_list[i].inline_content_status) {
1165                         if (!emstorage_get_new_attachment_no(multi_user_name, &attachment_id, &err)) {
1166                                 EM_DEBUG_EXCEPTION("emstorage_get_new_attachment_no failed [%d]", err);
1167                                 emstorage_rollback_transaction(multi_user_name, NULL, NULL, NULL);
1168                                 goto FINISH_OFF;
1169                         }
1170                 }
1171
1172                 if (!emstorage_create_dir(multi_user_name, mail_data->account_id, mail_data->mail_id, attachment_data_list[i].inline_content_status ? 0  :  attachment_id, &err)) {
1173                         EM_DEBUG_EXCEPTION("emstorage_create_dir failed [%d]", err);
1174                         emstorage_rollback_transaction(multi_user_name, NULL, NULL, NULL);
1175                         goto FINISH_OFF;
1176                 }
1177
1178                 if (!emstorage_get_save_name(multi_user_name,
1179                                         mail_data->account_id,
1180                                         mail_data->mail_id, attachment_data_list[i].inline_content_status ? 0  :  attachment_id,
1181                                         attachment_data_list[i].attachment_name,
1182                                         name_buf,
1183                                         path_buf,
1184                                         sizeof(path_buf),
1185                                         &err)) {
1186                         EM_DEBUG_EXCEPTION("emstorage_get_save_name failed [%d]", err);
1187                         emstorage_rollback_transaction(multi_user_name, NULL, NULL, NULL);
1188                         goto FINISH_OFF;
1189                 }
1190                 /* if (input_from_eas == 0 || attachment_data_list[i].save_status) { */
1191                 if (attachment_data_list[i].save_status) {
1192                         if (attachment_data_list[i].attachment_mime_type && strcasestr(attachment_data_list[i].attachment_mime_type, "PKCS7")) {
1193                                 if (!emstorage_move_file(real_file_path, name_buf, input_from_eas, &err)) {
1194                                         EM_DEBUG_EXCEPTION("emstorage_move_file failed [%d]", err);
1195                                         emstorage_rollback_transaction(multi_user_name, NULL, NULL, NULL);
1196                                         goto FINISH_OFF;
1197                                 }
1198                         } else {
1199                                 if (!emstorage_copy_file(real_file_path, name_buf, input_from_eas, &err)) {
1200                                         EM_DEBUG_EXCEPTION("emstorage_copy_file failed [%d]", err);
1201                                         emstorage_rollback_transaction(multi_user_name, NULL, NULL, NULL);
1202                                         goto FINISH_OFF;
1203                                 }
1204                         }
1205                 }
1206
1207                 memset(&attachment_tbl, 0, sizeof(emstorage_attachment_tbl_t));
1208                 attachment_tbl.attachment_name                  = attachment_data_list[i].attachment_name;
1209                 attachment_tbl.attachment_path                  = path_buf;
1210                 attachment_tbl.attachment_size                  = attachment_data_list[i].attachment_size;
1211                 attachment_tbl.mail_id                          = mail_data->mail_id;
1212                 attachment_tbl.account_id                       = mail_data->account_id;
1213                 attachment_tbl.mailbox_id                       = mail_data->mailbox_id;
1214                 attachment_tbl.attachment_save_status           = attachment_data_list[i].save_status;
1215                 attachment_tbl.attachment_drm_type              = attachment_data_list[i].drm_status;
1216                 attachment_tbl.attachment_inline_content_status = attachment_data_list[i].inline_content_status;
1217                 attachment_tbl.attachment_mime_type             = attachment_data_list[i].attachment_mime_type;
1218                 attachment_tbl.content_id                       = attachment_data_list[i].content_id;
1219
1220                 if (!emstorage_add_attachment(multi_user_name, &attachment_tbl, 0, false, &err)) {
1221                         EM_DEBUG_EXCEPTION("emstorage_add_attachment failed [%d]", err);
1222                         emstorage_rollback_transaction(multi_user_name, NULL, NULL, NULL);
1223                         goto FINISH_OFF;
1224                 }
1225
1226                 if (!mail_smime_flag)
1227                         attachment_data_list[i].attachment_id = attachment_tbl.attachment_id;
1228         }
1229
1230 #ifdef __FEATURE_BODY_SEARCH__
1231         /* Insert mail_text to DB */
1232         if (!emcore_strip_mail_body_from_file(multi_user_name, converted_mail_tbl, &stripped_text, &err)
1233                         || stripped_text == NULL) {
1234                 EM_DEBUG_EXCEPTION("emcore_strip_mail_body_from_file failed [%d]", err);
1235         }
1236
1237         if (!emcore_add_mail_text(multi_user_name, mailbox_tbl, converted_mail_tbl, stripped_text, &err)) {
1238                 EM_DEBUG_EXCEPTION("emcore_add_mail_text failed [%d]", err);
1239                 emstorage_rollback_transaction(multi_user_name, NULL, NULL, NULL);
1240                 goto FINISH_OFF;
1241         }
1242 #endif
1243
1244         /*  Insert Meeting request to DB */
1245         if (mail_data->meeting_request_status == EMAIL_MAIL_TYPE_MEETING_REQUEST
1246                         || mail_data->meeting_request_status == EMAIL_MAIL_TYPE_MEETING_RESPONSE
1247                         || mail_data->meeting_request_status == EMAIL_MAIL_TYPE_MEETING_ORIGINATINGREQUEST) {
1248                 EM_DEBUG_LOG("This mail has the meeting request");
1249                 input_meeting_request->mail_id = mail_data->mail_id;
1250
1251                 if (!emstorage_add_meeting_request(multi_user_name, mail_data->account_id, mailbox_tbl->mailbox_id, input_meeting_request, false, &err)) {
1252                         EM_DEBUG_EXCEPTION("emstorage_add_meeting_request failed [%d]", err);
1253                         emstorage_rollback_transaction(multi_user_name, NULL, NULL, NULL);
1254                         goto FINISH_OFF;
1255                 }
1256         }
1257
1258         emstorage_commit_transaction(multi_user_name, NULL, NULL, NULL);
1259
1260         if (emstorage_get_thread_id_of_thread_mails(multi_user_name, converted_mail_tbl, &thread_id, &latest_mail_id_in_thread, &thread_item_count) != EMAIL_ERROR_NONE)
1261                 EM_DEBUG_LOG(" emstorage_get_thread_id_of_thread_mails is failed.");
1262
1263         SNPRINTF(mailbox_id_param_string, 10, "%d", mailbox_tbl->mailbox_id);
1264         if (!emcore_notify_storage_event(NOTI_MAIL_ADD, converted_mail_tbl->account_id, converted_mail_tbl->mail_id, mailbox_id_param_string, thread_id))
1265                 EM_DEBUG_LOG("emcore_notify_storage_event[NOTI_MAIL_ADD] failed.");
1266
1267         if (account_tbl_item->incoming_server_type != EMAIL_SERVER_TYPE_ACTIVE_SYNC && !move_flag) {
1268                 if (!emcore_remove_overflowed_mails(multi_user_name, mailbox_tbl, &err)) {
1269                         if (err == EMAIL_ERROR_MAIL_NOT_FOUND || err == EMAIL_ERROR_NOT_SUPPORTED)
1270                                 err = EMAIL_ERROR_NONE;
1271                         else
1272                                 EM_DEBUG_LOG("emcore_remove_overflowed_mails failed [%d]", err);
1273                 }
1274         }
1275
1276         if (input_from_eas && (mail_data->flags_seen_field == 0)) {
1277                 // && mail_data->mailbox_type != EMAIL_MAILBOX_TYPE_TRASH
1278                 // && mail_data->mailbox_type != EMAIL_MAILBOX_TYPE_SPAMBOX) {
1279                 if ((err = emcore_update_sync_status_of_account(multi_user_name, mail_data->account_id, SET_TYPE_SET, SYNC_STATUS_SYNCING | SYNC_STATUS_HAVE_NEW_MAILS)) != EMAIL_ERROR_NONE)
1280                         EM_DEBUG_LOG("emcore_update_sync_status_of_account failed [%d]", err);
1281         }
1282
1283 FINISH_OFF:
1284         if (dl_handle)
1285                 dlclose(dl_handle);
1286
1287         EM_SAFE_FREE(body_text_file_name);
1288         EM_SAFE_FREE(prefix_path);
1289
1290 #ifdef __FEATURE_BODY_SEARCH__
1291         EM_SAFE_FREE(stripped_text);
1292 #endif
1293
1294         if (mail_smime_flag)
1295                 emcore_free_attachment_data(&attachment_data_list, attachment_count, NULL);
1296
1297         if (account_tbl_item)
1298                 emstorage_free_account(&account_tbl_item, 1, NULL);
1299
1300         if (mailbox_tbl)
1301                 emstorage_free_mailbox(&mailbox_tbl, 1, NULL);
1302
1303         if (converted_mail_tbl)
1304                 emstorage_free_mail(&converted_mail_tbl, 1, NULL);
1305
1306         EM_DEBUG_FUNC_END();
1307         return err;
1308 }
1309
1310 INTERNAL_FUNC int emcore_add_read_receipt(char *multi_user_name, int input_read_mail_id, int *output_receipt_mail_id)
1311 {
1312         EM_DEBUG_FUNC_BEGIN("input_read_mail_id [%d], output_receipt_mail_id [%p]", input_read_mail_id, output_receipt_mail_id);
1313         int                      err = EMAIL_ERROR_NONE;
1314         int                      attachment_count = 0;
1315         ENVELOPE                *envelope = NULL;
1316         email_mail_data_t       *read_mail_data = NULL;
1317         email_mail_data_t       *receipt_mail_data = NULL;
1318         emstorage_mail_tbl_t    *receipt_mail_tbl_data = NULL;
1319         email_attachment_data_t *attachment_data = NULL;
1320         emstorage_mailbox_tbl_t *mailbox_tbl = NULL;
1321         BODY                    *root_body = NULL;
1322
1323         if ((err = emcore_get_mail_data(multi_user_name, input_read_mail_id, &read_mail_data)) != EMAIL_ERROR_NONE) {
1324                 EM_DEBUG_EXCEPTION("emcore_get_mail_data failed [%d]", err);
1325                 goto FINISH_OFF;
1326         }
1327
1328         receipt_mail_data = em_malloc(sizeof(email_mail_data_t));
1329
1330         if (!receipt_mail_data) {
1331                 EM_DEBUG_EXCEPTION("em_mallocfailed...");
1332                 err = EMAIL_ERROR_OUT_OF_MEMORY;
1333                 goto FINISH_OFF;
1334         }
1335
1336         memcpy(receipt_mail_data, read_mail_data, sizeof(email_mail_data_t));
1337
1338         receipt_mail_data->full_address_to = EM_SAFE_STRDUP(read_mail_data->full_address_from);
1339         receipt_mail_data->message_id      = EM_SAFE_STRDUP(read_mail_data->message_id);
1340
1341         if (read_mail_data->subject) {
1342                 receipt_mail_data->subject = em_malloc(EM_SAFE_STRLEN(read_mail_data->subject) + 7);
1343                 if (!(receipt_mail_data->subject)) {
1344                         EM_DEBUG_EXCEPTION("em_mallocfailed...");
1345                         err = EMAIL_ERROR_OUT_OF_MEMORY;
1346                         goto FINISH_OFF;
1347                 }
1348
1349                 SNPRINTF(receipt_mail_data->subject, EM_SAFE_STRLEN(read_mail_data->subject) + 7,  "Read: %s", read_mail_data->subject);
1350         }
1351
1352         if (!emstorage_get_mailbox_by_mailbox_type(multi_user_name, receipt_mail_data->account_id, EMAIL_MAILBOX_TYPE_OUTBOX, &mailbox_tbl, true, &err)) {
1353                 EM_DEBUG_EXCEPTION("emstorage_get_mailbox_name_by_mailbox_type failed [%d]", err);
1354                 goto FINISH_OFF;
1355         }
1356
1357         receipt_mail_data->mailbox_id           = mailbox_tbl->mailbox_id;
1358         receipt_mail_data->mailbox_type         = EMAIL_MAILBOX_TYPE_OUTBOX;
1359         receipt_mail_data->file_path_html       = NULL;
1360         receipt_mail_data->flags_draft_field    = 1;
1361         receipt_mail_data->body_download_status = 1;
1362         receipt_mail_data->save_status          = (unsigned char)EMAIL_MAIL_STATUS_SENDING;
1363         receipt_mail_data->report_status        = (unsigned char)EMAIL_MAIL_REPORT_MDN;
1364
1365         if (!em_convert_mail_data_to_mail_tbl(receipt_mail_data, 1, &receipt_mail_tbl_data, &err)) {
1366                 EM_DEBUG_EXCEPTION("em_convert_mail_data_to_mail_tbl failed [%d]", err);
1367                 goto FINISH_OFF;
1368         }
1369
1370         if ((err = emcore_make_envelope_from_mail(multi_user_name, receipt_mail_tbl_data, &envelope)) != EMAIL_ERROR_NONE) {
1371                 EM_DEBUG_EXCEPTION("emcore_make_envelope_from_mail failed [%d]", err);
1372                 goto FINISH_OFF;
1373         }
1374
1375         envelope->references = EM_SAFE_STRDUP(read_mail_data->message_id);
1376
1377         if (!emcore_get_report_mail_body(multi_user_name, envelope, &root_body, &err)) {
1378                 EM_DEBUG_EXCEPTION("emcore_get_report_mail_body failed [%d]", err);
1379                 goto FINISH_OFF;
1380         }
1381
1382         receipt_mail_data->file_path_plain  = EM_SAFE_STRDUP(root_body->nested.part->body.sparep);
1383
1384         /* Report attachment */
1385         /* Final-Recipient :  rfc822;digipop@gmail.com
1386            Original-Message-ID:  <r97a77ag0jdhkvvxke58u9i5.1345611508570@email.android.com>
1387 Disposition :  manual-action/MDN-sent-manually; displayed */
1388
1389         /*
1390            receipt_mail_data->attachment_count = 1;
1391            attachment_count                    = 1;
1392
1393            attachment_data = em_malloc(sizeof(email_attachment_data_t));
1394            if (!attachment_data) {
1395            EM_DEBUG_EXCEPTION("em_mallocfailed...");
1396            err = EMAIL_ERROR_OUT_OF_MEMORY;
1397            goto FINISH_OFF;
1398            }
1399
1400            attachment_data->save_status     = 1;
1401            attachment_data->attachment_path = EM_SAFE_STRDUP(root_body->nested.part->next->body.sparep);
1402
1403            if (!emcore_get_file_name(attachment_data->attachment_path, &p, &err)) {
1404            EM_DEBUG_EXCEPTION("emcore_get_file_name failed [%d]", err);
1405            goto FINISH_OFF;
1406            }
1407
1408            attachment_data->attachment_name = cpystr(p);
1409            */
1410
1411         if ((err = emcore_add_mail(multi_user_name, receipt_mail_data, attachment_data, attachment_count, NULL, 0, false)) != EMAIL_ERROR_NONE) {
1412                 EM_DEBUG_EXCEPTION("emcore_add_mail failed [%d]", err);
1413                 goto FINISH_OFF;
1414         }
1415
1416         *output_receipt_mail_id = receipt_mail_data->mail_id;
1417
1418 FINISH_OFF:
1419         if (receipt_mail_data) {
1420                 EM_SAFE_FREE(receipt_mail_data->full_address_to);
1421                 EM_SAFE_FREE(receipt_mail_data->message_id);
1422                 EM_SAFE_FREE(receipt_mail_data->subject);
1423                 EM_SAFE_FREE(receipt_mail_data);
1424         }
1425
1426         if (mailbox_tbl)
1427                 emstorage_free_mailbox(&mailbox_tbl, 1, NULL);
1428
1429         if (read_mail_data)
1430                 emcore_free_mail_data_list(&read_mail_data, 1);
1431
1432         if (attachment_data)
1433                 emcore_free_attachment_data(&attachment_data, 1, NULL);
1434
1435         if (receipt_mail_tbl_data)
1436                 emstorage_free_mail(&receipt_mail_tbl_data, 1, NULL);
1437
1438         if (root_body)
1439                 mail_free_body(&root_body);
1440
1441         EM_DEBUG_FUNC_END("err [%d]", err);
1442         return err;
1443 }
1444
1445 INTERNAL_FUNC int emcore_add_meeting_request(char *multi_user_name, int account_id, int input_mailbox_id, email_meeting_request_t *meeting_req, int *err_code)
1446 {
1447         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);
1448         int ret = false;
1449         int err = EMAIL_ERROR_NONE;
1450
1451         if (!meeting_req || meeting_req->mail_id <= 0) {
1452                 if (meeting_req)
1453                         EM_DEBUG_EXCEPTION("mail_id[%d]", meeting_req->mail_id);
1454
1455                 err = EMAIL_ERROR_INVALID_PARAM;
1456                 goto FINISH_OFF;
1457         }
1458
1459         if (!emstorage_add_meeting_request(multi_user_name, account_id, input_mailbox_id, meeting_req, 1, &err)) {
1460                 EM_DEBUG_EXCEPTION(" emstorage_add_meeting_request failed [%d]", err);
1461                 goto FINISH_OFF;
1462         }
1463
1464         ret = true;
1465
1466 FINISH_OFF:
1467
1468         if (err_code)
1469                 *err_code = err;
1470
1471         EM_DEBUG_FUNC_END();
1472         return ret;
1473 }
1474
1475 INTERNAL_FUNC int emcore_query_mail_size_limit(char *multi_user_name, int account_id, int handle, int *err_code)
1476 {
1477         EM_DEBUG_FUNC_BEGIN("account_id[%d], err_code[%p]", account_id, err_code);
1478         int ret = false;
1479         int err = EMAIL_ERROR_NONE;
1480         SENDSTREAM *stream = NULL;
1481         void *tmp_stream = NULL;
1482         int mail_size_limit = -1;
1483         email_account_t *ref_account = NULL;
1484         sslstart_t stls = NULL;
1485         MAILSTREAM *mail_stream = NULL;
1486
1487         if (account_id <= 0) {
1488                 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
1489                 err = EMAIL_ERROR_INVALID_PARAM;
1490                 goto FINISH_OFF;
1491         }
1492
1493         if (!(ref_account = emcore_get_account_reference(multi_user_name, account_id, false))) {
1494                 EM_DEBUG_EXCEPTION("emcore_get_account_reference failed [%d]", account_id);
1495                 err = EMAIL_ERROR_INVALID_ACCOUNT;
1496                 goto FINISH_OFF;
1497         }
1498
1499         /*  if there is no security option, unset security. */
1500         if (!ref_account->outgoing_server_secure_connection) {
1501                 stls = (sslstart_t)mail_parameters(NULL, GET_SSLSTART, NULL);
1502                 mail_parameters(NULL, SET_SSLSTART, NULL);
1503         }
1504
1505         if (ref_account->pop_before_smtp != FALSE) {
1506                 if (!emcore_connect_to_remote_mailbox(multi_user_name,
1507                                         account_id,
1508                                         0,
1509                                         true,
1510                                         (void **)&mail_stream,
1511                                         &err)) {
1512                         EM_DEBUG_EXCEPTION(" POP before SMTP Authentication failed [%d]", err);
1513                         goto FINISH_OFF;
1514                 }
1515         }
1516
1517         if (!emcore_connect_to_remote_mailbox(multi_user_name,
1518                                 account_id,
1519                                 EMAIL_CONNECT_FOR_SENDING,
1520                                 true,
1521                                 (void **)&tmp_stream,
1522                                 &err)) {
1523                 EM_DEBUG_EXCEPTION(" emcore_connect_to_remote_mailbox failed [%d]", err);
1524                 goto FINISH_OFF;
1525         }
1526
1527         stream = (SENDSTREAM *)tmp_stream;
1528
1529         if (stream && stream->protocol.esmtp.ok) {
1530                 if (stream->protocol.esmtp.size.ok && stream->protocol.esmtp.size.limit > 0) {
1531                         EM_DEBUG_LOG("Server size limit : %ld", stream->protocol.esmtp.size.limit);
1532                         mail_size_limit = stream->protocol.esmtp.size.limit;
1533                 }
1534         }
1535
1536         ret = true;
1537
1538 FINISH_OFF:
1539
1540         if (ref_account) {
1541                 emcore_free_account(ref_account);
1542                 EM_SAFE_FREE(ref_account);
1543         }
1544
1545 #ifndef __FEATURE_KEEP_CONNECTION__
1546         if (stream)
1547                 smtp_close(stream);
1548 #endif /* __FEATURE_KEEP_CONNECTION__ */
1549
1550         if (mail_stream)
1551                 mail_stream = mail_close(mail_stream);
1552
1553         if (stls)
1554                 mail_parameters(NULL, SET_SSLSTART, (void  *)stls);
1555
1556         if (ret == true) {
1557                 if (!emcore_notify_network_event(NOTI_QUERY_SMTP_MAIL_SIZE_LIMIT_FINISH, account_id, NULL, mail_size_limit, handle))
1558                         EM_DEBUG_EXCEPTION("emcore_notify_network_event[NOTI_QUERY_SMTP_MAIL_SIZE_LIMIT_FINISH] Failed");
1559         } else {
1560                 if (!emcore_notify_network_event(NOTI_QUERY_SMTP_MAIL_SIZE_LIMIT_FAIL, account_id, NULL, handle, err))
1561                         EM_DEBUG_EXCEPTION("emcore_notify_network_event[NOTI_QUERY_SMTP_MAIL_SIZE_LIMIT_FAIL] Failed");
1562         }
1563
1564         if (err_code != NULL)
1565                 *err_code = err;
1566
1567         EM_DEBUG_FUNC_END("ret [%d], err [%d]", ret, err);
1568         return ret;
1569 }
1570
1571 /* thread local variable for reuse */
1572 __thread GList *g_send_stream_list = NULL;
1573 typedef struct {
1574         int account_id;
1575         SENDSTREAM **send_stream;
1576 } email_send_stream_list_t;
1577
1578 /*
1579    stmp stream should be closed when threads exit, otherwise memory leaks
1580    */
1581 INTERNAL_FUNC void emcore_close_smtp_stream_list()
1582 {
1583         EM_DEBUG_FUNC_BEGIN();
1584         GList *cur = g_send_stream_list;
1585         email_send_stream_list_t *data = NULL;
1586
1587         while (cur) {
1588                 data = cur->data;
1589                 if (data) *(data->send_stream) = smtp_close(*(data->send_stream));
1590                 g_send_stream_list = g_list_delete_link(g_send_stream_list, cur);
1591                 g_free(data);
1592                 cur = g_send_stream_list;
1593         }
1594
1595         EM_DEBUG_FUNC_END();
1596 }
1597
1598 /*
1599    if threads exit after calling the function, emcore_close_smtp_stream_list should be called.
1600    Otherwise, memory leaks
1601    */
1602 INTERNAL_FUNC SENDSTREAM **emcore_get_smtp_stream(char *multi_user_name, int account_id, int *error)
1603 {
1604         EM_DEBUG_FUNC_BEGIN("account_id[%d]", account_id);
1605         GList *cur = g_send_stream_list;
1606         email_send_stream_list_t *data = NULL;
1607         SENDSTREAM **ret = NULL;
1608         int err = EMAIL_ERROR_NONE;
1609
1610         for (; cur ; cur = g_list_next(cur)) {
1611                 data = cur->data;
1612                 if (data->account_id == account_id) {
1613                         if (data->send_stream == NULL || *(data->send_stream) == NULL) {
1614                                 EM_DEBUG_LOG("smtp_stream was closed before");
1615                                 g_send_stream_list = g_list_delete_link(g_send_stream_list, cur);
1616                                 g_free(data);
1617                                 break;
1618                         }
1619
1620                         int reply = smtp_send(*(data->send_stream), "NOOP", NULL);
1621                         if (reply/100 == 2) { /* 2xx means a success */
1622                                 EM_DEBUG_LOG("reusable smtp_stream found");
1623                                 return data->send_stream;
1624                         } else {
1625                                 EM_DEBUG_LOG("smtp_stream is not reusable");
1626                                 *(data->send_stream) = smtp_close(*(data->send_stream));
1627                                 g_send_stream_list = g_list_delete_link(g_send_stream_list, cur);
1628                                 g_free(data->send_stream);
1629                                 break;
1630                         }
1631                 }
1632         }
1633
1634         ret = em_malloc(sizeof(SENDSTREAM*));
1635         if (!ret) {
1636                 EM_DEBUG_EXCEPTION("em_mallocerror");
1637                 goto FINISH_OFF;
1638         }
1639
1640         if (!emcore_connect_to_remote_mailbox(multi_user_name,
1641                                 account_id,
1642                                 EMAIL_CONNECT_FOR_SENDING,
1643                                 true,
1644                                 (void **)ret,
1645                                 &err)) {
1646                 EM_DEBUG_EXCEPTION("emcore_connect_to_remote_mailbox failed [%d]", err);
1647
1648                 EM_SAFE_FREE(ret);
1649                 goto FINISH_OFF;
1650         }
1651
1652         email_send_stream_list_t *node = em_malloc(sizeof(email_send_stream_list_t));
1653         if (!node) {
1654                 EM_DEBUG_EXCEPTION("em_mallocerror");
1655                 *ret = smtp_close(*ret);
1656                 EM_SAFE_FREE(ret);
1657                 goto FINISH_OFF;
1658         }
1659
1660         node->account_id = account_id;
1661         node->send_stream = ret;
1662
1663         g_send_stream_list = g_list_prepend(g_send_stream_list, node);
1664
1665 FINISH_OFF:
1666
1667         if (error)
1668                 *error = err;
1669
1670         EM_DEBUG_FUNC_END();
1671
1672         return ret;
1673 }
1674
1675
1676 /*
1677    send a mail
1678    3 threads call this function :
1679    worker_send_event_queue
1680    mainloop (by alarm),
1681    thread_func_EMAIL_ASYNC_TASK_SEND_MAIL_WITH_DOWNLOADING_ATTACHMENT_OF_ORIGINAL_MAIL,
1682    */
1683
1684 INTERNAL_FUNC int emcore_send_mail(char *multi_user_name, int mail_id, int *err_code)
1685 {
1686         EM_DEBUG_FUNC_BEGIN("mail_id[%d], err_code[%p]", mail_id, err_code);
1687         EM_PROFILE_BEGIN(profile_emcore_send_mail);
1688         int ret = false;
1689         int err = EMAIL_ERROR_NONE, err2 = EMAIL_ERROR_NONE;
1690         int attachment_tbl_count = 0;
1691         int account_id = 0;
1692         SENDSTREAM** send_stream = NULL;
1693         ENVELOPE *envelope = NULL;
1694         sslstart_t stls = NULL;
1695         emstorage_mail_tbl_t       *mail_tbl_data = NULL;
1696         emstorage_attachment_tbl_t *attachment_tbl_data = NULL;
1697         email_account_t *ref_account = NULL;
1698         email_option_t *opt = NULL;
1699         char *fpath = NULL;
1700         emstorage_mailbox_tbl_t* local_mailbox = NULL;
1701         emstorage_read_mail_uid_tbl_t *downloaded_mail = NULL;
1702         int dst_mailbox_id = 0;
1703         int total_mail_size = 0;
1704         char *server_uid = NULL;
1705         MAILSTREAM *mail_stream = NULL;
1706
1707         if (!mail_id) {
1708                 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
1709                 err = EMAIL_ERROR_INVALID_PARAM;
1710                 goto FINISH_OFF;
1711         }
1712
1713         /*  get mail to send */
1714         if (!emstorage_get_mail_by_id(multi_user_name, mail_id, &mail_tbl_data, false, &err) || err != EMAIL_ERROR_NONE) {
1715                 EM_DEBUG_EXCEPTION("emstorage_get_mail_by_id failed [%d]", err);
1716                 goto FINISH_OFF;
1717         }
1718
1719         account_id = mail_tbl_data->account_id;
1720
1721         if (!(ref_account = emcore_get_account_reference(multi_user_name, account_id, false))) {
1722                 EM_DEBUG_EXCEPTION("emcore_get_account_reference failed [%d]", account_id);
1723                 err = EMAIL_ERROR_INVALID_ACCOUNT;
1724                 goto FINISH_OFF;
1725         }
1726
1727         if ((err = emstorage_get_attachment_list(multi_user_name, mail_id, false, &attachment_tbl_data, &attachment_tbl_count)) != EMAIL_ERROR_NONE) {
1728                 EM_DEBUG_EXCEPTION("emstorage_get_attachment_list failed [%d]", err);
1729                 goto FINISH_OFF;
1730         }
1731
1732         if (!emcore_check_send_mail_thread_status()) {
1733                 EM_DEBUG_EXCEPTION("emcore_check_send_mail_thread_status failed...");
1734                 err = EMAIL_ERROR_CANCELLED;
1735                 goto FINISH_OFF;
1736         }
1737
1738         if ((!mail_tbl_data->full_address_to) && (!mail_tbl_data->full_address_cc) && (!mail_tbl_data->full_address_bcc)) {
1739                 err = EMAIL_ERROR_NO_RECIPIENT;
1740                 EM_DEBUG_EXCEPTION("No Recipient information [%d]", err);
1741                 goto FINISH_OFF;
1742         } else {
1743                 if ((err = em_verify_email_address_of_mail_tbl(mail_tbl_data)) != EMAIL_ERROR_NONE) {
1744                         err = EMAIL_ERROR_INVALID_ADDRESS;
1745                         EM_DEBUG_EXCEPTION("em_verify_email_address_of_mail_tbl failed [%d]", err);
1746                         goto FINISH_OFF;
1747                 }
1748         }
1749
1750         if (!emcore_check_send_mail_thread_status()) {
1751                 EM_DEBUG_EXCEPTION("emcore_check_send_mail_thread_status failed...");
1752                 err = EMAIL_ERROR_CANCELLED;
1753                 goto FINISH_OFF;
1754         }
1755
1756         opt = &(ref_account->options);
1757
1758 #ifdef __FEATURE_SUPPORT_VALIDATION_SYSTEM__
1759         int i = 0;
1760         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);
1761         for (i = 0; i < attachment_tbl_count; i++) {
1762                 if (attachment_tbl_data)
1763                         EM_VALIDATION_SYSTEM_LOG("FILE", mail_id, "[%s], %d", attachment_tbl_data[i].attachment_path, attachment_tbl_data[i].attachment_size);
1764         }
1765 #endif /* __FEATURE_SUPPORT_VALIDATION_SYSTEM__ */
1766
1767         /*Update status flag to DB*/
1768
1769         /*  get rfc822 data */
1770         if (!emcore_make_rfc822_file_from_mail(multi_user_name, mail_tbl_data, attachment_tbl_data, attachment_tbl_count, &envelope, &fpath, opt, &err)) {
1771                 EM_DEBUG_EXCEPTION("emcore_make_rfc822_file_from_mail failed [%d]", err);
1772                 goto FINISH_OFF;
1773         }
1774
1775         if (!envelope || (!envelope->to && !envelope->cc && !envelope->bcc)) {
1776                 EM_DEBUG_EXCEPTION(" no recipients found...");
1777                 err = EMAIL_ERROR_NO_RECIPIENT;
1778                 goto FINISH_OFF;
1779         }
1780
1781         /*  if there is no security option, unset security. */
1782         if (!ref_account->outgoing_server_secure_connection) {
1783                 stls = (sslstart_t)mail_parameters(NULL, GET_SSLSTART, NULL);
1784                 mail_parameters(NULL, SET_SSLSTART, NULL);
1785         }
1786
1787         if (!emcore_check_send_mail_thread_status()) {
1788                 EM_DEBUG_EXCEPTION("emcore_check_send_mail_thread_status failed...");
1789                 err = EMAIL_ERROR_CANCELLED;
1790                 goto FINISH_OFF;
1791         }
1792
1793         if (ref_account->pop_before_smtp != FALSE) {
1794                 if (!emcore_connect_to_remote_mailbox(multi_user_name,
1795                                         account_id,
1796                                         0,
1797                                         true,
1798                                         (void **)&mail_stream,
1799                                         &err)) {
1800                         EM_DEBUG_EXCEPTION(" POP before SMTP Authentication failed [%d]", err);
1801                         if (err == EMAIL_ERROR_CONNECTION_BROKEN)
1802                                 err = EMAIL_ERROR_CANCELLED;
1803                         goto FINISH_OFF;
1804                 }
1805         }
1806
1807         if (!emstorage_get_mailbox_by_mailbox_type(multi_user_name, account_id, EMAIL_MAILBOX_TYPE_DRAFT, &local_mailbox, false, &err)) {
1808                 EM_DEBUG_EXCEPTION(" emstorage_get_mailbox_by_mailbox_type failed [%d]", err);
1809                 goto FINISH_OFF;
1810         }
1811         dst_mailbox_id = local_mailbox->mailbox_id;
1812         emstorage_free_mailbox(&local_mailbox, 1, NULL);
1813
1814         if (!emnetwork_check_network_status(&err)) {
1815                 EM_DEBUG_EXCEPTION("emnetwork_check_network_status failed [%d]", err);
1816                 goto FINISH_OFF;
1817         }
1818
1819         send_stream = emcore_get_smtp_stream(multi_user_name, account_id, &err);
1820         if (!send_stream) {
1821                 EM_DEBUG_EXCEPTION(" emcore_get_smtp_stream failed [%d]", err);
1822                 if (err == EMAIL_ERROR_CONNECTION_BROKEN)
1823                         err = EMAIL_ERROR_CANCELLED;
1824                 goto FINISH_OFF;
1825         }
1826
1827 #if 0
1828         if (!emcore_connect_to_remote_mailbox(multi_user_name,
1829                                 account_id,
1830                                 EMAIL_CONNECT_FOR_SENDING,
1831                                 true,
1832                                 (void **)&tmp_stream,
1833                                 &err)) {
1834                 EM_DEBUG_EXCEPTION(" emcore_connect_to_remote_mailbox failed [%d]", err);
1835
1836                 if (err == EMAIL_ERROR_CONNECTION_BROKEN)
1837                         err = EMAIL_ERROR_CANCELLED;
1838                 goto FINISH_OFF;
1839         }
1840
1841         stream = (SENDSTREAM *)tmp_stream;
1842 #endif
1843
1844         if (!emcore_check_send_mail_thread_status()) {
1845                 EM_DEBUG_EXCEPTION(" emcore_check_send_mail_thread_status failed...");
1846                 err = EMAIL_ERROR_CANCELLED;
1847                 goto FINISH_OFF;
1848         }
1849
1850         if (*send_stream && (*send_stream)->protocol.esmtp.ok) {
1851                 if ((*send_stream)->protocol.esmtp.size.ok && (*send_stream)->protocol.esmtp.size.limit > 0) {
1852                         EM_DEBUG_LOG("Server size limit : %ld", (*send_stream)->protocol.esmtp.size.limit);
1853                         emcore_get_file_size(fpath, &total_mail_size, NULL);
1854                         EM_DEBUG_LOG("mail size : %d", total_mail_size);
1855                         if (total_mail_size > (*send_stream)->protocol.esmtp.size.limit) {
1856                                 err = EMAIL_ERROR_SMTP_SEND_FAILURE_BY_OVERSIZE;
1857                                 goto FINISH_OFF;
1858                         }
1859                 }
1860         }
1861
1862         /*  set request of delivery status. */
1863         EM_DEBUG_LOG("opt->req_delivery_receipt [%d]", opt->req_delivery_receipt);
1864         EM_DEBUG_LOG("mail_tbl_data->report_status [%d]", mail_tbl_data->report_status);
1865
1866         if (opt->req_delivery_receipt == EMAIL_OPTION_REQ_DELIVERY_RECEIPT_ON || (mail_tbl_data->report_status & EMAIL_MAIL_REQUEST_DSN)) {
1867                 EM_DEBUG_LOG("DSN is required.");
1868                 if (*send_stream) {
1869                         (*send_stream)->protocol.esmtp.dsn.want = 1;
1870                         (*send_stream)->protocol.esmtp.dsn.full = 0;
1871                         (*send_stream)->protocol.esmtp.dsn.notify.failure = 1;
1872                         (*send_stream)->protocol.esmtp.dsn.notify.success = 1;
1873                 }
1874         }
1875
1876         mail_tbl_data->save_status = EMAIL_MAIL_STATUS_SENDING;
1877         emcore_show_user_message(multi_user_name, mail_id, EMAIL_ACTION_SENDING_MAIL, EMAIL_ERROR_NONE);
1878
1879         /*Update status save_status to DB*/
1880         if (!emstorage_set_field_of_mails_with_integer_value(multi_user_name, account_id, &mail_id, 1, "save_status", mail_tbl_data->save_status, true, &err))
1881                 EM_DEBUG_EXCEPTION("emstorage_set_field_of_mails_with_integer_value failed [%d]", err);
1882
1883         /*  send mail to server. */
1884         if (!emcore_send_mail_smtp(multi_user_name, *send_stream, envelope, fpath, account_id, mail_id, &err)) {
1885                 EM_DEBUG_EXCEPTION(" emcore_send_mail_smtp failed [%d]", err);
1886                 if (err == SMTP_RESPONSE_EXCEED_SIZE_LIMIT)
1887                         err = EMAIL_ERROR_SMTP_SEND_FAILURE_BY_OVERSIZE;
1888
1889 #ifndef __FEATURE_MOVE_TO_OUTBOX_FIRST__
1890                 if (!emstorage_get_mailbox_by_mailbox_type(multi_user_name, account_id, EMAIL_MAILBOX_TYPE_OUTBOX, &local_mailbox, false, &err)) {
1891                         EM_DEBUG_EXCEPTION("emstorage_get_mailbox_by_mailbox_type failed [%d]", err);
1892                         goto FINISH_OFF;
1893                 }
1894                 dst_mailbox_id = local_mailbox->mailbox_id;
1895                 emstorage_free_mailbox(&local_mailbox, 1, NULL);
1896
1897                 /*  unsent mail is moved to 'OUTBOX'. */
1898                 if (!emcore_move_mail(multi_user_name, &mail_id, 1, dst_mailbox_id, EMAIL_MOVED_BY_COMMAND, 0, NULL))
1899                         EM_DEBUG_EXCEPTION(" emcore_mail_move falied...");
1900 #endif
1901                 if (err > 0)
1902                         err = EMAIL_ERROR_SMTP_SEND_FAILURE;
1903                 goto FINISH_OFF;
1904         }
1905
1906
1907         /*  sent mail is moved to 'SENT' box or deleted. */
1908         if (opt->keep_local_copy) {
1909                 if (!emstorage_get_mailbox_by_mailbox_type(multi_user_name,
1910                                         account_id,
1911                                         EMAIL_MAILBOX_TYPE_SENTBOX,
1912                                         &local_mailbox,
1913                                         true,
1914                                         &err)) {
1915                         EM_DEBUG_EXCEPTION("emstorage_get_mailbox_by_mailbox_type failed [%d]", err);
1916                         goto FINISH_OFF;
1917                 }
1918                 dst_mailbox_id = local_mailbox->mailbox_id;
1919
1920                 if (!emcore_move_mail(multi_user_name, &mail_id, 1, dst_mailbox_id, EMAIL_MOVED_AFTER_SENDING, 0, &err))
1921                         EM_DEBUG_EXCEPTION(" emcore_mail_move falied [%d]", err);
1922 #ifdef __FEATURE_SYNC_CLIENT_TO_SERVER__
1923 #ifdef __FEATURE_LOCAL_ACTIVITY__
1924                 else if (ref_account->incoming_server_type == EMAIL_SERVER_TYPE_IMAP4) /* To be synced to Sent box only IMAP not for POP */ {
1925                         emstorage_activity_tbl_t new_activity;
1926                         int activityid = 0;
1927
1928                         if (false == emcore_get_next_activity_id(&activityid, &err))
1929                                 EM_DEBUG_EXCEPTION(" emcore_get_next_activity_id Failed [%d] ", err);
1930
1931                         memset(&new_activity, 0x00, sizeof(emstorage_activity_tbl_t));
1932                         new_activity.activity_id  =  activityid;
1933                         new_activity.server_mailid = NULL;
1934                         new_activity.account_id = account_id;
1935                         new_activity.mail_id    = mail_id;
1936                         new_activity.activity_type = ACTIVITY_SAVEMAIL;
1937                         new_activity.dest_mbox  = NULL;
1938                         new_activity.src_mbox   = NULL;
1939
1940                         if (!emcore_add_activity(&new_activity, &err))
1941                                 EM_DEBUG_EXCEPTION(" emcore_add_activity Failed [%d] ", err);
1942
1943                         if (!emcore_move_mail_on_server(multi_user_name, dest_mbox.account_id, dst_mailbox_id, &mail_id, 1, dest_mbox.name, &err)) {
1944                                 EM_DEBUG_EXCEPTION(" emcore_move_mail_on_server falied [%d]", err);
1945                         } else {
1946                                 /* Remove ACTIVITY_SAVEMAIL activity */
1947                                 new_activity.activity_id  =  activityid;
1948                                 new_activity.activity_type = ACTIVITY_SAVEMAIL;
1949                                 new_activity.account_id = account_id;
1950                                 new_activity.mail_id    = mail_id;
1951                                 new_activity.dest_mbox  = NULL;
1952                                 new_activity.server_mailid = NULL;
1953                                 new_activity.src_mbox   = NULL;
1954
1955                                 if (!emcore_delete_activity(&new_activity, &err))
1956                                         EM_DEBUG_EXCEPTION(">>>>>>Local Activity [ACTIVITY_SAVEMAIL] [%d] ", err);
1957                         }
1958                         sent_box = 1;
1959                 }
1960 #endif
1961 #endif
1962                 if (ref_account->incoming_server_type == EMAIL_SERVER_TYPE_IMAP4) {
1963                         emstorage_mailbox_tbl_t* src_mailbox = NULL;
1964                         //emstorage_mail_tbl_t *temp_mail = NULL;
1965
1966                         if (!emstorage_get_mailbox_by_mailbox_type(multi_user_name,
1967                                                 account_id,
1968                                                 EMAIL_MAILBOX_TYPE_OUTBOX,
1969                                                 &src_mailbox,
1970                                                 true,
1971                                                 &err)) {
1972                                 EM_DEBUG_EXCEPTION("emstorage_get_mailbox_by_mailbox_type failed [%d]", err);
1973                                 goto FINISH_OFF;
1974                         }
1975
1976                         EM_DEBUG_LOG("local_yn:[%d]", src_mailbox->local_yn);
1977                         if (src_mailbox->local_yn) {
1978                                 /* This is syncing operation in sent box
1979                                    but it slowed operation */
1980                                 /*
1981                                    void *local_stream = NULL;
1982                                    if (!emcore_sync_header (multi_user_name, local_mailbox, &local_stream, NULL, NULL, NULL, NULL, NULL, 0, -1, &err)) {
1983                                    EM_DEBUG_EXCEPTION("emcore_sync_header failed");
1984                                    }
1985                                    mail_close(local_stream);
1986                                    if (!emstorage_get_maildata_by_servermailid(multi_user_name,
1987                                    "0",
1988                                    local_mailbox->mailbox_id,
1989                                    &temp_mail,
1990                                    false,
1991                                    &err)) {
1992                                    if (err != EMAIL_ERROR_MAIL_NOT_FOUND) {
1993                                    EM_DEBUG_EXCEPTION("emstorage_get_maildata_by_servermailid failed : [%d]", err);
1994                                    goto FINISH_OFF;
1995                                    }
1996                                    }
1997
1998                                    if (temp_mail) {
1999                                    emcore_sync_mail_from_client_to_server(multi_user_name, mail_id);
2000                                    emstorage_free_mail(&temp_mail, 1, NULL);
2001                                    }
2002                                    */
2003
2004                                 /* sent box exception list : gmail (After the mail sent, moved the sent box) */
2005                                 if (ref_account->outgoing_server_address) {
2006                                         if (!strcasestr(ref_account->outgoing_server_address, "gmail")) {
2007                                                 emcore_sync_mail_from_client_to_server(multi_user_name, mail_id);
2008                                         } else {
2009                                                 err = emcore_sync_mail_by_message_id(multi_user_name,
2010                                                                 mail_id,
2011                                                                 dst_mailbox_id,
2012                                                                 &server_uid);
2013                                                 if (err != EMAIL_ERROR_NONE)
2014                                                         EM_DEBUG_EXCEPTION("emcore_sync_mail_by_message_id failed : [%d]", err);
2015
2016                                                 EM_DEBUG_LOG("server_uid : [%s]", server_uid);
2017
2018                                                 if (server_uid) {
2019                                                         if (!emstorage_update_server_uid(multi_user_name,
2020                                                                                 mail_id,
2021                                                                                 NULL,
2022                                                                                 server_uid,
2023                                                                                 &err)) {
2024                                                                 EM_DEBUG_EXCEPTION("emstorage_update_server_uid failed : [%d]", err);
2025                                                         }
2026
2027                                                         downloaded_mail = em_malloc(sizeof(emstorage_read_mail_uid_tbl_t));
2028                                                         if (downloaded_mail == NULL) {
2029                                                                 EM_DEBUG_EXCEPTION("em_mallocfailed");
2030                                                                 err = EMAIL_ERROR_OUT_OF_MEMORY;
2031                                                                 goto FINISH_OFF;
2032                                                         }
2033
2034                                                         downloaded_mail->account_id = account_id;
2035                                                         downloaded_mail->mailbox_id = dst_mailbox_id;
2036                                                         downloaded_mail->local_uid = mail_id;
2037                                                         downloaded_mail->mailbox_name = g_strdup(local_mailbox->mailbox_name);
2038                                                         downloaded_mail->server_uid = g_strdup(server_uid);
2039                                                         downloaded_mail->rfc822_size = mail_tbl_data->mail_size;
2040
2041                                                         if (!emstorage_add_downloaded_mail(multi_user_name,
2042                                                                                 downloaded_mail,
2043                                                                                 true,
2044                                                                                 &err)) {
2045                                                                 EM_DEBUG_EXCEPTION("emstorage_add_downloaded_mail failed : [%d]", err);
2046                                                         }
2047                                                 }
2048                                         }
2049                                 }
2050                         } else {
2051                                 if (!emcore_move_mail_on_server(multi_user_name,
2052                                                         account_id,
2053                                                         src_mailbox->mailbox_id,
2054                                                         &mail_id,
2055                                                         1,
2056                                                         local_mailbox->mailbox_name,
2057                                                         &err)) {
2058                                         EM_DEBUG_EXCEPTION(" emcore_move_mail_on_server falied [%d]", err);
2059                                 }
2060                         }
2061
2062                         emstorage_free_mailbox(&src_mailbox, 1, NULL);
2063                 }
2064
2065                 /* On Successful Mail sent remove the Draft flag */
2066                 mail_tbl_data->flags_draft_field = 0;
2067
2068                 if (!emstorage_set_field_of_mails_with_integer_value(multi_user_name,
2069                                         account_id,
2070                                         &mail_id,
2071                                         1,
2072                                         "flags_draft_field",
2073                                         mail_tbl_data->flags_draft_field,
2074                                         true,
2075                                         &err))
2076                         EM_DEBUG_EXCEPTION("Failed to modify extra flag [%d]", err);
2077         } else {
2078                 if (!emcore_delete_mail(multi_user_name,
2079                                         account_id,
2080                                         0,
2081                                         &mail_id,
2082                                         1,
2083                                         EMAIL_DELETE_LOCALLY,
2084                                         EMAIL_DELETED_AFTER_SENDING,
2085                                         false,
2086                                         &err))
2087                         EM_DEBUG_EXCEPTION(" emcore_delete_mail failed [%d]", err);
2088         }
2089
2090         /* Set the phone log */
2091         err = emcore_set_sent_contacts_log(multi_user_name, mail_tbl_data);
2092         if (err != EMAIL_ERROR_NONE)
2093                 EM_DEBUG_EXCEPTION("emcore_set_sent_contacts_log failed : [%d]", err);
2094
2095         /*Update save_status */
2096         mail_tbl_data->save_status = EMAIL_MAIL_STATUS_SENT;
2097         if (!emstorage_set_field_of_mails_with_integer_value(multi_user_name,
2098                                 account_id,
2099                                 &mail_id,
2100                                 1,
2101                                 "save_status",
2102                                 mail_tbl_data->save_status,
2103                                 true,
2104                                 &err))
2105                 EM_DEBUG_EXCEPTION("emstorage_set_field_of_mails_with_integer_value failed [%d]", err);
2106
2107         if (!emcore_delete_transaction_info_by_mailId(mail_id))
2108                 EM_DEBUG_EXCEPTION(" emcore_delete_transaction_info_by_mailId failed for mail_id[%d]", mail_id);
2109
2110         ret = true;
2111
2112 FINISH_OFF:
2113
2114         EM_SAFE_FREE(server_uid);
2115
2116         emcore_show_user_message(multi_user_name, mail_id, EMAIL_ACTION_SEND_MAIL, err);
2117
2118         if (ret == false && err != EMAIL_ERROR_INVALID_PARAM && mail_tbl_data) {
2119                 if (err != EMAIL_ERROR_CANCELLED) {
2120                         mail_tbl_data->save_status = EMAIL_MAIL_STATUS_SEND_FAILURE;
2121                         if (!emstorage_set_field_of_mails_with_integer_value(multi_user_name, account_id, &mail_id, 1, "save_status", mail_tbl_data->save_status, true, &err2))
2122                                 EM_DEBUG_EXCEPTION("emstorage_set_field_of_mails_with_integer_value failed [%d]", err2);
2123                 } else {
2124                         if (EMAIL_MAIL_STATUS_SEND_CANCELED == mail_tbl_data->save_status)
2125                                 EM_DEBUG_LOG("EMAIL_MAIL_STATUS_SEND_CANCELED Already set for ");
2126                         else {
2127                                 mail_tbl_data->save_status = EMAIL_MAIL_STATUS_SEND_CANCELED;
2128                                 if (!emstorage_set_field_of_mails_with_integer_value(multi_user_name,
2129                                                         account_id,
2130                                                         &mail_id,
2131                                                         1,
2132                                                         "save_status",
2133                                                         mail_tbl_data->save_status,
2134                                                         true,
2135                                                         &err2))
2136                                         EM_DEBUG_EXCEPTION("emstorage_set_field_of_mails_with_integer_value failed [%d]", err2);
2137                         }
2138                 }
2139         }
2140
2141         if (ref_account) {
2142                 emcore_free_account(ref_account);
2143                 EM_SAFE_FREE(ref_account);
2144         }
2145
2146 #if 0
2147 #ifndef __FEATURE_KEEP_CONNECTION__
2148         if (stream)
2149                 smtp_close(stream);
2150 #endif /* __FEATURE_KEEP_CONNECTION__ */
2151 #endif
2152
2153         if (downloaded_mail)
2154                 emstorage_free_read_mail_uid(&downloaded_mail, 1, NULL);
2155
2156         if (mail_stream)
2157                 mail_stream = mail_close(mail_stream);
2158
2159         if (stls)
2160                 mail_parameters(NULL, SET_SSLSTART, (void  *)stls);
2161
2162         if (attachment_tbl_data)
2163                 emstorage_free_attachment(&attachment_tbl_data, attachment_tbl_count, NULL);
2164
2165         if (envelope)
2166                 mail_free_envelope(&envelope);
2167
2168         if (fpath) {
2169                 EM_DEBUG_LOG_SEC("REMOVE TEMP FILE  :  %s", fpath);
2170                 remove(fpath);
2171                 EM_SAFE_FREE(fpath);
2172         }
2173
2174         if (local_mailbox)
2175                 emstorage_free_mailbox(&local_mailbox, 1, NULL);
2176
2177         if (ret == true) {
2178                 if (!emcore_notify_network_event(NOTI_SEND_FINISH, account_id, NULL, mail_id, 0))
2179                         EM_DEBUG_EXCEPTION("emcore_notify_network_event[NOTI_SEND_FINISH] Failed");
2180 #ifdef __FEATURE_SUPPORT_VALIDATION_SYSTEM__
2181                 if (mail_tbl_data)
2182                         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);
2183 #endif
2184         } else {
2185                 if (!emcore_notify_network_event(NOTI_SEND_FAIL, account_id, NULL, mail_id, err))
2186                         EM_DEBUG_EXCEPTION("emcore_notify_network_event[NOTI_SEND_FAIL] Failed");
2187 #ifdef __FEATURE_SUPPORT_VALIDATION_SYSTEM__
2188                 if (mail_tbl_data)
2189                         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);
2190 #endif
2191
2192                 if (err != EMAIL_ERROR_SMTP_SEND_FAILURE_BY_OVERSIZE) {
2193                         /* Add alarm for next sending mails */
2194                         if ((err2 = emcore_create_alarm_for_auto_resend(multi_user_name, AUTO_RESEND_INTERVAL)) != EMAIL_ERROR_NONE) {
2195                                 if (err2 != EMAIL_ERROR_MAIL_NOT_FOUND)
2196                                         EM_DEBUG_EXCEPTION("emcore_create_alarm_for_auto_resend failed [%d]", err2);
2197                         }
2198                 }
2199         }
2200
2201         if (mail_tbl_data)
2202                 emstorage_free_mail(&mail_tbl_data, 1, NULL);
2203
2204         if (err_code != NULL)
2205                 *err_code = err;
2206         EM_PROFILE_END(profile_emcore_send_mail);
2207         EM_DEBUG_FUNC_END("ret [%d], err [%d]", ret, err);
2208         return ret;
2209 }
2210
2211 /*  send a saved all mails */
2212 INTERNAL_FUNC int emcore_send_saved_mail(char *multi_user_name, int account_id, char *input_mailbox_name, int *err_code)
2213 {
2214         EM_DEBUG_FUNC_BEGIN("account_id[%d], input_mailbox_name[%p], err_code[%p]", account_id, input_mailbox_name, err_code);
2215
2216         int ret = false;
2217         int err = EMAIL_ERROR_NONE;
2218         int err2 = EMAIL_ERROR_NONE;
2219         int status = EMAIL_SEND_FAIL;
2220         int *mail_ids = NULL;
2221         DB_STMT handle = NULL;
2222         int i = 0;
2223         int total = 0;
2224         int attachment_tbl_count = 0;
2225         char *fpath = NULL;
2226         SENDSTREAM *stream = NULL;
2227         ENVELOPE *envelope = NULL;
2228         email_account_t *ref_account = NULL;
2229         emstorage_mail_tbl_t       *searched_mail_tbl_data = NULL;
2230         emstorage_attachment_tbl_t *attachment_tbl_data    = NULL;
2231         email_option_t *opt = NULL;
2232         sslstart_t      stls = NULL;
2233         void *tmp_stream = NULL;
2234         emstorage_mailbox_tbl_t* local_mailbox = NULL;
2235         int dst_mailbox_id = 0;
2236
2237         if (!account_id || !input_mailbox_name) {
2238                 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
2239                 err = EMAIL_ERROR_INVALID_PARAM;
2240                 goto FINISH_OFF;
2241         }
2242
2243
2244         if (!(ref_account = emcore_get_account_reference(multi_user_name, account_id, false))) {
2245                 EM_DEBUG_EXCEPTION("emcore_get_account_reference failed [%d]", account_id);
2246                 err = EMAIL_ERROR_INVALID_ACCOUNT;
2247                 goto FINISH_OFF;
2248         }
2249
2250         /*don't delete the comment. several threads including event thread call this func */
2251         /*      FINISH_OFF_IF_CANCELED; */
2252
2253         if (!emnetwork_check_network_status(&err)) {
2254                 EM_DEBUG_EXCEPTION("emnetwork_check_network_status failed [%d]", err);
2255                 goto FINISH_OFF;
2256         }
2257
2258         opt = &(ref_account->options);
2259
2260         if (!emstorage_get_mailbox_by_name(multi_user_name, account_id, -1, input_mailbox_name, &local_mailbox, false, &err)) {
2261                 EM_DEBUG_EXCEPTION("emstorage_get_mailbox_by_name failed : [%d]", err);
2262                 goto FINISH_OFF;
2263         }
2264
2265         /*  search mail. */
2266         if (!emstorage_mail_search_start(multi_user_name, NULL, account_id, local_mailbox->mailbox_id, 0, &handle, &total, true, &err)) {
2267                 EM_DEBUG_EXCEPTION("emstorage_mail_search_start failed [%d]", err);
2268                 goto FINISH_OFF;
2269         }
2270
2271         mail_ids = em_malloc(sizeof(int) * total);
2272         if (mail_ids == NULL) {
2273                 EM_DEBUG_EXCEPTION("malloc failed...");
2274                 err = EMAIL_ERROR_OUT_OF_MEMORY;
2275                 goto FINISH_OFF;
2276         }
2277
2278         for (i = 0; i < total ; i++) {
2279                 if (!emstorage_mail_search_result(handle, RETRIEVE_ID, (void **)&mail_ids[i], true, &err)) {
2280                         EM_DEBUG_EXCEPTION("emstorage_mail_search_result failed [%d]", err);
2281                         goto FINISH_OFF;
2282                 }
2283         }
2284
2285         if (!emstorage_mail_search_end(handle, true, &err)) {
2286                 EM_DEBUG_EXCEPTION("emstorage_mail_search_end failed [%d]", err);
2287                 goto FINISH_OFF;
2288         }
2289
2290         handle = 0;
2291
2292         mail_send_notify(EMAIL_SEND_PREPARE, 0, 0, account_id, mail_ids[total], err);
2293
2294         if (local_mailbox)
2295                 emstorage_free_mailbox(&local_mailbox, 1, NULL);
2296
2297         for (i = 0; i < total; i++) {
2298                 /*don't delete the comment. several threads including event thread call this func */
2299                 /*              FINISH_OFF_IF_CANCELED;*/
2300
2301                 if (!emstorage_get_mail_by_id(multi_user_name, mail_ids[i], &searched_mail_tbl_data, false, &err)) {
2302                         EM_DEBUG_EXCEPTION("emstorage_get_mail_by_id failed [%d]", err);
2303                         goto FINISH_OFF;
2304                 }
2305
2306                 /* Skip the mail canceled */
2307                 if (searched_mail_tbl_data->save_status == EMAIL_MAIL_STATUS_SEND_CANCELED) {
2308                         EM_DEBUG_EXCEPTION("The mail was canceled. [%d]", mail_ids[i]);
2309                         emstorage_free_mail(&searched_mail_tbl_data, 1, &err);
2310                         searched_mail_tbl_data = NULL;
2311                         continue;
2312                 }
2313
2314                 if ((err = emstorage_get_attachment_list(multi_user_name, mail_ids[i], false, &attachment_tbl_data, &attachment_tbl_count)) != EMAIL_ERROR_NONE) {
2315                         EM_DEBUG_EXCEPTION("emstorage_get_attachment_list failed [%d]", err);
2316                         goto FINISH_OFF;
2317                 }
2318
2319                 /* check for email_address validation */
2320                 if ((err = em_verify_email_address_of_mail_tbl(searched_mail_tbl_data)) != EMAIL_ERROR_NONE) {
2321                         err = EMAIL_ERROR_INVALID_ADDRESS;
2322                         EM_DEBUG_EXCEPTION("em_verify_email_address_of_mail_tbl failed [%d]", err);
2323                         goto FINISH_OFF;
2324                 }
2325
2326                 searched_mail_tbl_data->save_status = EMAIL_MAIL_STATUS_SENDING;
2327
2328                 if (!emcore_make_rfc822_file_from_mail(multi_user_name, searched_mail_tbl_data, attachment_tbl_data, attachment_tbl_count, &envelope, &fpath, opt, &err)) {
2329                         EM_DEBUG_EXCEPTION("emcore_make_rfc822_file_from_mail falied [%d]", err);
2330                         goto FINISH_OFF;
2331                 }
2332
2333                 /*don't delete the comment. several threads including event thread call this func */
2334                 /*              FINISH_OFF_IF_CANCELED;*/
2335
2336                 /*  connect mail server. */
2337                 if (!stream) {
2338                         /*  if there no security option, unset security. */
2339                         if (!ref_account->outgoing_server_secure_connection) {
2340                                 stls = (sslstart_t)mail_parameters(NULL, GET_SSLSTART, NULL);
2341                                 mail_parameters(NULL, SET_SSLSTART, NULL);
2342                         }
2343
2344                         stream = NULL;
2345                         if (!emcore_connect_to_remote_mailbox(multi_user_name,
2346                                                 account_id,
2347                                                 EMAIL_CONNECT_FOR_SENDING,
2348                                                 true,
2349                                                 &tmp_stream,
2350                                                 &err) || !tmp_stream) {
2351                                 EM_DEBUG_EXCEPTION("emcore_connect_to_remote_mailbox failed [%d]", err);
2352
2353                                 if (err == EMAIL_ERROR_CONNECTION_BROKEN)
2354                                         err = EMAIL_ERROR_CANCELLED;
2355
2356                                 status = EMAIL_SEND_CONNECTION_FAIL;
2357                                 goto FINISH_OFF;
2358                         }
2359
2360                         stream = (SENDSTREAM *)tmp_stream;
2361
2362                         /*don't delete the comment. several threads including event thread call this func */
2363                         /*                      FINISH_OFF_IF_CANCELED;*/
2364
2365                         mail_send_notify(EMAIL_SEND_CONNECTION_SUCCEED, 0, 0, account_id, mail_ids[i], err);
2366
2367                         /*  reqest of delivery status. */
2368                         if (opt && opt->req_delivery_receipt == EMAIL_OPTION_REQ_DELIVERY_RECEIPT_ON) {
2369                                 stream->protocol.esmtp.dsn.want = 1;
2370                                 stream->protocol.esmtp.dsn.full = 0;
2371                                 stream->protocol.esmtp.dsn.notify.failure = 1;
2372                                 stream->protocol.esmtp.dsn.notify.success = 1;
2373                         }
2374
2375                         mail_send_notify(EMAIL_SEND_START, 0, 0, account_id, mail_ids[i], err);
2376                 }
2377
2378                 searched_mail_tbl_data->save_status = EMAIL_MAIL_STATUS_SENDING;
2379
2380                 /*  update mail status to sending. */
2381                 if (!emstorage_change_mail_field(multi_user_name, mail_ids[i], UPDATE_EXTRA_FLAG, searched_mail_tbl_data, true, &err)) {
2382                         EM_DEBUG_EXCEPTION("emstorage_change_mail_field failed [%d]", err);
2383
2384                         goto FINISH_OFF;
2385                 }
2386
2387                 if (!emcore_send_mail_smtp(multi_user_name, stream, envelope, fpath, account_id, mail_ids[i], &err)) {
2388                         EM_DEBUG_EXCEPTION("emcore_send_mail_smtp failed [%d]", err);
2389                         if (err == SMTP_RESPONSE_EXCEED_SIZE_LIMIT) err = EMAIL_ERROR_SMTP_SEND_FAILURE_BY_OVERSIZE;
2390
2391                         searched_mail_tbl_data->save_status = EMAIL_MAIL_STATUS_SEND_FAILURE;
2392
2393                         /*  update mail status to failure. */
2394                         if (!emstorage_change_mail_field(multi_user_name, mail_ids[i], UPDATE_EXTRA_FLAG, searched_mail_tbl_data, true, &err2))
2395                                 EM_DEBUG_EXCEPTION("emstorage_change_mail_field failed [%d]", err);
2396
2397                         if (!emstorage_get_mailbox_by_mailbox_type(multi_user_name,
2398                                                 account_id,
2399                                                 EMAIL_MAILBOX_TYPE_OUTBOX,
2400                                                 &local_mailbox,
2401                                                 false,
2402                                                 &err)) {
2403                                 EM_DEBUG_EXCEPTION("emstorage_get_mailbox_by_mailbox_type failed [%d]", err);
2404                                 goto FINISH_OFF;
2405                         }
2406                         dst_mailbox_id = local_mailbox->mailbox_id;
2407
2408                         emcore_move_mail(multi_user_name, &mail_ids[i], 1, dst_mailbox_id, EMAIL_MOVED_AFTER_SENDING, 0, NULL);
2409
2410                         if (local_mailbox)
2411                                 emstorage_free_mailbox(&local_mailbox, 1, NULL);
2412
2413                         goto FINISH_OFF;
2414                 }
2415
2416                 searched_mail_tbl_data->save_status = EMAIL_MAIL_STATUS_SENT;
2417
2418                 /*  update mail status to sent mail. */
2419                 if (!emstorage_change_mail_field(multi_user_name,
2420                                         mail_ids[i],
2421                                         UPDATE_EXTRA_FLAG,
2422                                         searched_mail_tbl_data,
2423                                         true,
2424                                         &err)) {
2425                         EM_DEBUG_EXCEPTION("emstorage_change_mail_field failed [%d]", err);
2426                         goto FINISH_OFF;
2427                 }
2428
2429                 /*  sent mail is moved to 'SENT' box or deleted. */
2430                 if (opt->keep_local_copy) {
2431                         if (!emstorage_get_mailbox_by_mailbox_type(multi_user_name,
2432                                                 account_id,
2433                                                 EMAIL_MAILBOX_TYPE_SENTBOX,
2434                                                 &local_mailbox,
2435                                                 false,
2436                                                 &err)) {
2437                                 EM_DEBUG_EXCEPTION("emstorage_get_mailbox_by_mailbox_type failed [%d]", err);
2438                                 goto FINISH_OFF;
2439                         }
2440
2441                         dst_mailbox_id = local_mailbox->mailbox_id;
2442                         if (!emcore_move_mail(multi_user_name,
2443                                                 &mail_ids[i],
2444                                                 1,
2445                                                 dst_mailbox_id,
2446                                                 EMAIL_MOVED_AFTER_SENDING,
2447                                                 0,
2448                                                 &err))
2449                                 EM_DEBUG_EXCEPTION("emcore_mail_move falied [%d]", err);
2450
2451                         if (local_mailbox)
2452                                 emstorage_free_mailbox(&local_mailbox, 1, NULL);
2453                 } else {
2454                         if (!emcore_delete_mail(multi_user_name,
2455                                                 account_id,
2456                                                 0,
2457                                                 &mail_ids[i],
2458                                                 1,
2459                                                 EMAIL_DELETE_LOCALLY,
2460                                                 EMAIL_DELETED_AFTER_SENDING,
2461                                                 false,
2462                                                 &err))
2463                                 EM_DEBUG_EXCEPTION("emcore_delete_mail falied [%d]", err);
2464                 }
2465
2466                 /* Set the phone log */
2467                 err = emcore_set_sent_contacts_log(multi_user_name, searched_mail_tbl_data);
2468                 if (err != EMAIL_ERROR_NONE)
2469                         EM_DEBUG_EXCEPTION("emcore_set_sent_contacts_log failed : [%d]", err);
2470
2471                 if (searched_mail_tbl_data) {
2472                         emstorage_free_mail(&searched_mail_tbl_data, 1, NULL);
2473                         searched_mail_tbl_data = NULL;
2474                 }
2475
2476                 if (attachment_tbl_data)
2477                         emstorage_free_attachment(&attachment_tbl_data, attachment_tbl_count, NULL);
2478
2479                 mail_free_envelope(&envelope); envelope = NULL;
2480
2481                 if (fpath) {
2482                         remove(fpath);
2483                         EM_SAFE_FREE(fpath);
2484                 }
2485         }
2486
2487
2488         ret = true;
2489
2490 FINISH_OFF:
2491
2492         if (ref_account) {
2493                 emcore_free_account(ref_account);
2494                 EM_SAFE_FREE(ref_account);
2495         }
2496
2497         if (stream)
2498                 smtp_close(stream);
2499
2500         if (stls)
2501                 mail_parameters(NIL, SET_SSLSTART, (void  *)stls);
2502
2503         if (envelope)
2504                 mail_free_envelope(&envelope);
2505
2506         if (handle) {
2507                 if (!emstorage_mail_search_end(handle, true, &err2))
2508                         EM_DEBUG_EXCEPTION("emstorage_mail_search_end failed [%d]", err2);
2509         }
2510
2511         if (searched_mail_tbl_data)
2512                 emstorage_free_mail(&searched_mail_tbl_data, 1, NULL);
2513
2514         if (attachment_tbl_data)
2515                 emstorage_free_attachment(&attachment_tbl_data, attachment_tbl_count, NULL);
2516
2517         if (fpath) {
2518                 remove(fpath);
2519                 EM_SAFE_FREE(fpath);
2520         }
2521
2522         if (local_mailbox)
2523                 emstorage_free_mailbox(&local_mailbox, 1, NULL);
2524
2525         if (ret == true) {
2526                 mail_send_notify(EMAIL_SEND_FINISH, 0, 0, account_id, mail_ids[total], err);
2527                 emcore_show_user_message(multi_user_name, account_id, EMAIL_ACTION_SEND_MAIL, err);
2528         } else {
2529                 if (mail_ids) /* prevent 34385 */
2530                         mail_send_notify(status, 0, 0, account_id, mail_ids[total], err);
2531                 emcore_show_user_message(multi_user_name, account_id, EMAIL_ACTION_SEND_MAIL, err);
2532         }
2533
2534         EM_SAFE_FREE(mail_ids);
2535
2536         if (err_code != NULL)
2537                 *err_code = err;
2538
2539         return ret;
2540 }
2541
2542 static int emcore_send_mail_smtp(char *multi_user_name,
2543                 SENDSTREAM *stream,
2544                 ENVELOPE *env,
2545                 char *data_file,
2546                 int account_id,
2547                 int mail_id,
2548                 int *err_code)
2549 {
2550         EM_DEBUG_FUNC_BEGIN_SEC("stream[%p], env[%p], data_file[%s], account_id[%d], mail_id[%d], err_code[%p]",
2551                         stream, env, data_file, account_id, mail_id, err_code);
2552         EM_PROFILE_BEGIN(profile_emcore_send_mail_smtp);
2553
2554         int ret = false;
2555         int err = EMAIL_ERROR_NONE;
2556         int recipients = 0;
2557         long total = 0, sent = 0, send_ret = 0, send_err = 0, sent_percent = 0, last_sent_percent = 0;
2558         char buf[2048] = { 0, };
2559         email_account_t *ref_account = NULL;
2560         FILE *fp = NULL;
2561
2562         if (!env || !env->from || (!env->to && !env->cc && !env->bcc)) {
2563                 if (env != NULL)
2564                         EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
2565                 err = EMAIL_ERROR_INVALID_PARAM;
2566                 goto FINISH_OFF;
2567         }
2568
2569         if (!env->from->mailbox || !env->from->host) {
2570                 EM_DEBUG_EXCEPTION("env->from->mailbox[%p], env->from->host[%p]", env->from->mailbox, env->from->host);
2571                 err = EMAIL_ERROR_INVALID_PARAM;
2572                 goto FINISH_OFF;
2573         }
2574
2575         if (!(ref_account = emcore_get_account_reference(multi_user_name, account_id, false))) {
2576                 EM_DEBUG_EXCEPTION("emcore_get_account_reference failed [%d]", account_id);
2577                 err = EMAIL_ERROR_INVALID_ACCOUNT;
2578                 goto FINISH_OFF;
2579         }
2580
2581         EM_DEBUG_LOG("Modifying - MAIL FROM ");
2582         if (ref_account->user_email_address == NULL) {
2583                 EM_DEBUG_LOG("ref_account->user_email_address is null!!");
2584                 SNPRINTF(buf, sizeof(buf), "FROM:<%s@%s>", env->from->mailbox, env->from->host);
2585         } else
2586                 SNPRINTF(buf, sizeof(buf), "FROM:<%s>", ref_account->user_email_address);
2587
2588         /*  set DSN for ESMTP */
2589         if (stream->protocol.esmtp.ok) {
2590                 if (stream->protocol.esmtp.eightbit.ok && stream->protocol.esmtp.eightbit.want)
2591                         strncat(buf, " BODY=8BITMIME", sizeof(buf)-(EM_SAFE_STRLEN(buf)+1));
2592
2593                 EM_DEBUG_LOG("stream->protocol.esmtp.dsn.ok [%d]", stream->protocol.esmtp.dsn.ok);
2594
2595                 if (stream->protocol.esmtp.dsn.ok && stream->protocol.esmtp.dsn.want) {
2596                         EM_DEBUG_LOG("stream->protocol.esmtp.dsn.want is required");
2597                         strncat(buf, stream->protocol.esmtp.dsn.full ? " RET=FULL" : " RET=HDRS",
2598                                         sizeof(buf)-EM_SAFE_STRLEN(buf)-1);
2599
2600                         if (stream->protocol.esmtp.dsn.envid)
2601                                 SNPRINTF(buf + EM_SAFE_STRLEN(buf), sizeof(buf)-(EM_SAFE_STRLEN(buf)),
2602                                                 " ENVID=%.100s", stream->protocol.esmtp.dsn.envid);
2603                 } else
2604                         EM_DEBUG_LOG("stream->protocol.esmtp.dsn.want is not required or DSN is not supported");
2605         }
2606
2607         EM_PROFILE_BEGIN(profile_prepare_and_head);
2608         send_ret = smtp_send(stream, "RSET", 0);
2609         EM_DEBUG_LOG("[SMTP] RSET --------> %s", stream->reply);
2610
2611         if (send_ret != SMTP_RESPONSE_OK) {
2612                 err = send_ret;
2613                 goto FINISH_OFF;
2614         }
2615
2616         send_ret = smtp_send(stream, "MAIL", buf);
2617         EM_DEBUG_LOG_SEC("[SMTP] MAIL %s --------> %s", buf, stream->reply);
2618
2619         switch (send_ret) {
2620         case SMTP_RESPONSE_OK:
2621                 break;
2622
2623         case SMTP_RESPONSE_WANT_AUTH:
2624         case SMTP_RESPONSE_WANT_AUTH2:
2625                 EM_DEBUG_EXCEPTION("SMTP error : authentication required...");
2626                 err = EMAIL_ERROR_AUTH_REQUIRED;
2627                 goto FINISH_OFF;
2628
2629         case SMTP_RESPONSE_UNAVAIL:
2630                 EM_DEBUG_EXCEPTION("SMTP error : sending unavailable...");
2631                 err = EMAIL_ERROR_SMTP_SEND_FAILURE;
2632                 goto FINISH_OFF;
2633         case SMTP_RESPONSE_CONNECTION_BROKEN:
2634                 EM_DEBUG_EXCEPTION("SMTP error : SMTP connection broken...");
2635                 err = EMAIL_ERROR_SMTP_SEND_FAILURE;
2636                 goto FINISH_OFF;
2637         default:
2638                 EM_DEBUG_EXCEPTION("SMTP error : sending unavailable...");
2639                 err = EMAIL_ERROR_SMTP_SEND_FAILURE;
2640                 goto FINISH_OFF;
2641         }
2642
2643         if (env->to) {
2644                 send_ret = smtp_rcpt(stream, env->to, &send_err);
2645                 EM_DEBUG_LOG_SEC("[SMTP] RCPT TO : <%s@%s> ... --------> %s", env->to->mailbox, env->to->host, env->to->error ? env->to->error  :  stream->reply);
2646                 if (send_ret) {
2647                         err = stream->replycode;
2648                         goto FINISH_OFF;
2649                 }
2650
2651                 if (!send_err)
2652                         recipients++;
2653         }
2654
2655         if (env->cc) {
2656                 send_ret = smtp_rcpt(stream, env->cc, &send_err);
2657                 EM_DEBUG_LOG_SEC("[SMTP] RCPT TO : <%s@%s> ... --------> %s", env->cc->mailbox, env->cc->host, env->cc->error ? env->cc->error  :  stream->reply);
2658                 if (send_ret) {
2659                         err = stream->replycode;
2660                         goto FINISH_OFF;
2661                 }
2662
2663                 if (!send_err)
2664                         recipients++;
2665         }
2666
2667         if (env->bcc) {
2668                 send_ret = smtp_rcpt(stream, env->bcc, &send_err);
2669                 EM_DEBUG_LOG_SEC("[SMTP] RCPT TO : <%s@%s> ... --------> %s", env->bcc->mailbox, env->bcc->host, env->bcc->error ? env->bcc->error  :  stream->reply);
2670                 if (send_ret) {
2671                         err = stream->replycode;
2672                         goto FINISH_OFF;
2673                 }
2674
2675                 if (!send_err)
2676                         recipients++;
2677         }
2678
2679         if (send_err) {
2680                 EM_DEBUG_EXCEPTION("One or more recipients failed...");
2681                 err = EMAIL_ERROR_INVALID_ADDRESS;
2682         }
2683
2684         if (!recipients) {
2685                 EM_DEBUG_EXCEPTION("No valid recipients...");
2686
2687                 switch (stream->replycode) {
2688                 case SMTP_RESPONSE_UNAVAIL:
2689                 case SMTP_RESPONSE_WANT_AUTH:
2690                 case SMTP_RESPONSE_WANT_AUTH2:
2691                         err = EMAIL_ERROR_AUTH_REQUIRED;
2692                         break;
2693
2694                 default:
2695                         err = EMAIL_ERROR_INVALID_ADDRESS;
2696                         break;
2697                 }
2698                 goto FINISH_OFF;
2699         }
2700
2701         send_ret = smtp_send(stream, "DATA", 0);
2702         EM_DEBUG_LOG_SEC("[SMTP] DATA --------> %s", stream->reply);
2703         EM_PROFILE_END(profile_prepare_and_head);
2704
2705         if (send_ret != SMTP_RESPONSE_READY) {
2706                 err = send_ret;
2707                 goto FINISH_OFF;
2708         }
2709
2710         if (data_file) {
2711                 EM_PROFILE_BEGIN(profile_open_file);
2712
2713                 err = em_fopen(data_file, "r+", &fp);
2714                 if (err != EMAIL_ERROR_NONE) {
2715                         EM_DEBUG_EXCEPTION("em_fopen(\"%s\") failed..., error:[%d]", data_file, err);
2716                         goto FINISH_OFF;
2717                 }
2718                 EM_PROFILE_END(profile_open_file);
2719
2720 #ifdef __FEATURE_SEND_OPTMIZATION__
2721                 char *data = NULL;
2722                 int read_size, allocSize, dataSize, gMaxAllocSize = 40960; /*  40KB */
2723                 int total_fixed = 0;
2724                 fseek(fp, 0, SEEK_END);
2725                 total = ftell(fp);
2726                 total_fixed = total;
2727                 fseek(fp, 0, SEEK_SET);
2728                 EM_DEBUG_LOG("total size [%ld]", total);
2729
2730                 if (total < gMaxAllocSize)
2731                         allocSize = total + 1;
2732                 else
2733                         allocSize = gMaxAllocSize;
2734
2735                 EM_PROFILE_BEGIN(profile_allocation);
2736                 /* Allocate a buffer of max 2MB to read from file */
2737                 data = (char *)em_malloc(allocSize);
2738                 allocSize--;
2739                 EM_PROFILE_END(profile_allocation);
2740
2741                 if (NULL == data) {
2742                         err = EMAIL_ERROR_SMTP_SEND_FAILURE;
2743                         goto FINISH_OFF;
2744                 }
2745
2746                 while (total) {
2747                         /* Cancel the sending event */
2748                         if (!emcore_check_send_mail_thread_status()) {
2749                                 EM_SAFE_FREE(data);
2750                                 EM_DEBUG_EXCEPTION(" emcore_check_send_mail_thread_status failed...");
2751                                 err = EMAIL_ERROR_CANCELLED;
2752                                 goto FINISH_OFF;
2753                         }
2754
2755                         if (total < allocSize)
2756                                 dataSize = total;
2757                         else
2758                                 dataSize = allocSize;
2759
2760                         memset(data, 0x0, dataSize+1);
2761                         read_size = fread(data, sizeof(char), dataSize, fp);
2762
2763                         if (read_size != dataSize) {
2764                                 /* read fail. */
2765                                 EM_SAFE_FREE(data);
2766                                 EM_DEBUG_EXCEPTION("Read from file failed");
2767                                 err = EMAIL_ERROR_SMTP_SEND_FAILURE;
2768                                 goto FINISH_OFF;
2769                         }
2770                         sent += read_size;
2771
2772                         if (!(send_ret = smtp_soutr_test(stream->netstream, data))) {
2773                                 EM_SAFE_FREE(data);
2774                                 EM_DEBUG_EXCEPTION("Failed to send the data ");
2775                                 err = EMAIL_ERROR_SMTP_SEND_FAILURE;
2776                                 goto FINISH_OFF;
2777                         } else {
2778                                 sent_percent = (int) ((double)sent / (double)total_fixed * 100.0);
2779                                 if (last_sent_percent + 5 <= sent_percent) {
2780                                         double progress = (double)sent / (double)total_fixed;
2781                                         if (!emcore_notify_network_event(NOTI_SEND_START, account_id, NULL, mail_id, sent_percent))
2782                                                 EM_DEBUG_EXCEPTION("emcore_notify_network_event[NOTI_SEND_START] Failed >>>>");
2783                                         last_sent_percent = sent_percent;
2784
2785                                         emcore_update_notification_for_send(account_id, mail_id, progress);
2786                                 }
2787                                 EM_DEBUG_LOG("Sent data Successfully. sent[%ld] total[%ld] datasize[%d]",
2788                                                 sent, total, dataSize);
2789                         }
2790                         total -= dataSize;
2791                 }
2792
2793                 EM_SAFE_FREE(data);
2794         }
2795 #else
2796                 fseek(fp, 0, SEEK_END);
2797                 total = ftell(fp);
2798                 fseek(fp, 0, SEEK_SET);
2799
2800                 while (fgets(buf, 1024, fp)) {
2801 #ifdef FEATURE_SEND_DATA_DEBUG
2802                         EM_DEBUG_LOG("%s", buf);
2803 #endif
2804                         sent += EM_SAFE_STRLEN(buf);
2805
2806                         if (!(send_ret = smtp_soutr(stream->netstream, buf)))
2807                                 break;
2808                         /*  Sending Progress Notification */
2809                         sent_percent = (int) ((double)sent / (double)total * 100.0);
2810                         if (last_sent_percent + 5 <= sent_percent) {
2811                                 /* Disabled Temporary
2812                                 if (!emcore_notify_network_event(NOTI_SEND_START, account_id, NULL, mail_id, sent_percent))
2813                                         EM_DEBUG_EXCEPTION(" emcore_notify_network_event[NOTI_SEND_START] Failed >>>>");
2814                                 */
2815                                 last_sent_percent = sent_percent;
2816                         }
2817                 }
2818
2819                 if (!send_ret) {
2820                         EM_DEBUG_EXCEPTION("smtp_soutr failed - %ld", send_ret);
2821                         err = EMAIL_ERROR_SMTP_SEND_FAILURE;
2822                         goto FINISH_OFF;
2823                 }
2824         }
2825 #endif
2826
2827         send_ret = smtp_send(stream, ".", 0);
2828         EM_DEBUG_LOG("[SMTP] . --------> %s", stream->reply);
2829
2830         if (send_ret != SMTP_RESPONSE_OK) {
2831                 err = send_ret;
2832                 goto FINISH_OFF;
2833         }
2834
2835         ret = true;
2836
2837 FINISH_OFF:
2838
2839         if (ret == false)
2840                 smtp_send(stream, "RSET", 0);
2841
2842         if (ref_account) {
2843                 emcore_free_account(ref_account);
2844                 EM_SAFE_FREE(ref_account);
2845         }
2846
2847         if (err_code)
2848                 *err_code = err;
2849
2850         if (fp)
2851                 fclose(fp);
2852
2853         EM_PROFILE_END(profile_emcore_send_mail_smtp);
2854         EM_DEBUG_FUNC_END("ret [%d]", ret);
2855         return ret;
2856 }
2857
2858 /* ------ rfc822 handle --------------------------------------------------- */
2859 #define RANDOM_NUMBER_LENGTH 35
2860
2861 char *emcore_generate_content_id_string(const char *hostname, int *err)
2862 {
2863         EM_DEBUG_FUNC_BEGIN_SEC("hostname[%p]", hostname);
2864
2865         if (!hostname) {
2866                 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
2867                 if (err)
2868                         *err = EMAIL_ERROR_INVALID_PARAM;
2869                 return NULL;
2870         }
2871
2872         int cid_length = RANDOM_NUMBER_LENGTH + EM_SAFE_STRLEN(hostname) + 2, random_number_1, random_number_2, random_number_3, random_number_4;
2873         char *cid_string = NULL;
2874         unsigned int seed = clock();
2875         cid_string = malloc(cid_length);
2876
2877         if (!cid_string) {
2878                 if (err)
2879                         *err = EMAIL_ERROR_OUT_OF_MEMORY;
2880                 return NULL;
2881         }
2882
2883         memset(cid_string, 0, cid_length);
2884
2885         srand(time(NULL) + rand_r(&seed));
2886         random_number_1 = rand_r(&seed) * rand_r(&seed);
2887         random_number_2 = rand_r(&seed) * rand_r(&seed);
2888         random_number_3 = rand_r(&seed) * rand_r(&seed);
2889         random_number_4 = rand_r(&seed) * rand_r(&seed);
2890
2891         SNPRINTF(cid_string, cid_length, "<%08x%08x%08x%08x@%s>", random_number_1, random_number_2, random_number_3, random_number_4, hostname);
2892
2893         if (err)
2894                 *err = EMAIL_ERROR_NONE;
2895
2896         EM_DEBUG_FUNC_END_SEC("cid_string [%s]", cid_string);
2897         return cid_string;
2898 }
2899
2900
2901 /* ------ attach_part----------------------------------------------------- */
2902 /*  data  :  if filename NULL, content data. */
2903 /*              else absolute path of file to be attached. */
2904 /*  data_len  :  length of data. if filename not NULL, ignored. */
2905 /*  file_name :  attahcment name. */
2906 static int attach_part(BODY *body, const unsigned char *data, int data_len,
2907                 char *filename, char *content_sub_type, int is_inline, int *err_code)
2908 {
2909         EM_DEBUG_FUNC_BEGIN_SEC("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);
2910
2911         int        ret = false;
2912         int        error = EMAIL_ERROR_NONE;
2913         int        has_special_character = 0;
2914         int        base64_file_name_length = 0;
2915         int        i = 0;
2916         int        mail_type = EMAIL_SMIME_NONE;
2917         gsize      bytes_read;
2918         gsize      bytes_written;
2919         char      *encoded_file_name = NULL;
2920         char      *extension = NULL;
2921         char      *base64_file_name = NULL;
2922         char      *result_file_name = NULL;
2923         char       content_disposition[100] = { 0, };
2924         PARAMETER *last_param = NULL;
2925         PARAMETER *param = NULL;
2926         PART      *last_part = NULL;
2927         PART      *part = NULL;
2928         SIZEDTEXT  source_text;
2929         GError    *glib_error = NULL;
2930         CHARSET   *result_charset = NULL;
2931
2932         if (!body) {
2933                 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
2934                 error = EMAIL_ERROR_INVALID_PARAM;
2935                 goto FINISH_OFF;
2936         }
2937
2938         if (body->nested.part) {
2939                 last_part = body->nested.part;
2940
2941                 if (last_part != NULL) {
2942                         while (last_part->next)
2943                                 last_part = last_part->next;
2944                 }
2945         }
2946
2947         /*  PART */
2948         part = mail_newbody_part();
2949         if (part == NULL) {
2950                 EM_DEBUG_EXCEPTION("mail_newbody_part failed...");
2951                 error = EMAIL_ERROR_OUT_OF_MEMORY;
2952                 goto FINISH_OFF;
2953         }
2954
2955         /* add it to the last */
2956         part->next = NULL;
2957         if (last_part)
2958                 last_part->next = part;
2959         else
2960                 body->nested.part = part;
2961
2962         last_part = part;
2963
2964         /* set data..  */
2965         /* content_data = (unsigned char  *)fs_get(data_len + 1); */
2966         /* memcpy(content_data, data, data_len); */
2967         /* content_data[data_len] = 0; */
2968
2969         /* part->body.contents.text.data = content_data; */
2970         /* part->body.contents.text.size = data_len; */
2971
2972         if (filename) {   /*  attachment */
2973                 source_text.data = (unsigned char*)filename;
2974                 source_text.size = EM_SAFE_STRLEN(filename);
2975
2976                 result_charset   = (CHARSET*)utf8_infercharset(&source_text);
2977
2978                 if (result_charset) {
2979                         EM_DEBUG_LOG_SEC("return_charset->name [%s]", result_charset->name);
2980                         encoded_file_name = (char*)g_convert(filename, -1, "UTF-8", result_charset->name, &bytes_read, &bytes_written, &glib_error);
2981                 } else {
2982                         i = 0;
2983                         while (filename[i]) {
2984                                 if (filename[i++] & 0x80) {
2985                                         has_special_character = 1;
2986                                         break;
2987                                 }
2988                         }
2989                         EM_DEBUG_LOG("has_special_character [%d]", has_special_character);
2990                         if (has_special_character)
2991                                 encoded_file_name = (char*)g_convert(filename, -1, "UTF-8", "EUC-KR", &bytes_read, &bytes_written, &glib_error);
2992                 }
2993
2994                 EM_DEBUG_LOG_SEC("encoded_file_name [%s]", encoded_file_name);
2995
2996                 if (encoded_file_name == NULL)
2997                         encoded_file_name = strdup(filename);
2998
2999                 if (!em_encode_base64(encoded_file_name, EM_SAFE_STRLEN(encoded_file_name), &base64_file_name, (unsigned long*)&base64_file_name_length, &error)) {
3000                         EM_DEBUG_EXCEPTION("em_encode_base64 failed. error [%d]", error);
3001                         goto FINISH_OFF;
3002                 }
3003
3004                 result_file_name = em_replace_all_string(base64_file_name, "\015\012", "");
3005
3006                 EM_DEBUG_LOG("base64_file_name_length [%d]", base64_file_name_length);
3007
3008                 if (result_file_name) {
3009                         EM_SAFE_FREE(encoded_file_name);
3010                         encoded_file_name = em_malloc(EM_SAFE_STRLEN(result_file_name) + 15);
3011                         if (!encoded_file_name) {
3012                                 EM_DEBUG_EXCEPTION("em_mallocfailed.");
3013                                 goto FINISH_OFF;
3014                         }
3015                         snprintf(encoded_file_name, EM_SAFE_STRLEN(result_file_name) + 15, "=?UTF-8?B?%s?=", result_file_name);
3016                         EM_DEBUG_LOG_SEC("encoded_file_name [%s]", encoded_file_name);
3017                 }
3018
3019                 extension = em_get_extension_from_file_path(filename, NULL);
3020
3021                 part->body.type = em_get_content_type_from_extension_string(extension, NULL);
3022                 if (part->body.type == TYPEIMAGE) {
3023                         part->body.subtype = strdup(extension);
3024                         part->body.encoding = ENCBINARY;
3025                 } else if (part->body.type == TYPEPKCS7_SIGN) {
3026                         part->body.subtype = strdup("pkcs7-signature");
3027                         part->body.type = TYPEAPPLICATION;
3028                         part->body.encoding = ENCBINARY;
3029                 } else if (part->body.type == TYPEPKCS7_MIME) {
3030                         part->body.subtype = strdup("pkcs7-mime");
3031                         part->body.type = TYPEAPPLICATION;
3032                         part->body.encoding = ENCBINARY;
3033                 } else if (part->body.type == TYPEPGP) {
3034                         part->body.type     = TYPEAPPLICATION;
3035                         part->body.subtype  = EM_SAFE_STRDUP(content_sub_type);
3036                         part->body.encoding = ENC7BIT;
3037                 } else {
3038                         part->body.subtype = strdup("octet-stream");
3039                         part->body.encoding = ENCBINARY;
3040                 }
3041
3042                 if (!extension && content_sub_type) {
3043                         char *p = NULL;
3044
3045                         if (strcasecmp(content_sub_type, "IMAGE") == 0) {
3046                                 part->body.type = TYPEIMAGE;
3047                                 if ((p = strstr(content_sub_type, "/"))) {
3048                                         EM_SAFE_FREE(part->body.subtype);
3049                                         part->body.subtype = EM_SAFE_STRDUP(p+1);
3050                                 }
3051                         }
3052                 }
3053
3054                 part->body.size.bytes = data_len;
3055
3056                 if (data)
3057                         part->body.sparep = EM_SAFE_STRDUP((char *)data); /*  file path */
3058                 else
3059                         part->body.sparep = NULL;
3060
3061                 SNPRINTF(content_disposition, sizeof(content_disposition), "%s", "attachment");
3062
3063                 part->body.disposition.type = cpystr(content_disposition);
3064
3065                 /*  BODY PARAMETER */
3066                 /*  another parameter or get parameter-list from this   function-parameter */
3067                 param = mail_newbody_parameter();
3068                 if (param == NULL) {
3069                         EM_DEBUG_EXCEPTION("mail_newbody_parameter failed...");
3070                         error = EMAIL_ERROR_OUT_OF_MEMORY;
3071                         goto FINISH_OFF;
3072                 }
3073
3074                 param->attribute          = cpystr("name");
3075                 param->value              = cpystr(encoded_file_name);
3076                 param->next               = NULL;
3077                 last_param                = param;
3078                 last_part->body.parameter = last_param;
3079
3080                 if (is_inline) {
3081                         /*  CONTENT-ID */
3082                         part->body.id = emcore_generate_content_id_string("org.tizen.email", &error);
3083                         part->body.type = TYPEIMAGE;
3084                         /*  EM_SAFE_FREE(part->body.subtype); */
3085                         /*  part->body.subtype = EM_SAFE_STRDUP(content_sub_type); */
3086                 }
3087
3088                 /*  DISPOSITION PARAMETER */
3089                 param = mail_newbody_parameter();
3090                 if (param == NULL) {
3091                         EM_DEBUG_EXCEPTION("mail_newbody_parameter failed...");
3092                         error = EMAIL_ERROR_OUT_OF_MEMORY;
3093                         goto FINISH_OFF;
3094                 }
3095
3096                 param->attribute                      = cpystr("filename");
3097                 param->value                          = cpystr(encoded_file_name);
3098                 param->next                           = NULL;
3099                 last_param                            = param;
3100                 last_part->body.disposition.parameter = last_param;
3101
3102                 if (is_inline)
3103                         last_part->body.disposition.type = strdup("inline");
3104         } else {
3105                 if (content_sub_type && !strcasecmp(content_sub_type, "pgp-encrypted"))
3106                         mail_type = EMAIL_PGP_ENCRYPTED;
3107
3108                 if (mail_type != EMAIL_PGP_ENCRYPTED) {
3109                         /*  text body (plain/html) */
3110                         part->body.type = TYPETEXT;
3111                         part->body.size.bytes = data_len;
3112
3113                         if (data)
3114                                 part->body.sparep = EM_SAFE_STRDUP((char *)data); /*  file path */
3115                         else
3116                                 part->body.sparep = NULL;
3117
3118
3119                         if (!content_sub_type) {
3120                                 /* Plain text body */
3121                                 part->body.encoding = ENC8BIT;
3122                                 part->body.subtype = cpystr("plain");
3123                                 last_param = part->body.parameter;
3124
3125                                 if (last_param != NULL) {
3126                                         while (last_param->next)
3127                                                 last_param = last_param->next;
3128                                 }
3129
3130                                 param = mail_newbody_parameter();
3131
3132                                 if (param == NULL) {
3133                                         EM_DEBUG_EXCEPTION("mail_newbody_parameter failed...");
3134                                         error = EMAIL_ERROR_OUT_OF_MEMORY;
3135                                         goto FINISH_OFF;
3136                                 }
3137
3138                                 param->attribute = cpystr("CHARSET");
3139
3140                                 if (data != NULL) {
3141                                         gchar *extract_charset_plain = g_path_get_basename((const gchar *)data);
3142                                         if (extract_charset_plain != NULL && extract_charset_plain[0] != '\0')
3143                                                 param->value = cpystr(extract_charset_plain);
3144                                         g_free(extract_charset_plain);
3145                                 } else
3146                                         param->value = cpystr("UTF-8");
3147
3148                                 if (!param->value)
3149                                         param->value = cpystr("UTF-8");
3150
3151                                 param->next = NULL;
3152
3153                                 if (last_param != NULL)
3154                                         last_param->next = param;
3155                                 else
3156                                         part->body.parameter = param;
3157                         } else {
3158                                 /* HTML text body */
3159                                 part->body.encoding = ENC8BIT;
3160                                 part->body.subtype  = cpystr(content_sub_type);
3161
3162                                 last_param = part->body.parameter;
3163
3164                                 if (last_param != NULL) {
3165                                         while (last_param->next)
3166                                                 last_param = last_param->next;
3167                                 }
3168
3169                                 param = mail_newbody_parameter();
3170
3171                                 if (param == NULL) {
3172                                         EM_DEBUG_EXCEPTION("mail_newbody_parameter failed...");
3173                                         error = EMAIL_ERROR_OUT_OF_MEMORY;
3174                                         goto FINISH_OFF;
3175                                 }
3176
3177                                 param->attribute = cpystr("CHARSET");
3178
3179                                 char *pHtml = NULL;
3180                                 if (data != NULL) {
3181                                         gchar *extract_charset = g_path_get_basename((const gchar *)data);
3182                                         if (extract_charset != NULL) {
3183                                                 if ((pHtml = strstr(extract_charset, ".htm")) != NULL) {
3184                                                         extract_charset[pHtml-extract_charset] = '\0';
3185                                                         param->value = cpystr(extract_charset);
3186                                                 }
3187                                         }
3188
3189                                         if (!param->value)
3190                                                 param->value = cpystr("UTF-8");
3191
3192                                         EM_SAFE_FREE(extract_charset);
3193                                 } else
3194                                         param->value = cpystr("UTF-8");
3195                                 param->next = NULL;
3196
3197                                 if (last_param != NULL)
3198                                         last_param->next = param;
3199                                 else
3200                                         part->body.parameter = param;
3201                         }
3202
3203                         /* NOTE : need to require this code. */
3204                         /* sprintf(content_disposition, "%s\0", "inline"); */
3205                         if (is_inline) {
3206                                 SNPRINTF(content_disposition, sizeof(content_disposition), "%s", "inline");
3207                                 part->body.disposition.type = cpystr(content_disposition);
3208                         }
3209                 } else {
3210                         part->body.type = TYPEAPPLICATION;
3211                         part->body.subtype = strdup(content_sub_type);
3212                         part->body.size.bytes = data_len;
3213                         part->body.encoding = ENC7BIT;
3214
3215                         if (data)
3216                                 part->body.sparep = EM_SAFE_STRDUP((char *)data); /*  file path */
3217                         else {
3218                                 part->body.contents.text.data = (unsigned char *)strdup("Version: 1");
3219                                 part->body.contents.text.size = strlen("Version: 1");
3220                         }
3221                 }
3222         }
3223
3224         ret = true;
3225
3226 FINISH_OFF:
3227         EM_SAFE_FREE(encoded_file_name);
3228         EM_SAFE_FREE(result_file_name); /*prevent 26242*/
3229         EM_SAFE_FREE(base64_file_name);
3230         EM_SAFE_FREE(glib_error);
3231         if (err_code != NULL)
3232                 *err_code = error;
3233         EM_DEBUG_FUNC_END();
3234         return ret;
3235 }
3236
3237 static PART *attach_multipart_with_sub_type(BODY *parent_body, char *sub_type, int *err_code)
3238 {
3239         EM_DEBUG_FUNC_BEGIN("parent_body[%p], sub_type [%s], err_code[%p]", parent_body, sub_type, err_code);
3240
3241         int error = EMAIL_ERROR_NONE;
3242
3243         PART *tail_part_cur = NULL;
3244         PART *new_part = NULL;
3245
3246         if (!parent_body || !sub_type) {
3247                 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
3248                 error = EMAIL_ERROR_INVALID_PARAM;
3249                 goto FINISH_OFF;
3250         }
3251
3252         if (parent_body->nested.part) {
3253                 tail_part_cur = parent_body->nested.part;
3254
3255                 if (tail_part_cur != NULL) {
3256                         while (tail_part_cur->next)
3257                                 tail_part_cur = tail_part_cur->next;
3258                 }
3259         }
3260
3261         new_part = mail_newbody_part();
3262
3263         if (new_part == NULL) {
3264                 EM_DEBUG_EXCEPTION("EMAIL_ERROR_OUT_OF_MEMORY");
3265                 error = EMAIL_ERROR_OUT_OF_MEMORY;
3266                 goto FINISH_OFF;
3267
3268         }
3269
3270         new_part->next = NULL;
3271         new_part->body.type = TYPEMULTIPART;
3272         new_part->body.subtype = EM_SAFE_STRDUP(sub_type);
3273
3274         if (tail_part_cur)
3275                 tail_part_cur->next = new_part;
3276         else
3277                 parent_body->nested.part = new_part;
3278
3279 FINISH_OFF:
3280
3281         if (err_code)
3282                 *err_code = error;
3283
3284         EM_DEBUG_FUNC_END();
3285
3286         return new_part;
3287 }
3288 #ifdef __FEATURE_SUPPORT_REPORT_MAIL__
3289 static int attach_attachment_to_body(char *multi_user_name, BODY **multipart_body, BODY *text_body, emstorage_attachment_tbl_t *input_attachment_tbl, int input_attachment_tbl_count, int *err_code)
3290 {
3291         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);
3292
3293         int ret = false;
3294         int i = 0;
3295         int error = EMAIL_ERROR_NONE;
3296         BODY *frame_body = NULL;
3297         char *prefix_path = NULL;
3298         char real_file_path[MAX_PATH] = {0};
3299
3300         /*  make multipart body(multipart frame_body..) .. that has not content..  */
3301
3302         if (!multipart_body || !text_body || !input_attachment_tbl) {
3303                 EM_DEBUG_EXCEPTION(" multipart_body[%p], text_body[%p], input_attachment_tbl[%p]", multipart_body, text_body, input_attachment_tbl);
3304                 error = EMAIL_ERROR_INVALID_PARAM;
3305                 goto FINISH_OFF;
3306         }
3307
3308         frame_body = mail_newbody();
3309         if (frame_body == NULL) {
3310                 EM_DEBUG_EXCEPTION("mail_newbody failed...");
3311                 error = EMAIL_ERROR_OUT_OF_MEMORY;
3312                 goto FINISH_OFF;
3313         }
3314
3315         frame_body->type = TYPEMULTIPART;
3316         frame_body->contents.text.data = NULL;
3317         frame_body->contents.text.size = 0;
3318         frame_body->size.bytes = 0;
3319
3320         /*  insert original text_body to frame_body.. */
3321         if (!attach_part(frame_body, text_body->sparep, 0, NULL, NULL, false, &error)) {
3322                 EM_DEBUG_EXCEPTION(" attach_partfailed [%d]", error);
3323                 goto FINISH_OFF;
3324         }
3325
3326         /*  insert files..  */
3327         emstorage_attachment_tbl_t *temp_attachment_tbl = NULL;
3328         char *name = NULL;
3329         struct stat st_buf;
3330
3331         if (EM_SAFE_STRLEN(multi_user_name) > 0) {
3332                 error = emcore_get_container_path(multi_user_name, &prefix_path);
3333                 if (error != EMAIL_ERROR_NONE) {
3334                         EM_DEBUG_EXCEPTION("emcore_get_container_path failed : [%d]", error);
3335                         goto FINISH_OFF;
3336                 }
3337         } else {
3338                 prefix_path = strdup("");
3339         }
3340
3341         for (i = 0; i < input_attachment_tbl_count; i++) {
3342                 temp_attachment_tbl = input_attachment_tbl + i;
3343
3344                 EM_DEBUG_LOG("insert files - attachment id[%d]", temp_attachment_tbl->attachment_id);
3345
3346                 memset(real_file_path, 0x00, sizeof(real_file_path));
3347                 SNPRINTF(real_file_path, sizeof(real_file_path), "%s%s", prefix_path, temp_attachment_tbl->attachment_path);
3348
3349                 if (stat(temp_attachment_tbl->attachment_path, &st_buf) == 0) {
3350                         if (!temp_attachment_tbl->attachment_name) {
3351                                 if (!emcore_get_file_name(real_file_path, &name, &error)) {
3352                                         EM_DEBUG_EXCEPTION("emcore_get_file_name failed [%d]", error);
3353                                         goto FINISH_OFF;
3354                                 }
3355                         } else
3356                                 name = temp_attachment_tbl->attachment_name;
3357
3358                         if (!attach_part(frame_body, (unsigned char *)real_file_path, 0, name, NULL, false, &error)) {
3359                                 EM_DEBUG_EXCEPTION("attach_partfailed [%d]", error);
3360                                 goto FINISH_OFF;
3361                         }
3362                 }
3363         }
3364
3365         ret = true;
3366
3367 FINISH_OFF:
3368
3369         EM_SAFE_FREE(prefix_path);
3370
3371         if (ret == true)
3372                 *multipart_body = frame_body;
3373         else if (frame_body != NULL)
3374                 mail_free_body(&frame_body);
3375
3376         if (err_code != NULL)
3377                 *err_code = error;
3378         EM_DEBUG_FUNC_END();
3379         return ret;
3380 }
3381 #endif
3382 static char *emcore_encode_rfc2047_text(char *utf8_text, int *err_code)
3383 {
3384         EM_DEBUG_FUNC_BEGIN_SEC("utf8_text[%s], err_code[%p]", utf8_text, err_code);
3385
3386         if (utf8_text == NULL) {
3387                 if (err_code != NULL)
3388                         *err_code = EMAIL_ERROR_INVALID_PARAM;
3389                 return NULL;
3390         }
3391
3392         gsize len = EM_SAFE_STRLEN(utf8_text);
3393
3394         EM_DEBUG_FUNC_END();
3395
3396         if (len > 0) {
3397                 return emcore_gmime_get_encoding_to_utf8(utf8_text);
3398                 //              return g_strdup(utf8_text);    /* emoji handle */
3399         } else
3400                 return strdup("");
3401 }
3402
3403 static void emcore_encode_rfc2047_address(ADDRESS *address, int *err_code)
3404 {
3405         EM_DEBUG_FUNC_BEGIN("address[%p], err_code[%p]", address, err_code);
3406
3407         while (address) {
3408                 if (address->personal) {
3409                         char *rfc2047_personal = emcore_encode_rfc2047_text(address->personal, err_code);
3410                         EM_SAFE_FREE(address->personal);
3411                         address->personal = rfc2047_personal;
3412                 }
3413                 address = address->next;
3414         }
3415         EM_DEBUG_FUNC_END();
3416 }
3417
3418 #define DATE_STR_LENGTH 100
3419
3420 static int emcore_make_envelope_from_mail(char *multi_user_name, emstorage_mail_tbl_t *input_mail_tbl_data, ENVELOPE **output_envelope)
3421 {
3422         EM_DEBUG_FUNC_BEGIN("input_mail_tbl_data[%p], output_envelope[%p]", input_mail_tbl_data, output_envelope);
3423
3424         int ret = false;
3425         int error = EMAIL_ERROR_NONE;
3426         int is_incomplete = 0;
3427         char *pAdd = NULL;
3428         ENVELOPE *envelope = NULL;
3429         email_account_t *ref_account = NULL;
3430
3431         if (!input_mail_tbl_data || !output_envelope) {
3432                 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
3433                 error = EMAIL_ERROR_INVALID_PARAM;
3434                 return error; /* prevent 32729 */
3435         }
3436
3437         if ((input_mail_tbl_data->report_status & EMAIL_MAIL_REPORT_MDN) != 0 && !input_mail_tbl_data->body_download_status) {
3438                 EM_DEBUG_EXCEPTION("input_mail_tbl_data->body_download_status[%d]", input_mail_tbl_data->body_download_status);
3439                 error = EMAIL_ERROR_INVALID_PARAM;
3440                 goto FINISH_OFF;
3441         }
3442
3443         if (!(envelope = mail_newenvelope())) {
3444                 EM_DEBUG_EXCEPTION("mail_newenvelope failed...");
3445                 error = EMAIL_ERROR_OUT_OF_MEMORY;
3446                 goto FINISH_OFF;
3447         }
3448
3449         is_incomplete = input_mail_tbl_data->flags_draft_field || (input_mail_tbl_data->save_status == EMAIL_MAIL_STATUS_SENDING);
3450
3451         if (is_incomplete && (input_mail_tbl_data->account_id > 0)) {
3452                 ref_account = emcore_get_account_reference(multi_user_name, input_mail_tbl_data->account_id, false);
3453                 if (!ref_account) {
3454                         EM_DEBUG_EXCEPTION("emcore_get_account_reference failed [%d]", input_mail_tbl_data->account_id);
3455                         error = EMAIL_ERROR_INVALID_ACCOUNT;
3456                         goto FINISH_OFF;
3457                 }
3458
3459                 if (ref_account->user_email_address && ref_account->user_email_address[0] != '\0') {
3460                         char *p = cpystr(ref_account->user_email_address);
3461
3462                         if (p == NULL) {
3463                                 EM_DEBUG_EXCEPTION("cpystr failed...");
3464                                 error = EMAIL_ERROR_OUT_OF_MEMORY;
3465                                 goto FINISH_OFF;
3466                         }
3467
3468                         EM_DEBUG_LOG("Assign envelope->from");
3469
3470                         if (input_mail_tbl_data->full_address_from) {
3471                                 char *temp_address_string = NULL ;
3472                                 em_skip_whitespace_without_alias(input_mail_tbl_data->full_address_from , &temp_address_string);
3473                                 EM_DEBUG_LOG_SEC("address[temp_address_string][%s]", temp_address_string);
3474                                 rfc822_parse_adrlist(&envelope->from, temp_address_string, NULL);
3475                                 EM_SAFE_FREE(temp_address_string);
3476                                 temp_address_string = NULL ;
3477                         } else
3478                                 envelope->from = rfc822_parse_mailbox(&p, NULL);
3479
3480                         EM_SAFE_FREE(p);
3481                         if (!envelope->from) {
3482                                 EM_DEBUG_EXCEPTION("rfc822_parse_mailbox failed...");
3483                                 error = EMAIL_ERROR_INVALID_ADDRESS;
3484                                 goto FINISH_OFF;
3485                         } else {
3486                                 if (envelope->from->personal == NULL) {
3487                                         if (ref_account->options.display_name_from && ref_account->options.display_name_from[0] != '\0')
3488                                                 envelope->from->personal = cpystr(ref_account->options.display_name_from);
3489                                         else
3490                                                 envelope->from->personal =
3491                                                         (ref_account->user_display_name && ref_account->user_display_name[0] != '\0') ?
3492                                                         cpystr(ref_account->user_display_name)  :  NULL;
3493                                 }
3494                         }
3495                 }
3496
3497                 if (ref_account->return_address && ref_account->return_address[0] != '\0') {
3498                         char *p = cpystr(ref_account->return_address);
3499
3500                         if (p == NULL) {
3501                                 EM_DEBUG_EXCEPTION("cpystr failed...");
3502                                 error = EMAIL_ERROR_OUT_OF_MEMORY;
3503                                 goto FINISH_OFF;
3504                         }
3505                         envelope->return_path = rfc822_parse_mailbox(&p, NULL);
3506                         EM_SAFE_FREE(p);
3507                 }
3508         } else {
3509                 /*
3510                    if (input_mail_tbl_data->full_address_from == NULL) {
3511                    EM_DEBUG_EXCEPTION("input_mail_tbl_data->full_address_from[%p]", input_mail_tbl_data->full_address_from);
3512                    error = EMAIL_ERROR_INVALID_MAIL;
3513                    goto FINISH_OFF;
3514                    }
3515                    */
3516                 int i, j;
3517
3518                 if (input_mail_tbl_data->full_address_from) {
3519                         for (i = 0, j = EM_SAFE_STRLEN(input_mail_tbl_data->full_address_from); i < j; i++) {
3520                                 if (input_mail_tbl_data->full_address_from[i] == ';')
3521                                         input_mail_tbl_data->full_address_from[i] = ',';
3522                         }
3523                 }
3524
3525                 if (input_mail_tbl_data->full_address_return) {
3526                         for (i = 0, j = EM_SAFE_STRLEN(input_mail_tbl_data->full_address_return); i < j; i++) {
3527                                 if (input_mail_tbl_data->full_address_return[i] == ';')
3528                                         input_mail_tbl_data->full_address_return[i] = ',';
3529                         }
3530                 }
3531                 em_skip_whitespace_without_alias(input_mail_tbl_data->full_address_from , &pAdd);
3532                 EM_DEBUG_LOG_SEC("address[pAdd][%s]", pAdd);
3533
3534                 rfc822_parse_adrlist(&envelope->from, pAdd, NULL);
3535                 EM_SAFE_FREE(pAdd);
3536                 pAdd = NULL;
3537
3538                 em_skip_whitespace(input_mail_tbl_data->full_address_return , &pAdd);
3539                 EM_DEBUG_LOG_SEC("address[pAdd][%s]", pAdd);
3540
3541                 rfc822_parse_adrlist(&envelope->return_path, pAdd, NULL);
3542                 EM_SAFE_FREE(pAdd);
3543                 pAdd = NULL;
3544         }
3545
3546         {
3547                 int i, j;
3548
3549                 if (input_mail_tbl_data->full_address_to) {
3550                         for (i = 0, j = EM_SAFE_STRLEN(input_mail_tbl_data->full_address_to); i < j; i++) {
3551                                 if (input_mail_tbl_data->full_address_to[i] == ';')
3552                                         input_mail_tbl_data->full_address_to[i] = ',';
3553                         }
3554                 }
3555
3556                 if (input_mail_tbl_data->full_address_cc) {
3557                         for (i = 0, j = EM_SAFE_STRLEN(input_mail_tbl_data->full_address_cc); i < j; i++) {
3558                                 if (input_mail_tbl_data->full_address_cc[i] == ';')
3559                                         input_mail_tbl_data->full_address_cc[i] = ',';
3560                         }
3561                 }
3562
3563                 if (input_mail_tbl_data->full_address_bcc) {
3564                         for (i = 0, j = EM_SAFE_STRLEN(input_mail_tbl_data->full_address_bcc); i < j; i++) {
3565                                 if (input_mail_tbl_data->full_address_bcc[i] == ';')
3566                                         input_mail_tbl_data->full_address_bcc[i] = ',';
3567                         }
3568                 }
3569         }
3570
3571         envelope->message_id = EM_SAFE_STRDUP(input_mail_tbl_data->message_id);
3572         EM_DEBUG_LOG_SEC("message_id[%s]", envelope->message_id);
3573
3574         em_skip_whitespace(input_mail_tbl_data->full_address_to , &pAdd);
3575         EM_DEBUG_LOG_SEC("address[pAdd][%s]", pAdd);
3576
3577         rfc822_parse_adrlist(&envelope->to, pAdd, NULL);
3578         EM_SAFE_FREE(pAdd);
3579         pAdd = NULL ;
3580
3581         EM_DEBUG_LOG_SEC("address[input_mail_tbl_data->full_address_cc][%s]", input_mail_tbl_data->full_address_cc);
3582         em_skip_whitespace(input_mail_tbl_data->full_address_cc , &pAdd);
3583         EM_DEBUG_LOG_SEC("address[pAdd][%s]", pAdd);
3584
3585         rfc822_parse_adrlist(&envelope->cc, pAdd, NULL);
3586         EM_SAFE_FREE(pAdd);
3587         pAdd = NULL ;
3588
3589         em_skip_whitespace(input_mail_tbl_data->full_address_bcc , &pAdd);
3590         rfc822_parse_adrlist(&envelope->bcc, pAdd, NULL);
3591         EM_SAFE_FREE(pAdd);
3592         pAdd = NULL ;
3593
3594         emcore_encode_rfc2047_address(envelope->return_path, &error);
3595         emcore_encode_rfc2047_address(envelope->from, &error);
3596         emcore_encode_rfc2047_address(envelope->sender, &error);
3597         emcore_encode_rfc2047_address(envelope->reply_to, &error);
3598         emcore_encode_rfc2047_address(envelope->to, &error);
3599         emcore_encode_rfc2047_address(envelope->cc, &error);
3600         emcore_encode_rfc2047_address(envelope->bcc, &error);
3601
3602         if (input_mail_tbl_data->subject) {
3603                 envelope->subject = emcore_encode_rfc2047_text(
3604                                 input_mail_tbl_data->subject, &error);
3605         }
3606
3607         char rfc822_date_string[DATE_STR_LENGTH] = { 0, };
3608         rfc822_date(rfc822_date_string);
3609
3610         EM_DEBUG_LOG("rfc822_date : [%s]", rfc822_date_string);
3611
3612         if (!is_incomplete) {
3613                 char  localtime_string[DATE_STR_LENGTH] = { 0, };
3614                 time_t tn     = time(0);
3615                 struct tm time_buf;
3616                 struct tm *t  = gmtime_r(&tn, &time_buf);
3617                 if (t == NULL) {
3618                         EM_DEBUG_EXCEPTION("gmtime failed");
3619                         error = EMAIL_ERROR_SYSTEM_FAILURE;
3620                         goto FINISH_OFF;
3621                 }
3622
3623                 int zone      = t->tm_hour * 60 + t->tm_min;
3624                 int julian    = t->tm_yday;
3625
3626                 struct tm t_buf;
3627                 t = localtime_r(&input_mail_tbl_data->date_time, &t_buf);
3628                 if (t == NULL) {
3629                         EM_DEBUG_EXCEPTION("localtime failed");
3630                         error = EMAIL_ERROR_SYSTEM_FAILURE;
3631                         goto FINISH_OFF;
3632                 }
3633
3634                 zone = t->tm_hour * 60 + t->tm_min - zone;
3635
3636                 if ((julian = t->tm_yday - julian))
3637                         zone += ((julian < 0) == (abs(julian) == 1)) ? -24 * 60 : 24*60;
3638
3639                 SNPRINTF(localtime_string, DATE_STR_LENGTH, "%s, %d %s %d %02d:%02d:%02d "
3640                                 , days[t->tm_wday]
3641                                 , t->tm_mday
3642                                 , months[t->tm_mon]
3643                                 , t->tm_year + 1900
3644                                 , t->tm_hour
3645                                 , t->tm_min
3646                                 , t->tm_sec
3647                                 );
3648
3649                 EM_DEBUG_LOG("localtime string : [%s]", localtime_string);
3650                 /* append last 5byes("+0900") */
3651                 g_strlcat(localtime_string, strchr(rfc822_date_string, '+'), DATE_STR_LENGTH);
3652                 envelope->date = (unsigned char *)cpystr((const char *)localtime_string);
3653         } else {
3654                 envelope->date = (unsigned char *)cpystr((const char *)rfc822_date_string);
3655         }
3656
3657         ret = true;
3658
3659 FINISH_OFF:
3660
3661         if (ret)
3662                 *output_envelope = envelope;
3663         else {
3664                 mail_free_envelope(&envelope);
3665                 *output_envelope = NULL;
3666         }
3667
3668         if (ref_account) {
3669                 emcore_free_account(ref_account);
3670                 EM_SAFE_FREE(ref_account);
3671         }
3672
3673         EM_DEBUG_FUNC_END("error [%d]", error);
3674         return error;
3675 }
3676
3677 static char *emcore_get_digest_string(int digest_type, int mime_type)
3678 {
3679         EM_DEBUG_FUNC_BEGIN();
3680         char *digest_string = NULL;
3681         char p_digest_string[100] = {0, };
3682
3683         switch (mime_type) {
3684         case EMAIL_SMIME_SIGNED:
3685         case EMAIL_SMIME_ENCRYPTED:
3686         case EMAIL_SMIME_SIGNED_AND_ENCRYPTED:
3687                 memset(p_digest_string, 0x00, sizeof(p_digest_string));
3688                 break;
3689         case EMAIL_PGP_SIGNED:
3690         case EMAIL_PGP_ENCRYPTED:
3691         case EMAIL_PGP_SIGNED_AND_ENCRYPTED:
3692                 memset(p_digest_string, 0x00, sizeof(p_digest_string));
3693                 g_strlcpy(p_digest_string, "pgp-", sizeof(p_digest_string));
3694                 break;
3695         }
3696
3697         switch (digest_type) {
3698         case DIGEST_TYPE_SHA1:
3699                 strncat(p_digest_string, "sha1", sizeof(p_digest_string) - EM_SAFE_STRLEN(p_digest_string) - 1);
3700                 break;
3701         case DIGEST_TYPE_MD5:
3702                 strncat(p_digest_string, "md5", sizeof(p_digest_string) - EM_SAFE_STRLEN(p_digest_string) - 1);
3703                 break;
3704         case DIGEST_TYPE_RIPEMD160:
3705                 strncat(p_digest_string, "ripemd160", sizeof(p_digest_string) - EM_SAFE_STRLEN(p_digest_string) - 1);
3706                 break;
3707         case DIGEST_TYPE_MD2:
3708                 strncat(p_digest_string, "md2", sizeof(p_digest_string) - EM_SAFE_STRLEN(p_digest_string) - 1);
3709                 break;
3710         case DIGEST_TYPE_TIGER192:
3711                 strncat(p_digest_string, "tiger192", sizeof(p_digest_string) - EM_SAFE_STRLEN(p_digest_string) - 1);
3712                 break;
3713         case DIGEST_TYPE_HAVAL5160:
3714                 strncat(p_digest_string, "haval5160", sizeof(p_digest_string) - EM_SAFE_STRLEN(p_digest_string) - 1);
3715                 break;
3716         case DIGEST_TYPE_SHA256:
3717                 strncat(p_digest_string, "sha256", sizeof(p_digest_string) - EM_SAFE_STRLEN(p_digest_string) - 1);
3718                 break;
3719         case DIGEST_TYPE_SHA384:
3720                 strncat(p_digest_string, "sha384", sizeof(p_digest_string) - EM_SAFE_STRLEN(p_digest_string) - 1);
3721                 break;
3722         case DIGEST_TYPE_SHA512:
3723                 strncat(p_digest_string, "sha512", sizeof(p_digest_string) - EM_SAFE_STRLEN(p_digest_string) - 1);
3724                 break;
3725         case DIGEST_TYPE_SHA224:
3726                 strncat(p_digest_string, "sha224", sizeof(p_digest_string) - EM_SAFE_STRLEN(p_digest_string) - 1);
3727                 break;
3728         case DIGEST_TYPE_MD4:
3729                 strncat(p_digest_string, "md4", sizeof(p_digest_string) - EM_SAFE_STRLEN(p_digest_string) - 1);
3730                 break;
3731         }
3732
3733         digest_string = EM_SAFE_STRDUP(p_digest_string);
3734
3735         EM_DEBUG_FUNC_END();
3736         return digest_string;
3737 }
3738
3739
3740 /*  Description : Make RFC822 text file from mail_tbl data */
3741 /*  Parameters :  */
3742 /*      input_mail_tbl_data :  */
3743 /*      is_draft  : this mail is draft mail. */
3744 /*      file_path : path of file that rfc822 data will be written to. */
3745 INTERNAL_FUNC int emcore_make_rfc822_file_from_mail(char *multi_user_name, 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)
3746 {
3747         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);
3748
3749         int       ret = false;
3750         int       error = EMAIL_ERROR_NONE;
3751         int       i = 0;
3752         char     *digest_string = NULL;
3753
3754         ENVELOPE *envelope      = NULL;
3755         BODY     *root_body     = NULL;
3756         BODY     *text_body     = NULL;
3757         BODY     *html_body     = NULL;
3758         PART     *part_for_alternative = NULL;
3759         PART     *part_for_related = NULL;
3760         PARAMETER *param = NULL;
3761
3762         char *prefix_path = NULL;
3763         char real_file_path[MAX_PATH] = {0};
3764
3765         if (!input_mail_tbl_data) {
3766                 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
3767                 error = EMAIL_ERROR_INVALID_PARAM;
3768                 goto FINISH_OFF;
3769         }
3770
3771         if ((input_mail_tbl_data->report_status & EMAIL_MAIL_REPORT_MDN) != 0 && !input_mail_tbl_data->body_download_status) {
3772                 EM_DEBUG_EXCEPTION("input_mail_tbl_data->body_download_status[%d]", input_mail_tbl_data->body_download_status);
3773                 error = EMAIL_ERROR_INVALID_PARAM;
3774                 goto FINISH_OFF;
3775         }
3776
3777         if ((error = emcore_make_envelope_from_mail(multi_user_name, input_mail_tbl_data, &envelope)) != EMAIL_ERROR_NONE) {
3778                 EM_DEBUG_EXCEPTION("emcore_make_envelope_from_mail failed [%d]", error);
3779                 goto FINISH_OFF;
3780         }
3781
3782         EM_DEBUG_LOG_SEC("input_mail_tbl_data->file_path_plain[%s]", input_mail_tbl_data->file_path_plain);
3783         EM_DEBUG_LOG_SEC("input_mail_tbl_data->file_path_html[%s]", input_mail_tbl_data->file_path_html);
3784         EM_DEBUG_LOG_SEC("input_mail_tbl_data->file_path_mime_entity[%s]", input_mail_tbl_data->file_path_mime_entity);
3785         EM_DEBUG_LOG("input_mail_tbl_data->body->attachment_num[%d]", input_mail_tbl_data->attachment_count);
3786
3787         root_body = mail_newbody();
3788         if (root_body == NULL) {
3789                 EM_DEBUG_EXCEPTION("mail_newbody failed...");
3790                 error = EMAIL_ERROR_OUT_OF_MEMORY;
3791                 goto FINISH_OFF;
3792         }
3793
3794         param = mail_newbody_parameter();
3795         if (param == NULL) {
3796                 EM_DEBUG_EXCEPTION("mail_newbody_parameter failed...");
3797                 error = EMAIL_ERROR_OUT_OF_MEMORY;
3798                 goto FINISH_OFF;
3799         }
3800
3801         if (EM_SAFE_STRLEN(multi_user_name) > 0) {
3802                 error = emcore_get_container_path(multi_user_name, &prefix_path);
3803                 if (error != EMAIL_ERROR_NONE) {
3804                         EM_DEBUG_EXCEPTION("emcore_get_container_path failed : [%d]", error);
3805                         goto FINISH_OFF;
3806                 }
3807         } else {
3808                 prefix_path = strdup("");
3809         }
3810
3811         if (input_attachment_count > 0) {
3812                 /* handle the Multipart/mixed, Multipart/related and S/MIME */
3813                 EM_DEBUG_LOG("input_attachment_num [%d]", input_attachment_count);
3814                 EM_DEBUG_LOG("inline_attachment_num [%d]", input_mail_tbl_data->inline_content_count);
3815                 EM_DEBUG_LOG("attachment_num [%d]", input_mail_tbl_data->attachment_count);
3816
3817                 if (input_mail_tbl_data->smime_type == EMAIL_SMIME_NONE) {
3818                         if (input_mail_tbl_data->attachment_count > 0) {
3819                                 root_body->type    = TYPEMULTIPART;
3820                                 root_body->subtype = strdup("MIXED");
3821                         } else {
3822                                 root_body->type    = TYPEMULTIPART;
3823                                 root_body->subtype = strdup("RELATED");
3824                         }
3825
3826                         mail_free_body_parameter(&param);
3827                         param = NULL;
3828                 } else if (input_mail_tbl_data->smime_type == EMAIL_SMIME_SIGNED) {
3829                         PARAMETER *protocol_param   = mail_newbody_parameter();
3830
3831                         root_body->type             = TYPEMULTIPART;
3832                         root_body->subtype          = strdup("SIGNED");
3833
3834                         param->attribute            = cpystr("micalg");
3835
3836                         digest_string               = emcore_get_digest_string(input_mail_tbl_data->digest_type, input_mail_tbl_data->smime_type);
3837                         param->value                = cpystr(digest_string);
3838
3839                         protocol_param->attribute   = cpystr("protocol");
3840                         protocol_param->value       = cpystr("application/pkcs7-signature");
3841                         protocol_param->next        = NULL;
3842                         param->next                 = protocol_param;
3843                 } else if (input_mail_tbl_data->smime_type == EMAIL_SMIME_ENCRYPTED || input_mail_tbl_data->smime_type == EMAIL_SMIME_SIGNED_AND_ENCRYPTED) {
3844                         root_body->type    = TYPEAPPLICATION;
3845                         root_body->subtype = strdup("PKCS7-MIME");
3846
3847                         param->attribute = cpystr("name");
3848                         param->value = cpystr("smime.p7m");
3849                         param->next = NULL;
3850                 } else if (input_mail_tbl_data->smime_type == EMAIL_PGP_SIGNED) {
3851                         PARAMETER *protocol_param = mail_newbody_parameter();
3852
3853                         root_body->type           = TYPEMULTIPART;
3854                         root_body->subtype        = strdup("SIGNED");
3855
3856                         param->attribute          = cpystr("micalg");
3857
3858                         digest_string             = emcore_get_digest_string(input_mail_tbl_data->digest_type, input_mail_tbl_data->smime_type);
3859                         param->value              = cpystr(digest_string);
3860
3861                         protocol_param->attribute = cpystr("protocol");
3862                         protocol_param->value     = cpystr("application/pgp-signature");
3863                         protocol_param->next      = NULL;
3864                         param->next               = protocol_param;
3865                 } else {
3866                         root_body->type           = TYPEMULTIPART;
3867                         root_body->subtype        = strdup("encrypted");
3868
3869                         param->attribute          = cpystr("protocol");
3870                         param->value              = cpystr("application/pgp-encrypted");
3871                         param->next               = NULL;
3872                 }
3873
3874                 root_body->contents.text.data = NULL;
3875                 root_body->contents.text.size = 0;
3876                 root_body->size.bytes         = 0;
3877                 root_body->parameter          = param;
3878
3879                 if (input_mail_tbl_data->smime_type == EMAIL_SMIME_NONE &&
3880                                 (input_mail_tbl_data->file_path_plain && input_mail_tbl_data->file_path_html)) {
3881                         /* Multipart/mixed -> multipart/related -> multipart/alternative  : has inline content and */
3882                         /* Multipart/mixed -> Multipart/alternative */
3883
3884                         if (input_mail_tbl_data->inline_content_count > 0 && (strcasecmp(root_body->subtype, "RELATED") != 0)) {
3885                                 part_for_related = attach_multipart_with_sub_type(root_body, "RELATED", &error);
3886                                 if (!part_for_related) {
3887                                         EM_DEBUG_EXCEPTION("attach_multipart_with_sub_type [related] failed [%d]", error);
3888                                         goto FINISH_OFF;
3889                                 }
3890                         }
3891
3892                         if (part_for_related)
3893                                 part_for_alternative = attach_multipart_with_sub_type(&(part_for_related->body), "ALTERNATIVE", &error);
3894                         else
3895                                 part_for_alternative = attach_multipart_with_sub_type(root_body, "ALTERNATIVE", &error);
3896                         if (!part_for_alternative) {
3897                                 EM_DEBUG_EXCEPTION("attach_multipart_with_sub_type [alternative] failed [%d]", error);
3898                                 goto FINISH_OFF;
3899                         }
3900
3901                         if (strlen(input_mail_tbl_data->file_path_plain) > 0) {
3902                                 EM_DEBUG_LOG_SEC("file_path_plain[%s]", input_mail_tbl_data->file_path_plain);
3903
3904                                 memset(real_file_path, 0x00, sizeof(real_file_path));
3905                                 SNPRINTF(real_file_path, sizeof(real_file_path), "%s%s", prefix_path, input_mail_tbl_data->file_path_plain);
3906
3907                                 text_body = &(part_for_alternative->body);
3908                                 if (!attach_part(text_body, (unsigned char *)real_file_path, 0, NULL, "plain", false, &error)) {
3909                                         EM_DEBUG_EXCEPTION("attach_partfailed [%d]", error);
3910                                         goto FINISH_OFF;
3911                                 }
3912                         }
3913
3914                         if (strlen(input_mail_tbl_data->file_path_html) > 0) {
3915                                 EM_DEBUG_LOG_SEC("file_path_html[%s]", input_mail_tbl_data->file_path_html);
3916
3917                                 memset(real_file_path, 0x00, sizeof(real_file_path));
3918                                 SNPRINTF(real_file_path, sizeof(real_file_path), "%s%s", prefix_path, input_mail_tbl_data->file_path_html);
3919
3920                                 html_body = &(part_for_alternative->body);
3921                                 if (!attach_part(html_body, (unsigned char *)real_file_path, 0, NULL, "html", false, &error)) {
3922                                         EM_DEBUG_EXCEPTION("attach_partfailed [%d]", error);
3923                                         goto FINISH_OFF;
3924                                 }
3925                         }
3926                 } else if (input_mail_tbl_data->smime_type == EMAIL_SMIME_NONE &&
3927                                 (input_mail_tbl_data->file_path_plain || input_mail_tbl_data->file_path_html)) {
3928                         if (input_mail_tbl_data->file_path_plain && EM_SAFE_STRLEN(input_mail_tbl_data->file_path_plain) > 0) {
3929                                 EM_DEBUG_LOG_SEC("file_path_plain[%s]", input_mail_tbl_data->file_path_plain);
3930
3931                                 memset(real_file_path, 0x00, sizeof(real_file_path));
3932                                 SNPRINTF(real_file_path, sizeof(real_file_path), "%s%s", prefix_path, input_mail_tbl_data->file_path_plain);
3933
3934                                 if (!attach_part(root_body, (unsigned char *)real_file_path, 0, NULL, "plain", false, &error)) {
3935                                         EM_DEBUG_EXCEPTION("attach_partfailed [%d]", error);
3936                                         goto FINISH_OFF;
3937                                 }
3938                         }
3939
3940                         if (input_mail_tbl_data->file_path_html && EM_SAFE_STRLEN(input_mail_tbl_data->file_path_html) > 0) {
3941                                 EM_DEBUG_LOG_SEC("file_path_html[%s]", input_mail_tbl_data->file_path_html);
3942                                 if (input_mail_tbl_data->inline_content_count > 0 &&
3943                                                 (root_body->subtype && (strcasecmp(root_body->subtype, "RELATED") != 0))) {
3944                                         part_for_related = attach_multipart_with_sub_type(root_body, "RELATED", &error);
3945                                         if (!part_for_related) {
3946                                                 EM_DEBUG_EXCEPTION("attach_multipart_with_sub_type [related] failed [%d]", error);
3947                                                 goto FINISH_OFF;
3948                                         }
3949                                 }
3950
3951                                 memset(real_file_path, 0x00, sizeof(real_file_path));
3952                                 SNPRINTF(real_file_path, sizeof(real_file_path), "%s%s", prefix_path, input_mail_tbl_data->file_path_html);
3953
3954                                 if (part_for_related) {
3955                                         if (!attach_part(&(part_for_related->body), (unsigned char *)real_file_path, 0,
3956                                                                 NULL, "html", false, &error)) {
3957                                                 EM_DEBUG_EXCEPTION("attach_partfailed [%d]", error);
3958                                                 goto FINISH_OFF;
3959                                         }
3960                                 } else {
3961                                         if (!attach_part(root_body, (unsigned char *)real_file_path, 0,
3962                                                                 NULL, "html", false, &error)) {
3963                                                 EM_DEBUG_EXCEPTION("attach_partfailed [%d]", error);
3964                                                 goto FINISH_OFF;
3965                                         }
3966                                 }
3967                         }
3968                 } else if (input_mail_tbl_data->smime_type == EMAIL_SMIME_SIGNED || input_mail_tbl_data->smime_type == EMAIL_PGP_SIGNED) {
3969                         if (input_mail_tbl_data->file_path_mime_entity && EM_SAFE_STRLEN(input_mail_tbl_data->file_path_mime_entity) > 0) {
3970                                 EM_DEBUG_LOG_SEC("file_path_mime_entity[%s]", input_mail_tbl_data->file_path_mime_entity);
3971
3972                                 memset(real_file_path, 0x00, sizeof(real_file_path));
3973                                 SNPRINTF(real_file_path, sizeof(real_file_path), "%s%s", prefix_path, input_mail_tbl_data->file_path_mime_entity);
3974
3975                                 root_body->sparep = EM_SAFE_STRDUP(input_mail_tbl_data->file_path_mime_entity);
3976                         }
3977                 } else if (input_mail_tbl_data->smime_type == EMAIL_PGP_ENCRYPTED || input_mail_tbl_data->smime_type == EMAIL_PGP_SIGNED_AND_ENCRYPTED) {
3978                         if (input_mail_tbl_data->file_path_plain && EM_SAFE_STRLEN(input_mail_tbl_data->file_path_plain) > 0) {
3979                                 EM_DEBUG_LOG_SEC("file_path_plain[%s]", input_mail_tbl_data->file_path_plain);
3980                                 if (!attach_part(root_body, NULL, 0, NULL, "pgp-encrypted", false, &error)) {
3981                                         EM_DEBUG_EXCEPTION("attach_partfailed [%d]", error);
3982                                         goto FINISH_OFF;
3983                                 }
3984                         }
3985                 } else {
3986                         EM_DEBUG_LOG("S/MIME encrypted type");
3987                 }
3988
3989                 if (input_attachment_tbl && input_attachment_count) {
3990                         emstorage_attachment_tbl_t *temp_attachment_tbl = NULL;
3991                         char *name = NULL;
3992                         BODY *body_to_attach = NULL;
3993
3994                         for (i = 0; i < input_attachment_count; i++) {
3995                                 temp_attachment_tbl = input_attachment_tbl + i;
3996
3997                                 EM_DEBUG_LOG_SEC("attachment_name[%s], attachment_path[%s]", temp_attachment_tbl->attachment_name, temp_attachment_tbl->attachment_path);
3998
3999                                 if (!temp_attachment_tbl->attachment_name) {
4000                                         if (!emcore_get_file_name(temp_attachment_tbl->attachment_path, &name, &error)) {
4001                                                 EM_DEBUG_EXCEPTION("emcore_get_file_name failed [%d]", error);
4002                                                 continue;
4003                                         }
4004                                 } else
4005                                         name = temp_attachment_tbl->attachment_name;
4006
4007                                 EM_DEBUG_LOG_SEC("name[%s]", name);
4008
4009                                 if (temp_attachment_tbl->attachment_inline_content_status && part_for_related)
4010                                         body_to_attach = &(part_for_related->body);
4011                                 else
4012                                         body_to_attach = root_body;
4013
4014                                 memset(real_file_path, 0x00, sizeof(real_file_path));
4015                                 SNPRINTF(real_file_path, sizeof(real_file_path), "%s%s", prefix_path, temp_attachment_tbl->attachment_path);
4016
4017                                 if (!attach_part(body_to_attach,
4018                                                         (unsigned char *)real_file_path,
4019                                                         0,
4020                                                         name,
4021                                                         temp_attachment_tbl->attachment_mime_type,
4022                                                         temp_attachment_tbl->attachment_inline_content_status,
4023                                                         &error)) {
4024                                         EM_DEBUG_EXCEPTION("attach_partfailed [%d]", error);
4025                                         continue;
4026                                 }
4027                         }
4028                 }
4029                 text_body = NULL;
4030         } else if (input_mail_tbl_data->file_path_plain && input_mail_tbl_data->file_path_html) {
4031                 /* Handle the Multipart/alternative */
4032                 root_body->type    = TYPEMULTIPART;
4033                 root_body->subtype = strdup("ALTERNATIVE");
4034
4035                 mail_free_body_parameter(&param);
4036                 param = NULL;
4037
4038                 root_body->contents.text.data = NULL;
4039                 root_body->contents.text.size = 0;
4040                 root_body->size.bytes         = 0;
4041                 root_body->parameter          = param;
4042
4043                 if (strlen(input_mail_tbl_data->file_path_plain) > 0) {
4044                         EM_DEBUG_LOG_SEC("file_path_plain[%s]", input_mail_tbl_data->file_path_plain);
4045
4046                         memset(real_file_path, 0x00, sizeof(real_file_path));
4047                         SNPRINTF(real_file_path, sizeof(real_file_path), "%s%s", prefix_path, input_mail_tbl_data->file_path_plain);
4048
4049                         if (!attach_part(root_body, (unsigned char *)real_file_path, 0, NULL, "plain", false, &error)) {
4050                                 EM_DEBUG_EXCEPTION("attach_partfailed [%d]", error);
4051                                 goto FINISH_OFF;
4052                         }
4053                 }
4054
4055                 if (strlen(input_mail_tbl_data->file_path_html) > 0) {
4056                         EM_DEBUG_LOG_SEC("file_path_html[%s]", input_mail_tbl_data->file_path_html);
4057
4058                         memset(real_file_path, 0x00, sizeof(real_file_path));
4059                         SNPRINTF(real_file_path, sizeof(real_file_path), "%s%s", prefix_path, input_mail_tbl_data->file_path_html);
4060
4061                         if (!attach_part(root_body, (unsigned char *)real_file_path, 0, NULL, "html", false, &error)) {
4062                                 EM_DEBUG_EXCEPTION("attach_partfailed [%d]", error);
4063                                 goto FINISH_OFF;
4064                         }
4065                 }
4066         } else {
4067                 root_body->type = TYPETEXT;
4068                 root_body->encoding = ENC8BIT;
4069                 if (input_mail_tbl_data->file_path_plain || input_mail_tbl_data->file_path_html) {
4070                         if (input_mail_tbl_data->file_path_plain) {
4071                                 memset(real_file_path, 0x00, sizeof(real_file_path));
4072                                 SNPRINTF(real_file_path, sizeof(real_file_path), "%s%s", prefix_path, input_mail_tbl_data->file_path_plain);
4073                         } else {
4074                                 memset(real_file_path, 0x00, sizeof(real_file_path));
4075                                 SNPRINTF(real_file_path, sizeof(real_file_path), "%s%s", prefix_path, input_mail_tbl_data->file_path_html);
4076                         }
4077
4078                         root_body->sparep = EM_SAFE_STRDUP(real_file_path);
4079                 } else {
4080                         root_body->sparep = NULL;
4081                 }
4082
4083                 if (input_mail_tbl_data->file_path_html != NULL && input_mail_tbl_data->file_path_html[0] != '\0')
4084                         root_body->subtype = strdup("html");
4085                 if (root_body->sparep)
4086                         root_body->size.bytes = EM_SAFE_STRLEN(root_body->sparep);
4087                 else
4088                         root_body->size.bytes = 0;
4089         }
4090
4091
4092         if (input_mail_tbl_data->report_status & EMAIL_MAIL_REPORT_MDN) {
4093                 /*  Report mail */
4094                 EM_DEBUG_LOG("REPORT MAIL");
4095                 envelope->references = cpystr(input_mail_tbl_data->message_id);
4096         }
4097
4098         if (file_path) {
4099                 EM_DEBUG_LOG("write rfc822 : file_path[%p]", file_path);
4100
4101                 if ((error = emcore_write_rfc822(envelope, root_body, input_mail_tbl_data->priority,
4102                                                 input_mail_tbl_data->report_status, file_path)) != EMAIL_ERROR_NONE) {
4103                         EM_DEBUG_EXCEPTION("emcore_write_rfc822 failed [%d]", error);
4104                         goto FINISH_OFF;
4105                 }
4106         }
4107
4108         ret = true;
4109
4110 FINISH_OFF:
4111         if ((ret == true) && (env != NULL))
4112                 *env = envelope;
4113         else if (envelope != NULL)
4114                 mail_free_envelope(&envelope);
4115
4116         if (text_body != NULL)
4117                 mail_free_body(&text_body);
4118
4119         if (root_body != NULL)
4120                 mail_free_body(&root_body);
4121
4122         EM_SAFE_FREE(digest_string);
4123         EM_SAFE_FREE(prefix_path);
4124
4125         if (err_code != NULL)
4126                 *err_code = error;
4127
4128         EM_DEBUG_FUNC_END("ret [%d]", ret);
4129         return ret;
4130 }
4131
4132 INTERNAL_FUNC int emcore_make_rfc822_file(char *multi_user_name, email_mail_data_t *input_mail_tbl_data, email_attachment_data_t *input_attachment_tbl, int input_attachment_count, int mime_entity_status, char **file_path, int *err_code)
4133 {
4134         EM_DEBUG_FUNC_BEGIN("input_mail_tbl_data[%p], file_path[%p], err_code[%p]", input_mail_tbl_data, file_path, err_code);
4135
4136         int err = EMAIL_ERROR_NONE;
4137         int ret = false;
4138         int i = 0;
4139         int attachment_count = 0;
4140         int inline_content_count = 0;
4141
4142         emstorage_mail_tbl_t *modified_mail_data = NULL;
4143         emstorage_attachment_tbl_t *modified_attachment_data = NULL;
4144
4145         /* Convert from email_mail_data_t to emstorage_mail_tbl_t */
4146         if (!em_convert_mail_data_to_mail_tbl(input_mail_tbl_data, 1, &modified_mail_data, &err)) {
4147                 EM_DEBUG_EXCEPTION("em_convert_mail_tbl_to_mail_data falied [%d]", err);
4148                 goto FINISH_OFF;
4149         }
4150
4151         if (mime_entity_status)
4152                 modified_mail_data->smime_type = EMAIL_SMIME_NONE;
4153
4154         /* Convert from email_attachment_data_t to emstorage_attachment_tbl_t */
4155         if (input_attachment_count > 0) {
4156                 modified_attachment_data = em_malloc(sizeof(emstorage_attachment_tbl_t) * input_attachment_count);
4157                 if (modified_attachment_data == NULL) {
4158                         EM_DEBUG_EXCEPTION("em_mallocfailed");
4159                         err = EMAIL_ERROR_OUT_OF_MEMORY;
4160                         goto FINISH_OFF;
4161                 }
4162         }
4163
4164         for (i = 0; i < input_attachment_count; i++) {
4165                 modified_attachment_data[i].attachment_id                    = input_attachment_tbl[i].attachment_id;
4166                 modified_attachment_data[i].attachment_name                  = EM_SAFE_STRDUP(input_attachment_tbl[i].attachment_name);
4167                 modified_attachment_data[i].attachment_path                  = EM_SAFE_STRDUP(input_attachment_tbl[i].attachment_path);
4168                 modified_attachment_data[i].content_id                       = EM_SAFE_STRDUP(input_attachment_tbl[i].content_id);
4169                 modified_attachment_data[i].attachment_id                    = input_attachment_tbl[i].attachment_size;
4170                 modified_attachment_data[i].mail_id                          = input_attachment_tbl[i].mail_id;
4171                 modified_attachment_data[i].account_id                       = input_attachment_tbl[i].account_id;
4172                 modified_attachment_data[i].mailbox_id                       = input_attachment_tbl[i].mailbox_id;
4173                 modified_attachment_data[i].attachment_save_status           = input_attachment_tbl[i].save_status;
4174                 modified_attachment_data[i].attachment_drm_type              = input_attachment_tbl[i].drm_status;
4175                 modified_attachment_data[i].attachment_inline_content_status = input_attachment_tbl[i].inline_content_status;
4176                 modified_attachment_data[i].attachment_mime_type             = EM_SAFE_STRDUP(input_attachment_tbl[i].attachment_mime_type);
4177
4178                 if (input_attachment_tbl[i].inline_content_status == INLINE_ATTACHMENT)
4179                         inline_content_count += 1;
4180                 else
4181                         attachment_count += 1;
4182         }
4183
4184         modified_mail_data->attachment_count = attachment_count;
4185         modified_mail_data->inline_content_count = inline_content_count;
4186
4187         if (!emcore_make_rfc822_file_from_mail(multi_user_name, modified_mail_data, modified_attachment_data, input_attachment_count, NULL, file_path, NULL, &err)) {
4188                 EM_DEBUG_EXCEPTION("emcore_make_rfc822_file_from_mail failed [%d]", err);
4189                 goto FINISH_OFF;
4190         }
4191
4192         ret = true;
4193
4194 FINISH_OFF:
4195
4196         if (modified_mail_data)
4197                 emstorage_free_mail(&modified_mail_data, 1, NULL);
4198
4199         if (modified_attachment_data)
4200                 emstorage_free_attachment(&modified_attachment_data, input_attachment_count, NULL);
4201
4202         if (err_code)
4203                 *err_code = err;
4204
4205         EM_DEBUG_FUNC_END("ret [%d]", ret);
4206         return ret;
4207 }
4208
4209 #ifdef __FEATURE_SUPPORT_REPORT_MAIL__
4210 static int emcore_get_report_mail_body(char *multi_user_name, ENVELOPE *envelope, BODY **multipart_body, int *err_code)
4211 {
4212         EM_DEBUG_FUNC_BEGIN("envelope[%p], mulitpart_body[%p], err_code[%p]", envelope, multipart_body, err_code);
4213
4214         int ret = false;
4215         int err = EMAIL_ERROR_NONE;
4216
4217         BODY *m_body = NULL;
4218         BODY *p_body = NULL;
4219         BODY *text_body = NULL;
4220         PARAMETER *param = NULL;
4221         emstorage_attachment_tbl_t *temp_attachment_tbl = NULL;
4222         FILE *fp = NULL;
4223         char *fname = NULL;
4224         char buf[512] = {0x00, };
4225         int sz = 0;
4226
4227         if (!envelope || !multipart_body) {
4228                 EM_DEBUG_EXCEPTION(" envelope[%p], mulitpart_body[%p]", envelope, multipart_body);
4229                 err = EMAIL_ERROR_INVALID_PARAM;
4230                 goto FINISH_OFF;
4231         }
4232
4233         if (!(text_body = mail_newbody())) {
4234                 EM_DEBUG_EXCEPTION(" mail_newbody failed...");
4235                 err = EMAIL_ERROR_OUT_OF_MEMORY;
4236                 goto FINISH_OFF;
4237         }
4238
4239         if (!emcore_get_temp_file_name(&fname, &err)) {
4240                 EM_DEBUG_EXCEPTION(" emcore_get_temp_file_name failed [%d]", err);
4241                 goto FINISH_OFF;
4242         }
4243
4244         err = em_fopen(fname, "wb+", &fp);
4245         if (err != EMAIL_ERROR_NONE) {
4246                 EM_DEBUG_EXCEPTION("em_fopen failed - %s, error : [%d]", fname, err);
4247                 goto FINISH_OFF;
4248         }
4249
4250         if (!envelope->from || !envelope->from->mailbox || !envelope->from->host) {
4251                 if (!envelope->from)
4252                         EM_DEBUG_EXCEPTION(" envelope->from[%p]", envelope->from);
4253                 else
4254                         EM_DEBUG_LOG(" envelope->from->mailbox[%p], envelope->from->host[%p]", envelope->from->mailbox, envelope->from->host);
4255
4256                 err = EMAIL_ERROR_INVALID_PARAM;
4257                 goto FINISH_OFF;
4258         }
4259
4260         /*
4261            if (envelope->from->personal)
4262            SNPRINTF(buf, sizeof(buf), "%s <%s@%s>", envelope->from->personal, envelope->from->mailbox, envelope->from->host);
4263            else
4264            */
4265         SNPRINTF(buf, sizeof(buf), "%s@%s", envelope->from->mailbox, envelope->from->host);
4266
4267         fprintf(fp, "Your message has been read by %s"CRLF_STRING, buf);
4268         fprintf(fp, "Date :  %s", envelope->date);
4269
4270         fclose(fp); fp = NULL;
4271
4272         if (!emcore_get_file_size(fname, &sz, &err)) {
4273                 EM_DEBUG_EXCEPTION(" emcore_get_file_size failed [%d]", err);
4274                 goto FINISH_OFF;
4275         }
4276
4277         text_body->type = TYPETEXT;
4278         text_body->encoding = ENC8BIT;
4279         text_body->sparep = EM_SAFE_STRDUP(fname);
4280         text_body->size.bytes = (unsigned long)sz;
4281
4282         if (!emcore_get_temp_file_name(&fname, &err)) {
4283                 EM_DEBUG_EXCEPTION(" emcore_get_temp_file_name failed [%d]", err);
4284                 goto FINISH_OFF;
4285         }
4286
4287         err = em_fopen(fname, "wb+", &fp);
4288         if (err != EMAIL_ERROR_NONE) {
4289                 EM_DEBUG_EXCEPTION("em_fopen failed - %s, error : [%d]", fname, err);
4290                 goto FINISH_OFF;
4291         }
4292
4293         if (!envelope->references) {
4294                 EM_DEBUG_EXCEPTION(" envelope->references[%p]", envelope->references);
4295                 err = EMAIL_ERROR_INVALID_PARAM;
4296                 goto FINISH_OFF;
4297         }
4298
4299         fprintf(fp, "Final-Recipient :  rfc822;%s@%s\r", envelope->from->mailbox, envelope->from->host);
4300         fprintf(fp, "Original-Message-ID:  %s\r", envelope->references);
4301         fprintf(fp, "Disposition :  manual-action/MDN-sent-manually; displayed");
4302
4303         fclose(fp); fp = NULL;
4304
4305         temp_attachment_tbl = (emstorage_attachment_tbl_t *)em_malloc(sizeof(emstorage_attachment_tbl_t));
4306         if (temp_attachment_tbl == NULL) {
4307                 EM_DEBUG_EXCEPTION("em_mallocfailed");
4308                 err = EMAIL_ERROR_OUT_OF_MEMORY;
4309                 goto FINISH_OFF;
4310         }
4311
4312         temp_attachment_tbl->attachment_path = EM_SAFE_STRDUP(fname);
4313
4314         if (!emcore_get_file_size(fname, &temp_attachment_tbl->attachment_size, &err)) {
4315                 EM_DEBUG_EXCEPTION(" emcore_get_file_size failed [%d]", err);
4316                 goto FINISH_OFF;
4317         }
4318
4319         if (!attach_attachment_to_body(multi_user_name, &m_body, text_body, temp_attachment_tbl, 1, &err)) {
4320                 EM_DEBUG_EXCEPTION(" attach_attachment_to_body failed [%d]", err);
4321                 goto FINISH_OFF;
4322         }
4323
4324         text_body->contents.text.data = NULL;
4325
4326         /*  change mail header */
4327
4328         /*  set content-type to multipart/report */
4329         m_body->subtype = strdup("report");
4330
4331         /*  set report-type parameter in content-type */
4332         param = em_malloc(sizeof(PARAMETER));
4333         if (!param) {
4334                 EM_DEBUG_EXCEPTION(" malloc failed...");
4335                 err = EMAIL_ERROR_OUT_OF_MEMORY;
4336                 goto FINISH_OFF;
4337         }
4338
4339         param->attribute  = strdup("report-type");
4340         param->value      = strdup("disposition-notification");
4341         param->next       = m_body->parameter;
4342
4343         m_body->parameter = param;
4344
4345         /*  change body-header */
4346
4347         p_body = &m_body->nested.part->next->body;
4348
4349         /*  set content-type to message/disposition-notification */
4350         p_body->type      = TYPEMESSAGE;
4351         p_body->encoding  = ENC7BIT;
4352
4353         EM_SAFE_FREE(p_body->subtype);
4354
4355         p_body->subtype = strdup("disposition-notification");
4356
4357         /*  set parameter */
4358         mail_free_body_parameter(&p_body->parameter);
4359         mail_free_body_parameter(&p_body->disposition.parameter);
4360
4361         EM_SAFE_FREE(p_body->disposition.type);
4362
4363         p_body->disposition.type = strdup("inline");
4364
4365         ret = true;
4366
4367 FINISH_OFF:
4368         if ((ret == true) && (multipart_body != NULL))
4369                 *multipart_body = m_body;
4370         else if (m_body != NULL)
4371                 mail_free_body(&m_body);
4372
4373         if (text_body != NULL)
4374                 mail_free_body(&text_body);
4375
4376         if (fp != NULL)
4377                 fclose(fp);
4378
4379         EM_SAFE_FREE(fname);
4380
4381         if (temp_attachment_tbl)
4382                 emstorage_free_attachment(&temp_attachment_tbl, 1, NULL);
4383
4384         if (err_code != NULL)
4385                 *err_code = err;
4386
4387         EM_DEBUG_FUNC_END("err [%d]", err);
4388         return ret;
4389 }
4390 #endif
4391
4392 INTERNAL_FUNC int emcore_get_body_buff(char *file_path, char **buff)
4393 {
4394         EM_DEBUG_FUNC_BEGIN();
4395
4396         FILE *r_fp = NULL;
4397         int ret = false;
4398         char *read_buff = NULL;
4399
4400         if (file_path)
4401                 r_fp = fopen(file_path, "r");
4402
4403         if (!r_fp) {
4404                 EM_DEBUG_EXCEPTION_SEC(" Filename %s failed to open", file_path);
4405                 goto FINISH_OFF;
4406         }
4407
4408         struct stat stbuf;
4409         if (stat(file_path, &stbuf) == 0 && stbuf.st_size > 0) {
4410                 EM_DEBUG_LOG(" File Size [ %jd ] ", stbuf.st_size);
4411                 read_buff = calloc((stbuf.st_size + 1), sizeof(char));
4412                 if (read_buff == NULL) {
4413                         EM_DEBUG_EXCEPTION("calloc failed");
4414                         goto FINISH_OFF;
4415                 }
4416                 read_buff[stbuf.st_size] = '\0';
4417         }
4418
4419         if (ferror(r_fp)) {
4420                 EM_DEBUG_EXCEPTION_SEC("file read failed - %s", file_path);
4421                 EM_SAFE_FREE(read_buff);
4422                 goto FINISH_OFF;
4423         }
4424
4425         ret = true;
4426         *buff = read_buff;
4427
4428 FINISH_OFF:
4429         if (r_fp)
4430                 fclose(r_fp);
4431
4432         return ret;
4433 }
4434
4435 static int emcore_copy_attachment_from_original_mail(char *multi_user_name, int input_original_mail_id, int input_target_mail_id)
4436 {
4437         EM_DEBUG_FUNC_BEGIN("input_original_mail_id[%d] input_target_mail_id[%d]", input_original_mail_id, input_target_mail_id);
4438         int err = EMAIL_ERROR_NONE;
4439         int i = 0, j = 0;
4440         int original_mail_attachment_count = 0;
4441         int target_mail_attachment_count = 0;
4442         int attachment_id = 0;
4443         char output_file_name[MAX_PATH] = { 0, };
4444         char output_file_path[MAX_PATH] = { 0, };
4445         char virtual_file_path[MAX_PATH] = { 0, };
4446         emstorage_attachment_tbl_t *original_mail_attachment_array = NULL;
4447         emstorage_attachment_tbl_t *target_mail_attachment_array = NULL;
4448         emstorage_attachment_tbl_t *target_attach = NULL;
4449
4450         if ((err = emstorage_get_attachment_list(multi_user_name, input_original_mail_id, false, &original_mail_attachment_array, &original_mail_attachment_count)) != EMAIL_ERROR_NONE) {
4451                 EM_DEBUG_EXCEPTION("emstorage_get_attachment_list failed [%d]", err);
4452                 goto FINISH_OFF;
4453         }
4454
4455         if ((err = emstorage_get_attachment_list(multi_user_name, input_target_mail_id, false, &target_mail_attachment_array, &target_mail_attachment_count)) != EMAIL_ERROR_NONE) {
4456                 EM_DEBUG_EXCEPTION("emstorage_get_attachment_list failed [%d]", err);
4457                 goto FINISH_OFF;
4458         }
4459
4460         for (i = 0; i < original_mail_attachment_count; i++) {
4461                 for (j = 0; j < target_mail_attachment_count; j++) {
4462                         if (strcmp(original_mail_attachment_array[i].attachment_name, target_mail_attachment_array[j].attachment_name) == 0) {
4463                                 target_attach = target_mail_attachment_array + j;
4464
4465                                 /* If attachment is inline content, fild path should not include attachment id */
4466                                 if (target_attach->attachment_inline_content_status == 1)
4467                                         attachment_id = 0;
4468                                 else
4469                                         attachment_id = target_attach->attachment_id;
4470
4471                                 EM_DEBUG_LOG("attachment_inline_content_status [%d] attachment_id[%d]", target_attach->attachment_inline_content_status, attachment_id);
4472
4473                                 if (!emcore_save_mail_file(multi_user_name,
4474                                                         target_attach->account_id,
4475                                                         target_attach->mail_id,
4476                                                         attachment_id,
4477                                                         original_mail_attachment_array[i].attachment_path,
4478                                                         original_mail_attachment_array[i].attachment_name,
4479                                                         output_file_path,
4480                                                         virtual_file_path,
4481                                                         &err)) {
4482                                         EM_DEBUG_EXCEPTION("emcore_save_mail_file failed [%d]", err);
4483                                         goto FINISH_OFF;
4484                                 }
4485
4486                                 EM_SAFE_FREE(target_attach->attachment_path);
4487                                 target_attach->attachment_path = EM_SAFE_STRDUP(virtual_file_path);
4488                                 target_attach->attachment_save_status = 1;
4489
4490                                 if (!emstorage_update_attachment(multi_user_name, target_attach, false, &err)) {
4491                                         EM_DEBUG_EXCEPTION("emstorage_update_attachment failed [%d]", err);
4492                                         goto FINISH_OFF;
4493                                 }
4494
4495                                 memset(output_file_path, 0, MAX_PATH);
4496                                 memset(output_file_name, 0, MAX_PATH);
4497                                 break;
4498                         }
4499                 }
4500         }
4501
4502 FINISH_OFF:
4503         if (original_mail_attachment_array)
4504                 emstorage_free_attachment(&original_mail_attachment_array, original_mail_attachment_count, NULL);
4505         if (target_mail_attachment_array)
4506                 emstorage_free_attachment(&target_mail_attachment_array, target_mail_attachment_count, NULL);
4507
4508
4509         EM_DEBUG_FUNC_END("err[%d]", err);
4510         return err;
4511 }
4512
4513 /*  send a mail */
4514 INTERNAL_FUNC int emcore_send_mail_with_downloading_attachment_of_original_mail(char *multi_user_name, int input_mail_id)
4515 {
4516         EM_DEBUG_FUNC_BEGIN("input_mail_id[%d]", input_mail_id);
4517         int err = EMAIL_ERROR_NONE;
4518         int i = 0;
4519         int attachment_count = 0;
4520         email_mail_data_t *mail_to_be_sent = NULL;
4521         email_mail_data_t *original_mail = NULL;
4522         email_attachment_data_t *attachment_array = NULL;
4523
4524         /* Get mail data */
4525         if ((err = emcore_get_mail_data(multi_user_name, input_mail_id, &mail_to_be_sent)) != EMAIL_ERROR_NONE) {
4526                 EM_DEBUG_EXCEPTION("emcore_get_mail_data failed [%d]", err);
4527                 goto FINISH_OFF;
4528         }
4529
4530         if (mail_to_be_sent->reference_mail_id <= 0) {
4531                 err = EMAIL_ERROR_INVALID_REFERENCE_MAIL;
4532                 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_REFERENCE_MAIL");
4533                 goto FINISH_OFF;
4534         }
4535
4536         /* Get original mail data */
4537         if ((err = emcore_get_mail_data(multi_user_name, mail_to_be_sent->reference_mail_id, &original_mail)) != EMAIL_ERROR_NONE) {
4538                 EM_DEBUG_EXCEPTION("emcore_get_mail_data failed [%d]", err);
4539                 goto FINISH_OFF;
4540         }
4541
4542         /* Check necessity of download */
4543         if ((err = emcore_get_attachment_data_list(multi_user_name, original_mail->mail_id, &attachment_array, &attachment_count)) != EMAIL_ERROR_NONE) {
4544                 EM_DEBUG_EXCEPTION("emcore_get_attachment_data_list failed [%d]", err);
4545                 goto FINISH_OFF;
4546         }
4547
4548         /* If need be, download attachments */
4549         for (i = 0; i < attachment_count; i++) {
4550                 if (attachment_array[i].save_status != 1) {
4551                         /* this function is not run by event thread,
4552                            so cancellable should be set to 0*/
4553                         if (!emcore_gmime_download_attachment(multi_user_name, original_mail->mail_id, i + 1, 0, -1, 0, &err)) {
4554                                 EM_DEBUG_EXCEPTION("emcore_gmime_download_attachment failed [%d]", err);
4555                                 goto FINISH_OFF;
4556                         }
4557                 }
4558         }
4559
4560         /* Copy attachment to the mail to be sent */
4561         if ((err = emcore_copy_attachment_from_original_mail(multi_user_name, original_mail->mail_id, mail_to_be_sent->mail_id)) != EMAIL_ERROR_NONE) {
4562                 EM_DEBUG_EXCEPTION("emcore_copy_attachment_from_original failed [%d]", err);
4563                 goto FINISH_OFF;
4564         }
4565
4566         /* Send the mail */
4567         if (!emcore_send_mail(multi_user_name, mail_to_be_sent->mail_id, &err)) {
4568                 EM_DEBUG_EXCEPTION("emcore_send_mail failed [%d]", err);
4569                 goto FINISH_OFF;
4570         }
4571 FINISH_OFF:
4572
4573         if (attachment_array)
4574                 emcore_free_attachment_data(&attachment_array, attachment_count, NULL);
4575
4576         if (mail_to_be_sent) {
4577                 emcore_free_mail_data(mail_to_be_sent);
4578                 EM_SAFE_FREE(mail_to_be_sent);
4579         }
4580
4581         if (original_mail) {
4582                 emcore_free_mail_data(original_mail);
4583                 EM_SAFE_FREE(original_mail);
4584         }
4585
4586
4587         EM_DEBUG_FUNC_END("err [%d]", err);
4588         return err;
4589 }
4590
4591 /* Scheduled sending ------------------------------------------------ */
4592
4593 static int emcore_sending_alarm_cb(email_alarm_data_t *alarm_data, void *user_parameter)
4594 {
4595         EM_DEBUG_FUNC_BEGIN("alarm_data [%p] user_parameter [%p]", alarm_data, user_parameter);
4596         int err = EMAIL_ERROR_NONE;
4597
4598         if (alarm_data == NULL) {
4599                 EM_DEBUG_EXCEPTION("Invalid parameter");
4600                 err = EMAIL_ERROR_INVALID_PARAM;
4601                 return err;
4602         }
4603
4604         if (alarm_data->reference_id <= 0) {
4605                 EM_DEBUG_EXCEPTION("Invalid parameter");
4606                 err = EMAIL_ERROR_INVALID_PARAM;
4607                 return err;
4608         }
4609
4610         /* Insert the sending mail event */
4611         int account_id = 0;
4612         int input_mail_id = alarm_data->reference_id;
4613         int dst_mailbox_id = 0;
4614         int result_handle = 0;
4615         char *multi_user_name = alarm_data->multi_user_name;
4616
4617         email_event_t *event_data = NULL;
4618         emstorage_mail_tbl_t *mail_data = NULL;
4619         emstorage_mailbox_tbl_t *outbox_tbl = NULL;
4620
4621         if (!emstorage_get_mail_by_id(multi_user_name, input_mail_id, &mail_data, false, &err)) {
4622                 EM_DEBUG_EXCEPTION("emstorage_get_mail_by_id failed : [%d]", err);
4623                 goto FINISH_OFF;
4624         }
4625
4626         account_id = mail_data->account_id;
4627
4628         if (!emnetwork_check_network_status(&err)) {
4629                 EM_DEBUG_EXCEPTION("emnetwork_check_network_status failed : [%d]", err);
4630                 goto FINISH_OFF;
4631         }
4632
4633 #ifdef __FEATURE_MOVE_TO_OUTBOX_FIRST__
4634         if (!emstorage_get_mailbox_by_mailbox_type(multi_user_name,
4635                                 account_id,
4636                                 EMAIL_MAILBOX_TYPE_OUTBOX,
4637                                 &outbox_tbl,
4638                                 false,
4639                                 &err)) {
4640                 EM_DEBUG_EXCEPTION("emstorage_get_mailbox_by_mailbox_type failed : [%d]", err);
4641                 goto FINISH_OFF;
4642         }
4643
4644         dst_mailbox_id = outbox_tbl->mailbox_id;
4645         emstorage_free_mailbox(&outbox_tbl, 1, NULL);
4646         outbox_tbl = NULL;
4647
4648         if (mail_data->mailbox_id != dst_mailbox_id) {
4649                 if (!emcore_move_mail(multi_user_name,
4650                                         &input_mail_id,
4651                                         1,
4652                                         dst_mailbox_id,
4653                                         EMAIL_MOVED_AFTER_SENDING,
4654                                         0,
4655                                         &err)) {
4656                         EM_DEBUG_EXCEPTION("emcore_move_mail failed : [%d]", err);
4657                         goto FINISH_OFF;
4658                 }
4659         }
4660 #endif /* __FEATURE_MOVE_TO_OUTBOX_FIRST__ */
4661
4662         if (!emstorage_set_field_of_mails_with_integer_value(multi_user_name,
4663                                 account_id,
4664                                 &input_mail_id,
4665                                 1,
4666                                 "save_status",
4667                                 EMAIL_MAIL_STATUS_SEND_WAIT,
4668                                 true,
4669                                 &err)) {
4670                 EM_DEBUG_EXCEPTION("emstorage_set_field_of_mails_with_integer_value failed : [%d]", err);
4671                 goto FINISH_OFF;
4672         }
4673
4674         event_data = em_malloc(sizeof(email_event_t));
4675         if (event_data == NULL) {
4676                 EM_DEBUG_EXCEPTION("em_malloc failed");
4677                 err = EMAIL_ERROR_OUT_OF_MEMORY;
4678                 goto FINISH_OFF;
4679         }
4680
4681         event_data->type               = EMAIL_EVENT_SEND_MAIL;
4682         event_data->account_id         = account_id;
4683         event_data->event_param_data_4 = input_mail_id;
4684         event_data->event_param_data_5 = mail_data->mailbox_id;
4685         event_data->multi_user_name    = EM_SAFE_STRDUP(multi_user_name);
4686
4687         if (!emcore_insert_event_for_sending_mails(event_data, &result_handle, &err)) {
4688                 EM_DEBUG_EXCEPTION(" emcore_insert_event failed [%d]", err);
4689                 goto FINISH_OFF;
4690         }
4691
4692 FINISH_OFF:
4693
4694         emcore_add_transaction_info(input_mail_id, result_handle, NULL);
4695
4696         if (err != EMAIL_ERROR_NONE) {
4697                 if (!emstorage_set_field_of_mails_with_integer_value(multi_user_name,
4698                                         account_id,
4699                                         &input_mail_id,
4700                                         1,
4701                                         "save_status",
4702                                         EMAIL_MAIL_STATUS_SAVED,
4703                                         true,
4704                                         &err))
4705                         EM_DEBUG_EXCEPTION("emstorage_set_field_of_mails_with_integer_value failed : [%d]", err);
4706
4707                 if (event_data) {
4708                         emcore_free_event(event_data);
4709                         EM_SAFE_FREE(event_data);
4710                 }
4711         }
4712
4713         if (mail_data)
4714                 emstorage_free_mail(&mail_data, 1, NULL);
4715
4716         if (outbox_tbl)
4717                 emstorage_free_mailbox(&outbox_tbl, 1, NULL);
4718
4719
4720         EM_DEBUG_FUNC_END("err [%d]", err);
4721         return err;
4722 }
4723
4724
4725 INTERNAL_FUNC int emcore_schedule_sending_mail(char *multi_user_name, int input_mail_id, time_t input_time_to_send)
4726 {
4727         EM_DEBUG_FUNC_BEGIN("input_mail_id[%d] input_time_to_send[%d]", input_mail_id, input_time_to_send);
4728         int err = EMAIL_ERROR_NONE;
4729         emstorage_mail_tbl_t *mail_data = NULL;
4730
4731         /* get mail data */
4732         if (!emstorage_get_mail_by_id(multi_user_name, input_mail_id, &mail_data, true, &err) || mail_data == NULL) {
4733                 EM_DEBUG_EXCEPTION("emstorage_get_mail_by_id failed [%d]", err);
4734                 goto FINISH_OFF;
4735         }
4736
4737         if (!emstorage_set_field_of_mails_with_integer_value(multi_user_name,
4738                                 mail_data->account_id,
4739                                 &(mail_data->mail_id),
4740                                 1,
4741                                 "scheduled_sending_time",
4742                                 input_time_to_send,
4743                                 true,
4744                                 &err)) {
4745                 EM_DEBUG_EXCEPTION("emstorage_set_field_of_mails_with_integer_value failed [%d]", err);
4746                 goto FINISH_OFF;
4747         }
4748
4749         /* add alarm */
4750         if ((err = emcore_add_alarm(multi_user_name,
4751                                         input_time_to_send,
4752                                         EMAIL_ALARM_CLASS_SCHEDULED_SENDING,
4753                                         input_mail_id,
4754                                         emcore_sending_alarm_cb,
4755                                         NULL)) != EMAIL_ERROR_NONE) {
4756                 EM_DEBUG_EXCEPTION("emcore_add_alarm failed [%d]", err);
4757                 goto FINISH_OFF;
4758         }
4759
4760 FINISH_OFF:
4761
4762         if (mail_data)
4763                 emstorage_free_mail(&mail_data, 1, NULL);
4764
4765         EM_DEBUG_FUNC_END("err [%d]", err);
4766         return err;
4767 }
4768 /* Scheduled sending ------------------------------------------------ */
4769
4770 #ifdef __FEATURE_AUTO_RETRY_SEND__
4771
4772 static int emcore_auto_resend_cb(email_alarm_data_t *alarm_data, void *user_parameter)
4773 {
4774         EM_DEBUG_FUNC_BEGIN("alarm_data [%p] user_parameter [%p]", alarm_data, user_parameter);
4775         int err = EMAIL_ERROR_NONE;
4776         char *conditional_clause_string = NULL;
4777         char *attribute_field_name = NULL;
4778         email_list_filter_t filter_list[5];
4779         email_mail_list_item_t *result_mail_list = NULL;
4780         email_list_sorting_rule_t sorting_rule_list[2];
4781         int filter_rule_count = 5;
4782         int sorting_rule_count = 2;
4783         int result_mail_count = 0;
4784         int result_handle = 0;
4785         int i = 0;
4786         char *multi_user_name = (char *)user_parameter;
4787
4788         email_event_t *event_data = NULL;
4789
4790         /* Get all mails have remaining resend counts in outbox with status 'EMAIL_MAIL_STATUS_SEND_FAILURE or EMAIL_MAIL_STATUS_SEND_WAIT' */
4791         attribute_field_name = emcore_get_mail_field_name_by_attribute_type(EMAIL_MAIL_ATTRIBUTE_REMAINING_RESEND_TIMES);
4792
4793         memset(filter_list, 0 , sizeof(email_list_filter_t) * filter_rule_count);
4794         memset(sorting_rule_list, 0 , sizeof(email_list_sorting_rule_t) * sorting_rule_count);
4795
4796         filter_list[0].list_filter_item_type                               = EMAIL_LIST_FILTER_ITEM_RULE;
4797         filter_list[0].list_filter_item.rule.target_attribute              = EMAIL_MAIL_ATTRIBUTE_REMAINING_RESEND_TIMES;
4798         filter_list[0].list_filter_item.rule.rule_type                     = EMAIL_LIST_FILTER_RULE_GREATER_THAN;
4799         filter_list[0].list_filter_item.rule.key_value.integer_type_value  = 0;
4800
4801         filter_list[1].list_filter_item_type                               = EMAIL_LIST_FILTER_ITEM_OPERATOR;
4802         filter_list[1].list_filter_item.operator_type                      = EMAIL_LIST_FILTER_OPERATOR_AND;
4803
4804         filter_list[2].list_filter_item_type                               = EMAIL_LIST_FILTER_ITEM_RULE;
4805         filter_list[2].list_filter_item.rule.target_attribute              = EMAIL_MAIL_ATTRIBUTE_MAILBOX_TYPE;
4806         filter_list[2].list_filter_item.rule.rule_type                     = EMAIL_LIST_FILTER_RULE_EQUAL;
4807         filter_list[2].list_filter_item.rule.key_value.integer_type_value  = EMAIL_MAILBOX_TYPE_OUTBOX;
4808
4809         filter_list[3].list_filter_item_type                               = EMAIL_LIST_FILTER_ITEM_OPERATOR;
4810         filter_list[3].list_filter_item.operator_type                      = EMAIL_LIST_FILTER_OPERATOR_AND;
4811
4812         filter_list[4].list_filter_item_type                               = EMAIL_LIST_FILTER_ITEM_RULE;
4813         filter_list[4].list_filter_item.rule.target_attribute              = EMAIL_MAIL_ATTRIBUTE_SAVE_STATUS;
4814         filter_list[4].list_filter_item.rule.rule_type                     = EMAIL_LIST_FILTER_RULE_EQUAL;
4815         filter_list[4].list_filter_item.rule.key_value.integer_type_value  = EMAIL_MAIL_STATUS_SEND_FAILURE;
4816
4817         sorting_rule_list[0].target_attribute                              = EMAIL_MAIL_ATTRIBUTE_ACCOUNT_ID;
4818         sorting_rule_list[0].sort_order                                    = EMAIL_SORT_ORDER_ASCEND;
4819
4820         sorting_rule_list[1].target_attribute                              = EMAIL_MAIL_ATTRIBUTE_MAIL_ID;
4821         sorting_rule_list[1].sort_order                                    = EMAIL_SORT_ORDER_ASCEND;
4822
4823         if ((err = emstorage_write_conditional_clause_for_getting_mail_list(multi_user_name, filter_list, filter_rule_count, sorting_rule_list, sorting_rule_count, -1, -1, &conditional_clause_string)) != EMAIL_ERROR_NONE) {
4824                 EM_DEBUG_EXCEPTION("emstorage_write_conditional_clause_for_getting_mail_list failed[%d]", err);
4825                 goto FINISH_OFF;
4826         }
4827
4828         EM_DEBUG_LOG("conditional_clause_string[%s].", conditional_clause_string);
4829
4830         if (!emstorage_query_mail_list(multi_user_name, conditional_clause_string, true, &result_mail_list, &result_mail_count, &err) && !result_mail_list) {
4831                 EM_DEBUG_LOG("There is no mails to be sent [%d]", err);
4832                 goto FINISH_OFF;
4833         }
4834
4835         /* Send mails in loop */
4836         for (i = 0; i < result_mail_count; i++) {
4837                 event_data = em_malloc(sizeof(email_event_t));
4838                 if (event_data == NULL) {
4839                         EM_DEBUG_EXCEPTION("em_malloc failed");
4840                         err = EMAIL_ERROR_OUT_OF_MEMORY;
4841                         goto FINISH_OFF;
4842                 }
4843
4844                 event_data->type = EMAIL_EVENT_SEND_MAIL;
4845                 event_data->account_id = result_mail_list[i].account_id;
4846                 event_data->event_param_data_4 = result_mail_list[i].mail_id;
4847                 event_data->event_param_data_5 = result_mail_list[i].mailbox_id;
4848                 event_data->multi_user_name = EM_SAFE_STRDUP(multi_user_name);
4849
4850                 if (!emcore_insert_event_for_sending_mails(event_data, &result_handle, &err)) {
4851                         EM_DEBUG_EXCEPTION("emcore_insert_event_for_sending_mails failed : [%d]", err);
4852                         goto FINISH_OFF;
4853                 }
4854
4855                 if (attribute_field_name) {
4856                         if (!emstorage_set_field_of_mails_with_integer_value(multi_user_name,
4857                                                 result_mail_list[i].account_id,
4858                                                 &(result_mail_list[i].mail_id),
4859                                                 1,
4860                                                 attribute_field_name,
4861                                                 result_mail_list[i].remaining_resend_times - 1,
4862                                                 true,
4863                                                 &err)) {
4864                                 EM_DEBUG_EXCEPTION("emstorage_set_field_of_mails_with_integer_value failed [%d]", err);
4865                         }
4866                 }
4867
4868                 /* Do not free the event_data */
4869                 /* Because the event_data is freed in event_handler */
4870                 event_data = NULL;
4871                 err = EMAIL_ERROR_NONE;
4872         }
4873
4874 FINISH_OFF:
4875
4876         if (err != EMAIL_ERROR_NONE) {
4877                 if (event_data) {
4878                         emcore_free_event(event_data);
4879                         EM_SAFE_FREE(event_data);
4880                 }
4881         }
4882
4883         EM_SAFE_FREE(conditional_clause_string); /* detected by valgrind */
4884         EM_SAFE_FREE(result_mail_list);
4885
4886         EM_DEBUG_FUNC_END("err [%d]", err);
4887         return err;
4888 }
4889
4890 INTERNAL_FUNC int emcore_create_alarm_for_auto_resend(char *multi_user_name, int input_alarm_interval_in_second)
4891 {
4892         EM_DEBUG_FUNC_BEGIN("input_alarm_interval_in_second[%d]", input_alarm_interval_in_second);
4893         int err = EMAIL_ERROR_NONE;
4894         time_t current_time;
4895         time_t trigger_at_time;
4896         char *conditional_clause_string = NULL;
4897         email_list_filter_t filter_list[5];
4898         email_mail_list_item_t *result_mail_list = NULL;
4899         email_list_sorting_rule_t sorting_rule_list[2];
4900         int filter_rule_count = 5;
4901         int sorting_rule_count = 2;
4902         int result_mail_count = 0;
4903
4904         if (input_alarm_interval_in_second <= 0) {
4905                 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
4906                 err = EMAIL_ERROR_INVALID_PARAM;
4907                 goto FINISH_OFF;
4908         }
4909
4910         /* Check whether the alarm is already existing */
4911         if (emcore_check_alarm_by_class_id(EMAIL_ALARM_CLASS_AUTO_RESEND) == EMAIL_ERROR_NONE) {
4912                 /* already exist */
4913                 err = EMAIL_ERROR_ALREADY_EXISTS;
4914                 goto FINISH_OFF;
4915         }
4916         /* Get all mails have remaining resend counts in outbox with status 'EMAIL_MAIL_STATUS_SEND_FAILURE or EMAIL_MAIL_STATUS_SEND_WAIT' */
4917
4918         memset(filter_list, 0 , sizeof(email_list_filter_t) * filter_rule_count);
4919         memset(sorting_rule_list, 0 , sizeof(email_list_sorting_rule_t) * sorting_rule_count);
4920
4921         filter_list[0].list_filter_item_type                               = EMAIL_LIST_FILTER_ITEM_RULE;
4922         filter_list[0].list_filter_item.rule.target_attribute              = EMAIL_MAIL_ATTRIBUTE_REMAINING_RESEND_TIMES;
4923         filter_list[0].list_filter_item.rule.rule_type                     = EMAIL_LIST_FILTER_RULE_GREATER_THAN;
4924         filter_list[0].list_filter_item.rule.key_value.integer_type_value  = 0;
4925
4926         filter_list[1].list_filter_item_type                               = EMAIL_LIST_FILTER_ITEM_OPERATOR;
4927         filter_list[1].list_filter_item.operator_type                      = EMAIL_LIST_FILTER_OPERATOR_AND;
4928
4929         filter_list[2].list_filter_item_type                               = EMAIL_LIST_FILTER_ITEM_RULE;
4930         filter_list[2].list_filter_item.rule.target_attribute              = EMAIL_MAIL_ATTRIBUTE_MAILBOX_TYPE;
4931         filter_list[2].list_filter_item.rule.rule_type                     = EMAIL_LIST_FILTER_RULE_EQUAL;
4932         filter_list[2].list_filter_item.rule.key_value.integer_type_value  = EMAIL_MAILBOX_TYPE_OUTBOX;
4933
4934         filter_list[3].list_filter_item_type                               = EMAIL_LIST_FILTER_ITEM_OPERATOR;
4935         filter_list[3].list_filter_item.operator_type                      = EMAIL_LIST_FILTER_OPERATOR_AND;
4936
4937         filter_list[4].list_filter_item_type                               = EMAIL_LIST_FILTER_ITEM_RULE;
4938         filter_list[4].list_filter_item.rule.target_attribute              = EMAIL_MAIL_ATTRIBUTE_SAVE_STATUS;
4939         filter_list[4].list_filter_item.rule.rule_type                     = EMAIL_LIST_FILTER_RULE_EQUAL;
4940         filter_list[4].list_filter_item.rule.key_value.integer_type_value  = EMAIL_MAIL_STATUS_SEND_FAILURE;
4941
4942         sorting_rule_list[0].target_attribute                              = EMAIL_MAIL_ATTRIBUTE_ACCOUNT_ID;
4943         sorting_rule_list[0].sort_order                                    = EMAIL_SORT_ORDER_ASCEND;
4944
4945         sorting_rule_list[1].target_attribute                              = EMAIL_MAIL_ATTRIBUTE_MAIL_ID;
4946         sorting_rule_list[1].sort_order                                    = EMAIL_SORT_ORDER_ASCEND;
4947
4948         if ((err = emstorage_write_conditional_clause_for_getting_mail_list(multi_user_name, filter_list, filter_rule_count, sorting_rule_list, sorting_rule_count, -1, -1, &conditional_clause_string)) != EMAIL_ERROR_NONE) {
4949                 EM_DEBUG_EXCEPTION("emstorage_write_conditional_clause_for_getting_mail_list failed[%d]", err);
4950                 goto FINISH_OFF;
4951         }
4952
4953         EM_DEBUG_LOG("conditional_clause_string[%s].", conditional_clause_string);
4954
4955         if (!emstorage_query_mail_list(multi_user_name, conditional_clause_string, true, &result_mail_list, &result_mail_count, &err) && !result_mail_list) {
4956                 if (err == EMAIL_ERROR_MAIL_NOT_FOUND)
4957                         EM_DEBUG_LOG("no mail found");
4958                 else
4959                         EM_DEBUG_EXCEPTION("emstorage_query_mail_list [%d]", err);
4960                 goto FINISH_OFF;
4961         }
4962
4963         if (result_mail_count > 0) {
4964                 /* Add alarm */
4965                 time(&current_time);
4966
4967                 trigger_at_time = current_time + input_alarm_interval_in_second;
4968
4969                 if ((err = emcore_add_alarm(multi_user_name, trigger_at_time, EMAIL_ALARM_CLASS_AUTO_RESEND, 0, emcore_auto_resend_cb, NULL)) != EMAIL_ERROR_NONE) {
4970                         EM_DEBUG_EXCEPTION("emcore_add_alarm failed [%d]", err);
4971                         goto FINISH_OFF;
4972                 }
4973         }
4974
4975 FINISH_OFF:
4976         EM_SAFE_FREE(result_mail_list);
4977         EM_SAFE_FREE(conditional_clause_string);
4978         EM_DEBUG_FUNC_END("err[%d]", err);
4979         return err;
4980 }
4981 #endif /* __FEATURE_AUTO_RETRY_SEND__ */