split create_box() off from open_box()
this allows us to do something else than creating missing boxes depending on circumstances. hypothetically, that is.
This commit is contained in:
parent
f1809ddd2b
commit
7b7304b625
|
@ -165,8 +165,13 @@ struct driver {
|
||||||
* As a side effect, this should resolve ctx->path if applicable. */
|
* As a side effect, this should resolve ctx->path if applicable. */
|
||||||
int (*select_box)( store_t *ctx, const char *name );
|
int (*select_box)( store_t *ctx, const char *name );
|
||||||
|
|
||||||
/* Open the selected mailbox. Optionally create missing boxes. */
|
/* Create the selected mailbox. */
|
||||||
void (*open_box)( store_t *ctx, int create,
|
void (*create_box)( store_t *ctx,
|
||||||
|
void (*cb)( int sts, void *aux ), void *aux );
|
||||||
|
|
||||||
|
/* Open the selected mailbox.
|
||||||
|
* Note that this should not directly complain about failure to open. */
|
||||||
|
void (*open_box)( store_t *ctx,
|
||||||
void (*cb)( int sts, void *aux ), void *aux );
|
void (*cb)( int sts, void *aux ), void *aux );
|
||||||
|
|
||||||
/* Invoked before load_box(), this informs the driver which operations (OP_*)
|
/* Invoked before load_box(), this informs the driver which operations (OP_*)
|
||||||
|
|
|
@ -143,8 +143,8 @@ struct imap_cmd {
|
||||||
int uid; /* to identify fetch responses */
|
int uid; /* to identify fetch responses */
|
||||||
char high_prio; /* if command is queued, put it at the front of the queue. */
|
char high_prio; /* if command is queued, put it at the front of the queue. */
|
||||||
char to_trash; /* we are storing to trash, not current. */
|
char to_trash; /* we are storing to trash, not current. */
|
||||||
char create; /* create the mailbox if we get an error ... */
|
char create; /* create the mailbox if we get an error which suggests so. */
|
||||||
char trycreate; /* ... but only if this is true or the server says so. */
|
char failok; /* Don't complain about NO response. */
|
||||||
} param;
|
} param;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1333,10 +1333,7 @@ imap_socket_read( void *aux )
|
||||||
resp = RESP_OK;
|
resp = RESP_OK;
|
||||||
} else {
|
} else {
|
||||||
if (!strcmp( "NO", arg )) {
|
if (!strcmp( "NO", arg )) {
|
||||||
if (cmdp->param.create &&
|
if (cmdp->param.create && cmd && starts_with( cmd, -1, "[TRYCREATE]", 11 )) { /* APPEND or UID COPY */
|
||||||
(cmdp->param.trycreate ||
|
|
||||||
(cmd && starts_with( cmd, -1, "[TRYCREATE]", 11 ))))
|
|
||||||
{ /* SELECT, APPEND or UID COPY */
|
|
||||||
struct imap_cmd_trycreate *cmd2 =
|
struct imap_cmd_trycreate *cmd2 =
|
||||||
(struct imap_cmd_trycreate *)new_imap_cmd( sizeof(*cmd2) );
|
(struct imap_cmd_trycreate *)new_imap_cmd( sizeof(*cmd2) );
|
||||||
cmd2->orig_cmd = cmdp;
|
cmd2->orig_cmd = cmdp;
|
||||||
|
@ -1348,12 +1345,15 @@ imap_socket_read( void *aux )
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
resp = RESP_NO;
|
resp = RESP_NO;
|
||||||
|
if (cmdp->param.failok)
|
||||||
|
goto doresp;
|
||||||
} else /*if (!strcmp( "BAD", arg ))*/
|
} else /*if (!strcmp( "BAD", arg ))*/
|
||||||
resp = RESP_CANCEL;
|
resp = RESP_CANCEL;
|
||||||
error( "IMAP command '%s' returned an error: %s %s\n",
|
error( "IMAP command '%s' returned an error: %s %s\n",
|
||||||
!starts_with( cmdp->cmd, -1, "LOGIN", 5 ) ? cmdp->cmd : "LOGIN <user> <pass>",
|
!starts_with( cmdp->cmd, -1, "LOGIN", 5 ) ? cmdp->cmd : "LOGIN <user> <pass>",
|
||||||
arg, cmd ? cmd : "" );
|
arg, cmd ? cmd : "" );
|
||||||
}
|
}
|
||||||
|
doresp:
|
||||||
if ((resp2 = parse_response_code( ctx, cmdp, cmd )) > resp)
|
if ((resp2 = parse_response_code( ctx, cmdp, cmd )) > resp)
|
||||||
resp = resp2;
|
resp = resp2;
|
||||||
imap_ref( ctx );
|
imap_ref( ctx );
|
||||||
|
@ -2124,7 +2124,7 @@ imap_select_box( store_t *gctx, const char *name )
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
imap_open_box( store_t *gctx, int create,
|
imap_open_box( store_t *gctx,
|
||||||
void (*cb)( int sts, void *aux ), void *aux )
|
void (*cb)( int sts, void *aux ), void *aux )
|
||||||
{
|
{
|
||||||
imap_store_t *ctx = (imap_store_t *)gctx;
|
imap_store_t *ctx = (imap_store_t *)gctx;
|
||||||
|
@ -2139,13 +2139,33 @@ imap_open_box( store_t *gctx, int create,
|
||||||
ctx->gen.uidnext = 0;
|
ctx->gen.uidnext = 0;
|
||||||
|
|
||||||
INIT_IMAP_CMD(imap_cmd_simple, cmd, cb, aux)
|
INIT_IMAP_CMD(imap_cmd_simple, cmd, cb, aux)
|
||||||
cmd->gen.param.create = create;
|
cmd->gen.param.failok = 1;
|
||||||
cmd->gen.param.trycreate = 1;
|
|
||||||
imap_exec( ctx, &cmd->gen, imap_done_simple_box,
|
imap_exec( ctx, &cmd->gen, imap_done_simple_box,
|
||||||
"SELECT \"%\\s\"", buf );
|
"SELECT \"%\\s\"", buf );
|
||||||
free( buf );
|
free( buf );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/******************* imap_create_box *******************/
|
||||||
|
|
||||||
|
static void
|
||||||
|
imap_create_box( store_t *gctx,
|
||||||
|
void (*cb)( int sts, void *aux ), void *aux )
|
||||||
|
{
|
||||||
|
imap_store_t *ctx = (imap_store_t *)gctx;
|
||||||
|
struct imap_cmd_simple *cmd;
|
||||||
|
char *buf;
|
||||||
|
|
||||||
|
if (prepare_box( &buf, ctx ) < 0) {
|
||||||
|
cb( DRV_BOX_BAD, aux );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
INIT_IMAP_CMD(imap_cmd_simple, cmd, cb, aux)
|
||||||
|
imap_exec( ctx, &cmd->gen, imap_done_simple_box,
|
||||||
|
"CREATE \"%\\s\"", buf );
|
||||||
|
free( buf );
|
||||||
|
}
|
||||||
|
|
||||||
/******************* imap_load_box *******************/
|
/******************* imap_load_box *******************/
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -2788,6 +2808,7 @@ struct driver imap_driver = {
|
||||||
imap_cancel_store,
|
imap_cancel_store,
|
||||||
imap_list_store,
|
imap_list_store,
|
||||||
imap_select_box,
|
imap_select_box,
|
||||||
|
imap_create_box,
|
||||||
imap_open_box,
|
imap_open_box,
|
||||||
imap_prepare_load_box,
|
imap_prepare_load_box,
|
||||||
imap_load_box,
|
imap_load_box,
|
||||||
|
|
|
@ -951,7 +951,7 @@ maildir_select_box( store_t *gctx, const char *name )
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
maildir_open_box( store_t *gctx, int create,
|
maildir_open_box( store_t *gctx,
|
||||||
void (*cb)( int sts, void *aux ), void *aux )
|
void (*cb)( int sts, void *aux ), void *aux )
|
||||||
{
|
{
|
||||||
maildir_store_t *ctx = (maildir_store_t *)gctx;
|
maildir_store_t *ctx = (maildir_store_t *)gctx;
|
||||||
|
@ -961,7 +961,7 @@ maildir_open_box( store_t *gctx, int create,
|
||||||
#endif /* USE_DB */
|
#endif /* USE_DB */
|
||||||
char uvpath[_POSIX_PATH_MAX];
|
char uvpath[_POSIX_PATH_MAX];
|
||||||
|
|
||||||
if ((ret = maildir_validate( gctx->path, create, ctx )) != DRV_OK) {
|
if ((ret = maildir_validate( gctx->path, 0, ctx )) != DRV_OK) {
|
||||||
cb( ret, aux );
|
cb( ret, aux );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1046,6 +1046,13 @@ maildir_open_box( store_t *gctx, int create,
|
||||||
cb( DRV_OK, aux );
|
cb( DRV_OK, aux );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
maildir_create_box( store_t *gctx,
|
||||||
|
void (*cb)( int sts, void *aux ), void *aux )
|
||||||
|
{
|
||||||
|
cb( maildir_validate( gctx->path, 1, (maildir_store_t *)gctx ), aux );
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
maildir_prepare_load_box( store_t *gctx, int opts )
|
maildir_prepare_load_box( store_t *gctx, int opts )
|
||||||
{
|
{
|
||||||
|
@ -1538,6 +1545,7 @@ struct driver maildir_driver = {
|
||||||
maildir_disown_store, /* _cancel_, but it's the same */
|
maildir_disown_store, /* _cancel_, but it's the same */
|
||||||
maildir_list_store,
|
maildir_list_store,
|
||||||
maildir_select_box,
|
maildir_select_box,
|
||||||
|
maildir_create_box,
|
||||||
maildir_open_box,
|
maildir_open_box,
|
||||||
maildir_prepare_load_box,
|
maildir_prepare_load_box,
|
||||||
maildir_load_box,
|
maildir_load_box,
|
||||||
|
|
64
src/sync.c
64
src/sync.c
|
@ -923,7 +923,10 @@ load_state( sync_vars_t *svars )
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void box_confirmed( int sts, void *aux );
|
||||||
|
static void box_created( int sts, void *aux );
|
||||||
static void box_opened( int sts, void *aux );
|
static void box_opened( int sts, void *aux );
|
||||||
|
static void box_opened2( sync_vars_t *svars, int t );
|
||||||
static void load_box( sync_vars_t *svars, int t, int minwuid, int *mexcs, int nmexcs );
|
static void load_box( sync_vars_t *svars, int t, int minwuid, int *mexcs, int nmexcs );
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -984,27 +987,78 @@ sync_boxes( store_t *ctx[], const char *names[], channel_conf_t *chan,
|
||||||
sync_ref( svars );
|
sync_ref( svars );
|
||||||
for (t = 0; ; t++) {
|
for (t = 0; ; t++) {
|
||||||
info( "Opening %s box %s...\n", str_ms[t], svars->orig_name[t] );
|
info( "Opening %s box %s...\n", str_ms[t], svars->orig_name[t] );
|
||||||
svars->drv[t]->open_box( ctx[t], (chan->ops[t] & OP_CREATE) != 0, box_opened, AUX );
|
svars->drv[t]->open_box( ctx[t], box_confirmed, AUX );
|
||||||
if (t || check_cancel( svars ))
|
if (t || check_cancel( svars ))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
sync_deref( svars );
|
sync_deref( svars );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
box_confirmed( int sts, void *aux )
|
||||||
|
{
|
||||||
|
DECL_SVARS;
|
||||||
|
|
||||||
|
if (sts == DRV_CANCELED)
|
||||||
|
return;
|
||||||
|
INIT_SVARS(aux);
|
||||||
|
if (check_cancel( svars ))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (sts == DRV_BOX_BAD) {
|
||||||
|
if (!(svars->chan->ops[t] & OP_CREATE)) {
|
||||||
|
box_opened( sts, aux );
|
||||||
|
} else {
|
||||||
|
info( "Creating %s %s...\n", str_ms[t], svars->orig_name[t] );
|
||||||
|
svars->drv[t]->create_box( svars->ctx[t], box_created, AUX );
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
box_opened2( svars, t );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
box_created( int sts, void *aux )
|
||||||
|
{
|
||||||
|
DECL_SVARS;
|
||||||
|
|
||||||
|
if (check_ret( sts, aux ))
|
||||||
|
return;
|
||||||
|
INIT_SVARS(aux);
|
||||||
|
|
||||||
|
svars->drv[t]->open_box( svars->ctx[t], box_opened, AUX );
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
box_opened( int sts, void *aux )
|
box_opened( int sts, void *aux )
|
||||||
{
|
{
|
||||||
DECL_SVARS;
|
DECL_SVARS;
|
||||||
|
|
||||||
|
if (sts == DRV_CANCELED)
|
||||||
|
return;
|
||||||
|
INIT_SVARS(aux);
|
||||||
|
if (check_cancel( svars ))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (sts == DRV_BOX_BAD) {
|
||||||
|
error( "Error: channel %s: %s %s cannot be opened.\n",
|
||||||
|
svars->chan->name, str_ms[t], svars->orig_name[t] );
|
||||||
|
svars->ret = SYNC_FAIL;
|
||||||
|
sync_bail( svars );
|
||||||
|
} else {
|
||||||
|
box_opened2( svars, t );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
box_opened2( sync_vars_t *svars, int t )
|
||||||
|
{
|
||||||
store_t *ctx[2];
|
store_t *ctx[2];
|
||||||
channel_conf_t *chan;
|
channel_conf_t *chan;
|
||||||
sync_rec_t *srec;
|
sync_rec_t *srec;
|
||||||
int opts[2], fails;
|
int opts[2], fails;
|
||||||
int *mexcs, nmexcs, rmexcs, minwuid;
|
int *mexcs, nmexcs, rmexcs, minwuid;
|
||||||
|
|
||||||
if (check_ret( sts, aux ))
|
|
||||||
return;
|
|
||||||
INIT_SVARS(aux);
|
|
||||||
|
|
||||||
svars->state[t] |= ST_SELECTED;
|
svars->state[t] |= ST_SELECTED;
|
||||||
if (!(svars->state[1-t] & ST_SELECTED))
|
if (!(svars->state[1-t] & ST_SELECTED))
|
||||||
return;
|
return;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user