handle copying/trashing failures more carefully
report them as errors (not warnings), let them cause a non-zero exit code, and in the case of trashing, prevent the subsequent expunge. the exception are messages that just disappeared below our feet.
This commit is contained in:
parent
4c14123144
commit
f7458a96d3
56
src/sync.c
56
src/sync.c
|
@ -57,6 +57,7 @@ BIT_ENUM(
|
||||||
ST_FIND_NEW,
|
ST_FIND_NEW,
|
||||||
ST_FOUND_NEW,
|
ST_FOUND_NEW,
|
||||||
ST_SENT_TRASH,
|
ST_SENT_TRASH,
|
||||||
|
ST_TRASH_BAD,
|
||||||
ST_CLOSING,
|
ST_CLOSING,
|
||||||
ST_CLOSED,
|
ST_CLOSED,
|
||||||
ST_SENT_CANCEL,
|
ST_SENT_CANCEL,
|
||||||
|
@ -82,6 +83,7 @@ sanitize_flags( uchar tflags, sync_vars_t *svars, int t )
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
COPY_OK,
|
COPY_OK,
|
||||||
|
COPY_GONE,
|
||||||
COPY_NOGOOD,
|
COPY_NOGOOD,
|
||||||
COPY_CANCELED,
|
COPY_CANCELED,
|
||||||
COPY_FAIL,
|
COPY_FAIL,
|
||||||
|
@ -144,7 +146,8 @@ msg_fetched( int sts, void *aux )
|
||||||
if (srec || scr != tcr) {
|
if (srec || scr != tcr) {
|
||||||
const char *err;
|
const char *err;
|
||||||
if ((err = copy_msg_convert( scr, tcr, vars ))) {
|
if ((err = copy_msg_convert( scr, tcr, vars ))) {
|
||||||
warn( "Warning: message %u from %s %s; skipping.\n", vars->msg->uid, str_fn[t^1], err );
|
error( "Error: message %u from %s %s; skipping.\n", vars->msg->uid, str_fn[t^1], err );
|
||||||
|
svars->ret |= SYNC_FAIL;
|
||||||
vars->cb( COPY_NOGOOD, 0, vars );
|
vars->cb( COPY_NOGOOD, 0, vars );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -156,7 +159,15 @@ msg_fetched( int sts, void *aux )
|
||||||
vars->cb( COPY_CANCELED, 0, vars );
|
vars->cb( COPY_CANCELED, 0, vars );
|
||||||
break;
|
break;
|
||||||
case DRV_MSG_BAD:
|
case DRV_MSG_BAD:
|
||||||
vars->cb( COPY_NOGOOD, 0, vars );
|
if (vars->msg->status & M_DEAD) {
|
||||||
|
// The message was expunged under our feet; this is no error.
|
||||||
|
vars->cb( COPY_GONE, 0, vars );
|
||||||
|
} else {
|
||||||
|
INIT_SVARS(vars->aux);
|
||||||
|
// Driver already reported error.
|
||||||
|
svars->ret |= SYNC_FAIL;
|
||||||
|
vars->cb( COPY_NOGOOD, 0, vars );
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default: // DRV_BOX_BAD
|
default: // DRV_BOX_BAD
|
||||||
vars->cb( COPY_FAIL, 0, vars );
|
vars->cb( COPY_FAIL, 0, vars );
|
||||||
|
@ -179,9 +190,10 @@ msg_stored( int sts, uint uid, void *aux )
|
||||||
break;
|
break;
|
||||||
case DRV_MSG_BAD:
|
case DRV_MSG_BAD:
|
||||||
INIT_SVARS(vars->aux);
|
INIT_SVARS(vars->aux);
|
||||||
(void)svars;
|
// Driver already reported error, but we still need to report the source.
|
||||||
warn( "Warning: %s refuses to store message %u from %s.\n",
|
error( "Error: %s refuses to store message %u from %s.\n",
|
||||||
str_fn[t], vars->msg->uid, str_fn[t^1] );
|
str_fn[t], vars->msg->uid, str_fn[t^1] );
|
||||||
|
svars->ret |= SYNC_FAIL;
|
||||||
vars->cb( COPY_NOGOOD, 0, vars );
|
vars->cb( COPY_NOGOOD, 0, vars );
|
||||||
break;
|
break;
|
||||||
default: // DRV_BOX_BAD
|
default: // DRV_BOX_BAD
|
||||||
|
@ -1404,6 +1416,7 @@ msg_copied( int sts, uint uid, copy_vars_t *vars )
|
||||||
ASSIGN_UID( srec, t, uid, "%sed message", str_hl[t] );
|
ASSIGN_UID( srec, t, uid, "%sed message", str_hl[t] );
|
||||||
break;
|
break;
|
||||||
case COPY_NOGOOD:
|
case COPY_NOGOOD:
|
||||||
|
case COPY_GONE:
|
||||||
srec->status = S_DEAD;
|
srec->status = S_DEAD;
|
||||||
JLOG( "- %u %u", (srec->uid[F], srec->uid[N]), "%s failed", str_hl[t] );
|
JLOG( "- %u %u", (srec->uid[F], srec->uid[N]), "%s failed", str_hl[t] );
|
||||||
break;
|
break;
|
||||||
|
@ -1715,10 +1728,22 @@ msgs_flags_set( sync_vars_t *svars, int t )
|
||||||
static void
|
static void
|
||||||
msg_trashed( int sts, void *aux )
|
msg_trashed( int sts, void *aux )
|
||||||
{
|
{
|
||||||
if (sts == DRV_MSG_BAD)
|
|
||||||
sts = DRV_BOX_BAD;
|
|
||||||
SVARS_CHECK_RET_VARS(trash_vars_t);
|
SVARS_CHECK_RET_VARS(trash_vars_t);
|
||||||
JLOG( "T %d %u", (t, vars->msg->uid), "trashed on %s", str_fn[t] );
|
switch (sts) {
|
||||||
|
case DRV_OK:
|
||||||
|
JLOG( "T %d %u", (t, vars->msg->uid), "trashed on %s", str_fn[t] );
|
||||||
|
break;
|
||||||
|
case DRV_MSG_BAD:
|
||||||
|
if (vars->msg->status & M_DEAD)
|
||||||
|
break;
|
||||||
|
// Driver already reported error.
|
||||||
|
svars->ret |= SYNC_FAIL;
|
||||||
|
if (svars->opts[t] & OPEN_UID_EXPUNGE)
|
||||||
|
vars->msg->status &= ~M_EXPUNGE;
|
||||||
|
else
|
||||||
|
svars->state[t] |= ST_TRASH_BAD;
|
||||||
|
break;
|
||||||
|
}
|
||||||
free( vars );
|
free( vars );
|
||||||
trash_done[t]++;
|
trash_done[t]++;
|
||||||
stats();
|
stats();
|
||||||
|
@ -1732,9 +1757,18 @@ static void
|
||||||
msg_rtrashed( int sts, uint uid ATTR_UNUSED, copy_vars_t *vars )
|
msg_rtrashed( int sts, uint uid ATTR_UNUSED, copy_vars_t *vars )
|
||||||
{
|
{
|
||||||
DECL_INIT_SVARS(vars->aux);
|
DECL_INIT_SVARS(vars->aux);
|
||||||
|
t ^= 1;
|
||||||
switch (sts) {
|
switch (sts) {
|
||||||
case COPY_OK:
|
case COPY_OK:
|
||||||
case COPY_NOGOOD: /* the message is gone or heavily busted */
|
JLOG( "T %d %u", (t, vars->msg->uid), "trashed remotely on %s", str_fn[t^1] );
|
||||||
|
break;
|
||||||
|
case COPY_GONE:
|
||||||
|
break;
|
||||||
|
case COPY_NOGOOD:
|
||||||
|
if (svars->opts[t] & OPEN_UID_EXPUNGE)
|
||||||
|
vars->msg->status &= ~M_EXPUNGE;
|
||||||
|
else
|
||||||
|
svars->state[t] |= ST_TRASH_BAD;
|
||||||
break;
|
break;
|
||||||
default: // COPY_FAIL
|
default: // COPY_FAIL
|
||||||
cancel_sync( svars );
|
cancel_sync( svars );
|
||||||
|
@ -1743,8 +1777,6 @@ msg_rtrashed( int sts, uint uid ATTR_UNUSED, copy_vars_t *vars )
|
||||||
free( vars );
|
free( vars );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
t ^= 1;
|
|
||||||
JLOG( "T %d %u", (t, vars->msg->uid), "trashed remotely on %s", str_fn[t^1] );
|
|
||||||
free( vars );
|
free( vars );
|
||||||
trash_done[t]++;
|
trash_done[t]++;
|
||||||
stats();
|
stats();
|
||||||
|
@ -1769,7 +1801,7 @@ sync_close( sync_vars_t *svars, int t )
|
||||||
svars->state[t] |= ST_CLOSING;
|
svars->state[t] |= ST_CLOSING;
|
||||||
|
|
||||||
if ((svars->chan->ops[t] & (OP_EXPUNGE | OP_EXPUNGE_SOLO)) && !(DFlags & FAKEEXPUNGE)
|
if ((svars->chan->ops[t] & (OP_EXPUNGE | OP_EXPUNGE_SOLO)) && !(DFlags & FAKEEXPUNGE)
|
||||||
/*&& !(svars->state[t] & ST_TRASH_BAD)*/) {
|
&& !(svars->state[t] & ST_TRASH_BAD)) {
|
||||||
if (Verbosity >= TERSE || (DFlags & EXT_EXIT)) {
|
if (Verbosity >= TERSE || (DFlags & EXT_EXIT)) {
|
||||||
if (svars->opts[t] & OPEN_UID_EXPUNGE) {
|
if (svars->opts[t] & OPEN_UID_EXPUNGE) {
|
||||||
for (message_t *tmsg = svars->msgs[t]; tmsg; tmsg = tmsg->next) {
|
for (message_t *tmsg = svars->msgs[t]; tmsg; tmsg = tmsg->next) {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user