Completed transition to the new mail API; ie. it compiles.

* Completely untested yet. Unlikely to work yet.
This commit is contained in:
Axel Dörfler
2015-01-06 15:21:55 +01:00
parent 383b34adac
commit 146357b547
14 changed files with 408 additions and 301 deletions
+3 -3
View File
@@ -2,8 +2,8 @@
* Copyright 2011-2012, Haiku, Inc. All Rights Reserved. * Copyright 2011-2012, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
*/ */
#ifndef MAIL_FILTER_H #ifndef _MAIL_FILTER_H
#define MAIL_FILTER_H #define _MAIL_FILTER_H
#include "MailProtocol.h" #include "MailProtocol.h"
@@ -47,4 +47,4 @@ extern "C" BMailFilter* instantiate_filter(BMailProtocol& protocol,
extern "C" BString filter_name(); extern "C" BString filter_name();
#endif // MAIL_FILTER_H #endif // _MAIL_FILTER_H
+18 -12
View File
@@ -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 2001 Dr. Zoidberg Enterprises. All rights reserved.
* Copyright 2011 Clemens Zeidler. All rights reserved. * Copyright 2011 Clemens Zeidler. All rights reserved.
*/ *
#ifndef MAIL_PROTOCOL_H * Distributed under the terms of the MIT License.
#define MAIL_PROTOCOL_H */
#ifndef _MAIL_PROTOCOL_H
#define _MAIL_PROTOCOL_H
#include <map> #include <map>
#include <vector>
#include <Handler.h>
#include <Looper.h> #include <Looper.h>
#include <OS.h> #include <OS.h>
#include <ObjectList.h> #include <ObjectList.h>
@@ -22,6 +22,7 @@
class BMailFilter; class BMailFilter;
class BView;
class BMailNotifier { class BMailNotifier {
@@ -41,7 +42,7 @@ public:
}; };
class BMailProtocol : BLooper { class BMailProtocol : public BLooper {
public: public:
BMailProtocol( BMailProtocol(
const BMailAccountSettings& settings); const BMailAccountSettings& settings);
@@ -74,6 +75,12 @@ public:
void ShowError(const char* error); void ShowError(const char* error);
void ShowMessage(const char* message); void ShowMessage(const char* message);
#if __GNUC__ > 2
// Unhide virtual base methods
using BHandler::AddFilter;
using BHandler::RemoveFilter;
#endif
protected: protected:
void SetTotalItems(uint32 items); void SetTotalItems(uint32 items);
void SetTotalItemsSize(uint64 size); void SetTotalItemsSize(uint64 size);
@@ -136,9 +143,8 @@ public:
virtual void MessageReceived(BMessage* message); virtual void MessageReceived(BMessage* message);
virtual status_t SendMessages( virtual status_t SendMessages(const BMessage& message,
const std::vector<entry_ref>& mails, off_t totalBytes) = 0;
size_t totalBytes) = 0;
}; };
@@ -151,4 +157,4 @@ extern "C" _EXPORT BView* instantiate_protocol_config_panel(
BMailAccountSettings& settings); BMailAccountSettings& settings);
#endif // MAIL_PROTOCOL_H #endif // _MAIL_PROTOCOL_H
+28 -33
View File
@@ -1,45 +1,40 @@
#ifndef MAIL_DAEMON_H /*
#define MAIL_DAEMON_H * Copyright 2012, Haiku Inc. All Rights Reserved.
/* Daemon - talking to the mail daemon * Distributed under the terms of the MIT License.
* */
* Copyright 2001 Dr. Zoidberg Enterprises. All rights reserved. #ifndef _MAIL_DAEMON_H
* Copyright 2011, Clemens Zeidler <[email protected]> #define _MAIL_DAEMON_H
*/
#include <E-mail.h> #include <E-mail.h>
#include <Messenger.h>
#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;
class BMailDaemon { class BMailDaemon {
public: public:
//! accountID = -1 means check all accounts BMailDaemon();
static status_t CheckMail(int32 accountID = -1); virtual ~BMailDaemon();
static status_t CheckAndSendQueuedMail(int32 accountID = -1);
static status_t SendQueuedMail(); bool IsRunning();
static int32 CountNewMessages(
status_t CheckMail(int32 accountID = -1);
status_t CheckAndSendQueuedMail(int32 accountID = -1);
status_t SendQueuedMail();
int32 CountNewMessages(
bool waitForFetchCompletion = false); 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); read_flags flag = B_READ);
static status_t FetchBody(const entry_ref& ref, status_t FetchBody(const entry_ref& ref,
BMessenger* listener = NULL); BMessenger* listener = NULL);
static status_t Quit();
status_t Quit();
status_t Launch();
private:
BMessenger fDaemon;
}; };
#endif // MAIL_DAEMON_H
#endif // _MAIL_DAEMON_H
+21 -1
View File
@@ -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. * Distributed under the terms of the MIT License.
*/ */
#ifndef MAIL_PRIVATE_H #ifndef MAIL_PRIVATE_H
@@ -12,13 +12,33 @@
namespace BPrivate { 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_directory();
BPath default_mail_in_directory(); BPath default_mail_in_directory();
BPath default_mail_out_directory(); BPath default_mail_out_directory();
status_t WriteMessageFile(const BMessage& archive, const BPath& path, status_t WriteMessageFile(const BMessage& archive, const BPath& path,
const char* name); const char* name);
} // namespace BPrivate } // namespace BPrivate
@@ -329,29 +329,33 @@ SMTPProtocol::Disconnect()
//! Process EMail to be sent //! Process EMail to be sent
status_t status_t
SMTPProtocol::SendMessages(const std::vector<entry_ref>& mails, SMTPProtocol::SendMessages(const BMessage& message, off_t totalBytes)
size_t totalBytes)
{ {
status_t status = Connect(); type_code type;
int32 count;
status_t status = message.GetInfo("ref", &type, &count);
if (status != B_OK) if (status != B_OK)
return status; return status;
for (unsigned int i = 0; i < mails.size(); i++) { SetTotalItems(count);
status = _SendMessage(mails[i]); 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) { if (status != B_OK) {
BString error; BString error;
error << "An error occurred while sending the message " << error << "An error occurred while sending the message "
mails[i].name << ":\n" << fLog; << ref.name << ":\n" << fLog;
ShowError(error.String()); ShowError(error.String());
ResetProgress(); ResetProgress();
break; break;
} }
off_t size = 0;
const entry_ref& ref = mails[i];
BNode(&ref).GetSize(&size);
ReportProgress(size, 1);
} }
Disconnect(); Disconnect();
@@ -521,10 +525,10 @@ SMTPProtocol::Open(const char *address, int port, bool esmtp)
status_t 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 // 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(); status_t status = file.InitCheck();
if (status != B_OK) if (status != B_OK)
return status; return status;
@@ -534,7 +538,7 @@ SMTPProtocol::_SendMessage(const entry_ref& mail)
const char *from = header.FindString("MAIL:from"); const char *from = header.FindString("MAIL:from");
const char *to = header.FindString("MAIL:recipients"); const char *to = header.FindString("MAIL:recipients");
if (!to) if (to == NULL)
to = header.FindString("MAIL:to"); to = header.FindString("MAIL:to");
if (to == NULL || from == NULL) { if (to == NULL || from == NULL) {
@@ -542,11 +546,16 @@ SMTPProtocol::_SendMessage(const entry_ref& mail)
return B_ERROR; return B_ERROR;
} }
NotifyMessageReadyToSend(mail, &file); NotifyMessageReadyToSend(ref, &file);
status = Send(to, from, &file); status = Send(to, from, &file);
if (status != B_OK) if (status != B_OK)
return status; return status;
NotifyMessageSent(mail, &file); NotifyMessageSent(ref, &file);
off_t size = 0;
file.GetSize(&size);
ReportProgress(size, 1);
return B_OK; return B_OK;
} }
@@ -24,13 +24,13 @@
class SMTPProtocol : public BOutboundMailProtocol { class SMTPProtocol : public BOutboundMailProtocol {
public: public:
SMTPProtocol(BMailAccountSettings& settings); SMTPProtocol(BMailAccountSettings& settings);
~SMTPProtocol(); virtual ~SMTPProtocol();
status_t Connect(); status_t Connect();
void Disconnect(); void Disconnect();
status_t SendMessages(const std::vector<entry_ref>& virtual status_t SendMessages(const BMessage& message,
mails, size_t totalBytes); off_t totalBytes);
status_t Open(const char *server, int port, bool esmtp); status_t Open(const char *server, int port, bool esmtp);
void Close(); void Close();
@@ -42,7 +42,7 @@ public:
status_t SendCommand(const char *cmd); status_t SendCommand(const char *cmd);
private: private:
status_t _SendMessage(const entry_ref& mail); status_t _SendMessage(const entry_ref& ref);
status_t _POP3Authentication(); status_t _POP3Authentication();
int fSocket; int fSocket;
+62 -37
View File
@@ -1,71 +1,92 @@
/* Daemon - talking to the mail daemon /*
** * Copyright 2004-2012, Haiku Inc. All Rights Reserved.
** Copyright 2001-2002 Dr. Zoidberg Enterprises. All rights reserved. * Copyright 2001-2002 Dr. Zoidberg Enterprises. All rights reserved.
*/ *
* Distributed under the terms of the MIT License.
*/
#include <Messenger.h>
#include <Message.h>
#include <List.h>
#include <MailDaemon.h> #include <MailDaemon.h>
#include <MailSettings.h>
#include <string.h> #include <List.h>
#include <MailSettings.h>
#include <Messenger.h>
#include <Message.h>
#include <Roster.h>
#include <MailPrivate.h>
using namespace BPrivate;
BMailDaemon::BMailDaemon()
:
fDaemon(B_MAIL_DAEMON_SIGNATURE)
{
}
BMailDaemon::~BMailDaemon()
{
}
bool
BMailDaemon::IsRunning()
{
return fDaemon.IsValid();
}
status_t status_t
BMailDaemon::CheckMail(int32 accountID) BMailDaemon::CheckMail(int32 accountID)
{ {
BMessenger daemon(B_MAIL_DAEMON_SIGNATURE); if (!fDaemon.IsValid())
if (!daemon.IsValid())
return B_MAIL_NO_DAEMON; return B_MAIL_NO_DAEMON;
BMessage message(kMsgCheckMessage); BMessage message(kMsgCheckMessage);
message.AddInt32("account", accountID); message.AddInt32("account", accountID);
return daemon.SendMessage(&message); return fDaemon.SendMessage(&message);
} }
status_t status_t
BMailDaemon::CheckAndSendQueuedMail(int32 accountID) BMailDaemon::CheckAndSendQueuedMail(int32 accountID)
{ {
BMessenger daemon(B_MAIL_DAEMON_SIGNATURE); if (!fDaemon.IsValid())
if (!daemon.IsValid())
return B_MAIL_NO_DAEMON; return B_MAIL_NO_DAEMON;
BMessage message(kMsgCheckAndSend); BMessage message(kMsgCheckAndSend);
message.AddInt32("account", accountID); message.AddInt32("account", accountID);
return daemon.SendMessage(&message); return fDaemon.SendMessage(&message);
} }
status_t status_t
BMailDaemon::SendQueuedMail() BMailDaemon::SendQueuedMail()
{ {
BMessenger daemon(B_MAIL_DAEMON_SIGNATURE); if (!fDaemon.IsValid())
if (!daemon.IsValid())
return B_MAIL_NO_DAEMON; return B_MAIL_NO_DAEMON;
return daemon.SendMessage(kMsgSendMessages); return fDaemon.SendMessage(kMsgSendMessages);
} }
int32 int32
BMailDaemon::CountNewMessages(bool wait_for_fetch_completion) BMailDaemon::CountNewMessages(bool waitForFetchCompletion)
{ {
BMessenger daemon(B_MAIL_DAEMON_SIGNATURE); if (!fDaemon.IsValid())
if (!daemon.IsValid())
return B_MAIL_NO_DAEMON; return B_MAIL_NO_DAEMON;
BMessage reply; BMessage reply;
BMessage first(kMsgCountNewMessages); BMessage first(kMsgCountNewMessages);
if (wait_for_fetch_completion) if (waitForFetchCompletion)
first.AddBool("wait_for_fetch_done",true); first.AddBool("wait_for_fetch_done",true);
daemon.SendMessage(&first, &reply); fDaemon.SendMessage(&first, &reply);
return reply.FindInt32("num_new_messages"); return reply.FindInt32("num_new_messages");
} }
@@ -73,8 +94,7 @@ BMailDaemon::CountNewMessages(bool wait_for_fetch_completion)
status_t status_t
BMailDaemon::MarkAsRead(int32 account, const entry_ref& ref, read_flags flag) BMailDaemon::MarkAsRead(int32 account, const entry_ref& ref, read_flags flag)
{ {
BMessenger daemon(B_MAIL_DAEMON_SIGNATURE); if (!fDaemon.IsValid())
if (!daemon.IsValid())
return B_MAIL_NO_DAEMON; return B_MAIL_NO_DAEMON;
BMessage message(kMsgMarkMessageAsRead); BMessage message(kMsgMarkMessageAsRead);
@@ -82,15 +102,14 @@ BMailDaemon::MarkAsRead(int32 account, const entry_ref& ref, read_flags flag)
message.AddRef("ref", &ref); message.AddRef("ref", &ref);
message.AddInt32("read", flag); message.AddInt32("read", flag);
return daemon.SendMessage(&message); return fDaemon.SendMessage(&message);
} }
status_t status_t
BMailDaemon::FetchBody(const entry_ref& ref, BMessenger* listener) BMailDaemon::FetchBody(const entry_ref& ref, BMessenger* listener)
{ {
BMessenger daemon(B_MAIL_DAEMON_SIGNATURE); if (!fDaemon.IsValid())
if (!daemon.IsValid())
return B_MAIL_NO_DAEMON; return B_MAIL_NO_DAEMON;
BMessage message(kMsgFetchBody); BMessage message(kMsgFetchBody);
@@ -99,16 +118,22 @@ BMailDaemon::FetchBody(const entry_ref& ref, BMessenger* listener)
message.AddMessenger("target", *listener); message.AddMessenger("target", *listener);
BMessage reply; BMessage reply;
return daemon.SendMessage(&message, &reply); return fDaemon.SendMessage(&message, &reply);
} }
status_t status_t
BMailDaemon::Quit() BMailDaemon::Quit()
{ {
BMessenger daemon(B_MAIL_DAEMON_SIGNATURE); if (!fDaemon.IsValid())
if (!daemon.IsValid())
return B_MAIL_NO_DAEMON; 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);
} }
+2
View File
@@ -35,6 +35,8 @@
#include <mail_util.h> #include <mail_util.h>
#include <StringList.h> #include <StringList.h>
#include <MailPrivate.h>
//-------Change the following!---------------------- //-------Change the following!----------------------
#define mime_boundary "----------Zoidberg-BeMail-temp--------" #define mime_boundary "----------Zoidberg-BeMail-temp--------"
+5 -15
View File
@@ -31,14 +31,14 @@
#include <MailSettings.h> #include <MailSettings.h>
#include <mail_util.h> #include <mail_util.h>
#include <MailPrivate.h>
#include "HaikuMailFormatFilter.h" #include "HaikuMailFormatFilter.h"
using std::map; using namespace BPrivate;
const uint32 kMsgSyncMessages = '&SyM';
const uint32 kMsgDeleteMessage = '&DeM'; const uint32 kMsgDeleteMessage = '&DeM';
const uint32 kMsgAppendMessage = '&ApM'; const uint32 kMsgAppendMessage = '&ApM';
@@ -67,7 +67,7 @@ BMailProtocol::~BMailProtocol()
for (int i = 0; i < fFilterList.CountItems(); i++) for (int i = 0; i < fFilterList.CountItems(); i++)
delete fFilterList.ItemAt(i); delete fFilterList.ItemAt(i);
map<entry_ref, image_id>::iterator it = fFilterImages.begin(); std::map<entry_ref, image_id>::iterator it = fFilterImages.begin();
for (; it != fFilterImages.end(); it++) for (; it != fFilterImages.end(); it++)
unload_add_on(it->second); unload_add_on(it->second);
} }
@@ -316,7 +316,7 @@ BMailFilter*
BMailProtocol::_LoadFilter(BMailAddOnSettings* filterSettings) BMailProtocol::_LoadFilter(BMailAddOnSettings* filterSettings)
{ {
const entry_ref& ref = filterSettings->AddOnRef(); const entry_ref& ref = filterSettings->AddOnRef();
map<entry_ref, image_id>::iterator it = fFilterImages.find(ref); std::map<entry_ref, image_id>::iterator it = fFilterImages.find(ref);
image_id image; image_id image;
if (it != fFilterImages.end()) if (it != fFilterImages.end())
image = it->second; image = it->second;
@@ -461,18 +461,8 @@ BOutboundMailProtocol::MessageReceived(BMessage* message)
{ {
switch (message->what) { switch (message->what) {
case kMsgSendMessage: case kMsgSendMessage:
{ SendMessages(*message, message->FindInt64("bytes"));
std::vector<entry_ref> 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);
break; break;
}
default: default:
BMailProtocol::MessageReceived(message); BMailProtocol::MessageReceived(message);
+17 -12
View File
@@ -1,8 +1,13 @@
/* C-mail API - compatibility function (stubs) for the old mail kit /*
** * Copyright 2004-2012, Haiku, Inc. All rights reserved.
** Copyright 2001 Dr. Zoidberg Enterprises. All rights reserved. * Copyright 2001, Dr. Zoidberg Enterprises. All rights reserved.
** Copyright 2011 Clemens Zeidler. 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 <stdlib.h> #include <stdlib.h>
@@ -22,14 +27,14 @@
_EXPORT status_t _EXPORT status_t
check_for_mail(int32 * incoming_count) check_for_mail(int32* _incomingCount)
{ {
status_t err = BMailDaemon::CheckMail(true); status_t status = BMailDaemon().CheckMail();
if (err < B_OK) if (status != B_OK)
return err; return status;
if (incoming_count != NULL) if (_incomingCount != NULL)
*incoming_count = BMailDaemon::CountNewMessages(true); *_incomingCount = BMailDaemon().CountNewMessages(true);
return B_OK; return B_OK;
} }
@@ -38,7 +43,7 @@ check_for_mail(int32 * incoming_count)
_EXPORT status_t _EXPORT status_t
send_queued_mail(void) send_queued_mail(void)
{ {
return BMailDaemon::SendQueuedMail(); return BMailDaemon().SendQueuedMail();
} }
+3
View File
@@ -1,6 +1,7 @@
/* /*
* Copyright 2011-2012, Haiku, Inc. All rights reserved. * Copyright 2011-2012, Haiku, Inc. All rights reserved.
* Copyright 2011, Clemens Zeidler <haiku@clemens-zeidler.de> * Copyright 2011, Clemens Zeidler <haiku@clemens-zeidler.de>
*
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
*/ */
@@ -12,6 +13,8 @@
#include <MailDaemon.h> #include <MailDaemon.h>
#include <Roster.h> #include <Roster.h>
#include <MailPrivate.h>
#undef B_TRANSLATION_CONTEXT #undef B_TRANSLATION_CONTEXT
#define B_TRANSLATION_CONTEXT "Notifier" #define B_TRANSLATION_CONTEXT "Notifier"
+33 -30
View File
@@ -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. * 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 "DeskbarView.h"
#include <stdio.h> #include <stdio.h>
@@ -39,6 +44,8 @@
#include <MailDaemon.h> #include <MailDaemon.h>
#include <MailSettings.h> #include <MailSettings.h>
#include <MailPrivate.h>
#include "DeskbarViewIcons.h" #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) if (fBitmaps[fStatus] == NULL)
return; return;
@@ -223,18 +231,17 @@ void DeskbarView::Draw(BRect /*updateRect*/)
void void
DeskbarView::MessageReceived(BMessage* message) DeskbarView::MessageReceived(BMessage* message)
{ {
switch(message->what) switch (message->what) {
{
case MD_CHECK_SEND_NOW: case MD_CHECK_SEND_NOW:
// also happens in DeskbarView::MouseUp() with // also happens in DeskbarView::MouseUp() with
// B_TERTIARY_MOUSE_BUTTON pressed // B_TERTIARY_MOUSE_BUTTON pressed
BMailDaemon::CheckAndSendQueuedMail(); BMailDaemon().CheckAndSendQueuedMail();
break; break;
case MD_CHECK_FOR_MAILS: case MD_CHECK_FOR_MAILS:
BMailDaemon::CheckMail(message->FindInt32("account")); BMailDaemon().CheckMail(message->FindInt32("account"));
break; break;
case MD_SEND_MAILS: case MD_SEND_MAILS:
BMailDaemon::SendQueuedMail(); BMailDaemon().SendQueuedMail();
break; break;
case MD_OPEN_NEW: case MD_OPEN_NEW:
@@ -282,12 +289,12 @@ DeskbarView::MessageReceived(BMessage* message)
fNewMessages--; fNewMessages--;
break; break;
} }
fStatus = (fNewMessages > 0) ? kStatusNewMail : kStatusNoMail; fStatus = fNewMessages > 0 ? kStatusNewMail : kStatusNoMail;
Invalidate(); Invalidate();
break; break;
} }
case B_QUIT_REQUESTED: case B_QUIT_REQUESTED:
BMailDaemon::Quit(); BMailDaemon().Quit();
break; break;
// open received files in the standard mail application // open received files in the standard mail application
@@ -364,38 +371,34 @@ DeskbarView::Pulse()
void void
DeskbarView::MouseUp(BPoint pos) DeskbarView::MouseUp(BPoint pos)
{ {
if (fLastButtons & B_PRIMARY_MOUSE_BUTTON) { if ((fLastButtons & B_PRIMARY_MOUSE_BUTTON) !=0
if (OpenWithTracker(B_USER_SETTINGS_DIRECTORY, "Mail/mailbox") && OpenWithTracker(B_USER_SETTINGS_DIRECTORY, "Mail/mailbox") != B_OK) {
!= B_OK) { entry_ref ref;
entry_ref ref; _GetNewQueryRef(ref);
_GetNewQueryRef(ref);
BMessenger trackerMessenger(kTrackerSignature); BMessenger trackerMessenger(kTrackerSignature);
BMessage message(B_REFS_RECEIVED); BMessage message(B_REFS_RECEIVED);
message.AddRef("refs", &ref); message.AddRef("refs", &ref);
trackerMessenger.SendMessage(&message); trackerMessenger.SendMessage(&message);
}
} }
if (fLastButtons & B_TERTIARY_MOUSE_BUTTON) if ((fLastButtons & B_TERTIARY_MOUSE_BUTTON) != 0)
BMailDaemon::CheckMail(); BMailDaemon().CheckMail();
} }
void void
DeskbarView::MouseDown(BPoint pos) 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); ConvertToScreen(&pos);
BPopUpMenu* menu = _BuildMenu(); BPopUpMenu* menu = _BuildMenu();
if (menu) { menu->Go(pos, true, true, BRect(pos.x - 2, pos.y - 2,
menu->Go(pos, true, true, BRect(pos.x - 2, pos.y - 2, pos.x + 2, pos.y + 2), true);
pos.x + 2, pos.y + 2), true);
}
} }
} }
@@ -563,7 +566,7 @@ DeskbarView::_BuildMenu()
} }
BMailAccounts accounts; BMailAccounts accounts;
if (modifiers() & B_SHIFT_KEY) { if ((modifiers() & B_SHIFT_KEY) != 0) {
BMenu *accountMenu = new BMenu(B_TRANSLATE("Check for mails only")); BMenu *accountMenu = new BMenu(B_TRANSLATE("Check for mails only"));
BFont font; BFont font;
menu->GetFont(&font); menu->GetFont(&font);
@@ -611,7 +614,7 @@ DeskbarView::_BuildMenu()
for (int32 i = menu->CountItems(); i-- > 0;) { for (int32 i = menu->CountItems(); i-- > 0;) {
item = menu->ItemAt(i); item = menu->ItemAt(i);
if (item && (msg = item->Message()) != NULL) { if (item != NULL && (msg = item->Message()) != NULL) {
if (msg->what == B_REFS_RECEIVED) if (msg->what == B_REFS_RECEIVED)
item->SetTarget(tracker); item->SetTarget(tracker);
else else
+171 -119
View File
@@ -33,23 +33,75 @@
#include <MailMessage.h> #include <MailMessage.h>
#include <MailSettings.h> #include <MailSettings.h>
#include <MailPrivate.h>
#undef B_TRANSLATION_CONTEXT #undef B_TRANSLATION_CONTEXT
#define B_TRANSLATION_CONTEXT "MailDaemon" #define B_TRANSLATION_CONTEXT "MailDaemon"
using std::map;
using std::vector;
struct send_mails_info { struct send_mails_info {
send_mails_info() send_mails_info()
{ {
totalSize = 0; bytes = 0;
} }
vector<entry_ref> files; BMessage files;
off_t totalSize; 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() MailDaemonApp::MailDaemonApp()
@@ -129,12 +194,13 @@ MailDaemonApp::~MailDaemonApp()
for (int32 i = 0; i < fQueries.CountItems(); i++) for (int32 i = 0; i < fQueries.CountItems(); i++)
delete fQueries.ItemAt(i); delete fQueries.ItemAt(i);
while (!fAccounts.empty()) {
_RemoveAccount(fAccounts.begin()->second);
fAccounts.erase(fAccounts.begin());
}
delete fLEDAnimation; delete fLEDAnimation;
delete fNotification; 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) sizeof(account)) < 0)
continue; continue;
InboundProtocolThread* protocolThread = _FindInboundProtocol(account); BInboundMailProtocol* protocol = _InboundProtocol(account);
if (protocolThread == NULL) if (protocol == NULL)
continue; continue;
BMessenger target; BMessenger target;
BMessenger* messenger = &target; BMessenger* replyTo = &target;
if (message->FindMessenger("target", &target) != B_OK) if (message->FindMessenger("target", &target) != B_OK)
messenger = NULL; replyTo = NULL;
protocolThread->FetchBody(ref, messenger);
InboundMessenger(protocol).FetchBody(ref, replyTo);
} }
} }
@@ -276,11 +343,10 @@ MailDaemonApp::MessageReceived(BMessage* msg)
if (msg->FindRef("ref", &ref) != B_OK) if (msg->FindRef("ref", &ref) != B_OK)
break; break;
read_flags read = (read_flags)msg->FindInt32("read"); read_flags read = (read_flags)msg->FindInt32("read");
AccountMap::iterator it = fAccounts.find(account);
if (it == fAccounts.end()) BInboundMailProtocol* protocol = _InboundProtocol(account);
break; if (protocol != NULL)
InboundProtocolThread* inboundThread = it->second.inboundThread; InboundMessenger(protocol).MarkAsRead(ref, read);
inboundThread->MarkMessageAsRead(ref, read);
break; break;
} }
@@ -447,18 +513,20 @@ MailDaemonApp::GetNewMessages(BMessage* msg)
{ {
int32 account = -1; int32 account = -1;
if (msg->FindInt32("account", &account) == B_OK && account >= 0) { 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) if (protocol != NULL)
protocol->SyncMessages(); InboundMessenger(protocol).SynchronizeMessages();
return; return;
} }
// else check all accounts // Check all accounts
AccountMap::const_iterator it = fAccounts.begin();
for (; it != fAccounts.end(); it++) { AccountMap::const_iterator iterator = fAccounts.begin();
InboundProtocolThread* protocol = it->second.inboundThread; for (; iterator != fAccounts.end(); iterator++) {
BInboundMailProtocol* protocol = iterator->second.inboundProtocol;
if (protocol != NULL) if (protocol != NULL)
protocol->SyncMessages(); InboundMessenger(protocol).SynchronizeMessages();
} }
} }
@@ -469,7 +537,7 @@ MailDaemonApp::SendPendingMessages(BMessage* msg)
BVolumeRoster roster; BVolumeRoster roster;
BVolume volume; BVolume volume;
map<int32, send_mails_info> messages; std::map<int32, send_mails_info> messages;
int32 account = -1; int32 account = -1;
if (msg->FindInt32("account", &account) != B_OK) if (msg->FindInt32("account", &account) != B_OK)
@@ -507,55 +575,34 @@ MailDaemonApp::SendPendingMessages(BMessage* msg)
if (!_IsPending(node)) if (!_IsPending(node))
continue; continue;
int32 messageAccount;
if (node.ReadAttr(B_MAIL_ATTR_ACCOUNT_ID, B_INT32_TYPE, 0, if (node.ReadAttr(B_MAIL_ATTR_ACCOUNT_ID, B_INT32_TYPE, 0,
&messageAccount, sizeof(int32)) < 0) &account, sizeof(int32)) < 0)
messageAccount = -1; account = -1;
off_t size = 0; _AddMessage(messages[account], entry, node);
node.GetSize(&size);
entry_ref ref;
entry.GetRef(&ref);
messages[messageAccount].files.push_back(ref);
messages[messageAccount].totalSize += size;
} }
} }
} else { } else {
// Send the requested message only
const char* path; const char* path;
if (msg->FindString("message_path", &path) != B_OK) if (msg->FindString("message_path", &path) != B_OK)
return; return;
off_t size = 0;
if (BNode(path).GetSize(&size) != B_OK)
return;
BEntry entry(path); BEntry entry(path);
entry_ref ref; _AddMessage(messages[account], entry, BNode(&entry));
entry.GetRef(&ref);
messages[account].files.push_back(ref);
messages[account].totalSize += size;
} }
map<int32, send_mails_info>::iterator iter = messages.begin(); std::map<int32, send_mails_info>::iterator iterator = messages.begin();
for (; iter != messages.end(); iter++) { for (; iterator != messages.end(); iterator++) {
OutboundProtocolThread* protocolThread = _FindOutboundProtocol( BOutboundMailProtocol* protocol = _OutboundProtocol(iterator->first);
iter->first); if (protocol == NULL)
if (!protocolThread)
continue; continue;
send_mails_info& info = iter->second; send_mails_info& info = iterator->second;
if (info.files.size() == 0) if (info.bytes == 0)
continue; continue;
MailProtocol* protocol = protocolThread->Protocol(); OutboundMessenger(protocol).SendMessages(info.files, info.bytes);
protocolThread->Lock();
protocol->SetTotalItems(info.files.size());
protocol->SetTotalItemsSize(info.totalSize);
protocolThread->Unlock();
protocolThread->SendMessages(iter->second.files, info.totalSize);
} }
} }
@@ -630,48 +677,38 @@ void
MailDaemonApp::_InitAccount(BMailAccountSettings& settings) MailDaemonApp::_InitAccount(BMailAccountSettings& settings)
{ {
account_protocols account; account_protocols account;
// inbound // inbound
if (settings.IsInboundEnabled()) { if (settings.IsInboundEnabled()) {
account.inboundProtocol = _CreateInboundProtocol(settings, account.inboundProtocol = _CreateInboundProtocol(settings,
account.inboundImage); account.inboundImage);
} else {
account.inboundProtocol = NULL;
} }
if (account.inboundProtocol) { if (account.inboundProtocol != NULL) {
DefaultNotifier* notifier = new DefaultNotifier(settings.Name(), true, DefaultNotifier* notifier = new DefaultNotifier(settings.Name(), true,
fErrorLogWindow, fNotifyMode); fErrorLogWindow, fNotifyMode);
account.inboundProtocol->SetMailNotifier(notifier); account.inboundProtocol->SetMailNotifier(notifier);
account.inboundProtocol->Run();
account.inboundThread = new InboundProtocolThread(
account.inboundProtocol);
account.inboundThread->Run();
} }
// outbound // outbound
if (settings.IsOutboundEnabled()) { if (settings.IsOutboundEnabled()) {
account.outboundProtocol = _CreateOutboundProtocol(settings, account.outboundProtocol = _CreateOutboundProtocol(settings,
account.outboundImage); account.outboundImage);
} else {
account.outboundProtocol = NULL;
} }
if (account.outboundProtocol) { if (account.outboundProtocol != NULL) {
DefaultNotifier* notifier = new DefaultNotifier(settings.Name(), false, DefaultNotifier* notifier = new DefaultNotifier(settings.Name(), false,
fErrorLogWindow, fNotifyMode); fErrorLogWindow, fNotifyMode);
account.outboundProtocol->SetMailNotifier(notifier); account.outboundProtocol->SetMailNotifier(notifier);
account.outboundProtocol->Run();
account.outboundThread = new OutboundProtocolThread(
account.outboundProtocol);
account.outboundThread->Run();
} }
printf("account name %s, id %i, in %p, out %p\n", settings.Name(), printf("account name %s, id %i, in %p, out %p\n", settings.Name(),
(int)settings.AccountID(), account.inboundProtocol, (int)settings.AccountID(), account.inboundProtocol,
account.outboundProtocol); account.outboundProtocol);
if (!account.inboundProtocol && !account.outboundProtocol)
return;
fAccounts[settings.AccountID()] = account;
}
if (account.inboundProtocol != NULL || account.outboundProtocol != NULL)
fAccounts[settings.AccountID()] = account;
}
void void
@@ -688,9 +725,12 @@ MailDaemonApp::_ReloadAccounts(BMessage* message)
for (int i = 0; i < countFound; i++) { for (int i = 0; i < countFound; i++) {
int32 account = message->FindInt32("account", i); int32 account = message->FindInt32("account", i);
AccountMap::const_iterator it = fAccounts.find(account); AccountMap::iterator found = fAccounts.find(account);
if (it != fAccounts.end()) if (found != fAccounts.end()) {
_RemoveAccount(it); _RemoveAccount(found->second);
fAccounts.erase(found);
}
BMailAccountSettings* settings = accounts.AccountByID(account); BMailAccountSettings* settings = accounts.AccountByID(account);
if (settings != NULL) if (settings != NULL)
_InitAccount(*settings); _InitAccount(*settings);
@@ -699,89 +739,88 @@ MailDaemonApp::_ReloadAccounts(BMessage* message)
void void
MailDaemonApp::_RemoveAccount(AccountMap::const_iterator it) MailDaemonApp::_RemoveAccount(const account_protocols& account)
{ {
BMessage reply; if (account.inboundProtocol != NULL) {
if (it->second.inboundThread) { account.inboundProtocol->Lock();
it->second.inboundThread->SetStopNow(); account.inboundProtocol->Quit();
BMessenger(it->second.inboundThread).SendMessage(B_QUIT_REQUESTED,
&reply); unload_add_on(account.inboundImage);
} }
if (it->second.outboundThread) {
it->second.outboundThread->SetStopNow(); if (account.outboundProtocol != NULL) {
BMessenger(it->second.outboundThread).SendMessage(B_QUIT_REQUESTED, account.outboundProtocol->Lock();
&reply); 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, MailDaemonApp::_CreateInboundProtocol(BMailAccountSettings& settings,
image_id& image) image_id& image)
{ {
const entry_ref& entry = settings.InboundPath(); const entry_ref& entry = settings.InboundAddOnRef();
InboundProtocol* (*instantiate_protocol)(BMailAccountSettings*); BInboundMailProtocol* (*instantiateProtocol)(BMailAccountSettings*);
BPath path(&entry); BPath path(&entry);
image = load_add_on(path.Path()); image = load_add_on(path.Path());
if (image < 0) if (image < 0)
return NULL; return NULL;
if (get_image_symbol(image, "instantiate_inbound_protocol", 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); unload_add_on(image);
image = -1; image = -1;
return NULL; return NULL;
} }
return (*instantiate_protocol)(&settings); return instantiateProtocol(&settings);
} }
OutboundProtocol* BOutboundMailProtocol*
MailDaemonApp::_CreateOutboundProtocol(BMailAccountSettings& settings, MailDaemonApp::_CreateOutboundProtocol(BMailAccountSettings& settings,
image_id& image) image_id& image)
{ {
const entry_ref& entry = settings.OutboundPath(); const entry_ref& entry = settings.OutboundAddOnRef();
OutboundProtocol* (*instantiate_protocol)(BMailAccountSettings*); BOutboundMailProtocol* (*instantiateProtocol)(BMailAccountSettings*);
BPath path(&entry); BPath path(&entry);
image = load_add_on(path.Path()); image = load_add_on(path.Path());
if (image < 0) if (image < 0)
return NULL; return NULL;
if (get_image_symbol(image, "instantiate_outbound_protocol", 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); unload_add_on(image);
image = -1; image = -1;
return NULL; return NULL;
} }
return (*instantiate_protocol)(&settings); return instantiateProtocol(&settings);
} }
InboundProtocolThread* BInboundMailProtocol*
MailDaemonApp::_FindInboundProtocol(int32 account) MailDaemonApp::_InboundProtocol(int32 account)
{ {
AccountMap::iterator it = fAccounts.find(account); AccountMap::iterator found = fAccounts.find(account);
if (it == fAccounts.end()) if (found == fAccounts.end())
return NULL; return NULL;
return it->second.inboundThread; return found->second.inboundProtocol;
} }
OutboundProtocolThread* BOutboundMailProtocol*
MailDaemonApp::_FindOutboundProtocol(int32 account) MailDaemonApp::_OutboundProtocol(int32 account)
{ {
if (account < 0) if (account < 0)
account = BMailSettings().DefaultOutboundAccount(); account = BMailSettings().DefaultOutboundAccount();
AccountMap::iterator it = fAccounts.find(account); AccountMap::iterator found = fAccounts.find(account);
if (it == fAccounts.end()) if (found == fAccounts.end())
return NULL; 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. /*! Work-around for a broken index that contains out-of-date information.
*/ */
/*static*/ bool /*static*/ bool
+16 -19
View File
@@ -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 2001-2002 Dr. Zoidberg Enterprises. All rights reserved.
* Copyright 2011, Clemens Zeidler <haiku@clemens-zeidler.de> * Copyright 2011, Clemens Zeidler <haiku@clemens-zeidler.de>
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
@@ -21,27 +21,20 @@
#include <MailProtocol.h> #include <MailProtocol.h>
#include "LEDAnimation.h" #include "LEDAnimation.h"
#include "Notifier.h" #include "DefaultNotifier.h"
class BNotification; class BNotification;
struct send_mails_info;
struct account_protocols { struct account_protocols {
account_protocols() { account_protocols();
inboundImage = -1;
inboundThread = NULL;
inboundProtocol = NULL;
outboundImage = -1;
outboundThread = NULL;
outboundProtocol = NULL;
}
image_id inboundImage; image_id inboundImage;
InboundProtocolThread* inboundThread; BInboundMailProtocol* inboundProtocol;
InboundProtocol* inboundProtocol;
image_id outboundImage; image_id outboundImage;
OutboundProtocolThread* outboundThread; BOutboundMailProtocol* outboundProtocol;
OutboundProtocol* outboundProtocol;
}; };
@@ -72,20 +65,24 @@ private:
void _InitAccounts(); void _InitAccounts();
void _InitAccount(BMailAccountSettings& settings); void _InitAccount(BMailAccountSettings& settings);
void _ReloadAccounts(BMessage* message); void _ReloadAccounts(BMessage* message);
void _RemoveAccount(AccountMap::const_iterator it); void _RemoveAccount(
const account_protocols& account);
InboundProtocol* _CreateInboundProtocol( BInboundMailProtocol* _CreateInboundProtocol(
BMailAccountSettings& settings, BMailAccountSettings& settings,
image_id& image); image_id& image);
OutboundProtocol* _CreateOutboundProtocol( BOutboundMailProtocol* _CreateOutboundProtocol(
BMailAccountSettings& settings, BMailAccountSettings& settings,
image_id& image); image_id& image);
InboundProtocolThread* _FindInboundProtocol(int32 account); BInboundMailProtocol* _InboundProtocol(int32 account);
OutboundProtocolThread* _FindOutboundProtocol(int32 account); BOutboundMailProtocol* _OutboundProtocol(int32 account);
void _UpdateAutoCheck(bigtime_t interval); void _UpdateAutoCheck(bigtime_t interval);
void _AddMessage(send_mails_info& info,
const BEntry& entry, const BNode& node);
static bool _IsPending(BNode& node); static bool _IsPending(BNode& node);
static bool _IsEntryInTrash(BEntry& entry); static bool _IsEntryInTrash(BEntry& entry);