isync

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

commit 6e32b88f3dd37f4160f55de66f817625c8ec9fd8
parent 8b7d3792e40fb4cc289f68eb94b3297cb5c99255
Author: Oswald Buddenhagen <ossi@users.sf.net>
Date:   Fri, 24 Mar 2017 17:44:11 +0100

let driver_t::list_store() return the list of boxes

... and make 'boxes' and 'listed' private to the drivers.

Diffstat:
Msrc/driver.h | 7+++----
Msrc/drv_imap.c | 36+++++++++++++++++++-----------------
Msrc/drv_maildir.c | 74++++++++++++++++++++++++++++++++++++++------------------------------------
Msrc/main.c | 5++---
4 files changed, 62 insertions(+), 60 deletions(-)

diff --git a/src/driver.h b/src/driver.h @@ -86,8 +86,6 @@ typedef struct message { typedef struct store { struct store *next; store_conf_t *conf; /* foreign */ - string_list_t *boxes; /* _list results - own */ - char listed; /* was _list already run? */ /* currently open mailbox */ message_t *msgs; /* own */ @@ -161,9 +159,10 @@ struct driver { * Pending commands will have their callbacks synchronously invoked with DRV_CANCELED. */ void (*cancel_store)( store_t *ctx ); - /* List the mailboxes in this store. Flags are ORed LIST_* values. */ + /* List the mailboxes in this store. Flags are ORed LIST_* values. + * The returned box list remains owned by the driver. */ void (*list_store)( store_t *ctx, int flags, - void (*cb)( int sts, void *aux ), void *aux ); + void (*cb)( int sts, string_list_t *boxes, void *aux ), void *aux ); /* Invoked before open_box(), this informs the driver which box is to be opened. */ int (*select_box)( store_t *ctx, const char *name ); diff --git a/src/drv_imap.c b/src/drv_imap.c @@ -107,6 +107,8 @@ struct imap_store { uint got_namespace:1; char delimiter[2]; /* hierarchy delimiter */ list_t *ns_personal, *ns_other, *ns_shared; /* NAMESPACE info */ + string_list_t *boxes; // _list results + char listed; // was _list already run with these flags? message_t **msgapp; /* FETCH results */ uint caps; /* CAPABILITY results */ string_list_t *auth_mechs; @@ -1257,8 +1259,8 @@ parse_list_rsp_p2( imap_store_t *ctx, list_t *list, char *cmd ATTR_UNUSED ) warn( "IMAP warning: ignoring mailbox %s (reserved character '/' in name)\n", arg ); goto skip; } - narg->next = ctx->gen.boxes; - ctx->gen.boxes = narg; + narg->next = ctx->boxes; + ctx->boxes = narg; skip: free_list( list ); return LIST_OK; @@ -1527,7 +1529,7 @@ static void imap_cleanup_store( imap_store_t *ctx ) { free_generic_messages( ctx->gen.msgs ); - free_string_list( ctx->gen.boxes ); + free_string_list( ctx->boxes ); } static void @@ -2901,16 +2903,16 @@ imap_find_new_msgs_p3( imap_store_t *ctx, imap_cmd_t *gcmd, int response ) typedef struct { imap_cmd_refcounted_state_t gen; - void (*callback)( int sts, void *aux ); + void (*callback)( int sts, string_list_t *, void *aux ); void *callback_aux; } imap_list_store_state_t; static void imap_list_store_p2( imap_store_t *, imap_cmd_t *, int ); -static void imap_list_store_p3( imap_list_store_state_t * ); +static void imap_list_store_p3( imap_store_t *, imap_list_store_state_t * ); static void imap_list_store( store_t *gctx, int flags, - void (*cb)( int sts, void *aux ), void *aux ) + void (*cb)( int sts, string_list_t *boxes, void *aux ), void *aux ) { imap_store_t *ctx = (imap_store_t *)gctx; INIT_REFCOUNTED_STATE(imap_list_store_state_t, sts, cb, aux) @@ -2931,36 +2933,36 @@ imap_list_store( store_t *gctx, int flags, // int pfx_is_empty = !*ctx->prefix; int pfx_is_inbox = !pfx_is_empty && is_inbox( ctx, ctx->prefix, -1 ); - if (((flags & (LIST_PATH | LIST_PATH_MAYBE)) || pfx_is_empty) && !pfx_is_inbox && !(ctx->gen.listed & LIST_PATH)) { - ctx->gen.listed |= LIST_PATH; + if (((flags & (LIST_PATH | LIST_PATH_MAYBE)) || pfx_is_empty) && !pfx_is_inbox && !(ctx->listed & LIST_PATH)) { + ctx->listed |= LIST_PATH; if (pfx_is_empty) - ctx->gen.listed |= LIST_INBOX; + ctx->listed |= LIST_INBOX; imap_exec( ctx, imap_refcounted_new_cmd( &sts->gen ), imap_list_store_p2, "LIST \"\" \"%\\s*\"", ctx->prefix ); } - if (((flags & LIST_INBOX) || pfx_is_inbox) && !pfx_is_empty && !(ctx->gen.listed & LIST_INBOX)) { - ctx->gen.listed |= LIST_INBOX; + if (((flags & LIST_INBOX) || pfx_is_inbox) && !pfx_is_empty && !(ctx->listed & LIST_INBOX)) { + ctx->listed |= LIST_INBOX; if (pfx_is_inbox) - ctx->gen.listed |= LIST_PATH; + ctx->listed |= LIST_PATH; imap_exec( ctx, imap_refcounted_new_cmd( &sts->gen ), imap_list_store_p2, "LIST \"\" INBOX*" ); } - imap_list_store_p3( sts ); + imap_list_store_p3( ctx, sts ); } static void -imap_list_store_p2( imap_store_t *ctx ATTR_UNUSED, imap_cmd_t *cmd, int response ) +imap_list_store_p2( imap_store_t *ctx, imap_cmd_t *cmd, int response ) { imap_list_store_state_t *sts = (imap_list_store_state_t *)((imap_cmd_refcounted_t *)cmd)->state; transform_refcounted_box_response( &sts->gen, response ); - imap_list_store_p3( sts ); + imap_list_store_p3( ctx, sts ); } static void -imap_list_store_p3( imap_list_store_state_t *sts ) +imap_list_store_p3( imap_store_t *ctx, imap_list_store_state_t *sts ) { - DONE_REFCOUNTED_STATE(sts) + DONE_REFCOUNTED_STATE_ARGS(sts, ctx->boxes) } /******************* imap_cancel_cmds *******************/ diff --git a/src/drv_maildir.c b/src/drv_maildir.c @@ -79,6 +79,8 @@ typedef struct { DB *db; char *usedb; #endif /* USE_DB */ + string_list_t *boxes; // _list results + char listed; // was _list already run with these flags? wakeup_t lcktmr; void (*bad_callback)( void *aux ); @@ -282,7 +284,7 @@ maildir_free_store( store_t *gctx ) maildir_cleanup( gctx ); wipe_wakeup( &ctx->lcktmr ); free( ctx->trash ); - free_string_list( gctx->boxes ); + free_string_list( ctx->boxes ); free( gctx ); } @@ -307,18 +309,18 @@ maildir_invoke_bad_callback( maildir_store_t *ctx ) } static int -maildir_list_maildirpp( store_t *gctx, int flags, const char *inbox ) +maildir_list_maildirpp( maildir_store_t *ctx, int flags, const char *inbox ) { DIR *dir; struct dirent *de; int warned = 0; struct stat st; - if (gctx->listed & LIST_PATH) // Implies LIST_INBOX + if (ctx->listed & LIST_PATH) // Implies LIST_INBOX return 0; - if (!(gctx->listed & LIST_INBOX)) - add_string_list( &gctx->boxes, "INBOX" ); + if (!(ctx->listed & LIST_INBOX)) + add_string_list( &ctx->boxes, "INBOX" ); char path[_POSIX_PATH_MAX]; int pathLen = nfsnprintf( path, _POSIX_PATH_MAX, "%s/", inbox ); @@ -335,7 +337,7 @@ maildir_list_maildirpp( store_t *gctx, int flags, const char *inbox ) char name[_POSIX_PATH_MAX]; char *effName = name; if (*ent == '.') { - if (gctx->listed & LIST_INBOX) + if (ctx->listed & LIST_INBOX) continue; if (!*++ent) continue; @@ -362,27 +364,27 @@ maildir_list_maildirpp( store_t *gctx, int flags, const char *inbox ) if (name[i] == '.') name[i] = '/'; } - add_string_list( &gctx->boxes, effName ); + add_string_list( &ctx->boxes, effName ); } } closedir (dir); if (flags & (LIST_PATH | LIST_PATH_MAYBE)) - gctx->listed |= LIST_PATH; - gctx->listed |= LIST_INBOX; + ctx->listed |= LIST_PATH; + ctx->listed |= LIST_INBOX; return 0; } -static int maildir_list_inbox( store_t *gctx, int flags, const char *basePath ); -static int maildir_list_path( store_t *gctx, int flags, const char *inbox ); +static int maildir_list_inbox( maildir_store_t *ctx, int flags, const char *basePath ); +static int maildir_list_path( maildir_store_t *ctx, int flags, const char *inbox ); static int -maildir_list_recurse( store_t *gctx, int isBox, int flags, +maildir_list_recurse( maildir_store_t *ctx, int isBox, int flags, const char *inbox, int inboxLen, const char *basePath, int basePathLen, char *path, int pathLen, char *name, int nameLen ) { DIR *dir; - int style = ((maildir_store_conf_t *)gctx->conf)->sub_style; + int style = ((maildir_store_conf_t *)ctx->gen.conf)->sub_style; int pl, nl; struct dirent *de; struct stat st; @@ -395,7 +397,7 @@ maildir_list_recurse( store_t *gctx, int isBox, int flags, } if (isBox > 1 && style == SUB_UNSET) { error( "Maildir error: found subfolder '%.*s', but store '%s' does not specify SubFolders style\n", - nameLen - 1, name, gctx->conf->name ); + nameLen - 1, name, ctx->gen.conf->name ); closedir( dir ); return -1; } @@ -409,13 +411,13 @@ maildir_list_recurse( store_t *gctx, int isBox, int flags, pl += pathLen; if (inbox && equals( path, pl, inbox, inboxLen )) { // Inbox nested into Path. - if (maildir_list_inbox( gctx, flags, 0 ) < 0) { + if (maildir_list_inbox( ctx, flags, 0 ) < 0) { closedir( dir ); return -1; } } else if (basePath && equals( path, pl, basePath, basePathLen )) { // Path nested into Inbox. - if (maildir_list_path( gctx, flags, 0 ) < 0) { + if (maildir_list_path( ctx, flags, 0 ) < 0) { closedir( dir ); return -1; } @@ -439,10 +441,10 @@ maildir_list_recurse( store_t *gctx, int isBox, int flags, path[pl++] = '/'; nfsnprintf( path + pl, _POSIX_PATH_MAX - pl, "cur" ); if (!stat( path, &st ) && S_ISDIR(st.st_mode)) - add_string_list( &gctx->boxes, name ); + add_string_list( &ctx->boxes, name ); path[pl] = 0; name[nl++] = '/'; - if (maildir_list_recurse( gctx, isBox + 1, flags, inbox, inboxLen, basePath, basePathLen, path, pl, name, nl ) < 0) { + if (maildir_list_recurse( ctx, isBox + 1, flags, inbox, inboxLen, basePath, basePathLen, path, pl, name, nl ) < 0) { closedir( dir ); return -1; } @@ -453,55 +455,55 @@ maildir_list_recurse( store_t *gctx, int isBox, int flags, } static int -maildir_list_inbox( store_t *gctx, int flags, const char *basePath ) +maildir_list_inbox( maildir_store_t *ctx, int flags, const char *basePath ) { char path[_POSIX_PATH_MAX], name[_POSIX_PATH_MAX]; - if (gctx->listed & LIST_INBOX) + if (ctx->listed & LIST_INBOX) return 0; - gctx->listed |= LIST_INBOX; + ctx->listed |= LIST_INBOX; - add_string_list( &gctx->boxes, "INBOX" ); + add_string_list( &ctx->boxes, "INBOX" ); return maildir_list_recurse( - gctx, 1, flags, 0, 0, basePath, basePath ? strlen( basePath ) - 1 : 0, - path, nfsnprintf( path, _POSIX_PATH_MAX, "%s/", ((maildir_store_conf_t *)gctx->conf)->inbox ), + ctx, 1, flags, 0, 0, basePath, basePath ? strlen( basePath ) - 1 : 0, + path, nfsnprintf( path, _POSIX_PATH_MAX, "%s/", ((maildir_store_conf_t *)ctx->gen.conf)->inbox ), name, nfsnprintf( name, _POSIX_PATH_MAX, "INBOX/" ) ); } static int -maildir_list_path( store_t *gctx, int flags, const char *inbox ) +maildir_list_path( maildir_store_t *ctx, int flags, const char *inbox ) { char path[_POSIX_PATH_MAX], name[_POSIX_PATH_MAX]; - if (gctx->listed & LIST_PATH) + if (ctx->listed & LIST_PATH) return 0; - gctx->listed |= LIST_PATH; + ctx->listed |= LIST_PATH; - if (maildir_ensure_path( (maildir_store_conf_t *)gctx->conf ) < 0) + if (maildir_ensure_path( (maildir_store_conf_t *)ctx->gen.conf ) < 0) return -1; return maildir_list_recurse( - gctx, 0, flags, inbox, inbox ? strlen( inbox ) : 0, 0, 0, - path, nfsnprintf( path, _POSIX_PATH_MAX, "%s", gctx->conf->path ), + ctx, 0, flags, inbox, inbox ? strlen( inbox ) : 0, 0, 0, + path, nfsnprintf( path, _POSIX_PATH_MAX, "%s", ctx->gen.conf->path ), name, 0 ); } static void maildir_list_store( store_t *gctx, int flags, - void (*cb)( int sts, void *aux ), void *aux ) + void (*cb)( int sts, string_list_t *boxes, 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 - ? maildir_list_maildirpp( gctx, flags, conf->inbox ) < 0 + ? maildir_list_maildirpp( ctx, flags, conf->inbox ) < 0 : ((((flags & LIST_PATH) || ((flags & LIST_PATH_MAYBE) && gctx->conf->path)) - && maildir_list_path( gctx, flags, conf->inbox ) < 0) || + && maildir_list_path( ctx, flags, conf->inbox ) < 0) || ((flags & LIST_INBOX) - && maildir_list_inbox( gctx, flags, gctx->conf->path ) < 0))) { + && maildir_list_inbox( ctx, flags, gctx->conf->path ) < 0))) { maildir_invoke_bad_callback( ctx ); - cb( DRV_CANCELED, aux ); + cb( DRV_CANCELED, 0, aux ); } else { - cb( DRV_OK, aux ); + cb( DRV_OK, ctx->boxes, aux ); } } diff --git a/src/main.c b/src/main.c @@ -775,7 +775,7 @@ store_bad( void *aux ) } static void store_connected( int sts, void *aux ); -static void store_listed( int sts, void *aux ); +static void store_listed( int sts, string_list_t *boxes, void *aux ); static int sync_listed_boxes( main_vars_t *mvars, box_ent_t *mbox ); static void done_sync_2_dyn( int sts, void *aux ); static void done_sync( int sts, void *aux ); @@ -999,10 +999,9 @@ store_connected( int sts, void *aux ) } static void -store_listed( int sts, void *aux ) +store_listed( int sts, string_list_t *boxes, void *aux ) { MVARS(aux) - string_list_t *boxes = mvars->ctx[t]->boxes; string_list_t *box; switch (sts) {