xref: /haiku/src/add-ons/mail_daemon/inbound_protocols/imap/IMAPProtocol.cpp (revision adbe8fc944d2568ba87d7603e921115830ef1416)
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