isync

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

commit e70a20477cde4b6ef4fd6608b5197a66d8891a69
parent be6e07c5c93fd8da1986e496ee6a19b342e8f460
Author: Oswald Buddenhagen <ossi@users.sf.net>
Date:   Tue, 28 Dec 2021 12:55:19 +0100

complain about --noop/--no-* conflicts

REFMAIL: 20211130124527.t3u7s4fyy57gmfzc@fastmail.com

Diffstat:
Msrc/config.c | 26++++++++++++++++++++------
Msrc/main.c | 13+++++++------
Msrc/mbsync.1 | 2++
Msrc/sync.h | 6++++++
4 files changed, 35 insertions(+), 12 deletions(-)

diff --git a/src/config.c b/src/config.c @@ -213,7 +213,9 @@ getopt_helper( conffile_t *cfile, int *cops, channel_conf_t *conf ) conf->ops[F] |= OP_FLAGS; } else if (!strcasecmp( "All", arg ) || !strcasecmp( "Full", arg )) { *cops |= XOP_PULL|XOP_PUSH; - } else if (strcasecmp( "None", arg ) && strcasecmp( "Noop", arg )) { + } else if (!strcasecmp( "None", arg ) || !strcasecmp( "Noop", arg )) { + conf->ops[F] |= XOP_TYPE_NOOP; + } else { error( "%s:%d: invalid Sync arg '%s'\n", cfile->file, cfile->line, arg ); cfile->err = 1; @@ -246,7 +248,9 @@ getopt_helper( conffile_t *cfile, int *cops, channel_conf_t *conf ) } else if (!strcasecmp( "Slave", arg )) { // Pre-1.4 legacy conf->ops[N] |= op; cfile->ms_warn = 1; - } else if (strcasecmp( "None", arg )) { + } else if (!strcasecmp( "None", arg )) { + conf->ops[F] |= op * (XOP_EXPUNGE_NOOP / OP_EXPUNGE); + } else { error( "%s:%d: invalid %s arg '%s'\n", cfile->file, cfile->line, boxOps[i].name, arg ); cfile->err = 1; @@ -300,7 +304,6 @@ channel_str( const char *chan_name ) return buf; } -/* XXX - this does not detect None conflicts ... */ int merge_ops( int cops, int ops[], const char *chan_name ) { @@ -310,8 +313,13 @@ merge_ops( int cops, int ops[], const char *chan_name ) aops = ops[F] | ops[N]; if (ops[F] & XOP_HAVE_TYPE) { if (aops & OP_MASK_TYPE) { // PullNew, etc. - if (aops & cops & OP_MASK_TYPE) { // Overlapping New, etc. + if (ops[F] & XOP_TYPE_NOOP) { cfl: + error( "Conflicting Sync options specified %s.\n", channel_str( chan_name ) ); + return 1; + } + if (aops & cops & OP_MASK_TYPE) { // Overlapping New, etc. + ovl: error( "Redundant Sync options specified %s.\n", channel_str( chan_name ) ); return 1; } @@ -321,15 +329,17 @@ merge_ops( int cops, int ops[], const char *chan_name ) ops[N] |= cops & OP_MASK_TYPE; if (cops & XOP_PULL) { if (ops[N] & OP_MASK_TYPE) - goto cfl; + goto ovl; ops[N] |= OP_MASK_TYPE; } if (cops & XOP_PUSH) { if (ops[F] & OP_MASK_TYPE) - goto cfl; + goto ovl; ops[F] |= OP_MASK_TYPE; } } else if (cops & (OP_MASK_TYPE | XOP_MASK_DIR)) { // Pull New, etc. + if (ops[F] & XOP_TYPE_NOOP) + goto cfl; if (!(cops & OP_MASK_TYPE)) cops |= OP_MASK_TYPE; else if (!(cops & XOP_MASK_DIR)) @@ -343,6 +353,10 @@ merge_ops( int cops, int ops[], const char *chan_name ) for (i = 0; i < as(boxOps); i++) { op = boxOps[i].op; if (ops[F] & (op * (XOP_HAVE_EXPUNGE / OP_EXPUNGE))) { + if (((aops | cops) & op) && (ops[F] & (op * (XOP_EXPUNGE_NOOP / OP_EXPUNGE)))) { + error( "Conflicting %s options specified %s.\n", boxOps[i].name, channel_str( chan_name ) ); + return 1; + } if (aops & cops & op) { error( "Redundant %s options specified %s.\n", boxOps[i].name, channel_str( chan_name ) ); return 1; diff --git a/src/main.c b/src/main.c @@ -238,15 +238,15 @@ main( int argc, char **argv ) op = OP_EXPUNGE|XOP_HAVE_EXPUNGE; goto lcop; } else if (!strcmp( opt, "no-expunge" )) { - mvars->ops[F] |= XOP_HAVE_EXPUNGE; + mvars->ops[F] |= XOP_EXPUNGE_NOOP | XOP_HAVE_EXPUNGE; } else if (!strcmp( opt, "no-create" )) { - mvars->ops[F] |= XOP_HAVE_CREATE; + mvars->ops[F] |= XOP_CREATE_NOOP | XOP_HAVE_CREATE; } else if (!strcmp( opt, "no-remove" )) { - mvars->ops[F] |= XOP_HAVE_REMOVE; + mvars->ops[F] |= XOP_REMOVE_NOOP | XOP_HAVE_REMOVE; } else if (!strcmp( opt, "full" )) { mvars->ops[F] |= XOP_HAVE_TYPE | XOP_PULL | XOP_PUSH; } else if (!strcmp( opt, "noop" )) { - mvars->ops[F] |= XOP_HAVE_TYPE; + mvars->ops[F] |= XOP_TYPE_NOOP | XOP_HAVE_TYPE; } else if (starts_with( opt, -1, "pull", 4 )) { op = XOP_PULL; lcac: @@ -335,10 +335,11 @@ main( int argc, char **argv ) goto cop; case 'F': cops |= XOP_PULL|XOP_PUSH; - FALLTHROUGH - case '0': mvars->ops[F] |= XOP_HAVE_TYPE; break; + case '0': + mvars->ops[F] |= XOP_TYPE_NOOP | XOP_HAVE_TYPE; + break; case 'n': case 'd': case 'f': diff --git a/src/mbsync.1 b/src/mbsync.1 @@ -624,6 +624,8 @@ changes from the near side to the far side. Note that it is not allowed to assert a cell in two ways, e.g. "\fBSync\fR\ \fBPullNew\fR\ \fBPull\fR" and "\fBSync\fR\ \fBPullNew\fR\ \fBDelete\fR\ \fBPush\fR" induce error messages. +.br +\fBNone\fR may not be combined with any other operation. . .TP \fBCreate\fR {\fBNone\fR|\fBFar\fR|\fBNear\fR|\fBBoth\fR} diff --git a/src/sync.h b/src/sync.h @@ -30,6 +30,12 @@ BIT_ENUM( XOP_HAVE_EXPUNGE, XOP_HAVE_CREATE, XOP_HAVE_REMOVE, + // ... until here. + XOP_TYPE_NOOP, + // ... and here again from scratch. + XOP_EXPUNGE_NOOP, + XOP_CREATE_NOOP, + XOP_REMOVE_NOOP, ) #define OP_MASK_TYPE (OP_NEW | OP_RENEW | OP_DELETE | OP_FLAGS) // Asserted in the target side ops