diff --git a/src/add-ons/mail_daemon/inbound_protocols/imap/IMAPInboundProtocol.cpp b/src/add-ons/mail_daemon/inbound_protocols/imap/IMAPInboundProtocol.cpp index 84718f4f8f..df945bc81f 100644 --- a/src/add-ons/mail_daemon/inbound_protocols/imap/IMAPInboundProtocol.cpp +++ b/src/add-ons/mail_daemon/inbound_protocols/imap/IMAPInboundProtocol.cpp @@ -512,11 +512,10 @@ IMAPInboundProtocol::DeleteMessage(const entry_ref& ref) Connect(fServer, fUsername, fPassword, fUseSSL); fIMAPMailboxThread->StopWatchingMailbox(); + int32 uid = fStorage.RefToUID(ref); - int32 flags = fStorage.GetFlags(uid); - flags |= kDeleted; - status_t status = fIMAPMailbox.SetFlags( - fIMAPMailbox.UIDToMessageNumber(uid), flags); + status_t status = fIMAPMailbox.DeleteMessage(uid, false); + fIMAPMailboxThread->SyncAndStartWatchingMailbox(); return status; } @@ -576,11 +575,10 @@ IMAPInboundProtocol::DeleteMessage(node_ref& node) fIMAPMailboxThread->SyncAndStartWatchingMailbox(); return B_BAD_VALUE; } + int32 uid = entry->uid; - int32 flags = fStorage.GetFlags(uid); - flags |= kDeleted; - status_t status = fIMAPMailbox.SetFlags( - fIMAPMailbox.UIDToMessageNumber(uid), flags); + status_t status = fIMAPMailbox.DeleteMessage(uid, false); + fIMAPMailboxThread->SyncAndStartWatchingMailbox(); return status; } diff --git a/src/add-ons/mail_daemon/inbound_protocols/imap/imap_lib/IMAPHandler.cpp b/src/add-ons/mail_daemon/inbound_protocols/imap/imap_lib/IMAPHandler.cpp index 0fcbb454ce..c46ebba221 100644 --- a/src/add-ons/mail_daemon/inbound_protocols/imap/imap_lib/IMAPHandler.cpp +++ b/src/add-ons/mail_daemon/inbound_protocols/imap/imap_lib/IMAPHandler.cpp @@ -628,6 +628,27 @@ ExistsHandler::Handle(const BString& response) } +ExpungeCommmand::ExpungeCommmand(IMAPMailbox& mailbox) + : + IMAPMailboxCommand(mailbox) +{ + +} + +BString +ExpungeCommmand::Command() +{ + return "EXPUNGE"; +} + + +bool +ExpungeCommmand::Handle(const BString& response) +{ + return false; +} + + ExpungeHandler::ExpungeHandler(IMAPMailbox& mailbox) : IMAPMailboxCommand(mailbox) @@ -645,7 +666,15 @@ ExpungeHandler::Handle(const BString& response) if (!IMAPParser::ExtractUntagedFromLeft(response, "EXPUNGE", expunge)) return false; - fIMAPMailbox.DeleteMessage(expunge); + // remove from storage + IMAPStorage& storage = fIMAPMailbox.GetStorage(); + storage.DeleteMessage(fIMAPMailbox.MessageNumberToUID(expunge)); + + // remove from min message list + MinMessageList& messageList = const_cast( + fIMAPMailbox.GetMessageList()); + messageList.erase(messageList.begin() + expunge - 1); + TRACE("EXPUNGE %i\n", (int)expunge); // the watching loop restarts again, we need to watch again to because diff --git a/src/add-ons/mail_daemon/inbound_protocols/imap/imap_lib/IMAPHandler.h b/src/add-ons/mail_daemon/inbound_protocols/imap/imap_lib/IMAPHandler.h index 2009e265c4..580c733862 100644 --- a/src/add-ons/mail_daemon/inbound_protocols/imap/imap_lib/IMAPHandler.h +++ b/src/add-ons/mail_daemon/inbound_protocols/imap/imap_lib/IMAPHandler.h @@ -197,6 +197,18 @@ public: }; +/*! Just send a expunge command to delete kDeleted flagged messages. The +response is handled by the unsolicited ExpungeHandler which is installed all +the time. */ +class ExpungeCommmand : public IMAPMailboxCommand { +public: + ExpungeCommmand(IMAPMailbox& mailbox); + + BString Command(); + bool Handle(const BString& response); +}; + + class ExpungeHandler : public IMAPMailboxCommand { public: ExpungeHandler(IMAPMailbox& mailbox); diff --git a/src/add-ons/mail_daemon/inbound_protocols/imap/imap_lib/IMAPMailbox.cpp b/src/add-ons/mail_daemon/inbound_protocols/imap/imap_lib/IMAPMailbox.cpp index 7cf236808d..4fa6a94db3 100644 --- a/src/add-ons/mail_daemon/inbound_protocols/imap/imap_lib/IMAPMailbox.cpp +++ b/src/add-ons/mail_daemon/inbound_protocols/imap/imap_lib/IMAPMailbox.cpp @@ -289,14 +289,18 @@ IMAPMailbox::MessageNumberToUID(int32 messageNumber) status_t -IMAPMailbox::DeleteMessage(int32 messageNumber) +IMAPMailbox::DeleteMessage(int32 uid, bool permanently) { - int32 index = messageNumber - 1; - if (index < 0 || index >= (int32)fMessageList.size()) - return B_BAD_VALUE; - status_t status = fStorage.DeleteMessage(MessageNumberToUID(messageNumber)); - fMessageList.erase(fMessageList.begin() + index); - return status; + int32 flags = fStorage.GetFlags(uid); + flags |= kDeleted; + status_t status = SetFlags(UIDToMessageNumber(uid), flags); + + if (!permanently || status != B_OK) + return status; + + // delete permanently by invoking expunge + ExpungeCommmand expungeCommand(*this); + return ProcessCommand(&expungeCommand); } diff --git a/src/add-ons/mail_daemon/inbound_protocols/imap/imap_lib/IMAPMailbox.h b/src/add-ons/mail_daemon/inbound_protocols/imap/imap_lib/IMAPMailbox.h index e249dc9fb7..ecf0a4caf9 100644 --- a/src/add-ons/mail_daemon/inbound_protocols/imap/imap_lib/IMAPMailbox.h +++ b/src/add-ons/mail_daemon/inbound_protocols/imap/imap_lib/IMAPMailbox.h @@ -72,7 +72,7 @@ public: int32 UIDToMessageNumber(int32 uid); int32 MessageNumberToUID(int32 messageNumber); - status_t DeleteMessage(int32 messageNumber); + status_t DeleteMessage(int32 uid, bool permanently); private: void _InstallUnsolicitedHandler(bool install);