Răsfoiți Sursa

docs

- insert "separator comments" between driver entry points
- document driver API
- document sync_vars_t parts that are stored in the sync state header
Oswald Buddenhagen 14 ani în urmă
părinte
comite
584e51ed7d
3 a modificat fișierele cu 100 adăugiri și 4 ștergeri
  1. 36 0
      src/drv_imap.c
  2. 60 2
      src/isync.h
  3. 4 2
      src/sync.c

+ 36 - 0
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

+ 60 - 2
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 );
 };
 

+ 4 - 2
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;