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:
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