1/* 2 * Copyright 2011, Haiku, Inc. All rights reserved. 3 * Copyright 2011, Clemens Zeidler <haiku@clemens-zeidler.de> 4 * Distributed under the terms of the MIT License. 5 */ 6 7 8#include "IMAPRootInboundProtocol.h" 9 10#include <Messenger.h> 11 12#include "IMAPFolders.h" 13 14 15IMAPRootInboundProtocol::IMAPRootInboundProtocol(BMailAccountSettings* settings) 16 : 17 IMAPInboundProtocol(settings, "INBOX") 18{ 19} 20 21 22IMAPRootInboundProtocol::~IMAPRootInboundProtocol() 23{ 24 _ShutdownChilds(); 25} 26 27 28status_t 29IMAPRootInboundProtocol::Connect(const char* server, const char* username, 30 const char* password, bool useSSL, int32 port) 31{ 32 status_t status = IMAPInboundProtocol::Connect(server, username, password, 33 useSSL, port); 34 if (status != B_OK) 35 return status; 36 37 IMAPFolders folder(fIMAPMailbox); 38 FolderList folders; 39 folder.GetFolders(folders); 40 for (unsigned int i = 0; i < folders.size(); i++) { 41 if (!folders[i].subscribed || folders[i].folder == "INBOX") 42 continue; 43 44 IMAPInboundProtocol* inboundProtocol = new IMAPInboundProtocol( 45 &fAccountSettings, folders[i].folder); 46 inboundProtocol->SetMailNotifier(fMailNotifier->Clone()); 47 48 InboundProtocolThread* inboundThread = new InboundProtocolThread( 49 inboundProtocol); 50 inboundThread->Run(); 51 52 fProtocolThreadList.AddItem(inboundThread); 53 } 54 return status; 55} 56 57 58status_t 59IMAPRootInboundProtocol::Disconnect() 60{ 61 status_t status = IMAPInboundProtocol::Disconnect(); 62 _ShutdownChilds(); 63 return status; 64} 65 66 67void 68IMAPRootInboundProtocol::SetStopNow() 69{ 70 for (int32 i = 0; i < fProtocolThreadList.CountItems(); i++) 71 fProtocolThreadList.ItemAt(i)->SetStopNow(); 72 IMAPInboundProtocol::SetStopNow(); 73} 74 75 76status_t 77IMAPRootInboundProtocol::SyncMessages() 78{ 79 for (int32 i = 0; i < fProtocolThreadList.CountItems(); i++) 80 fProtocolThreadList.ItemAt(i)->SyncMessages(); 81 return IMAPInboundProtocol::SyncMessages(); 82} 83 84 85status_t 86IMAPRootInboundProtocol::FetchBody(const entry_ref& ref) 87{ 88 if (InterestingEntry(ref)) 89 return IMAPInboundProtocol::FetchBody(ref); 90 InboundProtocolThread* thread = _FindThreadFor(ref); 91 if (!thread) 92 return B_BAD_VALUE; 93 thread->FetchBody(ref); 94 return B_OK; 95} 96 97 98status_t 99IMAPRootInboundProtocol::MarkMessageAsRead(const entry_ref& ref, 100 read_flags flag) 101{ 102 if (InterestingEntry(ref)) 103 return IMAPInboundProtocol::MarkMessageAsRead(ref, flag); 104 InboundProtocolThread* thread = _FindThreadFor(ref); 105 if (!thread) 106 return B_BAD_VALUE; 107 thread->MarkMessageAsRead(ref, flag); 108 return B_OK; 109} 110 111 112status_t 113IMAPRootInboundProtocol::DeleteMessage(const entry_ref& ref) 114{ 115 if (InterestingEntry(ref)) 116 return IMAPInboundProtocol::DeleteMessage(ref); 117 InboundProtocolThread* thread = _FindThreadFor(ref); 118 if (!thread) 119 return B_BAD_VALUE; 120 thread->DeleteMessage(ref); 121 return B_OK; 122} 123 124 125status_t 126IMAPRootInboundProtocol::AppendMessage(const entry_ref& ref) 127{ 128 if (InterestingEntry(ref)) 129 return IMAPInboundProtocol::AppendMessage(ref); 130 InboundProtocolThread* thread = _FindThreadFor(ref); 131 if (!thread) 132 return B_BAD_VALUE; 133 thread->AppendMessage(ref); 134 return B_OK; 135} 136 137 138status_t 139IMAPRootInboundProtocol::DeleteMessage(node_ref& node) 140{ 141 status_t status = IMAPInboundProtocol::DeleteMessage(node); 142 if (status == B_OK) 143 return status; 144 for (int32 i = 0; i < fProtocolThreadList.CountItems(); i++) 145 fProtocolThreadList.ItemAt(i)->TriggerFileDeleted(node); 146 return B_OK; 147} 148 149 150void 151IMAPRootInboundProtocol::_ShutdownChilds() 152{ 153 BMessage reply; 154 for (int32 i = 0; i < fProtocolThreadList.CountItems(); i++) { 155 InboundProtocolThread* thread = fProtocolThreadList.ItemAt(i); 156 MailProtocol* protocol = thread->Protocol(); 157 158 thread->SetStopNow(); 159 BMessenger(thread).SendMessage(B_QUIT_REQUESTED, &reply); 160 161 delete protocol; 162 } 163 fProtocolThreadList.MakeEmpty(); 164} 165 166 167InboundProtocolThread* 168IMAPRootInboundProtocol::_FindThreadFor(const entry_ref& ref) 169{ 170 for (int32 i = 0; i < fProtocolThreadList.CountItems(); i++) { 171 InboundProtocolThread* thread = fProtocolThreadList.ItemAt(i); 172 IMAPInboundProtocol* protocol 173 = (IMAPInboundProtocol*)thread->Protocol(); 174 if (protocol->InterestingEntry(ref)) 175 return thread; 176 } 177 return NULL; 178} 179 180 181// #pragma mark - 182 183 184InboundProtocol* 185instantiate_inbound_protocol(BMailAccountSettings* settings) 186{ 187 return new IMAPRootInboundProtocol(settings); 188} 189