1186c96d5SAxel Dörfler /* 2186c96d5SAxel Dörfler * Copyright 2013, Axel Dörfler, axeld@pinc-software.de. 3186c96d5SAxel Dörfler * Distributed under the terms of the MIT License. 4186c96d5SAxel Dörfler */ 5186c96d5SAxel Dörfler 6186c96d5SAxel Dörfler 7186c96d5SAxel Dörfler #include "IMAPProtocol.h" 8186c96d5SAxel Dörfler 9186c96d5SAxel Dörfler #include <Directory.h> 10186c96d5SAxel Dörfler 11186c96d5SAxel Dörfler #include "IMAPConnectionWorker.h" 12186c96d5SAxel Dörfler 13186c96d5SAxel Dörfler 14186c96d5SAxel Dörfler IMAPProtocol::IMAPProtocol(const BMailAccountSettings& settings) 15186c96d5SAxel Dörfler : 16186c96d5SAxel Dörfler BInboundMailProtocol(settings), 17186c96d5SAxel Dörfler fSettings(settings.InboundSettings()) 18186c96d5SAxel Dörfler { 19186c96d5SAxel Dörfler BPath destination = fSettings.Destination(); 20186c96d5SAxel Dörfler 21186c96d5SAxel Dörfler status_t status = create_directory(destination.Path(), 0755); 22186c96d5SAxel Dörfler if (status != B_OK) { 23186c96d5SAxel Dörfler fprintf(stderr, "imap: Could not create destination directory %s: %s\n", 24186c96d5SAxel Dörfler destination.Path(), strerror(status)); 25186c96d5SAxel Dörfler } 26186c96d5SAxel Dörfler 27186c96d5SAxel Dörfler PostMessage(B_READY_TO_RUN); 28186c96d5SAxel Dörfler } 29186c96d5SAxel Dörfler 30186c96d5SAxel Dörfler 31186c96d5SAxel Dörfler IMAPProtocol::~IMAPProtocol() 32186c96d5SAxel Dörfler { 33186c96d5SAxel Dörfler } 34186c96d5SAxel Dörfler 35186c96d5SAxel Dörfler 36186c96d5SAxel Dörfler status_t 37*adbe8fc9SAxel Dörfler IMAPProtocol::CheckSubscribedFolders(IMAP::Protocol& protocol) 38*adbe8fc9SAxel Dörfler { 39*adbe8fc9SAxel Dörfler // Get list of subscribed folders 40*adbe8fc9SAxel Dörfler 41*adbe8fc9SAxel Dörfler StringList folders; 42*adbe8fc9SAxel Dörfler status_t status = protocol.GetSubscribedFolders(folders); 43*adbe8fc9SAxel Dörfler if (status != B_OK) 44*adbe8fc9SAxel Dörfler return status; 45*adbe8fc9SAxel Dörfler 46*adbe8fc9SAxel Dörfler // Determine how many new mailboxes we have 47*adbe8fc9SAxel Dörfler 48*adbe8fc9SAxel Dörfler StringList::iterator iterator = folders.begin(); 49*adbe8fc9SAxel Dörfler for (; iterator != folders.end(); iterator++) { 50*adbe8fc9SAxel Dörfler if (fKnownMailboxes.find(*iterator) != fKnownMailboxes.end()) 51*adbe8fc9SAxel Dörfler iterator = folders.erase(iterator); 52*adbe8fc9SAxel Dörfler } 53*adbe8fc9SAxel Dörfler 54*adbe8fc9SAxel Dörfler if (fSettings.IdleMode()) { 55*adbe8fc9SAxel Dörfler // Create connection workers as allowed 56*adbe8fc9SAxel Dörfler 57*adbe8fc9SAxel Dörfler int32 totalMailboxes = fKnownMailboxes.size() + folders.size(); 58*adbe8fc9SAxel Dörfler 59*adbe8fc9SAxel Dörfler while (fWorkers.CountItems() < fSettings.MaxConnections() 60*adbe8fc9SAxel Dörfler && fWorkers.CountItems() < totalMailboxes) { 61*adbe8fc9SAxel Dörfler IMAPConnectionWorker* worker = new IMAPConnectionWorker(*this, 62*adbe8fc9SAxel Dörfler fSettings); 63*adbe8fc9SAxel Dörfler if (!fWorkers.AddItem(worker)) { 64*adbe8fc9SAxel Dörfler delete worker; 65*adbe8fc9SAxel Dörfler break; 66*adbe8fc9SAxel Dörfler } 67*adbe8fc9SAxel Dörfler 68*adbe8fc9SAxel Dörfler worker->Start(); 69*adbe8fc9SAxel Dörfler } 70*adbe8fc9SAxel Dörfler } 71*adbe8fc9SAxel Dörfler 72*adbe8fc9SAxel Dörfler // Distribute the new mailboxes to the existing workers 73*adbe8fc9SAxel Dörfler 74*adbe8fc9SAxel Dörfler int32 index = 0; 75*adbe8fc9SAxel Dörfler while (!folders.empty()) { 76*adbe8fc9SAxel Dörfler BString folder = folders[0]; 77*adbe8fc9SAxel Dörfler folders.erase(folders.begin()); 78*adbe8fc9SAxel Dörfler 79*adbe8fc9SAxel Dörfler fWorkers.ItemAt(index)->AddMailbox(folder); 80*adbe8fc9SAxel Dörfler fKnownMailboxes.insert(folder); 81*adbe8fc9SAxel Dörfler 82*adbe8fc9SAxel Dörfler index = (index + 1) % fWorkers.CountItems(); 83*adbe8fc9SAxel Dörfler } 84*adbe8fc9SAxel Dörfler 85*adbe8fc9SAxel Dörfler return B_OK; 86*adbe8fc9SAxel Dörfler } 87*adbe8fc9SAxel Dörfler 88*adbe8fc9SAxel Dörfler 89*adbe8fc9SAxel Dörfler status_t 90186c96d5SAxel Dörfler IMAPProtocol::SyncMessages() 91186c96d5SAxel Dörfler { 92186c96d5SAxel Dörfler puts("IMAP: sync"); 93*adbe8fc9SAxel Dörfler 94*adbe8fc9SAxel Dörfler if (fWorkers.IsEmpty()) { 95*adbe8fc9SAxel Dörfler // Create main (and possibly initial) connection worker 96*adbe8fc9SAxel Dörfler IMAPConnectionWorker* worker = new IMAPConnectionWorker(*this, 97*adbe8fc9SAxel Dörfler fSettings, true); 98*adbe8fc9SAxel Dörfler if (!fWorkers.AddItem(worker)) { 99*adbe8fc9SAxel Dörfler delete worker; 100*adbe8fc9SAxel Dörfler return B_NO_MEMORY; 101*adbe8fc9SAxel Dörfler } 102*adbe8fc9SAxel Dörfler 103*adbe8fc9SAxel Dörfler return worker->Start(); 104*adbe8fc9SAxel Dörfler } 105*adbe8fc9SAxel Dörfler 106*adbe8fc9SAxel Dörfler return B_OK; 107186c96d5SAxel Dörfler } 108186c96d5SAxel Dörfler 109186c96d5SAxel Dörfler 110186c96d5SAxel Dörfler status_t 111186c96d5SAxel Dörfler IMAPProtocol::FetchBody(const entry_ref& ref) 112186c96d5SAxel Dörfler { 113186c96d5SAxel Dörfler printf("IMAP: fetch body %s\n", ref.name); 114186c96d5SAxel Dörfler return B_ERROR; 115186c96d5SAxel Dörfler } 116186c96d5SAxel Dörfler 117186c96d5SAxel Dörfler 118186c96d5SAxel Dörfler status_t 119186c96d5SAxel Dörfler IMAPProtocol::MarkMessageAsRead(const entry_ref& ref, read_flags flags) 120186c96d5SAxel Dörfler { 121186c96d5SAxel Dörfler printf("IMAP: mark as read %s: %d\n", ref.name, flags); 122186c96d5SAxel Dörfler return B_ERROR; 123186c96d5SAxel Dörfler } 124186c96d5SAxel Dörfler 125186c96d5SAxel Dörfler 126186c96d5SAxel Dörfler status_t 127186c96d5SAxel Dörfler IMAPProtocol::DeleteMessage(const entry_ref& ref) 128186c96d5SAxel Dörfler { 129186c96d5SAxel Dörfler printf("IMAP: delete message %s\n", ref.name); 130186c96d5SAxel Dörfler return B_ERROR; 131186c96d5SAxel Dörfler } 132186c96d5SAxel Dörfler 133186c96d5SAxel Dörfler 134186c96d5SAxel Dörfler status_t 135186c96d5SAxel Dörfler IMAPProtocol::AppendMessage(const entry_ref& ref) 136186c96d5SAxel Dörfler { 137186c96d5SAxel Dörfler printf("IMAP: append message %s\n", ref.name); 138186c96d5SAxel Dörfler return B_ERROR; 139186c96d5SAxel Dörfler } 140186c96d5SAxel Dörfler 141186c96d5SAxel Dörfler 142186c96d5SAxel Dörfler void 143186c96d5SAxel Dörfler IMAPProtocol::MessageReceived(BMessage* message) 144186c96d5SAxel Dörfler { 145186c96d5SAxel Dörfler switch (message->what) { 146186c96d5SAxel Dörfler case B_READY_TO_RUN: 147186c96d5SAxel Dörfler ReadyToRun(); 148186c96d5SAxel Dörfler break; 149*adbe8fc9SAxel Dörfler 150*adbe8fc9SAxel Dörfler default: 151*adbe8fc9SAxel Dörfler BInboundMailProtocol::MessageReceived(message); 152*adbe8fc9SAxel Dörfler break; 153186c96d5SAxel Dörfler } 154186c96d5SAxel Dörfler } 155186c96d5SAxel Dörfler 156186c96d5SAxel Dörfler 157186c96d5SAxel Dörfler void 158186c96d5SAxel Dörfler IMAPProtocol::ReadyToRun() 159186c96d5SAxel Dörfler { 160*adbe8fc9SAxel Dörfler puts("IMAP: ready to run!"); 161*adbe8fc9SAxel Dörfler if (fSettings.IdleMode()) 162*adbe8fc9SAxel Dörfler SyncMessages(); 163186c96d5SAxel Dörfler } 164186c96d5SAxel Dörfler 165186c96d5SAxel Dörfler 166186c96d5SAxel Dörfler // #pragma mark - 167186c96d5SAxel Dörfler 168186c96d5SAxel Dörfler 169186c96d5SAxel Dörfler extern "C" BInboundMailProtocol* 170186c96d5SAxel Dörfler instantiate_inbound_protocol(const BMailAccountSettings& settings) 171186c96d5SAxel Dörfler { 172186c96d5SAxel Dörfler return new IMAPProtocol(settings); 173186c96d5SAxel Dörfler } 174