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