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