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