bool PersistentAccount::DeleteObject(boost::shared_ptr<Account> pAccount) { __int64 iID = pAccount->GetID(); assert(iID); if (iID <= 0) return false; // Delete messages connected to this account. DeleteMessages(pAccount); // Force delete the inbox as well. DeleteMessages above does not delete it. boost::shared_ptr<IMAPFolder> inbox = pAccount->GetFolders()->GetFolderByName("Inbox"); if (inbox) PersistentIMAPFolder::DeleteObject(inbox, true); pAccount->GetRules()->DeleteAll(); // Delete fetch accounts connected to this account. PersistentFetchAccount::DeleteByAccountID(iID); // Delete references from groups... PersistentGroupMember::DeleteByAccount(iID); PersistentACLPermission::DeleteOwnedByAccount(iID); SQLCommand deleteCommand("delete from hm_accounts where accountid = @ACCOUNTID"); deleteCommand.AddParameter("@ACCOUNTID", iID); bool bRet = Application::Instance()->GetDBManager()->Execute(deleteCommand); // Delete folder from data directory String sAccountFolder = IniFileSettings::Instance()->GetDataDirectory() + "\\" + StringParser::ExtractDomain(pAccount->GetAddress()) + "\\" + StringParser::ExtractAddress(pAccount->GetAddress()); FileUtilities::DeleteDirectory(sAccountFolder); // Refresh caches. Cache<Account, PersistentAccount>::Instance()->RemoveObject(pAccount); return bRet; }
IMAPResult IMAPCommandEXPUNGE::ExecuteCommand(std::shared_ptr<IMAPConnection> pConnection, std::shared_ptr<IMAPCommandArgument> pArgument) { if (!pConnection->IsAuthenticated()) return IMAPResult(IMAPResult::ResultNo, "Authenticate first"); if (pConnection->GetCurrentFolderReadOnly()) { return IMAPResult(IMAPResult::ResultNo, "Expunge command on read-only folder."); } // Iterate through mail boxes and delete messages marked for deletion. std::shared_ptr<IMAPFolder> pCurFolder = pConnection->GetCurrentFolder(); if (!pCurFolder) return IMAPResult(IMAPResult::ResultNo, "No folder selected."); if (!pConnection->CheckPermission(pCurFolder, ACLPermission::PermissionExpunge)) return IMAPResult(IMAPResult::ResultBad, "ACL: Expunge permission denied (Required for EXPUNGE command)."); std::vector<__int64> expunged_messages_uid; std::vector<__int64> expunged_messages_index; std::function<bool(int, std::shared_ptr<Message>)> filter = [&expunged_messages_index, &expunged_messages_uid](int index, std::shared_ptr<Message> message) { if (message->GetFlagDeleted()) { expunged_messages_index.push_back(index); expunged_messages_uid.push_back(message->GetID()); return true; } return false; }; auto messages = MessagesContainer::Instance()->GetMessages(pCurFolder->GetAccountID(), pCurFolder->GetID()); messages->DeleteMessages(filter); auto iterExpunged = expunged_messages_index.begin(); String sResponse; while (iterExpunged != expunged_messages_index.end()) { String sTemp; sTemp.Format(_T("* %d EXPUNGE\r\n"), (*iterExpunged)); sResponse += sTemp; iterExpunged++; } pConnection->SendAsciiData(sResponse); if (!expunged_messages_uid.empty()) { auto recent_messages = pConnection->GetRecentMessages(); for (__int64 messageUid : expunged_messages_uid) { auto recent_messages_it = recent_messages.find(messageUid); if (recent_messages_it != recent_messages.end()) recent_messages.erase(recent_messages_it); } // Messages have been expunged // Notify the mailbox notifier that the mailbox contents have changed. std::shared_ptr<ChangeNotification> pNotification = std::shared_ptr<ChangeNotification>(new ChangeNotification(pCurFolder->GetAccountID(), pCurFolder->GetID(), ChangeNotification::NotificationMessageDeleted, expunged_messages_index)); Application::Instance()->GetNotificationServer()->SendNotification(pConnection->GetNotificationClient(), pNotification); } // We're done. sResponse = pArgument->Tag() + " OK EXPUNGE Completed\r\n"; pConnection->SendAsciiData(sResponse); return IMAPResult(); }