isync

mailbox synchronization program
git clone https://git.code.sf.net/p/isync/isync
Log | Files | Refs | README | LICENSE

commit d624c9af5d0f9384b20bc0f01df0561787deacbe
parent f46cf8c887db43ac8dc31b68a4d7405fdf5d56b3
Author: Oswald Buddenhagen <ossi@users.sf.net>
Date:   Tue, 21 Mar 2017 19:27:04 +0100

make set_bad_callback() a proper driver_t entry

... and make the pointers private to the drivers.

Diffstat:
Msrc/driver.h | 16++++------------
Msrc/drv_imap.c | 21+++++++++++++++++----
Msrc/drv_maildir.c | 20+++++++++++++++++---
Msrc/main.c | 2+-
Msrc/sync.c | 2+-
5 files changed, 40 insertions(+), 21 deletions(-)

diff --git a/src/driver.h b/src/driver.h @@ -89,9 +89,6 @@ typedef struct store { string_list_t *boxes; /* _list results - own */ char listed; /* was _list already run? */ - void (*bad_callback)( void *aux ); - void *bad_callback_aux; - /* currently open mailbox */ char *path; /* own */ message_t *msgs; /* own */ @@ -103,15 +100,6 @@ 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 ) -{ - ctx->bad_callback = cb; - ctx->bad_callback_aux = aux; -} - typedef struct { char *data; int len; @@ -160,6 +148,10 @@ struct driver { * return quickly, and must not fail. */ store_t *(*alloc_store)( store_conf_t *conf, const char *label ); + /* When this callback is invoked (at most once per store), the store is fubar; + * call cancel_store() to dispose of it. */ + void (*set_bad_callback)( store_t *ctx, void (*cb)( void *aux ), void *aux ); + /* Open/connect the store. This may recycle existing server connections. */ void (*connect_store)( store_t *ctx, void (*cb)( int sts, void *aux ), void *aux ); diff --git a/src/drv_imap.c b/src/drv_imap.c @@ -131,6 +131,9 @@ struct imap_store { int sasl_cont; #endif + void (*bad_callback)( void *aux ); + void *bad_callback_aux; + conn_t conn; /* this is BIG, so put it last */ }; @@ -404,7 +407,7 @@ static void submit_imap_cmd( imap_store_t *ctx, imap_cmd_t *cmd ) { assert( ctx ); - assert( ctx->gen.bad_callback ); + assert( ctx->bad_callback ); assert( cmd ); assert( cmd->param.done ); @@ -1541,9 +1544,18 @@ imap_deref( imap_store_t *ctx ) } static void +imap_set_bad_callback( store_t *gctx, void (*cb)( void *aux ), void *aux ) +{ + imap_store_t *ctx = (imap_store_t *)gctx; + + ctx->bad_callback = cb; + ctx->bad_callback_aux = aux; +} + +static void imap_invoke_bad_callback( imap_store_t *ctx ) { - ctx->gen.bad_callback( ctx->gen.bad_callback_aux ); + ctx->bad_callback( ctx->bad_callback_aux ); } /******************* imap_free_store *******************/ @@ -1568,7 +1580,7 @@ imap_free_store( store_t *gctx ) { free_generic_messages( gctx->msgs ); gctx->msgs = 0; - set_bad_callback( gctx, imap_cancel_unowned, gctx ); + imap_set_bad_callback( gctx, imap_cancel_unowned, gctx ); gctx->next = unowned; unowned = gctx; } @@ -1584,7 +1596,7 @@ imap_cleanup( void ) for (ctx = unowned; ctx; ctx = nctx) { nctx = ctx->next; - set_bad_callback( ctx, (void (*)(void *))imap_cancel_store, ctx ); + imap_set_bad_callback( ctx, (void (*)(void *))imap_cancel_store, ctx ); if (((imap_store_t *)ctx)->state != SST_BAD) { ((imap_store_t *)ctx)->expectBYE = 1; imap_exec( (imap_store_t *)ctx, 0, imap_cleanup_p2, "LOGOUT" ); @@ -3194,6 +3206,7 @@ struct driver imap_driver = { imap_parse_store, imap_cleanup, imap_alloc_store, + imap_set_bad_callback, imap_connect_store, imap_free_store, imap_cancel_store, diff --git a/src/drv_maildir.c b/src/drv_maildir.c @@ -78,6 +78,9 @@ typedef struct { char *usedb; #endif /* USE_DB */ wakeup_t lcktmr; + + void (*bad_callback)( void *aux ); + void *bad_callback_aux; } maildir_store_t; #ifdef USE_DB @@ -287,7 +290,16 @@ maildir_cleanup_drv( void ) } static void -maildir_invoke_bad_callback( store_t *ctx ) +maildir_set_bad_callback( store_t *gctx, void (*cb)( void *aux ), void *aux ) +{ + maildir_store_t *ctx = (maildir_store_t *)gctx; + + ctx->bad_callback = cb; + ctx->bad_callback_aux = aux; +} + +static void +maildir_invoke_bad_callback( maildir_store_t *ctx ) { ctx->bad_callback( ctx->bad_callback_aux ); } @@ -475,6 +487,7 @@ static void maildir_list_store( store_t *gctx, int flags, void (*cb)( int sts, void *aux ), void *aux ) { + maildir_store_t *ctx = (maildir_store_t *)gctx; maildir_store_conf_t *conf = (maildir_store_conf_t *)gctx->conf; if (conf->sub_style == SUB_MAILDIRPP @@ -483,7 +496,7 @@ maildir_list_store( store_t *gctx, int flags, && maildir_list_path( gctx, flags, conf->inbox ) < 0) || ((flags & LIST_INBOX) && maildir_list_inbox( gctx, flags, gctx->conf->path ) < 0))) { - maildir_invoke_bad_callback( gctx ); + maildir_invoke_bad_callback( ctx ); cb( DRV_CANCELED, aux ); } else { cb( DRV_OK, aux ); @@ -582,7 +595,7 @@ maildir_validate( const char *box, int create, maildir_store_t *ctx ) if (make_box_dir( buf, bl )) { sys_error( "Maildir error: cannot create mailbox '%s'", box ); ((maildir_store_conf_t *)ctx->gen.conf)->failed = FAIL_FINAL; - maildir_invoke_bad_callback( &ctx->gen ); + maildir_invoke_bad_callback( ctx ); return DRV_CANCELED; } } else if (!S_ISDIR(st.st_mode)) { @@ -1876,6 +1889,7 @@ struct driver maildir_driver = { maildir_parse_store, maildir_cleanup_drv, maildir_alloc_store, + maildir_set_bad_callback, maildir_connect_store, maildir_free_store, maildir_free_store, /* _cancel_, but it's the same */ diff --git a/src/main.c b/src/main.c @@ -817,7 +817,7 @@ sync_chans( main_vars_t *mvars, int ent ) for (t = 0; t < 2; t++) { mvars->drv[t] = mvars->chan->stores[t]->driver; mvars->ctx[t] = mvars->drv[t]->alloc_store( mvars->chan->stores[t], labels[t] ); - set_bad_callback( mvars->ctx[t], store_bad, AUX ); + mvars->drv[t]->set_bad_callback( mvars->ctx[t], store_bad, AUX ); } for (t = 0; ; t++) { info( "Opening %s store %s...\n", str_ms[t], mvars->chan->stores[t]->name ); diff --git a/src/sync.c b/src/sync.c @@ -1002,8 +1002,8 @@ sync_boxes( store_t *ctx[], const char *names[], int present[], channel_conf_t * return; } ctx[t]->uidvalidity = -1; - set_bad_callback( ctx[t], store_bad, AUX ); svars->drv[t] = ctx[t]->conf->driver; + svars->drv[t]->set_bad_callback( ctx[t], store_bad, AUX ); } /* Both boxes must be fully set up at this point, so that error exit paths * don't run into uninitialized variables. */