1 /* 2 * Copyright 2012-2016, Axel Dörfler, axeld@pinc-software.de. 3 * Distributed under the terms of the MIT License. 4 */ 5 #ifndef IMAP_FOLDER_H 6 #define IMAP_FOLDER_H 7 8 9 #include <hash_map> 10 #include <hash_set> 11 12 #include <sys/stat.h> 13 14 #include <Entry.h> 15 #include <Node.h> 16 #include <Handler.h> 17 #include <String.h> 18 19 #include <locks.h> 20 21 #include "Commands.h" 22 23 24 class BFile; 25 class IMAPProtocol; 26 27 28 struct MessageToken { 29 BString mailboxName; 30 uint32 uidValidity; 31 uint32 uid; 32 }; 33 34 // Additional local only message flags 35 enum FolderMessageFlags { 36 kPartialMessage = 0x00010000, 37 }; 38 39 40 class FolderListener { 41 public: 42 virtual uint32 MessageAdded(const MessageToken& fromToken, 43 const entry_ref& ref) = 0; 44 virtual void MessageDeleted(const MessageToken& token) = 0; 45 46 virtual void MessageFlagsChanged(const MessageToken& token, 47 const entry_ref& ref, uint32 oldFlags, 48 uint32 newFlags) = 0; 49 }; 50 51 52 class IMAPFolder : public BHandler { 53 public: 54 IMAPFolder(IMAPProtocol& protocol, 55 const BString& mailboxName, 56 const entry_ref& ref); 57 virtual ~IMAPFolder(); 58 59 status_t Init(); 60 61 const BString& MailboxName() const { return fMailboxName; } 62 ino_t NodeID() const { return fNodeID; } 63 64 void SetListener(FolderListener* listener); 65 void SetUIDValidity(uint32 uidValidity); 66 67 uint32 LastUID() const { return fLastUID; } 68 69 status_t GetMessageEntryRef(uint32 uid, entry_ref& ref); 70 status_t GetMessageUID(const entry_ref& ref, 71 uint32& uid) const; 72 uint32 MessageFlags(uint32 uid); 73 74 void SyncMessageFlags(uint32 uid, 75 uint32 mailboxFlags); 76 void MessageEntriesFetched(); 77 78 status_t StoreMessage(uint32 fetchFlags, BDataIO& stream, 79 size_t& length, entry_ref& ref, 80 BFile& file); 81 void MessageStored(entry_ref& ref, BFile& file, 82 uint32 fetchFlags, uint32 uid, 83 uint32 flags); 84 85 void RegisterPendingBodies( 86 IMAP::MessageUIDList& uids, 87 const BMessenger* replyTo); 88 status_t StoreBody(uint32 uid, BDataIO& stream, 89 size_t& length, entry_ref& ref, 90 BFile& file); 91 void BodyStored(entry_ref& ref, BFile& file, 92 uint32 uid); 93 void StoringBodyFailed(const entry_ref& ref, 94 uint32 uid, status_t error); 95 96 void DeleteMessage(uint32 uid); 97 98 virtual void MessageReceived(BMessage* message); 99 100 private: 101 void _WaitForFolderState(); 102 void _InitializeFolderState(); 103 void _ReadFolderState(); 104 static status_t _ReadFolderState(void* self); 105 106 const MessageToken _Token(uint32 uid) const; 107 void _NotifyStoredBody(const entry_ref& ref, 108 uint32 uid, status_t status); 109 status_t _GetMessageEntryRef(uint32 uid, 110 entry_ref& ref) const; 111 status_t _DeleteLocalMessage(uint32 uid); 112 113 void _IMAPToMailFlags(uint32 flags, 114 BMessage& attributes); 115 status_t _MailToIMAPFlags(BNode& node, uint32& flags); 116 void _TestMessageFlags(uint32 previousFlags, 117 uint32 mailboxFlags, uint32 currentFlags, 118 uint32 testFlag, uint32& nextFlags); 119 120 uint32 _ReadUniqueID(BNode& node) const; 121 status_t _WriteUniqueID(BNode& node, uint32 uid) const; 122 uint32 _ReadUniqueIDValidity(BNode& node) const; 123 status_t _WriteUniqueIDValidity(BNode& node) const; 124 uint32 _ReadFlags(BNode& node) const; 125 status_t _WriteFlags(BNode& node, uint32 flags) const; 126 127 uint32 _ReadUInt32(BNode& node, 128 const char* attribute) const; 129 status_t _WriteUInt32(BNode& node, 130 const char* attribute, uint32 value) const; 131 132 status_t _WriteStream(BFile& file, BDataIO& stream, 133 size_t& length) const; 134 135 private: 136 typedef std::vector<BMessenger> MessengerList; 137 #if __GNUC__ >= 4 138 typedef __gnu_cxx::hash_map<uint32, uint32> UIDToFlagsMap; 139 typedef __gnu_cxx::hash_map<uint32, entry_ref> UIDToRefMap; 140 typedef __gnu_cxx::hash_map<uint32, MessengerList> MessengerMap; 141 typedef __gnu_cxx::hash_set<uint32> UIDSet; 142 #else 143 typedef std::hash_map<uint32, uint32> UIDToFlagsMap; 144 typedef std::hash_map<uint32, entry_ref> UIDToRefMap; 145 typedef std::hash_map<uint32, MessengerList> MessengerMap; 146 typedef std::hash_set<uint32> UIDSet; 147 #endif 148 149 IMAPProtocol& fProtocol; 150 const entry_ref fRef; 151 BString fMailboxName; 152 ino_t fNodeID; 153 uint32 fUIDValidity; 154 uint32 fLastUID; 155 FolderListener* fListener; 156 mutex fLock; 157 mutex fFolderStateLock; 158 thread_id fReadFolderStateThread; 159 bool fFolderStateInitialized; 160 bool fQuitFolderState; 161 UIDToRefMap fRefMap; 162 UIDToFlagsMap fFlagsMap; 163 UIDSet fSynchronizedUIDsSet; 164 UIDToFlagsMap fPendingFlagsMap; 165 MessengerMap fPendingBodies; 166 }; 167 168 169 #endif // IMAP_FOLDER_H 170