1 /*
2  * mbsync - mailbox synchronizer
3  * Copyright (C) 2000-2002 Michael R. Elkins <me@mutt.org>
4  * Copyright (C) 2002-2006,2010-2012 Oswald Buddenhagen <ossi@users.sf.net>
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 2 of the License, or
9  *  (at your option) any later version.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  *
19  * As a special exception, mbsync may be linked with the OpenSSL library,
20  * despite that library's more restrictive license.
21  */
22 
23 #ifndef DRIVER_H
24 #define DRIVER_H
25 
26 #include "config.h"
27 
28 typedef struct driver driver_t;
29 
30 #define FAIL_TEMP   0  /* Retry immediately (also: no error) */
31 #define FAIL_WAIT   1  /* Retry after some time (if at all) */
32 #define FAIL_FINAL  2  /* Don't retry until store reconfiguration */
33 
34 #define STORE_CONF \
35 	struct store_conf *next; \
36 	char *name; \
37 	driver_t *driver; \
38 	const char *flat_delim; \
39 	const char *map_inbox; \
40 	const char *trash; \
41 	uint max_size;  /* off_t is overkill */ \
42 	char trash_remote_new, trash_only_new;
43 
44 typedef struct store_conf {
45 	STORE_CONF
46 } store_conf_t;
47 
48 /* For message->flags */
49 /* Keep the mailbox driver flag definitions in sync: */
50 /* grep for MAILBOX_DRIVER_FLAG */
51 /* The order is according to alphabetical maildir flag sort */
52 #define F_DRAFT	     (1<<0) /* Draft */
53 #define F_FLAGGED    (1<<1) /* Flagged */
54 #define F_FORWARDED  (1<<2) /* Passed */
55 #define F_ANSWERED   (1<<3) /* Replied */
56 #define F_SEEN       (1<<4) /* Seen */
57 #define F_DELETED    (1<<5) /* Trashed */
58 #define NUM_FLAGS 6
59 
60 /* For message->status */
61 #define M_RECENT       (1<<0) /* unsyncable flag; maildir_* depend on this being 1<<0 */
62 #define M_DEAD         (1<<1) /* expunged */
63 #define M_FLAGS        (1<<2) /* flags fetched */
64 // The following are only for IMAP FETCH response parsing
65 #define M_DATE         (1<<3)
66 #define M_SIZE         (1<<4)
67 #define M_BODY         (1<<5)
68 #define M_HEADER       (1<<6)
69 
70 #define TUIDL 12
71 
72 #define MESSAGE(message) \
73 	message *next; \
74 	struct sync_rec *srec; \
75 	char *msgid;  /* owned */ \
76 	/* string_list_t *keywords; */ \
77 	uint size;  /* zero implies "not fetched" */ \
78 	uint uid; \
79 	uchar flags, status; \
80 	char tuid[TUIDL];
81 
82 typedef struct message {
83 	MESSAGE(struct message)
84 } message_t;
85 
86 // For driver_t->prepare_load_box(), which may amend the passed flags.
87 // The drivers don't use the first two, but may set them if loading the
88 // particular range is required to handle some other flag; note that these
89 // ranges may overlap.
90 #define OPEN_OLD        (1<<0)  // Paired messages *in* this store.
91 #define OPEN_NEW        (1<<1)  // Messages (possibly) not yet propagated *from* this store.
92 #define OPEN_FLAGS      (1<<2)  // Note that fetch_msg() gets the flags regardless.
93 #define OPEN_NEW_SIZE   (1<<4)
94 #define OPEN_EXPUNGE    (1<<5)
95 #define OPEN_SETFLAGS   (1<<6)
96 #define OPEN_APPEND     (1<<7)
97 #define OPEN_FIND       (1<<8)
98 #define OPEN_OLD_IDS    (1<<9)
99 
100 #define UIDVAL_BAD ((uint)-1)
101 
102 #define STORE(store) \
103 	store *next; \
104 	driver_t *driver; \
105 	store##_conf *conf;  /* foreign */
106 
107 typedef struct store {
108 	STORE(struct store)
109 } store_t;
110 
111 typedef struct {
112 	char *data;
113 	uint len;
114 	time_t date;
115 	uchar flags;
116 } msg_data_t;
117 
118 #define DRV_OK          0
119 /* Message went missing, or mailbox is full, etc. */
120 #define DRV_MSG_BAD     1
121 /* Something is wrong with the current mailbox - probably it is somehow inaccessible. */
122 #define DRV_BOX_BAD     2
123 /* Failed to connect store. */
124 #define DRV_STORE_BAD   3
125 /* The command has been cancel()ed or cancel_store()d. */
126 #define DRV_CANCELED    4
127 
128 /* All memory belongs to the driver's user, unless stated otherwise. */
129 // If the driver is NOT DRV_ASYNC, memory owned by the driver returned
130 // through callbacks MUST remain valid until a related subsequent command
131 // is invoked, as the proxy driver may deliver these pointers with delay.
132 
133 /*
134    This flag says that the driver CAN store messages with CRLFs,
135    not that it must. The lack of it OTOH implies that it CANNOT,
136    and as CRLF is the canonical format, we convert.
137 */
138 #define DRV_CRLF        1
139 /*
140    This flag says that the driver will act upon (DFlags & VERBOSE).
141 */
142 #define DRV_VERBOSE     2
143 /*
144    This flag says that the driver operates asynchronously.
145 */
146 #define DRV_ASYNC       4
147 
148 #define LIST_INBOX      1
149 #define LIST_PATH       2
150 #define LIST_PATH_MAYBE 4
151 
152 #define xint uint  // For auto-generation of appropriate printf() formats.
153 
154 struct driver {
155 	/* Return driver capabilities. */
156 	xint (*get_caps)( store_t *ctx );
157 
158 	/* Parse configuration. */
159 	int (*parse_store)( conffile_t *cfg, store_conf_t **storep );
160 
161 	/* Close remaining server connections. All stores must be discarded first. */
162 	void (*cleanup)( void );
163 
164 	/* Allocate a store with the given configuration. This is expected to
165 	 * return quickly, and must not fail. */
166 	store_t *(*alloc_store)( store_conf_t *conf, const char *label );
167 
168 	/* When this callback is invoked (at most once per store), the store is fubar;
169 	 * call cancel_store() to dispose of it. */
170 	void (*set_bad_callback)( store_t *ctx, void (*cb)( void *aux ), void *aux );
171 
172 	/* Open/connect the store. This may recycle existing server connections. */
173 	void (*connect_store)( store_t *ctx,
174 	                       void (*cb)( int sts, void *aux ), void *aux );
175 
176 	/* Discard the store. Underlying server connection may be kept alive. */
177 	void (*free_store)( store_t *ctx );
178 
179 	/* Discard the store after a bad_callback. The server connections will be closed.
180 	 * Pending commands will have their callbacks synchronously invoked with DRV_CANCELED. */
181 	void (*cancel_store)( store_t *ctx );
182 
183 	/* List the mailboxes in this store. Flags are ORed LIST_* values.
184 	 * The returned box list remains owned by the driver. */
185 	void (*list_store)( store_t *ctx, int flags,
186 	                    void (*cb)( int sts, string_list_t *boxes, void *aux ), void *aux );
187 
188 	/* Invoked before open_box(), this informs the driver which box is to be opened. */
189 	int (*select_box)( store_t *ctx, const char *name );
190 
191 	/* Get the selected box' on-disk path, if applicable, null otherwise. */
192 	const char *(*get_box_path)( store_t *ctx );
193 
194 	/* Create the selected mailbox. */
195 	void (*create_box)( store_t *ctx,
196 	                    void (*cb)( int sts, void *aux ), void *aux );
197 
198 	/* Open the selected mailbox.
199 	 * Note that this should not directly complain about failure to open. */
200 	void (*open_box)( store_t *ctx,
201 	                  void (*cb)( int sts, uint uidvalidity, void *aux ), void *aux );
202 
203 	/* Return the minimal UID the next stored message will have. */
204 	uint (*get_uidnext)( store_t *ctx );
205 
206 	/* Return the flags that can be stored in the selected mailbox. */
207 	xint (*get_supported_flags)( store_t *ctx );
208 
209 	/* Confirm that the open mailbox is empty. */
210 	int (*confirm_box_empty)( store_t *ctx );
211 
212 	/* Delete the open mailbox. The mailbox is expected to be empty.
213 	 * Subfolders of the mailbox are *not* deleted.
214 	 * Some artifacts of the mailbox may remain, but they won't be
215 	 * recognized as a mailbox any more. */
216 	void (*delete_box)( store_t *ctx,
217 	                    void (*cb)( int sts, void *aux ), void *aux );
218 
219 	/* Remove the last artifacts of the open mailbox, as far as possible. */
220 	int (*finish_delete_box)( store_t *ctx );
221 
222 	/* Invoked before load_box(), this informs the driver which operations (OP_*)
223 	 * will be performed on the mailbox. The driver may extend the set by implicitly
224 	 * needed or available operations. Returns this possibly extended set. */
225 	xint (*prepare_load_box)( store_t *ctx, xint opts );
226 
227 	/* Load the message attributes needed to perform the requested operations.
228 	 * Consider only messages with UIDs between minuid and maxuid (inclusive)
229 	 * and those named in the excs array (smaller than minuid).
230 	 * The driver takes ownership of the excs array.
231 	 * Messages starting with finduid need to have the TUID populated when OPEN_FIND is set.
232 	 * Messages up to pairuid need to have the Message-Id populated when OPEN_OLD_IDS is set.
233 	 * Messages up to newuid need to have the size populated when OPEN_OLD_SIZE is set;
234 	 * likewise messages above newuid when OPEN_NEW_SIZE is set.
235 	 * The returned message list remains owned by the driver. */
236 	void (*load_box)( store_t *ctx, uint minuid, uint maxuid, uint finduid, uint pairuid, uint newuid, uint_array_t excs,
237 	                  void (*cb)( int sts, message_t *msgs, int total_msgs, int recent_msgs, void *aux ), void *aux );
238 
239 	/* Fetch the contents and flags of the given message from the current mailbox.
240 	 * If minimal is non-zero, fetch only a placeholder for the requested message -
241 	 * ideally, this is precisely the header, but it may be more. */
242 	void (*fetch_msg)( store_t *ctx, message_t *msg, msg_data_t *data, int minimal,
243 	                   void (*cb)( int sts, void *aux ), void *aux );
244 
245 	/* Store the given message to either the current mailbox or the trash folder.
246 	 * If the new copy's UID can be immediately determined, return it, otherwise 0. */
247 	void (*store_msg)( store_t *ctx, msg_data_t *data, int to_trash,
248 	                   void (*cb)( int sts, uint uid, void *aux ), void *aux );
249 
250 	/* Index the messages which have newly appeared in the mailbox, including their
251 	 * temporary UID headers. This is needed if store_msg() does not guarantee returning
252 	 * a UID; otherwise the driver needs to implement only the OPEN_FIND flag.
253 	 * The returned message list remains owned by the driver. */
254 	void (*find_new_msgs)( store_t *ctx, uint newuid,
255 	                       void (*cb)( int sts, message_t *msgs, void *aux ), void *aux );
256 
257 	/* Add/remove the named flags to/from the given message. The message may be either
258 	 * a pre-fetched one (in which case the in-memory representation is updated),
259 	 * or it may be identifed by UID only. The operation may be delayed until commit()
260 	 * is called. */
261 	void (*set_msg_flags)( store_t *ctx, message_t *msg, uint uid, int add, int del,
262 	                       void (*cb)( int sts, void *aux ), void *aux );
263 
264 	/* Move the given message from the current mailbox to the trash folder.
265 	 * This may expunge the original message immediately, but it needn't to. */
266 	void (*trash_msg)( store_t *ctx, message_t *msg,
267 	                   void (*cb)( int sts, void *aux ), void *aux );
268 
269 	/* Expunge deleted messages from the current mailbox and close it.
270 	 * There is no need to explicitly close a mailbox if no expunge is needed. */
271 	void (*close_box)( store_t *ctx,
272 	                   void (*cb)( int sts, void *aux ), void *aux );
273 
274 	/* Cancel queued commands which are not in flight yet; they will have their
275 	 * callbacks invoked with DRV_CANCELED. Afterwards, wait for the completion of
276 	 * the in-flight commands. If the store is canceled before this command completes,
277 	 * the callback will *not* be invoked. */
278 	void (*cancel_cmds)( store_t *ctx,
279 	                     void (*cb)( void *aux ), void *aux );
280 
281 	/* Commit any pending set_msg_flags() commands. */
282 	void (*commit_cmds)( store_t *ctx );
283 
284 	/* Get approximate amount of memory occupied by the driver. */
285 	uint (*get_memory_usage)( store_t *ctx );
286 
287 	/* Get the FAIL_* state of the driver. */
288 	int (*get_fail_state)( store_conf_t *conf );
289 };
290 
291 uint count_generic_messages( message_t * );
292 void free_generic_messages( message_t * );
293 
294 void parse_generic_store( store_conf_t *store, conffile_t *cfg, const char *type );
295 
296 store_t *proxy_alloc_store( store_t *real_ctx, const char *label );
297 
298 #define N_DRIVERS 2
299 extern driver_t *drivers[N_DRIVERS];
300 extern driver_t maildir_driver, imap_driver, proxy_driver;
301 
302 #endif
303