[haiku-commits] BRANCH axeld-github.imap [002f094] src/kits/mail src/add-ons/mail_daemon/inbound_protocols/imap headers/os/add-ons/mail_daemon src/kits/app src/add-ons/mail_daemon/inbound_filters/spam_filter

  • From: axeld-github.imap <community@xxxxxxxxxxxx>
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Wed, 3 Jul 2013 23:15:37 +0200 (CEST)

added 1 changeset to branch 'refs/remotes/axeld-github/imap'
old head: d3ede35cf2c614eafe7cc08e9143c22fc74cb815
new head: 002f09437f5f468e0c52c884aa7fcdf9e37251d3
overview: https://github.com/axeld/haiku/compare/d3ede35...002f094

----------------------------------------------------------------------------

002f094: IMAP: downloading mails is now working.
  
  * Changed the way the attributes are written to make sure that everything
    that can be written once is in fact written just once.
  * The rename code in BMailProtocol::_ProcessFetchedHeader() was broken,
    and caused the hang of the last commit.

                                   [ Axel Dörfler <axeld@xxxxxxxxxxxxxxxx> ]

----------------------------------------------------------------------------

Commit:      002f09437f5f468e0c52c884aa7fcdf9e37251d3
Author:      Axel Dörfler <axeld@xxxxxxxxxxxxxxxx>
Date:        Wed Jul  3 20:52:22 2013 UTC

----------------------------------------------------------------------------

16 files changed, 181 insertions(+), 119 deletions(-)
headers/os/add-ons/mail_daemon/MailFilter.h      |   6 +-
headers/os/add-ons/mail_daemon/MailProtocol.h    |  10 +-
headers/os/app/Message.h                         |   5 +-
.../inbound_filters/match_header/RuleFilter.cpp  |  14 +-
.../inbound_filters/match_header/RuleFilter.h    |   3 +-
.../inbound_filters/spam_filter/SpamFilter.cpp   |   6 +-
.../inbound_filters/spam_filter/SpamFilter.h     |   6 +-
.../inbound_protocols/imap/IMAPFolder.cpp        |  12 +-
.../inbound_protocols/imap/IMAPProtocol.cpp      |  15 +-
.../inbound_protocols/imap/IMAPProtocol.h        |   2 +-
.../mail_daemon/inbound_protocols/pop3/POP3.cpp  |  13 +-
src/kits/app/Message.cpp                         |  15 +-
src/kits/mail/HaikuMailFormatFilter.cpp          |  26 ++--
src/kits/mail/HaikuMailFormatFilter.h            |   8 +-
src/kits/mail/MailFilter.cpp                     |   5 +-
src/kits/mail/MailProtocol.cpp                   | 154 ++++++++++++-------

----------------------------------------------------------------------------

diff --git a/headers/os/add-ons/mail_daemon/MailFilter.h 
b/headers/os/add-ons/mail_daemon/MailFilter.h
index b071c70..5721d6f 100644
--- a/headers/os/add-ons/mail_daemon/MailFilter.h
+++ b/headers/os/add-ons/mail_daemon/MailFilter.h
@@ -21,8 +21,10 @@ public:
        virtual                                         ~BMailFilter();
 
        // Message hooks if filter is installed to an inbound protocol
-       virtual BMailFilterAction       HeaderFetched(entry_ref& ref, BFile& 
file);
-       virtual void                            BodyFetched(const entry_ref& 
ref, BFile& file);
+       virtual BMailFilterAction       HeaderFetched(entry_ref& ref, BFile& 
file,
+                                                                       
BMessage& attributes);
+       virtual void                            BodyFetched(const entry_ref& 
ref, BFile& file,
+                                                                       
BMessage& attributes);
        virtual void                            MailboxSynchronized(status_t 
status);
 
        // Message hooks if filter is installed to an outbound protocol
