a40b31961479a266d7a64b025c36b60db1ba1223
[profile/ivi/wrt-plugins-tizen.git] / src / platform / Tizen / Messaging / Email.cpp
1 /*
2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License. 
15 */
16
17
18 /**
19  *
20  *
21  * @file       Email.cpp
22  * @author     Pawel Misiak (p.misiak@samsung.com)
23  * @version    0.1
24  * @brief
25  */
26 #include <cstdio>
27 #include <cstddef>
28 #include <cstdlib>
29 #include <ctime>
30 #include <emf-types.h>
31 #include <Emf_Mapi.h>
32 #include <dpl/log/log.h>
33 #include <dpl/assert.h>
34 #include <dpl/scoped_fclose.h>
35 #include <dpl/scoped_ptr.h>
36 #include <Commons/Exception.h>
37 #include <Commons/StringUtils.h>
38 #include <API/Messaging/MessageFactory.h>
39 #include <API/Messaging/EmailAccountInfo.h>
40 #include "Messaging.h"
41 #include "Email.h"
42 #include "EmailService.h"
43 #include "EmailUtils.h"
44 #include "EmailConverter.h"
45 #include "MailSender.h"
46 #include "MailSync.h"
47 #include "MessagingService.h"
48 #include "MessagingServiceManager.h"
49 #include "Attachment.h"
50
51 #define LOG_ENTER LogDebug("---> ENTER");
52 #define LOG_EXIT LogDebug("---> EXIT");
53
54 using namespace std;
55 using namespace TizenApis::Api::Messaging;
56 using namespace WrtDeviceApis::Commons;
57
58 namespace TizenApis {
59 namespace Platform {
60 namespace Messaging {
61
62 #if 0 // UNUSED CODE
63 namespace {
64 //#define USE_OUTBOX
65
66 #ifdef USE_OUTBOX
67 const Api::Messaging::FolderType DEFAULT_FOLDER = Api::Messaging::OUTBOX;
68 const char* DEFAULT_FOLDER_NAME = EMF_OUTBOX_NAME;
69 #else
70 const Api::Messaging::FolderType DEFAULT_FOLDER = Api::Messaging::DRAFTBOX;
71 const char* DEFAULT_FOLDER_NAME = EMF_DRAFTBOX_NAME;
72 #endif
73 }
74 #endif
75
76 namespace {
77 const char* TEMP_FOLDER = "/tmp";
78 const char* COMMAND_NAME = "/bin/cp";
79 const char* COMMAND_SWITCH_RECURSIVE = "-r";
80 const char* COMMAND_SWITCH_FORCE = "-f";
81 }
82
83 Email::Email(const string& id) :
84         IMessage(EMAIL, id) {
85         LOG_ENTER
86
87         try {
88                 if (getIdRef().empty()) {
89                         create();
90                 }
91                 // always read the message (after creation some of attributes change
92                 // i.e. body->plain)
93
94                 //get account ID
95                 
96                 reload();
97         } catch (const WrtDeviceApis::Commons::PlatformException& ex) {
98                 LogError("Exception: " << ex.DumpToString());
99         }
100
101         LOG_EXIT
102 }
103
104 Email::Email(const std::string& id, int accountId) :
105         IMessage(EMAIL, id) 
106 {
107         LOG_ENTER
108
109         try {
110                 // always read the message (after creation some of attributes change
111                 // i.e. body->plain)
112
113                 //get account ID
114                 LogDebug("Account ID = " << accountId);
115                 m_accountId = accountId;
116                 reload();
117                 
118         } catch (const WrtDeviceApis::Commons::PlatformException& ex) {
119                 LogError("Exception: " << ex.DumpToString());
120         }
121
122
123         LOG_EXIT
124 }
125
126 Email::Email(Api::Messaging::EmailAccountInfo& account) : IMessage(EMAIL)
127 {
128     LOG_ENTER
129
130     try {
131          if (getIdRef().empty()) {
132                 create(account);
133          }
134         // always read the message (after creation some of attributes change
135         // i.e. body->plain)
136         reload();
137     }
138     catch (const WrtDeviceApis::Commons::PlatformException& ex) {
139         LogError("Exception: " << ex.DumpToString());
140     }
141
142     LOG_EXIT
143 }
144
145 Email::~Email()
146 {
147     LogDebug("ENTER");
148 }
149
150 int Email::send()
151 {
152     LOG_ENTER
153
154     update();
155
156     int handle = MailSender::getInstance().send(
157         Api::Messaging::MessageFactory::convertToEmail(SharedFromThis())
158         );
159
160     return handle;
161     LOG_EXIT
162 }
163
164 void Email::sendCancel(int handle)
165 {
166     LOG_ENTER
167
168     MailSender::getInstance().cancel(handle);
169
170     LOG_EXIT
171 }
172
173 int Email::downloadBody()
174 {
175         LOG_ENTER
176
177         return MailSync::getInstance().downloadBody( Api::Messaging::MessageFactory::convertToEmail(SharedFromThis()) );
178         
179         LOG_EXIT
180 }
181
182 void Email::downloadBodyCancel( int handle)
183 {       
184         
185         return ;
186 }
187
188 int Email::downloadAttachment( const Api::Messaging::IAttachmentPtr& attachment)
189 {
190         LOG_ENTER
191
192         return MailSync::getInstance().downloadAttachment( Api::Messaging::MessageFactory::convertToEmail(SharedFromThis()), attachment );
193         
194         LOG_EXIT
195 }
196
197 void Email::update(bool draftsOnly)
198 {
199     LOG_ENTER
200
201     DPL::Mutex::ScopedLock mx(&m_updateMutex);
202
203     if (!m_mail) {
204         ThrowMsg(WrtDeviceApis::Commons::PlatformException, "Mail is NULL.");
205     }
206
207     LogDebug("getCurrentFolder() = " << getCurrentFolder() );
208     if (!draftsOnly || (getCurrentFolder() == Api::Messaging::DRAFTBOX)) {
209         updateBody();
210         updateSubject();
211         updateRecipients();
212         updateFrom();
213         updateAttachments();
214         updatePriority();
215     } else {
216         LogWarning("Updating only read status. Folder: " << getCurrentFolder());
217     }
218     updateReadStatus();
219
220     int error = email_update_message(getIntId(), m_mail.Get());
221     if (EMF_ERROR_NONE != error) {
222         LogWarning("Nothing to update or error. [" << error << "]");
223     }
224
225     LOG_EXIT
226 }
227
228 int Email::getAccountID()
229 {
230         LOG_ENTER
231
232         if ( m_mail )
233                 return m_mail->info->account_id;
234         else
235                 return -1;
236         
237         LOG_EXIT
238 }
239
240 int Email::getUID()
241 {
242         LOG_ENTER
243         
244         if (m_mail)
245                 return m_mail->info->uid;
246         else
247                 return -1;
248
249         LOG_EXIT
250 }
251
252 int Email::isBodyDownloaded()
253 {
254         
255         if (m_mail)
256                 return m_mail->info->body_downloaded;
257         else
258                 return false;
259 }
260
261 void Email::readAllData()
262 {
263     reload();
264 }
265
266 void Email::moveToFolder(const FolderType newFolder)
267 {
268     LOG_ENTER
269
270     moveToFolder(EmailConverter::toMailboxName(newFolder));
271
272     LOG_EXIT
273 }
274
275 void Email::moveToFolder(const string& newFolder)
276 {
277     update();
278
279     int accountId = Messaging::getInstance().getEmailAccountId(getFromRef());
280     ScopedMailbox mailbox(
281         EmailService::createMailbox(accountId, newFolder.c_str())
282         );
283
284     int mailId = getIntId();
285
286     int error = email_move_mail_to_mailbox(&mailId, 1, mailbox.Get());
287     if (EMF_ERROR_NONE != error) {
288         ThrowMsg(
289             WrtDeviceApis::Commons::PlatformException,
290             "Couldn't move mail to folder: " << newFolder << ". [" <<
291             error << "]");
292     }
293 }
294
295 void Email::copyToFolder(const FolderType newFolder)
296 {
297     LOG_ENTER
298
299     copyToFolder(EmailConverter::toMailboxName(newFolder));
300
301     LOG_EXIT
302 }
303
304 void Email::copyToFolder(const string& newFolder)
305 {
306     LOG_ENTER
307
308     update();
309
310     int accountId = Messaging::getInstance().getEmailAccountId(getFromRef());
311
312     ScopedMail mail(EmailService::cloneMail(m_mail.Get()));
313     ScopedMailbox mailbox(
314         EmailService::createMailbox(accountId, newFolder.c_str())
315         );
316
317     int mailId = EmailService::addMailToMailbox(mail.Get(), mailbox.Get());
318     // TODO Is following check necessary?
319     if (0 == mailId) {
320         ThrowMsg(WrtDeviceApis::Commons::PlatformException, "Cloned mail didn't get new id.");
321     }
322
323     LOG_EXIT
324 }
325
326 void Email::remove()
327 {
328     EmailService::deleteMail(m_accountId, getIntId());
329 }
330
331 void Email::create()
332 {
333     LOG_ENTER
334
335     EmailAccountInfo account = IMessaging::getInstance().getCurrentEmailAccount();
336     m_accountId = account.getIntId();
337     ScopedMail mail(EmailService::createMail(account));
338     ScopedMailbox mailbox(
339         EmailService::getMailboxByType(account.getIntId(),
340                                        EMF_MAILBOX_TYPE_DRAFT)
341         );
342     setId(convertId(EmailService::addMailToMailbox(mail.Get(), mailbox.Get())));
343     setFolderType(Api::Messaging::DRAFTBOX);
344     setMessageStatus(Api::Messaging::MESSAGE_STATUS_DRAFT);
345
346     LOG_EXIT
347 }
348
349 void Email::create( Api::Messaging::EmailAccountInfo& account )
350 {
351         LOG_ENTER
352
353         m_accountId = account.getIntId();
354         MailSender::getInstance();
355         
356       LogDebug("account ID : " << m_accountId);
357         ScopedMail mail(EmailService::createMail(account));
358         ScopedMailbox mailbox(EmailService::getMailboxByType(account.getIntId(), EMF_MAILBOX_TYPE_DRAFT));
359         setId(convertId(EmailService::addMailToMailbox(mail.Get(), mailbox.Get())));
360         setFolderType(Api::Messaging::DRAFTBOX);
361         setMessageStatus(Api::Messaging::MESSAGE_STATUS_DRAFT);
362             
363     LOG_EXIT
364 }
365
366 void Email::reload()
367 {
368     LOG_ENTER
369
370    //EmailAccountInfo account = Messaging::getInstance().getCurrentEmailAccount();
371     LogDebug("account ID :" << m_accountId);
372     m_mail.Reset(EmailService::readMail(m_accountId, getIntId()));
373
374     if (m_mail->head) { readHeader(); }
375     if (m_mail->body) { readBody(); }
376     if (m_mail->info) { readInfo(); }
377
378     m_mailbox.Reset(EmailService::getMailboxByMailId(m_accountId, getIntId()) );
379     setFolderType(EmailConverter::toFolderType(m_mailbox->mailbox_type));
380
381     LOG_EXIT
382 }
383
384 void Email::readHeader()
385 {
386     LOG_ENTER
387
388     Assert(m_mail && m_mail->head && "Header is NULL.");
389
390     if (m_mail->head->subject) {
391         setSubject(m_mail->head->subject);
392     }
393
394     if (m_mail->head->to) {
395         appendToRecipients(EmailUtils::stripAddressLine(m_mail->head->to));
396     }
397
398     if (m_mail->head->cc) {
399         appendCcRecipients(EmailUtils::stripAddressLine(m_mail->head->cc));
400     }
401
402     if (m_mail->head->bcc) {
403         appendBccRecipients(EmailUtils::stripAddressLine(m_mail->head->bcc));
404     }
405
406     time_t rawtime;
407     time(&rawtime);
408     struct tm tmpTime = *(localtime(&rawtime));
409     tmpTime.tm_year = m_mail->head->datetime.year;
410     tmpTime.tm_mon = m_mail->head->datetime.month;
411     tmpTime.tm_mday = m_mail->head->datetime.day;
412     tmpTime.tm_hour = m_mail->head->datetime.hour;
413     tmpTime.tm_min = m_mail->head->datetime.minute;
414     tmpTime.tm_sec = m_mail->head->datetime.second;
415     mktime(&tmpTime);
416     setDateTime(tmpTime);
417
418     if (m_mail->head->from) {
419         Recipients from;
420         from.setRecipients(m_mail->head->from);
421         setSourceAddress(from);
422         setSourceAddressValidity(true); //not needed to update in platform
423     }
424
425     LOG_EXIT
426 }
427
428 void Email::readBody() {
429         LOG_ENTER
430
431         Assert(m_mail && m_mail->body && "Body is NULL.");
432
433         if (m_mail->body->plain) {
434                 DPL::ScopedFClose file(::fopen(m_mail->body->plain, "r"));
435                 if (!file) {
436                         ThrowMsg(WrtDeviceApis::Commons::PlatformException,
437                                         "Cannot read body file: " << m_mail->body->plain);
438                 }
439                 fseek(file.Get(), 0, SEEK_END);
440                 long int size = ftell(file.Get());
441                 fseek(file.Get(), 0, SEEK_SET);
442                 DPL::ScopedPtr<char> data(new char[size + 1]);
443                 memset(data.Get(), 0, size + 1);
444                 fread(data.Get(), 1, size, file.Get());
445                 setBody(data.Get());
446         }
447
448         //html body.
449         if (m_mail->body->html) {
450                 DPL::ScopedFClose file(::fopen(m_mail->body->html, "r")); //auto close, scopedFClose
451                 if (!file) {
452                         ThrowMsg(WrtDeviceApis::Commons::PlatformException,
453                                         "Cannot read html body file: " << m_mail->body->html);
454                 }
455
456                 fseek(file.Get(), 0, SEEK_END);
457                 long int size = ftell(file.Get());
458                 fseek(file.Get(), 0, SEEK_SET);
459                 DPL::ScopedPtr<char> data(new char[size + 1]);
460                 memset(data.Get(), 0, size + 1);
461                 fread(data.Get(), 1, size, file.Get());
462                 setHtmlBody(data.Get()); //setHtmlBody declarate in Email Calss.
463         }
464         
465         if (m_mail->body->attachment && m_mail->body->attachment_num > 0) {
466                 LogDebug("reading attachments , attahcment count = " << m_mail->body->attachment_num);
467                 emf_attachment_info_t* attach = m_mail->body->attachment;
468                 for (int i = 0; i < m_mail->body->attachment_num; ++i) {
469                         if (!attach) {
470                                 LogDebug("throw platform exception");
471                                 ThrowMsg(WrtDeviceApis::Commons::PlatformException,
472                                                 "Attachment list shorter than expected.");
473                         }
474                         
475                         try {
476                                 
477                                 LogError("id :" << attach->attachment_id << " name :" << attach->name << " download :" << attach->downloaded << " savefile :" << attach->savename );
478                                 
479                                 IAttachmentPtr tmpAtt(new Attachment(attach));
480                                 LogError(" create new attachment ");
481                                 if (tmpAtt)
482                                 {
483                                         //tmpAtt->setMessage(SharedFromThis());                 //set IMessagePtr
484                                         tmpAtt->rename(attach->name);
485                                         tmpAtt->setAttachmentID(attach->attachment_id);
486                                         tmpAtt->setDownloaded(attach->downloaded);
487                                         tmpAtt->setNth(i+1);
488                                         appendAttachment(tmpAtt);
489                                         LogError(" append complete");
490                                 }
491                                                                 
492                                 attach = attach->next;
493                 }
494                 catch (const WrtDeviceApis::Commons::Exception& ex) {
495                                 LogError("Error while trying to append attachment " <<
496                                         attach->savename << ": " << ex.DumpToString());
497                         }
498                 }
499         }
500
501         LOG_EXIT
502 }
503
504 void Email::readInfo()
505 {
506     LOG_ENTER
507
508     Assert(m_mail && m_mail->info && "Info is NULL.");
509
510     setReadStatus(m_mail->info->flags.seen == 1);
511
512     m_accountId = m_mail->info->account_id;
513
514     setPriority(
515         EmailConverter::toMessagePriority( m_mail->info->extra_flags.priority )
516         );
517     setSize(m_mail->info->rfc822_size);
518
519     LOG_EXIT
520 }
521
522 void Email::updateBody()
523 {
524     LOG_ENTER
525
526     if (isBodyValid()) { return; }
527
528     if (!m_mail) {
529         ThrowMsg(WrtDeviceApis::Commons::PlatformException, "Mail is NULL.");
530     }
531
532     if (!m_mail->body) {
533         ThrowMsg(WrtDeviceApis::Commons::PlatformException, "Body is NULL.");
534     }
535     if (!m_mail->body->plain) {
536         ThrowMsg(WrtDeviceApis::Commons::PlatformException, "Body file is NULL.");
537     }
538
539     if (!m_mail->body->html) {
540         ThrowMsg(WrtDeviceApis::Commons::PlatformException, "Html Body file is NULL.");
541     }
542
543     if (!m_mail->info) {
544         ThrowMsg(WrtDeviceApis::Commons::PlatformException, "Info is NULL.");
545     }
546
547     //update plain body.
548     FILE* f = fopen(m_mail->body->plain, "w");
549     if (NULL != f) {
550         //fprintf(f, getBodyRef().c_str());
551         fwrite(getBodyRef().c_str(), strlen(getBodyRef().c_str()), 1, f);
552         fclose(f);
553     }
554     else
555     {
556                 LogDebug("Plain Body file is NULL.");
557     }
558
559     if (m_mail->body->html) {
560         //update html body
561         f = fopen(m_mail->body->html, "w");
562             if (NULL != f) {
563                 //fprintf(f, getHtmlBody().c_str());
564                   fwrite(getHtmlBody().c_str(), strlen(getHtmlBody().c_str()), 1, f);
565                 fclose(f);
566             } 
567     }
568     else
569     {
570                 LogDebug("Html Body file is NULL.");
571     }
572     
573     m_mail->info->body_downloaded = true;
574     setBodyValidity(true);
575
576     LOG_EXIT
577 }
578
579 void Email::updateSubject()
580 {
581     LOG_ENTER
582
583     if (isSubjectValid()) { return; }
584
585     LogDebug("update subject, msgId=" << getIdRef());
586
587     if (!m_mail) {
588         ThrowMsg(WrtDeviceApis::Commons::PlatformException, "Mail not allocated.");
589     }
590
591     if (!m_mail->head) {
592         m_mail->head = EmailService::alloc<emf_mail_head_t>();
593     }
594
595     m_mail->head->subject = String::strdup(getSubjectRef());
596     setSubjectValidity(true);
597
598     LOG_EXIT
599 }
600
601 void Email::updateReadStatus()
602 {
603     LOG_ENTER
604
605     if (isReadStatusValid()) { return; }
606
607     LogDebug("update read, msgId=" << getIdRef());
608
609     if (!m_mail) {
610         ThrowMsg(WrtDeviceApis::Commons::PlatformException, "Mail not allocated.");
611     }
612
613     if (!m_mail->info) {
614         EmailService::alloc<emf_mail_info_t>();
615     }
616
617     m_mail->info->flags.seen = isRead();
618     setReadStatusValidity(true);
619
620     LOG_EXIT
621 }
622
623 void Email::updateIsRead()
624 {
625     LOG_ENTER
626     if (isReadChangeStatusValid()) {
627         // do not update if not changed
628         return;
629     }
630
631     EmailService::updateSeenFlag(getAccountID(), getIntId(), isReadChangeStatus());
632     setisReadChangeStatusValidity(true);
633     LOG_EXIT
634 }
635
636 void Email::addMessageToDraft()
637 {
638     LOG_ENTER
639
640     DPL::Mutex::ScopedLock mx(&m_updateMutex);
641
642     if (!m_mail) {
643         ThrowMsg(WrtDeviceApis::Commons::PlatformException, "Mail is NULL.");
644     }
645
646     updateBody();
647     updateSubject();
648     updateRecipients();
649     updateFrom();
650     updatePriority();
651
652     int error = email_update_message(getIntId(), m_mail.Get()); 
653     LogDebug("add finished, mailId = " << error);               
654     LOG_EXIT
655 }
656
657 void Email::updateRecipients()
658 {
659     LOG_ENTER
660
661     if (getToValidity() && getCcValidity() && getBccValidity()) { return; }
662
663     if (!m_mail) {
664         ThrowMsg(WrtDeviceApis::Commons::PlatformException, "Mail is NULL.");
665     }
666
667     if (!m_mail->head) {
668         m_mail->head = EmailService::alloc<emf_mail_head_t>();
669     }
670
671     if (!getToValidity()) {
672         std::string addressLine = EmailUtils::formatAddressLine(getToRecipients());
673         if (m_mail->head->to) {
674             free(m_mail->head->to);
675         }
676         m_mail->head->to = String::strdup(addressLine);
677         setToValidity(true);
678     }
679
680     if (!getCcValidity()) {
681         std::string addressLine = EmailUtils::formatAddressLine(getCcRecipients());
682         if (m_mail->head->cc) {
683             free(m_mail->head->cc);
684         }
685         m_mail->head->cc = String::strdup(addressLine);
686         setCcValidity(true);
687     }
688
689     if (!getBccValidity()) {
690         std::string addressLine = EmailUtils::formatAddressLine(
691                 getBccRecipients());
692         if (m_mail->head->bcc) {
693             free(m_mail->head->bcc);
694         }
695         m_mail->head->bcc = String::strdup(addressLine);
696         setBccValidity(true);
697     }
698
699     LOG_EXIT
700 }
701
702 void Email::updateFrom()
703 {
704     LOG_ENTER
705
706     if (getFromValidity()) { return; }
707
708     if (!m_mail) {
709         ThrowMsg(WrtDeviceApis::Commons::PlatformException, "Mail is NULL.");
710     }
711
712     if (!m_mail->info) {
713         EmailService::alloc<emf_mail_info_t>();
714     }
715
716     m_mail->info->account_id = m_accountId;
717     // TODO Update m_mail->head->from as well
718
719     setFromValidity(true);
720
721     LOG_EXIT
722 }
723
724 void Email::updateAttachments()
725 {
726     LOG_ENTER
727
728     if (isAttachmentsValid()) { return; }
729
730     if (!m_mail) {
731         ThrowMsg(WrtDeviceApis::Commons::PlatformException, "Mail is NULL.");
732     }
733
734     emf_attachment_info_t* attachment = NULL;
735     Try {
736         LogDebug("update attachments, msgId=" << getIdRef());
737
738         if (!m_mail->body) {
739             m_mail->body = EmailService::alloc<emf_mail_body_t>();
740         } else {
741                 //clean attachment
742                 int i = m_mail->body->attachment_num;
743                 LogDebug("clean attachment, attachment count=" << i);
744                 attachment = m_mail->body->attachment;
745                 std::stringstream stream;
746                 
747                 while(attachment)
748                 {       
749                         LogDebug("delete file :" << attachment->name << " saved name :" << attachment->savename );
750                         int aId = attachment->attachment_id;
751                         char* mId = m_mail->head->mid;
752                         int n_mId = 0;
753                         stream << mId;
754                         stream >> n_mId;
755                         stream << aId;
756
757                         LogDebug("mID :"  << n_mId << " Attachment Id :" << aId );
758                         
759                         int error = email_delete_attachment(m_mailbox.Get(), n_mId, (const char*)(stream.str()).c_str());
760                         if (EMF_ERROR_NONE != error) {
761                             LogDebug("Error Num = " << error);
762                             ThrowMsg(WrtDeviceApis::Commons::PlatformException,
763                                      "Error while adding attachment. [" << error << "]");
764                         }
765                         attachment = attachment->next;
766                 }
767                 
768             m_mail->body->attachment_num = 0;
769             if (NULL != m_mail->body->attachment) {
770                 EmailService::freeAttachment(m_mail->body->attachment);
771                 m_mail->body->attachment = NULL;
772             }
773         }
774
775         std::size_t attachmentSize = getAttachmentsCount();
776         LogDebug("update attachments, attachmentSize=" << attachmentSize);
777         if (attachmentSize > 0) {
778             if (!m_mail->info) {
779                 ThrowMsg(WrtDeviceApis::Commons::PlatformException, "Mail info is NULL.");
780             }
781
782             for (std::size_t i = 0; i < attachmentSize; ++i) {
783                 IAttachmentPtr att = getAttachment(i);
784                 if (!att) {
785                     continue;
786                 }
787
788                         //copy attachment file
789                         std::stringstream to_oss;
790                         to_oss << TEMP_FOLDER << "/" << att->getShortName();
791                         LogDebug("temp file=" << to_oss.str());
792                         
793                         std::stringstream cp_oss;
794                         cp_oss << COMMAND_NAME;
795                         cp_oss << " " << COMMAND_SWITCH_RECURSIVE;
796                         cp_oss << " \"" << att->getFullPath() << "\"";
797                         cp_oss << " \"" << to_oss.str() << "\"";
798
799                 attachment = EmailService::alloc<emf_attachment_info_t>();      //create attachment struct
800                 attachment->name = String::strdup(att->getShortName());
801                 //attachment->savename = String::strdup( att->getFullPath() );
802                 attachment->savename = String::strdup( to_oss.str().c_str() );
803                 
804                 attachment->next = NULL;
805                      attachment->downloaded = true;
806
807                         int result = system(cp_oss.str().c_str());                      
808                         if (-1 != result) {
809                             if (0 != WIFEXITED(result)) {
810                                 if (0 != WEXITSTATUS(result)) {
811                                     ThrowMsg(WrtDeviceApis::Commons::PlatformException, "Command failed.");
812                                 }
813                             } else {
814                                 ThrowMsg(WrtDeviceApis::Commons::PlatformException,
815                                          "Command terminated abnormally.");
816                             }
817                         } else {
818                             ThrowMsg(WrtDeviceApis::Commons::PlatformException, "Couldn't launch command.");
819                         }
820                                                                         
821                      LogDebug( "mailbox type = " << m_mailbox.Get()->mailbox_type);
822
823                 int error = email_add_attachment(m_mailbox.Get(),
824                                                  m_mail->info->uid,
825                                                  attachment);
826                 if (EMF_ERROR_NONE != error) {
827                     ThrowMsg(WrtDeviceApis::Commons::PlatformException,
828                              "Error while adding attachment. [" << error << "]");
829                 }
830                 else 
831                 {       
832                         LogDebug(" attachment id : " << attachment->attachment_id);                             
833                         //IMessagePtr msg = DPL::DynamicPointerCast<IMessage>(this);
834                         att->setDownloaded(true);
835                         att->setAttachmentID(attachment->attachment_id);
836                         att->setMessage(SharedFromThis());
837                         att->setNth(i+1);
838                 }
839
840                 EmailService::freeAttachment(attachment);
841             }
842
843             setAttachmentsValidity(true);
844         }
845     }
846     Catch(WrtDeviceApis::Commons::PlatformException) {
847         EmailService::freeAttachment(attachment);
848         throw;
849     }
850
851     LOG_EXIT
852 }
853
854 void Email::updatePriority()
855 {
856     LOG_ENTER
857
858     if (isPriorityValid()) { return; }
859
860     if (!m_mail) {
861         ThrowMsg(WrtDeviceApis::Commons::PlatformException, "Mail not allocated.");
862     }
863
864     if (!m_mail->info) {
865         m_mail->info = EmailService::alloc<emf_mail_info_t>();
866     }
867
868     m_mail->info->extra_flags.priority = EmailConverter::toMailPriority(
869             getPriority());
870     setPriorityValid(true);
871
872     LOG_EXIT
873 }
874
875 int Email::getIntId() const
876 {
877     return convertId(getIdRef());
878 }
879 }
880 }
881 }