diff --git a/src/lib-sieve/sieve-extensions.c b/src/lib-sieve/sieve-extensions.c index 67ef66bddb552de6dfc0a47bf301950786782691..7af86ff1babec7047b374698a3c401c88c5c7e6e 100644 --- a/src/lib-sieve/sieve-extensions.c +++ b/src/lib-sieve/sieve-extensions.c @@ -273,13 +273,21 @@ void sieve_extensions_configure(struct sieve_instance *svinst) /* Apply sieve_extensions configuration */ - if ( (extensions=sieve_setting_get(svinst, "sieve_extensions")) != NULL ) - sieve_extensions_set_string(svinst, extensions, FALSE); + if ( (extensions=sieve_setting_get + (svinst, "sieve_extensions")) != NULL ) + sieve_extensions_set_string(svinst, extensions, FALSE, FALSE); /* Apply sieve_global_extensions configuration */ - if ( (extensions=sieve_setting_get(svinst, "sieve_global_extensions")) != NULL ) - sieve_extensions_set_string(svinst, extensions, TRUE); + if ( (extensions=sieve_setting_get + (svinst, "sieve_global_extensions")) != NULL ) + sieve_extensions_set_string(svinst, extensions, TRUE, FALSE); + + /* Apply sieve_implicit_extensions configuration */ + + if ( (extensions=sieve_setting_get + (svinst, "sieve_implicit_extensions")) != NULL ) + sieve_extensions_set_string(svinst, extensions, FALSE, TRUE); } void sieve_extensions_deinit(struct sieve_instance *svinst) @@ -494,13 +502,23 @@ void sieve_extension_override (*mod_ext)->overridden = TRUE; } -int sieve_extensions_get_count(struct sieve_instance *svinst) +unsigned int sieve_extensions_get_count(struct sieve_instance *svinst) { struct sieve_extension_registry *ext_reg = svinst->ext_reg; return array_count(&ext_reg->extensions); } +const struct sieve_extension *const * +sieve_extensions_get_all(struct sieve_instance *svinst, + unsigned int *count_r) +{ + struct sieve_extension_registry *ext_reg = svinst->ext_reg; + + return (const struct sieve_extension *const *) + array_get(&ext_reg->extensions, count_r); +} + const struct sieve_extension *sieve_extension_get_by_id (struct sieve_instance *svinst, unsigned int ext_id) { @@ -580,7 +598,6 @@ static void sieve_extension_set_enabled { if ( enabled ) { ext->enabled = TRUE; - ext->global = FALSE; if ( !ext->loaded ) { (void)_sieve_extension_load(ext); @@ -596,21 +613,27 @@ static void sieve_extension_set_global (struct sieve_extension *ext, bool enabled) { if ( enabled ) { - ext->enabled = TRUE; + sieve_extension_set_enabled(ext, TRUE); ext->global = TRUE; - - if ( !ext->loaded ) { - (void)_sieve_extension_load(ext); - } - - ext->loaded = TRUE; } else { ext->global = FALSE; } } +static void sieve_extension_set_implicit +(struct sieve_extension *ext, bool enabled) +{ + if ( enabled ) { + sieve_extension_set_enabled(ext, TRUE); + ext->implicit = TRUE; + } else { + ext->implicit = FALSE; + } +} + void sieve_extensions_set_string -(struct sieve_instance *svinst, const char *ext_string, bool global) +(struct sieve_instance *svinst, const char *ext_string, + bool global, bool implicit) { struct sieve_extension_registry *ext_reg = svinst->ext_reg; ARRAY(const struct sieve_extension *) enabled_extensions; @@ -623,7 +646,7 @@ void sieve_extensions_set_string bool relative = FALSE; if ( ext_string == NULL ) { - if ( global ) return; + if ( global || implicit ) return; /* Enable all */ exts = array_get_modifiable(&ext_reg->extensions, &ext_count); @@ -696,6 +719,8 @@ void sieve_extensions_set_string if ( relative ) { if ( global ) enabled = exts[i]->global; + else if ( implicit ) + enabled = exts[i]->implicit; else enabled = exts[i]->enabled; @@ -722,6 +747,8 @@ void sieve_extensions_set_string /* Perform actual activation/deactivation */ if ( global ) { sieve_extension_set_global(exts[i], enabled); + } else if ( implicit ) { + sieve_extension_set_implicit(exts[i], enabled); } else { sieve_extension_set_enabled(exts[i], enabled); } diff --git a/src/lib-sieve/sieve-extensions.h b/src/lib-sieve/sieve-extensions.h index 6cf0529c182b98812321d18dad20fc24d420e968..760d44bb39b57758a48392a837d3ed217c717654 100644 --- a/src/lib-sieve/sieve-extensions.h +++ b/src/lib-sieve/sieve-extensions.h @@ -95,6 +95,7 @@ struct sieve_extension { unsigned int enabled:1; unsigned int dummy:1; unsigned int global:1; + unsigned int implicit:1; unsigned int overridden:1; }; @@ -142,7 +143,10 @@ void sieve_extension_override (struct sieve_instance *svinst, const char *name, const struct sieve_extension *ext); -int sieve_extensions_get_count(struct sieve_instance *svinst); +unsigned int sieve_extensions_get_count(struct sieve_instance *svinst); +const struct sieve_extension *const * +sieve_extensions_get_all(struct sieve_instance *svinst, + unsigned int *count_r); const struct sieve_extension *sieve_extension_get_by_id (struct sieve_instance *svinst, unsigned int ext_id); @@ -152,7 +156,8 @@ const struct sieve_extension *sieve_extension_get_by_name const char *sieve_extensions_get_string (struct sieve_instance *svinst); void sieve_extensions_set_string - (struct sieve_instance *svinst, const char *ext_string, bool global); + (struct sieve_instance *svinst, const char *ext_string, + bool global, bool implicit); const struct sieve_extension *sieve_get_match_type_extension (struct sieve_instance *svinst); diff --git a/src/lib-sieve/sieve-validator.c b/src/lib-sieve/sieve-validator.c index 58dceddb4af68fc26ba291a2cd64fdc2056bbd3c..77ab8440c65780e053db1c824be6b2382ef36f66 100644 --- a/src/lib-sieve/sieve-validator.c +++ b/src/lib-sieve/sieve-validator.c @@ -1372,10 +1372,20 @@ static bool sieve_validate_block && !valdtr->finished_require && strcasecmp(cmd_node->identifier, cmd_require.identifier) != 0 ) { const struct sieve_validator_extension_reg *extrs; + const struct sieve_extension *const *exts; unsigned int ext_count, i; valdtr->finished_require = TRUE; + /* Load implicit extensions */ + exts = sieve_extensions_get_all(valdtr->svinst, &ext_count); + for (i = 0; i < ext_count; i++) { + if ( exts[i]->implicit ) { + (void)sieve_validator_extension_load + (valdtr, NULL, NULL, exts[i]); + } + } + /* Validate all 'require'd extensions */ extrs = array_get(&valdtr->extensions, &ext_count); for ( i = 0; i < ext_count; i++ ) { diff --git a/src/lib-sieve/sieve-validator.h b/src/lib-sieve/sieve-validator.h index 3a350573e400a3d5b4db4f75a0f80e753ae5e97c..857b7b2ffc4680965f5eba75244a58157eff7145 100644 --- a/src/lib-sieve/sieve-validator.h +++ b/src/lib-sieve/sieve-validator.h @@ -138,7 +138,8 @@ struct sieve_validator_extension { bool sieve_validator_extension_load (struct sieve_validator *valdtr, struct sieve_command *cmd, - struct sieve_ast_argument *ext_arg, const struct sieve_extension *ext); + struct sieve_ast_argument *ext_arg, const struct sieve_extension *ext) + ATTR_NULL(2, 3); const struct sieve_extension *sieve_validator_extension_load_by_name (struct sieve_validator *valdtr, struct sieve_command *cmd, struct sieve_ast_argument *ext_arg, const char *ext_name); diff --git a/src/lib-sieve/sieve.c b/src/lib-sieve/sieve.c index 5d28fd3549d86980d42941ff7e67d67c1e347861..84fbc89d580b1beae0b90fc13ed1214e6ba7833a 100644 --- a/src/lib-sieve/sieve.c +++ b/src/lib-sieve/sieve.c @@ -132,7 +132,7 @@ void sieve_deinit(struct sieve_instance **_svinst) void sieve_set_extensions (struct sieve_instance *svinst, const char *extensions) { - sieve_extensions_set_string(svinst, extensions, FALSE); + sieve_extensions_set_string(svinst, extensions, FALSE, FALSE); } const char *sieve_get_capabilities