1/*
2 * Copyright 2010-2015, Haiku Inc. All Rights Reserved.
3 * Copyright 2010 Clemens Zeidler. All rights reserved.
4 *
5 * Distributed under the terms of the MIT License.
6 */
7#ifndef COMMANDS_H
8#define COMMANDS_H
9
10
11#include <StringList.h>
12
13#include <vector>
14
15#include "Response.h"
16
17
18namespace IMAP {
19
20
21struct MessageEntry {
22	MessageEntry()
23		:
24		uid(0),
25		flags(0)
26	{
27	}
28
29	uint32	uid;
30	uint32	flags;
31	uint32	size;
32};
33typedef std::vector<MessageEntry> MessageEntryList;
34
35typedef std::vector<uint32> MessageUIDList;
36
37enum MessageFlags {
38	kSeen				= 0x01,
39	kAnswered			= 0x02,
40	kFlagged			= 0x04,
41	kDeleted			= 0x08,
42	kDraft				= 0x10,
43	// \Recent doesn't really have any useful meaning, so we just ignore it
44
45	kServerFlagsMask	= 0x0000ffff
46};
47
48
49class Handler {
50public:
51								Handler();
52	virtual						~Handler();
53
54	virtual	bool				HandleUntagged(Response& response) = 0;
55};
56
57
58class Command {
59public:
60	virtual						~Command();
61
62	virtual	BString				CommandString() = 0;
63	virtual	status_t			HandleTagged(Response& response);
64};
65
66
67class RawCommand : public Command {
68public:
69								RawCommand(const BString& command);
70
71	virtual	BString				CommandString();
72
73private:
74			BString				fCommand;
75};
76
77
78class LoginCommand : public Command, public Handler {
79public:
80								LoginCommand(const char* user,
81									const char* password);
82
83	virtual	BString				CommandString();
84	virtual	bool				HandleUntagged(Response& response);
85
86			const ArgumentList&	Capabilities() const { return fCapabilities; }
87
88private:
89			const char*			fUser;
90			const char*			fPassword;
91			ArgumentList		fCapabilities;
92};
93
94
95class SelectCommand : public Command, public Handler {
96public:
97								SelectCommand();
98								SelectCommand(const char* mailboxName);
99
100	virtual	BString				CommandString();
101	virtual	bool				HandleUntagged(Response& response);
102
103			void				SetTo(const char* mailboxName);
104			uint32				NextUID() { return fNextUID; }
105			uint32				UIDValidity() { return fUIDValidity; }
106
107private:
108			BString				fMailboxName;
109			uint32				fNextUID;
110			uint32				fUIDValidity;
111};
112
113
114class CapabilityHandler : public Command, public Handler {
115public:
116	virtual	BString				CommandString();
117	virtual	bool				HandleUntagged(Response& response);
118
119			const ArgumentList&	Capabilities() const { return fCapabilities; }
120
121private:
122			ArgumentList		fCapabilities;
123};
124
125
126class FetchMessageEntriesCommand : public Command, public Handler {
127public:
128								FetchMessageEntriesCommand(
129									MessageEntryList& entries, uint32 from,
130									uint32 to, bool uids);
131
132			BString				CommandString();
133	virtual	bool				HandleUntagged(Response& response);
134
135private:
136			MessageEntryList&	fEntries;
137			uint32				fFrom;
138			uint32				fTo;
139			bool				fUIDs;
140};
141
142
143enum FetchFlags {
144	kFetchHeader	= 0x01,
145	kFetchBody		= 0x02,
146	kFetchAll		= kFetchHeader | kFetchBody,
147	kFetchFlags		= 0x04,
148};
149
150
151class FetchListener {
152public:
153	virtual	bool				FetchData(uint32 fetchFlags, BDataIO& stream,
154									size_t& length) = 0;
155	virtual void				FetchedData(uint32 fetchFlags, uint32 uid,
156									uint32 flags) = 0;
157};
158
159
160class FetchCommand : public Command, public Handler,
161	public LiteralHandler {
162public:
163								FetchCommand(uint32 from, uint32 to,
164									uint32 fetchFlags);
165								FetchCommand(MessageUIDList& uids,
166									size_t max, uint32 fetchFlags);
167
168			void				SetListener(FetchListener* listener);
169			FetchListener*		Listener() const { return fListener; }
170
171	virtual	BString				CommandString();
172	virtual	bool				HandleUntagged(Response& response);
173	virtual bool				HandleLiteral(Response& response,
174									ArgumentList& arguments, BDataIO& stream,
175									size_t& length);
176
177private:
178			BString				fSequence;
179			uint32				fFlags;
180			FetchListener*		fListener;
181};
182
183
184class SetFlagsCommand : public Command, public Handler {
185public:
186								SetFlagsCommand(uint32 uid, uint32 flags);
187
188	virtual	BString				CommandString();
189	virtual	bool				HandleUntagged(Response& response);
190
191private:
192			uint32				fUID;
193			uint32				fFlags;
194};
195
196
197#if 0
198class AppendCommand : public IMAPMailboxCommand {
199public:
200								AppendCommand(IMAPMailbox& mailbox,
201									BPositionIO& message, off_t size,
202									int32 flags, time_t time);
203
204			BString				CommandString();
205			bool				HandleUntagged(const BString& response);
206
207private:
208			BPositionIO&		fMessageData;
209			off_t				fDataSize;
210			int32				fFlags;
211			time_t				fTime;
212};
213#endif
214
215
216class ExistsListener {
217public:
218	virtual	void				MessageExistsReceived(uint32 count) = 0;
219};
220
221
222class ExistsHandler : public Handler {
223public:
224								ExistsHandler();
225
226			void				SetListener(ExistsListener* listener);
227			ExistsListener*		Listener() const { return fListener; }
228
229	virtual	bool				HandleUntagged(Response& response);
230
231private:
232			ExistsListener*		fListener;
233};
234
235
236/*! Just send a expunge command to delete kDeleted flagged messages. The
237	response is handled by the unsolicited ExpungeHandler which is installed
238	all the time.
239*/
240class ExpungeCommand : public Command {
241public:
242								ExpungeCommand();
243
244			BString				CommandString();
245};
246
247
248class ExpungeListener {
249public:
250	virtual	void				MessageExpungeReceived(uint32 index) = 0;
251};
252
253
254class ExpungeHandler : public Handler {
255public:
256								ExpungeHandler();
257
258			void				SetListener(ExpungeListener* listener);
259			ExpungeListener*	Listener() const { return fListener; }
260
261	virtual	bool				HandleUntagged(Response& response);
262
263private:
264			ExpungeListener*	fListener;
265};
266
267
268#if 0
269class FlagsHandler : public Handler {
270public:
271								FlagsHandler(IMAPMailbox& mailbox);
272
273			bool				HandleUntagged(const BString& response);
274};
275#endif
276
277
278class ListCommand : public Command, public Handler {
279public:
280								ListCommand(const char* prefix,
281									bool subscribedOnly);
282
283	virtual	BString				CommandString();
284	virtual	bool				HandleUntagged(Response& response);
285
286			const BStringList&	FolderList();
287			const BString&		Separator() { return fSeparator; }
288
289private:
290			const char*			_Command() const;
291
292private:
293			RFC3501Encoding		fEncoding;
294			const char*			fPrefix;
295			BStringList			fFolders;
296			BString				fSeparator;
297			bool				fSubscribedOnly;
298};
299
300
301class SubscribeCommand : public Command {
302public:
303								SubscribeCommand(const char* mailboxName);
304
305			BString				CommandString();
306
307private:
308			BString				fMailboxName;
309};
310
311
312class UnsubscribeCommand : public Command {
313public:
314								UnsubscribeCommand(const char* mailboxName);
315
316			BString				CommandString();
317
318private:
319			BString				fMailboxName;
320};
321
322
323class GetQuotaCommand : public Command, public Handler {
324public:
325								GetQuotaCommand(
326									const char* mailboxName = "INBOX");
327
328			BString				CommandString();
329			bool				HandleUntagged(Response& response);
330
331			uint64				UsedStorage();
332			uint64				TotalStorage();
333private:
334			BString				fMailboxName;
335
336			uint64				fUsedStorage;
337			uint64				fTotalStorage;
338};
339
340
341}	// namespace IMAP
342
343
344#endif // COMMANDS_H
345