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