diff --git a/headers/os/add-ons/mail_daemon/MailProtocol.h 
b/headers/os/add-ons/mail_daemon/MailProtocol.h
index f263fc0..d4c3b2c 100644
--- a/headers/os/add-ons/mail_daemon/MailProtocol.h
+++ b/headers/os/add-ons/mail_daemon/MailProtocol.h
@@ -95,9 +95,11 @@ protected:
 
                        // Filter notifications
                        BMailFilterAction       ProcessHeaderFetched(entry_ref& 
ref,
-                                                                       BFile& 
mail);
+                                                                       BFile& 
mail, BMessage& attributes);
                        void                            NotifyBodyFetched(const 
entry_ref& ref,
-                                                                       BFile& 
mail);
+                                                                       BFile& 
mail, BMessage& attributes);
+                       BMailFilterAction       
ProcessMessageFetched(entry_ref& ref,
+                                                                       BFile& 
mail, BMessage& attributes);
                        void                            
NotifyMessageReadyToSend(const entry_ref& ref,
                                                                        BFile& 
mail);
                        void                            NotifyMessageSent(const 
entry_ref& ref,
@@ -108,6 +110,10 @@ protected:
 
 private:
                        BMailFilter*            _LoadFilter(const 
BMailAddOnSettings& settings);
+                       BMailFilterAction       
_ProcessHeaderFetched(entry_ref& ref,
+                                                                       BFile& 
mail, BMessage& attributes);
+                       void                            
_NotifyBodyFetched(const entry_ref& ref,
+                                                                       BFile& 
mail, BMessage& attributes);
 
 protected:
                        const BMailAccountSettings fAccountSettings;
diff --git a/headers/os/app/Message.h b/headers/os/app/Message.h
index bb3a74d..104ebf2 100644
--- a/headers/os/app/Message.h
+++ b/headers/os/app/Message.h
@@ -1,5 +1,5 @@
 /*
- * Copyright 2005-2012, Haiku Inc. All Rights Reserved.
+ * Copyright 2005-2013, Haiku Inc. All Rights Reserved.
  * Distributed under the terms of the MIT License.
  *
  * Authors:
@@ -486,7 +486,8 @@ public:
                        status_t                        SetRect(const char* 
name, const BRect& value);
                        status_t                        SetSize(const char* 
name, const BSize& value);
                        status_t                        SetData(const char* 
name, type_code type,
-                                                                       const 
void* data, ssize_t numBytes);
+                                                                       const 
void* data, ssize_t numBytes,
+                                                                       bool 
fixedSize = true, int count = 1);
 
        class Private;
        struct message_header;
diff --git 
a/src/add-ons/mail_daemon/inbound_filters/match_header/RuleFilter.cpp 
b/src/add-ons/mail_daemon/inbound_filters/match_header/RuleFilter.cpp
index 75bc5dd..c01f46e 100644
--- a/src/add-ons/mail_daemon/inbound_filters/match_header/RuleFilter.cpp
+++ b/src/add-ons/mail_daemon/inbound_filters/match_header/RuleFilter.cpp
@@ -57,7 +57,7 @@ RuleFilter::RuleFilter(BMailProtocol& protocol,
 
 
 BMailFilterAction
-RuleFilter::HeaderFetched(entry_ref& ref, BFile& file)
+RuleFilter::HeaderFetched(entry_ref& ref, BFile& file, BMessage& attributes)
 {
        // That field doesn't exist? NO match
        if (fAttribute == "")
@@ -68,16 +68,8 @@ RuleFilter::HeaderFetched(entry_ref& ref, BFile& file)
                || info.type != B_STRING_TYPE)
                return B_NO_MAIL_ACTION;
 
-       char* buffer = new char[info.size];
-       if (file.ReadAttr(fAttribute, B_STRING_TYPE, 0, buffer, info.size) < 0) 
{
-               delete[] buffer;
-               return B_NO_MAIL_ACTION;
-       }
-
-       BString data = buffer;
-       delete[] buffer;
-
-       if (!fMatcher.Match(data)) {
+       BString data = attributes.GetString(fAttribute.String(), NULL);
+       if (data.IsEmpty() || !fMatcher.Match(data)) {
                // We're not supposed to do anything
                return B_NO_MAIL_ACTION;
        }
diff --git a/src/add-ons/mail_daemon/inbound_filters/match_header/RuleFilter.h 
b/src/add-ons/mail_daemon/inbound_filters/match_header/RuleFilter.h
index ef24e80..e7a48f3 100644
--- a/src/add-ons/mail_daemon/inbound_filters/match_header/RuleFilter.h
+++ b/src/add-ons/mail_daemon/inbound_filters/match_header/RuleFilter.h
@@ -21,7 +21,8 @@ public:
                                                                
RuleFilter(BMailProtocol& protocol,
                                                                        const 
BMailAddOnSettings& settings);
 
-       virtual BMailFilterAction       HeaderFetched(entry_ref& ref, BFile& 
file);
+       virtual BMailFilterAction       HeaderFetched(entry_ref& ref, BFile& 
file,
+                                                                       
BMessage& attributes);
 
 private:
                        BString                         fAttribute;
diff --git a/src/add-ons/mail_daemon/inbound_filters/spam_filter/SpamFilter.cpp 
b/src/add-ons/mail_daemon/inbound_filters/spam_filter/SpamFilter.cpp
index 5544c83..9ca3a6c 100644
--- a/src/add-ons/mail_daemon/inbound_filters/spam_filter/SpamFilter.cpp
+++ b/src/add-ons/mail_daemon/inbound_filters/spam_filter/SpamFilter.cpp
@@ -67,7 +67,7 @@ SpamFilter::~SpamFilter()
 
 
 BMailFilterAction
-SpamFilter::HeaderFetched(entry_ref& ref, BFile& file)
+SpamFilter::HeaderFetched(entry_ref& ref, BFile& file, BMessage& attributes)
 {
        _CheckForSpam(file);
        return B_NO_MAIL_ACTION;
@@ -75,7 +75,7 @@ SpamFilter::HeaderFetched(entry_ref& ref, BFile& file)
 
 
 void
-SpamFilter::BodyFetched(const entry_ref& ref, BFile& file)
+SpamFilter::BodyFetched(const entry_ref& ref, BFile& file, BMessage& 
attributes)
 {
        if (fHeaderOnly)
                return;
@@ -85,7 +85,7 @@ SpamFilter::BodyFetched(const entry_ref& ref, BFile& file)
        // untrain the partial part before training on the complete message, 
but we
        // don't know how big it was, so instead just ignore the message.
        attr_info attributeInfo;
-       if (file.GetAttrInfo ("MAIL:classification", &attributeInfo) == B_OK)
+       if (file.GetAttrInfo("MAIL:classification", &attributeInfo) == B_OK)
                return;
 
        _CheckForSpam(file);
diff --git a/src/add-ons/mail_daemon/inbound_filters/spam_filter/SpamFilter.h 
b/src/add-ons/mail_daemon/inbound_filters/spam_filter/SpamFilter.h
index 15368c5..f255a39 100644
--- a/src/add-ons/mail_daemon/inbound_filters/spam_filter/SpamFilter.h
+++ b/src/add-ons/mail_daemon/inbound_filters/spam_filter/SpamFilter.h
@@ -18,8 +18,10 @@ public:
                                                                        const 
BMailAddOnSettings& settings);
        virtual                                         ~SpamFilter();
 
-       virtual BMailFilterAction       HeaderFetched(entry_ref& ref, BFile& 
file);
-       virtual void                            BodyFetched(const entry_ref& 
ref, BFile& file);
+       virtual BMailFilterAction       HeaderFetched(entry_ref& ref, BFile& 
file,
+                                                                       
BMessage& attributes);
+       virtual void                            BodyFetched(const entry_ref& 
ref, BFile& file,
+                                                                       
BMessage& attributes);
 
 private:
                        status_t                        _CheckForSpam(BFile& 
file);
diff --git a/src/add-ons/mail_daemon/inbound_protocols/imap/IMAPFolder.cpp 
b/src/add-ons/mail_daemon/inbound_protocols/imap/IMAPFolder.cpp
index 7a026af..cb58d82 100644
--- a/src/add-ons/mail_daemon/inbound_protocols/imap/IMAPFolder.cpp
+++ b/src/add-ons/mail_daemon/inbound_protocols/imap/IMAPFolder.cpp
@@ -231,7 +231,14 @@ IMAPFolder::MessageStored(entry_ref& ref, BFile& file, 
uint32 fetchFlags,
        if ((fetchFlags & IMAP::kFetchFlags) != 0)
                _WriteFlags(file, flags);
 
-       fProtocol.MessageStored(*this, ref, file, fetchFlags);
+       // TODO: add some utility function for this in libmail.so
+       BMessage attributes;
+       if ((flags & IMAP::kAnswered) != 0)
+               attributes.AddString(B_MAIL_ATTR_STATUS, "Answered");
+       else if ((flags & IMAP::kSeen) != 0)
+               attributes.AddString(B_MAIL_ATTR_STATUS, "Read");
+
+       fProtocol.MessageStored(*this, ref, file, fetchFlags, attributes);
        file.Unset();
 
        fRefMap.insert(std::make_pair(uid, ref));
@@ -282,7 +289,8 @@ IMAPFolder::StoreBody(uint32 uid, BDataIO& stream, size_t& 
length,
 void
 IMAPFolder::BodyStored(entry_ref& ref, BFile& file, uint32 uid)
 {
-       fProtocol.MessageStored(*this, ref, file, IMAP::kFetchBody);
+       BMessage attributes;
+       fProtocol.MessageStored(*this, ref, file, IMAP::kFetchBody, attributes);
        file.Unset();
 }
 
diff --git a/src/add-ons/mail_daemon/inbound_protocols/imap/IMAPProtocol.cpp 
b/src/add-ons/mail_daemon/inbound_protocols/imap/IMAPProtocol.cpp
index b9605b1..17ccf22 100644
--- a/src/add-ons/mail_daemon/inbound_protocols/imap/IMAPProtocol.cpp
+++ b/src/add-ons/mail_daemon/inbound_protocols/imap/IMAPProtocol.cpp
@@ -124,15 +124,16 @@ IMAPProtocol::WorkerQuit(IMAPConnectionWorker* worker)
 
 void
 IMAPProtocol::MessageStored(IMAPFolder& folder, entry_ref& ref, BFile& stream,
-       uint32 fetchFlags)
+       uint32 fetchFlags, BMessage& attributes)
 {
-       if ((fetchFlags & IMAP::kFetchHeader) != 0) {
-               BMailFilterAction action = ProcessHeaderFetched(ref, stream);
-               if (action < B_OK || action == B_DELETE_MAIL_ACTION)
-                       return;
+       if ((fetchFlags & (IMAP::kFetchHeader | IMAP::kFetchBody))
+                       == IMAP::kFetchHeader | IMAP::kFetchBody) {
+               ProcessMessageFetched(ref, stream, attributes);
+       } else if ((fetchFlags & IMAP::kFetchHeader) != 0) {
+               ProcessHeaderFetched(ref, stream, attributes);
+       } else if ((fetchFlags & IMAP::kFetchBody) != 0) {
+               NotifyBodyFetched(ref, stream, attributes);
        }
-       if ((fetchFlags & IMAP::kFetchBody) != 0)
-               NotifyBodyFetched(ref, stream);
 }
 
 
diff --git a/src/add-ons/mail_daemon/inbound_protocols/imap/IMAPProtocol.h 
b/src/add-ons/mail_daemon/inbound_protocols/imap/IMAPProtocol.h
index 531b5c9..fb3d144 100644
--- a/src/add-ons/mail_daemon/inbound_protocols/imap/IMAPProtocol.h
+++ b/src/add-ons/mail_daemon/inbound_protocols/imap/IMAPProtocol.h
@@ -36,7 +36,7 @@ public:
 
                        void                            
MessageStored(IMAPFolder& folder,
                                                                        
entry_ref& ref, BFile& stream,
-                                                                       uint32 
fetchFlags);
+                                                                       uint32 
fetchFlags, BMessage& attributes);
 
        virtual status_t                        SyncMessages();
        virtual status_t                        FetchBody(const entry_ref& ref);
diff --git a/src/add-ons/mail_daemon/inbound_protocols/pop3/POP3.cpp 
b/src/add-ons/mail_daemon/inbound_protocols/pop3/POP3.cpp
index 9a1f3cd..db2e893 100644
--- a/src/add-ons/mail_daemon/inbound_protocols/pop3/POP3.cpp
+++ b/src/add-ons/mail_daemon/inbound_protocols/pop3/POP3.cpp
@@ -203,14 +203,11 @@ POP3Protocol::SyncMessages()
                        break;
                }
                BMailMessageIO mailIO(this, &file, toRetrieve);
+               BMessage attributes;
 
                entry_ref ref;
                entry.GetRef(&ref);
 
-               // the ref becomes invalid after renaming the file thus we 
already
-               // write the status here
-               MarkMessageAsRead(ref, B_UNREAD);
-
                int32 size = MessageSize(toRetrieve);
                if (fFetchBodyLimit < 0 || size <= fFetchBodyLimit) {
                        error = mailIO.Seek(0, SEEK_END);
@@ -218,8 +215,7 @@ POP3Protocol::SyncMessages()
                                printf("POP3: Failed to download body %s\n ", 
uid);
                                break;
                        }
-                       ProcessHeaderFetched(ref, file);
-                       NotifyBodyFetched(ref, file);
+                       ProcessMessageFetched(ref, file, attributes);
 
                        if (!leaveOnServer)
                                Delete(toRetrieve);
@@ -230,7 +226,7 @@ POP3Protocol::SyncMessages()
                                printf("POP3: Failed to download header %s\n ", 
uid);
                                break;
                        }
-                       ProcessHeaderFetched(ref, file);
+                       ProcessHeaderFetched(ref, file, attributes);
                }
                ReportProgress(1, 0);
 
@@ -302,7 +298,8 @@ POP3Protocol::FetchBody(const entry_ref& ref)
                return status;
        }
 
-       NotifyBodyFetched(ref, file);
+       BMessage attributes;
+       NotifyBodyFetched(ref, file, attributes);
 
        if (!leaveOnServer)
                Delete(toRetrieve);
diff --git a/src/kits/app/Message.cpp b/src/kits/app/Message.cpp
index 3c0dbe6..fe4f18f 100644
--- a/src/kits/app/Message.cpp
+++ b/src/kits/app/Message.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright 2005-2012, Haiku Inc. All rights reserved.
+ * Copyright 2005-2013, Haiku Inc. All rights reserved.
  * Distributed under the terms of the MIT License.
  *
  * Authors:
@@ -3128,8 +3128,8 @@ BMessage::HasFlat(const char *name, const BFlattenable 
*object) const
 
 
 bool
-BMessage::HasFlat(const char *name, int32 index, const BFlattenable *object)
-       const
+BMessage::HasFlat(const char *name, int32 index,
+       const BFlattenable *object) const
 {
        return HasData(name, object->TypeCode(), index);
 }
@@ -3157,20 +3157,21 @@ BMessage::GetString(const char *name, int32 index,
 status_t
 BMessage::SetString(const char *name, const BString& value)
 {
-       return SetData(name, B_STRING_TYPE, value.String(), value.Length() + 1);
+       return SetData(name, B_STRING_TYPE, value.String(), value.Length() + 1,
+               false);
 }
 
 
 status_t
 BMessage::SetString(const char *name, const char* value)
 {
-       return SetData(name, B_STRING_TYPE, value, strlen(value) + 1);
+       return SetData(name, B_STRING_TYPE, value, strlen(value) + 1, false);
 }
 
 
 status_t
 BMessage::SetData(const char* name, type_code type, const void* data,
-       ssize_t numBytes)
+       ssize_t numBytes, bool fixedSize, int count)
 {
        if (numBytes <= 0 || data == NULL)
                return B_BAD_VALUE;
@@ -3178,5 +3179,5 @@ BMessage::SetData(const char* name, type_code type, const 
void* data,
        if (ReplaceData(name, type, data, numBytes) == B_OK)
                return B_OK;
 
-       return AddData(name, type, data, numBytes);
+       return AddData(name, type, data, numBytes, fixedSize, count);
 }
diff --git a/src/kits/mail/HaikuMailFormatFilter.cpp 
b/src/kits/mail/HaikuMailFormatFilter.cpp
index 96a28fa..8c4b4d8 100644
--- a/src/kits/mail/HaikuMailFormatFilter.cpp
+++ b/src/kits/mail/HaikuMailFormatFilter.cpp
@@ -16,7 +16,6 @@
 #include <NodeInfo.h>
 
 #include <mail_util.h>
-#include <NodeMessage.h>
 
 
 struct mail_header_field {
@@ -98,11 +97,11 @@ HaikuMailFormatFilter::DescriptiveName() const
 
 
 BMailFilterAction
-HaikuMailFormatFilter::HeaderFetched(entry_ref& ref, BFile& file)
+HaikuMailFormatFilter::HeaderFetched(entry_ref& ref, BFile& file,
+       BMessage& attributes)
 {
        file.Seek(0, SEEK_SET);
 
-       BMessage attributes;
        // TODO: attributes.AddInt32(B_MAIL_ATTR_CONTENT, length);
        attributes.AddInt32(B_MAIL_ATTR_ACCOUNT_ID, fAccountID);
        attributes.AddString(B_MAIL_ATTR_ACCOUNT, fAccountName);
@@ -196,11 +195,10 @@ HaikuMailFormatFilter::HeaderFetched(entry_ref& ref, 
BFile& file)
        _RemoveLeadingDots(name);
                // Avoid files starting with a dot.
 
-       file << attributes;
+       if (!attributes.HasString(B_MAIL_ATTR_STATUS))
+               attributes.AddString(B_MAIL_ATTR_STATUS, "New");
 
-       // TODO: find a way to not set that twice for each complete mail
-       BNodeInfo info(&file);
-       info.SetType(B_PARTIAL_MAIL_TYPE);
+       _SetType(attributes, B_PARTIAL_MAIL_TYPE);
 
        ref.set_name(name.String());
 
@@ -209,10 +207,10 @@ HaikuMailFormatFilter::HeaderFetched(entry_ref& ref, 
BFile& file)
 
 
 void
-HaikuMailFormatFilter::BodyFetched(const entry_ref& ref, BFile& file)
+HaikuMailFormatFilter::BodyFetched(const entry_ref& ref, BFile& file,
+       BMessage& attributes)
 {
-       BNodeInfo info(&file);
-       info.SetType(B_MAIL_TYPE);
+       _SetType(attributes, B_MAIL_TYPE);
 }
 
 
@@ -307,3 +305,11 @@ HaikuMailFormatFilter::_ExtractName(const BString& from)
        name.Trim();
        return name;
 }
+
+
+status_t
+HaikuMailFormatFilter::_SetType(BMessage& attributes, const char* mimeType)
+{
+       return attributes.SetData("BEOS:TYPE", B_MIME_STRING_TYPE, mimeType,
+               strlen(mimeType) + 1, false);
+}
diff --git a/src/kits/mail/HaikuMailFormatFilter.h 
b/src/kits/mail/HaikuMailFormatFilter.h
index 2eebb60..b8c1ef1 100644
--- a/src/kits/mail/HaikuMailFormatFilter.h
+++ b/src/kits/mail/HaikuMailFormatFilter.h
@@ -18,8 +18,10 @@ public:
 
        virtual BString                         DescriptiveName() const;
 
-                       BMailFilterAction       HeaderFetched(entry_ref& ref, 
BFile& file);
-                       void                            BodyFetched(const 
entry_ref& ref, BFile& file);
+                       BMailFilterAction       HeaderFetched(entry_ref& ref, 
BFile& file,
+                                                                       
BMessage& attributes);
+                       void                            BodyFetched(const 
entry_ref& ref, BFile& file,
+                                                                       
BMessage& attributes);
 
                        void                            MessageSent(const 
entry_ref& ref, BFile& file);
 
@@ -27,6 +29,8 @@ private:
                        void                            
_RemoveExtraWhitespace(BString& name);
                        void                            
_RemoveLeadingDots(BString& name);
                        BString                         _ExtractName(const 
BString& from);
+                       status_t                        _SetType(BMessage& 
attributes,
+                                                                       const 
char* mimeType);
 
 private:
                        int32                           fAccountID;
diff --git a/src/kits/mail/MailFilter.cpp b/src/kits/mail/MailFilter.cpp
index 7c7d626..faf93ea 100644
--- a/src/kits/mail/MailFilter.cpp
+++ b/src/kits/mail/MailFilter.cpp
@@ -22,14 +22,15 @@ BMailFilter::~BMailFilter()
 
 
 BMailFilterAction
-BMailFilter::HeaderFetched(entry_ref& ref, BFile& file)
+BMailFilter::HeaderFetched(entry_ref& ref, BFile& file, BMessage& attributes)
 {
        return B_NO_MAIL_ACTION;
 }
 
 
 void
-BMailFilter::BodyFetched(const entry_ref& ref, BFile& file)
+BMailFilter::BodyFetched(const entry_ref& ref, BFile& file,
+       BMessage& attributes)
 {
 }
 
diff --git a/src/kits/mail/MailProtocol.cpp b/src/kits/mail/MailProtocol.cpp
index b39185c..446e142 100644
--- a/src/kits/mail/MailProtocol.cpp
+++ b/src/kits/mail/MailProtocol.cpp
@@ -32,6 +32,7 @@
 
 #include <mail_util.h>
 #include <MailPrivate.h>
+#include <NodeMessage.h>
 
 #include "HaikuMailFormatFilter.h"
 
@@ -210,83 +211,53 @@ BMailProtocol::NotifyNewMessagesToFetch(int32 count)
 
 
 BMailFilterAction
-BMailProtocol::ProcessHeaderFetched(entry_ref& ref, BFile& data)
+BMailProtocol::ProcessHeaderFetched(entry_ref& ref, BFile& file,
+       BMessage& attributes)
 {
-       entry_ref outRef = ref;
-
-       for (int i = 0; i < fFilterList.CountItems(); i++) {
-               BMailFilterAction action = 
fFilterList.ItemAt(i)->HeaderFetched(outRef,
-                       data);
-               if (action == B_DELETE_MAIL_ACTION) {
-                       // We have to delete the message
-                       BEntry entry(&ref);
-                       status_t status = entry.Remove();
-                       if (status != B_OK) {
-                               fprintf(stderr, 
"BMailProtocol::NotifyHeaderFetched(): could "
-                                       "not delete mail: %s\n", 
strerror(status));
-                       }
-                       return B_DELETE_MAIL_ACTION;
-               }
-       }
-
-       if (ref == outRef)
-               return B_NO_MAIL_ACTION;
-
-       // We have to rename the file
-       node_ref newParentRef;
-       newParentRef.device = outRef.device;
-       newParentRef.node = outRef.directory;
-
-       BDirectory newParent(&newParentRef);
-       status_t status = newParent.InitCheck();
-       BString workerName;
-       if (status == B_OK) {
-               int32 uniqueNumber = 1;
-               do {
-                       workerName = outRef.name;
-                       if (uniqueNumber > 1)
-                               workerName << "_" << ++uniqueNumber;
+       BMailFilterAction action = _ProcessHeaderFetched(ref, file, attributes);
+       if (action >= B_OK && action != B_DELETE_MAIL_ACTION)
+               file << attributes;
 
-                       // TODO: support copying to another device!
-                       BEntry entry(&ref);
-                       status = entry.Rename(workerName);
-               } while (status == B_FILE_EXISTS);
-       }
+       return action;
+}
 
-       if (status != B_OK) {
-               fprintf(stderr, "BMailProtocol::NotifyHeaderFetched(): could 
not "
-                       "rename mail (%s)! (should be: %s)\n", strerror(status),
-                       workerName.String());
-       }
 
-       ref = outRef;
-       ref.set_name(workerName.String());
-
-       return B_MOVE_MAIL_ACTION;
+void
+BMailProtocol::NotifyBodyFetched(const entry_ref& ref, BFile& file,
+       BMessage& attributes)
+{
+       _NotifyBodyFetched(ref, file, attributes);
+       file << attributes;
 }
 
 
-void
-BMailProtocol::NotifyBodyFetched(const entry_ref& ref, BFile& data)
+BMailFilterAction
+BMailProtocol::ProcessMessageFetched(entry_ref& ref, BFile& file,
+       BMessage& attributes)
 {
-       for (int i = 0; i < fFilterList.CountItems(); i++)
-               fFilterList.ItemAt(i)->BodyFetched(ref, data);
+       BMailFilterAction action = _ProcessHeaderFetched(ref, file, attributes);
+       if (action >= B_OK && action != B_DELETE_MAIL_ACTION) {
+               _NotifyBodyFetched(ref, file, attributes);
+               file << attributes;
+       }
+
+       return action;
 }
 
 
 void
-BMailProtocol::NotifyMessageReadyToSend(const entry_ref& ref, BFile& data)
+BMailProtocol::NotifyMessageReadyToSend(const entry_ref& ref, BFile& file)
 {
        for (int i = 0; i < fFilterList.CountItems(); i++)
-               fFilterList.ItemAt(i)->MessageReadyToSend(ref, data);
+               fFilterList.ItemAt(i)->MessageReadyToSend(ref, file);
 }
 
 
 void
-BMailProtocol::NotifyMessageSent(const entry_ref& ref, BFile& data)
+BMailProtocol::NotifyMessageSent(const entry_ref& ref, BFile& file)
 {
        for (int i = 0; i < fFilterList.CountItems(); i++)
-               fFilterList.ItemAt(i)->MessageSent(ref, data);
+               fFilterList.ItemAt(i)->MessageSent(ref, file);
 }
 
 
@@ -331,6 +302,75 @@ BMailProtocol::_LoadFilter(const BMailAddOnSettings& 
settings)
 }
 
 
+BMailFilterAction
+BMailProtocol::_ProcessHeaderFetched(entry_ref& ref, BFile& file,
+       BMessage& attributes)
+{
+       entry_ref outRef = ref;
+
+       for (int i = 0; i < fFilterList.CountItems(); i++) {
+               BMailFilterAction action = 
fFilterList.ItemAt(i)->HeaderFetched(outRef,
+                       file, attributes);
+               if (action == B_DELETE_MAIL_ACTION) {
+                       // We have to delete the message
+                       BEntry entry(&ref);
+                       status_t status = entry.Remove();
+                       if (status != B_OK) {
+                               fprintf(stderr, 
"BMailProtocol::NotifyHeaderFetched(): could "
+                                       "not delete mail: %s\n", 
strerror(status));
+                       }
+                       return B_DELETE_MAIL_ACTION;
+               }
+       }
+
+       if (ref == outRef)
+               return B_NO_MAIL_ACTION;
+
+       // We have to rename the file
+       node_ref newParentRef;
+       newParentRef.device = outRef.device;
+       newParentRef.node = outRef.directory;
+
+       BDirectory newParent(&newParentRef);
+       status_t status = newParent.InitCheck();
+       BString workerName;
+       if (status == B_OK) {
+               int32 uniqueNumber = 1;
+               do {
+                       workerName = outRef.name;
+                       if (uniqueNumber > 1)
+                               workerName << "_" << uniqueNumber;
+
+                       // TODO: support copying to another device!
+                       BEntry entry(&ref);
+                       status = entry.Rename(workerName);
+
+                       uniqueNumber++;
+               } while (status == B_FILE_EXISTS);
+       }
+
+       if (status != B_OK) {
+               fprintf(stderr, "BMailProtocol::NotifyHeaderFetched(): could 
not "
+                       "rename mail (%s)! (should be: %s)\n", strerror(status),
+                       workerName.String());
+       }
+
+       ref = outRef;
+       ref.set_name(workerName.String());
+
+       return B_MOVE_MAIL_ACTION;
+}
+
+
+void
+BMailProtocol::_NotifyBodyFetched(const entry_ref& ref, BFile& file,
+       BMessage& attributes)
+{
+       for (int i = 0; i < fFilterList.CountItems(); i++)
+               fFilterList.ItemAt(i)->BodyFetched(ref, file, attributes);
+}
+
+
 // #pragma mark -
 
 


Other related posts:

  • » [haiku-commits] BRANCH axeld-github.imap [002f094] src/kits/mail src/add-ons/mail_daemon/inbound_protocols/imap headers/os/add-ons/mail_daemon src/kits/app src/add-ons/mail_daemon/inbound_filters/spam_filter - axeld-github . imap