/* * Copyright 2011-2012, Haiku, Inc. All rights reserved. * Copyright 2001-2003 Dr. Zoidberg Enterprises. All rights reserved. */ //#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "HaikuMailFormatFilter.h" using namespace BPrivate; const uint32 kMsgDeleteMessage = '&DeM'; const uint32 kMsgAppendMessage = '&ApM'; const uint32 kMsgMoveFile = '&MoF'; const uint32 kMsgDeleteFile = '&DeF'; const uint32 kMsgFileRenamed = '&FiR'; const uint32 kMsgFileDeleted = '&FDe'; const uint32 kMsgInit = '&Ini'; const uint32 kMsgSendMessage = '&SeM'; BMailProtocol::BMailProtocol(const BMailAccountSettings& settings) : fAccountSettings(settings), fMailNotifier(NULL) { AddFilter(new HaikuMailFormatFilter(*this, settings)); } BMailProtocol::~BMailProtocol() { delete fMailNotifier; for (int i = 0; i < fFilterList.CountItems(); i++) delete fFilterList.ItemAt(i); std::map::iterator it = fFilterImages.begin(); for (; it != fFilterImages.end(); it++) unload_add_on(it->second); } const BMailAccountSettings& BMailProtocol::AccountSettings() const { return fAccountSettings; } void BMailProtocol::SetMailNotifier(BMailNotifier* mailNotifier) { delete fMailNotifier; fMailNotifier = mailNotifier; } BMailNotifier* BMailProtocol::MailNotifier() const { return fMailNotifier; } bool BMailProtocol::AddFilter(BMailFilter* filter) { BLocker locker(this); return fFilterList.AddItem(filter); } int32 BMailProtocol::CountFilter() const { BLocker locker(this); return fFilterList.CountItems(); } BMailFilter* BMailProtocol::FilterAt(int32 index) const { BLocker locker(this); return fFilterList.ItemAt(index); } BMailFilter* BMailProtocol::RemoveFilter(int32 index) { BLocker locker(this); return fFilterList.RemoveItemAt(index); } bool BMailProtocol::RemoveFilter(BMailFilter* filter) { BLocker locker(this); return fFilterList.RemoveItem(filter); } void BMailProtocol::MessageReceived(BMessage* message) { switch (message->what) { case kMsgMoveFile: { entry_ref file; message->FindRef("file", &file); entry_ref dir; message->FindRef("directory", &dir); BDirectory directory(&dir); MoveMessage(file, directory); break; } case kMsgDeleteFile: { entry_ref file; message->FindRef("file", &file); DeleteMessage(file); break; } case kMsgFileRenamed: { entry_ref from; message->FindRef("from", &from); entry_ref to; message->FindRef("to", &to); FileRenamed(from, to); break; } case kMsgFileDeleted: { node_ref node; message->FindInt32("device",&node.device); message->FindInt64("node", &node.node); FileDeleted(node); break; } default: BLooper::MessageReceived(message); } } status_t BMailProtocol::MoveMessage(const entry_ref& ref, BDirectory& dir) { BEntry entry(&ref); return entry.MoveTo(&dir); } status_t BMailProtocol::DeleteMessage(const entry_ref& ref) { BEntry entry(&ref); return entry.Remove(); } void BMailProtocol::FileRenamed(const entry_ref& from, const entry_ref& to) { } void BMailProtocol::FileDeleted(const node_ref& node) { } void BMailProtocol::ShowError(const char* error) { if (MailNotifier() != NULL) MailNotifier()->ShowError(error); } void BMailProtocol::ShowMessage(const char* message) { if (MailNotifier() != NULL) MailNotifier()->ShowMessage(message); } void BMailProtocol::SetTotalItems(uint32 items) { if (MailNotifier() != NULL) MailNotifier()->SetTotalItems(items); } void BMailProtocol::SetTotalItemsSize(uint64 size) { if (MailNotifier() != NULL) MailNotifier()->SetTotalItemsSize(size); } void BMailProtocol::ReportProgress(uint32 messages, uint64 bytes, const char* message) { if (MailNotifier() != NULL) MailNotifier()->ReportProgress(messages, bytes, message); } void BMailProtocol::ResetProgress(const char* message) { if (MailNotifier() != NULL) MailNotifier()->ResetProgress(message); } void BMailProtocol::NotifyNewMessagesToFetch(int32 count) { ResetProgress(); SetTotalItems(count); } void BMailProtocol::NotifyHeaderFetched(const entry_ref& ref, BFile* data) { for (int i = 0; i < fFilterList.CountItems(); i++) fFilterList.ItemAt(i)->HeaderFetched(ref, data); } void BMailProtocol::NotifyBodyFetched(const entry_ref& ref, BFile* data) { for (int i = 0; i < fFilterList.CountItems(); i++) fFilterList.ItemAt(i)->BodyFetched(ref, data); } void BMailProtocol::NotifyMessageReadyToSend(const entry_ref& ref, BFile* data) { for (int i = 0; i < fFilterList.CountItems(); i++) fFilterList.ItemAt(i)->MessageReadyToSend(ref, data); } void BMailProtocol::NotifyMessageSent(const entry_ref& ref, BFile* data) { for (int i = 0; i < fFilterList.CountItems(); i++) fFilterList.ItemAt(i)->MessageSent(ref, data); } void BMailProtocol::LoadFilters(const BMailProtocolSettings& settings) { for (int i = 0; i < settings.CountFilterSettings(); i++) { BMailAddOnSettings* filterSettings = settings.FilterSettingsAt(i); BMailFilter* filter = _LoadFilter(*filterSettings); if (filter != NULL) AddFilter(filter); } } BMailFilter* BMailProtocol::_LoadFilter(const BMailAddOnSettings& settings) { const entry_ref& ref = settings.AddOnRef(); std::map::iterator it = fFilterImages.find(ref); image_id image; if (it != fFilterImages.end()) image = it->second; else { BEntry entry(&ref); BPath path(&entry); image = load_add_on(path.Path()); } if (image < 0) return NULL; BMailFilter* (*instantiateFilter)(BMailProtocol& protocol, const BMailAddOnSettings& settings); if (get_image_symbol(image, "instantiate_filter", B_SYMBOL_TYPE_TEXT, (void**)&instantiateFilter) != B_OK) { unload_add_on(image); return NULL; } fFilterImages[ref] = image; return instantiateFilter(*this, settings); } // #pragma mark - BInboundMailProtocol::BInboundMailProtocol(const BMailAccountSettings& settings) : BMailProtocol(settings) { LoadFilters(fAccountSettings.InboundSettings()); } BInboundMailProtocol::~BInboundMailProtocol() { } void BInboundMailProtocol::MessageReceived(BMessage* message) { switch (message->what) { case kMsgSyncMessages: { NotiyMailboxSynchronized(SyncMessages()); break; } case kMsgFetchBody: { entry_ref ref; message->FindRef("ref", &ref); status_t status = FetchBody(ref); BMessenger target; if (message->FindMessenger("target", &target) != B_OK) break; BMessage message(B_MAIL_BODY_FETCHED); message.AddInt32("status", status); message.AddRef("ref", &ref); target.SendMessage(&message); break; } case kMsgMarkMessageAsRead: { entry_ref ref; message->FindRef("ref", &ref); read_flags read = (read_flags)message->FindInt32("read"); MarkMessageAsRead(ref, read); break; } case kMsgDeleteMessage: { entry_ref ref; message->FindRef("ref", &ref); DeleteMessage(ref); break; } case kMsgAppendMessage: { entry_ref ref; message->FindRef("ref", &ref); AppendMessage(ref); break; } default: BMailProtocol::MessageReceived(message); break; } } status_t BInboundMailProtocol::MarkMessageAsRead(const entry_ref& ref, read_flags flag) { BNode node(&ref); return write_read_attr(node, flag); } status_t BInboundMailProtocol::AppendMessage(const entry_ref& ref) { return B_OK; } void BInboundMailProtocol::NotiyMailboxSynchronized(status_t status) { for (int32 i = 0; i < CountFilter(); i++) FilterAt(i)->MailboxSynchronized(status); } // #pragma mark - BOutboundMailProtocol::BOutboundMailProtocol( const BMailAccountSettings& settings) : BMailProtocol(settings) { LoadFilters(fAccountSettings.OutboundSettings()); } BOutboundMailProtocol::~BOutboundMailProtocol() { } void BOutboundMailProtocol::MessageReceived(BMessage* message) { switch (message->what) { case kMsgSendMessage: SendMessages(*message, message->FindInt64("bytes")); break; default: BMailProtocol::MessageReceived(message); } }