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