From b85153f8eb7c37c4e14e5c95281aa51aac5f589a Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Sun, 26 Apr 2015 20:54:05 +0200 Subject: [PATCH] make skipping of failed stores more thorough in the case of imap stores, the failure is bound to the server config, not just the store config. that means that the storage of the failure state needs to be private to the driver, accessible only through a function. --- src/driver.h | 4 +++- src/drv_imap.c | 12 +++++++++++- src/drv_maildir.c | 14 +++++++++++--- src/main.c | 6 ++++-- 4 files changed, 29 insertions(+), 7 deletions(-) diff --git a/src/driver.h b/src/driver.h index 3aa30a9..dcf9255 100644 --- a/src/driver.h +++ b/src/driver.h @@ -41,7 +41,6 @@ typedef struct store_conf { const char *trash; uint max_size; /* off_t is overkill */ char trash_remote_new, trash_only_new; - char failed; } store_conf_t; /* For message->flags */ @@ -249,6 +248,9 @@ struct driver { /* Get approximate amount of memory occupied by the driver. */ int (*memory_usage)( store_t *ctx ); + + /* Get the FAIL_* state of the driver. */ + int (*fail_state)( store_conf_t *conf ); }; void free_generic_messages( message_t * ); diff --git a/src/drv_imap.c b/src/drv_imap.c index 7b41864..85fae81 100644 --- a/src/drv_imap.c +++ b/src/drv_imap.c @@ -57,6 +57,7 @@ typedef struct imap_server_conf { #ifdef HAVE_LIBSSL char ssl_type; #endif + char failed; } imap_server_conf_t; typedef struct imap_store_conf { @@ -2156,7 +2157,7 @@ imap_open_store_bail( imap_store_t *ctx, int failed ) { void (*cb)( store_t *srv, void *aux ) = ctx->callbacks.imap_open; void *aux = ctx->callback_aux; - ctx->gen.conf->failed = failed; + ((imap_store_conf_t *)ctx->gen.conf)->server->failed = failed; imap_cancel_store( &ctx->gen ); cb( 0, aux ); } @@ -2658,6 +2659,14 @@ imap_memory_usage( store_t *gctx ) return ctx->buffer_mem + ctx->conn.buffer_mem; } +/******************* imap_fail_state *******************/ + +static int +imap_fail_state( store_conf_t *gconf ) +{ + return ((imap_store_conf_t *)gconf)->server->failed; +} + /******************* imap_parse_store *******************/ imap_server_conf_t *servers, **serverapp = &servers; @@ -2937,4 +2946,5 @@ struct driver imap_driver = { imap_cancel_cmds, imap_commit_cmds, imap_memory_usage, + imap_fail_state, }; diff --git a/src/drv_maildir.c b/src/drv_maildir.c index b96950c..b9ed463 100644 --- a/src/drv_maildir.c +++ b/src/drv_maildir.c @@ -57,6 +57,7 @@ typedef struct maildir_store_conf { int alt_map; #endif /* USE_DB */ char info_delimiter; + char failed; char *info_prefix, *info_stop; /* precalculated from info_delimiter */ } maildir_store_conf_t; @@ -141,12 +142,12 @@ maildir_validate_path( store_conf_t *conf ) if (!conf->path) { error( "Maildir error: store '%s' has no Path\n", conf->name ); - conf->failed = FAIL_FINAL; + ((maildir_store_conf_t *)conf)->failed = FAIL_FINAL; return -1; } if (stat( conf->path, &st ) || !S_ISDIR(st.st_mode)) { error( "Maildir error: cannot open store '%s'\n", conf->path ); - conf->failed = FAIL_FINAL; + ((maildir_store_conf_t *)conf)->failed = FAIL_FINAL; return -1; } return 0; @@ -432,7 +433,7 @@ maildir_validate( const char *box, int create, maildir_store_t *ctx ) return DRV_BOX_BAD; if (make_box_dir( buf, bl )) { sys_error( "Maildir error: cannot create mailbox '%s'", box ); - ctx->gen.conf->failed = FAIL_FINAL; + ((maildir_store_conf_t *)ctx->gen.conf)->failed = FAIL_FINAL; maildir_invoke_bad_callback( &ctx->gen ); return DRV_CANCELED; } @@ -1630,6 +1631,12 @@ maildir_memory_usage( store_t *gctx ATTR_UNUSED ) return 0; } +static int +maildir_fail_state( store_conf_t *gconf ) +{ + return ((maildir_store_conf_t *)gconf)->failed; +} + static int maildir_parse_store( conffile_t *cfg, store_conf_t **storep ) { @@ -1698,4 +1705,5 @@ struct driver maildir_driver = { maildir_cancel_cmds, maildir_commit_cmds, maildir_memory_usage, + maildir_fail_state, }; diff --git a/src/main.c b/src/main.c index 2ed0b31..23b6931 100644 --- a/src/main.c +++ b/src/main.c @@ -757,8 +757,10 @@ sync_chans( main_vars_t *mvars, int ent ) info( "Channel %s\n", mvars->chan->name ); mvars->skip = mvars->cben = 0; for (t = 0; t < 2; t++) { - if (mvars->chan->stores[t]->failed != FAIL_TEMP) { - info( "Skipping due to failed %s store %s.\n", str_ms[t], mvars->chan->stores[t]->name ); + int st = mvars->chan->stores[t]->driver->fail_state( mvars->chan->stores[t] ); + if (st != FAIL_TEMP) { + info( "Skipping due to %sfailed %s store %s.\n", + (st == FAIL_WAIT) ? "temporarily " : "", str_ms[t], mvars->chan->stores[t]->name ); mvars->skip = 1; } }