From 78e0108c39aa23ce3d981b221f87592942d4ce08 Mon Sep 17 00:00:00 2001 From: Clemens Zeidler Date: Mon, 28 Feb 2011 08:27:23 +0000 Subject: [PATCH] google expunge all deleted flagged messages automatically but some server keep them and EXPUNGE has to be executed explicit. Add the infrastructure for expunge but don't use it for now. The problem is that with each expunge all messages are deleted and calling expunge each time when a mail is deleted would delete messages in a virtual trash folder on other clients. Have to think about how to deal with it first. So it might be that you delete a message and the message will be downloaded again when you sync the next time (but the message is flagged as deleted). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@40736 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../imap/IMAPInboundProtocol.cpp | 14 ++++----- .../imap/imap_lib/IMAPHandler.cpp | 31 ++++++++++++++++++- .../imap/imap_lib/IMAPHandler.h | 12 +++++++ .../imap/imap_lib/IMAPMailbox.cpp | 18 ++++++----- .../imap/imap_lib/IMAPMailbox.h | 2 +- 5 files changed, 60 insertions(+), 17 deletions(-) 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);