diff --git a/README b/README index 278c0257481acaaa64dedbae74d89ca39317401d..4578fd7d1b643e1b848f795ee5fb9ba6f1b1b26b 100644 --- a/README +++ b/README @@ -149,15 +149,15 @@ Extensions and their implementation status: encoded-character: full Other RFCs/drafts: - subaddress: full, but not configurable + subaddress: mostly full; not configurable comparator-i;ascii-numeric: full relational: full copy: full - regex: full, but suboptimal and no UTF-8 + regex: mostly full; but suboptimal and no UTF-8 body: full, but text body-transform implementation is simple - include: almost full; needs some more work (no external binaries) - vacation: almost full; no support for required References header - imapflags: flag management works, but flags are not stored + include: mostly full; needs some more work (no external binaries) + vacation: mostly full; no support for required References header + imapflags: full variables: mostly full; currently no support for future namespaces Low priority: diff --git a/TODO b/TODO index 0addc5b0736724af11422df018eebe825544f736..8e5750f3aa1f0a6252fdcc6349bcc7f5abe5ff4c 100644 --- a/TODO +++ b/TODO @@ -1,5 +1,4 @@ Next (in order of descending priority/precedence): -* Finish implementing all extensions supported by cmusieve, except notify. * Get rid of all <stdio.h> printf()s in the library; use trace macro instead * Revise extension support for comparators, match-types, address-parts and side-effects. Current implementation emits redundant bytes and associated code @@ -7,7 +6,6 @@ Next (in order of descending priority/precedence): * Emit line numbers for certain action commands to provide useful runtime error messages. * Improve handling of old/corrupt binaries. -* Handle persistent side-effects for the (implicit) keep action * Full security review. Enforce limits on number of created objects, script size, execution time, etc... diff --git a/src/lib-sieve/plugins/imapflags/ext-imapflags.c b/src/lib-sieve/plugins/imapflags/ext-imapflags.c index 7fa2c3f6fd47cc193929c6b4cf6f3ca5a43697bc..92a4a932d54becd537e0dabff9b1532f8b77ea0f 100644 --- a/src/lib-sieve/plugins/imapflags/ext-imapflags.c +++ b/src/lib-sieve/plugins/imapflags/ext-imapflags.c @@ -3,8 +3,8 @@ * * Authors: Stephan Bosch * Specification: draft-ietf-sieve-imapflags-05 - * Implementation: flag management works, not stored though. - * Status: under development + * Implementation: full + * Status: experimental, largely untested * */ diff --git a/src/lib-sieve/plugins/imapflags/imapflags.sieve b/src/lib-sieve/plugins/imapflags/imapflags.sieve index e33b13ebe6603738c6a6a5338e8993a02e7dbf0f..53c0fdc18e9a6eefa38e4b7bf70c6fc86a2a4220 100644 --- a/src/lib-sieve/plugins/imapflags/imapflags.sieve +++ b/src/lib-sieve/plugins/imapflags/imapflags.sieve @@ -25,4 +25,4 @@ if hasflag :count "ge" :comparator "i;ascii-numeric" "2" { fileinto "imap-twoflags"; } -fileinto :flags "\\Seen MDNRequired \\Draft" "INBOX"; +fileinto :flags "MDNRequired \\Draft" "INBOX"; diff --git a/src/lib-sieve/plugins/imapflags/tag-flags.c b/src/lib-sieve/plugins/imapflags/tag-flags.c index 254e15826d837e3625dde0da34cfe392d4d60d0e..5f1e6c5b85d1a7c4c32be7a979d2d790527b2ad4 100644 --- a/src/lib-sieve/plugins/imapflags/tag-flags.c +++ b/src/lib-sieve/plugins/imapflags/tag-flags.c @@ -235,7 +235,7 @@ static void seff_flags_print (const struct sieve_side_effect *seffect ATTR_UNUSED, const struct sieve_action *action ATTR_UNUSED, struct sieve_result *result, - void *se_context ATTR_UNUSED, bool *keep) + void *se_context ATTR_UNUSED, bool *keep ATTR_UNUSED) { struct seff_flags_context *ctx = (struct seff_flags_context *) se_context; unsigned int i; @@ -243,31 +243,31 @@ static void seff_flags_print if ( ctx == NULL ) ctx = seff_flags_get_implicit_context(result); - printf(" + add flags:"); + if ( ctx->flags != 0 || array_count(&ctx->keywords) ) { + printf(" + add flags:"); - if ( (ctx->flags & MAIL_FLAGGED) > 0 ) - printf(" \\flagged\n"); + if ( (ctx->flags & MAIL_FLAGGED) > 0 ) + printf(" \\flagged\n"); - if ( (ctx->flags & MAIL_ANSWERED) > 0 ) - printf(" \\answered"); + if ( (ctx->flags & MAIL_ANSWERED) > 0 ) + printf(" \\answered"); - if ( (ctx->flags & MAIL_DELETED) > 0 ) - printf(" \\deleted"); + if ( (ctx->flags & MAIL_DELETED) > 0 ) + printf(" \\deleted"); - if ( (ctx->flags & MAIL_SEEN) > 0 ) - printf(" \\seen"); + if ( (ctx->flags & MAIL_SEEN) > 0 ) + printf(" \\seen"); - if ( (ctx->flags & MAIL_DRAFT) > 0 ) - printf(" \\draft"); + if ( (ctx->flags & MAIL_DRAFT) > 0 ) + printf(" \\draft"); - for ( i = 0; i < array_count(&ctx->keywords); i++ ) { - const char *const *keyword = array_idx(&ctx->keywords, i); - printf(" %s", *keyword); - }; + for ( i = 0; i < array_count(&ctx->keywords); i++ ) { + const char *const *keyword = array_idx(&ctx->keywords, i); + printf(" %s", *keyword); + }; + } printf("\n"); - - *keep = TRUE; } static bool seff_flags_pre_execute diff --git a/src/lib-sieve/sieve-result.c b/src/lib-sieve/sieve-result.c index bfdd716687fcf119ce6cf4b4b4c221212d54a6a7..3319f0c95a046317c430d9a721245eaa0ff646b8 100644 --- a/src/lib-sieve/sieve-result.c +++ b/src/lib-sieve/sieve-result.c @@ -329,26 +329,71 @@ bool sieve_result_print(struct sieve_result *result) return TRUE; } -static bool sieve_result_implicit_keep(struct sieve_result *result) +static bool sieve_result_implicit_keep + (struct sieve_result *result, bool rollback) { bool success = TRUE; bool dummy = TRUE; struct act_store_context ctx; + struct sieve_result_side_effect *rsef, *rsef_first = NULL; void *tr_context; ctx.folder = result->action_env.scriptenv->inbox; - /* FIXME: Handle persistent side-effects for the (implicit) keep action */ + /* Also apply any implicit side effects if applicable */ + if ( !rollback && result->implicit_seffects != NULL ) { + struct sieve_result_implicit_side_effects *implseff; + + /* Check for implicit side effects to store action */ + implseff = (struct sieve_result_implicit_side_effects *) + hash_lookup(result->implicit_seffects, &act_store); + + if ( implseff != NULL && implseff->seffects != NULL ) + rsef_first = implseff->seffects->first_effect; + + } success = act_store.start (&act_store, &result->action_env, (void *) &ctx, &tr_context); + rsef = rsef_first; + while ( rsef != NULL ) { + const struct sieve_side_effect *sef = rsef->seffect; + if ( sef->pre_execute != NULL ) + success = success & sef->pre_execute + (sef, &act_store, &result->action_env, &rsef->context, tr_context); + rsef = rsef->next; + } + success = success && act_store.execute - (&act_store, &result->action_env, tr_context); + (&act_store, &result->action_env, tr_context); + + rsef = rsef_first; + while ( rsef != NULL ) { + const struct sieve_side_effect *sef = rsef->seffect; + if ( sef->post_execute != NULL ) + success = success && sef->post_execute + (sef, &act_store, &result->action_env, rsef->context, tr_context); + rsef = rsef->next; + } if ( success ) { - return act_store.commit - (&act_store, &result->action_env, tr_context, &dummy); + success = act_store.commit + (&act_store, &result->action_env, tr_context, &dummy); + + rsef = rsef_first; + while ( rsef != NULL ) { + const struct sieve_side_effect *sef = rsef->seffect; + bool keep = TRUE; + + if ( sef->post_commit != NULL ) + sef->post_commit + (sef, &act_store, &result->action_env, rsef->context, tr_context, + &keep); + rsef = rsef->next; + } + + return success; } act_store.rollback(&act_store, &result->action_env, tr_context, success); @@ -494,7 +539,7 @@ int sieve_result_execute if ( !commit_ok || implicit_keep ) { printf("Executing implicit keep\n"); - if ( !sieve_result_implicit_keep(result) ) + if ( !sieve_result_implicit_keep(result, !commit_ok) ) return -1; return ( commit_ok ? 1 /* Success */ : 0 /* Implicit keep executed */ );