From 146357b547221dd608cdb63feadd8b6bbc5988da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Tue, 30 Oct 2012 22:45:54 +0100 Subject: [PATCH] Completed transition to the new mail API; ie. it compiles. * Completely untested yet. Unlikely to work yet. --- headers/os/add-ons/mail_daemon/MailFilter.h | 6 +- headers/os/add-ons/mail_daemon/MailProtocol.h | 30 +- headers/os/mail/MailDaemon.h | 61 ++-- headers/private/mail/MailPrivate.h | 22 +- .../outbound_protocols/smtp/smtp.cpp | 41 ++- .../outbound_protocols/smtp/smtp.h | 8 +- src/kits/mail/MailDaemon.cpp | 99 +++--- src/kits/mail/MailMessage.cpp | 2 + src/kits/mail/MailProtocol.cpp | 20 +- src/kits/mail/c_mail_api.cpp | 29 +- src/servers/mail/DefaultNotifier.cpp | 3 + src/servers/mail/DeskbarView.cpp | 63 ++-- src/servers/mail/MailDaemon.cpp | 290 +++++++++++------- src/servers/mail/MailDaemon.h | 35 +-- 14 files changed, 408 insertions(+), 301 deletions(-) diff --git a/headers/os/add-ons/mail_daemon/MailFilter.h b/headers/os/add-ons/mail_daemon/MailFilter.h index 69b9f73d0a..00c66eacdb 100644 --- a/headers/os/add-ons/mail_daemon/MailFilter.h +++ b/headers/os/add-ons/mail_daemon/MailFilter.h @@ -2,8 +2,8 @@ * Copyright 2011-2012, Haiku, Inc. All Rights Reserved. * Distributed under the terms of the MIT License. */ -#ifndef MAIL_FILTER_H -#define MAIL_FILTER_H +#ifndef _MAIL_FILTER_H +#define _MAIL_FILTER_H #include "MailProtocol.h" @@ -47,4 +47,4 @@ extern "C" BMailFilter* instantiate_filter(BMailProtocol& protocol, extern "C" BString filter_name(); -#endif // MAIL_FILTER_H +#endif // _MAIL_FILTER_H diff --git a/headers/os/add-ons/mail_daemon/MailProtocol.h b/headers/os/add-ons/mail_daemon/MailProtocol.h index 85f99655a5..299ca8e8a0 100644 --- a/headers/os/add-ons/mail_daemon/MailProtocol.h +++ b/headers/os/add-ons/mail_daemon/MailProtocol.h @@ -1,16 +1,16 @@ -/* Protocol - the base class for protocol filters - * +/* + * Copyright 2004-2012, Haiku, Inc. All Rights Reserved. * Copyright 2001 Dr. Zoidberg Enterprises. All rights reserved. * Copyright 2011 Clemens Zeidler. All rights reserved. -*/ -#ifndef MAIL_PROTOCOL_H -#define MAIL_PROTOCOL_H + * + * Distributed under the terms of the MIT License. + */ +#ifndef _MAIL_PROTOCOL_H +#define _MAIL_PROTOCOL_H #include -#include -#include #include #include #include @@ -22,6 +22,7 @@ class BMailFilter; +class BView; class BMailNotifier { @@ -41,7 +42,7 @@ public: }; -class BMailProtocol : BLooper { +class BMailProtocol : public BLooper { public: BMailProtocol( const BMailAccountSettings& settings); @@ -74,6 +75,12 @@ public: void ShowError(const char* error); void ShowMessage(const char* message); +#if __GNUC__ > 2 + // Unhide virtual base methods + using BHandler::AddFilter; + using BHandler::RemoveFilter; +#endif + protected: void SetTotalItems(uint32 items); void SetTotalItemsSize(uint64 size); @@ -136,9 +143,8 @@ public: virtual void MessageReceived(BMessage* message); - virtual status_t SendMessages( - const std::vector& mails, - size_t totalBytes) = 0; + virtual status_t SendMessages(const BMessage& message, + off_t totalBytes) = 0; }; @@ -151,4 +157,4 @@ extern "C" _EXPORT BView* instantiate_protocol_config_panel( BMailAccountSettings& settings); -#endif // MAIL_PROTOCOL_H +#endif // _MAIL_PROTOCOL_H diff --git a/headers/os/mail/MailDaemon.h b/headers/os/mail/MailDaemon.h index 4cef96ac20..66e8ccb02e 100644 --- a/headers/os/mail/MailDaemon.h +++ b/headers/os/mail/MailDaemon.h @@ -1,45 +1,40 @@ -#ifndef MAIL_DAEMON_H -#define MAIL_DAEMON_H -/* Daemon - talking to the mail daemon - * - * Copyright 2001 Dr. Zoidberg Enterprises. All rights reserved. - * Copyright 2011, Clemens Zeidler -*/ +/* + * Copyright 2012, Haiku Inc. All Rights Reserved. + * Distributed under the terms of the MIT License. + */ +#ifndef _MAIL_DAEMON_H +#define _MAIL_DAEMON_H #include - - -#define B_MAIL_DAEMON_SIGNATURE "application/x-vnd.Be-POST" - -const uint32 kMsgCheckAndSend = 'mbth'; -const uint32 kMsgCheckMessage = 'mnow'; -const uint32 kMsgSendMessages = 'msnd'; -const uint32 kMsgSettingsUpdated = 'mrrs'; -const uint32 kMsgAccountsChanged = 'macc'; -const uint32 kMsgSetStatusWindowMode = 'shst'; -const uint32 kMsgCountNewMessages = 'mnum'; -const uint32 kMsgMarkMessageAsRead = 'mmar'; -const uint32 kMsgFetchBody = 'mfeb'; -const uint32 kMsgBodyFetched = 'mbfe'; - - -class BMessenger; +#include class BMailDaemon { public: - //! accountID = -1 means check all accounts - static status_t CheckMail(int32 accountID = -1); - static status_t CheckAndSendQueuedMail(int32 accountID = -1); - static status_t SendQueuedMail(); - static int32 CountNewMessages( + BMailDaemon(); + virtual ~BMailDaemon(); + + bool IsRunning(); + + status_t CheckMail(int32 accountID = -1); + status_t CheckAndSendQueuedMail(int32 accountID = -1); + + status_t SendQueuedMail(); + + int32 CountNewMessages( bool waitForFetchCompletion = false); - static status_t MarkAsRead(int32 account, const entry_ref& ref, + status_t MarkAsRead(int32 account, const entry_ref& ref, read_flags flag = B_READ); - static status_t FetchBody(const entry_ref& ref, + status_t FetchBody(const entry_ref& ref, BMessenger* listener = NULL); - static status_t Quit(); + + status_t Quit(); + status_t Launch(); + +private: + BMessenger fDaemon; }; -#endif // MAIL_DAEMON_H + +#endif // _MAIL_DAEMON_H diff --git a/headers/private/mail/MailPrivate.h b/headers/private/mail/MailPrivate.h index 74b8afaeba..03bb2bc653 100644 --- a/headers/private/mail/MailPrivate.h +++ b/headers/private/mail/MailPrivate.h @@ -1,5 +1,5 @@ /* - * Copyright 2011, Haiku Inc. All Rights Reserved. + * Copyright 2011-2012, Haiku Inc. All Rights Reserved. * Distributed under the terms of the MIT License. */ #ifndef MAIL_PRIVATE_H @@ -12,13 +12,33 @@ namespace BPrivate { + +#define B_MAIL_DAEMON_SIGNATURE "application/x-vnd.Be-POST" + + +// mail daemon & protocol message constants +const uint32 kMsgCheckAndSend = 'mbth'; +const uint32 kMsgCheckMessage = 'mnow'; +const uint32 kMsgSendMessages = 'msnd'; +const uint32 kMsgSettingsUpdated = 'mrrs'; +const uint32 kMsgAccountsChanged = 'macc'; +const uint32 kMsgSetStatusWindowMode = 'shst'; +const uint32 kMsgCountNewMessages = 'mnum'; +const uint32 kMsgMarkMessageAsRead = 'mmar'; +const uint32 kMsgFetchBody = 'mfeb'; +const uint32 kMsgBodyFetched = 'mbfe'; +const uint32 kMsgSyncMessages = '&SyM'; + + BPath default_mail_directory(); BPath default_mail_in_directory(); BPath default_mail_out_directory(); + status_t WriteMessageFile(const BMessage& archive, const BPath& path, const char* name); + } // namespace BPrivate diff --git a/src/add-ons/mail_daemon/outbound_protocols/smtp/smtp.cpp b/src/add-ons/mail_daemon/outbound_protocols/smtp/smtp.cpp index ba331fee12..3713246c7f 100644 --- a/src/add-ons/mail_daemon/outbound_protocols/smtp/smtp.cpp +++ b/src/add-ons/mail_daemon/outbound_protocols/smtp/smtp.cpp @@ -329,29 +329,33 @@ SMTPProtocol::Disconnect() //! Process EMail to be sent status_t -SMTPProtocol::SendMessages(const std::vector& mails, - size_t totalBytes) +SMTPProtocol::SendMessages(const BMessage& message, off_t totalBytes) { - status_t status = Connect(); + type_code type; + int32 count; + status_t status = message.GetInfo("ref", &type, &count); if (status != B_OK) return status; - for (unsigned int i = 0; i < mails.size(); i++) { - status = _SendMessage(mails[i]); + SetTotalItems(count); + SetTotalItemsSize(totalBytes); + status = Connect(); + if (status != B_OK) + return status; + + entry_ref ref; + for (int32 i = 0; message.FindRef("ref", i++, &ref) == B_OK;) { + status = _SendMessage(ref); if (status != B_OK) { BString error; - error << "An error occurred while sending the message " << - mails[i].name << ":\n" << fLog; + error << "An error occurred while sending the message " + << ref.name << ":\n" << fLog; ShowError(error.String()); ResetProgress(); break; } - off_t size = 0; - const entry_ref& ref = mails[i]; - BNode(&ref).GetSize(&size); - ReportProgress(size, 1); } Disconnect(); @@ -521,10 +525,10 @@ SMTPProtocol::Open(const char *address, int port, bool esmtp) status_t -SMTPProtocol::_SendMessage(const entry_ref& mail) +SMTPProtocol::_SendMessage(const entry_ref& ref) { // open read write to be able to manipulate in MessageReadyToSend hook - BFile file(&mail, B_READ_WRITE); + BFile file(&ref, B_READ_WRITE); status_t status = file.InitCheck(); if (status != B_OK) return status; @@ -534,7 +538,7 @@ SMTPProtocol::_SendMessage(const entry_ref& mail) const char *from = header.FindString("MAIL:from"); const char *to = header.FindString("MAIL:recipients"); - if (!to) + if (to == NULL) to = header.FindString("MAIL:to"); if (to == NULL || from == NULL) { @@ -542,11 +546,16 @@ SMTPProtocol::_SendMessage(const entry_ref& mail) return B_ERROR; } - NotifyMessageReadyToSend(mail, &file); + NotifyMessageReadyToSend(ref, &file); status = Send(to, from, &file); if (status != B_OK) return status; - NotifyMessageSent(mail, &file); + NotifyMessageSent(ref, &file); + + off_t size = 0; + file.GetSize(&size); + ReportProgress(size, 1); + return B_OK; } diff --git a/src/add-ons/mail_daemon/outbound_protocols/smtp/smtp.h b/src/add-ons/mail_daemon/outbound_protocols/smtp/smtp.h index ba6ae90a96..243511d64c 100644 --- a/src/add-ons/mail_daemon/outbound_protocols/smtp/smtp.h +++ b/src/add-ons/mail_daemon/outbound_protocols/smtp/smtp.h @@ -24,13 +24,13 @@ class SMTPProtocol : public BOutboundMailProtocol { public: SMTPProtocol(BMailAccountSettings& settings); - ~SMTPProtocol(); + virtual ~SMTPProtocol(); status_t Connect(); void Disconnect(); - status_t SendMessages(const std::vector& - mails, size_t totalBytes); + virtual status_t SendMessages(const BMessage& message, + off_t totalBytes); status_t Open(const char *server, int port, bool esmtp); void Close(); @@ -42,7 +42,7 @@ public: status_t SendCommand(const char *cmd); private: - status_t _SendMessage(const entry_ref& mail); + status_t _SendMessage(const entry_ref& ref); status_t _POP3Authentication(); int fSocket; diff --git a/src/kits/mail/MailDaemon.cpp b/src/kits/mail/MailDaemon.cpp index 6e73b9f1d2..21722feb26 100644 --- a/src/kits/mail/MailDaemon.cpp +++ b/src/kits/mail/MailDaemon.cpp @@ -1,71 +1,92 @@ -/* Daemon - talking to the mail daemon -** -** Copyright 2001-2002 Dr. Zoidberg Enterprises. All rights reserved. -*/ +/* + * Copyright 2004-2012, Haiku Inc. All Rights Reserved. + * Copyright 2001-2002 Dr. Zoidberg Enterprises. All rights reserved. + * + * Distributed under the terms of the MIT License. + */ -#include -#include -#include - #include -#include -#include +#include +#include +#include +#include +#include + +#include + + +using namespace BPrivate; + + +BMailDaemon::BMailDaemon() + : + fDaemon(B_MAIL_DAEMON_SIGNATURE) +{ +} + + +BMailDaemon::~BMailDaemon() +{ +} + + +bool +BMailDaemon::IsRunning() +{ + return fDaemon.IsValid(); +} status_t BMailDaemon::CheckMail(int32 accountID) { - BMessenger daemon(B_MAIL_DAEMON_SIGNATURE); - if (!daemon.IsValid()) + if (!fDaemon.IsValid()) return B_MAIL_NO_DAEMON; BMessage message(kMsgCheckMessage); message.AddInt32("account", accountID); - return daemon.SendMessage(&message); + return fDaemon.SendMessage(&message); } status_t BMailDaemon::CheckAndSendQueuedMail(int32 accountID) { - BMessenger daemon(B_MAIL_DAEMON_SIGNATURE); - if (!daemon.IsValid()) + if (!fDaemon.IsValid()) return B_MAIL_NO_DAEMON; BMessage message(kMsgCheckAndSend); message.AddInt32("account", accountID); - return daemon.SendMessage(&message); + return fDaemon.SendMessage(&message); } status_t BMailDaemon::SendQueuedMail() { - BMessenger daemon(B_MAIL_DAEMON_SIGNATURE); - if (!daemon.IsValid()) + if (!fDaemon.IsValid()) return B_MAIL_NO_DAEMON; - - return daemon.SendMessage(kMsgSendMessages); + + return fDaemon.SendMessage(kMsgSendMessages); } int32 -BMailDaemon::CountNewMessages(bool wait_for_fetch_completion) +BMailDaemon::CountNewMessages(bool waitForFetchCompletion) { - BMessenger daemon(B_MAIL_DAEMON_SIGNATURE); - if (!daemon.IsValid()) + if (!fDaemon.IsValid()) return B_MAIL_NO_DAEMON; BMessage reply; BMessage first(kMsgCountNewMessages); - if (wait_for_fetch_completion) + if (waitForFetchCompletion) first.AddBool("wait_for_fetch_done",true); - - daemon.SendMessage(&first, &reply); - + + fDaemon.SendMessage(&first, &reply); + return reply.FindInt32("num_new_messages"); } @@ -73,8 +94,7 @@ BMailDaemon::CountNewMessages(bool wait_for_fetch_completion) status_t BMailDaemon::MarkAsRead(int32 account, const entry_ref& ref, read_flags flag) { - BMessenger daemon(B_MAIL_DAEMON_SIGNATURE); - if (!daemon.IsValid()) + if (!fDaemon.IsValid()) return B_MAIL_NO_DAEMON; BMessage message(kMsgMarkMessageAsRead); @@ -82,15 +102,14 @@ BMailDaemon::MarkAsRead(int32 account, const entry_ref& ref, read_flags flag) message.AddRef("ref", &ref); message.AddInt32("read", flag); - return daemon.SendMessage(&message); + return fDaemon.SendMessage(&message); } status_t BMailDaemon::FetchBody(const entry_ref& ref, BMessenger* listener) { - BMessenger daemon(B_MAIL_DAEMON_SIGNATURE); - if (!daemon.IsValid()) + if (!fDaemon.IsValid()) return B_MAIL_NO_DAEMON; BMessage message(kMsgFetchBody); @@ -99,16 +118,22 @@ BMailDaemon::FetchBody(const entry_ref& ref, BMessenger* listener) message.AddMessenger("target", *listener); BMessage reply; - return daemon.SendMessage(&message, &reply); + return fDaemon.SendMessage(&message, &reply); } status_t BMailDaemon::Quit() { - BMessenger daemon(B_MAIL_DAEMON_SIGNATURE); - if (!daemon.IsValid()) + if (!fDaemon.IsValid()) return B_MAIL_NO_DAEMON; - - return daemon.SendMessage(B_QUIT_REQUESTED); + + return fDaemon.SendMessage(B_QUIT_REQUESTED); +} + + +status_t +BMailDaemon::Launch() +{ + return be_roster->Launch(B_MAIL_DAEMON_SIGNATURE); } diff --git a/src/kits/mail/MailMessage.cpp b/src/kits/mail/MailMessage.cpp index caf25d147b..bd90fbb0ff 100644 --- a/src/kits/mail/MailMessage.cpp +++ b/src/kits/mail/MailMessage.cpp @@ -35,6 +35,8 @@ #include #include +#include + //-------Change the following!---------------------- #define mime_boundary "----------Zoidberg-BeMail-temp--------" diff --git a/src/kits/mail/MailProtocol.cpp b/src/kits/mail/MailProtocol.cpp index d78e911a44..4229c5d5d3 100644 --- a/src/kits/mail/MailProtocol.cpp +++ b/src/kits/mail/MailProtocol.cpp @@ -31,14 +31,14 @@ #include #include +#include #include "HaikuMailFormatFilter.h" -using std::map; +using namespace BPrivate; -const uint32 kMsgSyncMessages = '&SyM'; const uint32 kMsgDeleteMessage = '&DeM'; const uint32 kMsgAppendMessage = '&ApM'; @@ -67,7 +67,7 @@ BMailProtocol::~BMailProtocol() for (int i = 0; i < fFilterList.CountItems(); i++) delete fFilterList.ItemAt(i); - map::iterator it = fFilterImages.begin(); + std::map::iterator it = fFilterImages.begin(); for (; it != fFilterImages.end(); it++) unload_add_on(it->second); } @@ -316,7 +316,7 @@ BMailFilter* BMailProtocol::_LoadFilter(BMailAddOnSettings* filterSettings) { const entry_ref& ref = filterSettings->AddOnRef(); - map::iterator it = fFilterImages.find(ref); + std::map::iterator it = fFilterImages.find(ref); image_id image; if (it != fFilterImages.end()) image = it->second; @@ -461,18 +461,8 @@ BOutboundMailProtocol::MessageReceived(BMessage* message) { switch (message->what) { case kMsgSendMessage: - { - std::vector mails; - for (int32 i = 0; ;i++) { - entry_ref ref; - if (message->FindRef("ref", i, &ref) != B_OK) - break; - mails.push_back(ref); - } - size_t size = message->FindInt32("size"); - SendMessages(mails, size); + SendMessages(*message, message->FindInt64("bytes")); break; - } default: BMailProtocol::MessageReceived(message); diff --git a/src/kits/mail/c_mail_api.cpp b/src/kits/mail/c_mail_api.cpp index 8b619c2887..59facf910f 100644 --- a/src/kits/mail/c_mail_api.cpp +++ b/src/kits/mail/c_mail_api.cpp @@ -1,8 +1,13 @@ -/* C-mail API - compatibility function (stubs) for the old mail kit -** -** Copyright 2001 Dr. Zoidberg Enterprises. All rights reserved. -** Copyright 2011 Clemens Zeidler. All rights reserved. -*/ +/* + * Copyright 2004-2012, Haiku, Inc. All rights reserved. + * Copyright 2001, Dr. Zoidberg Enterprises. All rights reserved. + * Copyright 2011, Clemens Zeidler. All rights reserved. + * + * Distributed under the terms of the MIT License. + */ + + +//! C-mail API - compatibility function (stubs) for the old mail kit #include @@ -22,14 +27,14 @@ _EXPORT status_t -check_for_mail(int32 * incoming_count) +check_for_mail(int32* _incomingCount) { - status_t err = BMailDaemon::CheckMail(true); - if (err < B_OK) - return err; + status_t status = BMailDaemon().CheckMail(); + if (status != B_OK) + return status; - if (incoming_count != NULL) - *incoming_count = BMailDaemon::CountNewMessages(true); + if (_incomingCount != NULL) + *_incomingCount = BMailDaemon().CountNewMessages(true); return B_OK; } @@ -38,7 +43,7 @@ check_for_mail(int32 * incoming_count) _EXPORT status_t send_queued_mail(void) { - return BMailDaemon::SendQueuedMail(); + return BMailDaemon().SendQueuedMail(); } diff --git a/src/servers/mail/DefaultNotifier.cpp b/src/servers/mail/DefaultNotifier.cpp index 4418de208e..018472f2a7 100644 --- a/src/servers/mail/DefaultNotifier.cpp +++ b/src/servers/mail/DefaultNotifier.cpp @@ -1,6 +1,7 @@ /* * Copyright 2011-2012, Haiku, Inc. All rights reserved. * Copyright 2011, Clemens Zeidler + * * Distributed under the terms of the MIT License. */ @@ -12,6 +13,8 @@ #include #include +#include + #undef B_TRANSLATION_CONTEXT #define B_TRANSLATION_CONTEXT "Notifier" diff --git a/src/servers/mail/DeskbarView.cpp b/src/servers/mail/DeskbarView.cpp index 33117a95cd..60266ef800 100644 --- a/src/servers/mail/DeskbarView.cpp +++ b/src/servers/mail/DeskbarView.cpp @@ -1,9 +1,14 @@ -/* DeskbarView - mail_daemon's deskbar menu and view - * +/* + * Copyright 2004-2012, Haiku Inc. All Rights Reserved. * Copyright 2001 Dr. Zoidberg Enterprises. All rights reserved. + * + * Distributed under the terms of the MIT License. */ +//! mail_daemon's deskbar menu and view + + #include "DeskbarView.h" #include @@ -39,6 +44,8 @@ #include #include +#include + #include "DeskbarViewIcons.h" @@ -209,7 +216,8 @@ status_t DeskbarView::Archive(BMessage *data,bool deep) const } -void DeskbarView::Draw(BRect /*updateRect*/) +void +DeskbarView::Draw(BRect /*updateRect*/) { if (fBitmaps[fStatus] == NULL) return; @@ -223,18 +231,17 @@ void DeskbarView::Draw(BRect /*updateRect*/) void DeskbarView::MessageReceived(BMessage* message) { - switch(message->what) - { + switch (message->what) { case MD_CHECK_SEND_NOW: // also happens in DeskbarView::MouseUp() with // B_TERTIARY_MOUSE_BUTTON pressed - BMailDaemon::CheckAndSendQueuedMail(); + BMailDaemon().CheckAndSendQueuedMail(); break; case MD_CHECK_FOR_MAILS: - BMailDaemon::CheckMail(message->FindInt32("account")); + BMailDaemon().CheckMail(message->FindInt32("account")); break; case MD_SEND_MAILS: - BMailDaemon::SendQueuedMail(); + BMailDaemon().SendQueuedMail(); break; case MD_OPEN_NEW: @@ -282,12 +289,12 @@ DeskbarView::MessageReceived(BMessage* message) fNewMessages--; break; } - fStatus = (fNewMessages > 0) ? kStatusNewMail : kStatusNoMail; + fStatus = fNewMessages > 0 ? kStatusNewMail : kStatusNoMail; Invalidate(); break; } case B_QUIT_REQUESTED: - BMailDaemon::Quit(); + BMailDaemon().Quit(); break; // open received files in the standard mail application @@ -364,38 +371,34 @@ DeskbarView::Pulse() void DeskbarView::MouseUp(BPoint pos) { - if (fLastButtons & B_PRIMARY_MOUSE_BUTTON) { - if (OpenWithTracker(B_USER_SETTINGS_DIRECTORY, "Mail/mailbox") - != B_OK) { - entry_ref ref; - _GetNewQueryRef(ref); + if ((fLastButtons & B_PRIMARY_MOUSE_BUTTON) !=0 + && OpenWithTracker(B_USER_SETTINGS_DIRECTORY, "Mail/mailbox") != B_OK) { + entry_ref ref; + _GetNewQueryRef(ref); - BMessenger trackerMessenger(kTrackerSignature); - BMessage message(B_REFS_RECEIVED); - message.AddRef("refs", &ref); + BMessenger trackerMessenger(kTrackerSignature); + BMessage message(B_REFS_RECEIVED); + message.AddRef("refs", &ref); - trackerMessenger.SendMessage(&message); - } + trackerMessenger.SendMessage(&message); } - if (fLastButtons & B_TERTIARY_MOUSE_BUTTON) - BMailDaemon::CheckMail(); + if ((fLastButtons & B_TERTIARY_MOUSE_BUTTON) != 0) + BMailDaemon().CheckMail(); } void DeskbarView::MouseDown(BPoint pos) { - Looper()->CurrentMessage()->FindInt32("buttons",&fLastButtons); + Looper()->CurrentMessage()->FindInt32("buttons", &fLastButtons); - if (fLastButtons & B_SECONDARY_MOUSE_BUTTON) { + if ((fLastButtons & B_SECONDARY_MOUSE_BUTTON) != 0) { ConvertToScreen(&pos); BPopUpMenu* menu = _BuildMenu(); - if (menu) { - menu->Go(pos, true, true, BRect(pos.x - 2, pos.y - 2, - pos.x + 2, pos.y + 2), true); - } + menu->Go(pos, true, true, BRect(pos.x - 2, pos.y - 2, + pos.x + 2, pos.y + 2), true); } } @@ -563,7 +566,7 @@ DeskbarView::_BuildMenu() } BMailAccounts accounts; - if (modifiers() & B_SHIFT_KEY) { + if ((modifiers() & B_SHIFT_KEY) != 0) { BMenu *accountMenu = new BMenu(B_TRANSLATE("Check for mails only")); BFont font; menu->GetFont(&font); @@ -611,7 +614,7 @@ DeskbarView::_BuildMenu() for (int32 i = menu->CountItems(); i-- > 0;) { item = menu->ItemAt(i); - if (item && (msg = item->Message()) != NULL) { + if (item != NULL && (msg = item->Message()) != NULL) { if (msg->what == B_REFS_RECEIVED) item->SetTarget(tracker); else diff --git a/src/servers/mail/MailDaemon.cpp b/src/servers/mail/MailDaemon.cpp index 16a7448502..f60a8c8204 100644 --- a/src/servers/mail/MailDaemon.cpp +++ b/src/servers/mail/MailDaemon.cpp @@ -33,23 +33,75 @@ #include #include +#include + #undef B_TRANSLATION_CONTEXT #define B_TRANSLATION_CONTEXT "MailDaemon" -using std::map; -using std::vector; - - struct send_mails_info { send_mails_info() { - totalSize = 0; + bytes = 0; } - vector files; - off_t totalSize; + BMessage files; + off_t bytes; +}; + + +class InboundMessenger : public BMessenger { +public: + InboundMessenger(BInboundMailProtocol* protocol) + : + BMessenger(protocol) + { + } + + status_t FetchBody(const entry_ref& ref, BMessenger* replyTo) + { + BMessage message(kMsgFetchBody); + message.AddRef("ref", &ref); + if (replyTo != NULL) + message.AddMessenger("target", *replyTo); + + return SendMessage(&message); + } + + status_t MarkAsRead(const entry_ref& ref, read_flags flag) + { + BMessage message(kMsgMarkMessageAsRead); + message.AddRef("ref", &ref); + message.AddInt32("read", flag); + + return SendMessage(&message); + } + + status_t SynchronizeMessages() + { + BMessage message(kMsgSyncMessages); + return SendMessage(&message); + } +}; + + +class OutboundMessenger : public BMessenger { +public: + OutboundMessenger(BOutboundMailProtocol* protocol) + : + BMessenger(protocol) + { + } + + status_t SendMessages(const BMessage& files, off_t totalBytes) + { + BMessage message(kMsgSendMessages); + message.Append(files); + message.AddInt64("bytes", totalBytes); + + return SendMessage(&message); + } }; @@ -103,7 +155,20 @@ addAttribute(BMessage& msg, const char* name, const char* publicName, } -// #pragma mark - +// #pragma mark - + + +account_protocols::account_protocols() + : + inboundImage(-1), + inboundProtocol(NULL), + outboundImage(-1), + outboundProtocol(NULL) +{ +} + + +// #pragma mark - MailDaemonApp::MailDaemonApp() @@ -129,12 +194,13 @@ MailDaemonApp::~MailDaemonApp() for (int32 i = 0; i < fQueries.CountItems(); i++) delete fQueries.ItemAt(i); + while (!fAccounts.empty()) { + _RemoveAccount(fAccounts.begin()->second); + fAccounts.erase(fAccounts.begin()); + } + delete fLEDAnimation; delete fNotification; - - AccountMap::const_iterator it = fAccounts.begin(); - for (; it != fAccounts.end(); it++) - _RemoveAccount(it); } @@ -218,15 +284,16 @@ MailDaemonApp::RefsReceived(BMessage* message) sizeof(account)) < 0) continue; - InboundProtocolThread* protocolThread = _FindInboundProtocol(account); - if (protocolThread == NULL) + BInboundMailProtocol* protocol = _InboundProtocol(account); + if (protocol == NULL) continue; BMessenger target; - BMessenger* messenger = ⌖ + BMessenger* replyTo = ⌖ if (message->FindMessenger("target", &target) != B_OK) - messenger = NULL; - protocolThread->FetchBody(ref, messenger); + replyTo = NULL; + + InboundMessenger(protocol).FetchBody(ref, replyTo); } } @@ -276,11 +343,10 @@ MailDaemonApp::MessageReceived(BMessage* msg) if (msg->FindRef("ref", &ref) != B_OK) break; read_flags read = (read_flags)msg->FindInt32("read"); - AccountMap::iterator it = fAccounts.find(account); - if (it == fAccounts.end()) - break; - InboundProtocolThread* inboundThread = it->second.inboundThread; - inboundThread->MarkMessageAsRead(ref, read); + + BInboundMailProtocol* protocol = _InboundProtocol(account); + if (protocol != NULL) + InboundMessenger(protocol).MarkAsRead(ref, read); break; } @@ -447,18 +513,20 @@ MailDaemonApp::GetNewMessages(BMessage* msg) { int32 account = -1; if (msg->FindInt32("account", &account) == B_OK && account >= 0) { - InboundProtocolThread* protocol = _FindInboundProtocol(account); + // Check the single requested account + BInboundMailProtocol* protocol = _InboundProtocol(account); if (protocol != NULL) - protocol->SyncMessages(); + InboundMessenger(protocol).SynchronizeMessages(); return; } - // else check all accounts - AccountMap::const_iterator it = fAccounts.begin(); - for (; it != fAccounts.end(); it++) { - InboundProtocolThread* protocol = it->second.inboundThread; + // Check all accounts + + AccountMap::const_iterator iterator = fAccounts.begin(); + for (; iterator != fAccounts.end(); iterator++) { + BInboundMailProtocol* protocol = iterator->second.inboundProtocol; if (protocol != NULL) - protocol->SyncMessages(); + InboundMessenger(protocol).SynchronizeMessages(); } } @@ -469,7 +537,7 @@ MailDaemonApp::SendPendingMessages(BMessage* msg) BVolumeRoster roster; BVolume volume; - map messages; + std::map messages; int32 account = -1; if (msg->FindInt32("account", &account) != B_OK) @@ -507,55 +575,34 @@ MailDaemonApp::SendPendingMessages(BMessage* msg) if (!_IsPending(node)) continue; - int32 messageAccount; if (node.ReadAttr(B_MAIL_ATTR_ACCOUNT_ID, B_INT32_TYPE, 0, - &messageAccount, sizeof(int32)) < 0) - messageAccount = -1; + &account, sizeof(int32)) < 0) + account = -1; - off_t size = 0; - node.GetSize(&size); - entry_ref ref; - entry.GetRef(&ref); - - messages[messageAccount].files.push_back(ref); - messages[messageAccount].totalSize += size; + _AddMessage(messages[account], entry, node); } } } else { + // Send the requested message only const char* path; if (msg->FindString("message_path", &path) != B_OK) return; - off_t size = 0; - if (BNode(path).GetSize(&size) != B_OK) - return; BEntry entry(path); - entry_ref ref; - entry.GetRef(&ref); - - messages[account].files.push_back(ref); - messages[account].totalSize += size; + _AddMessage(messages[account], entry, BNode(&entry)); } - map::iterator iter = messages.begin(); - for (; iter != messages.end(); iter++) { - OutboundProtocolThread* protocolThread = _FindOutboundProtocol( - iter->first); - if (!protocolThread) + std::map::iterator iterator = messages.begin(); + for (; iterator != messages.end(); iterator++) { + BOutboundMailProtocol* protocol = _OutboundProtocol(iterator->first); + if (protocol == NULL) continue; - send_mails_info& info = iter->second; - if (info.files.size() == 0) + send_mails_info& info = iterator->second; + if (info.bytes == 0) continue; - MailProtocol* protocol = protocolThread->Protocol(); - - protocolThread->Lock(); - protocol->SetTotalItems(info.files.size()); - protocol->SetTotalItemsSize(info.totalSize); - protocolThread->Unlock(); - - protocolThread->SendMessages(iter->second.files, info.totalSize); + OutboundMessenger(protocol).SendMessages(info.files, info.bytes); } } @@ -630,48 +677,38 @@ void MailDaemonApp::_InitAccount(BMailAccountSettings& settings) { account_protocols account; + // inbound if (settings.IsInboundEnabled()) { account.inboundProtocol = _CreateInboundProtocol(settings, account.inboundImage); - } else { - account.inboundProtocol = NULL; } - if (account.inboundProtocol) { + if (account.inboundProtocol != NULL) { DefaultNotifier* notifier = new DefaultNotifier(settings.Name(), true, fErrorLogWindow, fNotifyMode); account.inboundProtocol->SetMailNotifier(notifier); - - account.inboundThread = new InboundProtocolThread( - account.inboundProtocol); - account.inboundThread->Run(); + account.inboundProtocol->Run(); } // outbound if (settings.IsOutboundEnabled()) { account.outboundProtocol = _CreateOutboundProtocol(settings, account.outboundImage); - } else { - account.outboundProtocol = NULL; } - if (account.outboundProtocol) { + if (account.outboundProtocol != NULL) { DefaultNotifier* notifier = new DefaultNotifier(settings.Name(), false, fErrorLogWindow, fNotifyMode); account.outboundProtocol->SetMailNotifier(notifier); - - account.outboundThread = new OutboundProtocolThread( - account.outboundProtocol); - account.outboundThread->Run(); + account.outboundProtocol->Run(); } printf("account name %s, id %i, in %p, out %p\n", settings.Name(), (int)settings.AccountID(), account.inboundProtocol, account.outboundProtocol); - if (!account.inboundProtocol && !account.outboundProtocol) - return; - fAccounts[settings.AccountID()] = account; -} + if (account.inboundProtocol != NULL || account.outboundProtocol != NULL) + fAccounts[settings.AccountID()] = account; +} void @@ -688,9 +725,12 @@ MailDaemonApp::_ReloadAccounts(BMessage* message) for (int i = 0; i < countFound; i++) { int32 account = message->FindInt32("account", i); - AccountMap::const_iterator it = fAccounts.find(account); - if (it != fAccounts.end()) - _RemoveAccount(it); + AccountMap::iterator found = fAccounts.find(account); + if (found != fAccounts.end()) { + _RemoveAccount(found->second); + fAccounts.erase(found); + } + BMailAccountSettings* settings = accounts.AccountByID(account); if (settings != NULL) _InitAccount(*settings); @@ -699,89 +739,88 @@ MailDaemonApp::_ReloadAccounts(BMessage* message) void -MailDaemonApp::_RemoveAccount(AccountMap::const_iterator it) +MailDaemonApp::_RemoveAccount(const account_protocols& account) { - BMessage reply; - if (it->second.inboundThread) { - it->second.inboundThread->SetStopNow(); - BMessenger(it->second.inboundThread).SendMessage(B_QUIT_REQUESTED, - &reply); + if (account.inboundProtocol != NULL) { + account.inboundProtocol->Lock(); + account.inboundProtocol->Quit(); + + unload_add_on(account.inboundImage); } - if (it->second.outboundThread) { - it->second.outboundThread->SetStopNow(); - BMessenger(it->second.outboundThread).SendMessage(B_QUIT_REQUESTED, - &reply); + + if (account.outboundProtocol != NULL) { + account.outboundProtocol->Lock(); + account.outboundProtocol->Quit(); + + unload_add_on(account.outboundImage); } - delete it->second.inboundProtocol; - delete it->second.outboundProtocol; - unload_add_on(it->second.inboundImage); - unload_add_on(it->second.outboundImage); - fAccounts.erase(it->first); } -InboundProtocol* +BInboundMailProtocol* MailDaemonApp::_CreateInboundProtocol(BMailAccountSettings& settings, image_id& image) { - const entry_ref& entry = settings.InboundPath(); - InboundProtocol* (*instantiate_protocol)(BMailAccountSettings*); + const entry_ref& entry = settings.InboundAddOnRef(); + BInboundMailProtocol* (*instantiateProtocol)(BMailAccountSettings*); BPath path(&entry); image = load_add_on(path.Path()); if (image < 0) return NULL; + if (get_image_symbol(image, "instantiate_inbound_protocol", - B_SYMBOL_TYPE_TEXT, (void**)&instantiate_protocol) != B_OK) { + B_SYMBOL_TYPE_TEXT, (void**)&instantiateProtocol) != B_OK) { unload_add_on(image); image = -1; return NULL; } - return (*instantiate_protocol)(&settings); + return instantiateProtocol(&settings); } -OutboundProtocol* +BOutboundMailProtocol* MailDaemonApp::_CreateOutboundProtocol(BMailAccountSettings& settings, image_id& image) { - const entry_ref& entry = settings.OutboundPath(); - OutboundProtocol* (*instantiate_protocol)(BMailAccountSettings*); + const entry_ref& entry = settings.OutboundAddOnRef(); + BOutboundMailProtocol* (*instantiateProtocol)(BMailAccountSettings*); BPath path(&entry); image = load_add_on(path.Path()); if (image < 0) return NULL; + if (get_image_symbol(image, "instantiate_outbound_protocol", - B_SYMBOL_TYPE_TEXT, (void**)&instantiate_protocol) != B_OK) { + B_SYMBOL_TYPE_TEXT, (void**)&instantiateProtocol) != B_OK) { unload_add_on(image); image = -1; return NULL; } - return (*instantiate_protocol)(&settings); + return instantiateProtocol(&settings); } -InboundProtocolThread* -MailDaemonApp::_FindInboundProtocol(int32 account) +BInboundMailProtocol* +MailDaemonApp::_InboundProtocol(int32 account) { - AccountMap::iterator it = fAccounts.find(account); - if (it == fAccounts.end()) + AccountMap::iterator found = fAccounts.find(account); + if (found == fAccounts.end()) return NULL; - return it->second.inboundThread; + return found->second.inboundProtocol; } -OutboundProtocolThread* -MailDaemonApp::_FindOutboundProtocol(int32 account) +BOutboundMailProtocol* +MailDaemonApp::_OutboundProtocol(int32 account) { if (account < 0) account = BMailSettings().DefaultOutboundAccount(); - AccountMap::iterator it = fAccounts.find(account); - if (it == fAccounts.end()) + AccountMap::iterator found = fAccounts.find(account); + if (found == fAccounts.end()) return NULL; - return it->second.outboundThread; + return found->second.outboundProtocol; } @@ -803,6 +842,19 @@ MailDaemonApp::_UpdateAutoCheck(bigtime_t interval) } +void +MailDaemonApp::_AddMessage(send_mails_info& info, const BEntry& entry, + const BNode& node) +{ + entry_ref ref; + off_t size; + if (node.GetSize(&size) == B_OK && entry.GetRef(&ref) == B_OK) { + info.files.AddRef("ref", &ref); + info.bytes += size; + } +} + + /*! Work-around for a broken index that contains out-of-date information. */ /*static*/ bool diff --git a/src/servers/mail/MailDaemon.h b/src/servers/mail/MailDaemon.h index a740cd571d..d5111edbed 100644 --- a/src/servers/mail/MailDaemon.h +++ b/src/servers/mail/MailDaemon.h @@ -1,5 +1,5 @@ /* - * Copyright 2007-2011, Haiku, Inc. All rights reserved. + * Copyright 2007-2012, Haiku, Inc. All rights reserved. * Copyright 2001-2002 Dr. Zoidberg Enterprises. All rights reserved. * Copyright 2011, Clemens Zeidler * Distributed under the terms of the MIT License. @@ -21,27 +21,20 @@ #include #include "LEDAnimation.h" -#include "Notifier.h" +#include "DefaultNotifier.h" class BNotification; +struct send_mails_info; struct account_protocols { - account_protocols() { - inboundImage = -1; - inboundThread = NULL; - inboundProtocol = NULL; - outboundImage = -1; - outboundThread = NULL; - outboundProtocol = NULL; - } + account_protocols(); + image_id inboundImage; - InboundProtocolThread* inboundThread; - InboundProtocol* inboundProtocol; + BInboundMailProtocol* inboundProtocol; image_id outboundImage; - OutboundProtocolThread* outboundThread; - OutboundProtocol* outboundProtocol; + BOutboundMailProtocol* outboundProtocol; }; @@ -72,20 +65,24 @@ private: void _InitAccounts(); void _InitAccount(BMailAccountSettings& settings); void _ReloadAccounts(BMessage* message); - void _RemoveAccount(AccountMap::const_iterator it); + void _RemoveAccount( + const account_protocols& account); - InboundProtocol* _CreateInboundProtocol( + BInboundMailProtocol* _CreateInboundProtocol( BMailAccountSettings& settings, image_id& image); - OutboundProtocol* _CreateOutboundProtocol( + BOutboundMailProtocol* _CreateOutboundProtocol( BMailAccountSettings& settings, image_id& image); - InboundProtocolThread* _FindInboundProtocol(int32 account); - OutboundProtocolThread* _FindOutboundProtocol(int32 account); + BInboundMailProtocol* _InboundProtocol(int32 account); + BOutboundMailProtocol* _OutboundProtocol(int32 account); void _UpdateAutoCheck(bigtime_t interval); + void _AddMessage(send_mails_info& info, + const BEntry& entry, const BNode& node); + static bool _IsPending(BNode& node); static bool _IsEntryInTrash(BEntry& entry);