commit ca179c534915f4ca57fc444b62cce0a93c190b6f Author: Oswald Buddenhagen <o...@kde.org> Date: Sun Apr 3 18:21:46 2011 +0200
docs - insert "separator comments" between driver entry points - document driver API - document sync_vars_t parts that are stored in the sync state header src/drv_imap.c | 36 +++++++++++++++++++++++++++ src/isync.h | 62 ++++++++++++++++++++++++++++++++++++++++++++++- src/sync.c | 6 +++- 3 files changed, 100 insertions(+), 4 deletions(-) diff --git a/src/drv_imap.c b/src/drv_imap.c index 0c76a4c..da5b34e 100644 --- a/src/drv_imap.c +++ b/src/drv_imap.c @@ -144,6 +144,8 @@ struct imap_cmd { int tag; struct { + /* Will be called on each continuation request until it resets this pointer. + * Needs to invoke bad_callback and return -1 on error, otherwise return 0. */ int (*cont)( imap_store_t *ctx, struct imap_cmd *cmd, const char *prompt ); void (*done)( imap_store_t *ctx, struct imap_cmd *cmd, int response ); char *data; @@ -1248,6 +1250,8 @@ get_cmd_result_p2( imap_store_t *ctx, struct imap_cmd *cmd, int response ) } } +/******************* imap_cancel_store *******************/ + static void imap_cancel_store( store_t *gctx ) { @@ -1285,6 +1289,8 @@ imap_invoke_bad_callback( imap_store_t *ctx ) ctx->gen.bad_callback( ctx->gen.bad_callback_aux ); } +/******************* imap_disown_store & imap_own_store *******************/ + static store_t *unowned; static void @@ -1323,6 +1329,8 @@ imap_own_store( store_conf_t *conf ) return 0; } +/******************* imap_cleanup *******************/ + static void imap_cleanup_p2( imap_store_t *, struct imap_cmd *, int ); static void @@ -1345,6 +1353,8 @@ imap_cleanup_p2( imap_store_t *ctx, imap_cancel_store( &ctx->gen ); } +/******************* imap_open_store *******************/ + #ifdef HAVE_LIBSSL static int start_tls( imap_store_t *ctx ) @@ -1794,12 +1804,16 @@ imap_open_store_bail( imap_store_t *ctx ) cb( 0, aux ); } +/******************* imap_prepare_opts *******************/ + static void imap_prepare_opts( store_t *gctx, int opts ) { gctx->opts = opts; } +/******************* imap_select *******************/ + static void imap_select( store_t *gctx, int create, void (*cb)( int sts, void *aux ), void *aux ) @@ -1826,6 +1840,8 @@ imap_select( store_t *gctx, int create, "SELECT \"%s%s\"", prefix, gctx->name ); } +/******************* imap_load *******************/ + static int imap_submit_load( imap_store_t *, const char *, struct imap_cmd_refcounted_state *, struct imap_cmd ** ); static void imap_load_p2( imap_store_t *, struct imap_cmd *, int ); @@ -1906,6 +1922,8 @@ imap_load_p2( imap_store_t *ctx ATTR_UNUSED, struct imap_cmd *cmd, int response imap_refcounted_done( sts ); } +/******************* imap_fetch_msg *******************/ + static void imap_fetch_msg( store_t *ctx, message_t *msg, msg_data_t *data, void (*cb)( int sts, void *aux ), void *aux ) @@ -1920,6 +1938,8 @@ imap_fetch_msg( store_t *ctx, message_t *msg, msg_data_t *data, msg->uid, (msg->status & M_FLAGS) ? "" : "FLAGS " ); } +/******************* imap_set_flags *******************/ + static void imap_set_flags_p2( imap_store_t *, struct imap_cmd *, int ); static int @@ -1995,6 +2015,8 @@ imap_set_flags_p2( imap_store_t *ctx ATTR_UNUSED, struct imap_cmd *cmd, int resp imap_refcounted_done( sts ); } +/******************* imap_close *******************/ + static void imap_close( store_t *ctx, void (*cb)( int sts, void *aux ), void *aux ) @@ -2005,6 +2027,8 @@ imap_close( store_t *ctx, imap_exec( (imap_store_t *)ctx, &cmd->gen, imap_done_simple_box, "CLOSE" ); } +/******************* imap_trash_msg *******************/ + static void imap_trash_msg( store_t *gctx, message_t *msg, void (*cb)( int sts, void *aux ), void *aux ) @@ -2020,6 +2044,8 @@ imap_trash_msg( store_t *gctx, message_t *msg, msg->uid, ctx->prefix, gctx->conf->trash ); } +/******************* imap_store_msg *******************/ + static void imap_store_msg_p2( imap_store_t *, struct imap_cmd *, int ); static void @@ -2066,6 +2092,8 @@ imap_store_msg_p2( imap_store_t *ctx ATTR_UNUSED, struct imap_cmd *cmd, int resp cmdp->callback( response, cmdp->out_uid, cmdp->callback_aux ); } +/******************* imap_find_msg *******************/ + static void imap_find_msg_p2( imap_store_t *, struct imap_cmd *, int ); static void @@ -2095,6 +2123,8 @@ imap_find_msg_p2( imap_store_t *ctx ATTR_UNUSED, struct imap_cmd *cmd, int respo cmdp->out_uid, cmdp->callback_aux ); } +/******************* imap_list *******************/ + static void imap_list( store_t *gctx, void (*cb)( int sts, void *aux ), void *aux ) @@ -2107,6 +2137,8 @@ imap_list( store_t *gctx, "LIST \"\" \"%s%%\"", ctx->prefix ); } +/******************* imap_cancel *******************/ + static void imap_cancel( store_t *gctx, void (*cb)( void *aux ), void *aux ) @@ -2115,12 +2147,16 @@ imap_cancel( store_t *gctx, cb( aux ); } +/******************* imap_commit *******************/ + static void imap_commit( store_t *gctx ) { (void)gctx; } +/******************* imap_parse_store *******************/ + imap_server_conf_t *servers, **serverapp = &servers; static int diff --git a/src/isync.h b/src/isync.h index f18427a..3af13a8 100644 --- a/src/isync.h +++ b/src/isync.h @@ -167,6 +167,8 @@ typedef struct store { int recent; /* # of recent messages - don't trust this beyond the initial read */ } store_t; +/* When the callback is invoked (at most once per store), the store is fubar; + * call the driver's cancel_store() to dispose of it. */ static INLINE void set_bad_callback( store_t *ctx, void (*cb)( void *aux ), void *aux ) { @@ -181,11 +183,14 @@ typedef struct { } msg_data_t; #define DRV_OK 0 +/* Message went missing, or mailbox is full, etc. */ #define DRV_MSG_BAD 1 +/* Something is wrong with the current mailbox - probably it is somehow inaccessible. */ #define DRV_BOX_BAD 2 +/* The command has been cancel()ed or cancel_store()d. */ #define DRV_CANCELED 3 -/* All memory belongs to the driver's user. */ +/* All memory belongs to the driver's user, unless stated otherwise. */ /* This flag says that the driver CAN store messages with CRLFs, @@ -198,34 +203,87 @@ typedef struct { struct driver { int flags; + + /* Parse configuration. */ int (*parse_store)( conffile_t *cfg, store_conf_t **storep, int *err ); + + /* Close remaining server connections. All stores must be disowned first. */ void (*cleanup)( void ); + + /* Open a store with the given configuration. This may recycle existing + * server connections. Upon failure, a null store is passed to the callback. */ void (*open_store)( store_conf_t *conf, void (*cb)( store_t *ctx, void *aux ), void *aux ); + + /* Mark the store as available for recycling. Server connection may be kept alive. */ void (*disown_store)( store_t *ctx ); + + /* Try to recycle a store with the given configuration. */ store_t *(*own_store)( store_conf_t *conf ); + + /* Discard the store after a bad_callback. The server connections will be closed. + * Pending commands will have their callbacks synchronously invoked with DRV_CANCELED. */ void (*cancel_store)( store_t *ctx ); + + /* List the mailboxes in this store. */ void (*list)( store_t *ctx, void (*cb)( int sts, void *aux ), void *aux ); + + /* Invoked before select(), this informs the driver which operations (OP_*) + * will be performed on the mailbox. The driver may extend the set by implicitly + * needed or available operations. */ void (*prepare_opts)( store_t *ctx, int opts ); + + /* Open the mailbox ctx->name. Optionally create missing boxes. + * As a side effect, this should resolve ctx->path if applicable. */ void (*select)( store_t *ctx, int create, void (*cb)( int sts, void *aux ), void *aux ); + + /* Load the message attributes needed to perform the requested operations. + * Consider only messages with UIDs between minuid and maxuid (inclusive) + * and those named in the excs array (smaller than minuid). + * The driver takes ownership of the excs array. */ void (*load)( store_t *ctx, int minuid, int maxuid, int *excs, int nexcs, void (*cb)( int sts, void *aux ), void *aux ); + + /* Fetch the contents and flags of the given message from the current mailbox. */ void (*fetch_msg)( store_t *ctx, message_t *msg, msg_data_t *data, void (*cb)( int sts, void *aux ), void *aux ); + + /* Store the given message to either the current mailbox or the trash folder. + * If the new copy's UID can be immediately determined, return it, otherwise -1. */ void (*store_msg)( store_t *ctx, msg_data_t *data, int to_trash, void (*cb)( int sts, int uid, void *aux ), void *aux ); + + /* Find a message by its temporary UID header to determine its real UID. */ void (*find_msg)( store_t *ctx, const char *tuid, void (*cb)( int sts, int uid, void *aux ), void *aux ); + + /* Add/remove the named flags to/from the given message. The message may be either + * a pre-fetched one (in which case the in-memory representation is updated), + * or it may be identifed by UID only. The operation may be delayed until commit() + * is called. */ void (*set_flags)( store_t *ctx, message_t *msg, int uid, int add, int del, /* msg can be null, therefore uid as a fallback */ void (*cb)( int sts, void *aux ), void *aux ); + + /* Move the given message from the current mailbox to the trash folder. + * This may expunge the original message immediately, but it needn't to. */ void (*trash_msg)( store_t *ctx, message_t *msg, /* This may expunge the original message immediately, but it needn't to */ void (*cb)( int sts, void *aux ), void *aux ); + + /* Expunge deleted messages from the current mailbox and close it. + * There is no need to explicitly close a mailbox if no expunge is needed. */ void (*close)( store_t *ctx, /* IMAP-style: expunge inclusive */ void (*cb)( int sts, void *aux ), void *aux ); - void (*cancel)( store_t *ctx, /* only not yet sent commands */ + + /* Cancel queued commands which are not in flight yet; they will have their + * callbacks invoked with DRV_CANCELED. Afterwards, wait for the completion of + * the in-flight commands. If the store is canceled before this command completes, + * the callback will *not* be invoked. */ + void (*cancel)( store_t *ctx, void (*cb)( void *aux ), void *aux ); + + /* Commit any pending set_flags() commands. */ void (*commit)( store_t *ctx ); }; diff --git a/src/sync.c b/src/sync.c index 6ae0b2d..9db8228 100644 --- a/src/sync.c +++ b/src/sync.c @@ -145,13 +145,15 @@ typedef struct { channel_conf_t *chan; store_t *ctx[2]; driver_t *drv[2]; - int state[2], ref_count, ret; + int state[2], ref_count, ret, lfd; int find_old_total[2], find_old_done[2]; int new_total[2], new_done[2]; int find_new_total[2], find_new_done[2]; int flags_total[2], flags_done[2]; int trash_total[2], trash_done[2]; - int maxuid[2], uidval[2], smaxxuid, lfd; + int maxuid[2]; /* highest UID that was already propagated */ + int uidval[2]; /* UID validity value */ + int smaxxuid; /* highest expired UID on slave */ unsigned find:1; } sync_vars_t; ------------------------------------------------------------------------------ Live Security Virtual Conference Exclusive live event will cover all the ways today's security and threat landscape has changed and how IT managers can respond. Discussions will include endpoint security, mobile security and the latest in malware threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/ _______________________________________________ isync-devel mailing list isync-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/isync-devel