const struct sieve_enotify_method *sieve_enotify_method_register (struct sieve_instance *svinst, const struct sieve_enotify_method_def *nmth_def) { const struct sieve_extension *ntfy_ext = sieve_extension_get_by_name(svinst, "enotify"); if ( ntfy_ext != NULL ) { struct ext_enotify_context *ectx = (struct ext_enotify_context *) ntfy_ext->context; return ext_enotify_method_register(svinst, ectx, nmth_def); } return NULL; }
static int _read_extensions(struct sieve_binary_block *sblock) { struct sieve_binary *sbin = sblock->sbin; sieve_size_t offset = 0; unsigned int i, count; bool result = 1; if ( !sieve_binary_read_unsigned(sblock, &offset, &count) ) return -1; for ( i = 0; result > 0 && i < count; i++ ) { T_BEGIN { string_t *extension; const struct sieve_extension *ext; unsigned int version; if ( sieve_binary_read_string(sblock, &offset, &extension) ) { ext = sieve_extension_get_by_name(sbin->svinst, str_c(extension)); if ( ext == NULL ) { sieve_sys_error(sbin->svinst, "binary open: binary %s requires unknown extension `%s'", sbin->path, str_sanitize(str_c(extension), 128)); result = 0; } else { struct sieve_binary_extension_reg *ereg = NULL; (void) sieve_binary_extension_register(sbin, ext, &ereg); if ( !sieve_binary_read_unsigned(sblock, &offset, &version) || !sieve_binary_read_unsigned(sblock, &offset, &ereg->block_id) ) { result = -1; } else if ( !sieve_extension_version_is(ext, version) ) { sieve_sys_debug(sbin->svinst, "binary open: binary %s was compiled with different version " "of the `%s' extension (compiled v%d, expected v%d;" "automatically fixed when re-compiled)", sbin->path, sieve_extension_name(ext), version, sieve_extension_version(ext)); result = 0; } } } else result = -1; } T_END; } return result; }
void sieve_enotify_method_unregister (const struct sieve_enotify_method *nmth) { struct sieve_instance *svinst = nmth->svinst; const struct sieve_extension *ntfy_ext = sieve_extension_get_by_name(svinst, "enotify"); if ( ntfy_ext != NULL ) { struct ext_enotify_context *ectx = (struct ext_enotify_context *) ntfy_ext->context; int nmth_id = nmth->id; if ( nmth_id >= 0 && nmth_id < (int)array_count(&ectx->notify_methods) ) { struct sieve_enotify_method *nmth_mod = array_idx_modifiable(&ectx->notify_methods, nmth_id); nmth_mod->def = NULL; } } }
static int cmd_test_config_reload_operation_execute (const struct sieve_runtime_env *renv, sieve_size_t *address) { const struct sieve_extension *ext; int opt_code = 0; string_t *extension = NULL; int ret; /* * Read operands */ /* Optional operands */ for (;;) { int opt; if ( (opt=sieve_opr_optional_read(renv, address, &opt_code)) < 0 ) return SIEVE_EXEC_BIN_CORRUPT; if ( opt == 0 ) break; switch ( opt_code ) { case OPT_EXTENSION: ret = sieve_opr_string_read(renv, address, "extension", &extension); break; default: sieve_runtime_trace_error(renv, "unknown optional operand"); ret = SIEVE_EXEC_BIN_CORRUPT; } if ( ret <= 0 ) return ret; } /* * Perform operation */ if ( sieve_runtime_trace_active(renv, SIEVE_TRLVL_COMMANDS) ) { sieve_runtime_trace(renv, 0, "testsuite: test_config_reload command"); sieve_runtime_trace_descend(renv); } if ( extension == NULL ) { if ( sieve_runtime_trace_active(renv, SIEVE_TRLVL_COMMANDS) ) { sieve_runtime_trace(renv, 0, "reload configuration for sieve engine"); } sieve_settings_load(renv->svinst); } else { if ( sieve_runtime_trace_active(renv, SIEVE_TRLVL_COMMANDS) ) { sieve_runtime_trace(renv, 0, "reload configuration for extension `%s'", str_c(extension)); } ext = sieve_extension_get_by_name(renv->svinst, str_c(extension)); if ( ext == NULL ) { testsuite_test_failf("test_config_reload: " "unknown extension '%s'", str_c(extension)); return SIEVE_EXEC_OK; } sieve_extension_reload(ext); } return SIEVE_EXEC_OK; }
static bool tst_ihave_validate (struct sieve_validator *valdtr, struct sieve_command *tst) { struct _capability { const struct sieve_extension *ext; struct sieve_ast_argument *arg; }; struct sieve_ast_argument *arg = tst->first_positional; struct sieve_ast_argument *stritem; enum sieve_compile_flags cpflags = sieve_validator_compile_flags(valdtr); bool no_global = ( (cpflags & SIEVE_COMPILE_FLAG_NOGLOBAL) != 0 ); ARRAY(struct _capability) capabilities; struct _capability capability; const struct _capability *caps; unsigned int i, count; bool all_known = TRUE; t_array_init(&capabilities, 64); tst->data = (void *) FALSE; /* Check stringlist argument */ if ( !sieve_validate_positional_argument (valdtr, tst, arg, "capabilities", 1, SAAT_STRING_LIST) ) { return FALSE; } switch ( sieve_ast_argument_type(arg) ) { case SAAT_STRING: /* Single string */ capability.arg = arg; capability.ext = sieve_extension_get_by_name (tst->ext->svinst, sieve_ast_argument_strc(arg)); if ( capability.ext == NULL || (no_global && capability.ext->global)) { all_known = FALSE; ext_ihave_ast_add_missing_extension (tst->ext, tst->ast_node->ast, sieve_ast_argument_strc(arg)); } else { array_append(&capabilities, &capability, 1); } break; case SAAT_STRING_LIST: /* String list */ stritem = sieve_ast_strlist_first(arg); while ( stritem != NULL ) { capability.arg = stritem; capability.ext = sieve_extension_get_by_name (tst->ext->svinst, sieve_ast_argument_strc(stritem)); if ( capability.ext == NULL || (no_global && capability.ext->global)) { all_known = FALSE; ext_ihave_ast_add_missing_extension (tst->ext, tst->ast_node->ast, sieve_ast_argument_strc(stritem)); } else { array_append(&capabilities, &capability, 1); } stritem = sieve_ast_strlist_next(stritem); } break; default: i_unreached(); } if ( !all_known ) return TRUE; /* RFC 5463, Section 4, page 4: * * The "ihave" extension is designed to be used with other extensions * that add tests, actions, comparators, or arguments. Implementations * MUST NOT allow it to be used with extensions that change the * underlying Sieve grammar, or extensions like encoded-character * [RFC5228], or variables [RFC5229] that change how the content of * Sieve scripts are interpreted. The test MUST fail and the extension * MUST NOT be enabled if such usage is attempted. * * FIXME: current implementation of this restriction is hardcoded and * therefore highly inflexible */ caps = array_get(&capabilities, &count); for ( i = 0; i < count; i++ ) { if ( sieve_extension_name_is(caps[i].ext, "variables") || sieve_extension_name_is(caps[i].ext, "encoded-character") ) return TRUE; } /* Load all extensions */ caps = array_get(&capabilities, &count); for ( i = 0; i < count; i++ ) { if ( !sieve_validator_extension_load (valdtr, tst, caps[i].arg, caps[i].ext) ) return FALSE; } tst->data = (void *) TRUE; return TRUE; }
if ( sieve_extension_is(ext, spamtest_extension) ) { /* Register validator extension to warn for duplicate */ sieve_validator_extension_register (valdtr, ext, &spamtest_validator_extension, NULL); } sieve_validator_register_command(valdtr, ext, &spamtest_test); } return TRUE; } static bool ext_spamtest_validator_extension_validate (const struct sieve_extension *ext, struct sieve_validator *valdtr, void *context ATTR_UNUSED, struct sieve_ast_argument *require_arg) { const struct sieve_extension *ext_spamtestplus = sieve_extension_get_by_name(ext->svinst, "spamtestplus"); if ( ext_spamtestplus != NULL && sieve_validator_extension_loaded(valdtr, ext_spamtestplus) ) { sieve_argument_validate_warning(valdtr, require_arg, "the spamtest and spamtestplus extensions should not be specified " "at the same time"); } return TRUE; }