From 65583101b7765dcdf509a67b4088382d45b7bc32 Mon Sep 17 00:00:00 2001 From: Stephan Bosch <stephan@rename-it.nl> Date: Mon, 2 Nov 2009 01:01:08 +0100 Subject: [PATCH] Major rework of extension handling, making sure that no global state is maintained. --- src/lib-sieve-tool/sieve-tool.c | 15 +- src/lib-sieve-tool/sieve-tool.h | 6 + src/lib-sieve/cmd-discard.c | 50 +- src/lib-sieve/cmd-if.c | 84 +- src/lib-sieve/cmd-keep.c | 42 +- src/lib-sieve/cmd-redirect.c | 77 +- src/lib-sieve/cmd-require.c | 21 +- src/lib-sieve/cmd-stop.c | 24 +- src/lib-sieve/cmp-i-ascii-casemap.c | 2 +- src/lib-sieve/cmp-i-octet.c | 2 +- src/lib-sieve/ext-encoded-character.c | 31 +- src/lib-sieve/ext-envelope.c | 105 +-- src/lib-sieve/ext-fileinto.c | 57 +- src/lib-sieve/ext-reject.c | 145 ++-- src/lib-sieve/mcht-contains.c | 6 +- src/lib-sieve/mcht-is.c | 6 +- src/lib-sieve/mcht-matches.c | 13 +- src/lib-sieve/plugins/Makefile.am | 1 + src/lib-sieve/plugins/body/ext-body-common.c | 14 +- src/lib-sieve/plugins/body/ext-body-common.h | 6 +- src/lib-sieve/plugins/body/ext-body.c | 13 +- src/lib-sieve/plugins/body/tst-body.c | 110 +-- .../ext-cmp-i-ascii-numeric.c | 27 +- src/lib-sieve/plugins/copy/ext-copy.c | 54 +- src/lib-sieve/plugins/date/ext-date-common.c | 20 +- src/lib-sieve/plugins/date/ext-date-common.h | 13 +- src/lib-sieve/plugins/date/ext-date.c | 17 +- src/lib-sieve/plugins/date/tst-date.c | 149 ++-- src/lib-sieve/plugins/enotify/cmd-notify.c | 128 ++- .../plugins/enotify/ext-enotify-common.c | 56 +- .../plugins/enotify/ext-enotify-common.h | 42 +- src/lib-sieve/plugins/enotify/ext-enotify.c | 50 +- .../plugins/enotify/sieve-ext-enotify.h | 3 +- .../enotify/tst-notify-method-capability.c | 67 +- .../plugins/enotify/tst-valid-notify-method.c | 32 +- .../plugins/enotify/vmodf-encodeurl.c | 4 +- .../environment/ext-environment-common.c | 65 +- .../environment/ext-environment-common.h | 15 +- .../plugins/environment/ext-environment.c | 12 +- .../environment/sieve-ext-environment.h | 3 +- .../plugins/environment/tst-environment.c | 66 +- src/lib-sieve/plugins/imap4flags/cmd-flag.c | 82 +- .../imap4flags/ext-imap4flags-common.c | 94 +- .../imap4flags/ext-imap4flags-common.h | 30 +- .../plugins/imap4flags/ext-imap4flags.c | 32 +- .../plugins/imap4flags/ext-imapflags.c | 80 +- src/lib-sieve/plugins/imap4flags/tag-flags.c | 126 +-- .../plugins/imap4flags/tst-hasflag.c | 54 +- src/lib-sieve/plugins/include/cmd-global.c | 116 +-- src/lib-sieve/plugins/include/cmd-include.c | 113 ++- src/lib-sieve/plugins/include/cmd-return.c | 19 +- .../plugins/include/ext-include-binary.c | 114 +-- .../plugins/include/ext-include-binary.h | 13 +- .../plugins/include/ext-include-common.c | 118 +-- .../plugins/include/ext-include-common.h | 56 +- .../plugins/include/ext-include-variables.c | 14 +- .../plugins/include/ext-include-variables.h | 5 +- src/lib-sieve/plugins/include/ext-include.c | 74 +- .../plugins/mailbox/ext-mailbox-common.h | 10 +- src/lib-sieve/plugins/mailbox/ext-mailbox.c | 15 +- .../plugins/mailbox/tag-mailbox-create.c | 31 +- .../plugins/mailbox/tst-mailboxexists.c | 30 +- src/lib-sieve/plugins/notify/cmd-denotify.c | 76 +- src/lib-sieve/plugins/notify/cmd-notify.c | 115 ++- .../plugins/notify/ext-notify-common.c | 48 +- .../plugins/notify/ext-notify-common.h | 12 +- src/lib-sieve/plugins/notify/ext-notify.c | 33 +- .../plugins/regex/ext-regex-common.c | 2 +- .../plugins/regex/ext-regex-common.h | 6 +- src/lib-sieve/plugins/regex/ext-regex.c | 13 +- src/lib-sieve/plugins/regex/mcht-regex.c | 38 +- .../relational/ext-relational-common.c | 28 +- .../relational/ext-relational-common.h | 35 +- .../plugins/relational/ext-relational.c | 15 +- src/lib-sieve/plugins/relational/mcht-count.c | 4 +- src/lib-sieve/plugins/relational/mcht-value.c | 8 +- .../plugins/subaddress/ext-subaddress.c | 91 +- src/lib-sieve/plugins/vacation/cmd-vacation.c | 194 +++-- .../plugins/vacation/ext-vacation-common.h | 6 +- src/lib-sieve/plugins/vacation/ext-vacation.c | 13 +- src/lib-sieve/plugins/variables/cmd-set.c | 134 +-- .../variables/ext-variables-arguments.c | 118 +-- .../variables/ext-variables-arguments.h | 6 +- .../plugins/variables/ext-variables-common.c | 96 ++- .../plugins/variables/ext-variables-common.h | 42 +- .../plugins/variables/ext-variables-dump.c | 37 +- .../plugins/variables/ext-variables-dump.h | 7 +- .../variables/ext-variables-modifiers.c | 81 +- .../variables/ext-variables-modifiers.h | 34 +- .../variables/ext-variables-operands.c | 76 +- .../variables/ext-variables-operands.h | 22 +- .../plugins/variables/ext-variables.c | 24 +- .../plugins/variables/sieve-ext-variables.h | 54 +- src/lib-sieve/plugins/variables/tst-string.c | 62 +- src/lib-sieve/sieve-actions.c | 79 +- src/lib-sieve/sieve-actions.h | 95 +- src/lib-sieve/sieve-address-parts.c | 165 ++-- src/lib-sieve/sieve-address-parts.h | 68 +- src/lib-sieve/sieve-ast.c | 41 +- src/lib-sieve/sieve-ast.h | 18 +- src/lib-sieve/sieve-binary-dumper.c | 9 +- src/lib-sieve/sieve-binary.c | 137 +-- src/lib-sieve/sieve-binary.h | 30 +- src/lib-sieve/sieve-code-dumper.c | 53 +- src/lib-sieve/sieve-code-dumper.h | 4 +- src/lib-sieve/sieve-code.c | 347 ++++---- src/lib-sieve/sieve-code.h | 103 ++- src/lib-sieve/sieve-commands.c | 135 +-- src/lib-sieve/sieve-commands.h | 166 ++-- src/lib-sieve/sieve-common.h | 24 + src/lib-sieve/sieve-comparators.c | 150 ++-- src/lib-sieve/sieve-comparators.h | 64 +- src/lib-sieve/sieve-dump.h | 6 + src/lib-sieve/sieve-extensions.c | 479 ++++++----- src/lib-sieve/sieve-extensions.h | 105 ++- src/lib-sieve/sieve-generator.c | 132 +-- src/lib-sieve/sieve-generator.h | 11 +- src/lib-sieve/sieve-interpreter.c | 135 ++- src/lib-sieve/sieve-interpreter.h | 24 +- src/lib-sieve/sieve-match-types.c | 231 ++--- src/lib-sieve/sieve-match-types.h | 88 +- src/lib-sieve/sieve-match.c | 41 +- src/lib-sieve/sieve-match.h | 3 +- src/lib-sieve/sieve-message.c | 17 +- src/lib-sieve/sieve-message.h | 2 +- src/lib-sieve/sieve-objects.c | 83 +- src/lib-sieve/sieve-objects.h | 43 +- src/lib-sieve/sieve-result.c | 409 ++++----- src/lib-sieve/sieve-result.h | 23 +- src/lib-sieve/sieve-script-private.h | 7 +- src/lib-sieve/sieve-script.c | 22 +- src/lib-sieve/sieve-script.h | 6 +- src/lib-sieve/sieve-types.h | 11 + src/lib-sieve/sieve-validator.c | 813 ++++++++++-------- src/lib-sieve/sieve-validator.h | 96 ++- src/lib-sieve/sieve.c | 87 +- src/lib-sieve/sieve.h | 29 +- src/lib-sieve/tst-address.c | 58 +- src/lib-sieve/tst-allof.c | 10 +- src/lib-sieve/tst-anyof.c | 8 +- src/lib-sieve/tst-exists.c | 28 +- src/lib-sieve/tst-header.c | 52 +- src/lib-sieve/tst-not.c | 6 +- src/lib-sieve/tst-size.c | 89 +- src/lib-sieve/tst-truefalse.c | 16 +- src/plugins/lda-sieve/lda-sieve-plugin.c | 62 +- src/sieve-tools/debug/cmd-debug-print.c | 32 +- src/sieve-tools/debug/ext-debug-common.h | 4 +- src/sieve-tools/debug/ext-debug.c | 13 +- src/sieve-tools/debug/sieve-ext-debug.h | 2 +- src/sieve-tools/sieve-filter.c | 4 +- src/sieve-tools/sieve-test.c | 8 +- src/sieve-tools/sievec.c | 4 +- src/sieve-tools/sieved.c | 6 +- src/testsuite/cmd-test-binary.c | 73 +- src/testsuite/cmd-test-fail.c | 30 +- src/testsuite/cmd-test-mailbox.c | 69 +- src/testsuite/cmd-test-message.c | 85 +- src/testsuite/cmd-test-result-print.c | 18 +- src/testsuite/cmd-test-result-reset.c | 18 +- src/testsuite/cmd-test-set.c | 40 +- src/testsuite/cmd-test.c | 44 +- src/testsuite/ext-testsuite.c | 82 +- src/testsuite/testsuite-arguments.c | 10 +- src/testsuite/testsuite-arguments.h | 2 +- src/testsuite/testsuite-binary.c | 3 +- src/testsuite/testsuite-common.c | 18 +- src/testsuite/testsuite-common.h | 81 +- src/testsuite/testsuite-objects.c | 152 ++-- src/testsuite/testsuite-objects.h | 45 +- src/testsuite/testsuite-result.c | 6 +- src/testsuite/testsuite-script.c | 9 +- src/testsuite/testsuite-substitutions.c | 120 +-- src/testsuite/testsuite-substitutions.h | 13 +- src/testsuite/testsuite.c | 5 +- src/testsuite/tst-test-error.c | 77 +- src/testsuite/tst-test-multiscript.c | 33 +- src/testsuite/tst-test-result-execute.c | 18 +- src/testsuite/tst-test-result.c | 76 +- src/testsuite/tst-test-script-compile.c | 33 +- src/testsuite/tst-test-script-run.c | 34 +- tests/compile/errors/typos.sieve | 2 +- tests/extensions/environment/basic.svtest | 9 +- .../extensions/imap4flags/multiscript.svtest | 30 +- 184 files changed, 5834 insertions(+), 4803 deletions(-) diff --git a/src/lib-sieve-tool/sieve-tool.c b/src/lib-sieve-tool/sieve-tool.c index b415906f4..390f5107c 100644 --- a/src/lib-sieve-tool/sieve-tool.c +++ b/src/lib-sieve-tool/sieve-tool.c @@ -23,6 +23,14 @@ static struct ioloop *ioloop; +/* Sieve instance */ + +struct sieve_instance *sieve_instance; + +static const struct sieve_callbacks sieve_callbacks = { + NULL +}; + /* * Signal handlers */ @@ -65,13 +73,14 @@ void sieve_tool_init(sieve_settings_func_t settings_func, bool init_lib) lib_signals_ignore(SIGALRM, FALSE); } - if ( !sieve_init(settings_func) ) + if ( (sieve_instance=sieve_init(&sieve_callbacks, NULL)) == NULL ) i_fatal("failed to initialize sieve implementation\n"); } void sieve_tool_deinit(void) { sieve_deinit(); + sieve_deinit(&sieve_instance); if ( _init_lib ) { lib_signals_deinit(); @@ -145,7 +154,7 @@ struct sieve_binary *sieve_tool_script_compile ehandler = sieve_stderr_ehandler_create(0); sieve_error_handler_accept_infolog(ehandler, TRUE); - if ( (sbin = sieve_compile(filename, name, ehandler)) == NULL ) + if ( (sbin = sieve_compile(sieve_instance, filename, name, ehandler)) == NULL ) i_error("failed to compile sieve script '%s'\n", filename); sieve_error_handler_unref(&ehandler); @@ -161,7 +170,7 @@ struct sieve_binary *sieve_tool_script_open(const char *filename) ehandler = sieve_stderr_ehandler_create(0); sieve_error_handler_accept_infolog(ehandler, TRUE); - if ( (sbin = sieve_open(filename, NULL, ehandler, NULL)) == NULL ) { + if ( (sbin = sieve_open(sieve_instance, filename, NULL, ehandler, NULL)) == NULL ) { sieve_error_handler_unref(&ehandler); i_fatal("Failed to compile sieve script\n"); } diff --git a/src/lib-sieve-tool/sieve-tool.h b/src/lib-sieve-tool/sieve-tool.h index e9c2b535f..80f12ef60 100644 --- a/src/lib-sieve-tool/sieve-tool.h +++ b/src/lib-sieve-tool/sieve-tool.h @@ -8,6 +8,12 @@ /* Functionality common to all Sieve command line tools. */ +/* + * Sieve instance + */ + +struct sieve_instance *sieve_instance; + /* * Initialization */ diff --git a/src/lib-sieve/cmd-discard.c b/src/lib-sieve/cmd-discard.c index 7dfcb4f0e..04e9b3be9 100644 --- a/src/lib-sieve/cmd-discard.c +++ b/src/lib-sieve/cmd-discard.c @@ -23,9 +23,9 @@ static bool cmd_discard_generate (const struct sieve_codegen_env *cgenv, - struct sieve_command_context *ctx ATTR_UNUSED); + struct sieve_command *ctx ATTR_UNUSED); -const struct sieve_command cmd_discard = { +const struct sieve_command_def cmd_discard = { "discard", SCT_COMMAND, 0, 0, FALSE, FALSE, @@ -39,13 +39,11 @@ const struct sieve_command cmd_discard = { */ static bool cmd_discard_operation_dump - (const struct sieve_operation *op, - const struct sieve_dumptime_env *denv, sieve_size_t *address); + (const struct sieve_dumptime_env *denv, sieve_size_t *address); static int cmd_discard_operation_execute - (const struct sieve_operation *op, - const struct sieve_runtime_env *renv, sieve_size_t *address); + (const struct sieve_runtime_env *renv, sieve_size_t *address); -const struct sieve_operation cmd_discard_operation = { +const struct sieve_operation_def cmd_discard_operation = { "DISCARD", NULL, SIEVE_OPERATION_DISCARD, @@ -58,13 +56,13 @@ const struct sieve_operation cmd_discard_operation = { */ static void act_discard_print - (const struct sieve_action *action, const struct sieve_result_print_env *rpenv, - void *context, bool *keep); + (const struct sieve_action *action, + const struct sieve_result_print_env *rpenv, bool *keep); static bool act_discard_commit (const struct sieve_action *action, const struct sieve_action_exec_env *aenv, void *tr_context, bool *keep); -const struct sieve_action act_discard = { +const struct sieve_action_def act_discard = { "discard", 0, NULL, NULL, NULL, @@ -79,13 +77,12 @@ const struct sieve_action act_discard = { */ static bool cmd_discard_generate -(const struct sieve_codegen_env *cgenv, - struct sieve_command_context *ctx ATTR_UNUSED) +(const struct sieve_codegen_env *cgenv, struct sieve_command *cmd) { - sieve_operation_emit_code(cgenv->sbin, &cmd_discard_operation); + sieve_operation_emit(cgenv->sbin, NULL, &cmd_discard_operation); /* Emit line number */ - sieve_code_source_line_emit(cgenv->sbin, sieve_command_source_line(ctx)); + sieve_code_source_line_emit(cgenv->sbin, sieve_command_source_line(cmd)); return TRUE; } @@ -95,17 +92,16 @@ static bool cmd_discard_generate */ static bool cmd_discard_operation_dump -(const struct sieve_operation *op ATTR_UNUSED, - const struct sieve_dumptime_env *denv, sieve_size_t *address) +(const struct sieve_dumptime_env *denv, sieve_size_t *address) { - sieve_code_dumpf(denv, "DISCARD"); - sieve_code_descend(denv); + sieve_code_dumpf(denv, "DISCARD"); + sieve_code_descend(denv); - /* Source line */ - if ( !sieve_code_source_line_dump(denv, address) ) - return FALSE; + /* Source line */ + if ( !sieve_code_source_line_dump(denv, address) ) + return FALSE; - return sieve_code_dumper_print_optional_operands(denv, address); + return sieve_code_dumper_print_optional_operands(denv, address); } /* @@ -113,14 +109,13 @@ static bool cmd_discard_operation_dump */ static int cmd_discard_operation_execute -(const struct sieve_operation *op ATTR_UNUSED, - const struct sieve_runtime_env *renv ATTR_UNUSED, +(const struct sieve_runtime_env *renv ATTR_UNUSED, sieve_size_t *address ATTR_UNUSED) { unsigned int source_line; /* Source line */ - if ( !sieve_code_source_line_read(renv, address, &source_line) ) { + if ( !sieve_code_source_line_read(renv, address, &source_line) ) { sieve_runtime_trace_error(renv, "failed to read source line"); return SIEVE_EXEC_BIN_CORRUPT; } @@ -128,7 +123,7 @@ static int cmd_discard_operation_execute sieve_runtime_trace(renv, "DISCARD action"); return ( sieve_result_add_action - (renv, &act_discard, NULL, source_line, NULL, 0) >= 0 ); + (renv, NULL, &act_discard, NULL, source_line, NULL, 0) >= 0 ); } /* @@ -137,8 +132,7 @@ static int cmd_discard_operation_execute static void act_discard_print (const struct sieve_action *action ATTR_UNUSED, - const struct sieve_result_print_env *rpenv, void *context ATTR_UNUSED, - bool *keep) + const struct sieve_result_print_env *rpenv, bool *keep) { sieve_result_action_printf(rpenv, "discard"); diff --git a/src/lib-sieve/cmd-if.c b/src/lib-sieve/cmd-if.c index 8cf3a19fa..b86095c79 100644 --- a/src/lib-sieve/cmd-if.c +++ b/src/lib-sieve/cmd-if.c @@ -19,11 +19,11 @@ */ static bool cmd_if_validate - (struct sieve_validator *validator, struct sieve_command_context *cmd); + (struct sieve_validator *valdtr, struct sieve_command *cmd); static bool cmd_if_generate - (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx); + (const struct sieve_codegen_env *cgenv, struct sieve_command *cmd); -const struct sieve_command cmd_if = { +const struct sieve_command_def cmd_if = { "if", SCT_COMMAND, 0, 1, TRUE, TRUE, @@ -40,9 +40,9 @@ const struct sieve_command cmd_if = { */ static bool cmd_elsif_validate - (struct sieve_validator *validator, struct sieve_command_context *cmd); + (struct sieve_validator *valdtr, struct sieve_command *cmd); -const struct sieve_command cmd_elsif = { +const struct sieve_command_def cmd_elsif = { "elsif", SCT_COMMAND, 0, 1, TRUE, TRUE, @@ -59,9 +59,9 @@ const struct sieve_command cmd_elsif = { */ static bool cmd_else_generate - (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx); + (const struct sieve_codegen_env *cgenv, struct sieve_command *cmd); -const struct sieve_command cmd_else = { +const struct sieve_command_def cmd_else = { "else", SCT_COMMAND, 0, 0, TRUE, TRUE, @@ -84,23 +84,23 @@ struct cmd_if_context_data { }; static void cmd_if_initialize_context_data -(struct sieve_command_context *cmd, struct cmd_if_context_data *previous) +(struct sieve_command *cmd, struct cmd_if_context_data *previous) { - struct cmd_if_context_data *ctx_data; + struct cmd_if_context_data *cmd_data; /* Assign context */ - ctx_data = p_new(sieve_command_pool(cmd), struct cmd_if_context_data, 1); - ctx_data->exit_jump = 0; - ctx_data->jump_generated = FALSE; + cmd_data = p_new(sieve_command_pool(cmd), struct cmd_if_context_data, 1); + cmd_data->exit_jump = 0; + cmd_data->jump_generated = FALSE; /* Update linked list of contexts */ - ctx_data->previous = previous; - ctx_data->next = NULL; + cmd_data->previous = previous; + cmd_data->next = NULL; if ( previous != NULL ) - previous->next = ctx_data; + previous->next = cmd_data; /* Assign to command context */ - cmd->data = ctx_data; + cmd->data = cmd_data; } /* @@ -108,7 +108,7 @@ static void cmd_if_initialize_context_data */ static bool cmd_if_validate -(struct sieve_validator *validator ATTR_UNUSED, struct sieve_command_context *cmd) +(struct sieve_validator *valdtr ATTR_UNUSED, struct sieve_command *cmd) { /* Start if-command structure */ cmd_if_initialize_context_data(cmd, NULL); @@ -117,26 +117,24 @@ static bool cmd_if_validate } static bool cmd_elsif_validate -(struct sieve_validator *validator, struct sieve_command_context *cmd) +(struct sieve_validator *valdtr, struct sieve_command *cmd) { - struct sieve_command_context *prev_context = - sieve_command_prev_context(cmd); + struct sieve_command *prev = sieve_command_prev(cmd); /* Check valid command placement */ - if ( prev_context == NULL || - ( prev_context->command != &cmd_if && - prev_context->command != &cmd_elsif ) ) + if ( prev == NULL || + ( !sieve_command_is(prev, cmd_if) && !sieve_command_is(prev, cmd_elsif) ) ) { - sieve_command_validate_error(validator, cmd, + sieve_command_validate_error(valdtr, cmd, "the %s command must follow an if or elseif command", - cmd->command->identifier); + sieve_command_identifier(cmd)); return FALSE; } /* Previous command in this block is 'if' or 'elsif', so we can safely refer * to its context data */ - cmd_if_initialize_context_data(cmd, prev_context->data); + cmd_if_initialize_context_data(cmd, prev->data); return TRUE; } @@ -151,9 +149,9 @@ static bool cmd_elsif_validate */ static void cmd_if_resolve_exit_jumps -(struct sieve_binary *sbin, struct cmd_if_context_data *ctx_data) +(struct sieve_binary *sbin, struct cmd_if_context_data *cmd_data) { - struct cmd_if_context_data *if_ctx = ctx_data->previous; + struct cmd_if_context_data *if_ctx = cmd_data->previous; /* Iterate backwards through all if-command contexts and resolve the * exit jumps to the current code position. @@ -166,10 +164,11 @@ static void cmd_if_resolve_exit_jumps } static bool cmd_if_generate -(const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx) +(const struct sieve_codegen_env *cgenv, struct sieve_command *cmd) { struct sieve_binary *sbin = cgenv->sbin; - struct cmd_if_context_data *ctx_data = (struct cmd_if_context_data *) ctx->data; + struct cmd_if_context_data *cmd_data = + (struct cmd_if_context_data *) cmd->data; struct sieve_ast_node *test; struct sieve_jumplist jmplist; @@ -177,29 +176,29 @@ static bool cmd_if_generate sieve_jumplist_init_temp(&jmplist, sbin); /* Generate test condition */ - test = sieve_ast_test_first(ctx->ast_node); + test = sieve_ast_test_first(cmd->ast_node); if ( !sieve_generate_test(cgenv, test, &jmplist, FALSE) ) return FALSE; /* Case true { */ - if ( !sieve_generate_block(cgenv, ctx->ast_node) ) + if ( !sieve_generate_block(cgenv, cmd->ast_node) ) return FALSE; /* Are we the final command in this if-elsif-else structure? */ - if ( ctx_data->next != NULL ) { + if ( cmd_data->next != NULL ) { /* No, generate jump to end of if-elsif-else structure (resolved later) * This of course is not necessary if the {} block contains a command * like stop at top level that unconditionally exits the block already * anyway. */ - if ( !sieve_command_block_exits_unconditionally(ctx) ) { - sieve_operation_emit_code(sbin, &sieve_jmp_operation); - ctx_data->exit_jump = sieve_binary_emit_offset(sbin, 0); - ctx_data->jump_generated = TRUE; + if ( !sieve_command_block_exits_unconditionally(cmd) ) { + sieve_operation_emit(sbin, NULL, &sieve_jmp_operation); + cmd_data->exit_jump = sieve_binary_emit_offset(sbin, 0); + cmd_data->jump_generated = TRUE; } } else { /* Yes, Resolve previous exit jumps to this point */ - cmd_if_resolve_exit_jumps(sbin, ctx_data); + cmd_if_resolve_exit_jumps(sbin, cmd_data); } /* Case false ... (subsequent elsif/else commands might generate more) */ @@ -209,16 +208,17 @@ static bool cmd_if_generate } static bool cmd_else_generate -(const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx) +(const struct sieve_codegen_env *cgenv, struct sieve_command *cmd) { - struct cmd_if_context_data *ctx_data = (struct cmd_if_context_data *) ctx->data; + struct cmd_if_context_data *cmd_data = + (struct cmd_if_context_data *) cmd->data; /* Else { */ - if ( !sieve_generate_block(cgenv, ctx->ast_node) ) + if ( !sieve_generate_block(cgenv, cmd->ast_node) ) return FALSE; /* } End: resolve all exit blocks */ - cmd_if_resolve_exit_jumps(cgenv->sbin, ctx_data); + cmd_if_resolve_exit_jumps(cgenv->sbin, cmd_data); return TRUE; } diff --git a/src/lib-sieve/cmd-keep.c b/src/lib-sieve/cmd-keep.c index dfc0abfc9..7786dd0df 100644 --- a/src/lib-sieve/cmd-keep.c +++ b/src/lib-sieve/cmd-keep.c @@ -21,10 +21,9 @@ */ static bool cmd_keep_generate - (const struct sieve_codegen_env *cgenv, - struct sieve_command_context *ctx); + (const struct sieve_codegen_env *cgenv, struct sieve_command *cmd); -const struct sieve_command cmd_keep = { +const struct sieve_command_def cmd_keep = { "keep", SCT_COMMAND, 0, 0, FALSE, FALSE, @@ -38,13 +37,11 @@ const struct sieve_command cmd_keep = { */ static bool cmd_keep_operation_dump - (const struct sieve_operation *op, - const struct sieve_dumptime_env *denv, sieve_size_t *address); + (const struct sieve_dumptime_env *denv, sieve_size_t *address); static int cmd_keep_operation_execute - (const struct sieve_operation *op, - const struct sieve_runtime_env *renv, sieve_size_t *address); + (const struct sieve_runtime_env *renv, sieve_size_t *address); -const struct sieve_operation cmd_keep_operation = { +const struct sieve_operation_def cmd_keep_operation = { "KEEP", NULL, SIEVE_OPERATION_KEEP, @@ -57,17 +54,16 @@ const struct sieve_operation cmd_keep_operation = { */ static bool cmd_keep_generate -(const struct sieve_codegen_env *cgenv, - struct sieve_command_context *ctx ATTR_UNUSED) +(const struct sieve_codegen_env *cgenv, struct sieve_command *cmd) { /* Emit opcode */ - sieve_operation_emit_code(cgenv->sbin, &cmd_keep_operation); + sieve_operation_emit(cgenv->sbin, NULL, &cmd_keep_operation); /* Emit line number */ - sieve_code_source_line_emit(cgenv->sbin, sieve_command_source_line(ctx)); + sieve_code_source_line_emit(cgenv->sbin, sieve_command_source_line(cmd)); /* Generate arguments */ - return sieve_generate_arguments(cgenv, ctx, NULL); + return sieve_generate_arguments(cgenv, cmd, NULL); } /* @@ -75,17 +71,16 @@ static bool cmd_keep_generate */ static bool cmd_keep_operation_dump -(const struct sieve_operation *op ATTR_UNUSED, - const struct sieve_dumptime_env *denv, sieve_size_t *address) +(const struct sieve_dumptime_env *denv, sieve_size_t *address) { - sieve_code_dumpf(denv, "KEEP"); - sieve_code_descend(denv); + sieve_code_dumpf(denv, "KEEP"); + sieve_code_descend(denv); - /* Source line */ - if ( !sieve_code_source_line_dump(denv, address) ) - return FALSE; + /* Source line */ + if ( !sieve_code_source_line_dump(denv, address) ) + return FALSE; - return sieve_code_dumper_print_optional_operands(denv, address); + return sieve_code_dumper_print_optional_operands(denv, address); } /* @@ -93,8 +88,7 @@ static bool cmd_keep_operation_dump */ static int cmd_keep_operation_execute -(const struct sieve_operation *op ATTR_UNUSED, - const struct sieve_runtime_env *renv ATTR_UNUSED, +(const struct sieve_runtime_env *renv ATTR_UNUSED, sieve_size_t *address ATTR_UNUSED) { struct sieve_side_effects_list *slist = NULL; @@ -104,7 +98,7 @@ static int cmd_keep_operation_execute /* Source line */ if ( !sieve_code_source_line_read(renv, address, &source_line) ) { sieve_runtime_trace_error(renv, "invalid source line"); - return SIEVE_EXEC_BIN_CORRUPT; + return SIEVE_EXEC_BIN_CORRUPT; } /* Optional operands (side effects only) */ diff --git a/src/lib-sieve/cmd-redirect.c b/src/lib-sieve/cmd-redirect.c index 996b90459..d035a2212 100644 --- a/src/lib-sieve/cmd-redirect.c +++ b/src/lib-sieve/cmd-redirect.c @@ -40,11 +40,11 @@ */ static bool cmd_redirect_validate - (struct sieve_validator *validator, struct sieve_command_context *cmd); + (struct sieve_validator *validator, struct sieve_command *cmd); static bool cmd_redirect_generate - (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx); + (const struct sieve_codegen_env *cgenv, struct sieve_command *cmd); -const struct sieve_command cmd_redirect = { +const struct sieve_command_def cmd_redirect = { "redirect", SCT_COMMAND, 1, 0, FALSE, FALSE, @@ -59,13 +59,11 @@ const struct sieve_command cmd_redirect = { */ static bool cmd_redirect_operation_dump - (const struct sieve_operation *op, - const struct sieve_dumptime_env *denv, sieve_size_t *address); + (const struct sieve_dumptime_env *denv, sieve_size_t *address); static int cmd_redirect_operation_execute - (const struct sieve_operation *op, - const struct sieve_runtime_env *renv, sieve_size_t *address); + (const struct sieve_runtime_env *renv, sieve_size_t *address); -const struct sieve_operation cmd_redirect_operation = { +const struct sieve_operation_def cmd_redirect_operation = { "REDIRECT", NULL, SIEVE_OPERATION_REDIRECT, @@ -78,19 +76,20 @@ const struct sieve_operation cmd_redirect_operation = { */ static bool act_redirect_equals - (const struct sieve_script_env *senv, const void *ctx1, const void *ctx2); + (const struct sieve_script_env *senv, const struct sieve_action *act1, + const struct sieve_action *act2); static int act_redirect_check_duplicate (const struct sieve_runtime_env *renv, - const struct sieve_action_data *act, - const struct sieve_action_data *act_other); + const struct sieve_action *act, + const struct sieve_action *act_other); static void act_redirect_print (const struct sieve_action *action, const struct sieve_result_print_env *rpenv, - void *context, bool *keep); + bool *keep); static bool act_redirect_commit (const struct sieve_action *action, const struct sieve_action_exec_env *aenv, void *tr_context, bool *keep); -const struct sieve_action act_redirect = { +const struct sieve_action_def act_redirect = { "redirect", SIEVE_ACTFLAG_TRIES_DELIVER, act_redirect_equals, @@ -111,7 +110,7 @@ struct act_redirect_context { */ static bool cmd_redirect_validate -(struct sieve_validator *validator, struct sieve_command_context *cmd) +(struct sieve_validator *validator, struct sieve_command *cmd) { struct sieve_ast_argument *arg = cmd->first_positional; @@ -159,15 +158,15 @@ static bool cmd_redirect_validate */ static bool cmd_redirect_generate -(const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx) +(const struct sieve_codegen_env *cgenv, struct sieve_command *cmd) { - sieve_operation_emit_code(cgenv->sbin, &cmd_redirect_operation); + sieve_operation_emit(cgenv->sbin, NULL, &cmd_redirect_operation); /* Emit line number */ - sieve_code_source_line_emit(cgenv->sbin, sieve_command_source_line(ctx)); + sieve_code_source_line_emit(cgenv->sbin, sieve_command_source_line(cmd)); /* Generate arguments */ - return sieve_generate_arguments(cgenv, ctx, NULL); + return sieve_generate_arguments(cgenv, cmd, NULL); } /* @@ -175,8 +174,7 @@ static bool cmd_redirect_generate */ static bool cmd_redirect_operation_dump -(const struct sieve_operation *op ATTR_UNUSED, - const struct sieve_dumptime_env *denv, sieve_size_t *address) +(const struct sieve_dumptime_env *denv, sieve_size_t *address) { sieve_code_dumpf(denv, "REDIRECT"); sieve_code_descend(denv); @@ -196,8 +194,7 @@ static bool cmd_redirect_operation_dump */ static int cmd_redirect_operation_execute -(const struct sieve_operation *op ATTR_UNUSED, - const struct sieve_runtime_env *renv, sieve_size_t *address) +(const struct sieve_runtime_env *renv, sieve_size_t *address) { struct sieve_side_effects_list *slist = NULL; struct act_redirect_context *act; @@ -226,7 +223,8 @@ static int cmd_redirect_operation_execute /* FIXME: perform address normalization if the string is not a string literal */ - sieve_runtime_trace(renv, "REDIRECT action (\"%s\")", str_sanitize(str_c(redirect), 64)); + sieve_runtime_trace(renv, "REDIRECT action (\"%s\")", + str_sanitize(str_c(redirect), 64)); /* Add redirect action to the result */ @@ -235,7 +233,8 @@ static int cmd_redirect_operation_execute act->to_address = p_strdup(pool, str_c(redirect)); ret = sieve_result_add_action - (renv, &act_redirect, slist, source_line, (void *) act, sieve_max_redirects); + (renv, NULL, &act_redirect, slist, source_line, (void *) act, + sieve_max_redirects); return ( ret >= 0 ); } @@ -246,12 +245,12 @@ static int cmd_redirect_operation_execute static bool act_redirect_equals (const struct sieve_script_env *senv ATTR_UNUSED, - const void *ctx1, const void *ctx2) + const struct sieve_action *act1, const struct sieve_action *act2) { - struct act_redirect_context *rd_ctx1 = - (struct act_redirect_context *) ctx1; + struct act_redirect_context *rd_ctx1 = + (struct act_redirect_context *) act1->context; struct act_redirect_context *rd_ctx2 = - (struct act_redirect_context *) ctx2; + (struct act_redirect_context *) act2->context; /* Address is already normalized */ return ( sieve_address_compare @@ -260,18 +259,18 @@ static bool act_redirect_equals static int act_redirect_check_duplicate (const struct sieve_runtime_env *renv ATTR_UNUSED, - const struct sieve_action_data *act, - const struct sieve_action_data *act_other) + const struct sieve_action *act, + const struct sieve_action *act_other) { - return ( act_redirect_equals - (renv->scriptenv, act->context, act_other->context) ? 1 : 0 ); + return ( act_redirect_equals(renv->scriptenv, act, act_other) ? 1 : 0 ); } static void act_redirect_print -(const struct sieve_action *action ATTR_UNUSED, - const struct sieve_result_print_env *rpenv, void *context, bool *keep) +(const struct sieve_action *action, + const struct sieve_result_print_env *rpenv, bool *keep) { - struct act_redirect_context *ctx = (struct act_redirect_context *) context; + struct act_redirect_context *ctx = + (struct act_redirect_context *) action->context; sieve_result_action_printf(rpenv, "redirect message to: %s", str_sanitize(ctx->to_address, 128)); @@ -340,10 +339,12 @@ static bool act_redirect_send } static bool act_redirect_commit -(const struct sieve_action *action ATTR_UNUSED, - const struct sieve_action_exec_env *aenv, void *tr_context, bool *keep) +(const struct sieve_action *action, + const struct sieve_action_exec_env *aenv, void *tr_context ATTR_UNUSED, + bool *keep) { - struct act_redirect_context *ctx = (struct act_redirect_context *) tr_context; + struct act_redirect_context *ctx = + (struct act_redirect_context *) action->context; const struct sieve_message_data *msgdata = aenv->msgdata; const struct sieve_script_env *senv = aenv->scriptenv; const char *dupeid; diff --git a/src/lib-sieve/cmd-require.c b/src/lib-sieve/cmd-require.c index a54f24740..0e45669b6 100644 --- a/src/lib-sieve/cmd-require.c +++ b/src/lib-sieve/cmd-require.c @@ -17,9 +17,9 @@ */ static bool cmd_require_validate - (struct sieve_validator *validator, struct sieve_command_context *cmd); + (struct sieve_validator *valdtr, struct sieve_command *cmd); -const struct sieve_command cmd_require = { +const struct sieve_command_def cmd_require = { "require", SCT_COMMAND, 1, 0, FALSE, FALSE, @@ -33,19 +33,18 @@ const struct sieve_command cmd_require = { */ static bool cmd_require_validate - (struct sieve_validator *validator, struct sieve_command_context *cmd) +(struct sieve_validator *valdtr, struct sieve_command *cmd) { bool result = TRUE; struct sieve_ast_argument *arg; - struct sieve_command_context *prev_context = - sieve_command_prev_context(cmd); + struct sieve_command *prev = sieve_command_prev(cmd); /* Check valid command placement */ if ( !sieve_command_is_toplevel(cmd) || - ( !sieve_command_is_first(cmd) && prev_context != NULL && - prev_context->command != &cmd_require ) ) + ( !sieve_command_is_first(cmd) && prev != NULL && + !sieve_command_is(prev, cmd_require) ) ) { - sieve_command_validate_error(validator, cmd, + sieve_command_validate_error(valdtr, cmd, "require commands can only be placed at top level " "at the beginning of the file"); return FALSE; @@ -57,7 +56,7 @@ static bool cmd_require_validate if ( sieve_ast_argument_type(arg) == SAAT_STRING ) { /* Single string */ const struct sieve_extension *ext = sieve_validator_extension_load - (validator, cmd, arg, sieve_ast_argument_str(arg)); + (valdtr, cmd, arg, sieve_ast_argument_str(arg)); if ( ext == NULL ) result = FALSE; @@ -67,7 +66,7 @@ static bool cmd_require_validate while ( stritem != NULL ) { const struct sieve_extension *ext = sieve_validator_extension_load - (validator, cmd, stritem, sieve_ast_strlist_str(stritem)); + (valdtr, cmd, stritem, sieve_ast_strlist_str(stritem)); if ( ext == NULL ) result = FALSE; @@ -75,7 +74,7 @@ static bool cmd_require_validate } } else { /* Something else */ - sieve_argument_validate_error(validator, arg, + sieve_argument_validate_error(valdtr, arg, "the require command accepts a single string or string list argument, " "but %s was found", sieve_ast_argument_name(arg)); diff --git a/src/lib-sieve/cmd-stop.c b/src/lib-sieve/cmd-stop.c index 595005a70..9a3bd7d79 100644 --- a/src/lib-sieve/cmd-stop.c +++ b/src/lib-sieve/cmd-stop.c @@ -16,11 +16,11 @@ static bool cmd_stop_generate (const struct sieve_codegen_env *cgenv, - struct sieve_command_context *ctx ATTR_UNUSED); + struct sieve_command *ctx ATTR_UNUSED); static bool cmd_stop_validate - (struct sieve_validator *validator, struct sieve_command_context *ctx); + (struct sieve_validator *valdtr, struct sieve_command *cmd); -const struct sieve_command cmd_stop = { +const struct sieve_command_def cmd_stop = { "stop", SCT_COMMAND, 0, 0, FALSE, FALSE, @@ -35,10 +35,9 @@ const struct sieve_command cmd_stop = { */ static int opc_stop_execute - (const struct sieve_operation *op, - const struct sieve_runtime_env *renv, sieve_size_t *address); + (const struct sieve_runtime_env *renv, sieve_size_t *address); -const struct sieve_operation cmd_stop_operation = { +const struct sieve_operation_def cmd_stop_operation = { "STOP", NULL, SIEVE_OPERATION_STOP, @@ -51,10 +50,9 @@ const struct sieve_operation cmd_stop_operation = { */ static bool cmd_stop_validate -(struct sieve_validator *validator ATTR_UNUSED, - struct sieve_command_context *ctx) +(struct sieve_validator *valdtr ATTR_UNUSED, struct sieve_command *cmd) { - sieve_command_exit_block_unconditionally(ctx); + sieve_command_exit_block_unconditionally(cmd); return TRUE; } @@ -65,9 +63,9 @@ static bool cmd_stop_validate static bool cmd_stop_generate (const struct sieve_codegen_env *cgenv, - struct sieve_command_context *ctx ATTR_UNUSED) + struct sieve_command *cmd ATTR_UNUSED) { - sieve_operation_emit_code(cgenv->sbin, &cmd_stop_operation); + sieve_operation_emit(cgenv->sbin, NULL, &cmd_stop_operation); return TRUE; } @@ -77,9 +75,7 @@ static bool cmd_stop_generate */ static int opc_stop_execute -(const struct sieve_operation *op ATTR_UNUSED, - const struct sieve_runtime_env *renv, - sieve_size_t *address ATTR_UNUSED) +(const struct sieve_runtime_env *renv, sieve_size_t *address ATTR_UNUSED) { sieve_runtime_trace(renv, "STOP"); diff --git a/src/lib-sieve/cmp-i-ascii-casemap.c b/src/lib-sieve/cmp-i-ascii-casemap.c index 5e4d4b342..230b8e422 100644 --- a/src/lib-sieve/cmp-i-ascii-casemap.c +++ b/src/lib-sieve/cmp-i-ascii-casemap.c @@ -29,7 +29,7 @@ static bool cmp_i_ascii_casemap_char_match * Comparator object */ -const struct sieve_comparator i_ascii_casemap_comparator = { +const struct sieve_comparator_def i_ascii_casemap_comparator = { SIEVE_OBJECT ("i;ascii-casemap", &comparator_operand, SIEVE_COMPARATOR_I_ASCII_CASEMAP), SIEVE_COMPARATOR_FLAG_ORDERING | SIEVE_COMPARATOR_FLAG_EQUALITY | diff --git a/src/lib-sieve/cmp-i-octet.c b/src/lib-sieve/cmp-i-octet.c index 9fb0d1fa6..be0da5c8b 100644 --- a/src/lib-sieve/cmp-i-octet.c +++ b/src/lib-sieve/cmp-i-octet.c @@ -28,7 +28,7 @@ static bool cmp_i_octet_char_match * Comparator object */ -const struct sieve_comparator i_octet_comparator = { +const struct sieve_comparator_def i_octet_comparator = { SIEVE_OBJECT("i;octet", &comparator_operand, SIEVE_COMPARATOR_I_OCTET), SIEVE_COMPARATOR_FLAG_ORDERING | SIEVE_COMPARATOR_FLAG_EQUALITY | SIEVE_COMPARATOR_FLAG_SUBSTRING_MATCH | SIEVE_COMPARATOR_FLAG_PREFIX_MATCH, diff --git a/src/lib-sieve/ext-encoded-character.c b/src/lib-sieve/ext-encoded-character.c index 24f41f74d..af88da476 100644 --- a/src/lib-sieve/ext-encoded-character.c +++ b/src/lib-sieve/ext-encoded-character.c @@ -25,13 +25,10 @@ */ static bool ext_encoded_character_validator_load - (struct sieve_validator *validator); - -static int ext_my_id = -1; + (const struct sieve_extension *ext, struct sieve_validator *valdtr); -struct sieve_extension encoded_character_extension = { +struct sieve_extension_def encoded_character_extension = { "encoded-character", - &ext_my_id, NULL, NULL, ext_encoded_character_validator_load, NULL, NULL, NULL, NULL, NULL, @@ -44,14 +41,14 @@ struct sieve_extension encoded_character_extension = { */ bool arg_encoded_string_validate - (struct sieve_validator *validator, struct sieve_ast_argument **arg, - struct sieve_command_context *context); + (struct sieve_validator *valdtr, struct sieve_ast_argument **arg, + struct sieve_command *context); -const struct sieve_argument encoded_string_argument = { +const struct sieve_argument_def encoded_string_argument = { "@encoded-string", - NULL, NULL, + NULL, arg_encoded_string_validate, - NULL, NULL + NULL, NULL, NULL }; /* Parsing */ @@ -156,8 +153,8 @@ static int _decode_unicode } bool arg_encoded_string_validate -(struct sieve_validator *validator, struct sieve_ast_argument **arg, - struct sieve_command_context *cmd) +(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, + struct sieve_command *cmd) { bool result = TRUE; enum { ST_NONE, ST_OPEN, ST_TYPE, ST_CLOSE } @@ -227,7 +224,7 @@ bool arg_encoded_string_validate /* We now know that the substitution is valid */ if ( error_hex != 0 ) { - sieve_argument_validate_error(validator, *arg, + sieve_argument_validate_error(valdtr, *arg, "invalid unicode character 0x%08x in encoded character substitution", error_hex); result = FALSE; @@ -262,7 +259,7 @@ bool arg_encoded_string_validate /* Pass the processed string to a (possible) next layer of processing */ return sieve_validator_argument_activate_super - (validator, cmd, *arg, TRUE); + (valdtr, cmd, *arg, TRUE); } /* @@ -270,11 +267,11 @@ bool arg_encoded_string_validate */ static bool ext_encoded_character_validator_load -(struct sieve_validator *validator ATTR_UNUSED) +(const struct sieve_extension *ext, struct sieve_validator *valdtr) { /* Override the constant string argument with our own */ - sieve_validator_argument_override(validator, SAT_CONST_STRING, - &encoded_string_argument); + sieve_validator_argument_override + (valdtr, SAT_CONST_STRING, ext, &encoded_string_argument); return TRUE; } diff --git a/src/lib-sieve/ext-envelope.c b/src/lib-sieve/ext-envelope.c index 9cd364339..e7c226843 100644 --- a/src/lib-sieve/ext-envelope.c +++ b/src/lib-sieve/ext-envelope.c @@ -35,21 +35,19 @@ * Forward declarations */ -static const struct sieve_command envelope_test; -const struct sieve_operation envelope_operation; -const struct sieve_extension envelope_extension; +static const struct sieve_command_def envelope_test; +const struct sieve_operation_def envelope_operation; +const struct sieve_extension_def envelope_extension; /* * Extension */ -static bool ext_envelope_validator_load(struct sieve_validator *validator); +static bool ext_envelope_validator_load +(const struct sieve_extension *ext, struct sieve_validator *valdtr); -static int ext_my_id = -1; - -const struct sieve_extension envelope_extension = { +const struct sieve_extension_def envelope_extension = { "envelope", - &ext_my_id, NULL, NULL, ext_envelope_validator_load, NULL, NULL, NULL, NULL, NULL, @@ -57,10 +55,11 @@ const struct sieve_extension envelope_extension = { SIEVE_EXT_DEFINE_NO_OPERANDS }; -static bool ext_envelope_validator_load(struct sieve_validator *validator) +static bool ext_envelope_validator_load +(const struct sieve_extension *ext, struct sieve_validator *valdtr) { /* Register new test */ - sieve_validator_register_command(validator, &envelope_test); + sieve_validator_register_command(valdtr, ext, &envelope_test); return TRUE; } @@ -74,13 +73,14 @@ static bool ext_envelope_validator_load(struct sieve_validator *validator) */ static bool tst_envelope_registered - (struct sieve_validator *validator, struct sieve_command_registration *cmd_reg); + (struct sieve_validator *valdtr, const struct sieve_extension *ext, + struct sieve_command_registration *cmd_reg); static bool tst_envelope_validate - (struct sieve_validator *validator, struct sieve_command_context *tst); + (struct sieve_validator *valdtr, struct sieve_command *tst); static bool tst_envelope_generate - (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx); + (const struct sieve_codegen_env *cgenv, struct sieve_command *ctx); -static const struct sieve_command envelope_test = { +static const struct sieve_command_def envelope_test = { "envelope", SCT_TEST, 2, 0, FALSE, FALSE, @@ -96,13 +96,11 @@ static const struct sieve_command envelope_test = { */ static bool ext_envelope_operation_dump - (const struct sieve_operation *op, - const struct sieve_dumptime_env *denv, sieve_size_t *address); + (const struct sieve_dumptime_env *denv, sieve_size_t *address); static int ext_envelope_operation_execute - (const struct sieve_operation *op, - const struct sieve_runtime_env *renv, sieve_size_t *address); + (const struct sieve_runtime_env *renv, sieve_size_t *address); -const struct sieve_operation envelope_operation = { +const struct sieve_operation_def envelope_operation = { "ENVELOPE", &envelope_extension, 0, @@ -184,12 +182,13 @@ static const struct sieve_envelope_part *_envelope_part_find */ static bool tst_envelope_registered -(struct sieve_validator *validator, struct sieve_command_registration *cmd_reg) +(struct sieve_validator *valdtr, const struct sieve_extension *ext ATTR_UNUSED, + struct sieve_command_registration *cmd_reg) { /* The order of these is not significant */ - sieve_comparators_link_tag(validator, cmd_reg, SIEVE_AM_OPT_COMPARATOR); - sieve_address_parts_link_tags(validator, cmd_reg, SIEVE_AM_OPT_ADDRESS_PART); - sieve_match_types_link_tags(validator, cmd_reg, SIEVE_AM_OPT_MATCH_TYPE); + sieve_comparators_link_tag(valdtr, cmd_reg, SIEVE_AM_OPT_COMPARATOR); + sieve_address_parts_link_tags(valdtr, cmd_reg, SIEVE_AM_OPT_ADDRESS_PART); + sieve_match_types_link_tags(valdtr, cmd_reg, SIEVE_AM_OPT_MATCH_TYPE); return TRUE; } @@ -223,18 +222,22 @@ static int _envelope_part_is_supported } static bool tst_envelope_validate -(struct sieve_validator *validator, struct sieve_command_context *tst) +(struct sieve_validator *valdtr, struct sieve_command *tst) { struct sieve_ast_argument *arg = tst->first_positional; struct sieve_ast_argument *epart; + struct sieve_comparator cmp_default = + SIEVE_COMPARATOR_DEFAULT(i_ascii_casemap_comparator); + struct sieve_match_type mcht_default = + SIEVE_MATCH_TYPE_DEFAULT(is_match_type); const struct sieve_envelope_part *not_address = NULL; if ( !sieve_validate_positional_argument - (validator, tst, arg, "envelope part", 1, SAAT_STRING_LIST) ) { + (valdtr, tst, arg, "envelope part", 1, SAAT_STRING_LIST) ) { return FALSE; } - if ( !sieve_validator_argument_activate(validator, tst, arg, FALSE) ) + if ( !sieve_validator_argument_activate(valdtr, tst, arg, FALSE) ) return FALSE; /* Check whether supplied envelope parts are supported @@ -244,7 +247,7 @@ static bool tst_envelope_validate if ( !sieve_ast_stringlist_map(&epart, (void *) ¬_address, _envelope_part_is_supported) ) { - sieve_argument_validate_error(validator, epart, + sieve_argument_validate_error(valdtr, epart, "specified envelope part '%s' is not supported by the envelope test", str_sanitize(sieve_ast_strlist_strc(epart), 64)); return FALSE; @@ -255,7 +258,7 @@ static bool tst_envelope_validate sieve_command_find_argument(tst, &address_part_tag); if ( addrp_arg != NULL ) { - sieve_argument_validate_error(validator, addrp_arg, + sieve_argument_validate_error(valdtr, addrp_arg, "address part ':%s' specified while non-address envelope part '%s' " "is tested with the envelope test", sieve_ast_argument_tag(addrp_arg), not_address->identifier); @@ -266,16 +269,16 @@ static bool tst_envelope_validate arg = sieve_ast_argument_next(arg); if ( !sieve_validate_positional_argument - (validator, tst, arg, "key list", 2, SAAT_STRING_LIST) ) { + (valdtr, tst, arg, "key list", 2, SAAT_STRING_LIST) ) { return FALSE; } - if ( !sieve_validator_argument_activate(validator, tst, arg, FALSE) ) + if ( !sieve_validator_argument_activate(valdtr, tst, arg, FALSE) ) return FALSE; /* Validate the key argument to a specified match type */ return sieve_match_type_validate - (validator, tst, arg, &is_match_type, &i_ascii_casemap_comparator); + (valdtr, tst, arg, &mcht_default, &cmp_default); } /* @@ -283,12 +286,12 @@ static bool tst_envelope_validate */ static bool tst_envelope_generate -(const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx) +(const struct sieve_codegen_env *cgenv, struct sieve_command *cmd) { - (void)sieve_operation_emit_code(cgenv->sbin, &envelope_operation); + (void)sieve_operation_emit(cgenv->sbin, cmd->ext, &envelope_operation); /* Generate arguments */ - if ( !sieve_generate_arguments(cgenv, ctx, NULL) ) + if ( !sieve_generate_arguments(cgenv, cmd, NULL) ) return FALSE; return TRUE; @@ -299,8 +302,7 @@ static bool tst_envelope_generate */ static bool ext_envelope_operation_dump -(const struct sieve_operation *op ATTR_UNUSED, - const struct sieve_dumptime_env *denv, sieve_size_t *address) +(const struct sieve_dumptime_env *denv, sieve_size_t *address) { sieve_code_dumpf(denv, "ENVELOPE"); sieve_code_descend(denv); @@ -405,13 +407,15 @@ static const char *const *_auth_part_get_values } static int ext_envelope_operation_execute -(const struct sieve_operation *op ATTR_UNUSED, - const struct sieve_runtime_env *renv, sieve_size_t *address) +(const struct sieve_runtime_env *renv, sieve_size_t *address) { bool result = TRUE; - const struct sieve_comparator *cmp = &i_ascii_casemap_comparator; - const struct sieve_match_type *mtch = &is_match_type; - const struct sieve_address_part *addrp = &all_address_part; + struct sieve_comparator cmp = + SIEVE_COMPARATOR_DEFAULT(i_ascii_casemap_comparator); + struct sieve_match_type mcht = + SIEVE_MATCH_TYPE_DEFAULT(is_match_type); + struct sieve_address_part addrp = + SIEVE_ADDRESS_PART_DEFAULT(all_address_part); struct sieve_match_context *mctx; struct sieve_coded_stringlist *envp_list; struct sieve_coded_stringlist *key_list; @@ -426,7 +430,7 @@ static int ext_envelope_operation_execute sieve_runtime_trace(renv, "ENVELOPE test"); if ( (ret=sieve_addrmatch_default_get_optionals - (renv, address, &addrp, &mtch, &cmp)) <= 0 ) + (renv, address, &addrp, &mcht, &cmp)) <= 0 ) return ret; /* Read envelope-part */ @@ -442,7 +446,7 @@ static int ext_envelope_operation_execute } /* Initialize match */ - mctx = sieve_match_begin(renv->interp, mtch, cmp, NULL, key_list); + mctx = sieve_match_begin(renv->interp, &mcht, &cmp, NULL, key_list); /* Iterate through all requested headers to match */ envp_item = NULL; @@ -466,7 +470,10 @@ static int ext_envelope_operation_execute /* Null path <> */ ret = sieve_match_value(mctx, "", 0); } else { - const char *part = addrp->extract_from(addresses[i]); + const char *part = NULL; + + if ( addrp.def != NULL && addrp.def->extract_from != NULL ) + part = addrp.def->extract_from(&addrp, addresses[i]); if ( part != NULL ) ret = sieve_match_value(mctx, part, strlen(part)); @@ -479,13 +486,13 @@ static int ext_envelope_operation_execute break; } - matched = ret > 0; + matched = ret > 0; } } } if ( epart->get_values != NULL && addresses == NULL && - addrp == &all_address_part ) { + sieve_address_part_is(&addrp, all_address_part) ) { /* Field contains something else */ const char *const *values = epart->get_values(renv); @@ -495,9 +502,9 @@ static int ext_envelope_operation_execute if ( (ret=sieve_match_value (mctx, values[i], strlen(values[i]))) < 0 ) { - result = FALSE; - break; - } + result = FALSE; + break; + } matched = ret > 0; } diff --git a/src/lib-sieve/ext-fileinto.c b/src/lib-sieve/ext-fileinto.c index e710a5dff..5a90a702d 100644 --- a/src/lib-sieve/ext-fileinto.c +++ b/src/lib-sieve/ext-fileinto.c @@ -31,21 +31,19 @@ * Forward declarations */ -static const struct sieve_command fileinto_command; -const struct sieve_operation fileinto_operation; -const struct sieve_extension fileinto_extension; +static const struct sieve_command_def fileinto_command; +const struct sieve_operation_def fileinto_operation; +const struct sieve_extension_def fileinto_extension; /* * Extension */ -static bool ext_fileinto_validator_load(struct sieve_validator *validator); +static bool ext_fileinto_validator_load +(const struct sieve_extension *ext, struct sieve_validator *valdtr); -static int ext_my_id = -1; - -const struct sieve_extension fileinto_extension = { +const struct sieve_extension_def fileinto_extension = { "fileinto", - &ext_my_id, NULL, NULL, ext_fileinto_validator_load, NULL, NULL, NULL, NULL, NULL, @@ -53,10 +51,11 @@ const struct sieve_extension fileinto_extension = { SIEVE_EXT_DEFINE_NO_OPERANDS }; -static bool ext_fileinto_validator_load(struct sieve_validator *validator) +static bool ext_fileinto_validator_load +(const struct sieve_extension *ext, struct sieve_validator *valdtr) { /* Register new command */ - sieve_validator_register_command(validator, &fileinto_command); + sieve_validator_register_command(valdtr, ext, &fileinto_command); return TRUE; } @@ -69,11 +68,11 @@ static bool ext_fileinto_validator_load(struct sieve_validator *validator) */ static bool cmd_fileinto_validate - (struct sieve_validator *validator, struct sieve_command_context *cmd); + (struct sieve_validator *valdtr, struct sieve_command *cmd); static bool cmd_fileinto_generate - (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx); + (const struct sieve_codegen_env *cgenv, struct sieve_command *ctx); -static const struct sieve_command fileinto_command = { +static const struct sieve_command_def fileinto_command = { "fileinto", SCT_COMMAND, 1, 0, FALSE, FALSE, @@ -88,13 +87,11 @@ static const struct sieve_command fileinto_command = { */ static bool ext_fileinto_operation_dump - (const struct sieve_operation *op, - const struct sieve_dumptime_env *denv, sieve_size_t *address); + (const struct sieve_dumptime_env *denv, sieve_size_t *address); static int ext_fileinto_operation_execute - (const struct sieve_operation *op, - const struct sieve_runtime_env *renv, sieve_size_t *address); + (const struct sieve_runtime_env *renv, sieve_size_t *address); -const struct sieve_operation fileinto_operation = { +const struct sieve_operation_def fileinto_operation = { "FILEINTO", &fileinto_extension, 0, @@ -107,16 +104,16 @@ const struct sieve_operation fileinto_operation = { */ static bool cmd_fileinto_validate -(struct sieve_validator *validator, struct sieve_command_context *cmd) +(struct sieve_validator *valdtr, struct sieve_command *cmd) { struct sieve_ast_argument *arg = cmd->first_positional; if ( !sieve_validate_positional_argument - (validator, cmd, arg, "folder", 1, SAAT_STRING) ) { + (valdtr, cmd, arg, "folder", 1, SAAT_STRING) ) { return FALSE; } - return sieve_validator_argument_activate(validator, cmd, arg, FALSE); + return sieve_validator_argument_activate(valdtr, cmd, arg, FALSE); } /* @@ -124,15 +121,15 @@ static bool cmd_fileinto_validate */ static bool cmd_fileinto_generate -(const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx) +(const struct sieve_codegen_env *cgenv, struct sieve_command *cmd) { - sieve_operation_emit_code(cgenv->sbin, &fileinto_operation); + sieve_operation_emit(cgenv->sbin, cmd->ext, &fileinto_operation); /* Emit line number */ - sieve_code_source_line_emit(cgenv->sbin, sieve_command_source_line(ctx)); + sieve_code_source_line_emit(cgenv->sbin, sieve_command_source_line(cmd)); /* Generate arguments */ - return sieve_generate_arguments(cgenv, ctx, NULL); + return sieve_generate_arguments(cgenv, cmd, NULL); } /* @@ -140,15 +137,14 @@ static bool cmd_fileinto_generate */ static bool ext_fileinto_operation_dump -(const struct sieve_operation *op ATTR_UNUSED, - const struct sieve_dumptime_env *denv, sieve_size_t *address) +(const struct sieve_dumptime_env *denv, sieve_size_t *address) { sieve_code_dumpf(denv, "FILEINTO"); sieve_code_descend(denv); /* Source line */ - if ( !sieve_code_source_line_dump(denv, address) ) - return FALSE; + if ( !sieve_code_source_line_dump(denv, address) ) + return FALSE; if ( !sieve_code_dumper_print_optional_operands(denv, address) ) { return FALSE; @@ -162,8 +158,7 @@ static bool ext_fileinto_operation_dump */ static int ext_fileinto_operation_execute -(const struct sieve_operation *op ATTR_UNUSED, - const struct sieve_runtime_env *renv, sieve_size_t *address) +(const struct sieve_runtime_env *renv, sieve_size_t *address) { struct sieve_side_effects_list *slist = NULL; string_t *folder, *folder_utf7; diff --git a/src/lib-sieve/ext-reject.c b/src/lib-sieve/ext-reject.c index 266994751..66490b189 100644 --- a/src/lib-sieve/ext-reject.c +++ b/src/lib-sieve/ext-reject.c @@ -40,11 +40,11 @@ * Forward declarations */ -static const struct sieve_command reject_command; -static const struct sieve_operation reject_operation; +static const struct sieve_command_def reject_command; +static const struct sieve_operation_def reject_operation; -static const struct sieve_command ereject_command; -static const struct sieve_operation ereject_operation; +static const struct sieve_command_def ereject_command; +static const struct sieve_operation_def ereject_operation; /* * Extensions @@ -52,13 +52,11 @@ static const struct sieve_operation ereject_operation; /* Reject */ -static bool ext_reject_validator_load(struct sieve_validator *validator); - -static int ext_reject_my_id = -1; +static bool ext_reject_validator_load +(const struct sieve_extension *ext, struct sieve_validator *valdtr); -const struct sieve_extension reject_extension = { +const struct sieve_extension_def reject_extension = { "reject", - &ext_reject_my_id, NULL, NULL, ext_reject_validator_load, NULL, NULL, NULL, NULL, NULL, @@ -66,23 +64,22 @@ const struct sieve_extension reject_extension = { SIEVE_EXT_DEFINE_NO_OPERANDS }; -static bool ext_reject_validator_load(struct sieve_validator *validator) +static bool ext_reject_validator_load +(const struct sieve_extension *ext, struct sieve_validator *valdtr) { /* Register new command */ - sieve_validator_register_command(validator, &reject_command); + sieve_validator_register_command(valdtr, ext, &reject_command); return TRUE; } /* EReject */ -static bool ext_ereject_validator_load(struct sieve_validator *validator); - -static int ext_ereject_my_id = -1; +static bool ext_ereject_validator_load +(const struct sieve_extension *ext, struct sieve_validator *valdtr); -const struct sieve_extension ereject_extension = { +const struct sieve_extension_def ereject_extension = { "ereject", - &ext_ereject_my_id, NULL, NULL, ext_ereject_validator_load, NULL, NULL, NULL, NULL, NULL, @@ -90,10 +87,11 @@ const struct sieve_extension ereject_extension = { SIEVE_EXT_DEFINE_NO_OPERANDS }; -static bool ext_ereject_validator_load(struct sieve_validator *validator) +static bool ext_ereject_validator_load +(const struct sieve_extension *ext, struct sieve_validator *valdtr) { /* Register new command */ - sieve_validator_register_command(validator, &ereject_command); + sieve_validator_register_command(valdtr, ext, &ereject_command); return TRUE; } @@ -105,9 +103,9 @@ static bool ext_ereject_validator_load(struct sieve_validator *validator) /* Forward declarations */ static bool cmd_reject_validate - (struct sieve_validator *validator, struct sieve_command_context *cmd); + (struct sieve_validator *valdtr, struct sieve_command *cmd); static bool cmd_reject_generate - (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx); + (const struct sieve_codegen_env *cgenv, struct sieve_command *cmd); /* Reject command * @@ -115,7 +113,7 @@ static bool cmd_reject_generate * reject <reason: string> */ -static const struct sieve_command reject_command = { +static const struct sieve_command_def reject_command = { "reject", SCT_COMMAND, 1, 0, FALSE, FALSE, @@ -131,7 +129,7 @@ static const struct sieve_command reject_command = { * ereject <reason: string> */ -static const struct sieve_command ereject_command = { +static const struct sieve_command_def ereject_command = { "ereject", SCT_COMMAND, 1, 0, FALSE, FALSE, @@ -148,15 +146,13 @@ static const struct sieve_command ereject_command = { /* Forward declarations */ static bool ext_reject_operation_dump - (const struct sieve_operation *op, - const struct sieve_dumptime_env *denv, sieve_size_t *address); + (const struct sieve_dumptime_env *denv, sieve_size_t *address); static int ext_reject_operation_execute - (const struct sieve_operation *op, - const struct sieve_runtime_env *renv, sieve_size_t *address); + (const struct sieve_runtime_env *renv, sieve_size_t *address); /* Reject operation */ -static const struct sieve_operation reject_operation = { +static const struct sieve_operation_def reject_operation = { "REJECT", &reject_extension, 0, @@ -166,7 +162,7 @@ static const struct sieve_operation reject_operation = { /* EReject operation */ -static const struct sieve_operation ereject_operation = { +static const struct sieve_operation_def ereject_operation = { "EREJECT", &ereject_extension, 0, @@ -180,20 +176,20 @@ static const struct sieve_operation ereject_operation = { static int act_reject_check_duplicate (const struct sieve_runtime_env *renv, - const struct sieve_action_data *act, - const struct sieve_action_data *act_other); + const struct sieve_action *act, + const struct sieve_action *act_other); int act_reject_check_conflict (const struct sieve_runtime_env *renv, - const struct sieve_action_data *act, - const struct sieve_action_data *act_other); + const struct sieve_action *act, + const struct sieve_action *act_other); static void act_reject_print - (const struct sieve_action *action, const struct sieve_result_print_env *rpenv, - void *context, bool *keep); + (const struct sieve_action *action, + const struct sieve_result_print_env *rpenv, bool *keep); static bool act_reject_commit (const struct sieve_action *action ATTR_UNUSED, const struct sieve_action_exec_env *aenv, void *tr_context, bool *keep); -const struct sieve_action act_reject = { +const struct sieve_action_def act_reject = { "reject", SIEVE_ACTFLAG_SENDS_RESPONSE, NULL, @@ -215,16 +211,16 @@ struct act_reject_context { */ static bool cmd_reject_validate -(struct sieve_validator *validator, struct sieve_command_context *cmd) +(struct sieve_validator *valdtr, struct sieve_command *cmd) { struct sieve_ast_argument *arg = cmd->first_positional; if ( !sieve_validate_positional_argument - (validator, cmd, arg, "reason", 1, SAAT_STRING) ) { + (valdtr, cmd, arg, "reason", 1, SAAT_STRING) ) { return FALSE; } - return sieve_validator_argument_activate(validator, cmd, arg, FALSE); + return sieve_validator_argument_activate(valdtr, cmd, arg, FALSE); } /* @@ -232,18 +228,18 @@ static bool cmd_reject_validate */ static bool cmd_reject_generate -(const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx) +(const struct sieve_codegen_env *cgenv, struct sieve_command *cmd) { - if ( ctx->command == &reject_command ) - sieve_operation_emit_code(cgenv->sbin, &reject_operation); + if ( sieve_command_is(cmd, reject_command) ) + sieve_operation_emit(cgenv->sbin, cmd->ext, &reject_operation); else - sieve_operation_emit_code(cgenv->sbin, &ereject_operation); + sieve_operation_emit(cgenv->sbin, cmd->ext, &ereject_operation); /* Emit line number */ - sieve_code_source_line_emit(cgenv->sbin, sieve_command_source_line(ctx)); + sieve_code_source_line_emit(cgenv->sbin, sieve_command_source_line(cmd)); /* Generate arguments */ - return sieve_generate_arguments(cgenv, ctx, NULL); + return sieve_generate_arguments(cgenv, cmd, NULL); } /* @@ -251,10 +247,11 @@ static bool cmd_reject_generate */ static bool ext_reject_operation_dump -(const struct sieve_operation *op, - const struct sieve_dumptime_env *denv, sieve_size_t *address) +(const struct sieve_dumptime_env *denv, sieve_size_t *address) { - sieve_code_dumpf(denv, "%s", op->mnemonic); + const struct sieve_operation *op = &denv->oprtn; + + sieve_code_dumpf(denv, "%s", sieve_operation_mnemonic(op)); sieve_code_descend(denv); /* Source line */ @@ -272,9 +269,10 @@ static bool ext_reject_operation_dump */ static int ext_reject_operation_execute -(const struct sieve_operation *op, - const struct sieve_runtime_env *renv, sieve_size_t *address) +(const struct sieve_runtime_env *renv, sieve_size_t *address) { + const struct sieve_operation *op = &renv->oprtn; + const struct sieve_extension *this_ext = op->ext; struct sieve_side_effects_list *slist = NULL; struct act_reject_context *act; string_t *reason; @@ -299,16 +297,17 @@ static int ext_reject_operation_execute return SIEVE_EXEC_BIN_CORRUPT; } - sieve_runtime_trace(renv, "%s action (\"%s\")", op->mnemonic, str_sanitize(str_c(reason), 64)); + sieve_runtime_trace(renv, "%s action (\"%s\")", sieve_operation_mnemonic(op), + str_sanitize(str_c(reason), 64)); /* Add reject action to the result */ pool = sieve_result_pool(renv->result); act = p_new(pool, struct act_reject_context, 1); act->reason = p_strdup(pool, str_c(reason)); - act->ereject = ( op == &ereject_operation ); + act->ereject = ( sieve_operation_is(op, ereject_operation) ); ret = sieve_result_add_action - (renv, &act_reject, slist, source_line, (void *) act, 0); + (renv, this_ext, &act_reject, slist, source_line, (void *) act, 0); return ( ret >= 0 ); } @@ -319,8 +318,8 @@ static int ext_reject_operation_execute static int act_reject_check_duplicate (const struct sieve_runtime_env *renv ATTR_UNUSED, - const struct sieve_action_data *act, - const struct sieve_action_data *act_other) + const struct sieve_action *act, + const struct sieve_action *act_other) { if ( !act_other->executed ) { sieve_runtime_error(renv, act->location, @@ -334,27 +333,27 @@ static int act_reject_check_duplicate int act_reject_check_conflict (const struct sieve_runtime_env *renv, - const struct sieve_action_data *act, - const struct sieve_action_data *act_other) + const struct sieve_action *act, + const struct sieve_action *act_other) { - if ( (act_other->action->flags & SIEVE_ACTFLAG_TRIES_DELIVER) > 0 ) { + if ( (act_other->def->flags & SIEVE_ACTFLAG_TRIES_DELIVER) > 0 ) { if ( !act_other->executed ) { sieve_runtime_error(renv, act->location, "reject/ereject action conflicts with other action: " "the %s action (%s) tries to deliver the message", - act_other->action->name, act_other->location); + act_other->def->name, act_other->location); return -1; } } - if ( (act_other->action->flags & SIEVE_ACTFLAG_SENDS_RESPONSE) > 0 ) { + if ( (act_other->def->flags & SIEVE_ACTFLAG_SENDS_RESPONSE) > 0 ) { struct act_reject_context *rj_ctx; if ( !act_other->executed ) { sieve_runtime_error(renv, act->location, "reject/ereject action conflicts with other action: " "the %s action (%s) also sends a response to the sender", - act_other->action->name, act_other->location); + act_other->def->name, act_other->location); return -1; } @@ -369,16 +368,18 @@ int act_reject_check_conflict } static void act_reject_print -(const struct sieve_action *action ATTR_UNUSED, - const struct sieve_result_print_env *rpenv, void *context, bool *keep) +(const struct sieve_action *action, const struct sieve_result_print_env *rpenv, + bool *keep) { - struct act_reject_context *rj_ctx = (struct act_reject_context *) context; + struct act_reject_context *rj_ctx = + (struct act_reject_context *) action->context; if ( rj_ctx->reason != NULL ) { sieve_result_action_printf(rpenv, "reject message with reason: %s", str_sanitize(rj_ctx->reason, 128)); } else { - sieve_result_action_printf(rpenv, "reject message without sending a response (discard)"); + sieve_result_action_printf(rpenv, + "reject message without sending a response (discard)"); } *keep = FALSE; @@ -495,20 +496,23 @@ static bool act_reject_send } static bool act_reject_commit -(const struct sieve_action *action ATTR_UNUSED, - const struct sieve_action_exec_env *aenv, void *tr_context, bool *keep) +(const struct sieve_action *action, const struct sieve_action_exec_env *aenv, + void *tr_context ATTR_UNUSED, bool *keep) { - struct act_reject_context *rj_ctx = (struct act_reject_context *) tr_context; + struct act_reject_context *rj_ctx = + (struct act_reject_context *) action->context; const char *sender = sieve_message_get_sender(aenv->msgctx); const char *recipient = sieve_message_get_recipient(aenv->msgctx); if ( recipient == NULL ) { - sieve_result_warning(aenv, "reject action aborted: envelope recipient is <>"); + sieve_result_warning(aenv, + "reject action aborted: envelope recipient is <>"); return TRUE; } if ( rj_ctx->reason == NULL ) { - sieve_result_log(aenv, "not sending reject message (would cause second response to sender)"); + sieve_result_log(aenv, + "not sending reject message (would cause second response to sender)"); *keep = FALSE; return TRUE; @@ -522,7 +526,8 @@ static bool act_reject_commit } if ( act_reject_send(aenv, rj_ctx, sender, recipient) ) { - sieve_result_log(aenv, "rejected message from <%s> (%s)", str_sanitize(sender, 80), + sieve_result_log(aenv, + "rejected message from <%s> (%s)", str_sanitize(sender, 80), ( rj_ctx->ereject ? "ereject" : "reject" )); *keep = FALSE; diff --git a/src/lib-sieve/mcht-contains.c b/src/lib-sieve/mcht-contains.c index b648c887d..eda223e4f 100644 --- a/src/lib-sieve/mcht-contains.c +++ b/src/lib-sieve/mcht-contains.c @@ -25,7 +25,7 @@ static int mcht_contains_match * Match-type object */ -const struct sieve_match_type contains_match_type = { +const struct sieve_match_type_def contains_match_type = { SIEVE_OBJECT("contains", &match_type_operand, SIEVE_MATCH_TYPE_CONTAINS), TRUE, TRUE, NULL, @@ -55,11 +55,11 @@ static int mcht_contains_match if ( val == NULL || val_size == 0 ) return ( key_size == 0 ); - if ( mctx->comparator->char_match == NULL ) + if ( cmp->def == NULL || cmp->def->char_match == NULL ) return FALSE; while ( (vp < vend) && (kp < kend) ) { - if ( !cmp->char_match(cmp, &vp, vend, &kp, kend) ) + if ( !cmp->def->char_match(cmp, &vp, vend, &kp, kend) ) vp++; } diff --git a/src/lib-sieve/mcht-is.c b/src/lib-sieve/mcht-is.c index cbde42ac1..6a3275087 100644 --- a/src/lib-sieve/mcht-is.c +++ b/src/lib-sieve/mcht-is.c @@ -25,7 +25,7 @@ static int mcht_is_match * Match-type object */ -const struct sieve_match_type is_match_type = { +const struct sieve_match_type_def is_match_type = { SIEVE_OBJECT("is", &match_type_operand, SIEVE_MATCH_TYPE_IS), TRUE, TRUE, NULL, NULL, NULL, @@ -45,8 +45,8 @@ static int mcht_is_match if ( (val == NULL || val_size == 0) ) return ( key_size == 0 ); - if ( mctx->comparator->compare != NULL ) - return (mctx->comparator->compare(mctx->comparator, + if ( mctx->comparator->def != NULL && mctx->comparator->def->compare != NULL ) + return (mctx->comparator->def->compare(mctx->comparator, val, val_size, key, key_size) == 0); return FALSE; diff --git a/src/lib-sieve/mcht-matches.c b/src/lib-sieve/mcht-matches.c index 99eb612b9..102e85dbf 100644 --- a/src/lib-sieve/mcht-matches.c +++ b/src/lib-sieve/mcht-matches.c @@ -26,7 +26,7 @@ static int mcht_matches_match * Match-type object */ -const struct sieve_match_type matches_match_type = { +const struct sieve_match_type_def matches_match_type = { SIEVE_OBJECT("matches", &match_type_operand, SIEVE_MATCH_TYPE_MATCHES), TRUE, FALSE, NULL, @@ -54,7 +54,7 @@ static inline bool _string_find(const struct sieve_comparator *cmp, const char **valp, const char *vend, const char **keyp, const char *kend) { while ( (*valp < vend) && (*keyp < kend) ) { - if ( !cmp->char_match(cmp, valp, vend, keyp, kend) ) + if ( !cmp->def->char_match(cmp, valp, vend, keyp, kend) ) (*valp)++; } @@ -97,6 +97,9 @@ static int mcht_matches_match char next_wcard = '\0'; /* Next widlcard */ unsigned int key_offset = 0; + if ( cmp->def == NULL || cmp->def->char_match == NULL ) + return FALSE; + /* Value may be NULL, parse empty string in stead */ if ( val == NULL ) { val = ""; @@ -211,7 +214,7 @@ static int mcht_matches_match str_append_n(mvalue, pvp, qp-pvp); /* Compare needle to end of value string */ - if ( !cmp->char_match(cmp, &vp, vend, &needle, nend) ) { + if ( !cmp->def->char_match(cmp, &vp, vend, &needle, nend) ) { debug_printf(" match at end failed\n"); break; } @@ -250,7 +253,7 @@ static int mcht_matches_match debug_printf(" begin needle: '%s'\n", t_strdup_until(needle, nend)); debug_printf(" begin value: '%s'\n", t_strdup_until(vp, vend)); - if ( !cmp->char_match(cmp, &vp, vend, &needle, nend) ) { + if ( !cmp->def->char_match(cmp, &vp, vend, &needle, nend) ) { debug_printf(" failed to find needle at beginning\n"); break; } @@ -315,7 +318,7 @@ static int mcht_matches_match /* Try matching the needle at fixed position */ if ( (needle == nend && next_wcard == '\0' && vp < vend ) || - !cmp->char_match(cmp, &vp, vend, &needle, nend) ) { + !cmp->def->char_match(cmp, &vp, vend, &needle, nend) ) { /* Match failed: now we have a problem. We need to backtrack to the previous * '*' wildcard occurence and start scanning for the next possible match. diff --git a/src/lib-sieve/plugins/Makefile.am b/src/lib-sieve/plugins/Makefile.am index b571efa7a..1ce185c97 100644 --- a/src/lib-sieve/plugins/Makefile.am +++ b/src/lib-sieve/plugins/Makefile.am @@ -20,3 +20,4 @@ SUBDIRS = \ date \ $(UNFINISHED) + diff --git a/src/lib-sieve/plugins/body/ext-body-common.c b/src/lib-sieve/plugins/body/ext-body-common.c index f60e97ba0..44b66a0a7 100644 --- a/src/lib-sieve/plugins/body/ext-body-common.c +++ b/src/lib-sieve/plugins/body/ext-body-common.c @@ -299,14 +299,14 @@ static bool ext_body_parts_add_missing } static struct ext_body_message_context *ext_body_get_context -(struct sieve_message_context *msgctx) +(const struct sieve_extension *this_ext, struct sieve_message_context *msgctx) { pool_t pool = sieve_message_context_pool(msgctx); struct ext_body_message_context *ctx; /* Get message context (contains cached message body information) */ ctx = (struct ext_body_message_context *) - sieve_message_context_extension_get(msgctx, &body_extension); + sieve_message_context_extension_get(msgctx, this_ext); /* Create it if it does not exist already */ if ( ctx == NULL ) { @@ -318,7 +318,7 @@ static struct ext_body_message_context *ext_body_get_context ctx->raw_body = NULL; /* Register context */ - sieve_message_context_extension_set(msgctx, &body_extension, (void *) ctx); + sieve_message_context_extension_set(msgctx, this_ext, (void *) ctx); } return ctx; @@ -328,8 +328,10 @@ bool ext_body_get_content (const struct sieve_runtime_env *renv, const char * const *content_types, int decode_to_plain, struct ext_body_part **parts_r) { + const struct sieve_extension *this_ext = renv->oprtn.ext; + struct ext_body_message_context *ctx = + ext_body_get_context(this_ext, renv->msgctx); bool result = TRUE; - struct ext_body_message_context *ctx = ext_body_get_context(renv->msgctx); T_BEGIN { /* Fill the return_body_parts array */ @@ -351,7 +353,9 @@ bool ext_body_get_content bool ext_body_get_raw (const struct sieve_runtime_env *renv, struct ext_body_part **parts_r) { - struct ext_body_message_context *ctx = ext_body_get_context(renv->msgctx); + const struct sieve_extension *this_ext = renv->oprtn.ext; + struct ext_body_message_context *ctx = + ext_body_get_context(this_ext, renv->msgctx); struct ext_body_part *return_part; buffer_t *buf; diff --git a/src/lib-sieve/plugins/body/ext-body-common.h b/src/lib-sieve/plugins/body/ext-body-common.h index 33a0f6c8c..3c21bd4b8 100644 --- a/src/lib-sieve/plugins/body/ext-body-common.h +++ b/src/lib-sieve/plugins/body/ext-body-common.h @@ -8,19 +8,19 @@ * Extension */ -extern const struct sieve_extension body_extension; +extern const struct sieve_extension_def body_extension; /* * Commands */ -extern const struct sieve_command body_test; +extern const struct sieve_command_def body_test; /* * Operations */ -extern const struct sieve_operation body_operation; +extern const struct sieve_operation_def body_operation; /* * Message body part extraction diff --git a/src/lib-sieve/plugins/body/ext-body.c b/src/lib-sieve/plugins/body/ext-body.c index 049c13086..50e53275e 100644 --- a/src/lib-sieve/plugins/body/ext-body.c +++ b/src/lib-sieve/plugins/body/ext-body.c @@ -48,13 +48,11 @@ * Extension */ -static bool ext_body_validator_load(struct sieve_validator *validator); +static bool ext_body_validator_load +(const struct sieve_extension *ext, struct sieve_validator *valdtr); -int ext_body_my_id = -1; - -const struct sieve_extension body_extension = { +const struct sieve_extension_def body_extension = { "body", - &ext_body_my_id, NULL, NULL, ext_body_validator_load, NULL, NULL, NULL, NULL, NULL, @@ -62,10 +60,11 @@ const struct sieve_extension body_extension = { SIEVE_EXT_DEFINE_NO_OPERANDS }; -static bool ext_body_validator_load(struct sieve_validator *validator) +static bool ext_body_validator_load +(const struct sieve_extension *ext, struct sieve_validator *valdtr) { /* Register new test */ - sieve_validator_register_command(validator, &body_test); + sieve_validator_register_command(valdtr, ext, &body_test); return TRUE; } diff --git a/src/lib-sieve/plugins/body/tst-body.c b/src/lib-sieve/plugins/body/tst-body.c index c1057cc21..2892f783f 100644 --- a/src/lib-sieve/plugins/body/tst-body.c +++ b/src/lib-sieve/plugins/body/tst-body.c @@ -36,13 +36,14 @@ enum tst_body_transform { */ static bool tst_body_registered - (struct sieve_validator *validator, struct sieve_command_registration *cmd_reg); + (struct sieve_validator *valdtr, const struct sieve_extension *ext, + struct sieve_command_registration *cmd_reg); static bool tst_body_validate - (struct sieve_validator *validator, struct sieve_command_context *tst); + (struct sieve_validator *valdtr, struct sieve_command *tst); static bool tst_body_generate - (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx); + (const struct sieve_codegen_env *cgenv, struct sieve_command *ctx); -const struct sieve_command body_test = { +const struct sieve_command_def body_test = { "body", SCT_TEST, 1, 0, FALSE, FALSE, @@ -58,13 +59,11 @@ const struct sieve_command body_test = { */ static bool ext_body_operation_dump - (const struct sieve_operation *op, - const struct sieve_dumptime_env *denv, sieve_size_t *address); + (const struct sieve_dumptime_env *denv, sieve_size_t *address); static int ext_body_operation_execute - (const struct sieve_operation *op, - const struct sieve_runtime_env *renv, sieve_size_t *address); + (const struct sieve_runtime_env *renv, sieve_size_t *address); -const struct sieve_operation body_operation = { +const struct sieve_operation_def body_operation = { "body", &body_extension, 0, @@ -87,43 +86,43 @@ enum tst_body_optional { /* Forward declarations */ static bool tag_body_transform_validate - (struct sieve_validator *validator, struct sieve_ast_argument **arg, - struct sieve_command_context *cmd); + (struct sieve_validator *valdtr, struct sieve_ast_argument **arg, + struct sieve_command *cmd); static bool tag_body_transform_generate (const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, - struct sieve_command_context *cmd); + struct sieve_command *cmd); /* Argument objects */ -static const struct sieve_argument body_raw_tag = { +static const struct sieve_argument_def body_raw_tag = { "raw", - NULL, NULL, + NULL, tag_body_transform_validate, - NULL, + NULL, NULL, tag_body_transform_generate }; -static const struct sieve_argument body_content_tag = { +static const struct sieve_argument_def body_content_tag = { "content", - NULL, NULL, + NULL, tag_body_transform_validate, - NULL, + NULL, NULL, tag_body_transform_generate }; -static const struct sieve_argument body_text_tag = { +static const struct sieve_argument_def body_text_tag = { "text", - NULL, NULL, + NULL, tag_body_transform_validate, - NULL, + NULL, NULL, tag_body_transform_generate }; /* Argument implementation */ static bool tag_body_transform_validate -(struct sieve_validator *validator, struct sieve_ast_argument **arg, - struct sieve_command_context *cmd) +(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, + struct sieve_command *cmd) { enum tst_body_transform transform; struct sieve_ast_argument *tag = *arg; @@ -134,7 +133,7 @@ static bool tag_body_transform_validate * / :text */ if ( (bool) cmd->data ) { - sieve_argument_validate_error(validator, *arg, + sieve_argument_validate_error(valdtr, *arg, "the :raw, :content and :text arguments for the body test are mutually " "exclusive, but more than one was specified"); return FALSE; @@ -144,22 +143,22 @@ static bool tag_body_transform_validate *arg = sieve_ast_argument_next(*arg); /* :content tag has a string-list argument */ - if ( tag->argument == &body_raw_tag ) + if ( sieve_argument_is(tag, body_raw_tag) ) transform = TST_BODY_TRANSFORM_RAW; - else if ( tag->argument == &body_text_tag ) + else if ( sieve_argument_is(tag, body_text_tag) ) transform = TST_BODY_TRANSFORM_TEXT; - else if ( tag->argument == &body_content_tag ) { + else if ( sieve_argument_is(tag, body_content_tag) ) { /* Check syntax: * :content <content-types: string-list> */ if ( !sieve_validate_tag_parameter - (validator, cmd, tag, *arg, SAAT_STRING_LIST) ) { + (valdtr, cmd, tag, *arg, SAAT_STRING_LIST) ) { return FALSE; } - if ( !sieve_validator_argument_activate(validator, cmd, *arg, FALSE) ) + if ( !sieve_validator_argument_activate(valdtr, cmd, *arg, FALSE) ) return FALSE; /* Assign tag parameters */ @@ -174,7 +173,7 @@ static bool tag_body_transform_validate cmd->data = (void *) TRUE; /* Assign context data */ - tag->context = (void *) transform; + tag->argument->data = (void *) transform; return TRUE; } @@ -184,18 +183,19 @@ static bool tag_body_transform_validate */ static bool tst_body_registered -(struct sieve_validator *validator, struct sieve_command_registration *cmd_reg) +(struct sieve_validator *valdtr, const struct sieve_extension *ext, + struct sieve_command_registration *cmd_reg) { /* The order of these is not significant */ - sieve_comparators_link_tag(validator, cmd_reg, SIEVE_MATCH_OPT_COMPARATOR); - sieve_match_types_link_tags(validator, cmd_reg, SIEVE_MATCH_OPT_MATCH_TYPE); + sieve_comparators_link_tag(valdtr, cmd_reg, SIEVE_MATCH_OPT_COMPARATOR); + sieve_match_types_link_tags(valdtr, cmd_reg, SIEVE_MATCH_OPT_MATCH_TYPE); sieve_validator_register_tag - (validator, cmd_reg, &body_raw_tag, OPT_BODY_TRANSFORM); + (valdtr, cmd_reg, ext, &body_raw_tag, OPT_BODY_TRANSFORM); sieve_validator_register_tag - (validator, cmd_reg, &body_content_tag, OPT_BODY_TRANSFORM); + (valdtr, cmd_reg, ext, &body_content_tag, OPT_BODY_TRANSFORM); sieve_validator_register_tag - (validator, cmd_reg, &body_text_tag, OPT_BODY_TRANSFORM); + (valdtr, cmd_reg, ext, &body_text_tag, OPT_BODY_TRANSFORM); return TRUE; } @@ -205,21 +205,25 @@ static bool tst_body_registered */ static bool tst_body_validate -(struct sieve_validator *validator, struct sieve_command_context *tst) +(struct sieve_validator *valdtr, struct sieve_command *tst) { struct sieve_ast_argument *arg = tst->first_positional; + const struct sieve_match_type mcht_default = + SIEVE_MATCH_TYPE_DEFAULT(is_match_type); + const struct sieve_comparator cmp_default = + SIEVE_COMPARATOR_DEFAULT(i_ascii_casemap_comparator); if ( !sieve_validate_positional_argument - (validator, tst, arg, "key list", 1, SAAT_STRING_LIST) ) { + (valdtr, tst, arg, "key list", 1, SAAT_STRING_LIST) ) { return FALSE; } - if ( !sieve_validator_argument_activate(validator, tst, arg, FALSE) ) + if ( !sieve_validator_argument_activate(valdtr, tst, arg, FALSE) ) return FALSE; /* Validate the key argument to a specified match type */ return sieve_match_type_validate - (validator, tst, arg, &is_match_type, &i_ascii_casemap_comparator); + (valdtr, tst, arg, &mcht_default, &cmp_default); } /* @@ -227,19 +231,20 @@ static bool tst_body_validate */ static bool tst_body_generate - (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx) +(const struct sieve_codegen_env *cgenv, struct sieve_command *cmd) { - (void)sieve_operation_emit_code(cgenv->sbin, &body_operation); + (void)sieve_operation_emit(cgenv->sbin, cmd->ext, &body_operation); /* Generate arguments */ - return sieve_generate_arguments(cgenv, ctx, NULL); + return sieve_generate_arguments(cgenv, cmd, NULL); } static bool tag_body_transform_generate (const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, - struct sieve_command_context *cmd ATTR_UNUSED) + struct sieve_command *cmd ATTR_UNUSED) { - enum tst_body_transform transform = (enum tst_body_transform) arg->context; + enum tst_body_transform transform = + (enum tst_body_transform) arg->argument->data; sieve_binary_emit_byte(cgenv->sbin, transform); sieve_generate_argument_parameters(cgenv, cmd, arg); @@ -252,8 +257,7 @@ static bool tag_body_transform_generate */ static bool ext_body_operation_dump -(const struct sieve_operation *op ATTR_UNUSED, - const struct sieve_dumptime_env *denv, sieve_size_t *address) +(const struct sieve_dumptime_env *denv, sieve_size_t *address) { enum tst_body_transform transform; int opt_code = 0; @@ -306,16 +310,16 @@ static bool ext_body_operation_dump */ static int ext_body_operation_execute -(const struct sieve_operation *op ATTR_UNUSED, - const struct sieve_runtime_env *renv, sieve_size_t *address) +(const struct sieve_runtime_env *renv, sieve_size_t *address) { static const char * const _no_content_types[] = { "", NULL }; - int ret = SIEVE_EXEC_OK; int opt_code = 0; int mret; - const struct sieve_comparator *cmp = &i_ascii_casemap_comparator; - const struct sieve_match_type *mtch = &is_match_type; + struct sieve_comparator cmp = + SIEVE_COMPARATOR_DEFAULT(i_ascii_casemap_comparator); + struct sieve_match_type mtch = + SIEVE_MATCH_TYPE_DEFAULT(is_match_type); enum tst_body_transform transform; struct sieve_coded_stringlist *key_list, *ctype_list = NULL; struct sieve_match_context *mctx; @@ -398,7 +402,7 @@ static int ext_body_operation_execute /* Iterate through all requested body parts to match */ matched = FALSE; - mctx = sieve_match_begin(renv->interp, mtch, cmp, NULL, key_list); + mctx = sieve_match_begin(renv->interp, &mtch, &cmp, NULL, key_list); while ( !matched && body_parts->content != NULL ) { if ( (mret=sieve_match_value(mctx, body_parts->content, body_parts->size)) < 0) diff --git a/src/lib-sieve/plugins/comparator-i-ascii-numeric/ext-cmp-i-ascii-numeric.c b/src/lib-sieve/plugins/comparator-i-ascii-numeric/ext-cmp-i-ascii-numeric.c index 94b382d36..4e18a7fe0 100644 --- a/src/lib-sieve/plugins/comparator-i-ascii-numeric/ext-cmp-i-ascii-numeric.c +++ b/src/lib-sieve/plugins/comparator-i-ascii-numeric/ext-cmp-i-ascii-numeric.c @@ -26,22 +26,19 @@ * Forward declarations */ -static const struct sieve_operand my_comparator_operand; +static const struct sieve_operand_def my_comparator_operand; -const struct sieve_comparator i_ascii_numeric_comparator; - -static bool ext_cmp_i_ascii_numeric_validator_load - (struct sieve_validator *validator); +const struct sieve_comparator_def i_ascii_numeric_comparator; /* * Extension */ -static int ext_my_id = -1; +static bool ext_cmp_i_ascii_numeric_validator_load + (const struct sieve_extension *ext, struct sieve_validator *validator); -const struct sieve_extension comparator_i_ascii_numeric_extension = { +const struct sieve_extension_def comparator_i_ascii_numeric_extension = { "comparator-i;ascii-numeric", - &ext_my_id, NULL, NULL, ext_cmp_i_ascii_numeric_validator_load, NULL, NULL, NULL, NULL, NULL, @@ -50,9 +47,9 @@ const struct sieve_extension comparator_i_ascii_numeric_extension = { }; static bool ext_cmp_i_ascii_numeric_validator_load - (struct sieve_validator *validator) +(const struct sieve_extension *ext, struct sieve_validator *validator) { - sieve_comparator_register(validator, &i_ascii_numeric_comparator); + sieve_comparator_register(validator, ext, &i_ascii_numeric_comparator); return TRUE; } @@ -63,7 +60,7 @@ static bool ext_cmp_i_ascii_numeric_validator_load static const struct sieve_extension_objects ext_comparators = SIEVE_EXT_DEFINE_COMPARATOR(i_ascii_numeric_comparator); -static const struct sieve_operand my_comparator_operand = { +static const struct sieve_operand_def my_comparator_operand = { "comparator-i;ascii-numeric", &comparator_i_ascii_numeric_extension, 0, @@ -83,7 +80,7 @@ static int cmp_i_ascii_numeric_compare /* Comparator object */ -const struct sieve_comparator i_ascii_numeric_comparator = { +const struct sieve_comparator_def i_ascii_numeric_comparator = { SIEVE_OBJECT("i;ascii-numeric", &my_comparator_operand, 0), SIEVE_COMPARATOR_FLAG_ORDERING | SIEVE_COMPARATOR_FLAG_EQUALITY, cmp_i_ascii_numeric_compare, @@ -113,9 +110,9 @@ static int cmp_i_ascii_numeric_compare } } else { if ( !i_isdigit(*kp) ) { - /* Value is less */ - return -1; - } + /* Value is less */ + return -1; + } } /* Ignore leading zeros */ diff --git a/src/lib-sieve/plugins/copy/ext-copy.c b/src/lib-sieve/plugins/copy/ext-copy.c index 12786a1a8..35ce9d54c 100644 --- a/src/lib-sieve/plugins/copy/ext-copy.c +++ b/src/lib-sieve/plugins/copy/ext-copy.c @@ -28,20 +28,18 @@ * Forward declarations */ -static const struct sieve_argument copy_tag; -static const struct sieve_operand copy_side_effect_operand; +static const struct sieve_argument_def copy_tag; +static const struct sieve_operand_def copy_side_effect_operand; /* * Extension */ -static bool ext_copy_validator_load(struct sieve_validator *validator); +static bool ext_copy_validator_load +(const struct sieve_extension *ext, struct sieve_validator *valdtr); -static int ext_my_id = -1; - -const struct sieve_extension copy_extension = { +const struct sieve_extension_def copy_extension = { "copy", - &ext_my_id, NULL, NULL, ext_copy_validator_load, NULL, NULL, NULL, NULL, NULL, @@ -49,16 +47,17 @@ const struct sieve_extension copy_extension = { SIEVE_EXT_DEFINE_OPERAND(copy_side_effect_operand) }; -static bool ext_copy_validator_load(struct sieve_validator *validator) +static bool ext_copy_validator_load +(const struct sieve_extension *ext, struct sieve_validator *valdtr) { /* Register copy tag with redirect and fileinto commands and we don't care * whether these commands are registered or even whether they will be * registered at all. The validator handles either situation gracefully */ sieve_validator_register_external_tag - (validator, ©_tag, "redirect", SIEVE_OPT_SIDE_EFFECT); + (valdtr, "redirect", ext, ©_tag, SIEVE_OPT_SIDE_EFFECT); sieve_validator_register_external_tag - (validator, ©_tag, "fileinto", SIEVE_OPT_SIDE_EFFECT); + (valdtr, "fileinto", ext, ©_tag, SIEVE_OPT_SIDE_EFFECT); return TRUE; } @@ -69,13 +68,12 @@ static bool ext_copy_validator_load(struct sieve_validator *validator) static void seff_copy_print (const struct sieve_side_effect *seffect, const struct sieve_action *action, - const struct sieve_result_print_env *rpenv, void *se_context, bool *keep); + const struct sieve_result_print_env *rpenv, bool *keep); static void seff_copy_post_commit (const struct sieve_side_effect *seffect, const struct sieve_action *action, - const struct sieve_action_exec_env *aenv, void *se_context, - void *tr_context, bool *keep); + const struct sieve_action_exec_env *aenv, void *tr_context, bool *keep); -const struct sieve_side_effect copy_side_effect = { +const struct sieve_side_effect_def copy_side_effect = { SIEVE_OBJECT("copy", ©_side_effect_operand, 0), &act_store, NULL, NULL, NULL, @@ -90,17 +88,17 @@ const struct sieve_side_effect copy_side_effect = { */ static bool tag_copy_validate - (struct sieve_validator *validator, struct sieve_ast_argument **arg, - struct sieve_command_context *cmd); + (struct sieve_validator *valdtr, struct sieve_ast_argument **arg, + struct sieve_command *cmd); static bool tag_copy_generate (const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, - struct sieve_command_context *context); + struct sieve_command *cmd); -static const struct sieve_argument copy_tag = { +static const struct sieve_argument_def copy_tag = { "copy", - NULL, NULL, - tag_copy_validate, NULL, + tag_copy_validate, + NULL, NULL, tag_copy_generate }; @@ -111,7 +109,7 @@ static const struct sieve_argument copy_tag = { static const struct sieve_extension_objects ext_side_effects = SIEVE_EXT_DEFINE_SIDE_EFFECT(copy_side_effect); -static const struct sieve_operand copy_side_effect_operand = { +static const struct sieve_operand_def copy_side_effect_operand = { "copy operand", ©_extension, 0, @@ -124,9 +122,9 @@ static const struct sieve_operand copy_side_effect_operand = { */ static bool tag_copy_validate - (struct sieve_validator *validator ATTR_UNUSED, + (struct sieve_validator *valdtr ATTR_UNUSED, struct sieve_ast_argument **arg ATTR_UNUSED, - struct sieve_command_context *cmd ATTR_UNUSED) + struct sieve_command *cmd ATTR_UNUSED) { *arg = sieve_ast_argument_next(*arg); @@ -139,13 +137,14 @@ static bool tag_copy_validate static bool tag_copy_generate (const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, - struct sieve_command_context *context ATTR_UNUSED) + struct sieve_command *cmd ATTR_UNUSED) { if ( sieve_ast_argument_type(arg) != SAAT_TAG ) { return FALSE; } - sieve_opr_side_effect_emit(cgenv->sbin, ©_side_effect); + sieve_opr_side_effect_emit + (cgenv->sbin, sieve_argument_ext(arg), ©_side_effect); return TRUE; } @@ -157,8 +156,7 @@ static bool tag_copy_generate static void seff_copy_print (const struct sieve_side_effect *seffect ATTR_UNUSED, const struct sieve_action *action ATTR_UNUSED, - const struct sieve_result_print_env *rpenv, - void *se_context ATTR_UNUSED, bool *keep) + const struct sieve_result_print_env *rpenv, bool *keep) { sieve_result_seffect_printf(rpenv, "preserve implicit keep"); @@ -169,7 +167,7 @@ static void seff_copy_post_commit (const struct sieve_side_effect *seffect ATTR_UNUSED, const struct sieve_action *action ATTR_UNUSED, const struct sieve_action_exec_env *aenv ATTR_UNUSED, - void *se_context ATTR_UNUSED, void *tr_context ATTR_UNUSED, bool *keep) + void *tr_context ATTR_UNUSED, bool *keep) { *keep = TRUE; } diff --git a/src/lib-sieve/plugins/date/ext-date-common.c b/src/lib-sieve/plugins/date/ext-date-common.c index 40a47fe28..de051d44c 100644 --- a/src/lib-sieve/plugins/date/ext-date-common.c +++ b/src/lib-sieve/plugins/date/ext-date-common.c @@ -23,7 +23,8 @@ struct ext_date_context { */ static void ext_date_runtime_init -(const struct sieve_runtime_env *renv, void *context ATTR_UNUSED) +(const struct sieve_extension *ext, const struct sieve_runtime_env *renv, + void *context ATTR_UNUSED) { struct ext_date_context *dctx; pool_t pool; @@ -44,7 +45,7 @@ static void ext_date_runtime_init dctx->zone_offset = zone_offset; sieve_message_context_extension_set - (renv->msgctx, &date_extension, (void *) dctx); + (renv->msgctx, ext, (void *) dctx); } static struct sieve_interpreter_extension date_interpreter_extension = { @@ -54,14 +55,14 @@ static struct sieve_interpreter_extension date_interpreter_extension = { }; bool ext_date_interpreter_load -(const struct sieve_runtime_env *renv, sieve_size_t *address ATTR_UNUSED) +(const struct sieve_extension *ext, const struct sieve_runtime_env *renv, + sieve_size_t *address ATTR_UNUSED) { /* Register runtime hook to obtain stript start timestamp */ if ( renv->msgctx == NULL || - sieve_message_context_extension_get(renv->msgctx, &date_extension) - == NULL ) { + sieve_message_context_extension_get(renv->msgctx, ext) == NULL ) { sieve_interpreter_extension_register - (renv->interp, &date_interpreter_extension, NULL); + (renv->interp, ext, &date_interpreter_extension, NULL); } return TRUE; @@ -103,13 +104,14 @@ bool ext_date_parse_timezone time_t ext_date_get_current_date (const struct sieve_runtime_env *renv, int *zone_offset_r) { + const struct sieve_extension *this_ext = renv->oprtn.ext; struct ext_date_context *dctx = (struct ext_date_context *) - sieve_message_context_extension_get(renv->msgctx, &date_extension); + sieve_message_context_extension_get(renv->msgctx, this_ext); if ( dctx == NULL ) { - ext_date_runtime_init(renv, NULL); + ext_date_runtime_init(this_ext, renv, NULL); dctx = (struct ext_date_context *) - sieve_message_context_extension_get(renv->msgctx, &date_extension); + sieve_message_context_extension_get(renv->msgctx, this_ext); i_assert(dctx != NULL); } diff --git a/src/lib-sieve/plugins/date/ext-date-common.h b/src/lib-sieve/plugins/date/ext-date-common.h index 11810efdf..33d366fda 100644 --- a/src/lib-sieve/plugins/date/ext-date-common.h +++ b/src/lib-sieve/plugins/date/ext-date-common.h @@ -12,17 +12,18 @@ * Extension */ -extern const struct sieve_extension date_extension; +extern const struct sieve_extension_def date_extension; bool ext_date_interpreter_load - (const struct sieve_runtime_env *renv, sieve_size_t *address ATTR_UNUSED); + (const struct sieve_extension *ext, const struct sieve_runtime_env *renv, + sieve_size_t *address ATTR_UNUSED); /* * Tests */ -extern const struct sieve_command date_test; -extern const struct sieve_command currentdate_test; +extern const struct sieve_command_def date_test; +extern const struct sieve_command_def currentdate_test; /* * Operations @@ -33,8 +34,8 @@ enum ext_date_opcode { EXT_DATE_OPERATION_CURRENTDATE }; -extern const struct sieve_operation date_operation; -extern const struct sieve_operation currentdate_operation; +extern const struct sieve_operation_def date_operation; +extern const struct sieve_operation_def currentdate_operation; /* * Zone string diff --git a/src/lib-sieve/plugins/date/ext-date.c b/src/lib-sieve/plugins/date/ext-date.c index 6d5cf9adf..d2321ddcb 100644 --- a/src/lib-sieve/plugins/date/ext-date.c +++ b/src/lib-sieve/plugins/date/ext-date.c @@ -34,18 +34,16 @@ * Extension */ -static bool ext_date_validator_load(struct sieve_validator *validator); +static bool ext_date_validator_load +(const struct sieve_extension *ext, struct sieve_validator *validator); -int ext_date_my_id = -1; - -const struct sieve_operation *ext_date_operations[] = { +const struct sieve_operation_def *ext_date_operations[] = { &date_operation, ¤tdate_operation }; -const struct sieve_extension date_extension = { +const struct sieve_extension_def date_extension = { "date", - &ext_date_my_id, NULL, NULL, ext_date_validator_load, NULL, @@ -55,11 +53,12 @@ const struct sieve_extension date_extension = { SIEVE_EXT_DEFINE_NO_OPERANDS }; -static bool ext_date_validator_load(struct sieve_validator *valdtr) +static bool ext_date_validator_load +(const struct sieve_extension *ext, struct sieve_validator *valdtr) { /* Register new test */ - sieve_validator_register_command(valdtr, &date_test); - sieve_validator_register_command(valdtr, ¤tdate_test); + sieve_validator_register_command(valdtr, ext, &date_test); + sieve_validator_register_command(valdtr, ext, ¤tdate_test); return TRUE; } diff --git a/src/lib-sieve/plugins/date/tst-date.c b/src/lib-sieve/plugins/date/tst-date.c index 5e1aaad41..14a0f87f4 100644 --- a/src/lib-sieve/plugins/date/tst-date.c +++ b/src/lib-sieve/plugins/date/tst-date.c @@ -26,9 +26,9 @@ */ static bool tst_date_validate - (struct sieve_validator *valdtr, struct sieve_command_context *tst); + (struct sieve_validator *valdtr, struct sieve_command *tst); static bool tst_date_generate - (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx); + (const struct sieve_codegen_env *cgenv, struct sieve_command *ctx); /* Address test * @@ -39,9 +39,10 @@ static bool tst_date_generate */ static bool tst_date_registered - (struct sieve_validator *valdtr, struct sieve_command_registration *cmd_reg); + (struct sieve_validator *valdtr, const struct sieve_extension *ext, + struct sieve_command_registration *cmd_reg); -const struct sieve_command date_test = { +const struct sieve_command_def date_test = { "date", SCT_TEST, 3, 0, FALSE, FALSE, @@ -61,9 +62,10 @@ const struct sieve_command date_test = { */ static bool tst_currentdate_registered - (struct sieve_validator *valdtr, struct sieve_command_registration *cmd_reg); + (struct sieve_validator *valdtr, const struct sieve_extension *ext, + struct sieve_command_registration *cmd_reg); -const struct sieve_command currentdate_test = { +const struct sieve_command_def currentdate_test = { "currentdate", SCT_TEST, 2, 0, FALSE, FALSE, @@ -81,27 +83,27 @@ const struct sieve_command currentdate_test = { /* Forward declarations */ static bool tag_zone_validate - (struct sieve_validator *validator, struct sieve_ast_argument **arg, - struct sieve_command_context *cmd); + (struct sieve_validator *valdtr, struct sieve_ast_argument **arg, + struct sieve_command *cmd); static bool tag_zone_generate (const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, - struct sieve_command_context *cmd); + struct sieve_command *cmd); /* Argument objects */ -static const struct sieve_argument date_zone_tag = { +static const struct sieve_argument_def date_zone_tag = { "zone", - NULL, NULL, - tag_zone_validate, NULL, + tag_zone_validate, + NULL, NULL, tag_zone_generate }; -static const struct sieve_argument date_originalzone_tag = { +static const struct sieve_argument_def date_originalzone_tag = { "originalzone", - NULL, NULL, - tag_zone_validate, NULL, + tag_zone_validate, + NULL, NULL, tag_zone_generate }; @@ -110,13 +112,11 @@ static const struct sieve_argument date_originalzone_tag = { */ static bool tst_date_operation_dump - (const struct sieve_operation *op, - const struct sieve_dumptime_env *denv, sieve_size_t *address); + (const struct sieve_dumptime_env *denv, sieve_size_t *address); static int tst_date_operation_execute - (const struct sieve_operation *op, - const struct sieve_runtime_env *renv, sieve_size_t *address); + (const struct sieve_runtime_env *renv, sieve_size_t *address); -const struct sieve_operation date_operation = { +const struct sieve_operation_def date_operation = { "DATE", &date_extension, EXT_DATE_OPERATION_DATE, @@ -124,7 +124,7 @@ const struct sieve_operation date_operation = { tst_date_operation_execute }; -const struct sieve_operation currentdate_operation = { +const struct sieve_operation_def currentdate_operation = { "CURRENTDATE", &date_extension, EXT_DATE_OPERATION_CURRENTDATE, @@ -146,18 +146,18 @@ enum tst_date_optional { */ static bool tag_zone_validate -(struct sieve_validator *validator, struct sieve_ast_argument **arg, - struct sieve_command_context *cmd) +(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, + struct sieve_command *cmd) { struct sieve_ast_argument *tag = *arg; if ( (bool) cmd->data ) { - if ( cmd->command == &date_test ) { - sieve_argument_validate_error(validator, *arg, + if ( sieve_command_is(cmd, date_test) ) { + sieve_argument_validate_error(valdtr, *arg, "multiple :zone or :originalzone arguments specified for " "the currentdate test"); } else { - sieve_argument_validate_error(validator, *arg, + sieve_argument_validate_error(valdtr, *arg, "multiple :zone arguments specified for the currentdate test"); } return FALSE; @@ -167,13 +167,13 @@ static bool tag_zone_validate *arg = sieve_ast_argument_next(*arg); /* :content tag has a string-list argument */ - if ( tag->argument == &date_zone_tag ) { + if ( sieve_argument_is(tag, date_zone_tag) ) { /* Check syntax: * :zone <time-zone: string> */ if ( !sieve_validate_tag_parameter - (validator, cmd, tag, *arg, SAAT_STRING) ) { + (valdtr, cmd, tag, *arg, SAAT_STRING) ) { return FALSE; } @@ -182,7 +182,7 @@ static bool tag_zone_validate const char *zone = sieve_ast_argument_strc(*arg); if ( !ext_date_parse_timezone(zone, NULL) ) { - sieve_argument_validate_warning(validator, *arg, + sieve_argument_validate_warning(valdtr, *arg, "specified :zone argument '%s' is not a valid timezone", str_sanitize(zone, 40)); } @@ -203,27 +203,29 @@ static bool tag_zone_validate */ static bool tst_date_registered -(struct sieve_validator *valdtr, struct sieve_command_registration *cmd_reg) +(struct sieve_validator *valdtr, const struct sieve_extension *ext, + struct sieve_command_registration *cmd_reg) { sieve_comparators_link_tag(valdtr, cmd_reg, SIEVE_MATCH_OPT_COMPARATOR); sieve_match_types_link_tags(valdtr, cmd_reg, SIEVE_MATCH_OPT_MATCH_TYPE); sieve_validator_register_tag - (valdtr, cmd_reg, &date_zone_tag, OPT_DATE_ZONE); + (valdtr, cmd_reg, ext, &date_zone_tag, OPT_DATE_ZONE); sieve_validator_register_tag - (valdtr, cmd_reg, &date_originalzone_tag, OPT_DATE_ZONE); + (valdtr, cmd_reg, ext, &date_originalzone_tag, OPT_DATE_ZONE); return TRUE; } static bool tst_currentdate_registered -(struct sieve_validator *valdtr, struct sieve_command_registration *cmd_reg) +(struct sieve_validator *valdtr, const struct sieve_extension *ext, + struct sieve_command_registration *cmd_reg) { sieve_comparators_link_tag(valdtr, cmd_reg, SIEVE_MATCH_OPT_COMPARATOR); sieve_match_types_link_tags(valdtr, cmd_reg, SIEVE_MATCH_OPT_MATCH_TYPE); sieve_validator_register_tag - (valdtr, cmd_reg, &date_zone_tag, OPT_DATE_ZONE); + (valdtr, cmd_reg, ext, &date_zone_tag, OPT_DATE_ZONE); return TRUE; } @@ -233,14 +235,18 @@ static bool tst_currentdate_registered */ static bool tst_date_validate - (struct sieve_validator *valdtr, struct sieve_command_context *tst) +(struct sieve_validator *valdtr, struct sieve_command *tst) { struct sieve_ast_argument *arg = tst->first_positional; unsigned int arg_offset = 0 ; + const struct sieve_match_type mcht_default = + SIEVE_MATCH_TYPE_DEFAULT(is_match_type); + const struct sieve_comparator cmp_default = + SIEVE_COMPARATOR_DEFAULT(i_ascii_casemap_comparator); /* Check header name */ - if ( tst->command == &date_test ) { + if ( sieve_command_is(tst, date_test) ) { arg_offset = 1; if ( !sieve_validate_positional_argument @@ -281,7 +287,7 @@ static bool tst_date_validate /* Validate the key argument to a specified match type */ return sieve_match_type_validate - (valdtr, tst, arg, &is_match_type, &i_ascii_casemap_comparator); + (valdtr, tst, arg, &mcht_default, &cmp_default); } /* @@ -289,12 +295,12 @@ static bool tst_date_validate */ static bool tst_date_generate -(const struct sieve_codegen_env *cgenv, struct sieve_command_context *tst) +(const struct sieve_codegen_env *cgenv, struct sieve_command *tst) { - if ( tst->command == &date_test ) - sieve_operation_emit_code(cgenv->sbin, &date_operation); - else if ( tst->command == ¤tdate_test ) - sieve_operation_emit_code(cgenv->sbin, ¤tdate_operation); + if ( sieve_command_is(tst, date_test) ) + sieve_operation_emit(cgenv->sbin, tst->ext, &date_operation); + else if ( sieve_command_is(tst, currentdate_test) ) + sieve_operation_emit(cgenv->sbin, tst->ext, ¤tdate_operation); else i_unreached(); @@ -304,19 +310,14 @@ static bool tst_date_generate static bool tag_zone_generate (const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, - struct sieve_command_context *cmd) + struct sieve_command *cmd) { - struct sieve_ast_argument *param = arg->parameters; - - if ( param == NULL ) { + if ( arg->parameters == NULL ) { sieve_opr_omitted_emit(cgenv->sbin); return TRUE; } - if ( param->argument != NULL && param->argument->generate != NULL ) - return param->argument->generate(cgenv, param, cmd); - - return FALSE; + return sieve_generate_argument_parameters(cgenv, cmd, arg); } /* @@ -324,13 +325,13 @@ static bool tag_zone_generate */ static bool tst_date_operation_dump -(const struct sieve_operation *op, - const struct sieve_dumptime_env *denv, sieve_size_t *address) +(const struct sieve_dumptime_env *denv, sieve_size_t *address) { int opt_code = 0; - const struct sieve_operand *operand; + const struct sieve_operation *op = &denv->oprtn; + struct sieve_operand operand; - sieve_code_dumpf(denv, "%s", op->mnemonic); + sieve_code_dumpf(denv, "%s", sieve_operation_mnemonic(op)); sieve_code_descend(denv); /* Handle any optional arguments */ @@ -342,17 +343,16 @@ static bool tst_date_operation_dump case SIEVE_MATCH_OPT_END: break; case OPT_DATE_ZONE: - operand = sieve_operand_read(denv->sbin, address); - if ( operand == NULL ) { + if ( !sieve_operand_read(denv->sbin, address, &operand) ) { sieve_code_dumpf(denv, "ERROR: INVALID OPERAND"); return FALSE; } - if ( sieve_operand_is_omitted(operand) ) { + if ( sieve_operand_is_omitted(&operand) ) { sieve_code_dumpf(denv, "zone: ORIGINAL"); } else { if ( !sieve_opr_string_dump_data - (denv, operand, address, "zone") ) + (denv, &operand, address, "zone") ) return FALSE; } break; @@ -361,7 +361,7 @@ static bool tst_date_operation_dump } } while ( opt_code != SIEVE_MATCH_OPT_END ); - if ( op == &date_operation && + if ( sieve_operation_is(op, date_operation) && !sieve_opr_string_dump(denv, address, "header name") ) return FALSE; @@ -375,15 +375,17 @@ static bool tst_date_operation_dump */ static int tst_date_operation_execute -(const struct sieve_operation *op, - const struct sieve_runtime_env *renv, sieve_size_t *address) +(const struct sieve_runtime_env *renv, sieve_size_t *address) { + const struct sieve_operation *op = &renv->oprtn; bool result = TRUE, zone_specified = FALSE, got_date = FALSE, matched = FALSE; int opt_code = 0; const struct sieve_message_data *msgdata = renv->msgdata; - const struct sieve_comparator *cmp = &i_ascii_casemap_comparator; - const struct sieve_match_type *mtch = &is_match_type; - const struct sieve_operand *operand; + struct sieve_match_type mcht = + SIEVE_MATCH_TYPE_DEFAULT(is_match_type); + struct sieve_comparator cmp = + SIEVE_COMPARATOR_DEFAULT(i_ascii_casemap_comparator); + struct sieve_operand operand; struct sieve_match_context *mctx; string_t *header_name = NULL, *date_part = NULL, *zone = NULL; struct sieve_coded_stringlist *key_list; @@ -396,22 +398,21 @@ static int tst_date_operation_execute /* Read optional operands */ do { if ( (ret=sieve_match_read_optional_operands - (renv, address, &opt_code, &cmp, &mtch)) <= 0 ) + (renv, address, &opt_code, &cmp, &mcht)) <= 0 ) return ret; switch ( opt_code ) { case SIEVE_MATCH_OPT_END: break; case OPT_DATE_ZONE: - operand = sieve_operand_read(renv->sbin, address); - if ( operand == NULL ) { + if ( !sieve_operand_read(renv->sbin, address, &operand) ) { sieve_runtime_trace_error(renv, "invalid operand"); return SIEVE_EXEC_BIN_CORRUPT; } - if ( !sieve_operand_is_omitted(operand) ) { + if ( !sieve_operand_is_omitted(&operand) ) { if ( !sieve_opr_string_read_data - (renv, operand, address, &zone) ) { + (renv, &operand, address, &zone) ) { sieve_runtime_trace_error(renv, "invalid zone operand"); return SIEVE_EXEC_BIN_CORRUPT; } @@ -426,7 +427,7 @@ static int tst_date_operation_execute } while ( opt_code != SIEVE_MATCH_OPT_END ); - if ( op == &date_operation ) { + if ( sieve_operation_is(op, date_operation) ) { /* Read header name */ if ( !sieve_opr_string_read(renv, address, &header_name) ) { sieve_runtime_trace_error(renv, "invalid header-name operand"); @@ -448,13 +449,13 @@ static int tst_date_operation_execute /* Perform test */ - sieve_runtime_trace(renv, "%s test", op->mnemonic); + sieve_runtime_trace(renv, "%s test", sieve_operation_mnemonic(op)); /* Get the date value */ local_time = ext_date_get_current_date(renv, &local_zone); - if ( op == &date_operation ) { + if ( sieve_operation_is(op, date_operation) ) { const char *header_value; const char *date_string; @@ -482,7 +483,7 @@ static int tst_date_operation_execute got_date = TRUE; } } - } else if ( op == ¤tdate_operation ) { + } else if ( sieve_operation_is(op, currentdate_operation) ) { /* Use time stamp recorded at the time the script first started */ date_value = local_time; @@ -519,7 +520,7 @@ static int tst_date_operation_execute } /* Initialize match */ - mctx = sieve_match_begin(renv->interp, mtch, cmp, NULL, key_list); + mctx = sieve_match_begin(renv->interp, &mcht, &cmp, NULL, key_list); if ( got_date && part_value != NULL ) { /* Match value */ diff --git a/src/lib-sieve/plugins/enotify/cmd-notify.c b/src/lib-sieve/plugins/enotify/cmd-notify.c index 7149be15b..c86fc0b23 100644 --- a/src/lib-sieve/plugins/enotify/cmd-notify.c +++ b/src/lib-sieve/plugins/enotify/cmd-notify.c @@ -20,10 +20,10 @@ * Forward declarations */ -static const struct sieve_argument notify_importance_tag; -static const struct sieve_argument notify_from_tag; -static const struct sieve_argument notify_options_tag; -static const struct sieve_argument notify_message_tag; +static const struct sieve_argument_def notify_importance_tag; +static const struct sieve_argument_def notify_from_tag; +static const struct sieve_argument_def notify_options_tag; +static const struct sieve_argument_def notify_message_tag; /* * Notify command @@ -37,16 +37,16 @@ static const struct sieve_argument notify_message_tag; */ static bool cmd_notify_registered - (struct sieve_validator *valdtr, + (struct sieve_validator *valdtr, const struct sieve_extension *ext, struct sieve_command_registration *cmd_reg); static bool cmd_notify_pre_validate - (struct sieve_validator *validator, struct sieve_command_context *cmd); + (struct sieve_validator *validator, struct sieve_command *cmd); static bool cmd_notify_validate - (struct sieve_validator *valdtr, struct sieve_command_context *cmd); + (struct sieve_validator *valdtr, struct sieve_command *cmd); static bool cmd_notify_generate - (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx); + (const struct sieve_codegen_env *cgenv, struct sieve_command *ctx); -const struct sieve_command notify_command = { +const struct sieve_command_def notify_command = { "notify", SCT_COMMAND, 1, 0, FALSE, FALSE, @@ -65,42 +65,42 @@ const struct sieve_command notify_command = { static bool cmd_notify_validate_string_tag (struct sieve_validator *valdtr, struct sieve_ast_argument **arg, - struct sieve_command_context *cmd); + struct sieve_command *cmd); static bool cmd_notify_validate_stringlist_tag (struct sieve_validator *valdtr, struct sieve_ast_argument **arg, - struct sieve_command_context *cmd); + struct sieve_command *cmd); static bool cmd_notify_validate_importance_tag (struct sieve_validator *valdtr, struct sieve_ast_argument **arg, - struct sieve_command_context *cmd); + struct sieve_command *cmd); /* Argument objects */ -static const struct sieve_argument notify_from_tag = { +static const struct sieve_argument_def notify_from_tag = { "from", - NULL, NULL, + NULL, cmd_notify_validate_string_tag, - NULL, NULL + NULL, NULL, NULL }; -static const struct sieve_argument notify_options_tag = { +static const struct sieve_argument_def notify_options_tag = { "options", - NULL, NULL, + NULL, cmd_notify_validate_stringlist_tag, - NULL, NULL + NULL, NULL, NULL }; -static const struct sieve_argument notify_message_tag = { +static const struct sieve_argument_def notify_message_tag = { "message", - NULL, NULL, + NULL, cmd_notify_validate_string_tag, - NULL, NULL + NULL, NULL, NULL }; -static const struct sieve_argument notify_importance_tag = { +static const struct sieve_argument_def notify_importance_tag = { "importance", - NULL, NULL, + NULL, cmd_notify_validate_importance_tag, - NULL, NULL + NULL, NULL, NULL }; /* @@ -108,13 +108,11 @@ static const struct sieve_argument notify_importance_tag = { */ static bool cmd_notify_operation_dump - (const struct sieve_operation *op, - const struct sieve_dumptime_env *denv, sieve_size_t *address); + (const struct sieve_dumptime_env *denv, sieve_size_t *address); static int cmd_notify_operation_execute - (const struct sieve_operation *op, - const struct sieve_runtime_env *renv, sieve_size_t *address); + (const struct sieve_runtime_env *renv, sieve_size_t *address); -const struct sieve_operation notify_operation = { +const struct sieve_operation_def notify_operation = { "NOTIFY", &enotify_extension, EXT_ENOTIFY_OPERATION_NOTIFY, @@ -130,18 +128,18 @@ const struct sieve_operation notify_operation = { static int act_notify_check_duplicate (const struct sieve_runtime_env *renv, - const struct sieve_action_data *act, - const struct sieve_action_data *act_other); + const struct sieve_action *act, + const struct sieve_action *act_other); static void act_notify_print (const struct sieve_action *action, const struct sieve_result_print_env *rpenv, - void *context, bool *keep); + bool *keep); static bool act_notify_commit (const struct sieve_action *action, const struct sieve_action_exec_env *aenv, void *tr_context, bool *keep); /* Action object */ -const struct sieve_action act_notify = { +const struct sieve_action_def act_notify = { "notify", 0, NULL, @@ -169,7 +167,7 @@ struct cmd_notify_context_data { static bool cmd_notify_validate_string_tag (struct sieve_validator *valdtr, struct sieve_ast_argument **arg, - struct sieve_command_context *cmd) + struct sieve_command *cmd) { struct sieve_ast_argument *tag = *arg; struct cmd_notify_context_data *ctx_data = @@ -185,13 +183,13 @@ static bool cmd_notify_validate_string_tag if ( !sieve_validate_tag_parameter(valdtr, cmd, tag, *arg, SAAT_STRING) ) return FALSE; - if ( tag->argument == ¬ify_from_tag ) { + if ( sieve_argument_is(tag, notify_from_tag) ) { ctx_data->from = *arg; /* Skip parameter */ *arg = sieve_ast_argument_next(*arg); - } else if ( tag->argument == ¬ify_message_tag ) { + } else if ( sieve_argument_is(tag, notify_message_tag) ) { ctx_data->message = *arg; /* Skip parameter */ @@ -203,7 +201,7 @@ static bool cmd_notify_validate_string_tag static bool cmd_notify_validate_stringlist_tag (struct sieve_validator *valdtr, struct sieve_ast_argument **arg, - struct sieve_command_context *cmd) + struct sieve_command *cmd) { struct sieve_ast_argument *tag = *arg; struct cmd_notify_context_data *ctx_data = @@ -229,7 +227,7 @@ static bool cmd_notify_validate_stringlist_tag static bool cmd_notify_validate_importance_tag (struct sieve_validator *valdtr, struct sieve_ast_argument **arg, - struct sieve_command_context *cmd ATTR_UNUSED) + struct sieve_command *cmd ATTR_UNUSED) { const struct sieve_ast_argument *tag = *arg; const char *impstr; @@ -259,8 +257,8 @@ static bool cmd_notify_validate_importance_tag } sieve_ast_argument_number_substitute(*arg, impstr[0] - '0'); - (*arg)->arg_id_code = tag->arg_id_code; - (*arg)->argument = &number_argument; + (*arg)->argument = sieve_argument_create + ((*arg)->ast, &number_argument, tag->argument->ext, tag->argument->id_code); /* Skip parameter */ *arg = sieve_ast_argument_next(*arg); @@ -274,16 +272,17 @@ static bool cmd_notify_validate_importance_tag */ static bool cmd_notify_registered -(struct sieve_validator *valdtr, struct sieve_command_registration *cmd_reg) +(struct sieve_validator *valdtr, const struct sieve_extension *ext, + struct sieve_command_registration *cmd_reg) { sieve_validator_register_tag - (valdtr, cmd_reg, ¬ify_importance_tag, CMD_NOTIFY_OPT_IMPORTANCE); + (valdtr, cmd_reg, ext, ¬ify_importance_tag, CMD_NOTIFY_OPT_IMPORTANCE); sieve_validator_register_tag - (valdtr, cmd_reg, ¬ify_from_tag, CMD_NOTIFY_OPT_FROM); + (valdtr, cmd_reg, ext, ¬ify_from_tag, CMD_NOTIFY_OPT_FROM); sieve_validator_register_tag - (valdtr, cmd_reg, ¬ify_options_tag, CMD_NOTIFY_OPT_OPTIONS); + (valdtr, cmd_reg, ext, ¬ify_options_tag, CMD_NOTIFY_OPT_OPTIONS); sieve_validator_register_tag - (valdtr, cmd_reg, ¬ify_message_tag, CMD_NOTIFY_OPT_MESSAGE); + (valdtr, cmd_reg, ext, ¬ify_message_tag, CMD_NOTIFY_OPT_MESSAGE); return TRUE; } @@ -294,7 +293,7 @@ static bool cmd_notify_registered static bool cmd_notify_pre_validate (struct sieve_validator *validator ATTR_UNUSED, - struct sieve_command_context *cmd) + struct sieve_command *cmd) { struct cmd_notify_context_data *ctx_data; @@ -307,7 +306,7 @@ static bool cmd_notify_pre_validate } static bool cmd_notify_validate -(struct sieve_validator *valdtr, struct sieve_command_context *cmd) +(struct sieve_validator *valdtr, struct sieve_command *cmd) { struct sieve_ast_argument *arg = cmd->first_positional; struct cmd_notify_context_data *ctx_data = @@ -322,7 +321,7 @@ static bool cmd_notify_validate return FALSE; return ext_enotify_compile_check_arguments - (valdtr, arg, ctx_data->message, ctx_data->from, ctx_data->options); + (valdtr, cmd, arg, ctx_data->message, ctx_data->from, ctx_data->options); } /* @@ -330,15 +329,15 @@ static bool cmd_notify_validate */ static bool cmd_notify_generate -(const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx) +(const struct sieve_codegen_env *cgenv, struct sieve_command *cmd) { - sieve_operation_emit_code(cgenv->sbin, ¬ify_operation); + sieve_operation_emit(cgenv->sbin, cmd->ext, ¬ify_operation); /* Emit source line */ - sieve_code_source_line_emit(cgenv->sbin, sieve_command_source_line(ctx)); + sieve_code_source_line_emit(cgenv->sbin, sieve_command_source_line(cmd)); /* Generate arguments */ - return sieve_generate_arguments(cgenv, ctx, NULL); + return sieve_generate_arguments(cgenv, cmd, NULL); } /* @@ -346,8 +345,7 @@ static bool cmd_notify_generate */ static bool cmd_notify_operation_dump -(const struct sieve_operation *op ATTR_UNUSED, - const struct sieve_dumptime_env *denv, sieve_size_t *address) +(const struct sieve_dumptime_env *denv, sieve_size_t *address) { int opt_code = 1; @@ -401,9 +399,9 @@ static bool cmd_notify_operation_dump */ static int cmd_notify_operation_execute -(const struct sieve_operation *op ATTR_UNUSED, - const struct sieve_runtime_env *renv, sieve_size_t *address) +(const struct sieve_runtime_env *renv, sieve_size_t *address) { + const struct sieve_extension *this_ext = renv->oprtn.ext; struct sieve_side_effects_list *slist = NULL; struct sieve_enotify_action *act; void *method_context; @@ -505,7 +503,7 @@ static int cmd_notify_operation_execute act->from = p_strdup(pool, str_c(from)); return ( sieve_result_add_action - (renv, &act_notify, slist, source_line, (void *) act, 0) >= 0 ); + (renv, this_ext, &act_notify, slist, source_line, (void *) act, 0) >= 0 ); } return result; @@ -519,8 +517,8 @@ static int cmd_notify_operation_execute static int act_notify_check_duplicate (const struct sieve_runtime_env *renv ATTR_UNUSED, - const struct sieve_action_data *act ATTR_UNUSED, - const struct sieve_action_data *act_other ATTR_UNUSED) + const struct sieve_action *act ATTR_UNUSED, + const struct sieve_action *act_other ATTR_UNUSED) { const struct sieve_enotify_action *nact1, *nact2; struct sieve_enotify_log nlog; @@ -545,12 +543,11 @@ static int act_notify_check_duplicate /* Result printing */ static void act_notify_print -(const struct sieve_action *action ATTR_UNUSED, - const struct sieve_result_print_env *rpenv, void *context, +(const struct sieve_action *action, const struct sieve_result_print_env *rpenv, bool *keep ATTR_UNUSED) { const struct sieve_enotify_action *act = - (const struct sieve_enotify_action *) context; + (const struct sieve_enotify_action *) action->context; sieve_result_action_printf ( rpenv, "send notification with method '%s:':", act->method->identifier); @@ -568,12 +565,11 @@ static void act_notify_print /* Result execution */ static bool act_notify_commit -(const struct sieve_action *action ATTR_UNUSED, - const struct sieve_action_exec_env *aenv, void *tr_context, - bool *keep ATTR_UNUSED) +(const struct sieve_action *action, const struct sieve_action_exec_env *aenv, + void *tr_context ATTR_UNUSED, bool *keep ATTR_UNUSED) { const struct sieve_enotify_action *act = - (const struct sieve_enotify_action *) tr_context; + (const struct sieve_enotify_action *) action->context; struct sieve_enotify_exec_env nenv; struct sieve_enotify_log nlog; diff --git a/src/lib-sieve/plugins/enotify/ext-enotify-common.c b/src/lib-sieve/plugins/enotify/ext-enotify-common.c index 55b61dffa..a704af387 100644 --- a/src/lib-sieve/plugins/enotify/ext-enotify-common.c +++ b/src/lib-sieve/plugins/enotify/ext-enotify-common.c @@ -43,11 +43,11 @@ * Notify capability */ -static const char *ext_notify_get_methods_string(void); +static const char *ext_notify_get_methods_string + (const struct sieve_extension *ntfy_ext); const struct sieve_extension_capabilities notify_capabilities = { "notify", - &enotify_extension, ext_notify_get_methods_string }; @@ -55,32 +55,42 @@ const struct sieve_extension_capabilities notify_capabilities = { * Notify method registry */ -static ARRAY_DEFINE(ext_enotify_methods, const struct sieve_enotify_method *); +static void ext_enotify_method_register +(struct ext_enotify_context *ectx, const struct sieve_enotify_method *method) +{ + array_append(&ectx->notify_methods, &method, 1); +} -void ext_enotify_methods_init(void) +void ext_enotify_methods_init(struct ext_enotify_context *ectx) { - p_array_init(&ext_enotify_methods, default_pool, 4); + p_array_init(&ectx->notify_methods, default_pool, 4); - sieve_enotify_method_register(&mailto_notify); + ext_enotify_method_register(ectx, &mailto_notify); } -void ext_enotify_methods_deinit(void) +void ext_enotify_methods_deinit(struct ext_enotify_context *ectx) { - array_free(&ext_enotify_methods); + array_free(&ectx->notify_methods); } -void sieve_enotify_method_register(const struct sieve_enotify_method *method) +void sieve_enotify_method_register +(struct sieve_extension *ntfy_ext, const struct sieve_enotify_method *method) { - array_append(&ext_enotify_methods, &method, 1); + struct ext_enotify_context *ectx = + (struct ext_enotify_context *) ntfy_ext->context; + + ext_enotify_method_register(ectx, method); } const struct sieve_enotify_method *ext_enotify_method_find -(const char *identifier) +(const struct sieve_extension *ntfy_ext, const char *identifier) { + struct ext_enotify_context *ectx = + (struct ext_enotify_context *) ntfy_ext->context; unsigned int meth_count, i; const struct sieve_enotify_method *const *methods; - methods = array_get(&ext_enotify_methods, &meth_count); + methods = array_get(&ectx->notify_methods, &meth_count); for ( i = 0; i < meth_count; i++ ) { if ( strcasecmp(methods[i]->identifier, identifier) == 0 ) { @@ -91,13 +101,16 @@ const struct sieve_enotify_method *ext_enotify_method_find return NULL; } -static const char *ext_notify_get_methods_string(void) +static const char *ext_notify_get_methods_string +(const struct sieve_extension *ntfy_ext) { + struct ext_enotify_context *ectx = + (struct ext_enotify_context *) ntfy_ext->context; unsigned int meth_count, i; const struct sieve_enotify_method *const *methods; string_t *result = t_str_new(128); - methods = array_get(&ext_enotify_methods, &meth_count); + methods = array_get(&ectx->notify_methods, &meth_count); if ( meth_count > 0 ) { str_append(result, methods[0]->identifier); @@ -282,10 +295,11 @@ static int _ext_enotify_option_check } bool ext_enotify_compile_check_arguments -(struct sieve_validator *valdtr, struct sieve_ast_argument *uri_arg, - struct sieve_ast_argument *msg_arg, struct sieve_ast_argument *from_arg, - struct sieve_ast_argument *options_arg) +(struct sieve_validator *valdtr, struct sieve_command *cmd, + struct sieve_ast_argument *uri_arg, struct sieve_ast_argument *msg_arg, + struct sieve_ast_argument *from_arg, struct sieve_ast_argument *options_arg) { + const struct sieve_extension *this_ext = cmd->ext; const char *uri = sieve_ast_argument_strc(uri_arg); const char *scheme; const struct sieve_enotify_method *method; @@ -306,7 +320,7 @@ bool ext_enotify_compile_check_arguments } /* Find used method with the parsed scheme identifier */ - if ( (method=ext_enotify_method_find(scheme)) == NULL ) { + if ( (method=ext_enotify_method_find(this_ext, scheme)) == NULL ) { sieve_argument_validate_error(valdtr, uri_arg, "notify command: invalid method '%s'", scheme); return FALSE; @@ -383,6 +397,7 @@ bool ext_enotify_runtime_method_validate (const struct sieve_runtime_env *renv, unsigned int source_line, string_t *method_uri) { + const struct sieve_extension *this_ext = renv->oprtn.ext; const struct sieve_enotify_method *method; const char *uri = str_c(method_uri); const char *scheme; @@ -392,7 +407,7 @@ bool ext_enotify_runtime_method_validate if ( (scheme=ext_enotify_uri_scheme_parse(&uri)) == NULL ) return FALSE; - if ( (method=ext_enotify_method_find(scheme)) == NULL ) + if ( (method=ext_enotify_method_find(this_ext, scheme)) == NULL ) return FALSE; /* Validate the provided URI */ @@ -417,6 +432,7 @@ static const struct sieve_enotify_method *ext_enotify_get_method (const struct sieve_runtime_env *renv, unsigned int source_line, string_t *method_uri, const char **uri_body_r) { + const struct sieve_extension *this_ext = renv->oprtn.ext; const struct sieve_enotify_method *method; const char *uri = str_c(method_uri); const char *scheme; @@ -433,7 +449,7 @@ static const struct sieve_enotify_method *ext_enotify_get_method } /* Find the notify method */ - if ( (method=ext_enotify_method_find(scheme)) == NULL ) { + if ( (method=ext_enotify_method_find(this_ext, scheme)) == NULL ) { sieve_runtime_error (renv, sieve_error_script_location(renv->script, source_line), "invalid notify method '%s'", scheme); diff --git a/src/lib-sieve/plugins/enotify/ext-enotify-common.h b/src/lib-sieve/plugins/enotify/ext-enotify-common.h index b4e6e3984..5cb8619af 100644 --- a/src/lib-sieve/plugins/enotify/ext-enotify-common.h +++ b/src/lib-sieve/plugins/enotify/ext-enotify-common.h @@ -4,6 +4,11 @@ #ifndef __EXT_ENOTIFY_COMMON_H #define __EXT_ENOTIFY_COMMON_H +#include "lib.h" +#include "array.h" + +#include "sieve-common.h" + #include "sieve-ext-variables.h" #include "sieve-ext-enotify.h" @@ -12,14 +17,20 @@ * Extension */ -extern const struct sieve_extension enotify_extension; +extern const struct sieve_extension_def enotify_extension; extern const struct sieve_extension_capabilities notify_capabilities; +struct ext_enotify_context { + const struct sieve_extension *var_ext; + ARRAY_DEFINE(notify_methods, const struct sieve_enotify_method *); +}; + + /* * Commands */ -extern const struct sieve_command notify_command; +extern const struct sieve_command_def notify_command; /* Codes for optional arguments */ @@ -35,16 +46,16 @@ enum cmd_notify_optional { * Tests */ -extern const struct sieve_command valid_notify_method_test; -extern const struct sieve_command notify_method_capability_test; +extern const struct sieve_command_def valid_notify_method_test; +extern const struct sieve_command_def notify_method_capability_test; /* * Operations */ -extern const struct sieve_operation notify_operation; -extern const struct sieve_operation valid_notify_method_operation; -extern const struct sieve_operation notify_method_capability_operation; +extern const struct sieve_operation_def notify_operation; +extern const struct sieve_operation_def valid_notify_method_operation; +extern const struct sieve_operation_def notify_method_capability_operation; enum ext_variables_opcode { EXT_ENOTIFY_OPERATION_NOTIFY, @@ -56,13 +67,13 @@ enum ext_variables_opcode { * Operands */ -extern const struct sieve_operand encodeurl_operand; +extern const struct sieve_operand_def encodeurl_operand; /* * Modifiers */ -extern const struct sieve_variables_modifier encodeurl_modifier; +extern const struct sieve_variables_modifier_def encodeurl_modifier; /* * Notify methods @@ -70,20 +81,21 @@ extern const struct sieve_variables_modifier encodeurl_modifier; extern const struct sieve_enotify_method mailto_notify; -void ext_enotify_methods_init(void); -void ext_enotify_methods_deinit(void); +void ext_enotify_methods_init(struct ext_enotify_context *ectx); +void ext_enotify_methods_deinit(struct ext_enotify_context *ectx); const struct sieve_enotify_method *ext_enotify_method_find - (const char *identifier); + (const struct sieve_extension *ntfy_ext, const char *identifier); /* * Validation */ bool ext_enotify_compile_check_arguments -(struct sieve_validator *valdtr, struct sieve_ast_argument *uri_arg, - struct sieve_ast_argument *msg_arg, struct sieve_ast_argument *from_arg, - struct sieve_ast_argument *options_arg); + (struct sieve_validator *valdtr, struct sieve_command *cmd, + struct sieve_ast_argument *uri_arg, struct sieve_ast_argument *msg_arg, + struct sieve_ast_argument *from_arg, + struct sieve_ast_argument *options_arg); /* * Runtime diff --git a/src/lib-sieve/plugins/enotify/ext-enotify.c b/src/lib-sieve/plugins/enotify/ext-enotify.c index 2ed08298d..99183547b 100644 --- a/src/lib-sieve/plugins/enotify/ext-enotify.c +++ b/src/lib-sieve/plugins/enotify/ext-enotify.c @@ -32,7 +32,7 @@ * Operations */ -const struct sieve_operation *ext_enotify_operations[] = { +const struct sieve_operation_def *ext_enotify_operations[] = { ¬ify_operation, &valid_notify_method_operation, ¬ify_method_capability_operation @@ -42,15 +42,13 @@ const struct sieve_operation *ext_enotify_operations[] = { * Extension */ -static bool ext_enotify_load(void); -static void ext_enotify_unload(void); -static bool ext_enotify_validator_load(struct sieve_validator *valdtr); +static bool ext_enotify_load(const struct sieve_extension *ext, void **context); +static void ext_enotify_unload(const struct sieve_extension *ext); +static bool ext_enotify_validator_load + (const struct sieve_extension *ext, struct sieve_validator *valdtr); -static int ext_my_id = -1; - -const struct sieve_extension enotify_extension = { +const struct sieve_extension_def enotify_extension = { "enotify", - &ext_my_id, ext_enotify_load, ext_enotify_unload, ext_enotify_validator_load, @@ -59,29 +57,45 @@ const struct sieve_extension enotify_extension = { SIEVE_EXT_DEFINE_OPERAND(encodeurl_operand) }; -static bool ext_enotify_load(void) +static bool ext_enotify_load(const struct sieve_extension *ext, void **context) { - ext_enotify_methods_init(); + struct ext_enotify_context *ectx; + + ectx = i_new(struct ext_enotify_context, 1); + ectx->var_ext = sieve_ext_variables_get_extension(ext->svinst); + *context = (void *) ectx; + + ext_enotify_methods_init(ectx); - sieve_extension_capabilities_register(¬ify_capabilities); + sieve_extension_capabilities_register(ext->svinst, ext, ¬ify_capabilities); return TRUE; } -static void ext_enotify_unload(void) +static void ext_enotify_unload(const struct sieve_extension *ext) { - ext_enotify_methods_deinit(); + struct ext_enotify_context *ectx = + (struct ext_enotify_context *) ext->context; + + ext_enotify_methods_deinit(ectx); + + i_free(ectx); } -static bool ext_enotify_validator_load(struct sieve_validator *valdtr) +static bool ext_enotify_validator_load +(const struct sieve_extension *ext, struct sieve_validator *valdtr) { + struct ext_enotify_context *ectx = + (struct ext_enotify_context *) ext->context; + /* Register new commands */ - sieve_validator_register_command(valdtr, ¬ify_command); - sieve_validator_register_command(valdtr, &valid_notify_method_test); - sieve_validator_register_command(valdtr, ¬ify_method_capability_test); + sieve_validator_register_command(valdtr, ext, ¬ify_command); + sieve_validator_register_command(valdtr, ext, &valid_notify_method_test); + sieve_validator_register_command(valdtr, ext, ¬ify_method_capability_test); /* Register new set modifier for variables extension */ - sieve_variables_modifier_register(valdtr, &encodeurl_modifier); + sieve_variables_modifier_register + (ectx->var_ext, valdtr, ext, &encodeurl_modifier); return TRUE; } diff --git a/src/lib-sieve/plugins/enotify/sieve-ext-enotify.h b/src/lib-sieve/plugins/enotify/sieve-ext-enotify.h index 494480dc8..44d2a3988 100644 --- a/src/lib-sieve/plugins/enotify/sieve-ext-enotify.h +++ b/src/lib-sieve/plugins/enotify/sieve-ext-enotify.h @@ -86,7 +86,8 @@ struct sieve_enotify_method { const struct sieve_enotify_action *act); }; -void sieve_enotify_method_register(const struct sieve_enotify_method *method); +void sieve_enotify_method_register +(struct sieve_extension *ntfy_ext, const struct sieve_enotify_method *method); /* * Notify method printing diff --git a/src/lib-sieve/plugins/enotify/tst-notify-method-capability.c b/src/lib-sieve/plugins/enotify/tst-notify-method-capability.c index f37172c53..67ffb7c27 100644 --- a/src/lib-sieve/plugins/enotify/tst-notify-method-capability.c +++ b/src/lib-sieve/plugins/enotify/tst-notify-method-capability.c @@ -27,13 +27,14 @@ */ static bool tst_notifymc_registered - (struct sieve_validator *validator, struct sieve_command_registration *cmd_reg); + (struct sieve_validator *valdtr, const struct sieve_extension *ext, + struct sieve_command_registration *cmd_reg); static bool tst_notifymc_validate - (struct sieve_validator *validator, struct sieve_command_context *tst); + (struct sieve_validator *valdtr, struct sieve_command *tst); static bool tst_notifymc_generate - (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx); + (const struct sieve_codegen_env *cgenv, struct sieve_command *ctx); -const struct sieve_command notify_method_capability_test = { +const struct sieve_command_def notify_method_capability_test = { "notify_method_capability", SCT_TEST, 3, 0, FALSE, FALSE, @@ -49,13 +50,11 @@ const struct sieve_command notify_method_capability_test = { */ static bool tst_notifymc_operation_dump - (const struct sieve_operation *op, - const struct sieve_dumptime_env *denv, sieve_size_t *address); + (const struct sieve_dumptime_env *denv, sieve_size_t *address); static int tst_notifymc_operation_execute - (const struct sieve_operation *op, - const struct sieve_runtime_env *renv, sieve_size_t *address); + (const struct sieve_runtime_env *renv, sieve_size_t *address); -const struct sieve_operation notify_method_capability_operation = { +const struct sieve_operation_def notify_method_capability_operation = { "NOTIFY_METHOD_CAPABILITY", &enotify_extension, EXT_ENOTIFY_OPERATION_NOTIFY_METHOD_CAPABILITY, @@ -78,11 +77,12 @@ enum tst_notifymc_optional { */ static bool tst_notifymc_registered - (struct sieve_validator *validator, struct sieve_command_registration *cmd_reg) +(struct sieve_validator *valdtr, const struct sieve_extension *ext ATTR_UNUSED, + struct sieve_command_registration *cmd_reg) { /* The order of these is not significant */ - sieve_comparators_link_tag(validator, cmd_reg, OPT_COMPARATOR); - sieve_match_types_link_tags(validator, cmd_reg, OPT_MATCH_TYPE); + sieve_comparators_link_tag(valdtr, cmd_reg, OPT_COMPARATOR); + sieve_match_types_link_tags(valdtr, cmd_reg, OPT_MATCH_TYPE); return TRUE; } @@ -92,41 +92,45 @@ static bool tst_notifymc_registered */ static bool tst_notifymc_validate - (struct sieve_validator *validator, struct sieve_command_context *tst) +(struct sieve_validator *valdtr, struct sieve_command *tst) { struct sieve_ast_argument *arg = tst->first_positional; + const struct sieve_match_type mcht_default = + SIEVE_MATCH_TYPE_DEFAULT(is_match_type); + const struct sieve_comparator cmp_default = + SIEVE_COMPARATOR_DEFAULT(i_ascii_casemap_comparator); if ( !sieve_validate_positional_argument - (validator, tst, arg, "notification-uri", 1, SAAT_STRING) ) { + (valdtr, tst, arg, "notification-uri", 1, SAAT_STRING) ) { return FALSE; } - if ( !sieve_validator_argument_activate(validator, tst, arg, FALSE) ) + if ( !sieve_validator_argument_activate(valdtr, tst, arg, FALSE) ) return FALSE; arg = sieve_ast_argument_next(arg); if ( !sieve_validate_positional_argument - (validator, tst, arg, "notification-capability", 2, SAAT_STRING) ) { + (valdtr, tst, arg, "notification-capability", 2, SAAT_STRING) ) { return FALSE; } - if ( !sieve_validator_argument_activate(validator, tst, arg, FALSE) ) + if ( !sieve_validator_argument_activate(valdtr, tst, arg, FALSE) ) return FALSE; arg = sieve_ast_argument_next(arg); if ( !sieve_validate_positional_argument - (validator, tst, arg, "key-list", 3, SAAT_STRING_LIST) ) { + (valdtr, tst, arg, "key-list", 3, SAAT_STRING_LIST) ) { return FALSE; } - if ( !sieve_validator_argument_activate(validator, tst, arg, FALSE) ) + if ( !sieve_validator_argument_activate(valdtr, tst, arg, FALSE) ) return FALSE; /* Validate the key argument to a specified match type */ return sieve_match_type_validate - (validator, tst, arg, &is_match_type, &i_ascii_casemap_comparator); + (valdtr, tst, arg, &mcht_default, &cmp_default); } /* @@ -134,12 +138,13 @@ static bool tst_notifymc_validate */ static bool tst_notifymc_generate - (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx) + (const struct sieve_codegen_env *cgenv, struct sieve_command *cmd) { - sieve_operation_emit_code(cgenv->sbin, ¬ify_method_capability_operation); + sieve_operation_emit + (cgenv->sbin, cmd->ext, ¬ify_method_capability_operation); /* Generate arguments */ - return sieve_generate_arguments(cgenv, ctx, NULL); + return sieve_generate_arguments(cgenv, cmd, NULL); } /* @@ -147,8 +152,7 @@ static bool tst_notifymc_generate */ static bool tst_notifymc_operation_dump -(const struct sieve_operation *op ATTR_UNUSED, - const struct sieve_dumptime_env *denv, sieve_size_t *address) +(const struct sieve_dumptime_env *denv, sieve_size_t *address) { int opt_code = 0; @@ -173,14 +177,15 @@ static bool tst_notifymc_operation_dump */ static int tst_notifymc_operation_execute -(const struct sieve_operation *op ATTR_UNUSED, - const struct sieve_runtime_env *renv, sieve_size_t *address) +(const struct sieve_runtime_env *renv, sieve_size_t *address) { int ret, mret; bool result = TRUE; int opt_code = 0; - const struct sieve_comparator *cmp = &i_octet_comparator; - const struct sieve_match_type *mtch = &is_match_type; + struct sieve_match_type mcht = + SIEVE_MATCH_TYPE_DEFAULT(is_match_type); + struct sieve_comparator cmp = + SIEVE_COMPARATOR_DEFAULT(i_ascii_casemap_comparator); struct sieve_match_context *mctx; string_t *notify_uri, *notify_capability; struct sieve_coded_stringlist *key_list; @@ -193,7 +198,7 @@ static int tst_notifymc_operation_execute /* Handle match-type and comparator operands */ if ( (ret=sieve_match_read_optional_operands - (renv, address, &opt_code, &cmp, &mtch)) <= 0 ) + (renv, address, &opt_code, &cmp, &mcht)) <= 0 ) return ret; /* Check whether we neatly finished the list of optional operands */ @@ -230,7 +235,7 @@ static int tst_notifymc_operation_execute (renv, 0 /* FIXME */, notify_uri, str_c(notify_capability)); if ( cap_value != NULL ) { - mctx = sieve_match_begin(renv->interp, mtch, cmp, NULL, key_list); + mctx = sieve_match_begin(renv->interp, &mcht, &cmp, NULL, key_list); if ( (mret=sieve_match_value(mctx, cap_value, strlen(cap_value))) < 0 ) result = FALSE; diff --git a/src/lib-sieve/plugins/enotify/tst-valid-notify-method.c b/src/lib-sieve/plugins/enotify/tst-valid-notify-method.c index 779318a7c..8972f14a7 100644 --- a/src/lib-sieve/plugins/enotify/tst-valid-notify-method.c +++ b/src/lib-sieve/plugins/enotify/tst-valid-notify-method.c @@ -22,11 +22,11 @@ */ static bool tst_vnotifym_validate - (struct sieve_validator *validator, struct sieve_command_context *tst); + (struct sieve_validator *valdtr, struct sieve_command *tst); static bool tst_vnotifym_generate - (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx); + (const struct sieve_codegen_env *cgenv, struct sieve_command *ctx); -const struct sieve_command valid_notify_method_test = { +const struct sieve_command_def valid_notify_method_test = { "valid_notify_method", SCT_TEST, 1, 0, FALSE, FALSE, @@ -41,13 +41,11 @@ const struct sieve_command valid_notify_method_test = { */ static bool tst_vnotifym_operation_dump - (const struct sieve_operation *op, - const struct sieve_dumptime_env *denv, sieve_size_t *address); + (const struct sieve_dumptime_env *denv, sieve_size_t *address); static int tst_vnotifym_operation_execute - (const struct sieve_operation *op, - const struct sieve_runtime_env *renv, sieve_size_t *address); + (const struct sieve_runtime_env *renv, sieve_size_t *address); -const struct sieve_operation valid_notify_method_operation = { +const struct sieve_operation_def valid_notify_method_operation = { "VALID_NOTIFY_METHOD", &enotify_extension, EXT_ENOTIFY_OPERATION_VALID_NOTIFY_METHOD, @@ -60,16 +58,16 @@ const struct sieve_operation valid_notify_method_operation = { */ static bool tst_vnotifym_validate - (struct sieve_validator *validator, struct sieve_command_context *tst) + (struct sieve_validator *valdtr, struct sieve_command *tst) { struct sieve_ast_argument *arg = tst->first_positional; if ( !sieve_validate_positional_argument - (validator, tst, arg, "notification-uris", 1, SAAT_STRING_LIST) ) { + (valdtr, tst, arg, "notification-uris", 1, SAAT_STRING_LIST) ) { return FALSE; } - return sieve_validator_argument_activate(validator, tst, arg, FALSE); + return sieve_validator_argument_activate(valdtr, tst, arg, FALSE); } /* @@ -77,12 +75,12 @@ static bool tst_vnotifym_validate */ static bool tst_vnotifym_generate - (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx) +(const struct sieve_codegen_env *cgenv, struct sieve_command *cmd) { - sieve_operation_emit_code(cgenv->sbin, &valid_notify_method_operation); + sieve_operation_emit(cgenv->sbin, cmd->ext, &valid_notify_method_operation); /* Generate arguments */ - return sieve_generate_arguments(cgenv, ctx, NULL); + return sieve_generate_arguments(cgenv, cmd, NULL); } /* @@ -90,8 +88,7 @@ static bool tst_vnotifym_generate */ static bool tst_vnotifym_operation_dump -(const struct sieve_operation *op ATTR_UNUSED, - const struct sieve_dumptime_env *denv, sieve_size_t *address) +(const struct sieve_dumptime_env *denv, sieve_size_t *address) { sieve_code_dumpf(denv, "VALID_NOTIFY_METHOD"); sieve_code_descend(denv); @@ -105,8 +102,7 @@ static bool tst_vnotifym_operation_dump */ static int tst_vnotifym_operation_execute -(const struct sieve_operation *op ATTR_UNUSED, - const struct sieve_runtime_env *renv, sieve_size_t *address) +(const struct sieve_runtime_env *renv, sieve_size_t *address) { struct sieve_coded_stringlist *notify_uris; string_t *uri_item; diff --git a/src/lib-sieve/plugins/enotify/vmodf-encodeurl.c b/src/lib-sieve/plugins/enotify/vmodf-encodeurl.c index 1e404ffa8..779568079 100644 --- a/src/lib-sieve/plugins/enotify/vmodf-encodeurl.c +++ b/src/lib-sieve/plugins/enotify/vmodf-encodeurl.c @@ -17,7 +17,7 @@ bool mod_encodeurl_modify(string_t *in, string_t **result); -const struct sieve_variables_modifier encodeurl_modifier = { +const struct sieve_variables_modifier_def encodeurl_modifier = { SIEVE_OBJECT("encodeurl", &encodeurl_operand, 0), 15, mod_encodeurl_modify @@ -30,7 +30,7 @@ const struct sieve_variables_modifier encodeurl_modifier = { static const struct sieve_extension_objects ext_enotify_modifiers = SIEVE_VARIABLES_DEFINE_MODIFIER(encodeurl_modifier); -const struct sieve_operand encodeurl_operand = { +const struct sieve_operand_def encodeurl_operand = { "modifier", &enotify_extension, 0, diff --git a/src/lib-sieve/plugins/environment/ext-environment-common.c b/src/lib-sieve/plugins/environment/ext-environment-common.c index 22c766ee1..06db8513c 100644 --- a/src/lib-sieve/plugins/environment/ext-environment-common.c +++ b/src/lib-sieve/plugins/environment/ext-environment-common.c @@ -1,9 +1,14 @@ #include "lib.h" #include "hash.h" +#include "sieve-common.h" +#include "sieve-extensions.h" + #include "ext-environment-common.h" -static struct hash_table *environment_items; +struct ext_environment_context { + struct hash_table *environment_items; +}; /* * Core environment items @@ -20,50 +25,74 @@ static const struct sieve_environment_item *core_env_items[] = { static unsigned int core_env_items_count = N_ELEMENTS(core_env_items); +/* + * Registration + */ + +static void ext_environment_item_register +(struct ext_environment_context *ectx, + const struct sieve_environment_item *item) +{ + hash_table_insert + (ectx->environment_items, (void *) item->name, (void *) item); +} + +void sieve_ext_environment_item_register +(const struct sieve_extension *ext, const struct sieve_environment_item *item) +{ + struct ext_environment_context *ectx = + (struct ext_environment_context *) ext->context; + + ext_environment_item_register(ectx, item); +} + /* * Initialization */ -bool ext_environment_init(void) +bool ext_environment_init +(const struct sieve_extension *ext ATTR_UNUSED, void **context) { + struct ext_environment_context *ectx = + i_new(struct ext_environment_context, 1); + unsigned int i; - environment_items = hash_table_create + ectx->environment_items = hash_table_create (default_pool, default_pool, 0, str_hash, (hash_cmp_callback_t *)strcmp); for ( i = 0; i < core_env_items_count; i++ ) { - sieve_ext_environment_item_register(core_env_items[i]); + ext_environment_item_register(ectx, core_env_items[i]); } + *context = (void *) ectx; + return TRUE; } -void ext_environment_deinit(void) +void ext_environment_deinit(const struct sieve_extension *ext) { - hash_table_destroy(&environment_items); -} - -/* - * Registration - */ + struct ext_environment_context *ectx = + (struct ext_environment_context *) ext->context; -void sieve_ext_environment_item_register -(const struct sieve_environment_item *item) -{ - hash_table_insert - (environment_items, (void *) item->name, (void *) item); + hash_table_destroy(&ectx->environment_items); + i_free(ectx); } + /* * Retrieval */ const char *ext_environment_item_get_value -(const char *name, const struct sieve_script_env *senv) +(const struct sieve_extension *ext, const char *name, + const struct sieve_script_env *senv) { + struct ext_environment_context *ectx = + (struct ext_environment_context *) ext->context; const struct sieve_environment_item *item = (const struct sieve_environment_item *) - hash_table_lookup(environment_items, name); + hash_table_lookup(ectx->environment_items, name); if ( item == NULL ) return NULL; diff --git a/src/lib-sieve/plugins/environment/ext-environment-common.h b/src/lib-sieve/plugins/environment/ext-environment-common.h index 96010f673..04074e09e 100644 --- a/src/lib-sieve/plugins/environment/ext-environment-common.h +++ b/src/lib-sieve/plugins/environment/ext-environment-common.h @@ -4,6 +4,8 @@ #ifndef __EXT_ENVIRONMENT_COMMON_H #define __EXT_ENVIRONMENT_COMMON_H +#include "lib.h" + #include "sieve-common.h" #include "sieve-ext-environment.h" @@ -12,19 +14,19 @@ * Extension */ -extern const struct sieve_extension environment_extension; +extern const struct sieve_extension_def environment_extension; /* * Commands */ -extern const struct sieve_command tst_environment; +extern const struct sieve_command_def tst_environment; /* * Operations */ -extern const struct sieve_operation tst_environment_operation; +extern const struct sieve_operation_def tst_environment_operation; /* * Environment items @@ -41,14 +43,15 @@ extern const struct sieve_environment_item version_env_item; * Initialization */ -bool ext_environment_init(void); -void ext_environment_deinit(void); +bool ext_environment_init(const struct sieve_extension *ext, void **context); +void ext_environment_deinit(const struct sieve_extension *ext); /* * Environment item retrieval */ const char *ext_environment_item_get_value - (const char *name, const struct sieve_script_env *senv); + (const struct sieve_extension *ext, const char *name, + const struct sieve_script_env *senv); #endif /* __EXT_VARIABLES_COMMON_H */ diff --git a/src/lib-sieve/plugins/environment/ext-environment.c b/src/lib-sieve/plugins/environment/ext-environment.c index f53ff057c..d4cbc9005 100644 --- a/src/lib-sieve/plugins/environment/ext-environment.c +++ b/src/lib-sieve/plugins/environment/ext-environment.c @@ -28,13 +28,11 @@ * Extension */ -static bool ext_environment_validator_load(struct sieve_validator *validator); - -static int ext_my_id = -1; +static bool ext_environment_validator_load + (const struct sieve_extension *ext, struct sieve_validator *valdtr); -const struct sieve_extension environment_extension = { +const struct sieve_extension_def environment_extension = { "environment", - &ext_my_id, ext_environment_init, ext_environment_deinit, ext_environment_validator_load, @@ -44,9 +42,9 @@ const struct sieve_extension environment_extension = { }; static bool ext_environment_validator_load - (struct sieve_validator *validator) +(const struct sieve_extension *ext, struct sieve_validator *valdtr) { - sieve_validator_register_command(validator, &tst_environment); + sieve_validator_register_command(valdtr, ext, &tst_environment); return TRUE; } diff --git a/src/lib-sieve/plugins/environment/sieve-ext-environment.h b/src/lib-sieve/plugins/environment/sieve-ext-environment.h index 19060dd45..daf977435 100644 --- a/src/lib-sieve/plugins/environment/sieve-ext-environment.h +++ b/src/lib-sieve/plugins/environment/sieve-ext-environment.h @@ -11,6 +11,7 @@ struct sieve_environment_item { }; void sieve_ext_environment_item_register - (const struct sieve_environment_item *item); + (const struct sieve_extension *ext, + const struct sieve_environment_item *item); #endif diff --git a/src/lib-sieve/plugins/environment/tst-environment.c b/src/lib-sieve/plugins/environment/tst-environment.c index 8e13e1704..bee1d6998 100644 --- a/src/lib-sieve/plugins/environment/tst-environment.c +++ b/src/lib-sieve/plugins/environment/tst-environment.c @@ -23,13 +23,14 @@ */ static bool tst_environment_registered - (struct sieve_validator *validator, struct sieve_command_registration *cmd_reg); + (struct sieve_validator *valdtr, const struct sieve_extension *ext, + struct sieve_command_registration *cmd_reg); static bool tst_environment_validate - (struct sieve_validator *validator, struct sieve_command_context *tst); + (struct sieve_validator *valdtr, struct sieve_command *tst); static bool tst_environment_generate - (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx); + (const struct sieve_codegen_env *cgenv, struct sieve_command *cmd); -const struct sieve_command tst_environment = { +const struct sieve_command_def tst_environment = { "environment", SCT_TEST, 2, 0, FALSE, FALSE, @@ -45,13 +46,11 @@ const struct sieve_command tst_environment = { */ static bool tst_environment_operation_dump - (const struct sieve_operation *op, - const struct sieve_dumptime_env *denv, sieve_size_t *address); + (const struct sieve_dumptime_env *denv, sieve_size_t *address); static int tst_environment_operation_execute - (const struct sieve_operation *op, - const struct sieve_runtime_env *renv, sieve_size_t *address); + (const struct sieve_runtime_env *renv, sieve_size_t *address); -const struct sieve_operation tst_environment_operation = { +const struct sieve_operation_def tst_environment_operation = { "ENVIRONMENT", &environment_extension, 0, @@ -64,11 +63,12 @@ const struct sieve_operation tst_environment_operation = { */ static bool tst_environment_registered - (struct sieve_validator *validator, struct sieve_command_registration *cmd_reg) +(struct sieve_validator *valdtr, const struct sieve_extension *ext ATTR_UNUSED, + struct sieve_command_registration *cmd_reg) { /* The order of these is not significant */ - sieve_comparators_link_tag(validator, cmd_reg, SIEVE_MATCH_OPT_COMPARATOR); - sieve_match_types_link_tags(validator, cmd_reg, SIEVE_MATCH_OPT_MATCH_TYPE); + sieve_comparators_link_tag(valdtr, cmd_reg, SIEVE_MATCH_OPT_COMPARATOR); + sieve_match_types_link_tags(valdtr, cmd_reg, SIEVE_MATCH_OPT_MATCH_TYPE); return TRUE; } @@ -78,31 +78,35 @@ static bool tst_environment_registered */ static bool tst_environment_validate - (struct sieve_validator *validator, struct sieve_command_context *tst) +(struct sieve_validator *valdtr, struct sieve_command *tst) { struct sieve_ast_argument *arg = tst->first_positional; + const struct sieve_match_type mcht_default = + SIEVE_MATCH_TYPE_DEFAULT(is_match_type); + const struct sieve_comparator cmp_default = + SIEVE_COMPARATOR_DEFAULT(i_ascii_casemap_comparator); if ( !sieve_validate_positional_argument - (validator, tst, arg, "name", 1, SAAT_STRING) ) { + (valdtr, tst, arg, "name", 1, SAAT_STRING) ) { return FALSE; } - if ( !sieve_validator_argument_activate(validator, tst, arg, FALSE) ) + if ( !sieve_validator_argument_activate(valdtr, tst, arg, FALSE) ) return FALSE; arg = sieve_ast_argument_next(arg); if ( !sieve_validate_positional_argument - (validator, tst, arg, "key list", 2, SAAT_STRING_LIST) ) { + (valdtr, tst, arg, "key list", 2, SAAT_STRING_LIST) ) { return FALSE; } - if ( !sieve_validator_argument_activate(validator, tst, arg, FALSE) ) + if ( !sieve_validator_argument_activate(valdtr, tst, arg, FALSE) ) return FALSE; /* Validate the key argument to a specified match type */ return sieve_match_type_validate - (validator, tst, arg, &is_match_type, &i_octet_comparator); + (valdtr, tst, arg, &mcht_default, &cmp_default); } /* @@ -110,12 +114,12 @@ static bool tst_environment_validate */ static bool tst_environment_generate - (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx) + (const struct sieve_codegen_env *cgenv, struct sieve_command *cmd) { - sieve_operation_emit_code(cgenv->sbin, &tst_environment_operation); + sieve_operation_emit(cgenv->sbin, cmd->ext, &tst_environment_operation); /* Generate arguments */ - if ( !sieve_generate_arguments(cgenv, ctx, NULL) ) + if ( !sieve_generate_arguments(cgenv, cmd, NULL) ) return FALSE; return TRUE; @@ -126,8 +130,7 @@ static bool tst_environment_generate */ static bool tst_environment_operation_dump -(const struct sieve_operation *op ATTR_UNUSED, - const struct sieve_dumptime_env *denv, sieve_size_t *address) +(const struct sieve_dumptime_env *denv, sieve_size_t *address) { int opt_code = 0; @@ -151,14 +154,16 @@ static bool tst_environment_operation_dump */ static int tst_environment_operation_execute -(const struct sieve_operation *op ATTR_UNUSED, - const struct sieve_runtime_env *renv, sieve_size_t *address) +(const struct sieve_runtime_env *renv, sieve_size_t *address) { + const struct sieve_extension *this_ext = renv->oprtn.ext; int ret, mret; bool result = TRUE; int opt_code = 0; - const struct sieve_comparator *cmp = &i_ascii_casemap_comparator; - const struct sieve_match_type *mtch = &is_match_type; + struct sieve_match_type mcht = + SIEVE_MATCH_TYPE_DEFAULT(is_match_type); + struct sieve_comparator cmp = + SIEVE_COMPARATOR_DEFAULT(i_ascii_casemap_comparator); struct sieve_match_context *mctx; string_t *name; struct sieve_coded_stringlist *key_list; @@ -171,7 +176,7 @@ static int tst_environment_operation_execute /* Handle match-type and comparator operands */ if ( (ret=sieve_match_read_optional_operands - (renv, address, &opt_code, &cmp, &mtch)) <= 0 ) + (renv, address, &opt_code, &cmp, &mcht)) <= 0 ) return ret; /* Check whether we neatly finished the list of optional operands*/ @@ -198,10 +203,11 @@ static int tst_environment_operation_execute sieve_runtime_trace(renv, "ENVIRONMENT test"); - env_item = ext_environment_item_get_value(str_c(name), renv->scriptenv); + env_item = ext_environment_item_get_value + (this_ext, str_c(name), renv->scriptenv); if ( env_item != NULL ) { - mctx = sieve_match_begin(renv->interp, mtch, cmp, NULL, key_list); + mctx = sieve_match_begin(renv->interp, &mcht, &cmp, NULL, key_list); if ( (mret=sieve_match_value(mctx, strlen(env_item) == 0 ? NULL : env_item, strlen(env_item))) < 0 ) { diff --git a/src/lib-sieve/plugins/imap4flags/cmd-flag.c b/src/lib-sieve/plugins/imap4flags/cmd-flag.c index 6654b24c2..248b5e062 100644 --- a/src/lib-sieve/plugins/imap4flags/cmd-flag.c +++ b/src/lib-sieve/plugins/imap4flags/cmd-flag.c @@ -19,7 +19,7 @@ /* Forward declarations */ static bool cmd_flag_generate - (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx); + (const struct sieve_codegen_env *cgenv, struct sieve_command *ctx); /* Setflag command * @@ -27,7 +27,7 @@ static bool cmd_flag_generate * setflag [<variablename: string>] <list-of-flags: string-list> */ -const struct sieve_command cmd_setflag = { +const struct sieve_command_def cmd_setflag = { "setflag", SCT_COMMAND, -1, /* We check positional arguments ourselves */ @@ -44,7 +44,7 @@ const struct sieve_command cmd_setflag = { * addflag [<variablename: string>] <list-of-flags: string-list> */ -const struct sieve_command cmd_addflag = { +const struct sieve_command_def cmd_addflag = { "addflag", SCT_COMMAND, -1, /* We check positional arguments ourselves */ @@ -62,7 +62,7 @@ const struct sieve_command cmd_addflag = { * removeflag [<variablename: string>] <list-of-flags: string-list> */ -const struct sieve_command cmd_removeflag = { +const struct sieve_command_def cmd_removeflag = { "removeflag", SCT_COMMAND, -1, /* We check positional arguments ourselves */ @@ -80,15 +80,13 @@ const struct sieve_command cmd_removeflag = { /* Forward declarations */ bool cmd_flag_operation_dump - (const struct sieve_operation *op, - const struct sieve_dumptime_env *denv, sieve_size_t *address); + (const struct sieve_dumptime_env *denv, sieve_size_t *address); static int cmd_flag_operation_execute - (const struct sieve_operation *op, - const struct sieve_runtime_env *renv, sieve_size_t *address); + (const struct sieve_runtime_env *renv, sieve_size_t *address); /* Setflag operation */ -const struct sieve_operation setflag_operation = { +const struct sieve_operation_def setflag_operation = { "SETFLAG", &imap4flags_extension, ext_imap4flags_OPERATION_SETFLAG, @@ -98,7 +96,7 @@ const struct sieve_operation setflag_operation = { /* Addflag operation */ -const struct sieve_operation addflag_operation = { +const struct sieve_operation_def addflag_operation = { "ADDFLAG", &imap4flags_extension, ext_imap4flags_OPERATION_ADDFLAG, @@ -108,7 +106,7 @@ const struct sieve_operation addflag_operation = { /* Removeflag operation */ -const struct sieve_operation removeflag_operation = { +const struct sieve_operation_def removeflag_operation = { "REMOVEFLAG", &imap4flags_extension, ext_imap4flags_OPERATION_REMOVEFLAG, @@ -121,20 +119,18 @@ const struct sieve_operation removeflag_operation = { */ static bool cmd_flag_generate -(const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx) +(const struct sieve_codegen_env *cgenv, struct sieve_command *cmd) { - const struct sieve_command *command = ctx->command; - /* Emit operation */ - if ( command == &cmd_setflag ) - sieve_operation_emit_code(cgenv->sbin, &setflag_operation); - else if ( command == &cmd_addflag ) - sieve_operation_emit_code(cgenv->sbin, &addflag_operation); - else if ( command == &cmd_removeflag ) - sieve_operation_emit_code(cgenv->sbin, &removeflag_operation); + if ( sieve_command_is(cmd, cmd_setflag) ) + sieve_operation_emit(cgenv->sbin, cmd->ext, &setflag_operation); + else if ( sieve_command_is(cmd, cmd_addflag) ) + sieve_operation_emit(cgenv->sbin, cmd->ext, &addflag_operation); + else if ( sieve_command_is(cmd, cmd_removeflag) ) + sieve_operation_emit(cgenv->sbin, cmd->ext, &removeflag_operation); /* Generate arguments */ - if ( !sieve_generate_arguments(cgenv, ctx, NULL) ) + if ( !sieve_generate_arguments(cgenv, cmd, NULL) ) return FALSE; return TRUE; @@ -145,31 +141,29 @@ static bool cmd_flag_generate */ bool cmd_flag_operation_dump -(const struct sieve_operation *op, - const struct sieve_dumptime_env *denv, sieve_size_t *address) +(const struct sieve_dumptime_env *denv, sieve_size_t *address) { - const struct sieve_operand *operand; + struct sieve_operand operand; - sieve_code_dumpf(denv, "%s", op->mnemonic); + sieve_code_dumpf(denv, "%s", sieve_operation_mnemonic(&denv->oprtn)); sieve_code_descend(denv); sieve_code_mark(denv); - operand = sieve_operand_read(denv->sbin, address); - if ( operand == NULL ) { + if ( !sieve_operand_read(denv->sbin, address, &operand) ) { sieve_code_dumpf(denv, "ERROR: INVALID OPERAND"); return FALSE; } - if ( sieve_operand_is_variable(operand) ) { + if ( sieve_operand_is_variable(&operand) ) { return - sieve_opr_string_dump_data(denv, operand, address, + sieve_opr_string_dump_data(denv, &operand, address, "variable name") && sieve_opr_stringlist_dump(denv, address, "list of flags"); } return - sieve_opr_stringlist_dump_data(denv, operand, address, + sieve_opr_stringlist_dump_data(denv, &operand, address, "list of flags"); } @@ -178,11 +172,10 @@ bool cmd_flag_operation_dump */ static int cmd_flag_operation_execute -(const struct sieve_operation *op, - const struct sieve_runtime_env *renv, sieve_size_t *address) +(const struct sieve_runtime_env *renv, sieve_size_t *address) { - const struct sieve_operand *operand; - sieve_size_t op_address = *address; + const struct sieve_operation *op = &renv->oprtn; + struct sieve_operand operand; bool result = TRUE; string_t *flag_item; struct sieve_coded_stringlist *flag_list; @@ -195,17 +188,16 @@ static int cmd_flag_operation_execute * Read operands */ - operand = sieve_operand_read(renv->sbin, address); - if ( operand == NULL ) { + if ( !sieve_operand_read(renv->sbin, address, &operand) ) { sieve_runtime_trace_error(renv, "invalid operand"); return SIEVE_EXEC_BIN_CORRUPT; } - if ( sieve_operand_is_variable(operand) ) { + if ( sieve_operand_is_variable(&operand) ) { /* Read the variable operand */ if ( !sieve_variable_operand_read_data - (renv, operand, address, &storage, &var_index) ) { + (renv, &operand, address, &storage, &var_index) ) { sieve_runtime_trace_error(renv, "invalid variable operand"); return SIEVE_EXEC_BIN_CORRUPT; } @@ -216,20 +208,20 @@ static int cmd_flag_operation_execute return SIEVE_EXEC_BIN_CORRUPT; } - } else if ( sieve_operand_is_stringlist(operand) ) { + } else if ( sieve_operand_is_stringlist(&operand) ) { storage = NULL; var_index = 0; /* Read flag list */ if ( (flag_list=sieve_opr_stringlist_read_data - (renv, operand, op_address, address)) == NULL ) { + (renv, &operand, address)) == NULL ) { sieve_runtime_trace_error(renv, "invalid flag-list operand"); return SIEVE_EXEC_BIN_CORRUPT; } } else { sieve_runtime_trace_error(renv, "unexpected operand '%s'", - operand->name); + sieve_operand_name(&operand)); return SIEVE_EXEC_BIN_CORRUPT; } @@ -237,15 +229,15 @@ static int cmd_flag_operation_execute * Perform operation */ - sieve_runtime_trace(renv, "%s command", op->mnemonic); + sieve_runtime_trace(renv, "%s command", sieve_operation_mnemonic(op)); /* Determine what to do */ - if ( op == &setflag_operation ) + if ( sieve_operation_is(op, setflag_operation) ) flag_op = ext_imap4flags_set_flags; - else if ( op == &addflag_operation ) + else if ( sieve_operation_is(op, addflag_operation) ) flag_op = ext_imap4flags_add_flags; - else if ( op == &removeflag_operation ) + else if ( sieve_operation_is(op, removeflag_operation) ) flag_op = ext_imap4flags_remove_flags; else i_unreached(); diff --git a/src/lib-sieve/plugins/imap4flags/ext-imap4flags-common.c b/src/lib-sieve/plugins/imap4flags/ext-imap4flags-common.c index 9c068073d..41077a084 100644 --- a/src/lib-sieve/plugins/imap4flags/ext-imap4flags-common.c +++ b/src/lib-sieve/plugins/imap4flags/ext-imap4flags-common.c @@ -29,35 +29,36 @@ static bool flag_is_valid(const char *flag); * Tagged arguments */ -extern const struct sieve_argument tag_flags; -extern const struct sieve_argument tag_flags_implicit; +extern const struct sieve_argument_def tag_flags; +extern const struct sieve_argument_def tag_flags_implicit; /* * Common command functions */ bool ext_imap4flags_command_validate -(struct sieve_validator *validator, struct sieve_command_context *cmd) +(struct sieve_validator *valdtr, struct sieve_command *cmd) { struct sieve_ast_argument *arg = cmd->first_positional; struct sieve_ast_argument *arg2; + const struct sieve_extension *var_ext; /* Check arguments */ if ( arg == NULL ) { - sieve_command_validate_error(validator, cmd, + sieve_command_validate_error(valdtr, cmd, "the %s %s expects at least one argument, but none was found", - cmd->command->identifier, sieve_command_type_name(cmd->command)); + sieve_command_identifier(cmd), sieve_command_type_name(cmd)); return FALSE; } if ( sieve_ast_argument_type(arg) != SAAT_STRING && sieve_ast_argument_type(arg) != SAAT_STRING_LIST ) { - sieve_argument_validate_error(validator, arg, + sieve_argument_validate_error(valdtr, arg, "the %s %s expects either a string (variable name) or " "a string-list (list of flags) as first argument, but %s was found", - cmd->command->identifier, sieve_command_type_name(cmd->command), + sieve_command_identifier(cmd), sieve_command_type_name(cmd), sieve_ast_argument_name(arg)); return FALSE; } @@ -68,19 +69,19 @@ bool ext_imap4flags_command_validate if ( sieve_ast_argument_type(arg) != SAAT_STRING ) { - if ( cmd->command == &tst_hasflag ) { + if ( sieve_command_is(cmd, tst_hasflag) ) { if ( sieve_ast_argument_type(arg) != SAAT_STRING_LIST ) { - sieve_argument_validate_error(validator, arg, + sieve_argument_validate_error(valdtr, arg, "if a second argument is specified for the hasflag, the first " "must be a string-list (variable-list), but %s was found", sieve_ast_argument_name(arg)); return FALSE; } } else { - sieve_argument_validate_error(validator, arg, + sieve_argument_validate_error(valdtr, arg, "if a second argument is specified for the %s %s, the first " "must be a string (variable name), but %s was found", - cmd->command->identifier, sieve_command_type_name(cmd->command), + sieve_command_identifier(cmd), sieve_command_type_name(cmd), sieve_ast_argument_name(arg)); return FALSE; } @@ -88,36 +89,40 @@ bool ext_imap4flags_command_validate /* Then, check whether the second argument is permitted */ - if ( !sieve_ext_variables_is_active(validator) ) { - sieve_argument_validate_error(validator,arg, + var_ext = sieve_ext_variables_get_extension(cmd->ext->svinst); + + if ( var_ext == NULL || !sieve_ext_variables_is_active(var_ext, valdtr) ) + { + sieve_argument_validate_error(valdtr,arg, "the %s %s only allows for the specification of a " "variable name when the variables extension is active", - cmd->command->identifier, sieve_command_type_name(cmd->command)); + sieve_command_identifier(cmd), sieve_command_type_name(cmd)); return FALSE; } - if ( !sieve_variable_argument_activate(validator, cmd, arg, - cmd->command != &tst_hasflag ) ) + if ( !sieve_variable_argument_activate + (var_ext, valdtr, cmd, arg, !sieve_command_is(cmd, tst_hasflag) ) ) return FALSE; if ( sieve_ast_argument_type(arg2) != SAAT_STRING && sieve_ast_argument_type(arg2) != SAAT_STRING_LIST ) { - sieve_argument_validate_error(validator, arg2, + sieve_argument_validate_error(valdtr, arg2, "the %s %s expects a string list (list of flags) as " "second argument when two arguments are specified, " "but %s was found", - cmd->command->identifier, sieve_command_type_name(cmd->command), + sieve_command_identifier(cmd), sieve_command_type_name(cmd), sieve_ast_argument_name(arg2)); return FALSE; } } else arg2 = arg; - if ( !sieve_validator_argument_activate(validator, cmd, arg2, FALSE) ) + if ( !sieve_validator_argument_activate(valdtr, cmd, arg2, FALSE) ) return FALSE; - if ( cmd->command != &tst_hasflag && sieve_argument_is_string_literal(arg2) ) { + if ( !sieve_command_is(cmd, tst_hasflag) && + sieve_argument_is_string_literal(arg2) ) { struct ext_imap4flags_iter fiter; const char *flag; @@ -126,10 +131,10 @@ bool ext_imap4flags_command_validate while ( (flag=ext_imap4flags_iter_get_flag(&fiter)) != NULL ) { if ( !flag_is_valid(flag) ) { - sieve_argument_validate_warning(validator, arg, + sieve_argument_validate_warning(valdtr, arg, "IMAP flag '%s' specified for the %s command is invalid " "and will be ignored (only first invalid is reported)", - str_sanitize(flag, 64), cmd->command->identifier); + str_sanitize(flag, 64), sieve_command_identifier(cmd)); break; } } @@ -143,7 +148,8 @@ bool ext_imap4flags_command_validate */ void ext_imap4flags_attach_flags_tag -(struct sieve_validator *valdtr, const char *command) +(struct sieve_validator *valdtr, const struct sieve_extension *ext, + const char *command) { /* Register :flags tag with the command and we don't care whether it is * registered or even whether it will be registered at all. The validator @@ -152,11 +158,11 @@ void ext_imap4flags_attach_flags_tag /* Tag specified by user */ sieve_validator_register_external_tag - (valdtr, &tag_flags, command, SIEVE_OPT_SIDE_EFFECT); + (valdtr, command, ext, &tag_flags, SIEVE_OPT_SIDE_EFFECT); /* Implicit tag if none is specified */ sieve_validator_register_persistent_tag - (valdtr, &tag_flags_implicit, command); + (valdtr, command, ext, &tag_flags_implicit); } /* @@ -200,11 +206,11 @@ static void _get_initial_flags } static inline struct ext_imap4flags_result_context *_get_result_context -(struct sieve_result *result) +(const struct sieve_extension *this_ext, struct sieve_result *result) { struct ext_imap4flags_result_context *rctx = (struct ext_imap4flags_result_context *) - sieve_result_extension_get_context(result, &imap4flags_extension); + sieve_result_extension_get_context(result, this_ext); if ( rctx == NULL ) { pool_t pool = sieve_result_pool(result); @@ -214,17 +220,17 @@ static inline struct ext_imap4flags_result_context *_get_result_context _get_initial_flags(result, rctx->internal_flags); sieve_result_extension_set_context - (result, &imap4flags_extension, rctx); + (result, this_ext, rctx); } return rctx; } static string_t *_get_flags_string -(struct sieve_result *result) +(const struct sieve_extension *this_ext, struct sieve_result *result) { struct ext_imap4flags_result_context *ctx = - _get_result_context(result); + _get_result_context(this_ext, result); return ctx->internal_flags; } @@ -234,10 +240,11 @@ static string_t *_get_flags_string */ static void ext_imap4flags_runtime_init -(const struct sieve_runtime_env *renv, void *context ATTR_UNUSED) +(const struct sieve_extension *ext, const struct sieve_runtime_env *renv, + void *context ATTR_UNUSED) { sieve_result_add_implicit_side_effect - (renv->result, NULL, TRUE, &flags_side_effect, NULL); + (renv->result, NULL, TRUE, ext, &flags_side_effect, NULL); } const struct sieve_interpreter_extension imap4flags_interpreter_extension = { @@ -426,7 +433,7 @@ int ext_imap4flags_set_flags if ( !sieve_variable_get_modifiable(storage, var_index, &cur_flags) ) return SIEVE_EXEC_BIN_CORRUPT; } else - cur_flags = _get_flags_string(renv->result); + cur_flags = _get_flags_string(renv->oprtn.ext, renv->result); if ( cur_flags != NULL ) flags_list_set_flags(cur_flags, flags); @@ -435,7 +442,7 @@ int ext_imap4flags_set_flags } int ext_imap4flags_add_flags -(const struct sieve_runtime_env *renv, struct sieve_variable_storage *storage, +(const struct sieve_runtime_env *renv, struct sieve_variable_storage *storage, unsigned int var_index, string_t *flags) { string_t *cur_flags; @@ -444,7 +451,7 @@ int ext_imap4flags_add_flags if ( !sieve_variable_get_modifiable(storage, var_index, &cur_flags) ) return SIEVE_EXEC_BIN_CORRUPT; } else - cur_flags = _get_flags_string(renv->result); + cur_flags = _get_flags_string(renv->oprtn.ext, renv->result); if ( cur_flags != NULL ) flags_list_add_flags(cur_flags, flags); @@ -453,7 +460,7 @@ int ext_imap4flags_add_flags } int ext_imap4flags_remove_flags -(const struct sieve_runtime_env *renv, struct sieve_variable_storage *storage, +(const struct sieve_runtime_env *renv, struct sieve_variable_storage *storage, unsigned int var_index, string_t *flags) { string_t *cur_flags; @@ -462,7 +469,7 @@ int ext_imap4flags_remove_flags if ( !sieve_variable_get_modifiable(storage, var_index, &cur_flags) ) return SIEVE_EXEC_BIN_CORRUPT; } else - cur_flags = _get_flags_string(renv->result); + cur_flags = _get_flags_string(renv->oprtn.ext, renv->result); if ( cur_flags != NULL ) flags_list_remove_flags(cur_flags, flags); @@ -471,7 +478,7 @@ int ext_imap4flags_remove_flags } int ext_imap4flags_get_flags_string -(const struct sieve_runtime_env *renv, struct sieve_variable_storage *storage, +(const struct sieve_runtime_env *renv, struct sieve_variable_storage *storage, unsigned int var_index, const char **flags) { string_t *cur_flags; @@ -480,7 +487,7 @@ int ext_imap4flags_get_flags_string if ( !sieve_variable_get_modifiable(storage, var_index, &cur_flags) ) return SIEVE_EXEC_BIN_CORRUPT; } else - cur_flags = _get_flags_string(renv->result); + cur_flags = _get_flags_string(renv->oprtn.ext, renv->result); if ( cur_flags == NULL ) *flags = ""; @@ -491,7 +498,7 @@ int ext_imap4flags_get_flags_string } void ext_imap4flags_get_flags_init -(struct ext_imap4flags_iter *iter, const struct sieve_runtime_env *renv, +(struct ext_imap4flags_iter *iter, const struct sieve_runtime_env *renv, string_t *flags_list) { string_t *cur_flags; @@ -502,15 +509,16 @@ void ext_imap4flags_get_flags_init flags_list_set_flags(cur_flags, flags_list); } else - cur_flags = _get_flags_string(renv->result); + cur_flags = _get_flags_string(renv->oprtn.ext, renv->result); ext_imap4flags_iter_init(iter, cur_flags); } void ext_imap4flags_get_implicit_flags_init -(struct ext_imap4flags_iter *iter, struct sieve_result *result) +(struct ext_imap4flags_iter *iter, const struct sieve_extension *this_ext, + struct sieve_result *result) { - string_t *cur_flags = _get_flags_string(result); + string_t *cur_flags = _get_flags_string(this_ext, result); ext_imap4flags_iter_init(iter, cur_flags); } diff --git a/src/lib-sieve/plugins/imap4flags/ext-imap4flags-common.h b/src/lib-sieve/plugins/imap4flags/ext-imap4flags-common.h index 534501692..fd946ce2d 100644 --- a/src/lib-sieve/plugins/imap4flags/ext-imap4flags-common.h +++ b/src/lib-sieve/plugins/imap4flags/ext-imap4flags-common.h @@ -13,7 +13,7 @@ * Extension */ -extern const struct sieve_extension imap4flags_extension; +extern const struct sieve_extension_def imap4flags_extension; extern const struct sieve_interpreter_extension imap4flags_interpreter_extension; @@ -21,13 +21,13 @@ extern const struct sieve_interpreter_extension * Side effect */ -extern const struct sieve_side_effect flags_side_effect; +extern const struct sieve_side_effect_def flags_side_effect; /* * Operands */ -extern const struct sieve_operand flags_side_effect_operand; +extern const struct sieve_operand_def flags_side_effect_operand; /* * Operations @@ -40,34 +40,35 @@ enum ext_imap4flags_opcode { ext_imap4flags_OPERATION_HASFLAG }; -extern const struct sieve_operation setflag_operation; -extern const struct sieve_operation addflag_operation; -extern const struct sieve_operation removeflag_operation; -extern const struct sieve_operation hasflag_operation; +extern const struct sieve_operation_def setflag_operation; +extern const struct sieve_operation_def addflag_operation; +extern const struct sieve_operation_def removeflag_operation; +extern const struct sieve_operation_def hasflag_operation; /* * Commands */ -extern const struct sieve_command cmd_setflag; -extern const struct sieve_command cmd_addflag; -extern const struct sieve_command cmd_removeflag; +extern const struct sieve_command_def cmd_setflag; +extern const struct sieve_command_def cmd_addflag; +extern const struct sieve_command_def cmd_removeflag; -extern const struct sieve_command tst_hasflag; +extern const struct sieve_command_def tst_hasflag; /* * Common command functions */ bool ext_imap4flags_command_validate - (struct sieve_validator *validator, struct sieve_command_context *cmd); + (struct sieve_validator *valdtr, struct sieve_command *cmd); /* * Flags tagged argument */ void ext_imap4flags_attach_flags_tag - (struct sieve_validator *valdtr, const char *command); + (struct sieve_validator *valdtr, const struct sieve_extension *ext, + const char *command); /* * Flag management @@ -111,7 +112,8 @@ void ext_imap4flags_get_flags_init (struct ext_imap4flags_iter *iter, const struct sieve_runtime_env *renv, string_t *flags_list); void ext_imap4flags_get_implicit_flags_init - (struct ext_imap4flags_iter *iter, struct sieve_result *result); + (struct ext_imap4flags_iter *iter, const struct sieve_extension *this_ext, + struct sieve_result *result); #endif /* __EXT_IMAP4FLAGS_COMMON_H */ diff --git a/src/lib-sieve/plugins/imap4flags/ext-imap4flags.c b/src/lib-sieve/plugins/imap4flags/ext-imap4flags.c index 3e60ebef7..8a5c90c2a 100644 --- a/src/lib-sieve/plugins/imap4flags/ext-imap4flags.c +++ b/src/lib-sieve/plugins/imap4flags/ext-imap4flags.c @@ -31,7 +31,7 @@ * Operations */ -const struct sieve_operation *imap4flags_operations[] = { +const struct sieve_operation_def *imap4flags_operations[] = { &setflag_operation, &addflag_operation, &removeflag_operation, @@ -42,15 +42,14 @@ const struct sieve_operation *imap4flags_operations[] = { * Extension */ -static bool ext_imap4flags_validator_load(struct sieve_validator *valdtr); +static bool ext_imap4flags_validator_load + (const struct sieve_extension *ext, struct sieve_validator *valdtr); static bool ext_imap4flags_interpreter_load - (const struct sieve_runtime_env *renv, sieve_size_t *address); - -int ext_imap4flags_my_id = -1; + (const struct sieve_extension *ext, const struct sieve_runtime_env *renv, + sieve_size_t *address); -const struct sieve_extension imap4flags_extension = { +const struct sieve_extension_def imap4flags_extension = { "imap4flags", - &ext_imap4flags_my_id, NULL, NULL, ext_imap4flags_validator_load, NULL, @@ -61,25 +60,26 @@ const struct sieve_extension imap4flags_extension = { }; static bool ext_imap4flags_validator_load -(struct sieve_validator *valdtr) +(const struct sieve_extension *ext, struct sieve_validator *valdtr) { /* Register commands */ - sieve_validator_register_command(valdtr, &cmd_setflag); - sieve_validator_register_command(valdtr, &cmd_addflag); - sieve_validator_register_command(valdtr, &cmd_removeflag); - sieve_validator_register_command(valdtr, &tst_hasflag); + sieve_validator_register_command(valdtr, ext, &cmd_setflag); + sieve_validator_register_command(valdtr, ext, &cmd_addflag); + sieve_validator_register_command(valdtr, ext, &cmd_removeflag); + sieve_validator_register_command(valdtr, ext, &tst_hasflag); - ext_imap4flags_attach_flags_tag(valdtr, "keep"); - ext_imap4flags_attach_flags_tag(valdtr, "fileinto"); + ext_imap4flags_attach_flags_tag(valdtr, ext, "keep"); + ext_imap4flags_attach_flags_tag(valdtr, ext, "fileinto"); return TRUE; } static bool ext_imap4flags_interpreter_load -(const struct sieve_runtime_env *renv, sieve_size_t *address ATTR_UNUSED) +(const struct sieve_extension *ext, const struct sieve_runtime_env *renv, + sieve_size_t *address ATTR_UNUSED) { sieve_interpreter_extension_register - (renv->interp, &imap4flags_interpreter_extension, NULL); + (renv->interp, ext, &imap4flags_interpreter_extension, NULL); return TRUE; } diff --git a/src/lib-sieve/plugins/imap4flags/ext-imapflags.c b/src/lib-sieve/plugins/imap4flags/ext-imapflags.c index 68860da0f..dd6dd3386 100644 --- a/src/lib-sieve/plugins/imap4flags/ext-imapflags.c +++ b/src/lib-sieve/plugins/imap4flags/ext-imapflags.c @@ -33,7 +33,7 @@ */ static bool cmd_mark_validate - (struct sieve_validator *valdtr, struct sieve_command_context *cmd); + (struct sieve_validator *valdtr, struct sieve_command *cmd); /* Mark command * @@ -41,7 +41,7 @@ static bool cmd_mark_validate * mark */ -static const struct sieve_command cmd_mark = { +static const struct sieve_command_def cmd_mark = { "mark", SCT_COMMAND, 0, 0, FALSE, FALSE, @@ -55,7 +55,7 @@ static const struct sieve_command cmd_mark = { * Syntax: * unmark */ -static const struct sieve_command cmd_unmark = { +static const struct sieve_command_def cmd_unmark = { "unmark", SCT_COMMAND, 0, 0, FALSE, FALSE, @@ -68,16 +68,16 @@ static const struct sieve_command cmd_unmark = { * Extension */ -static bool ext_imapflags_load(void); -static bool ext_imapflags_validator_load(struct sieve_validator *valdtr); +static bool ext_imapflags_load + (const struct sieve_extension *ext, void **context); +static bool ext_imapflags_validator_load + (const struct sieve_extension *ext, struct sieve_validator *valdtr); static bool ext_imapflags_interpreter_load - (const struct sieve_runtime_env *renv, sieve_size_t *address); - -int ext_imapflags_my_id = -1; + (const struct sieve_extension *ext, const struct sieve_runtime_env *renv, + sieve_size_t *address); -const struct sieve_extension imapflags_extension = { +const struct sieve_extension_def imapflags_extension = { "imapflags", - &ext_imapflags_my_id, ext_imapflags_load, NULL, ext_imapflags_validator_load, @@ -88,10 +88,12 @@ const struct sieve_extension imapflags_extension = { SIEVE_EXT_DEFINE_NO_OPERANDS }; -static bool ext_imapflags_load(void) +static bool ext_imapflags_load +(const struct sieve_extension *ext, void **context) { /* Make sure real extension is registered, it is needed by the binary */ - (void)sieve_extension_require(&imap4flags_extension); + *context = (void *) + sieve_extension_require(ext->svinst, &imap4flags_extension); return TRUE; } @@ -101,7 +103,8 @@ static bool ext_imapflags_load(void) */ static bool ext_imapflags_validator_extension_validate - (struct sieve_validator *valdtr, void *context, struct sieve_ast_argument *require_arg); + (const struct sieve_extension *ext, struct sieve_validator *valdtr, + void *context, struct sieve_ast_argument *require_arg); const struct sieve_validator_extension imapflags_validator_extension = { &imapflags_extension, @@ -110,27 +113,33 @@ const struct sieve_validator_extension imapflags_validator_extension = { }; static bool ext_imapflags_validator_load -(struct sieve_validator *valdtr) +(const struct sieve_extension *ext, struct sieve_validator *valdtr) { + const struct sieve_extension *master_ext = + (const struct sieve_extension *) ext->context; + sieve_validator_extension_register - (valdtr, &imapflags_validator_extension, NULL); + (valdtr, ext, &imapflags_validator_extension, NULL); /* Register commands */ - sieve_validator_register_command(valdtr, &cmd_setflag); - sieve_validator_register_command(valdtr, &cmd_addflag); - sieve_validator_register_command(valdtr, &cmd_removeflag); + sieve_validator_register_command(valdtr, master_ext, &cmd_setflag); + sieve_validator_register_command(valdtr, master_ext, &cmd_addflag); + sieve_validator_register_command(valdtr, master_ext, &cmd_removeflag); - sieve_validator_register_command(valdtr, &cmd_mark); - sieve_validator_register_command(valdtr, &cmd_unmark); + sieve_validator_register_command(valdtr, master_ext, &cmd_mark); + sieve_validator_register_command(valdtr, master_ext, &cmd_unmark); return TRUE; } static bool ext_imapflags_validator_extension_validate -(struct sieve_validator *valdtr, void *context ATTR_UNUSED, - struct sieve_ast_argument *require_arg) +(const struct sieve_extension *ext, struct sieve_validator *valdtr, + void *context ATTR_UNUSED, struct sieve_ast_argument *require_arg) { - if ( sieve_validator_extension_loaded(valdtr, &imap4flags_extension) ) { + const struct sieve_extension *master_ext = + (const struct sieve_extension *) ext->context; + + if ( sieve_validator_extension_loaded(valdtr, master_ext) ) { sieve_argument_validate_error(valdtr, require_arg, "the (deprecated) imapflags extension cannot be used " "together with the imap4flags extension"); @@ -145,12 +154,16 @@ static bool ext_imapflags_validator_extension_validate */ static bool ext_imapflags_interpreter_load -(const struct sieve_runtime_env *renv, sieve_size_t *address ATTR_UNUSED) +(const struct sieve_extension *ext, const struct sieve_runtime_env *renv, + sieve_size_t *address ATTR_UNUSED) { - sieve_interpreter_extension_register - (renv->interp, &imap4flags_interpreter_extension, NULL); + const struct sieve_extension *master_ext = + (const struct sieve_extension *) ext->context; + + sieve_interpreter_extension_register + (renv->interp, master_ext, &imap4flags_interpreter_extension, NULL); - return TRUE; + return TRUE; } /* @@ -158,18 +171,19 @@ static bool ext_imapflags_interpreter_load */ static bool cmd_mark_validate -(struct sieve_validator *valdtr, struct sieve_command_context *cmd) +(struct sieve_validator *valdtr, struct sieve_command *cmd) { - if ( cmd->command == &cmd_mark ) - cmd->command = &cmd_addflag; + if ( sieve_command_is(cmd, cmd_mark) ) + cmd->def = &cmd_addflag; else - cmd->command = &cmd_removeflag; + cmd->def = &cmd_removeflag; cmd->first_positional = sieve_ast_argument_cstring_create (cmd->ast_node, "\\flagged", cmd->ast_node->source_line); - if ( !sieve_validator_argument_activate(valdtr, cmd, cmd->first_positional, FALSE) ) - return FALSE; + if ( !sieve_validator_argument_activate + (valdtr, cmd, cmd->first_positional, FALSE) ) + return FALSE; return TRUE; } diff --git a/src/lib-sieve/plugins/imap4flags/tag-flags.c b/src/lib-sieve/plugins/imap4flags/tag-flags.c index 6a85ab94b..c942f0ae5 100644 --- a/src/lib-sieve/plugins/imap4flags/tag-flags.c +++ b/src/lib-sieve/plugins/imap4flags/tag-flags.c @@ -25,27 +25,27 @@ */ static bool tag_flags_validate - (struct sieve_validator *validator, struct sieve_ast_argument **arg, - struct sieve_command_context *cmd); + (struct sieve_validator *valdtr, struct sieve_ast_argument **arg, + struct sieve_command *cmd); static bool tag_flags_validate_persistent - (struct sieve_validator *validator, struct sieve_command_context *cmd); + (struct sieve_validator *valdtr, struct sieve_command *cmd, + const struct sieve_extension *ext); static bool tag_flags_generate (const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, - struct sieve_command_context *cmd); + struct sieve_command *cmd); -const struct sieve_argument tag_flags = { +const struct sieve_argument_def tag_flags = { "flags", - NULL, NULL, - tag_flags_validate, NULL, + tag_flags_validate, + NULL, NULL, tag_flags_generate }; -const struct sieve_argument tag_flags_implicit = { +const struct sieve_argument_def tag_flags_implicit = { "flags-implicit", - NULL, + NULL, NULL, NULL, tag_flags_validate_persistent, - NULL, NULL, tag_flags_generate }; @@ -59,21 +59,21 @@ static bool seff_flags_dump_context static bool seff_flags_read_context (const struct sieve_side_effect *seffect, const struct sieve_runtime_env *renv, sieve_size_t *address, - void **se_context); + void **context); static int seff_flags_merge (const struct sieve_runtime_env *renv, const struct sieve_action *action, - const struct sieve_side_effect *seffect, - void **old_context, void *new_context); + const struct sieve_side_effect *old_seffect, + const struct sieve_side_effect *new_seffect, void **old_context); + static void seff_flags_print (const struct sieve_side_effect *seffect, const struct sieve_action *action, - const struct sieve_result_print_env *rpenv, void *se_context, bool *keep); + const struct sieve_result_print_env *rpenv, bool *keep); static bool seff_flags_pre_execute (const struct sieve_side_effect *seffect, const struct sieve_action *action, - const struct sieve_action_exec_env *aenv, - void **se_context, void *tr_context); + const struct sieve_action_exec_env *aenv, void **context, void *tr_context); -const struct sieve_side_effect flags_side_effect = { +const struct sieve_side_effect_def flags_side_effect = { SIEVE_OBJECT("flags", &flags_side_effect_operand, 0), &act_store, @@ -92,7 +92,7 @@ const struct sieve_side_effect flags_side_effect = { static const struct sieve_extension_objects ext_side_effects = SIEVE_EXT_DEFINE_SIDE_EFFECT(flags_side_effect); -const struct sieve_operand flags_side_effect_operand = { +const struct sieve_operand_def flags_side_effect_operand = { "flags operand", &imap4flags_extension, 0, @@ -105,18 +105,19 @@ const struct sieve_operand flags_side_effect_operand = { */ static bool tag_flags_validate_persistent -(struct sieve_validator *validator ATTR_UNUSED, struct sieve_command_context *cmd) +(struct sieve_validator *valdtr ATTR_UNUSED, struct sieve_command *cmd, + const struct sieve_extension *ext) { if ( sieve_command_find_argument(cmd, &tag_flags) == NULL ) { - sieve_command_add_dynamic_tag(cmd, &tag_flags_implicit, -1); + sieve_command_add_dynamic_tag(cmd, ext, &tag_flags_implicit, -1); } return TRUE; } static bool tag_flags_validate -(struct sieve_validator *validator, struct sieve_ast_argument **arg, - struct sieve_command_context *cmd) +(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, + struct sieve_command *cmd) { struct sieve_ast_argument *tag = *arg; @@ -127,7 +128,7 @@ static bool tag_flags_validate * :flags <list-of-flags: string-list> */ if ( !sieve_validate_tag_parameter - (validator, cmd, tag, *arg, SAAT_STRING_LIST) ) { + (valdtr, cmd, tag, *arg, SAAT_STRING_LIST) ) { return FALSE; } @@ -145,7 +146,7 @@ static bool tag_flags_validate static bool tag_flags_generate (const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, - struct sieve_command_context *cmd) + struct sieve_command *cmd) { struct sieve_ast_argument *param; @@ -153,18 +154,20 @@ static bool tag_flags_generate return FALSE; } - sieve_opr_side_effect_emit(cgenv->sbin, &flags_side_effect); + sieve_opr_side_effect_emit + (cgenv->sbin, arg->argument->ext, &flags_side_effect); - if ( arg->argument == &tag_flags ) { + if ( sieve_argument_is(arg, tag_flags) ) { /* Explicit :flags tag */ param = arg->parameters; /* Call the generation function for the argument */ - if ( param->argument != NULL && param->argument->generate != NULL && - !param->argument->generate(cgenv, param, cmd) ) + if ( param->argument != NULL && param->argument->def != NULL && + param->argument->def->generate != NULL && + !param->argument->def->generate(cgenv, param, cmd) ) return FALSE; - } else if ( arg->argument == &tag_flags_implicit ) { + } else if ( sieve_argument_is(arg, tag_flags_implicit) ) { /* Implicit flags */ sieve_opr_omitted_emit(cgenv->sbin); @@ -193,26 +196,23 @@ static bool seff_flags_dump_context (const struct sieve_side_effect *seffect ATTR_UNUSED, const struct sieve_dumptime_env *denv, sieve_size_t *address) { - const struct sieve_operand *operand; + struct sieve_operand operand; - operand = sieve_operand_read(denv->sbin, address); - if ( operand == NULL ) { + if ( !sieve_operand_read(denv->sbin, address, &operand) ) { sieve_code_dumpf(denv, "ERROR: INVALID OPERAND"); return FALSE; } - - if ( sieve_operand_is_omitted(operand) ) { + if ( sieve_operand_is_omitted(&operand) ) { sieve_code_dumpf(denv, "flags: INTERNAL"); return TRUE; - } + } - return sieve_opr_stringlist_dump_data(denv, operand, address, - "flags"); + return sieve_opr_stringlist_dump_data(denv, &operand, address, "flags"); } static struct seff_flags_context *seff_flags_get_implicit_context -(struct sieve_result *result) +(const struct sieve_extension *this_ext, struct sieve_result *result) { pool_t pool = sieve_result_pool(result); struct seff_flags_context *ctx; @@ -225,7 +225,7 @@ static struct seff_flags_context *seff_flags_get_implicit_context T_BEGIN { /* Unpack */ - ext_imap4flags_get_implicit_flags_init(&flit, result); + ext_imap4flags_get_implicit_flags_init(&flit, this_ext, result); while ( (flag=ext_imap4flags_iter_get_flag(&flit)) != NULL ) { if (flag != NULL && *flag != '\\') { /* keyword */ @@ -252,13 +252,12 @@ static struct seff_flags_context *seff_flags_get_implicit_context } static bool seff_flags_read_context -(const struct sieve_side_effect *seffect ATTR_UNUSED, +(const struct sieve_side_effect *seffect, const struct sieve_runtime_env *renv, sieve_size_t *address, void **se_context) { bool result = TRUE; - sieve_size_t op_address = *address; - const struct sieve_operand *operand; + const struct sieve_operand operand; pool_t pool = sieve_result_pool(renv->result); struct seff_flags_context *ctx; string_t *flags_item; @@ -270,26 +269,25 @@ static bool seff_flags_read_context t_push(); /* Check whether explicit flag list operand is present */ - operand = sieve_operand_read(renv->sbin, address); - - if ( operand == NULL ) { + if ( !sieve_operand_read(renv->sbin, address, &operand) ) { sieve_runtime_trace_error(renv, "invalid operand"); t_pop(); return FALSE; } - if ( sieve_operand_is_omitted(operand) ) { + if ( sieve_operand_is_omitted(&operand) ) { /* Flag list is omitted, use current value of internal * variable to construct side effect context. */ - *se_context = seff_flags_get_implicit_context(renv->result); + *se_context = seff_flags_get_implicit_context + (SIEVE_OBJECT_EXTENSION(seffect), renv->result); t_pop(); return TRUE; } /* Read flag-list */ if ( (flag_list=sieve_opr_stringlist_read_data - (renv, operand, op_address, address)) == NULL ) { + (renv, &operand, address)) == NULL ) { t_pop(); return FALSE; } @@ -339,10 +337,11 @@ static bool seff_flags_read_context static int seff_flags_merge (const struct sieve_runtime_env *renv ATTR_UNUSED, const struct sieve_action *action ATTR_UNUSED, - const struct sieve_side_effect *seffect ATTR_UNUSED, - void **old_context, void *new_context) + const struct sieve_side_effect *old_seffect ATTR_UNUSED, + const struct sieve_side_effect *new_seffect, + void **old_context) { - *old_context = new_context; + *old_context = new_seffect->context; return 1; } @@ -350,17 +349,18 @@ static int seff_flags_merge /* Result printing */ static void seff_flags_print -(const struct sieve_side_effect *seffect ATTR_UNUSED, +(const struct sieve_side_effect *seffect, const struct sieve_action *action ATTR_UNUSED, - const struct sieve_result_print_env *rpenv, - void *se_context, bool *keep ATTR_UNUSED) + const struct sieve_result_print_env *rpenv,bool *keep ATTR_UNUSED) { struct sieve_result *result = rpenv->result; - struct seff_flags_context *ctx = (struct seff_flags_context *) se_context; + struct seff_flags_context *ctx = + (struct seff_flags_context *) seffect->context; unsigned int i; if ( ctx == NULL ) - ctx = seff_flags_get_implicit_context(result); + ctx = seff_flags_get_implicit_context + (SIEVE_OBJECT_EXTENSION(seffect), result); if ( ctx->flags != 0 || array_count(&ctx->keywords) > 0 ) { T_BEGIN { @@ -394,17 +394,17 @@ static void seff_flags_print /* Result execution */ static bool seff_flags_pre_execute -(const struct sieve_side_effect *seffect ATTR_UNUSED, - const struct sieve_action *action ATTR_UNUSED, - const struct sieve_action_exec_env *aenv, - void **se_context, void *tr_context) +(const struct sieve_side_effect *seffect, + const struct sieve_action *action ATTR_UNUSED, + const struct sieve_action_exec_env *aenv, void **context, void *tr_context) { - struct seff_flags_context *ctx = (struct seff_flags_context *) *se_context; + struct seff_flags_context *ctx = (struct seff_flags_context *) *context; const char *const *keywords; if ( ctx == NULL ) { - ctx = seff_flags_get_implicit_context(aenv->result); - *se_context = (void *) ctx; + ctx = seff_flags_get_implicit_context + (SIEVE_OBJECT_EXTENSION(seffect), aenv->result); + *context = (void *) ctx; } (void)array_append_space(&ctx->keywords); diff --git a/src/lib-sieve/plugins/imap4flags/tst-hasflag.c b/src/lib-sieve/plugins/imap4flags/tst-hasflag.c index 23d7ca75d..ea2ac889d 100644 --- a/src/lib-sieve/plugins/imap4flags/tst-hasflag.c +++ b/src/lib-sieve/plugins/imap4flags/tst-hasflag.c @@ -24,14 +24,14 @@ */ static bool tst_hasflag_registered - (struct sieve_validator *validator, + (struct sieve_validator *valdtr, const struct sieve_extension *ext, struct sieve_command_registration *cmd_reg); static bool tst_hasflag_validate - (struct sieve_validator *validator, struct sieve_command_context *ctx); + (struct sieve_validator *valdtr, struct sieve_command *tst); static bool tst_hasflag_generate - (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx); + (const struct sieve_codegen_env *cgenv, struct sieve_command *cmd); -const struct sieve_command tst_hasflag = { +const struct sieve_command_def tst_hasflag = { "hasflag", SCT_TEST, -1, /* We check positional arguments ourselves */ @@ -48,13 +48,11 @@ const struct sieve_command tst_hasflag = { */ static bool tst_hasflag_operation_dump - (const struct sieve_operation *op, - const struct sieve_dumptime_env *denv, sieve_size_t *address); + (const struct sieve_dumptime_env *denv, sieve_size_t *address); static int tst_hasflag_operation_execute - (const struct sieve_operation *op, - const struct sieve_runtime_env *renv, sieve_size_t *address); + (const struct sieve_runtime_env *renv, sieve_size_t *address); -const struct sieve_operation hasflag_operation = { +const struct sieve_operation_def hasflag_operation = { "HASFLAG", &imap4flags_extension, ext_imap4flags_OPERATION_HASFLAG, @@ -75,12 +73,12 @@ enum tst_hasflag_optional { */ static bool tst_hasflag_registered -(struct sieve_validator *validator, +(struct sieve_validator *valdtr, const struct sieve_extension *ext ATTR_UNUSED, struct sieve_command_registration *cmd_reg) { /* The order of these is not significant */ - sieve_comparators_link_tag(validator, cmd_reg, SIEVE_MATCH_OPT_COMPARATOR); - sieve_match_types_link_tags(validator, cmd_reg, SIEVE_MATCH_OPT_MATCH_TYPE); + sieve_comparators_link_tag(valdtr, cmd_reg, SIEVE_MATCH_OPT_COMPARATOR); + sieve_match_types_link_tags(valdtr, cmd_reg, SIEVE_MATCH_OPT_MATCH_TYPE); return TRUE; } @@ -90,24 +88,28 @@ static bool tst_hasflag_registered */ static bool tst_hasflag_validate -(struct sieve_validator *validator, struct sieve_command_context *tst) +(struct sieve_validator *valdtr, struct sieve_command *tst) { struct sieve_ast_argument *vars = tst->first_positional; struct sieve_ast_argument *keys = sieve_ast_argument_next(vars); + const struct sieve_match_type mcht_default = + SIEVE_MATCH_TYPE_DEFAULT(is_match_type); + const struct sieve_comparator cmp_default = + SIEVE_COMPARATOR_DEFAULT(i_ascii_casemap_comparator); - if ( !ext_imap4flags_command_validate(validator, tst) ) + if ( !ext_imap4flags_command_validate(valdtr, tst) ) return FALSE; if ( keys == NULL ) { keys = vars; vars = NULL; } else { - vars->arg_id_code = OPT_VARIABLES; + vars->argument->id_code = OPT_VARIABLES; } /* Validate the key argument to a specified match type */ return sieve_match_type_validate - (validator, tst, keys, &is_match_type, &i_ascii_casemap_comparator); + (valdtr, tst, keys, &mcht_default, &cmp_default); } /* @@ -115,12 +117,12 @@ static bool tst_hasflag_validate */ static bool tst_hasflag_generate -(const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx) +(const struct sieve_codegen_env *cgenv, struct sieve_command *cmd) { - sieve_operation_emit_code(cgenv->sbin, &hasflag_operation); + sieve_operation_emit(cgenv->sbin, cmd->ext, &hasflag_operation); /* Generate arguments */ - if ( !sieve_generate_arguments(cgenv, ctx, NULL) ) + if ( !sieve_generate_arguments(cgenv, cmd, NULL) ) return FALSE; return TRUE; @@ -131,8 +133,7 @@ static bool tst_hasflag_generate */ static bool tst_hasflag_operation_dump -(const struct sieve_operation *op ATTR_UNUSED, - const struct sieve_dumptime_env *denv, sieve_size_t *address) +(const struct sieve_dumptime_env *denv, sieve_size_t *address) { int opt_code = 0; @@ -194,14 +195,15 @@ static const struct sieve_match_key_extractor _flag_extractor = { }; static int tst_hasflag_operation_execute -(const struct sieve_operation *op ATTR_UNUSED, - const struct sieve_runtime_env *renv, sieve_size_t *address) +(const struct sieve_runtime_env *renv, sieve_size_t *address) { int ret, mret; bool result = TRUE; int opt_code = 0; - const struct sieve_comparator *cmp = &i_ascii_casemap_comparator; - const struct sieve_match_type *mtch = &is_match_type; + struct sieve_comparator cmp = + SIEVE_COMPARATOR_DEFAULT(i_ascii_casemap_comparator); + struct sieve_match_type mtch = + SIEVE_MATCH_TYPE_DEFAULT(is_match_type); struct sieve_match_context *mctx; struct sieve_coded_stringlist *flag_list, *variables_list = NULL; struct ext_imap4flags_iter iter; @@ -248,7 +250,7 @@ static int tst_hasflag_operation_execute matched = FALSE; mctx = sieve_match_begin - (renv->interp, mtch, cmp, &_flag_extractor, flag_list); + (renv->interp, &mtch, &cmp, &_flag_extractor, flag_list); matched = FALSE; diff --git a/src/lib-sieve/plugins/include/cmd-global.c b/src/lib-sieve/plugins/include/cmd-global.c index b42f294d7..b8952547e 100644 --- a/src/lib-sieve/plugins/include/cmd-global.c +++ b/src/lib-sieve/plugins/include/cmd-global.c @@ -23,11 +23,11 @@ */ static bool cmd_global_validate - (struct sieve_validator *validator, struct sieve_command_context *cmd); + (struct sieve_validator *valdtr, struct sieve_command *cmd); static bool cmd_global_generate -(const struct sieve_codegen_env *cgenv, struct sieve_command_context *cmd); +(const struct sieve_codegen_env *cgenv, struct sieve_command *cmd); -const struct sieve_command cmd_global = { +const struct sieve_command_def cmd_global = { "global", SCT_COMMAND, 1, 0, FALSE, FALSE, @@ -45,7 +45,7 @@ const struct sieve_command cmd_global = { * Syntax * import */ -const struct sieve_command cmd_import = { +const struct sieve_command_def cmd_import = { "import", SCT_COMMAND, 1, 0, FALSE, FALSE, @@ -60,7 +60,7 @@ const struct sieve_command cmd_import = { * Syntax * export */ -const struct sieve_command cmd_export = { +const struct sieve_command_def cmd_export = { "export", SCT_COMMAND, 1, 0, FALSE, FALSE, @@ -75,15 +75,13 @@ const struct sieve_command cmd_export = { */ static bool opc_global_dump - (const struct sieve_operation *op, - const struct sieve_dumptime_env *denv, sieve_size_t *address); + (const struct sieve_dumptime_env *denv, sieve_size_t *address); static int opc_global_execute - (const struct sieve_operation *op, - const struct sieve_runtime_env *renv, sieve_size_t *address); + (const struct sieve_runtime_env *renv, sieve_size_t *address); /* Global operation */ -const struct sieve_operation global_operation = { +const struct sieve_operation_def global_operation = { "global", &include_extension, EXT_INCLUDE_OPERATION_GLOBAL, @@ -95,41 +93,55 @@ const struct sieve_operation global_operation = { * Validation */ +static inline struct sieve_argument *_create_variable_argument +(struct sieve_command *cmd, struct sieve_variable *var) +{ + struct sieve_argument *argument = sieve_argument_create + (cmd->ast_node->ast, NULL, cmd->ext, 0); + + argument->data = (void *) var; + + return argument; +} + static bool cmd_global_validate - (struct sieve_validator *validator, struct sieve_command_context *cmd) +(struct sieve_validator *valdtr, struct sieve_command *cmd) { + const struct sieve_extension *this_ext = cmd->ext; struct sieve_ast_argument *arg = cmd->first_positional; - struct sieve_command_context *prev_context = - sieve_command_prev_context(cmd); + struct sieve_command *prev = sieve_command_prev(cmd); /* Check valid command placement */ if ( !sieve_command_is_toplevel(cmd) || - ( !sieve_command_is_first(cmd) && prev_context != NULL && - prev_context->command != &cmd_require ) ) { + ( !sieve_command_is_first(cmd) && prev != NULL && + !sieve_command_is(prev, cmd_require) ) ) { - if ( cmd->command == &cmd_global ) { - if ( prev_context->command != &cmd_global ) { - sieve_command_validate_error(validator, cmd, + if ( sieve_command_is(cmd, cmd_global) ) { + if ( !sieve_command_is(prev, cmd_global) ) { + sieve_command_validate_error(valdtr, cmd, "a global command can only be placed at top level " - "at the beginning of the file after any require or other global commands"); + "at the beginning of the file after any require or " + "other global commands"); return FALSE; } } else { - if ( prev_context->command != &cmd_import && prev_context->command != &cmd_export ) { - sieve_command_validate_error(validator, cmd, - "the DEPRICATED %s command can only be placed at top level " - "at the beginning of the file after any require or import/export commands", - cmd->command->identifier); - return FALSE; - } + if ( !sieve_command_is(prev, cmd_import) && + !sieve_command_is(prev, cmd_export) ) { + sieve_command_validate_error(valdtr, cmd, + "the DEPRICATED %s command can only be placed at top level " + "at the beginning of the file after any require or " + "import/export commands", + sieve_command_identifier(cmd)); + return FALSE; + } } } /* Check for use of variables extension */ - if ( !sieve_ext_variables_is_active(validator) ) { - sieve_command_validate_error(validator, cmd, + if ( !ext_include_validator_have_variables(this_ext, valdtr) ) { + sieve_command_validate_error(valdtr, cmd, "%s command requires that variables extension is active", - cmd->command->identifier); + sieve_command_identifier(cmd)); return FALSE; } @@ -140,10 +152,10 @@ static bool cmd_global_validate struct sieve_variable *var; if ( (var=ext_include_variable_import_global - (validator, cmd, identifier)) == NULL ) + (valdtr, cmd, identifier)) == NULL ) return FALSE; - arg->context = (void *) var; + arg->argument = _create_variable_argument(cmd, var); } else if ( sieve_ast_argument_type(arg) == SAAT_STRING_LIST ) { /* String list */ @@ -154,31 +166,31 @@ static bool cmd_global_validate struct sieve_variable *var; if ( (var=ext_include_variable_import_global - (validator, cmd, identifier)) == NULL ) + (valdtr, cmd, identifier)) == NULL ) return FALSE; - stritem->context = (void *) var; + stritem->argument = _create_variable_argument(cmd, var); stritem = sieve_ast_strlist_next(stritem); } } else { /* Something else */ - sieve_argument_validate_error(validator, arg, + sieve_argument_validate_error(valdtr, arg, "the %s command accepts a single string or string list argument, " - "but %s was found", cmd->command->identifier, + "but %s was found", sieve_command_identifier(cmd), sieve_ast_argument_name(arg)); return FALSE; } /* Join global commands with predecessors if possible */ - if ( prev_context->command == cmd->command ) { + if ( sieve_commands_equal(prev, cmd) ) { /* Join this command's string list with the previous one */ - prev_context->first_positional = sieve_ast_stringlist_join - (prev_context->first_positional, cmd->first_positional); + prev->first_positional = sieve_ast_stringlist_join + (prev->first_positional, cmd->first_positional); - if ( prev_context->first_positional == NULL ) { + if ( prev->first_positional == NULL ) { /* Not going to happen unless MAXINT stringlist items are specified */ - sieve_command_validate_error(validator, cmd, + sieve_command_validate_error(valdtr, cmd, "compiler reached AST limit (script too complex)"); return FALSE; } @@ -195,15 +207,15 @@ static bool cmd_global_validate */ static bool cmd_global_generate -(const struct sieve_codegen_env *cgenv, struct sieve_command_context *cmd) +(const struct sieve_codegen_env *cgenv, struct sieve_command *cmd) { struct sieve_ast_argument *arg = cmd->first_positional; - sieve_operation_emit_code(cgenv->sbin, &global_operation); + sieve_operation_emit(cgenv->sbin, cmd->ext, &global_operation); if ( sieve_ast_argument_type(arg) == SAAT_STRING ) { /* Single string */ - struct sieve_variable *var = (struct sieve_variable *) arg->context; + struct sieve_variable *var = (struct sieve_variable *) arg->argument->data; (void)sieve_binary_emit_unsigned(cgenv->sbin, 1); (void)sieve_binary_emit_unsigned(cgenv->sbin, var->index); @@ -215,7 +227,8 @@ static bool cmd_global_generate (void)sieve_binary_emit_unsigned(cgenv->sbin, sieve_ast_strlist_count(arg)); while ( stritem != NULL ) { - struct sieve_variable *var = (struct sieve_variable *) stritem->context; + struct sieve_variable *var = + (struct sieve_variable *) stritem->argument->data; (void)sieve_binary_emit_unsigned(cgenv->sbin, var->index); @@ -233,9 +246,9 @@ static bool cmd_global_generate */ static bool opc_global_dump -(const struct sieve_operation *op ATTR_UNUSED, - const struct sieve_dumptime_env *denv, sieve_size_t *address) +(const struct sieve_dumptime_env *denv, sieve_size_t *address) { + const struct sieve_extension *this_ext = denv->oprtn.ext; unsigned int count, i, var_count; struct sieve_variable_scope *scope; struct sieve_variable * const *vars; @@ -245,7 +258,7 @@ static bool opc_global_dump sieve_code_dumpf(denv, "GLOBAL (count: %u):", count); - scope = ext_include_binary_get_global_scope(denv->sbin); + scope = ext_include_binary_get_global_scope(this_ext, denv->sbin); vars = sieve_variable_scope_get_variables(scope, &var_count); sieve_code_descend(denv); @@ -269,9 +282,9 @@ static bool opc_global_dump */ static int opc_global_execute -(const struct sieve_operation *op ATTR_UNUSED, - const struct sieve_runtime_env *renv, sieve_size_t *address) +(const struct sieve_runtime_env *renv, sieve_size_t *address) { + const struct sieve_extension *this_ext = renv->oprtn.ext; struct sieve_variable_scope *scope; struct sieve_variable_storage *storage; struct sieve_variable * const *vars; @@ -282,9 +295,10 @@ static int opc_global_execute return SIEVE_EXEC_BIN_CORRUPT; } - scope = ext_include_binary_get_global_scope(renv->sbin); + scope = ext_include_binary_get_global_scope(this_ext, renv->sbin); vars = sieve_variable_scope_get_variables(scope, &var_count); - storage = ext_include_interpreter_get_global_variables(renv->interp); + storage = ext_include_interpreter_get_global_variables + (renv->oprtn.ext, renv->interp); for ( i = 0; i < count; i++ ) { unsigned int index; diff --git a/src/lib-sieve/plugins/include/cmd-include.c b/src/lib-sieve/plugins/include/cmd-include.c index fb2e66b32..8e6816529 100644 --- a/src/lib-sieve/plugins/include/cmd-include.c +++ b/src/lib-sieve/plugins/include/cmd-include.c @@ -30,17 +30,16 @@ */ static bool cmd_include_registered - (struct sieve_validator *validator, + (struct sieve_validator *valdtr, const struct sieve_extension *ext, struct sieve_command_registration *cmd_reg); static bool cmd_include_pre_validate - (struct sieve_validator *validator ATTR_UNUSED, - struct sieve_command_context *cmd); + (struct sieve_validator *valdtr ATTR_UNUSED, struct sieve_command *cmd); static bool cmd_include_validate - (struct sieve_validator *validator, struct sieve_command_context *cmd); + (struct sieve_validator *valdtr, struct sieve_command *cmd); static bool cmd_include_generate - (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx); + (const struct sieve_codegen_env *cgenv, struct sieve_command *ctx); -const struct sieve_command cmd_include = { +const struct sieve_command_def cmd_include = { "include", SCT_COMMAND, 1, 0, FALSE, FALSE, @@ -56,13 +55,11 @@ const struct sieve_command cmd_include = { */ static bool opc_include_dump - (const struct sieve_operation *op, - const struct sieve_dumptime_env *denv, sieve_size_t *address); + (const struct sieve_dumptime_env *denv, sieve_size_t *address); static int opc_include_execute - (const struct sieve_operation *op, - const struct sieve_runtime_env *renv, sieve_size_t *address); + (const struct sieve_runtime_env *renv, sieve_size_t *address); -const struct sieve_operation include_operation = { +const struct sieve_operation_def include_operation = { "include", &include_extension, EXT_INCLUDE_OPERATION_INCLUDE, @@ -88,32 +85,32 @@ struct cmd_include_context_data { */ static bool cmd_include_validate_location_tag - (struct sieve_validator *validator, struct sieve_ast_argument **arg, - struct sieve_command_context *cmd); + (struct sieve_validator *valdtr, struct sieve_ast_argument **arg, + struct sieve_command *cmd); -static const struct sieve_argument include_personal_tag = { +static const struct sieve_argument_def include_personal_tag = { "personal", - NULL, NULL, + NULL, cmd_include_validate_location_tag, - NULL, NULL + NULL, NULL, NULL }; -static const struct sieve_argument include_global_tag = { +static const struct sieve_argument_def include_global_tag = { "global", - NULL, NULL, + NULL, cmd_include_validate_location_tag, - NULL, NULL + NULL, NULL, NULL }; static bool cmd_include_validate_once_tag - (struct sieve_validator *validator, struct sieve_ast_argument **arg, - struct sieve_command_context *cmd); + (struct sieve_validator *valdtr, struct sieve_ast_argument **arg, + struct sieve_command *cmd); -static const struct sieve_argument include_once_tag = { +static const struct sieve_argument_def include_once_tag = { "once", - NULL, NULL, + NULL, cmd_include_validate_once_tag, - NULL, NULL + NULL, NULL, NULL }; /* @@ -121,22 +118,22 @@ static const struct sieve_argument include_once_tag = { */ static bool cmd_include_validate_location_tag -(struct sieve_validator *validator, struct sieve_ast_argument **arg, - struct sieve_command_context *cmd) +(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, + struct sieve_command *cmd) { struct cmd_include_context_data *ctx_data = (struct cmd_include_context_data *) cmd->data; if ( ctx_data->location_assigned) { - sieve_argument_validate_error(validator, *arg, + sieve_argument_validate_error(valdtr, *arg, "include: cannot use location tags ':personal' and ':global' " "multiple times"); return FALSE; } - if ( (*arg)->argument == &include_personal_tag ) + if ( sieve_argument_is(*arg, include_personal_tag) ) ctx_data->location = EXT_INCLUDE_LOCATION_PERSONAL; - else if ( (*arg)->argument == &include_global_tag ) + else if ( sieve_argument_is(*arg, include_global_tag) ) ctx_data->location = EXT_INCLUDE_LOCATION_GLOBAL; else return FALSE; @@ -150,8 +147,8 @@ static bool cmd_include_validate_location_tag } static bool cmd_include_validate_once_tag -(struct sieve_validator *validator ATTR_UNUSED, struct sieve_ast_argument **arg, - struct sieve_command_context *cmd) +(struct sieve_validator *valdtr ATTR_UNUSED, struct sieve_ast_argument **arg, + struct sieve_command *cmd) { struct cmd_include_context_data *ctx_data = (struct cmd_include_context_data *) cmd->data; @@ -169,14 +166,12 @@ static bool cmd_include_validate_once_tag */ static bool cmd_include_registered - (struct sieve_validator *validator, struct sieve_command_registration *cmd_reg) +(struct sieve_validator *valdtr, const struct sieve_extension *ext, + struct sieve_command_registration *cmd_reg) { - sieve_validator_register_tag - (validator, cmd_reg, &include_personal_tag, 0); - sieve_validator_register_tag - (validator, cmd_reg, &include_global_tag, 0); - sieve_validator_register_tag - (validator, cmd_reg, &include_once_tag, 0); + sieve_validator_register_tag(valdtr, cmd_reg, ext, &include_personal_tag, 0); + sieve_validator_register_tag(valdtr, cmd_reg, ext, &include_global_tag, 0); + sieve_validator_register_tag(valdtr, cmd_reg, ext, &include_once_tag, 0); return TRUE; } @@ -186,8 +181,7 @@ static bool cmd_include_registered */ static bool cmd_include_pre_validate - (struct sieve_validator *validator ATTR_UNUSED, - struct sieve_command_context *cmd) +(struct sieve_validator *valdtr ATTR_UNUSED, struct sieve_command *cmd) { struct cmd_include_context_data *ctx_data; @@ -199,9 +193,10 @@ static bool cmd_include_pre_validate return TRUE; } -static bool cmd_include_validate(struct sieve_validator *validator, - struct sieve_command_context *cmd) -{ +static bool cmd_include_validate +(struct sieve_validator *valdtr, struct sieve_command *cmd) +{ + const struct sieve_extension *this_ext = cmd->ext; struct sieve_ast_argument *arg = cmd->first_positional; struct cmd_include_context_data *ctx_data = (struct cmd_include_context_data *) cmd->data; @@ -211,18 +206,18 @@ static bool cmd_include_validate(struct sieve_validator *validator, /* Check argument */ if ( !sieve_validate_positional_argument - (validator, cmd, arg, "value", 1, SAAT_STRING) ) { + (valdtr, cmd, arg, "value", 1, SAAT_STRING) ) { return FALSE; } - if ( !sieve_validator_argument_activate(validator, cmd, arg, FALSE) ) + if ( !sieve_validator_argument_activate(valdtr, cmd, arg, FALSE) ) return FALSE; /* * Variables are not allowed. */ if ( !sieve_argument_is_string_literal(arg) ) { - sieve_argument_validate_error(validator, arg, + sieve_argument_validate_error(valdtr, arg, "the include command requires a constant string for its value argument"); return FALSE; } @@ -232,7 +227,7 @@ static bool cmd_include_validate(struct sieve_validator *validator, script_name = sieve_ast_argument_strc(arg); if ( strchr(script_name, '/') != NULL ) { - sieve_argument_validate_error(validator, arg, + sieve_argument_validate_error(valdtr, arg, "include: '/' not allowed in script name (%s)", str_sanitize(script_name, 80)); return FALSE; @@ -241,7 +236,7 @@ static bool cmd_include_validate(struct sieve_validator *validator, script_path = ext_include_get_script_directory (ctx_data->location, script_name); if ( script_path == NULL ) { - sieve_argument_validate_error(validator, arg, + sieve_argument_validate_error(valdtr, arg, "include: %s location for included script '%s' is unavailable " "(contact system administrator for more information)", ext_include_script_location_name(ctx_data->location), @@ -250,11 +245,13 @@ static bool cmd_include_validate(struct sieve_validator *validator, } /* Create script object */ - script = sieve_script_create_in_directory(script_path, script_name, - sieve_validator_error_handler(validator), &exists); + script = sieve_script_create_in_directory + (this_ext->svinst, script_path, script_name, + sieve_validator_error_handler(valdtr), &exists); + if ( script == NULL ) { if ( !exists ) { - sieve_argument_validate_error(validator, arg, + sieve_argument_validate_error(valdtr, arg, "included %s script '%s' does not exist", ext_include_script_location_name(ctx_data->location), str_sanitize(script_name, 80)); @@ -262,7 +259,7 @@ static bool cmd_include_validate(struct sieve_validator *validator, return FALSE; } - ext_include_ast_link_included_script(cmd->ast_node->ast, script); + ext_include_ast_link_included_script(cmd->ext, cmd->ast_node->ast, script); ctx_data->script = script; arg = sieve_ast_arguments_detach(arg, 1); @@ -275,7 +272,7 @@ static bool cmd_include_validate(struct sieve_validator *validator, */ static bool cmd_include_generate -(const struct sieve_codegen_env *cgenv, struct sieve_command_context *cmd) +(const struct sieve_codegen_env *cgenv, struct sieve_command *cmd) { struct cmd_include_context_data *ctx_data = (struct cmd_include_context_data *) cmd->data; @@ -290,7 +287,7 @@ static bool cmd_include_generate ctx_data->include_once) ) return FALSE; - (void)sieve_operation_emit_code(cgenv->sbin, &include_operation); + (void)sieve_operation_emit(cgenv->sbin, cmd->ext, &include_operation); (void)sieve_binary_emit_unsigned(cgenv->sbin, included->id); (void)sieve_binary_emit_byte(cgenv->sbin, flags); @@ -302,8 +299,7 @@ static bool cmd_include_generate */ static bool opc_include_dump -(const struct sieve_operation *op ATTR_UNUSED, - const struct sieve_dumptime_env *denv, sieve_size_t *address) +(const struct sieve_dumptime_env *denv, sieve_size_t *address) { const struct ext_include_script_info *included; struct ext_include_binary_context *binctx; @@ -318,7 +314,7 @@ static bool opc_include_dump if ( !sieve_binary_read_byte(denv->sbin, address, &flags) ) return FALSE; - binctx = ext_include_binary_get_context(denv->sbin); + binctx = ext_include_binary_get_context(denv->oprtn.ext, denv->sbin); included = ext_include_binary_script_get_included(binctx, include_id); if ( included == NULL ) return FALSE; @@ -336,8 +332,7 @@ static bool opc_include_dump */ static int opc_include_execute -(const struct sieve_operation *op ATTR_UNUSED, - const struct sieve_runtime_env *renv, sieve_size_t *address) +(const struct sieve_runtime_env *renv, sieve_size_t *address) { unsigned int include_id, flags; diff --git a/src/lib-sieve/plugins/include/cmd-return.c b/src/lib-sieve/plugins/include/cmd-return.c index b666f4c9c..c63285138 100644 --- a/src/lib-sieve/plugins/include/cmd-return.c +++ b/src/lib-sieve/plugins/include/cmd-return.c @@ -19,10 +19,9 @@ */ static bool cmd_return_generate - (const struct sieve_codegen_env *cgenv, - struct sieve_command_context *ctx ATTR_UNUSED); + (const struct sieve_codegen_env *cgenv, struct sieve_command *cmd); -const struct sieve_command cmd_return = { +const struct sieve_command_def cmd_return = { "return", SCT_COMMAND, 0, 0, FALSE, FALSE, @@ -36,10 +35,9 @@ const struct sieve_command cmd_return = { */ static int opc_return_execute - (const struct sieve_operation *op, - const struct sieve_runtime_env *renv, sieve_size_t *address); + (const struct sieve_runtime_env *renv, sieve_size_t *address); -const struct sieve_operation return_operation = { +const struct sieve_operation_def return_operation = { "return", &include_extension, EXT_INCLUDE_OPERATION_RETURN, @@ -52,10 +50,9 @@ const struct sieve_operation return_operation = { */ static bool cmd_return_generate -(const struct sieve_codegen_env *cgenv, - struct sieve_command_context *ctx ATTR_UNUSED) +(const struct sieve_codegen_env *cgenv, struct sieve_command *cmd) { - sieve_operation_emit_code(cgenv->sbin, &return_operation); + sieve_operation_emit(cgenv->sbin, cmd->ext, &return_operation); return TRUE; } @@ -65,9 +62,7 @@ static bool cmd_return_generate */ static int opc_return_execute -(const struct sieve_operation *op ATTR_UNUSED, - const struct sieve_runtime_env *renv, - sieve_size_t *address ATTR_UNUSED) +(const struct sieve_runtime_env *renv, sieve_size_t *address ATTR_UNUSED) { sieve_runtime_trace(renv, "RETURN command"); diff --git a/src/lib-sieve/plugins/include/ext-include-binary.c b/src/lib-sieve/plugins/include/ext-include-binary.c index 245c4460b..3c02dc48d 100644 --- a/src/lib-sieve/plugins/include/ext-include-binary.c +++ b/src/lib-sieve/plugins/include/ext-include-binary.c @@ -23,10 +23,14 @@ * Forward declarations */ -static bool ext_include_binary_save(struct sieve_binary *sbin); -static bool ext_include_binary_open(struct sieve_binary *sbin); -static bool ext_include_binary_up_to_date(struct sieve_binary *sbin); -static void ext_include_binary_free(struct sieve_binary *sbin); +static bool ext_include_binary_save + (const struct sieve_extension *ext, struct sieve_binary *sbin, void *context); +static bool ext_include_binary_open + (const struct sieve_extension *ext, struct sieve_binary *sbin, void *context); +static bool ext_include_binary_up_to_date + (const struct sieve_extension *ext, struct sieve_binary *sbin, void *context); +static void ext_include_binary_free + (const struct sieve_extension *ext, struct sieve_binary *sbin, void *context); /* * Binary include extension @@ -56,7 +60,7 @@ struct ext_include_binary_context { static struct ext_include_binary_context *ext_include_binary_create_context -(struct sieve_binary *sbin) +(const struct sieve_extension *this_ext, struct sieve_binary *sbin) { pool_t pool = sieve_binary_pool(sbin); @@ -69,37 +73,38 @@ static struct ext_include_binary_context *ext_include_binary_create_context (hash_cmp_callback_t *) sieve_script_cmp); p_array_init(&ctx->include_index, pool, 128); - sieve_binary_extension_set(sbin, &include_binary_ext, ctx); + sieve_binary_extension_set(sbin, this_ext, &include_binary_ext, ctx); return ctx; } struct ext_include_binary_context *ext_include_binary_get_context -(struct sieve_binary *sbin) +(const struct sieve_extension *this_ext, struct sieve_binary *sbin) { struct ext_include_binary_context *ctx = (struct ext_include_binary_context *) - sieve_binary_extension_get_context(sbin, &include_extension); + sieve_binary_extension_get_context(sbin, this_ext); if ( ctx == NULL ) - ctx = ext_include_binary_create_context(sbin); + ctx = ext_include_binary_create_context(this_ext, sbin); return ctx; } struct ext_include_binary_context *ext_include_binary_init -(struct sieve_binary *sbin, struct sieve_ast *ast) +(const struct sieve_extension *this_ext, struct sieve_binary *sbin, + struct sieve_ast *ast) { struct ext_include_ast_context *ast_ctx = - ext_include_get_ast_context(ast); + ext_include_get_ast_context(this_ext, ast); struct ext_include_binary_context *ctx; /* Get/create our context from the binary we are working on */ - ctx = ext_include_binary_get_context(sbin); + ctx = ext_include_binary_get_context(this_ext, sbin); /* Create dependency block */ if ( ctx->dependency_block == 0 ) ctx->dependency_block = - sieve_binary_extension_create_block(sbin, &include_extension); + sieve_binary_extension_create_block(sbin, this_ext); if ( ctx->global_vars == NULL ) { ctx->global_vars = ast_ctx->global_vars; @@ -129,7 +134,8 @@ const struct ext_include_script_info *ext_include_binary_script_include /* Unreferenced on binary_free */ sieve_script_ref(script); - hash_table_insert(binctx->included_scripts, (void *) script, (void *) incscript); + hash_table_insert + (binctx->included_scripts, (void *) script, (void *) incscript); array_append(&binctx->include_index, &incscript, 1); return incscript; @@ -152,7 +158,8 @@ bool ext_include_binary_script_is_included const struct ext_include_script_info *ext_include_binary_script_get_included (struct ext_include_binary_context *binctx, unsigned int include_id) { - if ( include_id > 0 && (include_id - 1) < array_count(&binctx->include_index) ) { + if ( include_id > 0 && + (include_id - 1) < array_count(&binctx->include_index) ) { struct ext_include_script_info *const *sinfo = array_idx(&binctx->include_index, include_id - 1); @@ -180,10 +187,10 @@ unsigned int ext_include_binary_script_get_count */ struct sieve_variable_scope *ext_include_binary_get_global_scope -(struct sieve_binary *sbin) +(const struct sieve_extension *this_ext, struct sieve_binary *sbin) { struct ext_include_binary_context *binctx = - ext_include_binary_get_context(sbin); + ext_include_binary_get_context(this_ext, sbin); return binctx->global_vars; } @@ -192,10 +199,12 @@ struct sieve_variable_scope *ext_include_binary_get_global_scope * Binary extension */ -static bool ext_include_binary_save(struct sieve_binary *sbin) +static bool ext_include_binary_save +(const struct sieve_extension *ext ATTR_UNUSED, struct sieve_binary *sbin, + void *context) { struct ext_include_binary_context *binctx = - ext_include_binary_get_context(sbin); + (struct ext_include_binary_context *) context; struct ext_include_script_info *const *scripts; unsigned int script_count, i; unsigned int prvblk; @@ -224,13 +233,15 @@ static bool ext_include_binary_save(struct sieve_binary *sbin) return result; } -static bool ext_include_binary_open(struct sieve_binary *sbin) +static bool ext_include_binary_open +(const struct sieve_extension *ext, struct sieve_binary *sbin, void *context) { - struct ext_include_binary_context *binctx; + struct ext_include_binary_context *binctx = + (struct ext_include_binary_context *) context; unsigned int block, prvblk, depcount, i; sieve_size_t offset; - block = sieve_binary_extension_get_block(sbin, &include_extension); + block = sieve_binary_extension_get_block(sbin, ext); if ( !sieve_binary_block_set_active(sbin, block, &prvblk) ) return FALSE; @@ -243,8 +254,6 @@ static bool ext_include_binary_open(struct sieve_binary *sbin) return FALSE; } - binctx = ext_include_binary_get_context(sbin); - /* Check include limit */ if ( depcount > EXT_INCLUDE_MAX_INCLUDES ) { sieve_sys_error("include: binary %s includes too many scripts (%u > %u)", @@ -282,7 +291,7 @@ static bool ext_include_binary_open(struct sieve_binary *sbin) script_dir = ext_include_get_script_directory(location, str_c(script_name)); if ( script_dir == NULL || !(script=sieve_script_create_in_directory - (script_dir, str_c(script_name), NULL, NULL)) ) { + (ext->svinst, script_dir, str_c(script_name), NULL, NULL)) ) { /* No, recompile */ return FALSE; } @@ -292,7 +301,8 @@ static bool ext_include_binary_open(struct sieve_binary *sbin) sieve_script_unref(&script); } - if ( !ext_include_variables_load(sbin, &offset, block, &binctx->global_vars) ) + if ( !ext_include_variables_load + (ext, sbin, &offset, block, &binctx->global_vars) ) return FALSE; /* Restore previously active block */ @@ -301,17 +311,20 @@ static bool ext_include_binary_open(struct sieve_binary *sbin) return TRUE; } -static bool ext_include_binary_up_to_date(struct sieve_binary *sbin) +static bool ext_include_binary_up_to_date +(const struct sieve_extension *ext ATTR_UNUSED, struct sieve_binary *sbin, + void *context) { struct ext_include_binary_context *binctx = - ext_include_binary_get_context(sbin); + (struct ext_include_binary_context *) context; struct hash_iterate_context *hctx; void *key, *value; /* Check all included scripts for changes */ hctx = hash_table_iterate_init(binctx->included_scripts); while ( hash_table_iterate(hctx, &key, &value) ) { - struct ext_include_script_info *incscript = (struct ext_include_script_info *) value; + struct ext_include_script_info *incscript = + (struct ext_include_script_info *) value; /* Is the binary newer than this dependency? */ if ( !sieve_binary_script_older(sbin, incscript->script) ) { @@ -324,17 +337,20 @@ static bool ext_include_binary_up_to_date(struct sieve_binary *sbin) return TRUE; } -static void ext_include_binary_free(struct sieve_binary *sbin) +static void ext_include_binary_free +(const struct sieve_extension *ext ATTR_UNUSED, + struct sieve_binary *sbin ATTR_UNUSED, void *context) { struct ext_include_binary_context *binctx = - ext_include_binary_get_context(sbin); + (struct ext_include_binary_context *) context; struct hash_iterate_context *hctx; void *key, *value; /* Release references to all included script objects */ hctx = hash_table_iterate_init(binctx->included_scripts); while ( hash_table_iterate(hctx, &key, &value) ) { - struct ext_include_script_info *incscript = (struct ext_include_script_info *) value; + struct ext_include_script_info *incscript = + (struct ext_include_script_info *) value; sieve_script_unref(&incscript->script); } @@ -350,26 +366,12 @@ static void ext_include_binary_free(struct sieve_binary *sbin) * Dumping the binary */ -inline static const char *_script_location -(enum ext_include_script_location loc) -{ - switch ( loc ) { - case EXT_INCLUDE_LOCATION_PERSONAL: - return "personal"; - case EXT_INCLUDE_LOCATION_GLOBAL: - return "global"; - default: - break; - } - - return "<<INVALID LOCATION>>"; -} - -bool ext_include_binary_dump(struct sieve_dumptime_env *denv) +bool ext_include_binary_dump +(const struct sieve_extension *ext, struct sieve_dumptime_env *denv) { struct sieve_binary *sbin = denv->sbin; struct ext_include_binary_context *binctx = - ext_include_binary_get_context(sbin); + ext_include_binary_get_context(ext, sbin); struct hash_iterate_context *hctx; void *key, *value; unsigned int prvblk = 0; @@ -379,10 +381,11 @@ bool ext_include_binary_dump(struct sieve_dumptime_env *denv) hctx = hash_table_iterate_init(binctx->included_scripts); while ( hash_table_iterate(hctx, &key, &value) ) { - struct ext_include_script_info *incscript = (struct ext_include_script_info *) value; + struct ext_include_script_info *incscript = + (struct ext_include_script_info *) value; sieve_binary_dump_sectionf(denv, "Included %s script '%s' (block: %d)", - _script_location(incscript->location), + ext_include_script_location_name(incscript->location), sieve_script_name(incscript->script), incscript->block_id); if ( prvblk == 0 ) { @@ -411,13 +414,16 @@ bool ext_include_binary_dump(struct sieve_dumptime_env *denv) } bool ext_include_code_dump -(const struct sieve_dumptime_env *denv, sieve_size_t *address ATTR_UNUSED) +(const struct sieve_extension *ext, const struct sieve_dumptime_env *denv, + sieve_size_t *address ATTR_UNUSED) { struct sieve_binary *sbin = denv->sbin; struct ext_include_binary_context *binctx = - ext_include_binary_get_context(sbin); + ext_include_binary_get_context(ext, sbin); + struct ext_include_context *ectx = ext_include_get_context(ext); - sieve_ext_variables_dump_set_scope(denv, &include_extension, binctx->global_vars); + sieve_ext_variables_dump_set_scope + (ectx->var_ext, denv, ext, binctx->global_vars); return TRUE; } diff --git a/src/lib-sieve/plugins/include/ext-include-binary.h b/src/lib-sieve/plugins/include/ext-include-binary.h index a6c500fa8..1838f3033 100644 --- a/src/lib-sieve/plugins/include/ext-include-binary.h +++ b/src/lib-sieve/plugins/include/ext-include-binary.h @@ -13,16 +13,17 @@ struct ext_include_binary_context; struct ext_include_binary_context *ext_include_binary_init - (struct sieve_binary *sbin, struct sieve_ast *ast); + (const struct sieve_extension *this_ext, struct sieve_binary *sbin, + struct sieve_ast *ast); struct ext_include_binary_context *ext_include_binary_get_context - (struct sieve_binary *sbin); + (const struct sieve_extension *this_ext, struct sieve_binary *sbin); /* * Variables */ struct sieve_variable_scope *ext_include_binary_get_global_scope - (struct sieve_binary *sbin); + (const struct sieve_extension *this_ext, struct sieve_binary *sbin); /* * Including scripts @@ -55,9 +56,11 @@ unsigned int ext_include_binary_script_get_count * Dumping the binary */ -bool ext_include_binary_dump(struct sieve_dumptime_env *denv); +bool ext_include_binary_dump + (const struct sieve_extension *ext, struct sieve_dumptime_env *denv); bool ext_include_code_dump - (const struct sieve_dumptime_env *denv, sieve_size_t *address ATTR_UNUSED); + (const struct sieve_extension *ext, const struct sieve_dumptime_env *denv, + sieve_size_t *address ATTR_UNUSED); #endif /* __EXT_INCLUDE_BINARY_H */ diff --git a/src/lib-sieve/plugins/include/ext-include-common.c b/src/lib-sieve/plugins/include/ext-include-common.c index 51ede03f1..4445c9b37 100644 --- a/src/lib-sieve/plugins/include/ext-include-common.c +++ b/src/lib-sieve/plugins/include/ext-include-common.c @@ -13,6 +13,7 @@ #include "sieve-ast.h" #include "sieve-binary.h" #include "sieve-commands.h" +#include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-interpreter.h" @@ -37,7 +38,7 @@ struct ext_include_generator_context { static inline struct ext_include_generator_context * ext_include_get_generator_context - (struct sieve_generator *gentr); + (const struct sieve_extension *ext_this, struct sieve_generator *gentr); /* Interpreter context */ @@ -107,7 +108,6 @@ const char *ext_include_get_script_directory return NULL; } - return sieve_dir; } @@ -116,7 +116,8 @@ const char *ext_include_get_script_directory */ static void ext_include_ast_free -(struct sieve_ast *ast ATTR_UNUSED, void *context) +(const struct sieve_extension *ext ATTR_UNUSED, + struct sieve_ast *ast ATTR_UNUSED, void *context) { struct ext_include_ast_context *actx = (struct ext_include_ast_context *) context; @@ -140,7 +141,8 @@ static const struct sieve_ast_extension include_ast_extension = { }; struct ext_include_ast_context *ext_include_create_ast_context -(struct sieve_ast *ast, struct sieve_ast *parent) +(const struct sieve_extension *this_ext, struct sieve_ast *ast, + struct sieve_ast *parent) { struct ext_include_ast_context *actx; @@ -151,45 +153,57 @@ struct ext_include_ast_context *ext_include_create_ast_context if ( parent != NULL ) { struct ext_include_ast_context *parent_ctx = (struct ext_include_ast_context *) - sieve_ast_extension_get_context(parent, &include_extension); + sieve_ast_extension_get_context(parent, this_ext); actx->global_vars = parent_ctx->global_vars; i_assert( actx->global_vars != NULL ); sieve_variable_scope_ref(actx->global_vars); - } else - actx->global_vars = sieve_variable_scope_create(&include_extension); + } else { + actx->global_vars = sieve_variable_scope_create(this_ext); + } - sieve_ast_extension_register(ast, &include_ast_extension, (void *) actx); + sieve_ast_extension_register + (ast, this_ext, &include_ast_extension, (void *) actx); return actx; } struct ext_include_ast_context *ext_include_get_ast_context -(struct sieve_ast *ast) +(const struct sieve_extension *this_ext, struct sieve_ast *ast) { struct ext_include_ast_context *actx = (struct ext_include_ast_context *) - sieve_ast_extension_get_context(ast, &include_extension); + sieve_ast_extension_get_context(ast, this_ext); if ( actx != NULL ) return actx; - return ext_include_create_ast_context(ast, NULL); + return ext_include_create_ast_context(this_ext, ast, NULL); } void ext_include_ast_link_included_script -(struct sieve_ast *ast, struct sieve_script *script) +(const struct sieve_extension *this_ext, struct sieve_ast *ast, + struct sieve_script *script) { - struct ext_include_ast_context *actx = ext_include_get_ast_context(ast); + struct ext_include_ast_context *actx = + ext_include_get_ast_context(this_ext, ast); array_append(&actx->included_scripts, &script, 1); } +bool ext_include_validator_have_variables +(const struct sieve_extension *this_ext, struct sieve_validator *valdtr) +{ + struct ext_include_context *ectx = ext_include_get_context(this_ext); + + return sieve_ext_variables_is_active(ectx->var_ext, valdtr); +} + /* * Generator context management */ static struct ext_include_generator_context * - ext_include_create_generator_context +ext_include_create_generator_context (struct sieve_generator *gentr, struct ext_include_generator_context *parent, struct sieve_script *script) { @@ -210,25 +224,25 @@ static struct ext_include_generator_context * static inline struct ext_include_generator_context * ext_include_get_generator_context -(struct sieve_generator *gentr) +(const struct sieve_extension *this_ext, struct sieve_generator *gentr) { return (struct ext_include_generator_context *) - sieve_generator_extension_get_context(gentr, &include_extension); + sieve_generator_extension_get_context(gentr, this_ext); } static inline void ext_include_initialize_generator_context -(struct sieve_generator *gentr, struct ext_include_generator_context *parent, - struct sieve_script *script) +(const struct sieve_extension *this_ext, struct sieve_generator *gentr, + struct ext_include_generator_context *parent, struct sieve_script *script) { - sieve_generator_extension_set_context(gentr, &include_extension, + sieve_generator_extension_set_context(gentr, this_ext, ext_include_create_generator_context(gentr, parent, script)); } void ext_include_register_generator_context -(const struct sieve_codegen_env *cgenv) +(const struct sieve_extension *this_ext, const struct sieve_codegen_env *cgenv) { struct ext_include_generator_context *ctx = - ext_include_get_generator_context(cgenv->gentr); + ext_include_get_generator_context(this_ext, cgenv->gentr); /* Initialize generator context if necessary */ if ( ctx == NULL ) { @@ -236,12 +250,12 @@ void ext_include_register_generator_context cgenv->gentr, NULL, cgenv->script); sieve_generator_extension_set_context - (cgenv->gentr, &include_extension, (void *) ctx); + (cgenv->gentr, this_ext, (void *) ctx); } /* Initialize ast context if necessary */ - (void)ext_include_get_ast_context(cgenv->ast); - (void)ext_include_binary_init(cgenv->sbin, cgenv->ast); + (void)ext_include_get_ast_context(this_ext, cgenv->ast); + (void)ext_include_binary_init(this_ext, cgenv->sbin, cgenv->ast); } /* @@ -249,22 +263,26 @@ void ext_include_register_generator_context */ static void ext_include_runtime_init - (const struct sieve_runtime_env *renv, void *context) +(const struct sieve_extension *this_ext, const struct sieve_runtime_env *renv, + void *context) { struct ext_include_interpreter_context *ctx = (struct ext_include_interpreter_context *) context; + struct ext_include_context *ectx = ext_include_get_context(this_ext); if ( ctx->parent == NULL ) { ctx->global = p_new(ctx->pool, struct ext_include_interpreter_global, 1); - ctx->global->variables = sieve_variable_storage_create - (ctx->pool, ext_include_binary_get_global_scope(renv->sbin), 0); p_array_init(&ctx->global->included_scripts, ctx->pool, 10); + + + ctx->global->variables = sieve_variable_storage_create + (ctx->pool, ext_include_binary_get_global_scope(this_ext, renv->sbin), 0); } else { ctx->global = ctx->parent->global; } sieve_ext_variables_set_storage - (renv->interp, ctx->global->variables, &include_extension); + (ectx->var_ext, renv->interp, ctx->global->variables, this_ext); } static struct sieve_interpreter_extension include_interpreter_extension = { @@ -304,15 +322,15 @@ static struct ext_include_interpreter_context * static inline struct ext_include_interpreter_context * ext_include_get_interpreter_context -(struct sieve_interpreter *interp) +(const struct sieve_extension *this_ext, struct sieve_interpreter *interp) { return (struct ext_include_interpreter_context *) - sieve_interpreter_extension_get_context(interp, &include_extension); + sieve_interpreter_extension_get_context(interp, this_ext); } static inline struct ext_include_interpreter_context * ext_include_interpreter_context_init_child -(struct sieve_interpreter *interp, +(const struct sieve_extension *this_ext, struct sieve_interpreter *interp, struct ext_include_interpreter_context *parent, struct sieve_script *script, const struct ext_include_script_info *sinfo) { @@ -320,16 +338,16 @@ static inline struct ext_include_interpreter_context * ext_include_interpreter_context_create(interp, parent, script, sinfo); sieve_interpreter_extension_register - (interp, &include_interpreter_extension, ctx); + (interp, this_ext, &include_interpreter_extension, ctx); return ctx; } void ext_include_interpreter_context_init -(struct sieve_interpreter *interp) +(const struct sieve_extension *this_ext, struct sieve_interpreter *interp) { struct ext_include_interpreter_context *ctx = - ext_include_get_interpreter_context(interp); + ext_include_get_interpreter_context(this_ext, interp); /* Is this is the top-level interpreter ? */ if ( ctx == NULL ) { @@ -341,15 +359,15 @@ void ext_include_interpreter_context_init (interp, NULL, script, NULL); sieve_interpreter_extension_register - (interp, &include_interpreter_extension, (void *) ctx); + (interp, this_ext, &include_interpreter_extension, (void *) ctx); } } struct sieve_variable_storage *ext_include_interpreter_get_global_variables -(struct sieve_interpreter *interp) +(const struct sieve_extension *this_ext, struct sieve_interpreter *interp) { struct ext_include_interpreter_context *ctx = - ext_include_get_interpreter_context(interp); + ext_include_get_interpreter_context(this_ext, interp); return ctx->global->variables; } @@ -359,10 +377,11 @@ struct sieve_variable_storage *ext_include_interpreter_get_global_variables */ bool ext_include_generate_include -(const struct sieve_codegen_env *cgenv, struct sieve_command_context *cmd, +(const struct sieve_codegen_env *cgenv, struct sieve_command *cmd, enum ext_include_script_location location, struct sieve_script *script, const struct ext_include_script_info **included_r, bool once) { + const struct sieve_extension *this_ext = cmd->ext; bool result = TRUE; struct sieve_ast *ast; struct sieve_binary *sbin = cgenv->sbin; @@ -370,7 +389,7 @@ bool ext_include_generate_include struct ext_include_binary_context *binctx; struct sieve_generator *subgentr; struct ext_include_generator_context *ctx = - ext_include_get_generator_context(gentr); + ext_include_get_generator_context(this_ext, gentr); struct ext_include_generator_context *pctx; struct sieve_error_handler *ehandler = sieve_generator_error_handler(gentr); const struct ext_include_script_info *included; @@ -406,7 +425,7 @@ bool ext_include_generate_include } /* Get binary context */ - binctx = ext_include_binary_init(sbin, cgenv->ast); + binctx = ext_include_binary_init(this_ext, sbin, cgenv->ast); /* Is the script already compiled into the current binary? */ if ( !ext_include_binary_script_is_included(binctx, script, &included) ) @@ -437,7 +456,7 @@ bool ext_include_generate_include } /* Included scripts inherit global variable scope */ - (void)ext_include_create_ast_context(ast, cmd->ast_node->ast); + (void)ext_include_create_ast_context(this_ext, ast, cmd->ast_node->ast); /* Validate */ if ( !sieve_validate(ast, ehandler) ) { @@ -454,7 +473,7 @@ bool ext_include_generate_include */ if ( sieve_binary_block_set_active(sbin, inc_block_id, &this_block_id) ) { subgentr = sieve_generator_create(ast, ehandler); - ext_include_initialize_generator_context(subgentr, ctx, script); + ext_include_initialize_generator_context(cmd->ext, subgentr, ctx, script); if ( !sieve_generator_run(subgentr, &sbin) ) { sieve_command_generate_error(gentr, cmd, @@ -524,11 +543,12 @@ static bool ext_include_runtime_include_mark int ext_include_execute_include (const struct sieve_runtime_env *renv, unsigned int include_id, bool once) { + const struct sieve_extension *this_ext = renv->oprtn.ext; int result = SIEVE_EXEC_OK; struct ext_include_interpreter_context *ctx; const struct ext_include_script_info *included; struct ext_include_binary_context *binctx = - ext_include_binary_get_context(renv->sbin); + ext_include_binary_get_context(this_ext, renv->sbin); /* Check for invalid include id (== corrupt binary) */ included = ext_include_binary_script_get_included(binctx, include_id); @@ -537,7 +557,7 @@ int ext_include_execute_include return SIEVE_EXEC_BIN_CORRUPT; } - ctx = ext_include_get_interpreter_context(renv->interp); + ctx = ext_include_get_interpreter_context(this_ext, renv->interp); sieve_runtime_trace(renv, "INCLUDE command (script: %s, id: %d block: %d) START::", @@ -590,7 +610,7 @@ int ext_include_execute_include if ( subinterp != NULL ) { curctx = ext_include_interpreter_context_init_child - (subinterp, ctx, included->script, included); + (this_ext, subinterp, ctx, included->script, included); /* Activate and start the top-level included script */ result = ( sieve_interpreter_start @@ -651,7 +671,7 @@ int ext_include_execute_include if ( subinterp != NULL ) { curctx = ext_include_interpreter_context_init_child - (subinterp, curctx, curctx->include->script, + (this_ext, subinterp, curctx, curctx->include->script, curctx->include); /* Start the sub-include's interpreter */ @@ -701,10 +721,12 @@ int ext_include_execute_include return result; } -void ext_include_execute_return(const struct sieve_runtime_env *renv) +void ext_include_execute_return +(const struct sieve_runtime_env *renv) { + const struct sieve_extension *this_ext = renv->oprtn.ext; struct ext_include_interpreter_context *ctx = - ext_include_get_interpreter_context(renv->interp); + ext_include_get_interpreter_context(this_ext, renv->interp); ctx->returned = TRUE; sieve_interpreter_interrupt(renv->interp); diff --git a/src/lib-sieve/plugins/include/ext-include-common.h b/src/lib-sieve/plugins/include/ext-include-common.h index d0e3ee81f..ac367694c 100644 --- a/src/lib-sieve/plugins/include/ext-include-common.h +++ b/src/lib-sieve/plugins/include/ext-include-common.h @@ -8,6 +8,7 @@ #include "hash.h" #include "sieve-common.h" +#include "sieve-extensions.h" /* * Forward declarations @@ -40,7 +41,7 @@ static inline const char *ext_include_script_location_name break; } - return "[INVALUD LOCATION]"; + return "[INVALID LOCATION]"; } @@ -48,20 +49,30 @@ static inline const char *ext_include_script_location_name * Extension */ -extern const struct sieve_extension include_extension; +extern const struct sieve_extension_def include_extension; extern const struct sieve_binary_extension include_binary_ext; +struct ext_include_context { + const struct sieve_extension *var_ext; +}; + +static inline struct ext_include_context *ext_include_get_context +(const struct sieve_extension *ext) +{ + return (struct ext_include_context *) ext->context; +} + /* * Commands */ -extern const struct sieve_command cmd_include; -extern const struct sieve_command cmd_return; -extern const struct sieve_command cmd_global; +extern const struct sieve_command_def cmd_include; +extern const struct sieve_command_def cmd_return; +extern const struct sieve_command_def cmd_global; /* DEPRICATED */ -extern const struct sieve_command cmd_import; -extern const struct sieve_command cmd_export; +extern const struct sieve_command_def cmd_import; +extern const struct sieve_command_def cmd_export; /* * Operations @@ -73,9 +84,9 @@ enum ext_include_opcode { EXT_INCLUDE_OPERATION_GLOBAL }; -extern const struct sieve_operation include_operation; -extern const struct sieve_operation return_operation; -extern const struct sieve_operation global_operation; +extern const struct sieve_operation_def include_operation; +extern const struct sieve_operation_def return_operation; +extern const struct sieve_operation_def global_operation; /* * Script access @@ -91,38 +102,45 @@ const char *ext_include_get_script_directory /* AST Context */ struct ext_include_ast_context { - struct sieve_variable_scope *global_vars; + struct sieve_variable_scope *global_vars; - ARRAY_DEFINE(included_scripts, struct sieve_script *); + ARRAY_DEFINE(included_scripts, struct sieve_script *); }; struct ext_include_ast_context *ext_include_create_ast_context - (struct sieve_ast *ast, struct sieve_ast *parent); + (const struct sieve_extension *this_ext, struct sieve_ast *ast, + struct sieve_ast *parent); struct ext_include_ast_context *ext_include_get_ast_context - (struct sieve_ast *ast); + (const struct sieve_extension *this_ext, struct sieve_ast *ast); void ext_include_ast_link_included_script - (struct sieve_ast *ast, struct sieve_script *script); + (const struct sieve_extension *this_ext, struct sieve_ast *ast, + struct sieve_script *script); + +bool ext_include_validator_have_variables + (const struct sieve_extension *this_ext, struct sieve_validator *valdtr); /* Generator context */ void ext_include_register_generator_context - (const struct sieve_codegen_env *cgenv); + (const struct sieve_extension *this_ext, + const struct sieve_codegen_env *cgenv); bool ext_include_generate_include - (const struct sieve_codegen_env *cgenv, struct sieve_command_context *cmd, + (const struct sieve_codegen_env *cgenv, struct sieve_command *cmd, enum ext_include_script_location location, struct sieve_script *script, const struct ext_include_script_info **included_r, bool once); /* Interpreter context */ -void ext_include_interpreter_context_init(struct sieve_interpreter *interp); +void ext_include_interpreter_context_init + (const struct sieve_extension *this_ext, struct sieve_interpreter *interp); int ext_include_execute_include (const struct sieve_runtime_env *renv, unsigned int block_id, bool once); void ext_include_execute_return(const struct sieve_runtime_env *renv); struct sieve_variable_storage *ext_include_interpreter_get_global_variables - (struct sieve_interpreter *interp); + (const struct sieve_extension *this_ext, struct sieve_interpreter *interp); #endif /* __EXT_INCLUDE_COMMON_H */ diff --git a/src/lib-sieve/plugins/include/ext-include-variables.c b/src/lib-sieve/plugins/include/ext-include-variables.c index 21d53ce8e..a0fb7c8b8 100644 --- a/src/lib-sieve/plugins/include/ext-include-variables.c +++ b/src/lib-sieve/plugins/include/ext-include-variables.c @@ -23,11 +23,14 @@ */ struct sieve_variable *ext_include_variable_import_global -(struct sieve_validator *valdtr, struct sieve_command_context *cmd, +(struct sieve_validator *valdtr, struct sieve_command *cmd, const char *variable) { + const struct sieve_extension *this_ext = cmd->ext; struct sieve_ast *ast = cmd->ast_node->ast; - struct ext_include_ast_context *ctx = ext_include_get_ast_context(ast); + struct ext_include_ast_context *ctx = + ext_include_get_ast_context(this_ext, ast); + struct ext_include_context *ectx = ext_include_get_context(this_ext); struct sieve_variable_scope *main_scope; struct sieve_variable *var = NULL; @@ -46,7 +49,7 @@ struct sieve_variable *ext_include_variable_import_global } /* Import the global variable into the local script scope */ - main_scope = sieve_ext_variables_get_main_scope(valdtr); + main_scope = sieve_ext_variables_get_main_scope(ectx->var_ext, valdtr); (void)sieve_variable_scope_import(main_scope, var); return var; @@ -77,7 +80,8 @@ bool ext_include_variables_save } bool ext_include_variables_load -(struct sieve_binary *sbin, sieve_size_t *offset, unsigned int block, +(const struct sieve_extension *this_ext, struct sieve_binary *sbin, + sieve_size_t *offset, unsigned int block, struct sieve_variable_scope **global_vars_r) { unsigned int count = 0; @@ -100,7 +104,7 @@ bool ext_include_variables_load return FALSE; } - *global_vars_r = sieve_variable_scope_create(&include_extension); + *global_vars_r = sieve_variable_scope_create(this_ext); pool = sieve_variable_scope_pool(*global_vars_r); /* Read global variable scope */ diff --git a/src/lib-sieve/plugins/include/ext-include-variables.h b/src/lib-sieve/plugins/include/ext-include-variables.h index 7b87e3367..231ed2c1d 100644 --- a/src/lib-sieve/plugins/include/ext-include-variables.h +++ b/src/lib-sieve/plugins/include/ext-include-variables.h @@ -15,7 +15,7 @@ */ struct sieve_variable *ext_include_variable_import_global - (struct sieve_validator *valdtr, struct sieve_command_context *cmd, + (struct sieve_validator *valdtr, struct sieve_command *cmd, const char *variable); /* @@ -25,7 +25,8 @@ struct sieve_variable *ext_include_variable_import_global bool ext_include_variables_save (struct sieve_binary *sbin, struct sieve_variable_scope *global_vars); bool ext_include_variables_load - (struct sieve_binary *sbin, sieve_size_t *offset, unsigned int block, + (const struct sieve_extension *this_ext, struct sieve_binary *sbin, + sieve_size_t *offset, unsigned int block, struct sieve_variable_scope **global_vars_r); bool ext_include_variables_dump (struct sieve_dumptime_env *denv, struct sieve_variable_scope *global_vars); diff --git a/src/lib-sieve/plugins/include/ext-include.c b/src/lib-sieve/plugins/include/ext-include.c index 6f6c8d216..edaa23c3b 100644 --- a/src/lib-sieve/plugins/include/ext-include.c +++ b/src/lib-sieve/plugins/include/ext-include.c @@ -27,6 +27,8 @@ #include "sieve-binary.h" #include "sieve-dump.h" +#include "sieve-ext-variables.h" + #include "ext-include-common.h" #include "ext-include-binary.h" @@ -34,7 +36,7 @@ * Operations */ -static const struct sieve_operation *ext_include_operations[] = { +static const struct sieve_operation_def *ext_include_operations[] = { &include_operation, &return_operation, &global_operation @@ -46,20 +48,26 @@ static const struct sieve_operation *ext_include_operations[] = { /* Forward declaration */ -static bool ext_include_validator_load(struct sieve_validator *validator); -static bool ext_include_generator_load(const struct sieve_codegen_env *cgenv); +static bool ext_include_load + (const struct sieve_extension *ext, void **context); +static void ext_include_unload + (const struct sieve_extension *ext); +static bool ext_include_validator_load + (const struct sieve_extension *ext, struct sieve_validator *validator); +static bool ext_include_generator_load + (const struct sieve_extension *ext, const struct sieve_codegen_env *cgenv); static bool ext_include_interpreter_load - (const struct sieve_runtime_env *renv, sieve_size_t *address); -static bool ext_include_binary_load(struct sieve_binary *binary); + (const struct sieve_extension *ext, const struct sieve_runtime_env *renv, + sieve_size_t *address); +static bool ext_include_binary_load + (const struct sieve_extension *ext, struct sieve_binary *binary); /* Extension objects */ -static int ext_my_id = -1; - -const struct sieve_extension include_extension = { +const struct sieve_extension_def include_extension = { "include", - &ext_my_id, - NULL, NULL, + ext_include_load, + ext_include_unload, ext_include_validator_load, ext_include_generator_load, ext_include_interpreter_load, @@ -72,38 +80,60 @@ const struct sieve_extension include_extension = { /* Extension hooks */ -static bool ext_include_validator_load(struct sieve_validator *validator) +static bool ext_include_load +(const struct sieve_extension *ext, void **context) +{ + struct ext_include_context *ctx = i_new(struct ext_include_context, 1); + + ctx->var_ext = sieve_ext_variables_get_extension(ext->svinst); + *context = ctx; + + return TRUE; +} + +static void ext_include_unload +(const struct sieve_extension *ext) +{ + struct ext_include_context *ctx = (struct ext_include_context *) ext->context; + i_free(ctx); +} + +static bool ext_include_validator_load +(const struct sieve_extension *ext, struct sieve_validator *validator) { /* Register new commands */ - sieve_validator_register_command(validator, &cmd_include); - sieve_validator_register_command(validator, &cmd_return); - sieve_validator_register_command(validator, &cmd_global); + sieve_validator_register_command(validator, ext, &cmd_include); + sieve_validator_register_command(validator, ext, &cmd_return); + sieve_validator_register_command(validator, ext, &cmd_global); /* DEPRICATED */ - sieve_validator_register_command(validator, &cmd_import); - sieve_validator_register_command(validator, &cmd_export); + sieve_validator_register_command(validator, ext, &cmd_import); + sieve_validator_register_command(validator, ext, &cmd_export); return TRUE; } -static bool ext_include_generator_load(const struct sieve_codegen_env *cgenv) +static bool ext_include_generator_load +(const struct sieve_extension *ext, const struct sieve_codegen_env *cgenv) { - ext_include_register_generator_context(cgenv); + ext_include_register_generator_context(ext, cgenv); return TRUE; } static bool ext_include_interpreter_load -(const struct sieve_runtime_env *renv, sieve_size_t *address ATTR_UNUSED) +(const struct sieve_extension *ext, const struct sieve_runtime_env *renv, + sieve_size_t *address ATTR_UNUSED) { - ext_include_interpreter_context_init(renv->interp); + ext_include_interpreter_context_init(ext, renv->interp); return TRUE; } -static bool ext_include_binary_load(struct sieve_binary *sbin) +static bool ext_include_binary_load +(const struct sieve_extension *ext, struct sieve_binary *sbin) { - (void)ext_include_binary_get_context(sbin); + (void)ext_include_binary_get_context(ext, sbin); return TRUE; } diff --git a/src/lib-sieve/plugins/mailbox/ext-mailbox-common.h b/src/lib-sieve/plugins/mailbox/ext-mailbox-common.h index 4b593fd65..ee522b344 100644 --- a/src/lib-sieve/plugins/mailbox/ext-mailbox-common.h +++ b/src/lib-sieve/plugins/mailbox/ext-mailbox-common.h @@ -10,31 +10,31 @@ * Tagged arguments */ -extern const struct sieve_argument mailbox_create_tag; +extern const struct sieve_argument_def mailbox_create_tag; /* * Commands */ -extern const struct sieve_command mailboxexists_test; +extern const struct sieve_command_def mailboxexists_test; /* * Operands */ -extern const struct sieve_operand mailbox_create_operand; +extern const struct sieve_operand_def mailbox_create_operand; /* * Operations */ -extern const struct sieve_operation mailboxexists_operation; +extern const struct sieve_operation_def mailboxexists_operation; /* * Extension */ -extern const struct sieve_extension mailbox_extension; +extern const struct sieve_extension_def mailbox_extension; #endif /* __EXT_MAILBOX_COMMON_H */ diff --git a/src/lib-sieve/plugins/mailbox/ext-mailbox.c b/src/lib-sieve/plugins/mailbox/ext-mailbox.c index bb777923c..db381ef2b 100644 --- a/src/lib-sieve/plugins/mailbox/ext-mailbox.c +++ b/src/lib-sieve/plugins/mailbox/ext-mailbox.c @@ -30,13 +30,11 @@ * Extension */ -static bool ext_mailbox_validator_load(struct sieve_validator *valdtr); +static bool ext_mailbox_validator_load +(const struct sieve_extension *ext, struct sieve_validator *valdtr); -static int ext_my_id = -1; - -const struct sieve_extension mailbox_extension = { +const struct sieve_extension_def mailbox_extension = { "mailbox", - &ext_my_id, NULL, NULL, ext_mailbox_validator_load, NULL, NULL, NULL, NULL, NULL, @@ -44,17 +42,18 @@ const struct sieve_extension mailbox_extension = { SIEVE_EXT_DEFINE_OPERAND(mailbox_create_operand) }; -static bool ext_mailbox_validator_load(struct sieve_validator *valdtr) +static bool ext_mailbox_validator_load +(const struct sieve_extension *ext, struct sieve_validator *valdtr) { /* Register :create tag with fileinto command and we don't care whether this * command is registered or even whether it will be registered at all. The * validator handles either situation gracefully */ sieve_validator_register_external_tag - (valdtr, &mailbox_create_tag, "fileinto", SIEVE_OPT_SIDE_EFFECT); + (valdtr, "fileinto", ext, &mailbox_create_tag, SIEVE_OPT_SIDE_EFFECT); /* Register new test */ - sieve_validator_register_command(valdtr, &mailboxexists_test); + sieve_validator_register_command(valdtr, ext, &mailboxexists_test); return TRUE; } diff --git a/src/lib-sieve/plugins/mailbox/tag-mailbox-create.c b/src/lib-sieve/plugins/mailbox/tag-mailbox-create.c index f2bb4622b..1e2f9271a 100644 --- a/src/lib-sieve/plugins/mailbox/tag-mailbox-create.c +++ b/src/lib-sieve/plugins/mailbox/tag-mailbox-create.c @@ -20,17 +20,17 @@ */ static bool tag_mailbox_create_validate - (struct sieve_validator *validator, struct sieve_ast_argument **arg, - struct sieve_command_context *cmd); + (struct sieve_validator *valdtr, struct sieve_ast_argument **arg, + struct sieve_command *cmd); static bool tag_mailbox_create_generate (const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, - struct sieve_command_context *context); + struct sieve_command *context); -const struct sieve_argument mailbox_create_tag = { +const struct sieve_argument_def mailbox_create_tag = { "create", - NULL, NULL, - tag_mailbox_create_validate, NULL, + tag_mailbox_create_validate, + NULL, NULL, tag_mailbox_create_generate }; @@ -40,13 +40,13 @@ const struct sieve_argument mailbox_create_tag = { static void seff_mailbox_create_print (const struct sieve_side_effect *seffect, const struct sieve_action *action, - const struct sieve_result_print_env *rpenv, void *se_context, bool *keep); + const struct sieve_result_print_env *rpenv, bool *keep); static bool seff_mailbox_create_pre_execute (const struct sieve_side_effect *seffect, const struct sieve_action *action, const struct sieve_action_exec_env *aenv, void **se_context, void *tr_context);; -const struct sieve_side_effect mailbox_create_side_effect = { +const struct sieve_side_effect_def mailbox_create_side_effect = { SIEVE_OBJECT("create", &mailbox_create_operand, 0), &act_store, NULL, NULL, NULL, @@ -62,7 +62,7 @@ const struct sieve_side_effect mailbox_create_side_effect = { static const struct sieve_extension_objects ext_side_effects = SIEVE_EXT_DEFINE_SIDE_EFFECT(mailbox_create_side_effect); -const struct sieve_operand mailbox_create_operand = { +const struct sieve_operand_def mailbox_create_operand = { "create operand", &mailbox_extension, 0, @@ -75,9 +75,8 @@ const struct sieve_operand mailbox_create_operand = { */ static bool tag_mailbox_create_validate - (struct sieve_validator *validator ATTR_UNUSED, - struct sieve_ast_argument **arg ATTR_UNUSED, - struct sieve_command_context *cmd ATTR_UNUSED) +(struct sieve_validator *valdtr ATTR_UNUSED, + struct sieve_ast_argument **arg, struct sieve_command *cmd ATTR_UNUSED) { *arg = sieve_ast_argument_next(*arg); @@ -90,13 +89,14 @@ static bool tag_mailbox_create_validate static bool tag_mailbox_create_generate (const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, - struct sieve_command_context *context ATTR_UNUSED) + struct sieve_command *context ATTR_UNUSED) { if ( sieve_ast_argument_type(arg) != SAAT_TAG ) { return FALSE; } - sieve_opr_side_effect_emit(cgenv->sbin, &mailbox_create_side_effect); + sieve_opr_side_effect_emit + (cgenv->sbin, arg->argument->ext, &mailbox_create_side_effect); return TRUE; } @@ -108,8 +108,7 @@ static bool tag_mailbox_create_generate static void seff_mailbox_create_print (const struct sieve_side_effect *seffect ATTR_UNUSED, const struct sieve_action *action ATTR_UNUSED, - const struct sieve_result_print_env *rpenv, - void *se_context ATTR_UNUSED, bool *keep ATTR_UNUSED) + const struct sieve_result_print_env *rpenv, bool *keep ATTR_UNUSED) { sieve_result_seffect_printf(rpenv, "create mailbox if it does not exist"); } diff --git a/src/lib-sieve/plugins/mailbox/tst-mailboxexists.c b/src/lib-sieve/plugins/mailbox/tst-mailboxexists.c index 59fcee441..3c4bae881 100644 --- a/src/lib-sieve/plugins/mailbox/tst-mailboxexists.c +++ b/src/lib-sieve/plugins/mailbox/tst-mailboxexists.c @@ -23,11 +23,11 @@ */ static bool tst_mailboxexists_validate - (struct sieve_validator *validator, struct sieve_command_context *tst); + (struct sieve_validator *valdtr, struct sieve_command *tst); static bool tst_mailboxexists_generate - (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx); + (const struct sieve_codegen_env *cgenv, struct sieve_command *ctx); -const struct sieve_command mailboxexists_test = { +const struct sieve_command_def mailboxexists_test = { "mailboxexists", SCT_TEST, 1, 0, FALSE, FALSE, @@ -42,13 +42,11 @@ const struct sieve_command mailboxexists_test = { */ static bool tst_mailboxexists_operation_dump - (const struct sieve_operation *op, - const struct sieve_dumptime_env *denv, sieve_size_t *address); + (const struct sieve_dumptime_env *denv, sieve_size_t *address); static int tst_mailboxexists_operation_execute - (const struct sieve_operation *op, - const struct sieve_runtime_env *renv, sieve_size_t *address); + (const struct sieve_runtime_env *renv, sieve_size_t *address); -const struct sieve_operation mailboxexists_operation = { +const struct sieve_operation_def mailboxexists_operation = { "MAILBOXEXISTS", &mailbox_extension, 0, @@ -61,16 +59,16 @@ const struct sieve_operation mailboxexists_operation = { */ static bool tst_mailboxexists_validate - (struct sieve_validator *validator, struct sieve_command_context *tst) +(struct sieve_validator *valdtr, struct sieve_command *tst) { struct sieve_ast_argument *arg = tst->first_positional; if ( !sieve_validate_positional_argument - (validator, tst, arg, "mailbox-names", 1, SAAT_STRING_LIST) ) { + (valdtr, tst, arg, "mailbox-names", 1, SAAT_STRING_LIST) ) { return FALSE; } - return sieve_validator_argument_activate(validator, tst, arg, FALSE); + return sieve_validator_argument_activate(valdtr, tst, arg, FALSE); } /* @@ -78,9 +76,9 @@ static bool tst_mailboxexists_validate */ static bool tst_mailboxexists_generate - (const struct sieve_codegen_env *cgenv, struct sieve_command_context *tst) +(const struct sieve_codegen_env *cgenv, struct sieve_command *tst) { - sieve_operation_emit_code(cgenv->sbin, &mailboxexists_operation); + sieve_operation_emit(cgenv->sbin, tst->ext, &mailboxexists_operation); /* Generate arguments */ return sieve_generate_arguments(cgenv, tst, NULL); @@ -91,8 +89,7 @@ static bool tst_mailboxexists_generate */ static bool tst_mailboxexists_operation_dump -(const struct sieve_operation *op ATTR_UNUSED, - const struct sieve_dumptime_env *denv, sieve_size_t *address) +(const struct sieve_dumptime_env *denv, sieve_size_t *address) { sieve_code_dumpf(denv, "MAILBOXEXISTS"); sieve_code_descend(denv); @@ -106,8 +103,7 @@ static bool tst_mailboxexists_operation_dump */ static int tst_mailboxexists_operation_execute -(const struct sieve_operation *op ATTR_UNUSED, - const struct sieve_runtime_env *renv, sieve_size_t *address) +(const struct sieve_runtime_env *renv, sieve_size_t *address) { struct sieve_coded_stringlist *mailbox_names; string_t *mailbox_item; diff --git a/src/lib-sieve/plugins/notify/cmd-denotify.c b/src/lib-sieve/plugins/notify/cmd-denotify.c index 12e3837d8..2a9ccb80d 100644 --- a/src/lib-sieve/plugins/notify/cmd-denotify.c +++ b/src/lib-sieve/plugins/notify/cmd-denotify.c @@ -27,11 +27,12 @@ */ static bool cmd_denotify_registered - (struct sieve_validator *valdtr, struct sieve_command_registration *cmd_reg); + (struct sieve_validator *valdtr, const struct sieve_extension *ext, + struct sieve_command_registration *cmd_reg); static bool cmd_denotify_generate - (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx); + (const struct sieve_codegen_env *cgenv, struct sieve_command *cmd); -const struct sieve_command cmd_denotify = { +const struct sieve_command_def cmd_denotify = { "denotify", SCT_COMMAND, 0, 0, FALSE, FALSE, @@ -49,20 +50,19 @@ const struct sieve_command cmd_denotify = { /* Forward declarations */ static bool tag_match_type_is_instance_of - (struct sieve_validator *validator, struct sieve_command_context *cmd, - struct sieve_ast_argument *arg); + (struct sieve_validator *validator, struct sieve_command *cmd, + const struct sieve_extension *ext, const char *identifier, void **data); static bool tag_match_type_validate (struct sieve_validator *validator, struct sieve_ast_argument **arg, - struct sieve_command_context *cmd); + struct sieve_command *cmd); /* Argument object */ -const struct sieve_argument denotify_match_tag = { +const struct sieve_argument_def denotify_match_tag = { "MATCH-TYPE-STRING", tag_match_type_is_instance_of, - NULL, tag_match_type_validate, - NULL, NULL + NULL, NULL, NULL, }; /* Codes for optional operands */ @@ -79,13 +79,11 @@ enum cmd_denotify_optional { */ static bool cmd_denotify_operation_dump - (const struct sieve_operation *op ATTR_UNUSED, - const struct sieve_dumptime_env *denv, sieve_size_t *address); + (const struct sieve_dumptime_env *denv, sieve_size_t *address); static int cmd_denotify_operation_execute - (const struct sieve_operation *op ATTR_UNUSED, - const struct sieve_runtime_env *renv, sieve_size_t *address); + (const struct sieve_runtime_env *renv, sieve_size_t *address); -const struct sieve_operation denotify_operation = { +const struct sieve_operation_def denotify_operation = { "DENOTIFY", ¬ify_extension, EXT_NOTIFY_OPERATION_DENOTIFY, @@ -98,17 +96,21 @@ const struct sieve_operation denotify_operation = { */ static bool tag_match_type_is_instance_of -(struct sieve_validator *valdtr, struct sieve_command_context *cmd, - struct sieve_ast_argument *arg) +(struct sieve_validator *valdtr, struct sieve_command *cmd, + const struct sieve_extension *ext, const char *identifier, void **data) { - return match_type_tag.is_instance_of(valdtr, cmd, arg); + return match_type_tag.is_instance_of(valdtr, cmd, ext, identifier, data); } static bool tag_match_type_validate (struct sieve_validator *valdtr, struct sieve_ast_argument **arg, - struct sieve_command_context *cmd) + struct sieve_command *cmd) { struct sieve_ast_argument *tag = *arg; + const struct sieve_match_type mcht_default = + SIEVE_MATCH_TYPE_DEFAULT(is_match_type); + const struct sieve_comparator cmp_default = + SIEVE_COMPARATOR_DEFAULT(i_octet_comparator); if ( !match_type_tag.validate(valdtr, arg, cmd) ) return FALSE; @@ -134,12 +136,13 @@ static bool tag_match_type_validate return FALSE; if ( !sieve_match_type_validate - (valdtr, cmd, *arg, &is_match_type, &i_octet_comparator) ) + (valdtr, cmd, *arg, &mcht_default, &cmp_default) ) return FALSE; - tag->argument = &match_type_tag; + tag->argument->def = &match_type_tag; + tag->argument->ext = NULL; - (*arg)->arg_id_code = OPT_MATCH_KEY; + (*arg)->argument->id_code = OPT_MATCH_KEY; *arg = sieve_ast_argument_next(*arg); @@ -151,12 +154,13 @@ static bool tag_match_type_validate */ static bool cmd_denotify_registered -(struct sieve_validator *valdtr, struct sieve_command_registration *cmd_reg) +(struct sieve_validator *valdtr, const struct sieve_extension *ext, + struct sieve_command_registration *cmd_reg) { sieve_validator_register_tag - (valdtr, cmd_reg, &denotify_match_tag, OPT_MATCH_TYPE); + (valdtr, cmd_reg, ext, &denotify_match_tag, OPT_MATCH_TYPE); - ext_notify_register_importance_tags(valdtr, cmd_reg, OPT_IMPORTANCE); + ext_notify_register_importance_tags(valdtr, cmd_reg, ext, OPT_IMPORTANCE); return TRUE; } @@ -166,15 +170,15 @@ static bool cmd_denotify_registered */ static bool cmd_denotify_generate -(const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx) +(const struct sieve_codegen_env *cgenv, struct sieve_command *cmd) { - sieve_operation_emit_code(cgenv->sbin, &denotify_operation); + sieve_operation_emit(cgenv->sbin, cmd->ext, &denotify_operation); /* Emit source line */ - sieve_code_source_line_emit(cgenv->sbin, sieve_command_source_line(ctx)); + sieve_code_source_line_emit(cgenv->sbin, sieve_command_source_line(cmd)); /* Generate arguments */ - return sieve_generate_arguments(cgenv, ctx, NULL); + return sieve_generate_arguments(cgenv, cmd, NULL); } /* @@ -182,12 +186,12 @@ static bool cmd_denotify_generate */ static bool cmd_denotify_operation_dump -(const struct sieve_operation *op ATTR_UNUSED, - const struct sieve_dumptime_env *denv, sieve_size_t *address) +(const struct sieve_dumptime_env *denv, sieve_size_t *address) { + const struct sieve_operation *op = &denv->oprtn; int opt_code = 1; - sieve_code_dumpf(denv, "%s", op->mnemonic); + sieve_code_dumpf(denv, "%s", sieve_operation_mnemonic(op)); sieve_code_descend(denv); /* Source line */ @@ -231,12 +235,14 @@ static bool cmd_denotify_operation_dump */ static int cmd_denotify_operation_execute -(const struct sieve_operation *op ATTR_UNUSED, - const struct sieve_runtime_env *renv, sieve_size_t *address) +(const struct sieve_runtime_env *renv, sieve_size_t *address) { int opt_code = 1; sieve_number_t importance = 1; - const struct sieve_match_type *match_type = NULL; + struct sieve_match_type mcht = + SIEVE_MATCH_TYPE_DEFAULT(is_match_type); +/* const struct sieve_comparator cmp = + SIEVE_COMPARATOR_DEFAULT(i_octet_comparator);*/ string_t *match_key = NULL; unsigned int source_line; @@ -262,7 +268,7 @@ static int cmd_denotify_operation_execute case 0: break; case OPT_MATCH_TYPE: - if ( (match_type = sieve_opr_match_type_read(renv, address)) == NULL ) { + if ( !sieve_opr_match_type_read(renv, address, &mcht) ) { sieve_runtime_trace_error(renv, "invalid match type operand"); return SIEVE_EXEC_BIN_CORRUPT; } diff --git a/src/lib-sieve/plugins/notify/cmd-notify.c b/src/lib-sieve/plugins/notify/cmd-notify.c index bb539a56e..1734476ab 100644 --- a/src/lib-sieve/plugins/notify/cmd-notify.c +++ b/src/lib-sieve/plugins/notify/cmd-notify.c @@ -39,17 +39,17 @@ */ static bool cmd_notify_registered - (struct sieve_validator *valdtr, + (struct sieve_validator *valdtr, const struct sieve_extension *ext, struct sieve_command_registration *cmd_reg); static bool cmd_notify_pre_validate - (struct sieve_validator *valdtr, struct sieve_command_context *cmd); + (struct sieve_validator *valdtr, struct sieve_command *cmd); static bool cmd_notify_validate - (struct sieve_validator *valdtr, struct sieve_command_context *cmd); + (struct sieve_validator *valdtr, struct sieve_command *cmd); static bool cmd_notify_generate (const struct sieve_codegen_env *cgenv, - struct sieve_command_context *ctx); + struct sieve_command *ctx); -const struct sieve_command cmd_notify_old = { +const struct sieve_command_def cmd_notify_old = { "notify", SCT_COMMAND, 0, 0, FALSE, FALSE, @@ -68,39 +68,39 @@ const struct sieve_command cmd_notify_old = { static bool cmd_notify_validate_string_tag (struct sieve_validator *valdtr, struct sieve_ast_argument **arg, - struct sieve_command_context *cmd); + struct sieve_command *cmd); static bool cmd_notify_validate_stringlist_tag (struct sieve_validator *valdtr, struct sieve_ast_argument **arg, - struct sieve_command_context *cmd); + struct sieve_command *cmd); /* Argument objects */ -static const struct sieve_argument notify_method_tag = { +static const struct sieve_argument_def notify_method_tag = { "method", - NULL, NULL, + NULL, cmd_notify_validate_string_tag, - NULL, NULL + NULL, NULL, NULL }; -static const struct sieve_argument notify_options_tag = { +static const struct sieve_argument_def notify_options_tag = { "options", - NULL, NULL, + NULL, cmd_notify_validate_stringlist_tag, - NULL, NULL + NULL, NULL, NULL }; -static const struct sieve_argument notify_id_tag = { +static const struct sieve_argument_def notify_id_tag = { "id", - NULL, NULL, + NULL, cmd_notify_validate_string_tag, - NULL, NULL + NULL, NULL, NULL }; -static const struct sieve_argument notify_message_tag = { +static const struct sieve_argument_def notify_message_tag = { "message", - NULL, NULL, + NULL, cmd_notify_validate_string_tag, - NULL, NULL + NULL, NULL, NULL }; /* @@ -108,13 +108,11 @@ static const struct sieve_argument notify_message_tag = { */ static bool cmd_notify_operation_dump - (const struct sieve_operation *op, - const struct sieve_dumptime_env *denv, sieve_size_t *address); + (const struct sieve_dumptime_env *denv, sieve_size_t *address); static int cmd_notify_operation_execute - (const struct sieve_operation *op, - const struct sieve_runtime_env *renv, sieve_size_t *address); + (const struct sieve_runtime_env *renv, sieve_size_t *address); -const struct sieve_operation notify_old_operation = { +const struct sieve_operation_def notify_old_operation = { "NOTIFY", ¬ify_extension, EXT_NOTIFY_OPERATION_NOTIFY, @@ -140,18 +138,18 @@ enum cmd_notify_optional { static int act_notify_check_duplicate (const struct sieve_runtime_env *renv, - const struct sieve_action_data *act, - const struct sieve_action_data *act_other); + const struct sieve_action *act, + const struct sieve_action *act_other); static void act_notify_print (const struct sieve_action *action, const struct sieve_result_print_env *rpenv, - void *context, bool *keep); + bool *keep); static bool act_notify_commit (const struct sieve_action *action, const struct sieve_action_exec_env *aenv, void *tr_context, bool *keep); /* Action object */ -const struct sieve_action act_notify_old = { +const struct sieve_action_def act_notify_old = { "notify", 0, NULL, @@ -180,7 +178,7 @@ struct cmd_notify_context_data { static bool cmd_notify_validate_string_tag (struct sieve_validator *valdtr, struct sieve_ast_argument **arg, - struct sieve_command_context *cmd) + struct sieve_command *cmd) { struct sieve_ast_argument *tag = *arg; struct cmd_notify_context_data *ctx_data = @@ -197,19 +195,19 @@ static bool cmd_notify_validate_string_tag if ( !sieve_validate_tag_parameter(valdtr, cmd, tag, *arg, SAAT_STRING) ) return FALSE; - if ( tag->argument == ¬ify_method_tag ) { + if ( sieve_argument_is(tag, notify_method_tag) ) { ctx_data->method = *arg; /* Removed */ *arg = sieve_ast_arguments_detach(*arg, 1); - } else if ( tag->argument == ¬ify_id_tag ) { + } else if ( sieve_argument_is(tag, notify_id_tag) ) { ctx_data->id = *arg; /* Skip parameter */ *arg = sieve_ast_argument_next(*arg); - } else if ( tag->argument == ¬ify_message_tag ) { + } else if ( sieve_argument_is(tag, notify_message_tag) ) { ctx_data->message = *arg; /* Skip parameter */ @@ -221,7 +219,7 @@ static bool cmd_notify_validate_string_tag static bool cmd_notify_validate_stringlist_tag (struct sieve_validator *valdtr, struct sieve_ast_argument **arg, - struct sieve_command_context *cmd) + struct sieve_command *cmd) { struct sieve_ast_argument *tag = *arg; struct cmd_notify_context_data *ctx_data = @@ -250,18 +248,19 @@ static bool cmd_notify_validate_stringlist_tag */ static bool cmd_notify_registered -(struct sieve_validator *valdtr, struct sieve_command_registration *cmd_reg) +(struct sieve_validator *valdtr, const struct sieve_extension *ext, + struct sieve_command_registration *cmd_reg) { sieve_validator_register_tag - (valdtr, cmd_reg, ¬ify_method_tag, 0); + (valdtr, cmd_reg, ext, ¬ify_method_tag, 0); sieve_validator_register_tag - (valdtr, cmd_reg, ¬ify_id_tag, OPT_ID); + (valdtr, cmd_reg, ext, ¬ify_id_tag, OPT_ID); sieve_validator_register_tag - (valdtr, cmd_reg, ¬ify_message_tag, OPT_MESSAGE); + (valdtr, cmd_reg, ext, ¬ify_message_tag, OPT_MESSAGE); sieve_validator_register_tag - (valdtr, cmd_reg, ¬ify_options_tag, OPT_OPTIONS); + (valdtr, cmd_reg, ext, ¬ify_options_tag, OPT_OPTIONS); - ext_notify_register_importance_tags(valdtr, cmd_reg, OPT_IMPORTANCE); + ext_notify_register_importance_tags(valdtr, cmd_reg, ext, OPT_IMPORTANCE); return TRUE; } @@ -272,7 +271,7 @@ static bool cmd_notify_registered static bool cmd_notify_pre_validate (struct sieve_validator *valdtr ATTR_UNUSED, - struct sieve_command_context *cmd) + struct sieve_command *cmd) { struct cmd_notify_context_data *ctx_data; @@ -311,7 +310,7 @@ static int cmd_notify_address_validate } static bool cmd_notify_validate -(struct sieve_validator *valdtr, struct sieve_command_context *cmd) +(struct sieve_validator *valdtr, struct sieve_command *cmd) { struct cmd_notify_context_data *ctx_data = (struct cmd_notify_context_data *) cmd->data; @@ -350,15 +349,15 @@ static bool cmd_notify_validate */ static bool cmd_notify_generate -(const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx) +(const struct sieve_codegen_env *cgenv, struct sieve_command *cmd) { - sieve_operation_emit_code(cgenv->sbin, ¬ify_old_operation); + sieve_operation_emit(cgenv->sbin, cmd->ext, ¬ify_old_operation); /* Emit source line */ - sieve_code_source_line_emit(cgenv->sbin, sieve_command_source_line(ctx)); + sieve_code_source_line_emit(cgenv->sbin, sieve_command_source_line(cmd)); /* Generate arguments */ - return sieve_generate_arguments(cgenv, ctx, NULL); + return sieve_generate_arguments(cgenv, cmd, NULL); } /* @@ -366,8 +365,7 @@ static bool cmd_notify_generate */ static bool cmd_notify_operation_dump -(const struct sieve_operation *op ATTR_UNUSED, - const struct sieve_dumptime_env *denv, sieve_size_t *address) +(const struct sieve_dumptime_env *denv, sieve_size_t *address) { int opt_code = 1; @@ -420,9 +418,9 @@ static bool cmd_notify_operation_dump static int cmd_notify_operation_execute -(const struct sieve_operation *op ATTR_UNUSED, - const struct sieve_runtime_env *renv, sieve_size_t *address) +(const struct sieve_runtime_env *renv, sieve_size_t *address) { + const struct sieve_extension *this_ext = renv->oprtn.ext; struct ext_notify_action *act; pool_t pool; int opt_code = 1; @@ -582,7 +580,8 @@ static int cmd_notify_operation_execute } return ( sieve_result_add_action - (renv, &act_notify_old, NULL, source_line, (void *) act, 0) >= 0 ); + (renv, this_ext, &act_notify_old, NULL, source_line, (void *) act, 0) + >= 0 ); } return SIEVE_EXEC_OK; @@ -596,8 +595,8 @@ static int cmd_notify_operation_execute static int act_notify_check_duplicate (const struct sieve_runtime_env *renv ATTR_UNUSED, - const struct sieve_action_data *act ATTR_UNUSED, - const struct sieve_action_data *act_other ATTR_UNUSED) + const struct sieve_action *act ATTR_UNUSED, + const struct sieve_action *act_other ATTR_UNUSED) { struct ext_notify_action *new_nact, *old_nact; const struct ext_notify_recipient *new_rcpts; @@ -652,12 +651,11 @@ static int act_notify_check_duplicate /* Result printing */ static void act_notify_print -(const struct sieve_action *action ATTR_UNUSED, - const struct sieve_result_print_env *rpenv, void *context, +(const struct sieve_action *action, const struct sieve_result_print_env *rpenv, bool *keep ATTR_UNUSED) { const struct ext_notify_action *act = - (const struct ext_notify_action *) context; + (const struct ext_notify_action *) action->context; const struct ext_notify_recipient *recipients; unsigned int count, i; @@ -806,12 +804,11 @@ static bool act_notify_send } static bool act_notify_commit -(const struct sieve_action *action ATTR_UNUSED, - const struct sieve_action_exec_env *aenv, void *tr_context, - bool *keep ATTR_UNUSED) +(const struct sieve_action *action, const struct sieve_action_exec_env *aenv, + void *tr_context ATTR_UNUSED, bool *keep ATTR_UNUSED) { const struct ext_notify_action *act = - (const struct ext_notify_action *) tr_context; + (const struct ext_notify_action *) action->context; const struct sieve_message_data *msgdata = aenv->msgdata; const char *const *headers; diff --git a/src/lib-sieve/plugins/notify/ext-notify-common.c b/src/lib-sieve/plugins/notify/ext-notify-common.c index b4d48c7c8..c2c6e8f6b 100644 --- a/src/lib-sieve/plugins/notify/ext-notify-common.c +++ b/src/lib-sieve/plugins/notify/ext-notify-common.c @@ -29,43 +29,44 @@ static bool tag_importance_validate (struct sieve_validator *valdtr, struct sieve_ast_argument **arg, - struct sieve_command_context *cmd); + struct sieve_command *cmd); -static const struct sieve_argument importance_low_tag = { +static const struct sieve_argument_def importance_low_tag = { "low", - NULL, NULL, + NULL, tag_importance_validate, - NULL, NULL + NULL, NULL, NULL }; -static const struct sieve_argument importance_normal_tag = { +static const struct sieve_argument_def importance_normal_tag = { "normal", - NULL, NULL, + NULL, tag_importance_validate, - NULL, NULL + NULL, NULL, NULL }; -static const struct sieve_argument importance_high_tag = { +static const struct sieve_argument_def importance_high_tag = { "high", - NULL, NULL, + NULL, tag_importance_validate, - NULL, NULL + NULL, NULL, NULL }; static bool tag_importance_validate (struct sieve_validator *valdtr ATTR_UNUSED, struct sieve_ast_argument **arg, - struct sieve_command_context *cmd ATTR_UNUSED) + struct sieve_command *cmd ATTR_UNUSED) { struct sieve_ast_argument *tag = *arg; - if ( tag->argument == &importance_low_tag ) + if ( sieve_argument_is(tag, importance_low_tag) ) sieve_ast_argument_number_substitute(tag, 3); - else if ( tag->argument == &importance_normal_tag ) + else if ( sieve_argument_is(tag, importance_normal_tag) ) sieve_ast_argument_number_substitute(tag, 2); else sieve_ast_argument_number_substitute(tag, 1); - tag->argument = &number_argument; + tag->argument = sieve_argument_create + (tag->ast, &number_argument, tag->argument->ext, tag->argument->id_code); /* Skip parameter */ *arg = sieve_ast_argument_next(*arg); @@ -74,12 +75,12 @@ static bool tag_importance_validate } void ext_notify_register_importance_tags -(struct sieve_validator *valdtr, struct sieve_command_registration *cmd_reg, - unsigned int id_code) +(struct sieve_validator *valdtr, struct sieve_command_registration *cmd_reg, + const struct sieve_extension *ext, unsigned int id_code) { - sieve_validator_register_tag(valdtr, cmd_reg, &importance_low_tag, id_code); - sieve_validator_register_tag(valdtr, cmd_reg, &importance_normal_tag, id_code); - sieve_validator_register_tag(valdtr, cmd_reg, &importance_high_tag, id_code); + sieve_validator_register_tag(valdtr, cmd_reg, ext, &importance_low_tag, id_code); + sieve_validator_register_tag(valdtr, cmd_reg, ext, &importance_normal_tag, id_code); + sieve_validator_register_tag(valdtr, cmd_reg, ext, &importance_high_tag, id_code); } /* @@ -94,13 +95,13 @@ struct ext_notify_message_context { }; static struct ext_notify_message_context *ext_notify_get_message_context -(struct sieve_message_context *msgctx) +(const struct sieve_extension *this_ext, struct sieve_message_context *msgctx) { struct ext_notify_message_context *ctx; /* Get message context (contains cached message body information) */ ctx = (struct ext_notify_message_context *) - sieve_message_context_extension_get(msgctx, ¬ify_extension); + sieve_message_context_extension_get(msgctx, this_ext); /* Create it if it does not exist already */ if ( ctx == NULL ) { @@ -111,7 +112,7 @@ static struct ext_notify_message_context *ext_notify_get_message_context /* Register context */ sieve_message_context_extension_set - (msgctx, ¬ify_extension, (void *) ctx); + (msgctx, this_ext, (void *) ctx); } return ctx; @@ -149,6 +150,7 @@ static bool _is_text_content(const struct message_header_line *hdr) static buffer_t *cmd_notify_extract_body_text (const struct sieve_runtime_env *renv) { + const struct sieve_extension *this_ext = renv->oprtn.ext; struct ext_notify_message_context *mctx; struct message_parser_ctx *parser; struct message_decoder_context *decoder; @@ -159,7 +161,7 @@ static buffer_t *cmd_notify_extract_body_text int ret; /* Return cached result if available */ - mctx = ext_notify_get_message_context(renv->msgctx); + mctx = ext_notify_get_message_context(this_ext, renv->msgctx); if ( mctx->body_text != NULL ) { return mctx->body_text; } diff --git a/src/lib-sieve/plugins/notify/ext-notify-common.h b/src/lib-sieve/plugins/notify/ext-notify-common.h index 146d7c6d9..87deb188d 100644 --- a/src/lib-sieve/plugins/notify/ext-notify-common.h +++ b/src/lib-sieve/plugins/notify/ext-notify-common.h @@ -8,14 +8,14 @@ * Extension */ -extern const struct sieve_extension notify_extension; +extern const struct sieve_extension_def notify_extension; /* * Commands */ -extern const struct sieve_command cmd_notify_old; -extern const struct sieve_command cmd_denotify; +extern const struct sieve_command_def cmd_notify_old; +extern const struct sieve_command_def cmd_denotify; /* * Arguments @@ -23,14 +23,14 @@ extern const struct sieve_command cmd_denotify; void ext_notify_register_importance_tags (struct sieve_validator *valdtr, struct sieve_command_registration *cmd_reg, - unsigned int id_code); + const struct sieve_extension *this_ext, unsigned int id_code); /* * Operations */ -extern const struct sieve_operation notify_old_operation; -extern const struct sieve_operation denotify_operation; +extern const struct sieve_operation_def notify_old_operation; +extern const struct sieve_operation_def denotify_operation; enum ext_notify_opcode { EXT_NOTIFY_OPERATION_NOTIFY, diff --git a/src/lib-sieve/plugins/notify/ext-notify.c b/src/lib-sieve/plugins/notify/ext-notify.c index 749062a3f..1fd110f5f 100644 --- a/src/lib-sieve/plugins/notify/ext-notify.c +++ b/src/lib-sieve/plugins/notify/ext-notify.c @@ -35,7 +35,7 @@ * Operations */ -const struct sieve_operation *ext_notify_operations[] = { +const struct sieve_operation_def *ext_notify_operations[] = { ¬ify_old_operation, &denotify_operation }; @@ -44,13 +44,11 @@ const struct sieve_operation *ext_notify_operations[] = { * Extension */ -static bool ext_notify_validator_load(struct sieve_validator *valdtr); +static bool ext_notify_validator_load + (const struct sieve_extension *ext, struct sieve_validator *valdtr); -static int ext_notify_my_id = -1; - -const struct sieve_extension notify_extension = { +const struct sieve_extension_def notify_extension = { "notify", - &ext_notify_my_id, NULL, NULL, ext_notify_validator_load, @@ -64,8 +62,8 @@ const struct sieve_extension notify_extension = { */ static bool ext_notify_validator_extension_validate - (struct sieve_validator *valdtr, void *context, - struct sieve_ast_argument *require_arg); + (const struct sieve_extension *ext, struct sieve_validator *valdtr, + void *context, struct sieve_ast_argument *require_arg); const struct sieve_validator_extension notify_validator_extension = { ¬ify_extension, @@ -73,29 +71,30 @@ const struct sieve_validator_extension notify_validator_extension = { NULL }; -static bool ext_notify_validator_load(struct sieve_validator *valdtr) +static bool ext_notify_validator_load +(const struct sieve_extension *ext, struct sieve_validator *valdtr) { /* Register validator extension to check for conflict with enotify */ sieve_validator_extension_register - (valdtr, ¬ify_validator_extension, NULL); + (valdtr, ext, ¬ify_validator_extension, NULL); /* Register new commands */ - sieve_validator_register_command(valdtr, &cmd_notify_old); - sieve_validator_register_command(valdtr, &cmd_denotify); + sieve_validator_register_command(valdtr, ext, &cmd_notify_old); + sieve_validator_register_command(valdtr, ext, &cmd_denotify); return TRUE; } static bool ext_notify_validator_extension_validate -(struct sieve_validator *valdtr, void *context ATTR_UNUSED, - struct sieve_ast_argument *require_arg) +(const struct sieve_extension *ext, struct sieve_validator *valdtr, + void *context ATTR_UNUSED, struct sieve_ast_argument *require_arg) { - const struct sieve_extension *ext; + const struct sieve_extension *ext_entfy; - if ( (ext=sieve_extension_get_by_name("enotify")) != NULL ) { + if ( (ext_entfy=sieve_extension_get_by_name(ext->svinst, "enotify")) != NULL ) { /* Check for conflict with enotify */ - if ( sieve_validator_extension_loaded(valdtr, ext) ) { + if ( sieve_validator_extension_loaded(valdtr, ext_entfy) ) { sieve_argument_validate_error(valdtr, require_arg, "the (deprecated) notify extension cannot be used " "together with the enotify extension"); diff --git a/src/lib-sieve/plugins/regex/ext-regex-common.c b/src/lib-sieve/plugins/regex/ext-regex-common.c index a1aa90ebd..f340a9a02 100644 --- a/src/lib-sieve/plugins/regex/ext-regex-common.c +++ b/src/lib-sieve/plugins/regex/ext-regex-common.c @@ -13,7 +13,7 @@ static const struct sieve_extension_objects ext_match_types = SIEVE_EXT_DEFINE_MATCH_TYPE(regex_match_type); -const struct sieve_operand regex_match_type_operand = { +const struct sieve_operand_def regex_match_type_operand = { "regex match", ®ex_extension, 0, diff --git a/src/lib-sieve/plugins/regex/ext-regex-common.h b/src/lib-sieve/plugins/regex/ext-regex-common.h index 42462a7aa..4a8d62806 100644 --- a/src/lib-sieve/plugins/regex/ext-regex-common.h +++ b/src/lib-sieve/plugins/regex/ext-regex-common.h @@ -8,19 +8,19 @@ * Extension */ -extern const struct sieve_extension regex_extension; +extern const struct sieve_extension_def regex_extension; /* * Operand */ -extern const struct sieve_operand regex_match_type_operand; +extern const struct sieve_operand_def regex_match_type_operand; /* * Match type */ -extern const struct sieve_match_type regex_match_type; +extern const struct sieve_match_type_def regex_match_type; #endif /* __EXT_REGEX_COMMON_H */ diff --git a/src/lib-sieve/plugins/regex/ext-regex.c b/src/lib-sieve/plugins/regex/ext-regex.c index 5686a8039..4e0a570be 100644 --- a/src/lib-sieve/plugins/regex/ext-regex.c +++ b/src/lib-sieve/plugins/regex/ext-regex.c @@ -43,13 +43,11 @@ * Extension */ -static bool ext_regex_validator_load(struct sieve_validator *validator); +static bool ext_regex_validator_load + (const struct sieve_extension *ext, struct sieve_validator *validator); -static int ext_my_id = -1; - -const struct sieve_extension regex_extension = { +const struct sieve_extension_def regex_extension = { "regex", - &ext_my_id, NULL, NULL, ext_regex_validator_load, NULL, NULL, NULL, NULL, NULL, @@ -57,9 +55,10 @@ const struct sieve_extension regex_extension = { SIEVE_EXT_DEFINE_OPERAND(regex_match_type_operand) }; -static bool ext_regex_validator_load(struct sieve_validator *validator) +static bool ext_regex_validator_load +(const struct sieve_extension *ext, struct sieve_validator *valdtr) { - sieve_match_type_register(validator, ®ex_match_type); + sieve_match_type_register(valdtr, ext, ®ex_match_type); return TRUE; } diff --git a/src/lib-sieve/plugins/regex/mcht-regex.c b/src/lib-sieve/plugins/regex/mcht-regex.c index 8a06ef0cb..927750288 100644 --- a/src/lib-sieve/plugins/regex/mcht-regex.c +++ b/src/lib-sieve/plugins/regex/mcht-regex.c @@ -35,8 +35,8 @@ * Match type */ -bool mcht_regex_validate_context -(struct sieve_validator *validator, struct sieve_ast_argument *arg, +static bool mcht_regex_validate_context +(struct sieve_validator *valdtr, struct sieve_ast_argument *arg, struct sieve_match_type_context *ctx, struct sieve_ast_argument *key_arg); static void mcht_regex_match_init(struct sieve_match_context *mctx); @@ -45,7 +45,7 @@ static int mcht_regex_match const char *key, size_t key_size, int key_index); static int mcht_regex_match_deinit(struct sieve_match_context *mctx); -const struct sieve_match_type regex_match_type = { +const struct sieve_match_type_def regex_match_type = { SIEVE_OBJECT("regex", ®ex_match_type_operand, 0), TRUE, FALSE, NULL, @@ -85,15 +85,15 @@ static const char *_regexp_error(regex_t *regexp, int errorcode) } static int mcht_regex_validate_regexp -(struct sieve_validator *validator, - struct sieve_match_type_context *ctx ATTR_UNUSED, +(struct sieve_validator *valdtr, + struct sieve_match_type_context *mtctx ATTR_UNUSED, struct sieve_ast_argument *key, int cflags) { int ret; regex_t regexp; if ( (ret=regcomp(®exp, sieve_ast_argument_strc(key), cflags)) != 0 ) { - sieve_argument_validate_error(validator, key, + sieve_argument_validate_error(valdtr, key, "invalid regular expression for regex match: %s", _regexp_error(®exp, ret)); @@ -107,7 +107,7 @@ static int mcht_regex_validate_regexp struct _regex_key_context { struct sieve_validator *valdtr; - struct sieve_match_type_context *mctx; + struct sieve_match_type_context *mtctx; int cflags; }; @@ -127,25 +127,25 @@ static int mcht_regex_validate_key_argument } return mcht_regex_validate_regexp - (keyctx->valdtr, keyctx->mctx, key, keyctx->cflags); + (keyctx->valdtr, keyctx->mtctx, key, keyctx->cflags); } -bool mcht_regex_validate_context -(struct sieve_validator *validator, struct sieve_ast_argument *arg ATTR_UNUSED, - struct sieve_match_type_context *ctx, struct sieve_ast_argument *key_arg) +static bool mcht_regex_validate_context +(struct sieve_validator *valdtr, struct sieve_ast_argument *arg ATTR_UNUSED, + struct sieve_match_type_context *mtctx, struct sieve_ast_argument *key_arg) { - const struct sieve_comparator *cmp = ctx->comparator; + const struct sieve_comparator *cmp = mtctx->comparator; int cflags = REG_EXTENDED | REG_NOSUB; struct _regex_key_context keyctx; struct sieve_ast_argument *kitem; if ( cmp != NULL ) { - if ( cmp == &i_ascii_casemap_comparator ) + if ( sieve_comparator_is(cmp, i_ascii_casemap_comparator) ) cflags = REG_EXTENDED | REG_NOSUB | REG_ICASE; - else if ( cmp == &i_octet_comparator ) + else if ( sieve_comparator_is(cmp, i_octet_comparator) ) cflags = REG_EXTENDED | REG_NOSUB; else { - sieve_argument_validate_error(validator, ctx->match_type_arg, + sieve_argument_validate_error(valdtr, mtctx->argument, "regex match type only supports " "i;octet and i;ascii-casemap comparators" ); return FALSE; @@ -154,8 +154,8 @@ bool mcht_regex_validate_context /* Validate regular expression keys */ - keyctx.valdtr = validator; - keyctx.mctx = ctx; + keyctx.valdtr = valdtr; + keyctx.mtctx = mtctx; keyctx.cflags = cflags; kitem = key_arg; @@ -219,9 +219,9 @@ static regex_t *mcht_regex_get regexp = array_idx_modifiable(&ctx->reg_expressions, key_index); /* Configure case-sensitivity according to comparator */ - if ( cmp == &i_octet_comparator ) + if ( sieve_comparator_is(cmp, i_octet_comparator) ) cflags = REG_EXTENDED; - else if ( cmp == &i_ascii_casemap_comparator ) + else if ( sieve_comparator_is(cmp, i_ascii_casemap_comparator) ) cflags = REG_EXTENDED | REG_ICASE; else return NULL; /* Not supported */ diff --git a/src/lib-sieve/plugins/relational/ext-relational-common.c b/src/lib-sieve/plugins/relational/ext-relational-common.c index da7d65d7e..ddf0a243a 100644 --- a/src/lib-sieve/plugins/relational/ext-relational-common.c +++ b/src/lib-sieve/plugins/relational/ext-relational-common.c @@ -30,16 +30,17 @@ * Forward declarations */ -const struct sieve_match_type *rel_match_types[]; +const struct sieve_match_type_def *rel_match_types[]; /* * Validation */ bool mcht_relational_validate -(struct sieve_validator *validator, struct sieve_ast_argument **arg, +(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, struct sieve_match_type_context *ctx) { + struct sieve_match_type *mcht; enum relational_match rel_match = REL_MATCH_INVALID; string_t *rel_match_ident; @@ -52,11 +53,11 @@ bool mcht_relational_validate /* Did we get a string in the first place ? */ if ( (*arg)->type != SAAT_STRING ) { - sieve_argument_validate_error(validator, *arg, + sieve_argument_validate_error(valdtr, *arg, "the :%s match-type requires a constant string argument being " "one of \"gt\", \"ge\", \"lt\", \"le\", \"eq\" or \"ne\", " "but %s was found", - ctx->match_type->object.identifier, sieve_ast_argument_name(*arg)); + sieve_match_type_name(ctx->match_type), sieve_ast_argument_name(*arg)); return FALSE; } @@ -114,11 +115,11 @@ bool mcht_relational_validate } if ( rel_match >= REL_MATCH_INVALID ) { - sieve_argument_validate_error(validator, *arg, + sieve_argument_validate_error(valdtr, *arg, "the :%s match-type requires a constant string argument being " "one of \"gt\", \"ge\", \"lt\", \"le\", \"eq\" or \"ne\", " "but \"%s\" was found", - ctx->match_type->object.identifier, + sieve_match_type_name(ctx->match_type), str_sanitize(str_c(rel_match_ident), 32)); return FALSE; } @@ -129,9 +130,14 @@ bool mcht_relational_validate /* Not used just yet */ ctx->ctx_data = (void *) rel_match; - /* Override the actual match type with a parameter-specific one */ - ctx->match_type = rel_match_types - [REL_MATCH_INDEX(ctx->match_type->object.code, rel_match)]; + /* Override the actual match type with a parameter-specific one + * FIXME: ugly! + */ + mcht = p_new(sieve_ast_argument_pool(*arg), struct sieve_match_type, 1); + mcht->object.ext = ctx->match_type->object.ext; + SIEVE_OBJECT_SET_DEF(mcht, rel_match_types + [REL_MATCH_INDEX(ctx->match_type->object.def->code, rel_match)]); + ctx->match_type = mcht; return TRUE; } @@ -140,7 +146,7 @@ bool mcht_relational_validate * Relational match-type operand */ -const const struct sieve_match_type *rel_match_types[] = { +const const struct sieve_match_type_def *rel_match_types[] = { &rel_match_value_gt, &rel_match_value_ge, &rel_match_value_lt, &rel_match_value_le, &rel_match_value_eq, &rel_match_value_ne, &rel_match_count_gt, &rel_match_count_ge, &rel_match_count_lt, @@ -150,7 +156,7 @@ const const struct sieve_match_type *rel_match_types[] = { static const struct sieve_extension_objects ext_match_types = SIEVE_EXT_DEFINE_MATCH_TYPES(rel_match_types); -const struct sieve_operand rel_match_type_operand = { +const struct sieve_operand_def rel_match_type_operand = { "relational match", &relational_extension, 0, diff --git a/src/lib-sieve/plugins/relational/ext-relational-common.h b/src/lib-sieve/plugins/relational/ext-relational-common.h index 595726a41..8a7b41d16 100644 --- a/src/lib-sieve/plugins/relational/ext-relational-common.h +++ b/src/lib-sieve/plugins/relational/ext-relational-common.h @@ -39,10 +39,7 @@ enum relational_match { * Extension definitions */ -extern int ext_relational_my_id; - -extern const struct sieve_extension relational_extension; -extern const struct sieve_match_type_extension relational_match_extension; +extern const struct sieve_extension_def relational_extension; /* * Match types @@ -50,30 +47,30 @@ extern const struct sieve_match_type_extension relational_match_extension; /* Registered for validation */ -extern const struct sieve_match_type value_match_type; -extern const struct sieve_match_type count_match_type; +extern const struct sieve_match_type_def value_match_type; +extern const struct sieve_match_type_def count_match_type; /* Used in byte code */ -extern const struct sieve_match_type rel_match_count_gt; -extern const struct sieve_match_type rel_match_count_ge; -extern const struct sieve_match_type rel_match_count_lt; -extern const struct sieve_match_type rel_match_count_le; -extern const struct sieve_match_type rel_match_count_eq; -extern const struct sieve_match_type rel_match_count_ne; +extern const struct sieve_match_type_def rel_match_count_gt; +extern const struct sieve_match_type_def rel_match_count_ge; +extern const struct sieve_match_type_def rel_match_count_lt; +extern const struct sieve_match_type_def rel_match_count_le; +extern const struct sieve_match_type_def rel_match_count_eq; +extern const struct sieve_match_type_def rel_match_count_ne; -extern const struct sieve_match_type rel_match_value_gt; -extern const struct sieve_match_type rel_match_value_ge; -extern const struct sieve_match_type rel_match_value_lt; -extern const struct sieve_match_type rel_match_value_le; -extern const struct sieve_match_type rel_match_value_eq; -extern const struct sieve_match_type rel_match_value_ne; +extern const struct sieve_match_type_def rel_match_value_gt; +extern const struct sieve_match_type_def rel_match_value_ge; +extern const struct sieve_match_type_def rel_match_value_lt; +extern const struct sieve_match_type_def rel_match_value_le; +extern const struct sieve_match_type_def rel_match_value_eq; +extern const struct sieve_match_type_def rel_match_value_ne; /* * Operand */ -extern const struct sieve_operand rel_match_type_operand; +extern const struct sieve_operand_def rel_match_type_operand; /* diff --git a/src/lib-sieve/plugins/relational/ext-relational.c b/src/lib-sieve/plugins/relational/ext-relational.c index b30bf1047..e2284a9c7 100644 --- a/src/lib-sieve/plugins/relational/ext-relational.c +++ b/src/lib-sieve/plugins/relational/ext-relational.c @@ -32,13 +32,11 @@ * Extension */ -static bool ext_relational_validator_load(struct sieve_validator *validator); +static bool ext_relational_validator_load +(const struct sieve_extension *ext, struct sieve_validator *valdtr); -int ext_relational_my_id = -1; - -const struct sieve_extension relational_extension = { +const struct sieve_extension_def relational_extension = { "relational", - &ext_relational_my_id, NULL, NULL, ext_relational_validator_load, NULL, NULL, NULL, NULL, NULL, @@ -46,10 +44,11 @@ const struct sieve_extension relational_extension = { SIEVE_EXT_DEFINE_OPERAND(rel_match_type_operand) }; -static bool ext_relational_validator_load(struct sieve_validator *validator) +static bool ext_relational_validator_load +(const struct sieve_extension *ext, struct sieve_validator *valdtr) { - sieve_match_type_register(validator, &value_match_type); - sieve_match_type_register(validator, &count_match_type); + sieve_match_type_register(valdtr, ext, &value_match_type); + sieve_match_type_register(valdtr, ext, &count_match_type); return TRUE; } diff --git a/src/lib-sieve/plugins/relational/mcht-count.c b/src/lib-sieve/plugins/relational/mcht-count.c index 61e44776d..923757a72 100644 --- a/src/lib-sieve/plugins/relational/mcht-count.c +++ b/src/lib-sieve/plugins/relational/mcht-count.c @@ -35,7 +35,7 @@ static int mcht_count_match_deinit(struct sieve_match_context *mctx); * Match-type objects */ -const struct sieve_match_type count_match_type = { +const struct sieve_match_type_def count_match_type = { SIEVE_OBJECT("count", &rel_match_type_operand, RELATIONAL_COUNT), FALSE, FALSE, mcht_relational_validate, @@ -43,7 +43,7 @@ const struct sieve_match_type count_match_type = { }; #define COUNT_MATCH_TYPE(name, rel_match) \ -const struct sieve_match_type rel_match_count_ ## name = { \ +const struct sieve_match_type_def rel_match_count_ ## name = { \ SIEVE_OBJECT( \ "count-" #name, &rel_match_type_operand, \ REL_MATCH_INDEX(RELATIONAL_COUNT, rel_match)), \ diff --git a/src/lib-sieve/plugins/relational/mcht-value.c b/src/lib-sieve/plugins/relational/mcht-value.c index 865e8a61c..6d2829fa8 100644 --- a/src/lib-sieve/plugins/relational/mcht-value.c +++ b/src/lib-sieve/plugins/relational/mcht-value.c @@ -23,7 +23,7 @@ * Match-type objects */ -const struct sieve_match_type value_match_type = { +const struct sieve_match_type_def value_match_type = { SIEVE_OBJECT("value", &rel_match_type_operand, RELATIONAL_VALUE), TRUE, TRUE, mcht_relational_validate, @@ -31,7 +31,7 @@ const struct sieve_match_type value_match_type = { }; #define VALUE_MATCH_TYPE(name, rel_match) \ -const struct sieve_match_type rel_match_value_ ## name = { \ +const struct sieve_match_type_def rel_match_value_ ## name = { \ SIEVE_OBJECT( \ "value-" #name, &rel_match_type_operand, \ REL_MATCH_INDEX(RELATIONAL_VALUE, rel_match)), \ @@ -57,7 +57,7 @@ int mcht_value_match const char *key, size_t key_size, int key_index ATTR_UNUSED) { const struct sieve_match_type *mtch = mctx->match_type; - unsigned int rel_match = REL_MATCH(mtch->object.code); + unsigned int rel_match = REL_MATCH(mtch->object.def->code); int cmp_result; if ( val == NULL ) { @@ -65,7 +65,7 @@ int mcht_value_match val_size = 0; } - cmp_result = mctx->comparator-> + cmp_result = mctx->comparator->def-> compare(mctx->comparator, val, val_size, key, key_size); switch ( rel_match ) { diff --git a/src/lib-sieve/plugins/subaddress/ext-subaddress.c b/src/lib-sieve/plugins/subaddress/ext-subaddress.c index 094ee567d..fe7e8a09b 100644 --- a/src/lib-sieve/plugins/subaddress/ext-subaddress.c +++ b/src/lib-sieve/plugins/subaddress/ext-subaddress.c @@ -6,11 +6,8 @@ * * Author: Stephan Bosch * Specification: RFC 3598 - * Implementation: full, but not configurable - * Status: experimental, largely untested - * - * FIXME: This extension is not configurable in any way. The separation - * character is currently only configurable for compilation and not at runtime. + * Implementation: full, but not fully configurable + * Status: experimental * */ @@ -35,51 +32,72 @@ #define SUBADDRESS_DEFAULT_SEP "+" -static const char *sieve_subaddress_sep = SUBADDRESS_DEFAULT_SEP; +struct ext_subaddress_config { + char *separator; +}; /* * Forward declarations */ -const struct sieve_address_part user_address_part; -const struct sieve_address_part detail_address_part; +const struct sieve_address_part_def user_address_part; +const struct sieve_address_part_def detail_address_part; -static struct sieve_operand subaddress_operand; +static struct sieve_operand_def subaddress_operand; /* * Extension */ -static bool ext_subaddress_load(void); -static bool ext_subaddress_validator_load(struct sieve_validator *validator); - -static int ext_my_id = -1; +static bool ext_subaddress_load + (const struct sieve_extension *ext, void **context); +static bool ext_subaddress_unload + (const struct sieve_extension *ext); +static bool ext_subaddress_validator_load + (const struct sieve_extension *ext, struct sieve_validator *validator); -const struct sieve_extension subaddress_extension = { +const struct sieve_extension_def subaddress_extension = { "subaddress", - &ext_my_id, ext_subaddress_load, - NULL, + ext_subaddress_unload, ext_subaddress_validator_load, NULL, NULL, NULL, NULL, NULL, SIEVE_EXT_DEFINE_NO_OPERATIONS, SIEVE_EXT_DEFINE_OPERAND(subaddress_operand) }; -static bool ext_subaddress_load(void) +static bool ext_subaddress_load +(const struct sieve_extension *ext, void **context) { - sieve_subaddress_sep = sieve_setting_get_ext(&subaddress_extension, "sep"); + struct ext_subaddress_config *config; + const char *sep = getenv("SIEVE_SUBADDRESS_SEP"); + + if ( sep == NULL ) + sep = SUBADDRESS_DEFAULT_SEP; - if ( sieve_subaddress_sep == NULL ) - sieve_subaddress_sep = SUBADDRESS_DEFAULT_SEP; + config = i_new(struct ext_subaddress_config, 1); + config->separator = i_strdup(sep); + + *context = (void *) config; return TRUE; } -static bool ext_subaddress_validator_load(struct sieve_validator *validator) +static bool ext_subaddress_unload +(const struct sieve_extension *ext) { - sieve_address_part_register(validator, &user_address_part); - sieve_address_part_register(validator, &detail_address_part); + struct ext_subaddress_config *config = + (struct ext_subaddress_config *) ext->context; + + i_free(config->separator); + i_free(config); +} + +static bool ext_subaddress_validator_load +(const struct sieve_extension *ext, struct sieve_validator *validator) +{ + sieve_address_part_register(validator, ext, &user_address_part); + sieve_address_part_register(validator, ext, &detail_address_part); return TRUE; } @@ -96,19 +114,18 @@ enum ext_subaddress_address_part { /* Forward declarations */ static const char *subaddress_user_extract_from - (const struct sieve_address *address); + (const struct sieve_address_part *addrp, const struct sieve_address *address); static const char *subaddress_detail_extract_from - (const struct sieve_address *address); - + (const struct sieve_address_part *addrp, const struct sieve_address *address); /* Address part objects */ -const struct sieve_address_part user_address_part = { +const struct sieve_address_part_def user_address_part = { SIEVE_OBJECT("user", &subaddress_operand, SUBADDRESS_USER), subaddress_user_extract_from }; -const struct sieve_address_part detail_address_part = { +const struct sieve_address_part_def detail_address_part = { SIEVE_OBJECT("detail", &subaddress_operand, SUBADDRESS_DETAIL), subaddress_detail_extract_from }; @@ -116,11 +133,13 @@ const struct sieve_address_part detail_address_part = { /* Address part implementation */ static const char *subaddress_user_extract_from - (const struct sieve_address *address) +(const struct sieve_address_part *addrp, const struct sieve_address *address) { + struct ext_subaddress_config *config = + (struct ext_subaddress_config *) addrp->object.ext->context; const char *sep; - sep = strstr(address->local_part, sieve_subaddress_sep); + sep = strstr(address->local_part, config->separator); if ( sep == NULL ) return address->local_part; @@ -128,14 +147,16 @@ static const char *subaddress_user_extract_from } static const char *subaddress_detail_extract_from - (const struct sieve_address *address) +(const struct sieve_address_part *addrp, const struct sieve_address *address) { + struct ext_subaddress_config *config = + (struct ext_subaddress_config *) addrp->object.ext->context; const char *sep; - if ( (sep=strstr(address->local_part, sieve_subaddress_sep)) == NULL ) + if ( (sep=strstr(address->local_part, config->separator)) == NULL ) return NULL; - sep += strlen(sieve_subaddress_sep); + sep += strlen(config->separator); /* Just to be sure */ if ( sep > (address->local_part + strlen(address->local_part)) ) @@ -148,14 +169,14 @@ static const char *subaddress_detail_extract_from * Operand */ -const struct sieve_address_part *ext_subaddress_parts[] = { +const struct sieve_address_part_def *ext_subaddress_parts[] = { &user_address_part, &detail_address_part }; static const struct sieve_extension_objects ext_address_parts = SIEVE_EXT_DEFINE_ADDRESS_PARTS(ext_subaddress_parts); -static struct sieve_operand subaddress_operand = { +static struct sieve_operand_def subaddress_operand = { "address-part", &subaddress_extension, 0, &sieve_address_part_operand_class, diff --git a/src/lib-sieve/plugins/vacation/cmd-vacation.c b/src/lib-sieve/plugins/vacation/cmd-vacation.c index 08080a435..e0962d466 100644 --- a/src/lib-sieve/plugins/vacation/cmd-vacation.c +++ b/src/lib-sieve/plugins/vacation/cmd-vacation.c @@ -35,12 +35,12 @@ * Forward declarations */ -static const struct sieve_argument vacation_days_tag; -static const struct sieve_argument vacation_subject_tag; -static const struct sieve_argument vacation_from_tag; -static const struct sieve_argument vacation_addresses_tag; -static const struct sieve_argument vacation_mime_tag; -static const struct sieve_argument vacation_handle_tag; +static const struct sieve_argument_def vacation_days_tag; +static const struct sieve_argument_def vacation_subject_tag; +static const struct sieve_argument_def vacation_from_tag; +static const struct sieve_argument_def vacation_addresses_tag; +static const struct sieve_argument_def vacation_mime_tag; +static const struct sieve_argument_def vacation_handle_tag; /* * Vacation command @@ -52,16 +52,16 @@ static const struct sieve_argument vacation_handle_tag; */ static bool cmd_vacation_registered - (struct sieve_validator *validator, + (struct sieve_validator *valdtr, const struct sieve_extension *ext, struct sieve_command_registration *cmd_reg); static bool cmd_vacation_pre_validate - (struct sieve_validator *validator, struct sieve_command_context *cmd); + (struct sieve_validator *valdtr, struct sieve_command *cmd); static bool cmd_vacation_validate - (struct sieve_validator *validator, struct sieve_command_context *cmd); + (struct sieve_validator *valdtr, struct sieve_command *cmd); static bool cmd_vacation_generate - (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx); + (const struct sieve_codegen_env *cgenv, struct sieve_command *cmd); -const struct sieve_command vacation_command = { +const struct sieve_command_def vacation_command = { "vacation", SCT_COMMAND, 1, 0, FALSE, FALSE, @@ -79,60 +79,60 @@ const struct sieve_command vacation_command = { /* Forward declarations */ static bool cmd_vacation_validate_number_tag - (struct sieve_validator *validator, struct sieve_ast_argument **arg, - struct sieve_command_context *cmd); + (struct sieve_validator *valdtr, struct sieve_ast_argument **arg, + struct sieve_command *cmd); static bool cmd_vacation_validate_string_tag - (struct sieve_validator *validator, struct sieve_ast_argument **arg, - struct sieve_command_context *cmd); + (struct sieve_validator *valdtr, struct sieve_ast_argument **arg, + struct sieve_command *cmd); static bool cmd_vacation_validate_stringlist_tag - (struct sieve_validator *validator, struct sieve_ast_argument **arg, - struct sieve_command_context *cmd); + (struct sieve_validator *valdtr, struct sieve_ast_argument **arg, + struct sieve_command *cmd); static bool cmd_vacation_validate_mime_tag - (struct sieve_validator *validator, struct sieve_ast_argument **arg, - struct sieve_command_context *cmd); + (struct sieve_validator *valdtr, struct sieve_ast_argument **arg, + struct sieve_command *cmd); /* Argument objects */ -static const struct sieve_argument vacation_days_tag = { +static const struct sieve_argument_def vacation_days_tag = { "days", - NULL, NULL, + NULL, cmd_vacation_validate_number_tag, - NULL, NULL + NULL, NULL, NULL, }; -static const struct sieve_argument vacation_subject_tag = { +static const struct sieve_argument_def vacation_subject_tag = { "subject", - NULL, NULL, + NULL, cmd_vacation_validate_string_tag, - NULL, NULL + NULL, NULL, NULL }; -static const struct sieve_argument vacation_from_tag = { +static const struct sieve_argument_def vacation_from_tag = { "from", - NULL, NULL, + NULL, cmd_vacation_validate_string_tag, - NULL, NULL + NULL, NULL, NULL }; -static const struct sieve_argument vacation_addresses_tag = { +static const struct sieve_argument_def vacation_addresses_tag = { "addresses", - NULL, NULL, + NULL, cmd_vacation_validate_stringlist_tag, - NULL, NULL + NULL, NULL, NULL }; -static const struct sieve_argument vacation_mime_tag = { +static const struct sieve_argument_def vacation_mime_tag = { "mime", - NULL, NULL, + NULL, cmd_vacation_validate_mime_tag, - NULL, NULL + NULL, NULL, NULL }; -static const struct sieve_argument vacation_handle_tag = { +static const struct sieve_argument_def vacation_handle_tag = { "handle", - NULL, NULL, + NULL, cmd_vacation_validate_string_tag, - NULL, NULL + NULL, NULL, NULL }; /* Codes for optional arguments */ @@ -151,13 +151,11 @@ enum cmd_vacation_optional { */ static bool ext_vacation_operation_dump - (const struct sieve_operation *op, - const struct sieve_dumptime_env *denv, sieve_size_t *address); + (const struct sieve_dumptime_env *denv, sieve_size_t *address); static int ext_vacation_operation_execute - (const struct sieve_operation *op, - const struct sieve_runtime_env *renv, sieve_size_t *address); + (const struct sieve_runtime_env *renv, sieve_size_t *address); -const struct sieve_operation vacation_operation = { +const struct sieve_operation_def vacation_operation = { "VACATION", &vacation_extension, 0, @@ -173,22 +171,22 @@ const struct sieve_operation vacation_operation = { static int act_vacation_check_duplicate (const struct sieve_runtime_env *renv, - const struct sieve_action_data *act, - const struct sieve_action_data *act_other); + const struct sieve_action *act, + const struct sieve_action *act_other); int act_vacation_check_conflict (const struct sieve_runtime_env *renv, - const struct sieve_action_data *act, - const struct sieve_action_data *act_other); + const struct sieve_action *act, + const struct sieve_action *act_other); static void act_vacation_print (const struct sieve_action *action, - const struct sieve_result_print_env *rpenv, void *context, bool *keep); + const struct sieve_result_print_env *rpenv, bool *keep); static bool act_vacation_commit (const struct sieve_action *action, const struct sieve_action_exec_env *aenv, void *tr_context, bool *keep); /* Action object */ -const struct sieve_action act_vacation = { +const struct sieve_action_def act_vacation = { "vacation", SIEVE_ACTFLAG_SENDS_RESPONSE, NULL, @@ -232,8 +230,8 @@ struct cmd_vacation_context_data { */ static bool cmd_vacation_validate_number_tag -(struct sieve_validator *validator, struct sieve_ast_argument **arg, - struct sieve_command_context *cmd) +(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, + struct sieve_command *cmd) { struct sieve_ast_argument *tag = *arg; @@ -244,7 +242,7 @@ static bool cmd_vacation_validate_number_tag * :days number */ if ( !sieve_validate_tag_parameter - (validator, cmd, tag, *arg, SAAT_NUMBER) ) { + (valdtr, cmd, tag, *arg, SAAT_NUMBER) ) { return FALSE; } @@ -260,8 +258,8 @@ static bool cmd_vacation_validate_number_tag } static bool cmd_vacation_validate_string_tag -(struct sieve_validator *validator, struct sieve_ast_argument **arg, - struct sieve_command_context *cmd) +(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, + struct sieve_command *cmd) { struct sieve_ast_argument *tag = *arg; struct cmd_vacation_context_data *ctx_data = @@ -276,11 +274,11 @@ static bool cmd_vacation_validate_string_tag * :handle string */ if ( !sieve_validate_tag_parameter - (validator, cmd, tag, *arg, SAAT_STRING) ) { + (valdtr, cmd, tag, *arg, SAAT_STRING) ) { return FALSE; } - if ( tag->argument == &vacation_from_tag ) { + if ( sieve_argument_is(tag, vacation_from_tag) ) { if ( sieve_argument_is_string_literal(*arg) ) { string_t *address = sieve_ast_argument_str(*arg); const char *error; @@ -290,7 +288,7 @@ static bool cmd_vacation_validate_string_tag result = sieve_address_validate(address, &error); if ( !result ) { - sieve_argument_validate_error(validator, *arg, + sieve_argument_validate_error(valdtr, *arg, "specified :from address '%s' is invalid for vacation action: %s", str_sanitize(str_c(address), 128), error); } @@ -305,13 +303,13 @@ static bool cmd_vacation_validate_string_tag /* Skip parameter */ *arg = sieve_ast_argument_next(*arg); - } else if ( tag->argument == &vacation_subject_tag ) { + } else if ( sieve_argument_is(tag, vacation_subject_tag) ) { ctx_data->subject = sieve_ast_argument_str(*arg); /* Skip parameter */ *arg = sieve_ast_argument_next(*arg); - } else if ( tag->argument == &vacation_handle_tag ) { + } else if ( sieve_argument_is(tag, vacation_handle_tag) ) { ctx_data->handle = sieve_ast_argument_str(*arg); /* Detach optional argument (emitted as mandatory) */ @@ -322,8 +320,8 @@ static bool cmd_vacation_validate_string_tag } static bool cmd_vacation_validate_stringlist_tag -(struct sieve_validator *validator, struct sieve_ast_argument **arg, - struct sieve_command_context *cmd) +(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, + struct sieve_command *cmd) { struct sieve_ast_argument *tag = *arg; @@ -334,7 +332,7 @@ static bool cmd_vacation_validate_stringlist_tag * :addresses string-list */ if ( !sieve_validate_tag_parameter - (validator, cmd, tag, *arg, SAAT_STRING_LIST) ) { + (valdtr, cmd, tag, *arg, SAAT_STRING_LIST) ) { return FALSE; } @@ -345,8 +343,8 @@ static bool cmd_vacation_validate_stringlist_tag } static bool cmd_vacation_validate_mime_tag -(struct sieve_validator *validator ATTR_UNUSED, struct sieve_ast_argument **arg, - struct sieve_command_context *cmd) +(struct sieve_validator *valdtr ATTR_UNUSED, struct sieve_ast_argument **arg, + struct sieve_command *cmd) { struct cmd_vacation_context_data *ctx_data = (struct cmd_vacation_context_data *) cmd->data; @@ -364,20 +362,21 @@ static bool cmd_vacation_validate_mime_tag */ static bool cmd_vacation_registered -(struct sieve_validator *validator, struct sieve_command_registration *cmd_reg) +(struct sieve_validator *valdtr, const struct sieve_extension *ext, + struct sieve_command_registration *cmd_reg) { sieve_validator_register_tag - (validator, cmd_reg, &vacation_days_tag, OPT_DAYS); + (valdtr, cmd_reg, ext, &vacation_days_tag, OPT_DAYS); sieve_validator_register_tag - (validator, cmd_reg, &vacation_subject_tag, OPT_SUBJECT); + (valdtr, cmd_reg, ext, &vacation_subject_tag, OPT_SUBJECT); sieve_validator_register_tag - (validator, cmd_reg, &vacation_from_tag, OPT_FROM); + (valdtr, cmd_reg, ext, &vacation_from_tag, OPT_FROM); sieve_validator_register_tag - (validator, cmd_reg, &vacation_addresses_tag, OPT_ADDRESSES); + (valdtr, cmd_reg, ext, &vacation_addresses_tag, OPT_ADDRESSES); sieve_validator_register_tag - (validator, cmd_reg, &vacation_mime_tag, OPT_MIME); + (valdtr, cmd_reg, ext, &vacation_mime_tag, OPT_MIME); sieve_validator_register_tag - (validator, cmd_reg, &vacation_handle_tag, 0); + (valdtr, cmd_reg, ext, &vacation_handle_tag, 0); return TRUE; } @@ -387,8 +386,8 @@ static bool cmd_vacation_registered */ static bool cmd_vacation_pre_validate -(struct sieve_validator *validator ATTR_UNUSED, - struct sieve_command_context *cmd) +(struct sieve_validator *valdtr ATTR_UNUSED, + struct sieve_command *cmd) { struct cmd_vacation_context_data *ctx_data; @@ -406,18 +405,18 @@ static const char _handle_mime_enabled[] = "<MIME>"; static const char _handle_mime_disabled[] = "<NO-MIME>"; static bool cmd_vacation_validate -(struct sieve_validator *validator, struct sieve_command_context *cmd) +(struct sieve_validator *valdtr, struct sieve_command *cmd) { struct sieve_ast_argument *arg = cmd->first_positional; struct cmd_vacation_context_data *ctx_data = (struct cmd_vacation_context_data *) cmd->data; if ( !sieve_validate_positional_argument - (validator, cmd, arg, "reason", 1, SAAT_STRING) ) { + (valdtr, cmd, arg, "reason", 1, SAAT_STRING) ) { return FALSE; } - if ( !sieve_validator_argument_activate(validator, cmd, arg, FALSE) ) + if ( !sieve_validator_argument_activate(valdtr, cmd, arg, FALSE) ) return FALSE; /* Construct handle if not set explicitly */ @@ -459,18 +458,18 @@ static bool cmd_vacation_validate */ static bool cmd_vacation_generate -(const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx) +(const struct sieve_codegen_env *cgenv, struct sieve_command *cmd) { struct cmd_vacation_context_data *ctx_data = - (struct cmd_vacation_context_data *) ctx->data; + (struct cmd_vacation_context_data *) cmd->data; - sieve_operation_emit_code(cgenv->sbin, &vacation_operation); + sieve_operation_emit(cgenv->sbin, cmd->ext, &vacation_operation); /* Emit source line */ - sieve_code_source_line_emit(cgenv->sbin, sieve_command_source_line(ctx)); + sieve_code_source_line_emit(cgenv->sbin, sieve_command_source_line(cmd)); /* Generate arguments */ - if ( !sieve_generate_arguments(cgenv, ctx, NULL) ) + if ( !sieve_generate_arguments(cgenv, cmd, NULL) ) return FALSE; /* FIXME: this will not allow the handle to be a variable */ @@ -484,8 +483,7 @@ static bool cmd_vacation_generate */ static bool ext_vacation_operation_dump -(const struct sieve_operation *op ATTR_UNUSED, - const struct sieve_dumptime_env *denv, sieve_size_t *address) +(const struct sieve_dumptime_env *denv, sieve_size_t *address) { int opt_code = 1; @@ -544,9 +542,9 @@ static bool ext_vacation_operation_dump */ static int ext_vacation_operation_execute -(const struct sieve_operation *op ATTR_UNUSED, - const struct sieve_runtime_env *renv, sieve_size_t *address) +(const struct sieve_runtime_env *renv, sieve_size_t *address) { + const struct sieve_extension *this_ext = renv->oprtn.ext; struct sieve_side_effects_list *slist = NULL; struct act_vacation_context *act; pool_t pool; @@ -705,7 +703,7 @@ static int ext_vacation_operation_execute } return ( sieve_result_add_action - (renv, &act_vacation, slist, source_line, (void *) act, 0) >= 0 ); + (renv, this_ext, &act_vacation, slist, source_line, (void *) act, 0) >= 0 ); } /* @@ -716,8 +714,8 @@ static int ext_vacation_operation_execute static int act_vacation_check_duplicate (const struct sieve_runtime_env *renv ATTR_UNUSED, - const struct sieve_action_data *act, - const struct sieve_action_data *act_other) + const struct sieve_action *act, + const struct sieve_action *act_other) { if ( !act_other->executed ) { sieve_runtime_error(renv, act->location, @@ -732,15 +730,15 @@ static int act_vacation_check_duplicate int act_vacation_check_conflict (const struct sieve_runtime_env *renv, - const struct sieve_action_data *act, - const struct sieve_action_data *act_other) + const struct sieve_action *act, + const struct sieve_action *act_other) { - if ( (act_other->action->flags & SIEVE_ACTFLAG_SENDS_RESPONSE) > 0 ) { + if ( (act_other->def->flags & SIEVE_ACTFLAG_SENDS_RESPONSE) > 0 ) { if ( !act_other->executed && !act->executed) { sieve_runtime_error(renv, act->location, "vacation action conflicts with other action: " "the %s action (%s) also sends a response back to the sender", - act_other->action->name, act_other->location); + act_other->def->name, act_other->location); return -1; } else { /* Not an error if executed in preceeding script */ @@ -755,10 +753,10 @@ int act_vacation_check_conflict static void act_vacation_print (const struct sieve_action *action ATTR_UNUSED, - const struct sieve_result_print_env *rpenv, void *context, - bool *keep ATTR_UNUSED) + const struct sieve_result_print_env *rpenv, bool *keep ATTR_UNUSED) { - struct act_vacation_context *ctx = (struct act_vacation_context *) context; + struct act_vacation_context *ctx = + (struct act_vacation_context *) action->context; sieve_result_action_printf( rpenv, "send vacation message:"); sieve_result_printf(rpenv, " => days : %d\n", ctx->days); @@ -959,14 +957,14 @@ static void act_vacation_hash } static bool act_vacation_commit -(const struct sieve_action *action ATTR_UNUSED, - const struct sieve_action_exec_env *aenv, void *tr_context, - bool *keep ATTR_UNUSED) +(const struct sieve_action *action, const struct sieve_action_exec_env *aenv, + void *tr_context ATTR_UNUSED, bool *keep ATTR_UNUSED) { const char *const *hdsp; const struct sieve_message_data *msgdata = aenv->msgdata; const struct sieve_script_env *senv = aenv->scriptenv; - struct act_vacation_context *ctx = (struct act_vacation_context *) tr_context; + struct act_vacation_context *ctx = + (struct act_vacation_context *) action->context; unsigned char dupl_hash[MD5_RESULTLEN]; const char *const *headers; const char *sender = sieve_message_get_sender(aenv->msgctx); diff --git a/src/lib-sieve/plugins/vacation/ext-vacation-common.h b/src/lib-sieve/plugins/vacation/ext-vacation-common.h index 0368e4e2d..f9f0f64c9 100644 --- a/src/lib-sieve/plugins/vacation/ext-vacation-common.h +++ b/src/lib-sieve/plugins/vacation/ext-vacation-common.h @@ -10,16 +10,16 @@ * Commands */ -extern const struct sieve_command vacation_command; +extern const struct sieve_command_def vacation_command; /* * Operations */ -extern const struct sieve_operation vacation_operation; +extern const struct sieve_operation_def vacation_operation; /* Extension */ -extern const struct sieve_extension vacation_extension; +extern const struct sieve_extension_def vacation_extension; #endif /* __EXT_VACATION_COMMON_H */ diff --git a/src/lib-sieve/plugins/vacation/ext-vacation.c b/src/lib-sieve/plugins/vacation/ext-vacation.c index 5253ad533..a49a6e713 100644 --- a/src/lib-sieve/plugins/vacation/ext-vacation.c +++ b/src/lib-sieve/plugins/vacation/ext-vacation.c @@ -29,13 +29,11 @@ * Extension */ -static bool ext_vacation_validator_load(struct sieve_validator *validator); +static bool ext_vacation_validator_load + (const struct sieve_extension *ext, struct sieve_validator *valdtr); -static int ext_my_id = -1; - -const struct sieve_extension vacation_extension = { +const struct sieve_extension_def vacation_extension = { "vacation", - &ext_my_id, NULL, NULL, ext_vacation_validator_load, NULL, NULL, NULL, NULL, NULL, @@ -43,10 +41,11 @@ const struct sieve_extension vacation_extension = { SIEVE_EXT_DEFINE_NO_OPERANDS }; -static bool ext_vacation_validator_load(struct sieve_validator *validator) +static bool ext_vacation_validator_load +(const struct sieve_extension *ext, struct sieve_validator *valdtr) { /* Register new command */ - sieve_validator_register_command(validator, &vacation_command); + sieve_validator_register_command(valdtr, ext, &vacation_command); return TRUE; } diff --git a/src/lib-sieve/plugins/variables/cmd-set.c b/src/lib-sieve/plugins/variables/cmd-set.c index 6195d5519..c4b6b3f51 100644 --- a/src/lib-sieve/plugins/variables/cmd-set.c +++ b/src/lib-sieve/plugins/variables/cmd-set.c @@ -29,15 +29,16 @@ */ static bool cmd_set_registered - (struct sieve_validator *validator, struct sieve_command_registration *cmd_reg); + (struct sieve_validator *valdtr, const struct sieve_extension *ext, + struct sieve_command_registration *cmd_reg); static bool cmd_set_pre_validate - (struct sieve_validator *validator, struct sieve_command_context *cmd); + (struct sieve_validator *valdtr, struct sieve_command *cmd); static bool cmd_set_validate - (struct sieve_validator *validator, struct sieve_command_context *cmd); + (struct sieve_validator *valdtr, struct sieve_command *cmd); static bool cmd_set_generate - (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx); + (const struct sieve_codegen_env *cgenv, struct sieve_command *ctx); -const struct sieve_command cmd_set = { +const struct sieve_command_def cmd_set = { "set", SCT_COMMAND, 2, 0, FALSE, FALSE, @@ -53,13 +54,11 @@ const struct sieve_command cmd_set = { */ static bool cmd_set_operation_dump - (const struct sieve_operation *op, - const struct sieve_dumptime_env *denv, sieve_size_t *address); + (const struct sieve_dumptime_env *denv, sieve_size_t *address); static int cmd_set_operation_execute - (const struct sieve_operation *op, - const struct sieve_runtime_env *renv, sieve_size_t *address); + (const struct sieve_runtime_env *renv, sieve_size_t *address); -const struct sieve_operation cmd_set_operation = { +const struct sieve_operation_def cmd_set_operation = { "SET", &variables_extension, EXT_VARIABLES_OPERATION_SET, @@ -86,61 +85,66 @@ struct cmd_set_context { /* Forward declarations */ static bool tag_modifier_is_instance_of - (struct sieve_validator *validator, struct sieve_command_context *cmdctx, - struct sieve_ast_argument *arg); + (struct sieve_validator *valdtr, struct sieve_command *cmd, + const struct sieve_extension *ext, const char *identifier, void **context); static bool tag_modifier_validate - (struct sieve_validator *validator, struct sieve_ast_argument **arg, - struct sieve_command_context *cmd); + (struct sieve_validator *valdtr, struct sieve_ast_argument **arg, + struct sieve_command *cmd); /* Modifier tag object */ -const struct sieve_argument modifier_tag = { +const struct sieve_argument_def modifier_tag = { "MODIFIER", tag_modifier_is_instance_of, - NULL, tag_modifier_validate, - NULL, NULL + NULL, NULL, NULL }; /* Modifier tag implementation */ static bool tag_modifier_is_instance_of -(struct sieve_validator *validator ATTR_UNUSED, - struct sieve_command_context *cmdctx ATTR_UNUSED, - struct sieve_ast_argument *arg) +(struct sieve_validator *valdtr, struct sieve_command *cmd, + const struct sieve_extension *ext, const char *identifier, void **data) { - const struct sieve_variables_modifier *modf = ext_variables_modifier_find - (validator, sieve_ast_argument_tag(arg)); + const struct sieve_variables_modifier *modf; - arg->context = (void *) modf; + if ( data == NULL ) { + return ext_variables_modifier_exists(ext, valdtr, identifier); + } + + if ( (modf=ext_variables_modifier_create_instance + (ext, valdtr, cmd, identifier)) == NULL ) + return FALSE; + + *data = (void *) modf; - return ( modf != NULL ); + return TRUE; } static bool tag_modifier_validate -(struct sieve_validator *validator, struct sieve_ast_argument **arg, - struct sieve_command_context *cmd) +(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, + struct sieve_command *cmd) { - unsigned int i; + unsigned int i, modf_count; bool inserted; const struct sieve_variables_modifier *modf = - (const struct sieve_variables_modifier *) (*arg)->context; + (const struct sieve_variables_modifier *) (*arg)->argument->data; + const struct sieve_variables_modifier *const *modfs; struct cmd_set_context *sctx = (struct cmd_set_context *) cmd->data; inserted = FALSE; - for ( i = 0; i < array_count(&sctx->modifiers) && !inserted; i++ ) { - const struct sieve_variables_modifier * const *smdf = - array_idx(&sctx->modifiers, i); + modfs = array_get(&sctx->modifiers, &modf_count); + for ( i = 0; i < modf_count && !inserted; i++ ) { - if ( (*smdf)->precedence == modf->precedence ) { - sieve_argument_validate_error(validator, *arg, + if ( modfs[i]->def->precedence == modf->def->precedence ) { + sieve_argument_validate_error(valdtr, *arg, "modifiers :%s and :%s specified for the set command conflict " "having equal precedence", - (*smdf)->object.identifier, modf->object.identifier); + modfs[i]->def->obj_def.identifier, modf->def->obj_def.identifier); return FALSE; } - if ( (*smdf)->precedence < modf->precedence ) { + if ( modfs[i]->def->precedence < modf->def->precedence ) { array_insert(&sctx->modifiers, i, &modf, 1); inserted = TRUE; } @@ -158,9 +162,10 @@ static bool tag_modifier_validate /* Command registration */ static bool cmd_set_registered - (struct sieve_validator *validator, struct sieve_command_registration *cmd_reg) +(struct sieve_validator *valdtr, const struct sieve_extension *ext, + struct sieve_command_registration *cmd_reg) { - sieve_validator_register_tag(validator, cmd_reg, &modifier_tag, 0); + sieve_validator_register_tag(valdtr, cmd_reg, ext, &modifier_tag, 0); return TRUE; } @@ -170,8 +175,8 @@ static bool cmd_set_registered */ static bool cmd_set_pre_validate -(struct sieve_validator *validator ATTR_UNUSED, - struct sieve_command_context *cmd) +(struct sieve_validator *valdtr ATTR_UNUSED, + struct sieve_command *cmd) { pool_t pool = sieve_command_pool(cmd); struct cmd_set_context *sctx = p_new(pool, struct cmd_set_context, 1); @@ -184,28 +189,29 @@ static bool cmd_set_pre_validate return TRUE; } -static bool cmd_set_validate(struct sieve_validator *validator, - struct sieve_command_context *cmd) +static bool cmd_set_validate(struct sieve_validator *valdtr, + struct sieve_command *cmd) { + const struct sieve_extension *this_ext = cmd->ext; struct sieve_ast_argument *arg = cmd->first_positional; if ( !sieve_validate_positional_argument - (validator, cmd, arg, "name", 1, SAAT_STRING) ) { + (valdtr, cmd, arg, "name", 1, SAAT_STRING) ) { return FALSE; } - if ( !sieve_variable_argument_activate(validator, cmd, arg, TRUE) ) { + if ( !sieve_variable_argument_activate(this_ext, valdtr, cmd, arg, TRUE) ) { return FALSE; } arg = sieve_ast_argument_next(arg); if ( !sieve_validate_positional_argument - (validator, cmd, arg, "value", 2, SAAT_STRING) ) { + (valdtr, cmd, arg, "value", 2, SAAT_STRING) ) { return FALSE; } - return sieve_validator_argument_activate(validator, cmd, arg, FALSE); + return sieve_validator_argument_activate(valdtr, cmd, arg, FALSE); } /* @@ -213,25 +219,26 @@ static bool cmd_set_validate(struct sieve_validator *validator, */ static bool cmd_set_generate - (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx) + (const struct sieve_codegen_env *cgenv, struct sieve_command *cmd) { + const struct sieve_extension *this_ext = cmd->ext; struct sieve_binary *sbin = cgenv->sbin; - struct cmd_set_context *sctx = (struct cmd_set_context *) ctx->data; - unsigned int i; + struct cmd_set_context *sctx = (struct cmd_set_context *) cmd->data; + const struct sieve_variables_modifier *const *modfs; + unsigned int i, modf_count; - sieve_operation_emit_code(sbin, &cmd_set_operation); + sieve_operation_emit(sbin, this_ext, &cmd_set_operation); /* Generate arguments */ - if ( !sieve_generate_arguments(cgenv, ctx, NULL) ) + if ( !sieve_generate_arguments(cgenv, cmd, NULL) ) return FALSE; /* Generate modifiers (already sorted during validation) */ sieve_binary_emit_byte(sbin, array_count(&sctx->modifiers)); - for ( i = 0; i < array_count(&sctx->modifiers); i++ ) { - const struct sieve_variables_modifier * const * modf = - array_idx(&sctx->modifiers, i); - - ext_variables_opr_modifier_emit(sbin, *modf); + + modfs = array_get(&sctx->modifiers, &modf_count); + for ( i = 0; i < modf_count; i++ ) { + ext_variables_opr_modifier_emit(sbin, modfs[i]->object.ext, modfs[i]->def); } return TRUE; @@ -242,8 +249,7 @@ static bool cmd_set_generate */ static bool cmd_set_operation_dump -(const struct sieve_operation *op ATTR_UNUSED, - const struct sieve_dumptime_env *denv, sieve_size_t *address) +(const struct sieve_dumptime_env *denv, sieve_size_t *address) { unsigned int mdfs, i; @@ -273,8 +279,7 @@ static bool cmd_set_operation_dump */ static int cmd_set_operation_execute -(const struct sieve_operation *op ATTR_UNUSED, - const struct sieve_runtime_env *renv, sieve_size_t *address) +(const struct sieve_runtime_env *renv, sieve_size_t *address) { struct sieve_variable_storage *storage; unsigned int var_index, mdfs, i; @@ -319,10 +324,9 @@ static int cmd_set_operation_execute if ( str_len(value) > 0 ) { for ( i = 0; i < mdfs; i++ ) { string_t *new_value; - const struct sieve_variables_modifier *modf = - ext_variables_opr_modifier_read(renv, address); - - if ( modf == NULL ) { + struct sieve_variables_modifier modf; + + if ( !ext_variables_opr_modifier_read(renv, address, &modf) ) { value = NULL; sieve_runtime_trace_error(renv, "invalid modifier operand"); @@ -330,8 +334,8 @@ static int cmd_set_operation_execute break; } - if ( modf->modify != NULL ) { - if ( !modf->modify(value, &new_value) ) { + if ( modf.def != NULL && modf.def->modify != NULL ) { + if ( !modf.def->modify(value, &new_value) ) { value = NULL; ret = SIEVE_EXEC_FAILURE; break; diff --git a/src/lib-sieve/plugins/variables/ext-variables-arguments.c b/src/lib-sieve/plugins/variables/ext-variables-arguments.c index b7904537e..8043e6f5b 100644 --- a/src/lib-sieve/plugins/variables/ext-variables-arguments.c +++ b/src/lib-sieve/plugins/variables/ext-variables-arguments.c @@ -17,6 +17,7 @@ #include "ext-variables-common.h" #include "ext-variables-limits.h" #include "ext-variables-name.h" +#include "ext-variables-operands.h" #include "ext-variables-arguments.h" /* @@ -48,38 +49,40 @@ static inline void _ext_variables_match_index_error static bool arg_variable_generate (const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, - struct sieve_command_context *context); + struct sieve_command *context); -const struct sieve_argument variable_argument = { +const struct sieve_argument_def variable_argument = { "@variable", NULL, NULL, NULL, NULL, arg_variable_generate }; static struct sieve_ast_argument *ext_variables_variable_argument_create -(struct sieve_validator *validator, struct sieve_ast *ast, - unsigned int source_line, const char *variable) +(const struct sieve_extension *this_ext, struct sieve_validator *valdtr, + struct sieve_ast *ast, unsigned int source_line, const char *variable) { struct sieve_variable *var; struct sieve_ast_argument *arg; - var = ext_variables_validator_get_variable(validator, variable, TRUE); + var = ext_variables_validator_get_variable(this_ext, valdtr, variable, TRUE); if ( var == NULL ) return NULL; arg = sieve_ast_argument_create(ast, source_line); arg->type = SAAT_STRING; - arg->argument = &variable_argument; - arg->context = (void *) var; + arg->argument = sieve_argument_create(ast, &variable_argument, this_ext, 0); + arg->argument->data = (void *) var; return arg; } static bool _sieve_variable_argument_activate -(struct sieve_validator *validator, struct sieve_command_context *cmd ATTR_UNUSED, - struct sieve_ast_argument *arg, bool assignment) +(const struct sieve_extension *this_ext, struct sieve_validator *valdtr, + struct sieve_command *cmd ATTR_UNUSED, struct sieve_ast_argument *arg, + bool assignment) { + struct sieve_ast *ast = arg->ast; bool result = FALSE; struct sieve_variable *var; string_t *variable; @@ -98,7 +101,7 @@ static bool _sieve_variable_argument_activate /* Check whether name parsing succeeded */ if ( nelements < 0 || varstr != varend ) { /* Parse failed */ - sieve_argument_validate_error(validator, arg, + sieve_argument_validate_error(valdtr, arg, "invalid variable name '%s'", str_sanitize(str_c(variable),80)); } else if ( nelements == 1 ) { /* Normal (match) variable */ @@ -109,14 +112,15 @@ static bool _sieve_variable_argument_activate if ( cur_element->num_variable < 0 ) { /* Variable */ var = ext_variables_validator_get_variable - (validator, str_c(cur_element->identifier), TRUE); + (this_ext, valdtr, str_c(cur_element->identifier), TRUE); if ( var == NULL ) { _ext_variables_scope_size_error - (validator, arg, str_c(cur_element->identifier)); + (valdtr, arg, str_c(cur_element->identifier)); } else { - arg->argument = &variable_argument; - arg->context = (void *) var; + arg->argument = sieve_argument_create + (ast, &variable_argument, this_ext, 0); + arg->argument->data = (void *) var; result = TRUE; } @@ -125,15 +129,17 @@ static bool _sieve_variable_argument_activate if ( !assignment ) { if ( cur_element->num_variable > SIEVE_VARIABLES_MAX_MATCH_INDEX ) { _ext_variables_match_index_error - (validator, arg, cur_element->num_variable); + (valdtr, arg, cur_element->num_variable); } else { - arg->argument = &match_value_argument; - arg->context = POINTER_CAST(cur_element->num_variable); + arg->argument = sieve_argument_create + (ast, &match_value_argument, this_ext, 0); + arg->argument->data = (void *) + POINTER_CAST(cur_element->num_variable); result = TRUE; } } else { - sieve_argument_validate_error(validator, arg, + sieve_argument_validate_error(valdtr, arg, "cannot assign to match variable"); } } @@ -149,7 +155,7 @@ static bool _sieve_variable_argument_activate * the relevant extension MUST cause an error. */ - sieve_argument_validate_error(validator, arg, + sieve_argument_validate_error(valdtr, arg, "cannot %s to variable in unknown namespace '%s'", assignment ? "assign" : "refer", str_c(cur_element->identifier)); } @@ -159,12 +165,14 @@ static bool _sieve_variable_argument_activate } bool sieve_variable_argument_activate -(struct sieve_validator *validator, struct sieve_command_context *cmd, - struct sieve_ast_argument *arg, bool assignment) +(const struct sieve_extension *this_ext, struct sieve_validator *valdtr, + struct sieve_command *cmd, struct sieve_ast_argument *arg, + bool assignment) { if ( sieve_ast_argument_type(arg) == SAAT_STRING ) { /* Single string */ - return _sieve_variable_argument_activate(validator, cmd, arg, assignment); + return _sieve_variable_argument_activate + (this_ext, valdtr, cmd, arg, assignment); } else if ( sieve_ast_argument_type(arg) == SAAT_STRING_LIST ) { /* String list */ @@ -175,14 +183,14 @@ bool sieve_variable_argument_activate stritem = sieve_ast_strlist_first(arg); while ( stritem != NULL ) { if ( !_sieve_variable_argument_activate - (validator, cmd, stritem, assignment) ) + (this_ext, valdtr, cmd, stritem, assignment) ) return FALSE; stritem = sieve_ast_strlist_next(stritem); - } - arg->argument = &string_list_argument; + arg->argument = sieve_argument_create + (arg->ast, &string_list_argument, NULL, 0); return TRUE; } @@ -192,11 +200,12 @@ bool sieve_variable_argument_activate static bool arg_variable_generate (const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, - struct sieve_command_context *context ATTR_UNUSED) + struct sieve_command *context ATTR_UNUSED) { - struct sieve_variable *var = (struct sieve_variable *) arg->context; + struct sieve_argument *argument = arg->argument; + struct sieve_variable *var = (struct sieve_variable *) argument->data; - ext_variables_opr_variable_emit(cgenv->sbin, var); + ext_variables_opr_variable_emit(cgenv->sbin, argument->ext, var); return TRUE; } @@ -207,35 +216,38 @@ static bool arg_variable_generate static bool arg_match_value_generate (const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, - struct sieve_command_context *context ATTR_UNUSED); + struct sieve_command *context ATTR_UNUSED); -const struct sieve_argument match_value_argument = { +const struct sieve_argument_def match_value_argument = { "@match_value", NULL, NULL, NULL, NULL, arg_match_value_generate }; static struct sieve_ast_argument *ext_variables_match_value_argument_create -(struct sieve_validator *validator ATTR_UNUSED, struct sieve_ast *ast, +(const struct sieve_extension *this_ext, + struct sieve_validator *valdtr ATTR_UNUSED, struct sieve_ast *ast, unsigned int source_line, unsigned int index) { struct sieve_ast_argument *arg; arg = sieve_ast_argument_create(ast, source_line); arg->type = SAAT_STRING; - arg->argument = &match_value_argument; - arg->context = POINTER_CAST(index); + arg->argument = sieve_argument_create + (ast, &match_value_argument, this_ext, 0); + arg->argument->data = (void *) POINTER_CAST(index); return arg; } static bool arg_match_value_generate (const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, - struct sieve_command_context *context ATTR_UNUSED) + struct sieve_command *context ATTR_UNUSED) { - unsigned int index = POINTER_CAST_TO(arg->context, unsigned int); + struct sieve_argument *argument = arg->argument; + unsigned int index = POINTER_CAST_TO(argument->data, unsigned int); - ext_variables_opr_match_value_emit(cgenv->sbin, index); + ext_variables_opr_match_value_emit(cgenv->sbin, argument->ext, index); return TRUE; } @@ -245,21 +257,22 @@ static bool arg_match_value_generate */ static bool arg_variable_string_validate - (struct sieve_validator *validator, struct sieve_ast_argument **arg, - struct sieve_command_context *context); + (struct sieve_validator *valdtr, struct sieve_ast_argument **arg, + struct sieve_command *cmd); -const struct sieve_argument variable_string_argument = { +const struct sieve_argument_def variable_string_argument = { "@variable-string", - NULL, NULL, + NULL, arg_variable_string_validate, - NULL, + NULL, NULL, sieve_arg_catenated_string_generate, }; static bool arg_variable_string_validate -(struct sieve_validator *validator, struct sieve_ast_argument **arg, - struct sieve_command_context *cmd) +(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, + struct sieve_command *cmd) { + const struct sieve_extension *this_ext = (*arg)->argument->ext; enum { ST_NONE, ST_OPEN, ST_VARIABLE, ST_CLOSE } state = ST_NONE; pool_t pool = sieve_ast_pool((*arg)->ast); struct sieve_arg_catenated_string *catstr = NULL; @@ -337,7 +350,7 @@ static bool arg_variable_string_validate /* Give other substitution extensions a chance to do their work */ if ( !sieve_validator_argument_activate_super - (validator, cmd, strarg, FALSE) ) { + (valdtr, cmd, strarg, FALSE) ) { result = FALSE; break; } @@ -353,12 +366,14 @@ static bool arg_variable_string_validate string_t *cur_ident = cur_element->identifier; strarg = ext_variables_variable_argument_create - (validator, (*arg)->ast, (*arg)->source_line, str_c(cur_ident)); + (this_ext, valdtr, (*arg)->ast, (*arg)->source_line, + str_c(cur_ident)); + if ( strarg != NULL ) sieve_arg_catenated_string_add_element(catstr, strarg); else { _ext_variables_scope_size_error - (validator, *arg, str_c(cur_element->identifier)); + (valdtr, *arg, str_c(cur_element->identifier)); result = FALSE; break; } @@ -366,14 +381,15 @@ static bool arg_variable_string_validate /* Add match value argument '${000}' */ if ( cur_element->num_variable > SIEVE_VARIABLES_MAX_MATCH_INDEX ) { _ext_variables_match_index_error - (validator, *arg, cur_element->num_variable); + (valdtr, *arg, cur_element->num_variable); result = FALSE; break; } strarg = ext_variables_match_value_argument_create - (validator, (*arg)->ast, (*arg)->source_line, + (this_ext, valdtr, (*arg)->ast, (*arg)->source_line, cur_element->num_variable); + if ( strarg != NULL ) sieve_arg_catenated_string_add_element(catstr, strarg); } @@ -386,7 +402,7 @@ static bool arg_variable_string_validate /* References to namespaces without a prior require * statement for thecrelevant extension MUST cause an error. */ - sieve_argument_validate_error(validator, *arg, + sieve_argument_validate_error(valdtr, *arg, "referring to variable in unknown namespace '%s'", str_c(cur_element->identifier)); result = FALSE; @@ -413,7 +429,7 @@ static bool arg_variable_string_validate /* No substitutions in this string, pass it on to any other substution * extension. */ - return sieve_validator_argument_activate_super(validator, cmd, *arg, TRUE); + return sieve_validator_argument_activate_super(valdtr, cmd, *arg, TRUE); } /* Add the final substring that comes after the last substitution to the @@ -430,7 +446,7 @@ static bool arg_variable_string_validate /* Give other substitution extensions a chance to do their work */ if ( !sieve_validator_argument_activate_super - (validator, cmd, strarg, FALSE) ) + (valdtr, cmd, strarg, FALSE) ) return FALSE; } diff --git a/src/lib-sieve/plugins/variables/ext-variables-arguments.h b/src/lib-sieve/plugins/variables/ext-variables-arguments.h index 785899fe8..878cab460 100644 --- a/src/lib-sieve/plugins/variables/ext-variables-arguments.h +++ b/src/lib-sieve/plugins/variables/ext-variables-arguments.h @@ -10,18 +10,18 @@ * Variable argument */ -extern const struct sieve_argument variable_argument; +extern const struct sieve_argument_def variable_argument; /* * Match value argument */ -extern const struct sieve_argument match_value_argument; +extern const struct sieve_argument_def match_value_argument; /* * Variable string argument */ -extern const struct sieve_argument variable_string_argument; +extern const struct sieve_argument_def variable_string_argument; #endif /* __EXT_VARIABLES_ARGUMENTS_H */ diff --git a/src/lib-sieve/plugins/variables/ext-variables-common.c b/src/lib-sieve/plugins/variables/ext-variables-common.c index 92d9e780d..6f358754f 100644 --- a/src/lib-sieve/plugins/variables/ext-variables-common.c +++ b/src/lib-sieve/plugins/variables/ext-variables-common.c @@ -321,7 +321,8 @@ bool sieve_variable_assign */ static void ext_variables_ast_free -(struct sieve_ast *ast ATTR_UNUSED, void *context) +(const struct sieve_extension *ext ATTR_UNUSED, + struct sieve_ast *ast ATTR_UNUSED, void *context) { struct sieve_variable_scope *main_scope = (struct sieve_variable_scope *) context; @@ -336,23 +337,23 @@ static const struct sieve_ast_extension variables_ast_extension = { }; static struct sieve_variable_scope *ext_variables_create_main_scope -(struct sieve_ast *ast) +(const struct sieve_extension *this_ext, struct sieve_ast *ast) { struct sieve_variable_scope *scope; scope = sieve_variable_scope_create(NULL); - sieve_ast_extension_register(ast, &variables_ast_extension, (void *) scope); + sieve_ast_extension_register + (ast, this_ext, &variables_ast_extension, (void *) scope); return scope; } static struct sieve_variable_scope *ext_variables_ast_get_main_scope -(struct sieve_ast *ast) +(const struct sieve_extension *this_ext, struct sieve_ast *ast) { - struct sieve_variable_scope *main_scope = - (struct sieve_variable_scope *) sieve_ast_extension_get_context - (ast, &variables_extension); + struct sieve_variable_scope *main_scope = (struct sieve_variable_scope *) + sieve_ast_extension_get_context(ast, this_ext); return main_scope; } @@ -362,7 +363,8 @@ static struct sieve_variable_scope *ext_variables_ast_get_main_scope */ static struct ext_variables_validator_context * -ext_variables_validator_context_create(struct sieve_validator *valdtr) +ext_variables_validator_context_create +(const struct sieve_extension *this_ext, struct sieve_validator *valdtr) { pool_t pool = sieve_validator_pool(valdtr); struct ext_variables_validator_context *ctx; @@ -370,62 +372,63 @@ ext_variables_validator_context_create(struct sieve_validator *valdtr) ctx = p_new(pool, struct ext_variables_validator_context, 1); ctx->modifiers = sieve_validator_object_registry_create(valdtr); - ctx->main_scope = ext_variables_create_main_scope(ast); - - sieve_validator_extension_set_context - (valdtr, &variables_extension, (void *) ctx); + ctx->main_scope = ext_variables_create_main_scope(this_ext, ast); + sieve_validator_extension_set_context(valdtr, this_ext, (void *) ctx); return ctx; } struct ext_variables_validator_context *ext_variables_validator_context_get -(struct sieve_validator *valdtr) +(const struct sieve_extension *this_ext, struct sieve_validator *valdtr) { struct ext_variables_validator_context *ctx = (struct ext_variables_validator_context *) - sieve_validator_extension_get_context(valdtr, &variables_extension); + sieve_validator_extension_get_context(valdtr, this_ext); if ( ctx == NULL ) { - ctx = ext_variables_validator_context_create(valdtr); + ctx = ext_variables_validator_context_create(this_ext, valdtr); } return ctx; } -void ext_variables_validator_initialize(struct sieve_validator *validator) +void ext_variables_validator_initialize +(const struct sieve_extension *this_ext, struct sieve_validator *valdtr) { struct ext_variables_validator_context *ctx; /* Create our context */ - ctx = ext_variables_validator_context_get(validator); + ctx = ext_variables_validator_context_get(this_ext, valdtr); - ext_variables_register_core_modifiers(ctx); + ext_variables_register_core_modifiers(this_ext, ctx); ctx->active = TRUE; } struct sieve_variable *ext_variables_validator_get_variable -(struct sieve_validator *validator, const char *variable, bool declare) +(const struct sieve_extension *this_ext, struct sieve_validator *validator, + const char *variable, bool declare) { struct ext_variables_validator_context *ctx = - ext_variables_validator_context_get(validator); + ext_variables_validator_context_get(this_ext, validator); return sieve_variable_scope_get_variable(ctx->main_scope, variable, declare); } struct sieve_variable_scope *sieve_ext_variables_get_main_scope -(struct sieve_validator *validator) +(const struct sieve_extension *var_ext, struct sieve_validator *validator) { struct ext_variables_validator_context *ctx = - ext_variables_validator_context_get(validator); + ext_variables_validator_context_get(var_ext, validator); return ctx->main_scope; } -bool sieve_ext_variables_is_active(struct sieve_validator *valdtr) +bool sieve_ext_variables_is_active +(const struct sieve_extension *var_ext, struct sieve_validator *valdtr) { struct ext_variables_validator_context *ctx = - ext_variables_validator_context_get(valdtr); + ext_variables_validator_context_get(var_ext, valdtr); return ( ctx != NULL && ctx->active ); } @@ -434,10 +437,11 @@ bool sieve_ext_variables_is_active(struct sieve_validator *valdtr) * Code generation */ -bool ext_variables_generator_load(const struct sieve_codegen_env *cgenv) +bool ext_variables_generator_load +(const struct sieve_extension *ext, const struct sieve_codegen_env *cgenv) { struct sieve_variable_scope *main_scope = - ext_variables_ast_get_main_scope(cgenv->ast); + ext_variables_ast_get_main_scope(ext, cgenv->ast); unsigned int count = sieve_variable_scope_size(main_scope); sieve_size_t jump; @@ -471,23 +475,26 @@ struct ext_variables_interpreter_context { static struct ext_variables_interpreter_context * ext_variables_interpreter_context_create -(struct sieve_interpreter *interp, unsigned int max_size) +(const struct sieve_extension *this_ext, struct sieve_interpreter *interp, + unsigned int max_size) { pool_t pool = sieve_interpreter_pool(interp); struct ext_variables_interpreter_context *ctx; ctx = p_new(pool, struct ext_variables_interpreter_context, 1); ctx->local_storage = sieve_variable_storage_create(pool, NULL, max_size); - p_array_init(&ctx->ext_storages, pool, sieve_extensions_get_count()); + p_array_init(&ctx->ext_storages, pool, + sieve_extensions_get_count(this_ext->svinst)); sieve_interpreter_extension_set_context - (interp, &variables_extension, (void *) ctx); + (interp, this_ext, (void *) ctx); return ctx; } bool ext_variables_interpreter_load - (const struct sieve_runtime_env *renv, sieve_size_t *address) +(const struct sieve_extension *ext, const struct sieve_runtime_env *renv, + sieve_size_t *address) { struct ext_variables_interpreter_context *ctx; unsigned int scope_size; @@ -511,7 +518,8 @@ bool ext_variables_interpreter_load *address = pc + end_offset; /* Create our context */ - ctx = ext_variables_interpreter_context_create(renv->interp, scope_size); + ctx = ext_variables_interpreter_context_create + (ext, renv->interp, scope_size); /* Enable support for match values */ (void) sieve_match_values_set_enabled(renv->interp, TRUE); @@ -520,28 +528,28 @@ bool ext_variables_interpreter_load } static inline struct ext_variables_interpreter_context * -ext_variables_interpreter_context_get(struct sieve_interpreter *interp) +ext_variables_interpreter_context_get +(const struct sieve_extension *this_ext, struct sieve_interpreter *interp) { return (struct ext_variables_interpreter_context *) - sieve_interpreter_extension_get_context(interp, &variables_extension); + sieve_interpreter_extension_get_context(interp, this_ext); } struct sieve_variable_storage *sieve_ext_variables_get_storage -(struct sieve_interpreter *interp, const struct sieve_extension *ext) +(const struct sieve_extension *var_ext, struct sieve_interpreter *interp, + const struct sieve_extension *ext) { struct ext_variables_interpreter_context *ctx = - ext_variables_interpreter_context_get(interp); + ext_variables_interpreter_context_get(var_ext, interp); struct sieve_variable_storage * const *storage; - int ext_id; if ( ext == NULL ) return ctx->local_storage; - ext_id = SIEVE_EXT_ID(ext); - if ( ext_id >= (int) array_count(&ctx->ext_storages) ) { + if ( ext->id >= (int) array_count(&ctx->ext_storages) ) { storage = NULL; } else { - storage = array_idx(&ctx->ext_storages, ext_id); + storage = array_idx(&ctx->ext_storages, ext->id); } if ( storage == NULL || *storage == NULL ) @@ -551,16 +559,18 @@ struct sieve_variable_storage *sieve_ext_variables_get_storage } void sieve_ext_variables_set_storage -(struct sieve_interpreter *interp, struct sieve_variable_storage *storage, - const struct sieve_extension *ext) +(const struct sieve_extension *var_ext, struct sieve_interpreter *interp, + struct sieve_variable_storage *storage, const struct sieve_extension *ext) { struct ext_variables_interpreter_context *ctx = - ext_variables_interpreter_context_get(interp); + ext_variables_interpreter_context_get(var_ext, interp); if ( ctx == NULL || ext == NULL || storage == NULL ) return; + + if ( ext->id < 0 ) return; - array_idx_set(&ctx->ext_storages, (unsigned int) SIEVE_EXT_ID(ext), &storage); + array_idx_set(&ctx->ext_storages, (unsigned int) ext->id, &storage); } diff --git a/src/lib-sieve/plugins/variables/ext-variables-common.h b/src/lib-sieve/plugins/variables/ext-variables-common.h index 0fa046beb..5a42bb3b0 100644 --- a/src/lib-sieve/plugins/variables/ext-variables-common.h +++ b/src/lib-sieve/plugins/variables/ext-variables-common.h @@ -13,14 +13,14 @@ * Extension */ -extern const struct sieve_extension variables_extension; +extern const struct sieve_extension_def variables_extension; /* * Commands */ -extern const struct sieve_command cmd_set; -extern const struct sieve_command tst_string; +extern const struct sieve_command_def cmd_set; +extern const struct sieve_command_def tst_string; /* * Operands @@ -36,8 +36,8 @@ enum ext_variables_operand { * Operations */ -extern const struct sieve_operation cmd_set_operation; -extern const struct sieve_operation tst_string_operation; +extern const struct sieve_operation_def cmd_set_operation; +extern const struct sieve_operation_def tst_string_operation; enum ext_variables_opcode { EXT_VARIABLES_OPERATION_SET, @@ -56,45 +56,29 @@ struct ext_variables_validator_context { struct sieve_variable_scope *main_scope; }; -void ext_variables_validator_initialize(struct sieve_validator *validator); +void ext_variables_validator_initialize + (const struct sieve_extension *this_ext, struct sieve_validator *validator); struct ext_variables_validator_context *ext_variables_validator_context_get - (struct sieve_validator *valdtr); + (const struct sieve_extension *this_ext, struct sieve_validator *valdtr); struct sieve_variable *ext_variables_validator_get_variable - (struct sieve_validator *validator, const char *variable, bool declare); + (const struct sieve_extension *this_ext, struct sieve_validator *validator, + const char *variable, bool declare); /* * Code generation */ bool ext_variables_generator_load - (const struct sieve_codegen_env *cgenv); + (const struct sieve_extension *ext, const struct sieve_codegen_env *cgenv); /* * Interpreter context */ bool ext_variables_interpreter_load -(const struct sieve_runtime_env *renv, sieve_size_t *address); - -/* - * Variable coding - */ - -void ext_variables_opr_variable_emit - (struct sieve_binary *sbin, struct sieve_variable *var); -void ext_variables_opr_match_value_emit - (struct sieve_binary *sbin, unsigned int index); -bool ext_variables_opr_variable_read - (const struct sieve_runtime_env *renv, sieve_size_t *address, - struct sieve_variable_storage **storage, unsigned int *var_index); - -void ext_variables_opr_variable_string_emit - (struct sieve_binary *sbin, unsigned int elements); - -bool ext_variables_variable_assignment_activate -(struct sieve_validator *validator, struct sieve_ast_argument *arg, - struct sieve_command_context *cmd); + (const struct sieve_extension *ext, const struct sieve_runtime_env *renv, + sieve_size_t *address); #endif /* __EXT_VARIABLES_COMMON_H */ diff --git a/src/lib-sieve/plugins/variables/ext-variables-dump.c b/src/lib-sieve/plugins/variables/ext-variables-dump.c index f42ce9280..356d42e65 100644 --- a/src/lib-sieve/plugins/variables/ext-variables-dump.c +++ b/src/lib-sieve/plugins/variables/ext-variables-dump.c @@ -46,27 +46,29 @@ static void ext_variables_code_dumper_free } static struct ext_variables_dump_context *ext_variables_dump_get_context - (const struct sieve_dumptime_env *denv) +(const struct sieve_extension *this_ext, const struct sieve_dumptime_env *denv) { struct sieve_code_dumper *dumper = denv->cdumper; struct ext_variables_dump_context *dctx = sieve_dump_extension_get_context - (dumper, &variables_extension); + (dumper, this_ext); pool_t pool; if ( dctx == NULL ) { /* Create dumper context */ pool = sieve_code_dumper_pool(dumper); dctx = p_new(pool, struct ext_variables_dump_context, 1); - p_array_init(&dctx->ext_scopes, pool, sieve_extensions_get_count()); + p_array_init(&dctx->ext_scopes, pool, + sieve_extensions_get_count(this_ext->svinst)); - sieve_dump_extension_set_context(dumper, &variables_extension, dctx); + sieve_dump_extension_set_context(dumper, this_ext, dctx); } return dctx; } bool ext_variables_code_dump -(const struct sieve_dumptime_env *denv, sieve_size_t *address) +(const struct sieve_extension *ext, + const struct sieve_dumptime_env *denv, sieve_size_t *address) { struct ext_variables_dump_context *dctx; struct sieve_variable_scope *main_scope; @@ -102,7 +104,7 @@ bool ext_variables_code_dump (void) sieve_variable_scope_declare(main_scope, str_c(identifier)); } - dctx = ext_variables_dump_get_context(denv); + dctx = ext_variables_dump_get_context(ext, denv); dctx->main_scope = main_scope; return TRUE; @@ -113,12 +115,15 @@ bool ext_variables_code_dump */ void sieve_ext_variables_dump_set_scope -(const struct sieve_dumptime_env *denv, const struct sieve_extension *ext, - struct sieve_variable_scope *scope) +(const struct sieve_extension *var_ext, const struct sieve_dumptime_env *denv, + const struct sieve_extension *ext, struct sieve_variable_scope *scope) { - struct ext_variables_dump_context *dctx = ext_variables_dump_get_context(denv); + struct ext_variables_dump_context *dctx = + ext_variables_dump_get_context(var_ext, denv); + + if ( ext->id < 0 ) return; - array_idx_set(&dctx->ext_scopes, (unsigned int) SIEVE_EXT_ID(ext), &scope); + array_idx_set(&dctx->ext_scopes, (unsigned int) ext->id, &scope); } /* @@ -126,10 +131,11 @@ void sieve_ext_variables_dump_set_scope */ const char *ext_variables_dump_get_identifier -(const struct sieve_dumptime_env *denv, const struct sieve_extension *ext, - unsigned int index) +(const struct sieve_extension *var_ext, const struct sieve_dumptime_env *denv, + const struct sieve_extension *ext, unsigned int index) { - struct ext_variables_dump_context *dctx = ext_variables_dump_get_context(denv); + struct ext_variables_dump_context *dctx = + ext_variables_dump_get_context(var_ext, denv); struct sieve_variable_scope *scope; struct sieve_variable *var; @@ -137,12 +143,11 @@ const char *ext_variables_dump_get_identifier scope = dctx->main_scope; else { struct sieve_variable_scope *const *ext_scope; - int ext_id = SIEVE_EXT_ID(ext); - if ( ext_id < 0 || ext_id >= (int) array_count(&dctx->ext_scopes) ) + if ( ext->id < 0 || ext->id >= (int) array_count(&dctx->ext_scopes) ) return NULL; - ext_scope = array_idx(&dctx->ext_scopes, (unsigned int) ext_id); + ext_scope = array_idx(&dctx->ext_scopes, (unsigned int) ext->id); scope = *ext_scope; } diff --git a/src/lib-sieve/plugins/variables/ext-variables-dump.h b/src/lib-sieve/plugins/variables/ext-variables-dump.h index c1d1a0ded..c1633d822 100644 --- a/src/lib-sieve/plugins/variables/ext-variables-dump.h +++ b/src/lib-sieve/plugins/variables/ext-variables-dump.h @@ -11,14 +11,15 @@ */ bool ext_variables_code_dump - (const struct sieve_dumptime_env *denv, sieve_size_t *address); + (const struct sieve_extension *ext, const struct sieve_dumptime_env *denv, + sieve_size_t *address); /* * Variable identifier dump */ const char *ext_variables_dump_get_identifier -(const struct sieve_dumptime_env *denv, const struct sieve_extension *ext, - unsigned int index); +(const struct sieve_extension *var_ext, const struct sieve_dumptime_env *denv, + const struct sieve_extension *ext, unsigned int index); #endif /* __EXT_VARIABLES_DUMP_H */ diff --git a/src/lib-sieve/plugins/variables/ext-variables-modifiers.c b/src/lib-sieve/plugins/variables/ext-variables-modifiers.c index 2a5bedec3..fbe6a2e57 100644 --- a/src/lib-sieve/plugins/variables/ext-variables-modifiers.c +++ b/src/lib-sieve/plugins/variables/ext-variables-modifiers.c @@ -15,12 +15,12 @@ * Core modifiers */ -extern const struct sieve_variables_modifier lower_modifier; -extern const struct sieve_variables_modifier upper_modifier; -extern const struct sieve_variables_modifier lowerfirst_modifier; -extern const struct sieve_variables_modifier upperfirst_modifier; -extern const struct sieve_variables_modifier quotewildcard_modifier; -extern const struct sieve_variables_modifier length_modifier; +extern const struct sieve_variables_modifier_def lower_modifier; +extern const struct sieve_variables_modifier_def upper_modifier; +extern const struct sieve_variables_modifier_def lowerfirst_modifier; +extern const struct sieve_variables_modifier_def upperfirst_modifier; +extern const struct sieve_variables_modifier_def quotewildcard_modifier; +extern const struct sieve_variables_modifier_def length_modifier; enum ext_variables_modifier_code { EXT_VARIABLES_MODIFIER_LOWER, @@ -31,7 +31,7 @@ enum ext_variables_modifier_code { EXT_VARIABLES_MODIFIER_LENGTH }; -const struct sieve_variables_modifier *ext_variables_core_modifiers[] = { +const struct sieve_variables_modifier_def *ext_variables_core_modifiers[] = { &lower_modifier, &upper_modifier, &lowerfirst_modifier, @@ -43,40 +43,69 @@ const struct sieve_variables_modifier *ext_variables_core_modifiers[] = { const unsigned int ext_variables_core_modifiers_count = N_ELEMENTS(ext_variables_core_modifiers); +#define ext_variables_modifier_name(modf) \ + (modf)->object->def->name +#define ext_variables_modifiers_equal(modf1, modf2) \ + ( (modf1)->def == (modf2)->def ) +#define ext_variables_modifiers_equal_precedence(modf1, modf2) \ + ( (modf1)->def->precedence == (modf2)->def->precendence ) + /* * Modifier registry */ void sieve_variables_modifier_register -(struct sieve_validator *valdtr, const struct sieve_variables_modifier *smodf) +(const struct sieve_extension *var_ext, struct sieve_validator *valdtr, + const struct sieve_extension *ext, + const struct sieve_variables_modifier_def *smodf_def) { struct ext_variables_validator_context *ctx = - ext_variables_validator_context_get(valdtr); + ext_variables_validator_context_get(var_ext, valdtr); - sieve_validator_object_registry_add(ctx->modifiers, &smodf->object); + sieve_validator_object_registry_add(ctx->modifiers, ext, &smodf_def->obj_def); } -const struct sieve_variables_modifier *ext_variables_modifier_find -(struct sieve_validator *valdtr, const char *identifier) +bool ext_variables_modifier_exists +(const struct sieve_extension *var_ext, struct sieve_validator *valdtr, + const char *identifier) { struct ext_variables_validator_context *ctx = - ext_variables_validator_context_get(valdtr); - - const struct sieve_object *object = - sieve_validator_object_registry_find(ctx->modifiers, identifier); + ext_variables_validator_context_get(var_ext, valdtr); + + return sieve_validator_object_registry_find(ctx->modifiers, identifier, NULL); +} + +const struct sieve_variables_modifier *ext_variables_modifier_create_instance +(const struct sieve_extension *var_ext, struct sieve_validator *valdtr, + struct sieve_command *cmd, const char *identifier) +{ + struct ext_variables_validator_context *ctx = + ext_variables_validator_context_get(var_ext, valdtr); + struct sieve_object object; + struct sieve_variables_modifier *modf; + pool_t pool; + + if ( !sieve_validator_object_registry_find + (ctx->modifiers, identifier, &object) ) + return NULL; + + pool = sieve_command_pool(cmd); + modf = p_new(pool, struct sieve_variables_modifier, 1); + modf->object = object; + modf->def = (const struct sieve_variables_modifier_def *) object.def; - return (const struct sieve_variables_modifier *) object; + return modf; } void ext_variables_register_core_modifiers -(struct ext_variables_validator_context *ctx) +(const struct sieve_extension *ext, struct ext_variables_validator_context *ctx) { unsigned int i; /* Register core modifiers*/ for ( i = 0; i < ext_variables_core_modifiers_count; i++ ) { sieve_validator_object_registry_add - (ctx->modifiers, &(ext_variables_core_modifiers[i]->object)); + (ctx->modifiers, ext, &(ext_variables_core_modifiers[i]->obj_def)); } } @@ -90,7 +119,7 @@ const struct sieve_operand_class sieve_variables_modifier_operand_class = static const struct sieve_extension_objects core_modifiers = SIEVE_VARIABLES_DEFINE_MODIFIERS(ext_variables_core_modifiers); -const struct sieve_operand modifier_operand = { +const struct sieve_operand_def modifier_operand = { "modifier", &variables_extension, EXT_VARIABLES_OPERAND_MODIFIER, @@ -113,40 +142,40 @@ bool mod_quotewildcard_modify(string_t *in, string_t **result); /* Modifier objects */ -const struct sieve_variables_modifier lower_modifier = { +const struct sieve_variables_modifier_def lower_modifier = { SIEVE_OBJECT("lower", &modifier_operand, EXT_VARIABLES_MODIFIER_LOWER), 40, mod_lower_modify }; -const struct sieve_variables_modifier upper_modifier = { +const struct sieve_variables_modifier_def upper_modifier = { SIEVE_OBJECT("upper", &modifier_operand, EXT_VARIABLES_MODIFIER_UPPER), 40, mod_upper_modify }; -const struct sieve_variables_modifier lowerfirst_modifier = { +const struct sieve_variables_modifier_def lowerfirst_modifier = { SIEVE_OBJECT ("lowerfirst", &modifier_operand, EXT_VARIABLES_MODIFIER_LOWERFIRST), 30, mod_lowerfirst_modify }; -const struct sieve_variables_modifier upperfirst_modifier = { +const struct sieve_variables_modifier_def upperfirst_modifier = { SIEVE_OBJECT ("upperfirst", &modifier_operand, EXT_VARIABLES_MODIFIER_UPPERFIRST), 30, mod_upperfirst_modify }; -const struct sieve_variables_modifier quotewildcard_modifier = { +const struct sieve_variables_modifier_def quotewildcard_modifier = { SIEVE_OBJECT ("quotewildcard", &modifier_operand, EXT_VARIABLES_MODIFIER_QUOTEWILDCARD), 20, mod_quotewildcard_modify }; -const struct sieve_variables_modifier length_modifier = { +const struct sieve_variables_modifier_def length_modifier = { SIEVE_OBJECT("length", &modifier_operand, EXT_VARIABLES_MODIFIER_LENGTH), 10, mod_length_modify diff --git a/src/lib-sieve/plugins/variables/ext-variables-modifiers.h b/src/lib-sieve/plugins/variables/ext-variables-modifiers.h index deb47e496..b6038b993 100644 --- a/src/lib-sieve/plugins/variables/ext-variables-modifiers.h +++ b/src/lib-sieve/plugins/variables/ext-variables-modifiers.h @@ -11,30 +11,40 @@ * Modifier registry */ -const struct sieve_variables_modifier *ext_variables_modifier_find - (struct sieve_validator *validator, const char *identifier); - +bool ext_variables_modifier_exists + (const struct sieve_extension *var_ext, struct sieve_validator *valdtr, + const char *identifier); +const struct sieve_variables_modifier *ext_variables_modifier_create_instance + (const struct sieve_extension *var_ext, struct sieve_validator *valdtr, + struct sieve_command *cmd, const char *identifier); + void ext_variables_register_core_modifiers - (struct ext_variables_validator_context *ctx); + (const struct sieve_extension *var_ext, + struct ext_variables_validator_context *ctx); /* * Modifier operand */ -extern const struct sieve_operand modifier_operand; +extern const struct sieve_operand_def modifier_operand; static inline void ext_variables_opr_modifier_emit -(struct sieve_binary *sbin, const struct sieve_variables_modifier *modf) +(struct sieve_binary *sbin, const struct sieve_extension *ext, + const struct sieve_variables_modifier_def *modf_def) { - sieve_opr_object_emit(sbin, &modf->object); + sieve_opr_object_emit(sbin, ext, &modf_def->obj_def); } -static inline const struct sieve_variables_modifier * - ext_variables_opr_modifier_read -(const struct sieve_runtime_env *renv, sieve_size_t *address) +static inline bool ext_variables_opr_modifier_read +(const struct sieve_runtime_env *renv, sieve_size_t *address, + struct sieve_variables_modifier *modf) { - return (const struct sieve_variables_modifier *) sieve_opr_object_read - (renv, &sieve_variables_modifier_operand_class, address); + if ( !sieve_opr_object_read + (renv, &sieve_variables_modifier_operand_class, address, &modf->object) ) + return FALSE; + + modf->def = (const struct sieve_variables_modifier_def *) modf->object.def; + return TRUE; } static inline bool ext_variables_opr_modifier_dump diff --git a/src/lib-sieve/plugins/variables/ext-variables-operands.c b/src/lib-sieve/plugins/variables/ext-variables-operands.c index 0a52df147..a7028f83c 100644 --- a/src/lib-sieve/plugins/variables/ext-variables-operands.c +++ b/src/lib-sieve/plugins/variables/ext-variables-operands.c @@ -7,12 +7,11 @@ #include "array.h" #include "sieve-common.h" - +#include "sieve-extensions.h" #include "sieve-ast.h" #include "sieve-binary.h" #include "sieve-code.h" #include "sieve-match-types.h" - #include "sieve-commands.h" #include "sieve-validator.h" #include "sieve-generator.h" @@ -22,23 +21,25 @@ #include "ext-variables-common.h" #include "ext-variables-name.h" #include "ext-variables-dump.h" +#include "ext-variables-operands.h" /* * Variable operand */ static bool opr_variable_read_value - (const struct sieve_runtime_env *renv, sieve_size_t *address, string_t **str); + (const struct sieve_runtime_env *renv, const struct sieve_operand *operand, + sieve_size_t *address, string_t **str); static bool opr_variable_dump - (const struct sieve_dumptime_env *denv, sieve_size_t *address, - const char *field_name); + (const struct sieve_dumptime_env *denv, const struct sieve_operand *operand, + sieve_size_t *address, const char *field_name); const struct sieve_opr_string_interface variable_interface = { opr_variable_dump, opr_variable_read_value }; -const struct sieve_operand variable_operand = { +const struct sieve_operand_def variable_operand = { "variable", &variables_extension, EXT_VARIABLES_OPERAND_VARIABLE, @@ -47,25 +48,27 @@ const struct sieve_operand variable_operand = { }; void ext_variables_opr_variable_emit -(struct sieve_binary *sbin, struct sieve_variable *var) +(struct sieve_binary *sbin, const struct sieve_extension *var_ext, + struct sieve_variable *var) { if ( var->ext == NULL ) { /* Default variable storage */ - (void) sieve_operand_emit_code(sbin, &variable_operand); + (void) sieve_operand_emit(sbin, var_ext, &variable_operand); (void) sieve_binary_emit_byte(sbin, 0); (void) sieve_binary_emit_unsigned(sbin, var->index); return; } - (void) sieve_operand_emit_code(sbin, &variable_operand); + (void) sieve_operand_emit(sbin, var_ext, &variable_operand); (void) sieve_binary_emit_extension(sbin, var->ext, 1); (void) sieve_binary_emit_unsigned(sbin, var->index); } static bool opr_variable_dump -(const struct sieve_dumptime_env *denv, sieve_size_t *address, - const char *field_name) +(const struct sieve_dumptime_env *denv, const struct sieve_operand *operand, + sieve_size_t *address, const char *field_name) { + const struct sieve_extension *this_ext = operand->ext; unsigned int index = 0; const struct sieve_extension *ext; unsigned int code = 1; /* Initially set to offset value */ @@ -77,7 +80,7 @@ static bool opr_variable_dump if ( !sieve_binary_read_unsigned(denv->sbin, address, &index) ) return FALSE; - identifier = ext_variables_dump_get_identifier(denv, ext, index); + identifier = ext_variables_dump_get_identifier(this_ext, denv, ext, index); identifier = identifier == NULL ? "??" : identifier; if ( ext == NULL ) { @@ -90,17 +93,19 @@ static bool opr_variable_dump } else { if ( field_name != NULL ) sieve_code_dumpf(denv, "%s: VAR [%s] ${%s} (%ld)", - field_name, ext->name, identifier, (long) index); + field_name, sieve_extension_name(ext), identifier, (long) index); else sieve_code_dumpf(denv, "VAR [%s] ${%s} (%ld)", - ext->name, identifier, (long) index); + sieve_extension_name(ext), identifier, (long) index); } return TRUE; } static bool opr_variable_read_value -(const struct sieve_runtime_env *renv, sieve_size_t *address, string_t **str) +(const struct sieve_runtime_env *renv, const struct sieve_operand *operand, + sieve_size_t *address, string_t **str) { + const struct sieve_extension *this_ext = operand->ext; const struct sieve_extension *ext; unsigned int code = 1; /* Initially set to offset value */ struct sieve_variable_storage *storage; @@ -109,7 +114,7 @@ static bool opr_variable_read_value if ( !sieve_binary_read_extension(renv->sbin, address, &code, &ext) ) return FALSE; - storage = sieve_ext_variables_get_storage(renv->interp, ext); + storage = sieve_ext_variables_get_storage(this_ext, renv->interp, ext); if ( storage == NULL ) return FALSE; @@ -138,14 +143,14 @@ bool sieve_variable_operand_read_data unsigned int code = 1; /* Initially set to offset value */ unsigned int idx = 0; - if ( operand != &variable_operand ) { + if ( !sieve_operand_is_variable(operand) ) { return FALSE; } if ( !sieve_binary_read_extension(renv->sbin, address, &code, &ext) ) - return FALSE; + return FALSE; - *storage = sieve_ext_variables_get_storage(renv->interp, ext); + *storage = sieve_ext_variables_get_storage(operand->ext, renv->interp, ext); if ( *storage == NULL ) return FALSE; @@ -160,10 +165,13 @@ bool sieve_variable_operand_read (const struct sieve_runtime_env *renv, sieve_size_t *address, struct sieve_variable_storage **storage, unsigned int *var_index) { - const struct sieve_operand *operand = sieve_operand_read(renv->sbin, address); + struct sieve_operand operand; + + if ( !sieve_operand_read(renv->sbin, address, &operand) ) + return FALSE; return sieve_variable_operand_read_data - (renv, operand, address, storage, var_index); + (renv, &operand, address, storage, var_index); } /* @@ -171,17 +179,18 @@ bool sieve_variable_operand_read */ static bool opr_match_value_read - (const struct sieve_runtime_env *renv, sieve_size_t *address, string_t **str); + (const struct sieve_runtime_env *renv, const struct sieve_operand *operand, + sieve_size_t *address, string_t **str); static bool opr_match_value_dump - (const struct sieve_dumptime_env *denv, sieve_size_t *address, - const char *field_name); + (const struct sieve_dumptime_env *denv, const struct sieve_operand *operand, + sieve_size_t *address, const char *field_name); const struct sieve_opr_string_interface match_value_interface = { opr_match_value_dump, opr_match_value_read }; -const struct sieve_operand match_value_operand = { +const struct sieve_operand_def match_value_operand = { "match-value", &variables_extension, EXT_VARIABLES_OPERAND_MATCH_VALUE, @@ -190,21 +199,24 @@ const struct sieve_operand match_value_operand = { }; void ext_variables_opr_match_value_emit -(struct sieve_binary *sbin, unsigned int index) +(struct sieve_binary *sbin, const struct sieve_extension *ext, + unsigned int index) { - (void) sieve_operand_emit_code(sbin, &match_value_operand); + (void) sieve_operand_emit(sbin, ext, &match_value_operand); (void) sieve_binary_emit_unsigned(sbin, index); } static bool opr_match_value_dump -(const struct sieve_dumptime_env *denv, sieve_size_t *address, - const char *field_name) +(const struct sieve_dumptime_env *denv, + const struct sieve_operand *operand ATTR_UNUSED, + sieve_size_t *address, const char *field_name) { unsigned int index = 0; if (sieve_binary_read_unsigned(denv->sbin, address, &index) ) { if ( field_name != NULL ) - sieve_code_dumpf(denv, "%s: MATCHVAL %lu", field_name, (unsigned long) index); + sieve_code_dumpf + (denv, "%s: MATCHVAL %lu", field_name, (unsigned long) index); else sieve_code_dumpf(denv, "MATCHVAL %lu", (unsigned long) index); @@ -215,7 +227,9 @@ static bool opr_match_value_dump } static bool opr_match_value_read -(const struct sieve_runtime_env *renv, sieve_size_t *address, string_t **str) +(const struct sieve_runtime_env *renv, + const struct sieve_operand *operand ATTR_UNUSED, + sieve_size_t *address, string_t **str) { unsigned int index = 0; diff --git a/src/lib-sieve/plugins/variables/ext-variables-operands.h b/src/lib-sieve/plugins/variables/ext-variables-operands.h index e5eee69cd..a5d973480 100644 --- a/src/lib-sieve/plugins/variables/ext-variables-operands.h +++ b/src/lib-sieve/plugins/variables/ext-variables-operands.h @@ -16,19 +16,33 @@ * Variable operand */ -extern const struct sieve_operand variable_operand; +extern const struct sieve_operand_def variable_operand; void ext_variables_opr_variable_emit - (struct sieve_binary *sbin, struct sieve_variable *var); + (struct sieve_binary *sbin, const struct sieve_extension *var_ext, + struct sieve_variable *var); + +bool ext_variables_opr_variable_read + (const struct sieve_runtime_env *renv, sieve_size_t *address, + struct sieve_variable_storage **storage, unsigned int *var_index); /* * Match value operand */ -extern const struct sieve_operand match_value_operand; +extern const struct sieve_operand_def match_value_operand; void ext_variables_opr_match_value_emit - (struct sieve_binary *sbin, unsigned int index); + (struct sieve_binary *sbin, const struct sieve_extension *ext, + unsigned int index); + +/* + * Variable string operand + */ + +void ext_variables_opr_variable_string_emit + (struct sieve_binary *sbin, unsigned int elements); + #endif /* __EXT_VARIABLES_OPERANDS_H */ diff --git a/src/lib-sieve/plugins/variables/ext-variables.c b/src/lib-sieve/plugins/variables/ext-variables.c index 6734b71d5..ebb26245c 100644 --- a/src/lib-sieve/plugins/variables/ext-variables.c +++ b/src/lib-sieve/plugins/variables/ext-variables.c @@ -38,7 +38,7 @@ * Operations */ -const struct sieve_operation *ext_variables_operations[] = { +const struct sieve_operation_def *ext_variables_operations[] = { &cmd_set_operation, &tst_string_operation }; @@ -47,7 +47,7 @@ const struct sieve_operation *ext_variables_operations[] = { * Operands */ -const struct sieve_operand *ext_variables_operands[] = { +const struct sieve_operand_def *ext_variables_operands[] = { &variable_operand, &match_value_operand, &modifier_operand @@ -57,13 +57,11 @@ const struct sieve_operand *ext_variables_operands[] = { * Extension */ -static bool ext_variables_validator_load(struct sieve_validator *validator); - -static int ext_my_id = -1; +static bool ext_variables_validator_load + (const struct sieve_extension *ext, struct sieve_validator *validator); -const struct sieve_extension variables_extension = { +const struct sieve_extension_def variables_extension = { "variables", - &ext_my_id, NULL, NULL, ext_variables_validator_load, ext_variables_generator_load, @@ -75,15 +73,15 @@ const struct sieve_extension variables_extension = { }; static bool ext_variables_validator_load - (struct sieve_validator *validator) +(const struct sieve_extension *ext, struct sieve_validator *validator) { - sieve_validator_argument_override(validator, SAT_VAR_STRING, - &variable_string_argument); + sieve_validator_argument_override + (validator, SAT_VAR_STRING, ext, &variable_string_argument); - sieve_validator_register_command(validator, &cmd_set); - sieve_validator_register_command(validator, &tst_string); + sieve_validator_register_command(validator, ext, &cmd_set); + sieve_validator_register_command(validator, ext, &tst_string); - ext_variables_validator_initialize(validator); + ext_variables_validator_initialize(ext, validator); return TRUE; } diff --git a/src/lib-sieve/plugins/variables/sieve-ext-variables.h b/src/lib-sieve/plugins/variables/sieve-ext-variables.h index f65bd2ff7..6cc3c0519 100644 --- a/src/lib-sieve/plugins/variables/sieve-ext-variables.h +++ b/src/lib-sieve/plugins/variables/sieve-ext-variables.h @@ -11,9 +11,24 @@ #include "sieve-common.h" #include "sieve-extensions.h" #include "sieve-objects.h" +#include "sieve-code.h" #include "ext-variables-limits.h" +/* + * Variable extension + */ + +/* FIXME: this is not suitable for future plugin support */ + +extern const struct sieve_extension_def variables_extension; + +static inline const struct sieve_extension *sieve_ext_variables_get_extension +(struct sieve_instance *svinst) +{ + return sieve_extension_register(svinst, &variables_extension, FALSE); +} + /* * Variable scope */ @@ -94,30 +109,32 @@ bool sieve_variable_get_identifier * Variables access */ -bool sieve_ext_variables_is_active(struct sieve_validator *valdtr); +bool sieve_ext_variables_is_active + (const struct sieve_extension *var_ext, struct sieve_validator *valdtr); struct sieve_variable_scope *sieve_ext_variables_get_main_scope - (struct sieve_validator *validator); + (const struct sieve_extension *var_ext, struct sieve_validator *valdtr); struct sieve_variable_storage *sieve_ext_variables_get_storage - (struct sieve_interpreter *interp, const struct sieve_extension *ext); + (const struct sieve_extension *var_ext, struct sieve_interpreter *interp, + const struct sieve_extension *ext); void sieve_ext_variables_set_storage - (struct sieve_interpreter *interp, struct sieve_variable_storage *storage, - const struct sieve_extension *ext); + (const struct sieve_extension *var_ext, struct sieve_interpreter *interp, + struct sieve_variable_storage *storage, const struct sieve_extension *ext); /* * Variable arguments */ bool sieve_variable_argument_activate -(struct sieve_validator *validator, struct sieve_command_context *cmd, - struct sieve_ast_argument *arg, bool assignment); +(const struct sieve_extension *this_ext, struct sieve_validator *valdtr, + struct sieve_command *cmd, struct sieve_ast_argument *arg, bool assignment); /* * Variable operands */ -extern const struct sieve_operand variable_operand; +extern const struct sieve_operand_def variable_operand; bool sieve_variable_operand_read_data (const struct sieve_runtime_env *renv, const struct sieve_operand *operand, @@ -130,35 +147,44 @@ bool sieve_variable_operand_read static inline bool sieve_operand_is_variable (const struct sieve_operand *operand) { - return ( operand != NULL && operand == &variable_operand ); + return ( operand != NULL && operand->def != NULL && + operand->def == &variable_operand ); } /* * Modifiers */ -struct sieve_variables_modifier { - struct sieve_object object; +struct sieve_variables_modifier_def { + struct sieve_object_def obj_def; unsigned int precedence; bool (*modify)(string_t *in, string_t **result); }; +struct sieve_variables_modifier { + struct sieve_object object; + + const struct sieve_variables_modifier_def *def; +}; + extern const struct sieve_operand_class sieve_variables_modifier_operand_class; #define SIEVE_VARIABLES_DEFINE_MODIFIER(OP) SIEVE_EXT_DEFINE_OBJECT(OP) #define SIEVE_VARIABLES_DEFINE_MODIFIERS(OPS) SIEVE_EXT_DEFINE_OBJECTS(OPS) void sieve_variables_modifier_register - (struct sieve_validator *valdtr, const struct sieve_variables_modifier *smodf); + (const struct sieve_extension *var_ext, struct sieve_validator *valdtr, + const struct sieve_extension *ext, + const struct sieve_variables_modifier_def *smodf); /* * Code dumping */ void sieve_ext_variables_dump_set_scope -(const struct sieve_dumptime_env *denv, const struct sieve_extension *ext, - struct sieve_variable_scope *scope); +(const struct sieve_extension *var_ext, const struct sieve_dumptime_env *denv, + const struct sieve_extension *ext, struct sieve_variable_scope *scope); #endif /* __SIEVE_EXT_VARIABLES_H */ diff --git a/src/lib-sieve/plugins/variables/tst-string.c b/src/lib-sieve/plugins/variables/tst-string.c index 63179f524..2cfe12197 100644 --- a/src/lib-sieve/plugins/variables/tst-string.c +++ b/src/lib-sieve/plugins/variables/tst-string.c @@ -23,13 +23,14 @@ */ static bool tst_string_registered - (struct sieve_validator *validator, struct sieve_command_registration *cmd_reg); + (struct sieve_validator *valdtr, const struct sieve_extension *ext, + struct sieve_command_registration *cmd_reg); static bool tst_string_validate - (struct sieve_validator *validator, struct sieve_command_context *tst); + (struct sieve_validator *valdtr, struct sieve_command *tst); static bool tst_string_generate - (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx); + (const struct sieve_codegen_env *cgenv, struct sieve_command *ctx); -const struct sieve_command tst_string = { +const struct sieve_command_def tst_string = { "string", SCT_TEST, 2, 0, FALSE, FALSE, @@ -45,13 +46,11 @@ const struct sieve_command tst_string = { */ static bool tst_string_operation_dump - (const struct sieve_operation *op, - const struct sieve_dumptime_env *denv, sieve_size_t *address); + (const struct sieve_dumptime_env *denv, sieve_size_t *address); static int tst_string_operation_execute - (const struct sieve_operation *op, - const struct sieve_runtime_env *renv, sieve_size_t *address); + (const struct sieve_runtime_env *renv, sieve_size_t *address); -const struct sieve_operation tst_string_operation = { +const struct sieve_operation_def tst_string_operation = { "STRING", &variables_extension, EXT_VARIABLES_OPERATION_STRING, @@ -74,11 +73,12 @@ enum tst_string_optional { */ static bool tst_string_registered - (struct sieve_validator *validator, struct sieve_command_registration *cmd_reg) +(struct sieve_validator *valdtr, const struct sieve_extension *ext ATTR_UNUSED, + struct sieve_command_registration *cmd_reg) { /* The order of these is not significant */ - sieve_comparators_link_tag(validator, cmd_reg, OPT_COMPARATOR); - sieve_match_types_link_tags(validator, cmd_reg, OPT_MATCH_TYPE); + sieve_comparators_link_tag(valdtr, cmd_reg, OPT_COMPARATOR); + sieve_match_types_link_tags(valdtr, cmd_reg, OPT_MATCH_TYPE); return TRUE; } @@ -88,31 +88,35 @@ static bool tst_string_registered */ static bool tst_string_validate - (struct sieve_validator *validator, struct sieve_command_context *tst) +(struct sieve_validator *valdtr, struct sieve_command *tst) { struct sieve_ast_argument *arg = tst->first_positional; + const struct sieve_match_type mcht_default = + SIEVE_MATCH_TYPE_DEFAULT(is_match_type); + const struct sieve_comparator cmp_default = + SIEVE_COMPARATOR_DEFAULT(i_octet_comparator); if ( !sieve_validate_positional_argument - (validator, tst, arg, "source", 1, SAAT_STRING_LIST) ) { + (valdtr, tst, arg, "source", 1, SAAT_STRING_LIST) ) { return FALSE; } - if ( !sieve_validator_argument_activate(validator, tst, arg, FALSE) ) + if ( !sieve_validator_argument_activate(valdtr, tst, arg, FALSE) ) return FALSE; arg = sieve_ast_argument_next(arg); if ( !sieve_validate_positional_argument - (validator, tst, arg, "key list", 2, SAAT_STRING_LIST) ) { + (valdtr, tst, arg, "key list", 2, SAAT_STRING_LIST) ) { return FALSE; } - if ( !sieve_validator_argument_activate(validator, tst, arg, FALSE) ) + if ( !sieve_validator_argument_activate(valdtr, tst, arg, FALSE) ) return FALSE; /* Validate the key argument to a specified match type */ return sieve_match_type_validate - (validator, tst, arg, &is_match_type, &i_octet_comparator); + (valdtr, tst, arg, &mcht_default, &cmp_default); } /* @@ -120,12 +124,12 @@ static bool tst_string_validate */ static bool tst_string_generate - (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx) +(const struct sieve_codegen_env *cgenv, struct sieve_command *cmd) { - sieve_operation_emit_code(cgenv->sbin, &tst_string_operation); + sieve_operation_emit(cgenv->sbin, cmd->ext, &tst_string_operation); /* Generate arguments */ - if ( !sieve_generate_arguments(cgenv, ctx, NULL) ) + if ( !sieve_generate_arguments(cgenv, cmd, NULL) ) return FALSE; return TRUE; @@ -136,8 +140,7 @@ static bool tst_string_generate */ static bool tst_string_operation_dump -(const struct sieve_operation *op ATTR_UNUSED, - const struct sieve_dumptime_env *denv, sieve_size_t *address) +(const struct sieve_dumptime_env *denv, sieve_size_t *address) { int opt_code = 0; @@ -161,14 +164,15 @@ static bool tst_string_operation_dump */ static int tst_string_operation_execute -(const struct sieve_operation *op ATTR_UNUSED, - const struct sieve_runtime_env *renv, sieve_size_t *address) +(const struct sieve_runtime_env *renv, sieve_size_t *address) { int ret, mret; bool result = TRUE; int opt_code = 0; - const struct sieve_comparator *cmp = &i_octet_comparator; - const struct sieve_match_type *mtch = &is_match_type; + struct sieve_match_type mcht = + SIEVE_MATCH_TYPE_DEFAULT(is_match_type); + struct sieve_comparator cmp = + SIEVE_COMPARATOR_DEFAULT(i_octet_comparator); struct sieve_match_context *mctx; struct sieve_coded_stringlist *source; struct sieve_coded_stringlist *key_list; @@ -181,7 +185,7 @@ static int tst_string_operation_execute /* Handle match-type and comparator operands */ if ( (ret=sieve_match_read_optional_operands - (renv, address, &opt_code, &cmp, &mtch)) <= 0 ) + (renv, address, &opt_code, &cmp, &mcht)) <= 0 ) return ret; /* Check whether we neatly finished the list of optional operands*/ @@ -208,7 +212,7 @@ static int tst_string_operation_execute sieve_runtime_trace(renv, "STRING test"); - mctx = sieve_match_begin(renv->interp, mtch, cmp, NULL, key_list); + mctx = sieve_match_begin(renv->interp, &mcht, &cmp, NULL, key_list); /* Iterate through all requested strings to match */ src_item = NULL; diff --git a/src/lib-sieve/sieve-actions.c b/src/lib-sieve/sieve-actions.c index 4e8989256..be8bb1468 100644 --- a/src/lib-sieve/sieve-actions.c +++ b/src/lib-sieve/sieve-actions.c @@ -34,21 +34,45 @@ const char *sieve_action_get_location(const struct sieve_action_exec_env *aenv) const struct sieve_operand_class sieve_side_effect_operand_class = { "SIDE-EFFECT" }; +bool sieve_opr_side_effect_read +(const struct sieve_runtime_env *renv, sieve_size_t *address, + struct sieve_side_effect *seffect) +{ + const struct sieve_side_effect_def *sdef; + + seffect->context = NULL; + + if ( !sieve_opr_object_read + (renv, &sieve_side_effect_operand_class, address, &seffect->object) ) + return FALSE; + + sdef = seffect->def = + (const struct sieve_side_effect_def *) seffect->object.def; + + if ( sdef->read_context != NULL && + !sdef->read_context(seffect, renv, address, &seffect->context) ) { + return FALSE; + } + + return TRUE; +} + bool sieve_opr_side_effect_dump (const struct sieve_dumptime_env *denv, sieve_size_t *address) { - const struct sieve_object *obj; - const struct sieve_side_effect *seffect; + struct sieve_side_effect seffect; + const struct sieve_side_effect_def *sdef; if ( !sieve_opr_object_dump - (denv, &sieve_side_effect_operand_class, address, &obj) ) + (denv, &sieve_side_effect_operand_class, address, &seffect.object) ) return FALSE; - seffect = (const struct sieve_side_effect *) obj; + sdef = seffect.def = + (const struct sieve_side_effect_def *) seffect.object.def; - if ( seffect->dump_context != NULL ) { + if ( sdef->dump_context != NULL ) { sieve_code_descend(denv); - if ( !seffect->dump_context(seffect, denv, address) ) { + if ( !sdef->dump_context(&seffect, denv, address) ) { return FALSE; } sieve_code_ascend(denv); @@ -64,19 +88,20 @@ bool sieve_opr_side_effect_dump /* Forward declarations */ static bool act_store_equals - (const struct sieve_script_env *senv, const void *ctx1, const void *ctx2); + (const struct sieve_script_env *senv, + const struct sieve_action *act1, const struct sieve_action *act2); static int act_store_check_duplicate (const struct sieve_runtime_env *renv, - const struct sieve_action_data *act, - const struct sieve_action_data *act_other); + const struct sieve_action *act, + const struct sieve_action *act_other); static void act_store_print (const struct sieve_action *action, - const struct sieve_result_print_env *rpenv, void *context, bool *keep); + const struct sieve_result_print_env *rpenv, bool *keep); static bool act_store_start (const struct sieve_action *action, - const struct sieve_action_exec_env *aenv, void *context, void **tr_context); + const struct sieve_action_exec_env *aenv, void **tr_context); static bool act_store_execute (const struct sieve_action *action, const struct sieve_action_exec_env *aenv, void *tr_context); @@ -89,7 +114,7 @@ static void act_store_rollback /* Action object */ -const struct sieve_action act_store = { +const struct sieve_action_def act_store = { "store", SIEVE_ACTFLAG_TRIES_DELIVER, act_store_equals, @@ -117,7 +142,7 @@ int sieve_act_store_add_to_result act = p_new(pool, struct act_store_context, 1); act->mailbox = p_strdup(pool, mailbox); - return sieve_result_add_action(renv, &act_store, seffects, + return sieve_result_add_action(renv, NULL, &act_store, seffects, source_line, (void *) act, 0); } @@ -181,10 +206,13 @@ void sieve_act_store_get_storage_error /* Equality */ static bool act_store_equals -(const struct sieve_script_env *senv, const void *ctx1, const void *ctx2) +(const struct sieve_script_env *senv, + const struct sieve_action *act1, const struct sieve_action *act2) { - struct act_store_context *st_ctx1 = (struct act_store_context *) ctx1; - struct act_store_context *st_ctx2 = (struct act_store_context *) ctx2; + struct act_store_context *st_ctx1 = + ( act1 == NULL ? NULL : (struct act_store_context *) act1->context ); + struct act_store_context *st_ctx2 = + ( act2 == NULL ? NULL : (struct act_store_context *) act2->context ); const char *mailbox1, *mailbox2; /* FIXME: consider namespace aliases */ @@ -209,20 +237,19 @@ static bool act_store_equals static int act_store_check_duplicate (const struct sieve_runtime_env *renv, - const struct sieve_action_data *act, - const struct sieve_action_data *act_other) + const struct sieve_action *act, + const struct sieve_action *act_other) { - return ( act_store_equals(renv->scriptenv, act->context, act_other->context) - ? 1 : 0 ); + return ( act_store_equals(renv->scriptenv, act, act_other) ? 1 : 0 ); } /* Result printing */ static void act_store_print -(const struct sieve_action *action ATTR_UNUSED, - const struct sieve_result_print_env *rpenv, void *context, bool *keep) +(const struct sieve_action *action, + const struct sieve_result_print_env *rpenv, bool *keep) { - struct act_store_context *ctx = (struct act_store_context *) context; + struct act_store_context *ctx = (struct act_store_context *) action->context; const char *mailbox; mailbox = ( ctx == NULL ? @@ -318,10 +345,10 @@ static struct mailbox *act_store_mailbox_open } static bool act_store_start -(const struct sieve_action *action ATTR_UNUSED, - const struct sieve_action_exec_env *aenv, void *context, void **tr_context) +(const struct sieve_action *action, + const struct sieve_action_exec_env *aenv, void **tr_context) { - struct act_store_context *ctx = (struct act_store_context *) context; + struct act_store_context *ctx = (struct act_store_context *) action->context; const struct sieve_script_env *senv = aenv->scriptenv; const struct sieve_message_data *msgdata = aenv->msgdata; struct act_store_transaction *trans; diff --git a/src/lib-sieve/sieve-actions.h b/src/lib-sieve/sieve-actions.h index 8a735274b..a8fa62e46 100644 --- a/src/lib-sieve/sieve-actions.h +++ b/src/lib-sieve/sieve-actions.h @@ -33,52 +33,41 @@ enum sieve_action_flags { SIEVE_ACTFLAG_TRIES_DELIVER = (1 << 0), SIEVE_ACTFLAG_SENDS_RESPONSE = (1 << 1) }; - -/* - * - */ -struct sieve_action_data { - const struct sieve_action *action; - const char *location; - void *context; - bool executed; -}; - /* - * Action object + * Action definition */ -struct sieve_action { +struct sieve_action_def { const char *name; unsigned int flags; bool (*equals) - (const struct sieve_script_env *senv, const void *ctx1, const void *ctx2); + (const struct sieve_script_env *senv, const struct sieve_action *act1, + const struct sieve_action *act2); /* Result verification */ int (*check_duplicate) (const struct sieve_runtime_env *renv, - const struct sieve_action_data *act, - const struct sieve_action_data *act_other); + const struct sieve_action *act, + const struct sieve_action *act_other); int (*check_conflict) (const struct sieve_runtime_env *renv, - const struct sieve_action_data *act, - const struct sieve_action_data *act_other); + const struct sieve_action *act, + const struct sieve_action *act_other); /* Result printing */ void (*print) (const struct sieve_action *action, - const struct sieve_result_print_env *penv, void *context, bool *keep); + const struct sieve_result_print_env *penv, bool *keep); /* Result execution */ bool (*start) (const struct sieve_action *action, - const struct sieve_action_exec_env *aenv, void *context, - void **tr_context); + const struct sieve_action_exec_env *aenv, void **tr_context); bool (*execute) (const struct sieve_action *action, const struct sieve_action_exec_env *aenv, void *tr_context); @@ -90,18 +79,31 @@ struct sieve_action { const struct sieve_action_exec_env *aenv, void *tr_context, bool success); }; +/* + * Action instance + */ + +struct sieve_action { + const struct sieve_action_def *def; + const struct sieve_extension *ext; + + const char *location; + void *context; + bool executed; +}; + /* * Action side effects */ /* Side effect object */ -struct sieve_side_effect { - struct sieve_object object; +struct sieve_side_effect_def { + struct sieve_object_def obj_def; /* The action it is supposed to link to */ - const struct sieve_action *to_action; + const struct sieve_action_def *to_action; /* Context coding */ @@ -117,33 +119,38 @@ struct sieve_side_effect { int (*merge) (const struct sieve_runtime_env *renv, const struct sieve_action *action, - const struct sieve_side_effect *seffect, - void **old_context, void *new_context); + const struct sieve_side_effect *old_seffect, + const struct sieve_side_effect *new_seffect, void **old_context); /* Result printing */ void (*print) (const struct sieve_side_effect *seffect, const struct sieve_action *action, - const struct sieve_result_print_env *penv, void *se_context, bool *keep); + const struct sieve_result_print_env *penv, bool *keep); /* Result execution */ bool (*pre_execute) (const struct sieve_side_effect *seffect, const struct sieve_action *action, - const struct sieve_action_exec_env *aenv, void **se_context, + const struct sieve_action_exec_env *aenv, void **context, void *tr_context); bool (*post_execute) (const struct sieve_side_effect *seffect, const struct sieve_action *action, - const struct sieve_action_exec_env *aenv, void *se_context, - void *tr_context); + const struct sieve_action_exec_env *aenv, void *tr_context); void (*post_commit) (const struct sieve_side_effect *seffect, const struct sieve_action *action, - const struct sieve_action_exec_env *aenv, void *se_context, - void *tr_context, bool *keep); + const struct sieve_action_exec_env *aenv, void *tr_context, bool *keep); void (*rollback) (const struct sieve_side_effect *seffect, const struct sieve_action *action, - const struct sieve_action_exec_env *aenv, void *se_context, - void *tr_context, bool success); + const struct sieve_action_exec_env *aenv, void *tr_context, bool success); +}; + +struct sieve_side_effect { + struct sieve_object object; + + const struct sieve_side_effect_def *def; + + void *context; }; /* @@ -158,17 +165,15 @@ struct sieve_side_effect { extern const struct sieve_operand_class sieve_side_effect_operand_class; static inline void sieve_opr_side_effect_emit -(struct sieve_binary *sbin, const struct sieve_side_effect *seff) +(struct sieve_binary *sbin, const struct sieve_extension *ext, + const struct sieve_side_effect_def *seff) { - sieve_opr_object_emit(sbin, &seff->object); + sieve_opr_object_emit(sbin, ext, &seff->obj_def); } -static inline const struct sieve_side_effect *sieve_opr_side_effect_read -(const struct sieve_runtime_env *renv, sieve_size_t *address) -{ - return (const struct sieve_side_effect *) sieve_opr_object_read - (renv, &sieve_side_effect_operand_class, address); -} +bool sieve_opr_side_effect_read + (const struct sieve_runtime_env *renv, sieve_size_t *address, + struct sieve_side_effect *seffect); bool sieve_opr_side_effect_dump (const struct sieve_dumptime_env *denv, sieve_size_t *address); @@ -177,9 +182,9 @@ bool sieve_opr_side_effect_dump * Core actions */ -extern const struct sieve_action act_redirect; -extern const struct sieve_action act_store; -extern const struct sieve_action act_discard; +extern const struct sieve_action_def act_redirect; +extern const struct sieve_action_def act_store; +extern const struct sieve_action_def act_discard; /* * Store action diff --git a/src/lib-sieve/sieve-address-parts.c b/src/lib-sieve/sieve-address-parts.c index 064c358de..45fde77b5 100644 --- a/src/lib-sieve/sieve-address-parts.c +++ b/src/lib-sieve/sieve-address-parts.c @@ -29,7 +29,7 @@ * Default address parts */ -const struct sieve_address_part *sieve_core_address_parts[] = { +const struct sieve_address_part_def *sieve_core_address_parts[] = { &all_address_part, &local_address_part, &domain_address_part }; @@ -40,68 +40,97 @@ const unsigned int sieve_core_address_parts_count = * Address-part 'extension' */ -static int ext_my_id = -1; +static bool addrp_validator_load + (const struct sieve_extension *ext, struct sieve_validator *valdtr); -static bool addrp_validator_load(struct sieve_validator *validator); - -const struct sieve_extension address_part_extension = { +const struct sieve_extension_def address_part_extension = { "@address-parts", - &ext_my_id, NULL, NULL, addrp_validator_load, NULL, NULL, NULL, NULL, NULL, SIEVE_EXT_DEFINE_NO_OPERATIONS, SIEVE_EXT_DEFINE_NO_OPERANDS /* Defined as core operand */ }; - -static const struct sieve_extension *ext_this = &address_part_extension; /* * Validator context: * name-based address-part registry. */ + +static struct sieve_validator_object_registry *_get_object_registry +(struct sieve_validator *valdtr) +{ + struct sieve_instance *svinst; + const struct sieve_extension *adrp_ext; + + svinst = sieve_validator_svinst(valdtr); + adrp_ext = sieve_get_address_part_extension(svinst); + return sieve_validator_object_registry_get(valdtr, adrp_ext); +} void sieve_address_part_register -(struct sieve_validator *validator, const struct sieve_address_part *addrp) +(struct sieve_validator *valdtr, const struct sieve_extension *ext, + const struct sieve_address_part_def *addrp_def) { - struct sieve_validator_object_registry *regs = - sieve_validator_object_registry_get(validator, ext_this); + struct sieve_validator_object_registry *regs = _get_object_registry(valdtr); - sieve_validator_object_registry_add(regs, &addrp->object); + sieve_validator_object_registry_add(regs, ext, &addrp_def->obj_def); } -const struct sieve_address_part *sieve_address_part_find -(struct sieve_validator *validator, const char *identifier) +static bool sieve_address_part_exists +(struct sieve_validator *valdtr, const char *identifier) { - struct sieve_validator_object_registry *regs = - sieve_validator_object_registry_get(validator, ext_this); - const struct sieve_object *object = - sieve_validator_object_registry_find(regs, identifier); + struct sieve_validator_object_registry *regs = _get_object_registry(valdtr); - return (const struct sieve_address_part *) object; + return sieve_validator_object_registry_find(regs, identifier, NULL); } -bool addrp_validator_load(struct sieve_validator *validator) +static const struct sieve_address_part *sieve_address_part_create_instance +(struct sieve_validator *valdtr, struct sieve_command *cmd, + const char *identifier) +{ + struct sieve_validator_object_registry *regs = _get_object_registry(valdtr); + struct sieve_object object; + struct sieve_address_part *addrp; + + if ( !sieve_validator_object_registry_find(regs, identifier, &object) ) + return NULL; + + addrp = p_new(sieve_command_pool(cmd), struct sieve_address_part, 1); + addrp->object = object; + addrp->def = (const struct sieve_address_part_def *) object.def; + + return addrp; +} + +static bool addrp_validator_load +(const struct sieve_extension *ext, struct sieve_validator *valdtr) { struct sieve_validator_object_registry *regs = - sieve_validator_object_registry_init(validator, ext_this); + sieve_validator_object_registry_init(valdtr, ext); unsigned int i; /* Register core address-parts */ for ( i = 0; i < sieve_core_address_parts_count; i++ ) { sieve_validator_object_registry_add - (regs, &(sieve_core_address_parts[i]->object)); + (regs, NULL, &(sieve_core_address_parts[i]->obj_def)); } return TRUE; } void sieve_address_parts_link_tags - (struct sieve_validator *validator, - struct sieve_command_registration *cmd_reg, int id_code) +(struct sieve_validator *valdtr, struct sieve_command_registration *cmd_reg, + int id_code) { + struct sieve_instance *svinst; + const struct sieve_extension *adrp_ext; + + svinst = sieve_validator_svinst(valdtr); + adrp_ext = sieve_get_address_part_extension(svinst); + sieve_validator_register_tag - (validator, cmd_reg, &address_part_tag, id_code); + (valdtr, cmd_reg, adrp_ext, &address_part_tag, id_code); } /* @@ -111,51 +140,48 @@ void sieve_address_parts_link_tags /* Forward declarations */ static bool tag_address_part_is_instance_of - (struct sieve_validator *validator, struct sieve_command_context *cmd, - struct sieve_ast_argument *arg); + (struct sieve_validator *valdtr, struct sieve_command *cmd, + const struct sieve_extension *ext, const char *identifier, void **data); static bool tag_address_part_validate - (struct sieve_validator *validator, struct sieve_ast_argument **arg, - struct sieve_command_context *cmd); + (struct sieve_validator *valdtr, struct sieve_ast_argument **arg, + struct sieve_command *cmd); static bool tag_address_part_generate (const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, - struct sieve_command_context *cmd); + struct sieve_command *cmd); /* Argument object */ -const struct sieve_argument address_part_tag = { +const struct sieve_argument_def address_part_tag = { "ADDRESS-PART", tag_address_part_is_instance_of, - NULL, tag_address_part_validate, - NULL, + NULL, NULL, tag_address_part_generate }; /* Argument implementation */ static bool tag_address_part_is_instance_of -(struct sieve_validator *validator, struct sieve_command_context *cmd, - struct sieve_ast_argument *arg) +(struct sieve_validator *valdtr, struct sieve_command *cmd, + const struct sieve_extension *ext ATTR_UNUSED, const char *identifier, + void **data) { - struct sieve_address_part_context *adpctx; - const struct sieve_address_part *addrp = sieve_address_part_find - (validator, sieve_ast_argument_tag(arg)); - - if ( addrp == NULL ) return FALSE; - - adpctx = p_new(sieve_command_pool(cmd), struct sieve_address_part_context, 1); - adpctx->command_ctx = cmd; - adpctx->address_part = addrp; + const struct sieve_address_part *addrp; - /* Store address-part in context */ - arg->context = (void *) adpctx; + if ( data == NULL ) + return sieve_address_part_exists(valdtr, identifier); + if ( (addrp=sieve_address_part_create_instance + (valdtr, cmd, identifier)) == NULL ) + return FALSE; + + *data = (void *) addrp; return TRUE; } static bool tag_address_part_validate -(struct sieve_validator *validator ATTR_UNUSED, struct sieve_ast_argument **arg, - struct sieve_command_context *cmd ATTR_UNUSED) +(struct sieve_validator *valdtr ATTR_UNUSED, struct sieve_ast_argument **arg, + struct sieve_command *cmd ATTR_UNUSED) { /* FIXME: Currenly trivial, but might need to allow for further validation for * future extensions. @@ -173,12 +199,12 @@ static bool tag_address_part_validate static bool tag_address_part_generate (const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, - struct sieve_command_context *cmd ATTR_UNUSED) + struct sieve_command *cmd ATTR_UNUSED) { - struct sieve_address_part_context *adpctx = - (struct sieve_address_part_context *) arg->context; + struct sieve_address_part *addrp = + (struct sieve_address_part *) arg->argument->data; - sieve_opr_address_part_emit(cgenv->sbin, adpctx->address_part); + sieve_opr_address_part_emit(cgenv->sbin, addrp); return TRUE; } @@ -193,7 +219,7 @@ const struct sieve_operand_class sieve_address_part_operand_class = static const struct sieve_extension_objects core_address_parts = SIEVE_EXT_DEFINE_MATCH_TYPES(sieve_core_address_parts); -const struct sieve_operand address_part_operand = { +const struct sieve_operand_def address_part_operand = { "address-part", NULL, SIEVE_OPERAND_ADDRESS_PART, &sieve_address_part_operand_class, @@ -232,7 +258,7 @@ int sieve_address_match } if ( !valid || addr == NULL ) { - if ( addrp == &all_address_part ) + if ( sieve_address_part_is(addrp, all_address_part) ) result = sieve_match_value(mctx, data, strlen(data)); else result = FALSE; @@ -240,13 +266,14 @@ int sieve_address_match while ( result == 0 && addr != NULL) { /* mailbox@domain */ struct sieve_address address; - const char *part; + const char *part = NULL; if ( addr->domain != NULL ) { address.local_part = addr->mailbox; address.domain = addr->domain; - part = addrp->extract_from(&address); + if ( addrp->def != NULL && addrp->def->extract_from ) + part = addrp->def->extract_from(addrp, &address); if ( part != NULL ) result = sieve_match_value(mctx, part, strlen(part)); @@ -299,12 +326,11 @@ bool sieve_addrmatch_default_dump_optionals bool sieve_addrmatch_default_get_optionals (const struct sieve_runtime_env *renv, sieve_size_t *address, - const struct sieve_address_part **addrp, const struct sieve_match_type **mtch, - const struct sieve_comparator **cmp) + struct sieve_address_part *addrp, struct sieve_match_type *mtch, + struct sieve_comparator *cmp) { int opt_code = 1; - if ( sieve_operand_optional_present(renv->sbin, address) ) { while ( opt_code != 0 ) { if ( !sieve_operand_optional_read(renv->sbin, address, &opt_code) ) @@ -314,15 +340,15 @@ bool sieve_addrmatch_default_get_optionals case 0: break; case SIEVE_AM_OPT_COMPARATOR: - if ( (*cmp = sieve_opr_comparator_read(renv, address)) == NULL ) + if ( !sieve_opr_comparator_read(renv, address, cmp) ) return FALSE; break; case SIEVE_AM_OPT_MATCH_TYPE: - if ( (*mtch = sieve_opr_match_type_read(renv, address)) == NULL ) + if ( !sieve_opr_match_type_read(renv, address, mtch) ) return FALSE; break; case SIEVE_AM_OPT_ADDRESS_PART: - if ( (*addrp = sieve_opr_address_part_read(renv, address)) == NULL ) + if ( !sieve_opr_address_part_read(renv, address, addrp) ) return FALSE; break; default: @@ -339,7 +365,8 @@ bool sieve_addrmatch_default_get_optionals */ static const char *addrp_all_extract_from - (const struct sieve_address *address) +(const struct sieve_address_part *addrp ATTR_UNUSED, + const struct sieve_address *address) { const char *local_part = address->local_part; const char *domain = address->domain; @@ -348,28 +375,30 @@ static const char *addrp_all_extract_from } static const char *addrp_domain_extract_from - (const struct sieve_address *address) +(const struct sieve_address_part *addrp ATTR_UNUSED, + const struct sieve_address *address) { return address->domain; } static const char *addrp_localpart_extract_from - (const struct sieve_address *address) +(const struct sieve_address_part *addrp ATTR_UNUSED, + const struct sieve_address *address) { return address->local_part; } -const struct sieve_address_part all_address_part = { +const struct sieve_address_part_def all_address_part = { SIEVE_OBJECT("all", &address_part_operand, SIEVE_ADDRESS_PART_ALL), addrp_all_extract_from }; -const struct sieve_address_part local_address_part = { +const struct sieve_address_part_def local_address_part = { SIEVE_OBJECT("localpart", &address_part_operand, SIEVE_ADDRESS_PART_LOCAL), addrp_localpart_extract_from }; -const struct sieve_address_part domain_address_part = { +const struct sieve_address_part_def domain_address_part = { SIEVE_OBJECT("domain", &address_part_operand, SIEVE_ADDRESS_PART_DOMAIN), addrp_domain_extract_from }; diff --git a/src/lib-sieve/sieve-address-parts.h b/src/lib-sieve/sieve-address-parts.h index ff340e437..9af06a3d0 100644 --- a/src/lib-sieve/sieve-address-parts.h +++ b/src/lib-sieve/sieve-address-parts.h @@ -11,15 +11,33 @@ #include "sieve-objects.h" /* - * Address part object + * Address part definition + */ + +struct sieve_address_part_def { + struct sieve_object_def obj_def; + + const char *(*extract_from) + (const struct sieve_address_part *addrp, + const struct sieve_address *address); +}; + +/* + * Address part instance */ struct sieve_address_part { - struct sieve_object object; + struct sieve_object object; - const char *(*extract_from)(const struct sieve_address *address); + const struct sieve_address_part_def *def; }; +#define SIEVE_ADDRESS_PART_DEFAULT(definition) \ + { SIEVE_OBJECT_DEFAULT(definition), &(definition) }; + +#define sieve_address_part_is(addrp, definition) \ + ( (addrp)->def == &(definition) ) + /* * Core address parts */ @@ -31,40 +49,33 @@ enum sieve_address_part_code { SIEVE_ADDRESS_PART_CUSTOM }; -extern const struct sieve_address_part all_address_part; -extern const struct sieve_address_part local_address_part; -extern const struct sieve_address_part domain_address_part; +extern const struct sieve_address_part_def all_address_part; +extern const struct sieve_address_part_def local_address_part; +extern const struct sieve_address_part_def domain_address_part; /* * Address part tagged argument */ -extern const struct sieve_argument address_part_tag; - -struct sieve_address_part_context { - struct sieve_command_context *command_ctx; - const struct sieve_address_part *address_part; -}; +extern const struct sieve_argument_def address_part_tag; void sieve_address_parts_link_tags - (struct sieve_validator *validator, - struct sieve_command_registration *cmd_reg, int id_code); + (struct sieve_validator *valdtr, struct sieve_command_registration *cmd_reg, + int id_code); /* * Address part registry */ void sieve_address_part_register - (struct sieve_validator *validator, - const struct sieve_address_part *addrp); -const struct sieve_address_part *sieve_address_part_find - (struct sieve_validator *validator, const char *identifier); + (struct sieve_validator *valdtr, const struct sieve_extension *ext, + const struct sieve_address_part_def *addrp); /* * Address part operand */ -extern const struct sieve_operand address_part_operand; +extern const struct sieve_operand_def address_part_operand; extern const struct sieve_operand_class sieve_address_part_operand_class; #define SIEVE_EXT_DEFINE_ADDRESS_PART(OP) SIEVE_EXT_DEFINE_OBJECT(OP) @@ -73,14 +84,19 @@ extern const struct sieve_operand_class sieve_address_part_operand_class; static inline void sieve_opr_address_part_emit (struct sieve_binary *sbin, const struct sieve_address_part *addrp) { - sieve_opr_object_emit(sbin, &addrp->object); + sieve_opr_object_emit(sbin, addrp->object.ext, addrp->object.def); } -static inline const struct sieve_address_part *sieve_opr_address_part_read - (const struct sieve_runtime_env *renv, sieve_size_t *address) +static inline bool sieve_opr_address_part_read +(const struct sieve_runtime_env *renv, sieve_size_t *address, + struct sieve_address_part *addrp) { - return (const struct sieve_address_part *) sieve_opr_object_read - (renv, &sieve_address_part_operand_class, address); + if ( !sieve_opr_object_read + (renv, &sieve_address_part_operand_class, address, &addrp->object) ) + return FALSE; + + addrp->def = (const struct sieve_address_part_def *) addrp->object.def; + return TRUE; } static inline bool sieve_opr_address_part_dump @@ -110,7 +126,7 @@ bool sieve_addrmatch_default_dump_optionals bool sieve_addrmatch_default_get_optionals (const struct sieve_runtime_env *renv, sieve_size_t *address, - const struct sieve_address_part **addp, - const struct sieve_match_type **mtch, const struct sieve_comparator **cmp); + struct sieve_address_part *addrp, + struct sieve_match_type *mtch, struct sieve_comparator *cmp); #endif /* __SIEVE_ADDRESS_PARTS_H */ diff --git a/src/lib-sieve/sieve-ast.c b/src/lib-sieve/sieve-ast.c index ce6b87b93..342291e89 100644 --- a/src/lib-sieve/sieve-ast.c +++ b/src/lib-sieve/sieve-ast.c @@ -29,6 +29,7 @@ static struct sieve_ast_node *sieve_ast_node_create /* Extensions to the AST */ struct sieve_ast_extension_reg { + const struct sieve_extension *ext; const struct sieve_ast_extension *ast_ext; void *context; }; @@ -40,6 +41,8 @@ struct sieve_ast_extension_reg { struct sieve_ast { pool_t pool; int refcount; + + struct sieve_instance *svinst; struct sieve_script *script; @@ -49,10 +52,12 @@ struct sieve_ast { ARRAY_DEFINE(extensions, struct sieve_ast_extension_reg); }; -struct sieve_ast *sieve_ast_create(struct sieve_script *script) +struct sieve_ast *sieve_ast_create +(struct sieve_script *script) { pool_t pool; struct sieve_ast *ast; + unsigned int ext_count; pool = pool_alloconly_create("sieve_ast", 16384); ast = p_new(pool, struct sieve_ast, 1); @@ -61,12 +66,14 @@ struct sieve_ast *sieve_ast_create(struct sieve_script *script) ast->script = script; sieve_script_ref(script); + ast->svinst = sieve_script_svinst(script); ast->root = sieve_ast_node_create(ast, NULL, SAT_ROOT, 0); ast->root->identifier = "ROOT"; - p_array_init(&ast->linked_extensions, pool, sieve_extensions_get_count()); - p_array_init(&ast->extensions, pool, sieve_extensions_get_count()); + ext_count = sieve_extensions_get_count(ast->svinst); + p_array_init(&ast->linked_extensions, pool, ext_count); + p_array_init(&ast->extensions, pool, ext_count); return ast; } @@ -94,7 +101,7 @@ void sieve_ast_unref(struct sieve_ast **ast) for ( i = 0; i < ext_count; i++ ) { if ( extrs[i].ast_ext != NULL && extrs[i].ast_ext->free != NULL ) - extrs[i].ast_ext->free(*ast, extrs[i].context); + extrs[i].ast_ext->free(extrs[i].ext, *ast, extrs[i].context); } /* Destroy AST */ @@ -125,11 +132,10 @@ struct sieve_script *sieve_ast_script(struct sieve_ast *ast) void sieve_ast_extension_link (struct sieve_ast *ast, const struct sieve_extension *ext) { - int ext_id = SIEVE_EXT_ID(ext); unsigned int i, ext_count; const struct sieve_extension *const *extensions; - if ( ext_id < 0 ) return; + if ( ext->id < 0 ) return; /* Prevent duplicates */ extensions = array_get(&ast->linked_extensions, &ext_count); @@ -149,30 +155,29 @@ const struct sieve_extension * const *sieve_ast_extensions_get } void sieve_ast_extension_register -(struct sieve_ast *ast, const struct sieve_ast_extension *ast_ext, - void *context) +(struct sieve_ast *ast, const struct sieve_extension *ext, + const struct sieve_ast_extension *ast_ext, void *context) { - int ext_id = SIEVE_EXT_ID(ast_ext->ext); - struct sieve_ast_extension_reg reg; + struct sieve_ast_extension_reg *reg; - if ( ext_id < 0 ) return; + if ( ext->id < 0 ) return; /* Initialize registration */ - reg.ast_ext = ast_ext; - reg.context = context; - array_idx_set(&ast->extensions, (unsigned int) ext_id, ®); + reg = array_idx_modifiable(&ast->extensions, (unsigned int) ext->id); + reg->ast_ext = ast_ext; + reg->ext = ext; + reg->context = context; } void *sieve_ast_extension_get_context (struct sieve_ast *ast, const struct sieve_extension *ext) { - int ext_id = SIEVE_EXT_ID(ext); const struct sieve_ast_extension_reg *reg; - if ( ext_id < 0 || ext_id >= (int) array_count(&ast->extensions) ) + if ( ext->id < 0 || ext->id >= (int) array_count(&ast->extensions) ) return NULL; - reg = array_idx(&ast->extensions, (unsigned int) ext_id); + reg = array_idx(&ast->extensions, (unsigned int) ext->id); return reg->context; } @@ -445,10 +450,8 @@ struct sieve_ast_argument *sieve_ast_argument_create arg->next = NULL; arg->source_line = source_line; - arg->context = NULL; arg->argument = NULL; - arg->arg_id_code = 0; return arg; } diff --git a/src/lib-sieve/sieve-ast.h b/src/lib-sieve/sieve-ast.h index 8682a900d..b60663836 100644 --- a/src/lib-sieve/sieve-ast.h +++ b/src/lib-sieve/sieve-ast.h @@ -104,14 +104,10 @@ struct sieve_ast_argument { /* Assigned during validation */ /* Argument associated with this ast element */ - const struct sieve_argument *argument; - int arg_id_code; + struct sieve_argument *argument; /* Parameters to this (tag) argument */ struct sieve_ast_argument *parameters; - - /* Context data associated with this ast element */ - void *context; }; struct sieve_ast_node { @@ -148,7 +144,7 @@ struct sieve_ast_node { /* Assigned during validation */ /* Context */ - struct sieve_command_context *context; + struct sieve_command *command; }; /* @@ -184,9 +180,10 @@ struct sieve_script *sieve_ast_script(struct sieve_ast *ast); /* Extension support */ struct sieve_ast_extension { - const struct sieve_extension *ext; + const struct sieve_extension_def *ext; - void (*free)(struct sieve_ast *ast, void *context); + void (*free)(const struct sieve_extension *ext, struct sieve_ast *ast, + void *context); }; void sieve_ast_extension_link @@ -195,8 +192,8 @@ const struct sieve_extension * const *sieve_ast_extensions_get (struct sieve_ast *ast, unsigned int *count_r); void sieve_ast_extension_register - (struct sieve_ast *ast, const struct sieve_ast_extension *ast_ext, - void *context); + (struct sieve_ast *ast, const struct sieve_extension *ext, + const struct sieve_ast_extension *ast_ext, void *context); void *sieve_ast_extension_get_context (struct sieve_ast *ast, const struct sieve_extension *ext); @@ -335,6 +332,7 @@ struct sieve_ast_argument *sieve_ast_stringlist_join #define sieve_ast_test_next(test) __AST_LIST_NEXT(test) /* AST argument macros */ +#define sieve_ast_argument_pool(node) (sieve_ast_pool((node)->ast)) #define sieve_ast_argument_first(node) __AST_NODE_LIST_FIRST(node, arguments) #define sieve_ast_argument_last(node) __AST_NODE_LIST_LAST(node, arguments) #define sieve_ast_argument_count(node) __AST_NODE_LIST_COUNT(node, arguments) diff --git a/src/lib-sieve/sieve-binary-dumper.c b/src/lib-sieve/sieve-binary-dumper.c index 89a041a97..066d610e5 100644 --- a/src/lib-sieve/sieve-binary-dumper.c +++ b/src/lib-sieve/sieve-binary-dumper.c @@ -36,6 +36,8 @@ struct sieve_binary_dumper *sieve_binary_dumper_create dumper->dumpenv.sbin = sbin; sieve_binary_ref(sbin); + dumper->dumpenv.svinst = sieve_binary_svinst(sbin); + return dumper; } @@ -106,7 +108,8 @@ bool sieve_binary_dumper_run for ( i = 0; i < count; i++ ) { const struct sieve_extension *ext = sieve_binary_extension_get_by_index (sbin, i); - sieve_binary_dumpf(denv, "%3d: %s (%d)\n", i, ext->name, SIEVE_EXT_ID(ext)); + sieve_binary_dumpf(denv, "%3d: %s (%d)\n", i, sieve_extension_name(ext), + ext->id); } } @@ -121,8 +124,8 @@ bool sieve_binary_dumper_run const struct sieve_extension *ext = sieve_binary_extension_get_by_index (sbin, i); - if ( ext->binary_dump != NULL ) { - success = ext->binary_dump(denv); + if ( ext->def != NULL && ext->def->binary_dump != NULL ) { + success = ext->def->binary_dump(ext, denv); } } T_END; diff --git a/src/lib-sieve/sieve-binary.c b/src/lib-sieve/sieve-binary.c index e6732efb9..818a213cd 100644 --- a/src/lib-sieve/sieve-binary.c +++ b/src/lib-sieve/sieve-binary.c @@ -128,6 +128,8 @@ struct sieve_binary_file { struct sieve_binary { pool_t pool; int refcount; + + struct sieve_instance *svinst; struct sieve_script *script; @@ -163,31 +165,39 @@ struct sieve_binary { size_t code_size; }; -static struct sieve_binary *sieve_binary_create(struct sieve_script *script) +static struct sieve_binary *sieve_binary_create +(struct sieve_instance *svinst, struct sieve_script *script) { pool_t pool; struct sieve_binary *sbin; - unsigned int i; + const struct sieve_extension *const *ext_preloaded; + unsigned int i, ext_count; pool = pool_alloconly_create("sieve_binary", 8192); sbin = p_new(pool, struct sieve_binary, 1); sbin->pool = pool; sbin->refcount = 1; + sbin->svinst = svinst; + sbin->script = script; if ( script != NULL ) sieve_script_ref(script); - p_array_init(&sbin->linked_extensions, pool, 5); - p_array_init(&sbin->extensions, pool, 5); - p_array_init(&sbin->extension_index, pool, sieve_extensions_get_count()); + ext_count = sieve_extensions_get_count(svinst); + + p_array_init(&sbin->linked_extensions, pool, ext_count); + p_array_init(&sbin->extensions, pool, ext_count); + p_array_init(&sbin->extension_index, pool, ext_count); p_array_init(&sbin->blocks, pool, 3); /* Pre-load core language features implemented as 'extensions' */ - for ( i = 0; i < sieve_preloaded_extensions_count; i++ ) { - const struct sieve_extension *ext = sieve_preloaded_extensions[i]; - if ( ext->binary_load != NULL ) - (void)ext->binary_load(sbin); + ext_preloaded = sieve_extensions_get_preloaded(svinst, &ext_count); + for ( i = 0; i < ext_count; i++ ) { + const struct sieve_extension_def *ext_def = ext_preloaded[i]->def; + + if ( ext_def != NULL && ext_def->binary_load != NULL ) + (void)ext_def->binary_load(ext_preloaded[i], sbin); } return sbin; @@ -195,7 +205,8 @@ static struct sieve_binary *sieve_binary_create(struct sieve_script *script) struct sieve_binary *sieve_binary_create_new(struct sieve_script *script) { - struct sieve_binary *sbin = sieve_binary_create(script); + struct sieve_binary *sbin = sieve_binary_create + (sieve_script_svinst(script), script); /* Extensions block */ (void) sieve_binary_block_create(sbin); @@ -214,17 +225,16 @@ void sieve_binary_ref(struct sieve_binary *sbin) static inline void sieve_binary_extensions_free(struct sieve_binary *sbin) { + struct sieve_binary_extension_reg *const *regs; unsigned int ext_count, i; /* Cleanup binary extensions */ - ext_count = array_count(&sbin->extensions); + regs = array_get(&sbin->extensions, &ext_count); for ( i = 0; i < ext_count; i++ ) { - struct sieve_binary_extension_reg * const *ereg - = array_idx(&sbin->extensions, i); - const struct sieve_binary_extension *binext = (*ereg)->binext; + const struct sieve_binary_extension *binext = regs[i]->binext; if ( binext != NULL && binext->binary_free != NULL ) - binext->binary_free(sbin); + binext->binary_free(regs[i]->extension, sbin, regs[i]->context); } } @@ -274,6 +284,11 @@ const char *sieve_binary_path(struct sieve_binary *sbin) return sbin->path; } +struct sieve_instance *sieve_binary_svinst(struct sieve_binary *sbin) +{ + return sbin->svinst; +} + bool sieve_binary_script_older (struct sieve_binary *sbin, struct sieve_script *script) { @@ -536,6 +551,7 @@ static bool _sieve_binary_save (struct sieve_binary *sbin, struct ostream *stream) { struct sieve_binary_header header; + struct sieve_binary_extension_reg *const *regs; unsigned int ext_count, blk_count, i; uoff_t block_index; @@ -543,14 +559,12 @@ static bool _sieve_binary_save /* Signal all extensions to finish generating their blocks */ - ext_count = array_count(&sbin->extensions); + regs = array_get(&sbin->extensions, &ext_count); for ( i = 0; i < ext_count; i++ ) { - struct sieve_binary_extension_reg * const *ereg - = array_idx(&sbin->extensions, i); - const struct sieve_binary_extension *binext = (*ereg)->binext; + const struct sieve_binary_extension *binext = regs[i]->binext; if ( binext != NULL && binext->binary_save != NULL ) - binext->binary_save(sbin); + binext->binary_save(regs[i]->extension, sbin, regs[i]->context); } /* Create header */ @@ -584,7 +598,7 @@ static bool _sieve_binary_save struct sieve_binary_extension_reg * const *ext = array_idx(&sbin->linked_extensions, i); - sieve_binary_emit_cstring(sbin, (*ext)->extension->name); + sieve_binary_emit_cstring(sbin, sieve_extension_name((*ext)->extension)); sieve_binary_emit_unsigned(sbin, (*ext)->block_id); } @@ -1036,7 +1050,7 @@ static bool _sieve_binary_load_extensions(struct sieve_binary *sbin) const struct sieve_extension *ext; if ( sieve_binary_read_string(sbin, &offset, &extension) ) { - ext = sieve_extension_get_by_name(str_c(extension)); + ext = sieve_extension_get_by_name(sbin->svinst, str_c(extension)); if ( ext == NULL ) { sieve_sys_error("loaded binary %s requires unknown extension '%s'", @@ -1161,19 +1175,22 @@ static bool _sieve_binary_load(struct sieve_binary *sbin) } struct sieve_binary *sieve_binary_open - (const char *path, struct sieve_script *script) +(struct sieve_instance *svinst, const char *path, struct sieve_script *script) { + struct sieve_binary_extension_reg *const *regs; unsigned int ext_count, i; struct sieve_binary *sbin; struct sieve_binary_file *file; - + + i_assert( script == NULL || sieve_script_svinst(script) == svinst ); + //file = _file_memory_open(path); file = _file_lazy_open(path); if ( file == NULL ) return NULL; /* Create binary object */ - sbin = sieve_binary_create(script); + sbin = sieve_binary_create(svinst, script); sbin->path = p_strdup(sbin->pool, path); sbin->file = file; @@ -1185,14 +1202,12 @@ struct sieve_binary *sieve_binary_open sieve_binary_activate(sbin); /* Signal open event to extensions */ - ext_count = array_count(&sbin->extensions); + regs = array_get(&sbin->extensions, &ext_count); for ( i = 0; i < ext_count; i++ ) { - struct sieve_binary_extension_reg * const *ereg - = array_idx(&sbin->extensions, i); - const struct sieve_binary_extension *binext = (*ereg)->binext; + const struct sieve_binary_extension *binext = regs[i]->binext; if ( binext != NULL && binext->binary_open != NULL && - !binext->binary_open(sbin) ) { + !binext->binary_open(regs[i]->extension, sbin, regs[i]->context) ) { /* Extension thinks its corrupt */ sieve_binary_unref(&sbin); return NULL; @@ -1224,6 +1239,7 @@ bool sieve_binary_load(struct sieve_binary *sbin) bool sieve_binary_up_to_date(struct sieve_binary *sbin) { + struct sieve_binary_extension_reg *const *regs; unsigned int ext_count, i; i_assert(sbin->file != NULL); @@ -1232,14 +1248,12 @@ bool sieve_binary_up_to_date(struct sieve_binary *sbin) (sbin->script, sbin->file->st.st_mtime) ) return FALSE; - ext_count = array_count(&sbin->extensions); + regs = array_get(&sbin->extensions, &ext_count); for ( i = 0; i < ext_count; i++ ) { - struct sieve_binary_extension_reg * const *ereg - = array_idx(&sbin->extensions, i); - const struct sieve_binary_extension *binext = (*ereg)->binext; + const struct sieve_binary_extension *binext = regs[i]->binext; if ( binext != NULL && binext->binary_up_to_date != NULL && - !binext->binary_up_to_date(sbin) ) + !binext->binary_up_to_date(regs[i]->extension, sbin, regs[i]->context) ) return FALSE; } @@ -1252,18 +1266,18 @@ bool sieve_binary_up_to_date(struct sieve_binary *sbin) void sieve_binary_activate(struct sieve_binary *sbin) { - unsigned int i; + struct sieve_binary_extension_reg *const *regs; + unsigned int i, ext_count; (void)sieve_binary_block_set_active(sbin, SBIN_SYSBLOCK_MAIN_PROGRAM, NULL); /* Load other extensions into binary */ - for ( i = 0; i < array_count(&sbin->linked_extensions); i++ ) { - struct sieve_binary_extension_reg * const *ereg = - array_idx(&sbin->linked_extensions, i); - const struct sieve_extension *ext = (*ereg)->extension; + regs = array_get(&sbin->linked_extensions, &ext_count); + for ( i = 0; i < ext_count; i++ ) { + const struct sieve_extension *ext = regs[i]->extension; - if ( ext != NULL && ext->binary_load != NULL ) - ext->binary_load(sbin); + if ( ext != NULL && ext->def != NULL && ext->def->binary_load != NULL ) + ext->def->binary_load(ext, sbin); } } @@ -1275,18 +1289,17 @@ static inline struct sieve_binary_extension_reg * sieve_binary_extension_create_reg (struct sieve_binary *sbin, const struct sieve_extension *ext) { - int ext_id = SIEVE_EXT_ID(ext); int index = array_count(&sbin->extensions); struct sieve_binary_extension_reg *ereg; - if ( ext_id < 0 ) return NULL; + if ( ext->id < 0 ) return NULL; ereg = p_new(sbin->pool, struct sieve_binary_extension_reg, 1); ereg->index = index; ereg->extension = ext; array_idx_set(&sbin->extensions, (unsigned int) index, &ereg); - array_idx_set(&sbin->extension_index, (unsigned int) ext_id, &ereg); + array_idx_set(&sbin->extension_index, (unsigned int) ext->id, &ereg); return ereg; } @@ -1294,12 +1307,11 @@ static inline struct sieve_binary_extension_reg * static inline struct sieve_binary_extension_reg *sieve_binary_extension_get_reg (struct sieve_binary *sbin, const struct sieve_extension *ext, bool create) { - int ext_id = SIEVE_EXT_ID(ext); struct sieve_binary_extension_reg *reg = NULL; - if ( ext_id >= 0 && ext_id < (int) array_count(&sbin->extension_index) ) { + if ( ext->id >= 0 && ext->id < (int) array_count(&sbin->extension_index) ) { struct sieve_binary_extension_reg * const *ereg = - array_idx(&sbin->extension_index, (unsigned int) ext_id); + array_idx(&sbin->extension_index, (unsigned int) ext->id); reg = *ereg; } @@ -1335,11 +1347,11 @@ const void *sieve_binary_extension_get_context } void sieve_binary_extension_set -(struct sieve_binary *sbin, const struct sieve_binary_extension *bext, - void *context) +(struct sieve_binary *sbin, const struct sieve_extension *ext, + const struct sieve_binary_extension *bext, void *context) { struct sieve_binary_extension_reg *ereg = - sieve_binary_extension_get_reg(sbin, bext->extension, TRUE); + sieve_binary_extension_get_reg(sbin, ext, TRUE); if ( ereg != NULL ) { ereg->binext = bext; @@ -1409,12 +1421,12 @@ int sieve_binary_extension_link static inline const struct sieve_extension *_sieve_binary_extension_get_by_index (struct sieve_binary *sbin, int index) { - struct sieve_binary_extension_reg * const *ext; + struct sieve_binary_extension_reg * const *ereg; if ( index < (int) array_count(&sbin->extensions) ) { - ext = array_idx(&sbin->extensions, (unsigned int) index); + ereg = array_idx(&sbin->extensions, (unsigned int) index); - return (*ext)->extension; + return (*ereg)->extension; } return NULL; @@ -1598,7 +1610,7 @@ sieve_size_t sieve_binary_emit_extension i_assert(ereg != NULL); - _sieve_binary_emit_byte(sbin, offset + ereg->index); + _sieve_binary_emit_byte(sbin, offset + ereg->index); return address; } @@ -1614,11 +1626,16 @@ void sieve_binary_emit_extension_object * Code retrieval */ -#define ADDR_CODE_AT(binary, address) ((signed char) ((binary)->code[*address])) -#define ADDR_DATA_AT(binary, address) ((unsigned char) ((binary)->code[*address])) -#define ADDR_POINTER(binary, address) ((const char *) (&(binary)->code[*address])) -#define ADDR_BYTES_LEFT(binary, address) ((binary)->code_size - (*address)) -#define ADDR_JUMP(address, offset) (*address) += offset +#define ADDR_CODE_AT(binary, address) \ + ((signed char) ((binary)->code[*address])) +#define ADDR_DATA_AT(binary, address) \ + ((unsigned char) ((binary)->code[*address])) +#define ADDR_POINTER(binary, address) \ + ((const char *) (&(binary)->code[*address])) +#define ADDR_BYTES_LEFT(binary, address) \ + ((binary)->code_size - (*address)) +#define ADDR_JUMP(address, offset) \ + (*address) += offset /* Literals */ diff --git a/src/lib-sieve/sieve-binary.h b/src/lib-sieve/sieve-binary.h index 11f48f5e9..adf744272 100644 --- a/src/lib-sieve/sieve-binary.h +++ b/src/lib-sieve/sieve-binary.h @@ -27,6 +27,7 @@ struct sieve_script *sieve_binary_script(struct sieve_binary *sbin); const char *sieve_binary_path(struct sieve_binary *sbin); bool sieve_binary_script_older (struct sieve_binary *sbin, struct sieve_script *script); +struct sieve_instance *sieve_binary_svinst(struct sieve_binary *sbin); const char *sieve_binary_script_name(struct sieve_binary *sbin); const char *sieve_binary_script_path(struct sieve_binary *sbin); @@ -49,7 +50,8 @@ bool sieve_binary_save */ struct sieve_binary *sieve_binary_open - (const char *path, struct sieve_script *script); + (struct sieve_instance *svinst, const char *path, + struct sieve_script *script); bool sieve_binary_up_to_date(struct sieve_binary *sbin); bool sieve_binary_load(struct sieve_binary *sbin); @@ -74,14 +76,22 @@ void sieve_binary_block_clear */ struct sieve_binary_extension { - const struct sieve_extension *extension; - - bool (*binary_save)(struct sieve_binary *sbin); - bool (*binary_open)(struct sieve_binary *sbin); - - void (*binary_free)(struct sieve_binary *sbin); + const struct sieve_extension_def *extension; + + bool (*binary_save) + (const struct sieve_extension *ext, struct sieve_binary *sbin, + void *context); + bool (*binary_open) + (const struct sieve_extension *ext, struct sieve_binary *sbin, + void *context); + + void (*binary_free) + (const struct sieve_extension *ext, struct sieve_binary *sbin, + void *context); - bool (*binary_up_to_date)(struct sieve_binary *sbin); + bool (*binary_up_to_date) + (const struct sieve_extension *ext, struct sieve_binary *sbin, + void *context); }; void sieve_binary_extension_set_context @@ -90,8 +100,8 @@ const void *sieve_binary_extension_get_context (struct sieve_binary *sbin, const struct sieve_extension *ext); void sieve_binary_extension_set - (struct sieve_binary *sbin, const struct sieve_binary_extension *bext, - void *context); + (struct sieve_binary *sbin, const struct sieve_extension *ext, + const struct sieve_binary_extension *bext, void *context); unsigned int sieve_binary_extension_create_block (struct sieve_binary *sbin, const struct sieve_extension *ext); diff --git a/src/lib-sieve/sieve-code-dumper.c b/src/lib-sieve/sieve-code-dumper.c index 12998d8de..5704d49d0 100644 --- a/src/lib-sieve/sieve-code-dumper.c +++ b/src/lib-sieve/sieve-code-dumper.c @@ -26,7 +26,8 @@ */ struct sieve_code_dumper_extension_reg { - const struct sieve_code_dumper_extension *val_ext; + const struct sieve_code_dumper_extension *cdmpext; + const struct sieve_extension *ext; void *context; }; @@ -59,7 +60,8 @@ struct sieve_code_dumper *sieve_code_dumper_create dumper->pc = 0; /* Setup storage for extension contexts */ - p_array_init(&dumper->extensions, pool, sieve_extensions_get_count()); + p_array_init(&dumper->extensions, pool, + sieve_extensions_get_count(denv->svinst)); return dumper; } @@ -79,39 +81,40 @@ pool_t sieve_code_dumper_pool(struct sieve_code_dumper *dumper) /* EXtension support */ void sieve_dump_extension_register -(struct sieve_code_dumper *dumper, - const struct sieve_code_dumper_extension *dump_ext, void *context) +(struct sieve_code_dumper *dumper, const struct sieve_extension *ext, + const struct sieve_code_dumper_extension *cdmpext, void *context) { - struct sieve_code_dumper_extension_reg reg = { dump_ext, context }; - int ext_id = SIEVE_EXT_ID(dump_ext->ext); + struct sieve_code_dumper_extension_reg *reg; - if ( ext_id < 0 ) return; - - array_idx_set(&dumper->extensions, (unsigned int) ext_id, ®); + if ( ext->id < 0 ) return; + + reg = array_idx_modifiable(&dumper->extensions, (unsigned int) ext->id); + reg->cdmpext = cdmpext; + reg->ext = ext; + reg->context = context; } void sieve_dump_extension_set_context (struct sieve_code_dumper *dumper, const struct sieve_extension *ext, void *context) { - struct sieve_code_dumper_extension_reg reg = { NULL, context }; - int ext_id = SIEVE_EXT_ID(ext); + struct sieve_code_dumper_extension_reg *reg; - if ( ext_id < 0 ) return; - - array_idx_set(&dumper->extensions, (unsigned int) ext_id, ®); + if ( ext->id < 0 ) return; + + reg = array_idx_modifiable(&dumper->extensions, (unsigned int) ext->id); + reg->context = context; } void *sieve_dump_extension_get_context (struct sieve_code_dumper *dumper, const struct sieve_extension *ext) { - int ext_id = SIEVE_EXT_ID(ext); const struct sieve_code_dumper_extension_reg *reg; - if ( ext_id < 0 || ext_id >= (int) array_count(&dumper->extensions) ) + if ( ext->id < 0 || ext->id >= (int) array_count(&dumper->extensions) ) return NULL; - reg = array_idx(&dumper->extensions, (unsigned int) ext_id); + reg = array_idx(&dumper->extensions, (unsigned int) ext->id); return reg->context; } @@ -192,8 +195,8 @@ bool sieve_code_dumper_print_optional_operands static bool sieve_code_dumper_print_operation (struct sieve_code_dumper *dumper) { - const struct sieve_operation *op; struct sieve_dumptime_env *denv = dumper->dumpenv; + struct sieve_operation *oprtn = &denv->oprtn; sieve_size_t address; /* Mark start address of operation */ @@ -201,13 +204,11 @@ static bool sieve_code_dumper_print_operation address = dumper->mark_address = dumper->pc; /* Read operation */ - dumper->operation = op = - sieve_operation_read(denv->sbin, &(dumper->pc)); + if ( sieve_operation_read(denv->sbin, &(dumper->pc), oprtn) ) { + const struct sieve_operation_def *op = oprtn->def; - /* Try to dump it */ - if ( op != NULL ) { if ( op->dump != NULL ) - return op->dump(op, denv, &(dumper->pc)); + return op->dump(denv, &(dumper->pc)); else if ( op->mnemonic != NULL ) sieve_code_dumpf(denv, "%s", op->mnemonic); else @@ -250,11 +251,11 @@ void sieve_code_dumper_run(struct sieve_code_dumper *dumper) break; } - sieve_code_dumpf(denv, "%s", ext->name); + sieve_code_dumpf(denv, "%s", sieve_extension_name(ext)); - if ( ext->code_dump != NULL ) { + if ( ext->def != NULL && ext->def->code_dump != NULL ) { sieve_code_descend(denv); - if ( !ext->code_dump(denv, &dumper->pc) ) { + if ( !ext->def->code_dump(ext, denv, &dumper->pc) ) { success = FALSE; break; } diff --git a/src/lib-sieve/sieve-code-dumper.h b/src/lib-sieve/sieve-code-dumper.h index 58b6a9919..16da3a7fb 100644 --- a/src/lib-sieve/sieve-code-dumper.h +++ b/src/lib-sieve/sieve-code-dumper.h @@ -20,13 +20,13 @@ pool_t sieve_code_dumper_pool */ struct sieve_code_dumper_extension { - const struct sieve_extension *ext; + const struct sieve_extension_def *ext; void (*free)(struct sieve_code_dumper *dumper, void *context); }; void sieve_dump_extension_register -(struct sieve_code_dumper *dumper, +(struct sieve_code_dumper *dumper, const struct sieve_extension *ext, const struct sieve_code_dumper_extension *dump_ext, void *context); void sieve_dump_extension_set_context (struct sieve_code_dumper *dumper, const struct sieve_extension *ext, diff --git a/src/lib-sieve/sieve-code.c b/src/lib-sieve/sieve-code.c index 3bb370d7f..a0fe68861 100644 --- a/src/lib-sieve/sieve-code.c +++ b/src/lib-sieve/sieve-code.c @@ -18,7 +18,7 @@ #include <stdio.h> -/* +/* return opr_r->def != NULL; * Coded stringlist */ @@ -194,11 +194,11 @@ bool sieve_code_source_line_read * Core operands */ -extern const struct sieve_operand comparator_operand; -extern const struct sieve_operand match_type_operand; -extern const struct sieve_operand address_part_operand; +extern const struct sieve_operand_def comparator_operand; +extern const struct sieve_operand_def match_type_operand; +extern const struct sieve_operand_def address_part_operand; -const struct sieve_operand *sieve_operands[] = { +const struct sieve_operand_def *sieve_operands[] = { &omitted_operand, /* SIEVE_OPERAND_OPTIONAL */ &number_operand, &string_operand, @@ -216,38 +216,53 @@ const unsigned int sieve_operand_count = * Operand functions */ -sieve_size_t sieve_operand_emit_code -(struct sieve_binary *sbin, const struct sieve_operand *opr) +sieve_size_t sieve_operand_emit +(struct sieve_binary *sbin, const struct sieve_extension *ext, + const struct sieve_operand_def *opr_def) { sieve_size_t address; - if ( opr->extension != NULL ) { + if ( ext != NULL ) { address = sieve_binary_emit_extension - (sbin, opr->extension, sieve_operand_count); + (sbin, ext, sieve_operand_count); sieve_binary_emit_extension_object - (sbin, &opr->extension->operands, opr->code); + (sbin, &opr_def->ext_def->operands, opr_def->code); return address; } - return sieve_binary_emit_byte(sbin, opr->code); + return sieve_binary_emit_byte(sbin, opr_def->code); } -const struct sieve_operand *sieve_operand_read -(struct sieve_binary *sbin, sieve_size_t *address) +bool sieve_operand_read +(struct sieve_binary *sbin, sieve_size_t *address, + struct sieve_operand *operand) { - const struct sieve_extension *ext; unsigned int code = sieve_operand_count; - if ( !sieve_binary_read_extension(sbin, address, &code, &ext) ) + operand->address = *address; + operand->ext = NULL; + operand->def = NULL; + + if ( !sieve_binary_read_extension(sbin, address, &code, &operand->ext) ) return NULL; - if ( !ext ) - return code < sieve_operand_count ? sieve_operands[code] : NULL; + if ( operand->ext == NULL ) { + if ( code < sieve_operand_count ) + operand->def = sieve_operands[code]; + + return ( operand->def != NULL ); + } + + if ( operand->ext->def == NULL ) + return FALSE; + + operand->def = (const struct sieve_operand_def *) + sieve_binary_read_extension_object(sbin, address, + &operand->ext->def->operands); - return (const struct sieve_operand *) sieve_binary_read_extension_object - (sbin, address, &ext->operands); + return ( operand->def != NULL ); } bool sieve_operand_optional_present @@ -285,7 +300,7 @@ bool sieve_operand_optional_read const struct sieve_operand_class omitted_class = { "OMITTED" }; -const struct sieve_operand omitted_operand = { +const struct sieve_operand_def omitted_operand = { "@OMITTED", NULL, SIEVE_OPERAND_OPTIONAL, &omitted_class, NULL @@ -308,7 +323,7 @@ const struct sieve_opr_number_interface number_interface = { const struct sieve_operand_class number_class = { "number" }; -const struct sieve_operand number_operand = { +const struct sieve_operand_def number_operand = { "@number", NULL, SIEVE_OPERAND_NUMBER, &number_class, @@ -318,10 +333,11 @@ const struct sieve_operand number_operand = { /* String */ static bool opr_string_dump - (const struct sieve_dumptime_env *denv, sieve_size_t *address, - const char *field_name); + (const struct sieve_dumptime_env *denv, const struct sieve_operand *opr, + sieve_size_t *address, const char *field_name); static bool opr_string_read - (const struct sieve_runtime_env *renv, sieve_size_t *address, string_t **str_r); + (const struct sieve_runtime_env *renv, const struct sieve_operand *opr, + sieve_size_t *address, string_t **str_r); const struct sieve_opr_string_interface string_interface ={ opr_string_dump, @@ -331,7 +347,7 @@ const struct sieve_opr_string_interface string_interface ={ const struct sieve_operand_class string_class = { "string" }; -const struct sieve_operand string_operand = { +const struct sieve_operand_def string_operand = { "@string", NULL, SIEVE_OPERAND_STRING, &string_class, @@ -354,7 +370,7 @@ const struct sieve_opr_stringlist_interface stringlist_interface = { const struct sieve_operand_class stringlist_class = { "string-list" }; -const struct sieve_operand stringlist_operand = { +const struct sieve_operand_def stringlist_operand = { "@string-list", NULL, SIEVE_OPERAND_STRING_LIST, &stringlist_class, @@ -364,17 +380,18 @@ const struct sieve_operand stringlist_operand = { /* Catenated String */ static bool opr_catenated_string_read - (const struct sieve_runtime_env *renv, sieve_size_t *address, string_t **str); + (const struct sieve_runtime_env *renv, const struct sieve_operand *operand, + sieve_size_t *address, string_t **str); static bool opr_catenated_string_dump - (const struct sieve_dumptime_env *denv, sieve_size_t *address, - const char *field_name); + (const struct sieve_dumptime_env *denv, const struct sieve_operand *operand, + sieve_size_t *address, const char *field_name); const struct sieve_opr_string_interface catenated_string_interface = { opr_catenated_string_dump, opr_catenated_string_read }; -const struct sieve_operand catenated_string_operand = { +const struct sieve_operand_def catenated_string_operand = { "@catenated-string", NULL, SIEVE_OPERAND_CATENATED_STRING, &string_class, @@ -389,27 +406,27 @@ const struct sieve_operand catenated_string_operand = { void sieve_opr_omitted_emit(struct sieve_binary *sbin) { - (void) sieve_operand_emit_code(sbin, &omitted_operand); + (void) sieve_operand_emit(sbin, NULL, &omitted_operand); } /* Number */ void sieve_opr_number_emit(struct sieve_binary *sbin, sieve_number_t number) { - (void) sieve_operand_emit_code(sbin, &number_operand); + (void) sieve_operand_emit(sbin, NULL, &number_operand); (void) sieve_binary_emit_integer(sbin, number); } bool sieve_opr_number_dump_data -(const struct sieve_dumptime_env *denv, const struct sieve_operand *operand, +(const struct sieve_dumptime_env *denv, const struct sieve_operand *opr, sieve_size_t *address, const char *field_name) { const struct sieve_opr_number_interface *intf; - if ( !sieve_operand_is_number(operand) ) + if ( !sieve_operand_is_number(opr) ) return FALSE; - intf = (const struct sieve_opr_number_interface *) operand->interface; + intf = (const struct sieve_opr_number_interface *) opr->def->interface; if ( intf->dump == NULL ) return FALSE; @@ -421,25 +438,26 @@ bool sieve_opr_number_dump (const struct sieve_dumptime_env *denv, sieve_size_t *address, const char *field_name) { - const struct sieve_operand *operand; + struct sieve_operand operand; sieve_code_mark(denv); - operand = sieve_operand_read(denv->sbin, address); + if ( !sieve_operand_read(denv->sbin, address, &operand) ) + return FALSE; - return sieve_opr_number_dump_data(denv, operand, address, field_name); + return sieve_opr_number_dump_data(denv, &operand, address, field_name); } bool sieve_opr_number_read_data -(const struct sieve_runtime_env *renv, const struct sieve_operand *operand, +(const struct sieve_runtime_env *renv, const struct sieve_operand *opr, sieve_size_t *address, sieve_number_t *number_r) { const struct sieve_opr_number_interface *intf; - if ( !sieve_operand_is_number(operand) ) + if ( !sieve_operand_is_number(opr) ) return FALSE; - intf = (const struct sieve_opr_number_interface *) operand->interface; + intf = (const struct sieve_opr_number_interface *) opr->def->interface; if ( intf->read == NULL ) return FALSE; @@ -451,9 +469,12 @@ bool sieve_opr_number_read (const struct sieve_runtime_env *renv, sieve_size_t *address, sieve_number_t *number_r) { - const struct sieve_operand *operand = sieve_operand_read(renv->sbin, address); + struct sieve_operand operand; + + if ( !sieve_operand_read(renv->sbin, address, &operand) ) + return FALSE; - return sieve_opr_number_read_data(renv, operand, address, number_r); + return sieve_opr_number_read_data(renv, &operand, address, number_r); } static bool opr_number_dump @@ -464,7 +485,8 @@ static bool opr_number_dump if (sieve_binary_read_integer(denv->sbin, address, &number) ) { if ( field_name != NULL ) - sieve_code_dumpf(denv, "%s: NUM %llu", field_name, (unsigned long long) number); + sieve_code_dumpf(denv, "%s: NUM %llu", field_name, + (unsigned long long) number); else sieve_code_dumpf(denv, "NUM %llu", (unsigned long long) number); @@ -485,96 +507,107 @@ static bool opr_number_read void sieve_opr_string_emit(struct sieve_binary *sbin, string_t *str) { - (void) sieve_operand_emit_code(sbin, &string_operand); + (void) sieve_operand_emit(sbin, NULL, &string_operand); (void) sieve_binary_emit_string(sbin, str); } bool sieve_opr_string_dump_data -(const struct sieve_dumptime_env *denv, const struct sieve_operand *operand, +(const struct sieve_dumptime_env *denv, const struct sieve_operand *opr, sieve_size_t *address, const char *field_name) { const struct sieve_opr_string_interface *intf; - if ( !sieve_operand_is_string(operand) ) { - sieve_code_dumpf(denv, "ERROR: INVALID STRING OPERAND %s", operand->name); + if ( !sieve_operand_is_string(opr) ) { + sieve_code_dumpf(denv, "ERROR: INVALID STRING OPERAND %s", + sieve_operand_name(opr)); return FALSE; } - intf = (const struct sieve_opr_string_interface *) operand->interface; + intf = (const struct sieve_opr_string_interface *) opr->def->interface; if ( intf->dump == NULL ) { sieve_code_dumpf(denv, "ERROR: DUMP STRING OPERAND"); return FALSE; } - return intf->dump(denv, address, field_name); + return intf->dump(denv, opr, address, field_name); } bool sieve_opr_string_dump (const struct sieve_dumptime_env *denv, sieve_size_t *address, const char *field_name) { - const struct sieve_operand *operand; + struct sieve_operand operand; sieve_code_mark(denv); - operand = sieve_operand_read(denv->sbin, address); - - if ( operand == NULL ) { + + if ( !sieve_operand_read(denv->sbin, address, &operand) ) { sieve_code_dumpf(denv, "ERROR: INVALID OPERAND"); return FALSE; } - return sieve_opr_string_dump_data(denv, operand, address, field_name); + return sieve_opr_string_dump_data(denv, &operand, address, field_name); } bool sieve_opr_string_dump_ex (const struct sieve_dumptime_env *denv, sieve_size_t *address, const char *field_name, bool *literal_r) { - const struct sieve_operand *operand; + struct sieve_operand operand; sieve_code_mark(denv); - operand = sieve_operand_read(denv->sbin, address); + if ( !sieve_operand_read(denv->sbin, address, &operand) ) { + sieve_code_dumpf(denv, "ERROR: INVALID OPERAND"); + return FALSE; + } - *literal_r = ( operand == &string_operand ); + *literal_r = sieve_operand_is(&operand, string_operand); - return sieve_opr_string_dump_data(denv, operand, address, field_name); + return sieve_opr_string_dump_data(denv, &operand, address, field_name); } bool sieve_opr_string_read_data -(const struct sieve_runtime_env *renv, const struct sieve_operand *operand, +(const struct sieve_runtime_env *renv, const struct sieve_operand *opr, sieve_size_t *address, string_t **str_r) { const struct sieve_opr_string_interface *intf; - if ( operand == NULL || operand->class != &string_class ) + if ( opr == NULL || opr->def == NULL || opr->def->class != &string_class ) return FALSE; - intf = (const struct sieve_opr_string_interface *) operand->interface; + intf = (const struct sieve_opr_string_interface *) opr->def->interface; if ( intf->read == NULL ) return FALSE; - return intf->read(renv, address, str_r); + return intf->read(renv, opr, address, str_r); } bool sieve_opr_string_read (const struct sieve_runtime_env *renv, sieve_size_t *address, string_t **str_r) { - const struct sieve_operand *operand = sieve_operand_read(renv->sbin, address); + struct sieve_operand operand; - return sieve_opr_string_read_data(renv, operand, address, str_r); + if ( !sieve_operand_read(renv->sbin, address, &operand) ) { + return FALSE; + } + + return sieve_opr_string_read_data(renv, &operand, address, str_r); } bool sieve_opr_string_read_ex (const struct sieve_runtime_env *renv, sieve_size_t *address, string_t **str_r, bool *literal_r) { - const struct sieve_operand *operand = sieve_operand_read(renv->sbin, address); + struct sieve_operand operand; + + if ( !sieve_operand_read(renv->sbin, address, &operand) ) { + return FALSE; + } - *literal_r = ( operand == &string_operand ); + *literal_r = sieve_operand_is(&operand, string_operand); - return sieve_opr_string_read_data(renv, operand, address, str_r); + return sieve_opr_string_read_data(renv, &operand, address, str_r); } static void _dump_string @@ -599,7 +632,8 @@ static void _dump_string } bool opr_string_dump -(const struct sieve_dumptime_env *denv, sieve_size_t *address, +(const struct sieve_dumptime_env *denv, + const struct sieve_operand *opr ATTR_UNUSED, sieve_size_t *address, const char *field_name) { string_t *str; @@ -614,7 +648,9 @@ bool opr_string_dump } static bool opr_string_read -(const struct sieve_runtime_env *renv, sieve_size_t *address, string_t **str_r) +(const struct sieve_runtime_env *renv, + const struct sieve_operand *opr ATTR_UNUSED, sieve_size_t *address, + string_t **str_r) { return sieve_binary_read_string(renv->sbin, address, str_r); } @@ -622,12 +658,12 @@ static bool opr_string_read /* String list */ void sieve_opr_stringlist_emit_start - (struct sieve_binary *sbin, unsigned int listlen, void **context) +(struct sieve_binary *sbin, unsigned int listlen, void **context) { sieve_size_t *end_offset = t_new(sieve_size_t, 1); /* Emit byte identifying the type of operand */ - (void) sieve_operand_emit_code(sbin, &stringlist_operand); + (void) sieve_operand_emit(sbin, NULL, &stringlist_operand); /* Give the interpreter an easy way to skip over this string list */ *end_offset = sieve_binary_emit_offset(sbin, 0); @@ -652,28 +688,28 @@ void sieve_opr_stringlist_emit_end } bool sieve_opr_stringlist_dump_data -(const struct sieve_dumptime_env *denv, const struct sieve_operand *operand, +(const struct sieve_dumptime_env *denv, const struct sieve_operand *opr, sieve_size_t *address, const char *field_name) { - if ( operand == NULL ) + if ( opr == NULL || opr->def == NULL ) return FALSE; - if ( operand->class == &stringlist_class ) { + if ( opr->def->class == &stringlist_class ) { const struct sieve_opr_stringlist_interface *intf = - (const struct sieve_opr_stringlist_interface *) operand->interface; + (const struct sieve_opr_stringlist_interface *) opr->def->interface; if ( intf->dump == NULL ) return FALSE; return intf->dump(denv, address, field_name); - } else if ( operand->class == &string_class ) { + } else if ( opr->def->class == &string_class ) { const struct sieve_opr_string_interface *intf = - (const struct sieve_opr_string_interface *) operand->interface; + (const struct sieve_opr_string_interface *) opr->def->interface; if ( intf->dump == NULL ) return FALSE; - return intf->dump(denv, address, field_name); + return intf->dump(denv, opr, address, field_name); } return FALSE; @@ -683,39 +719,42 @@ bool sieve_opr_stringlist_dump (const struct sieve_dumptime_env *denv, sieve_size_t *address, const char *field_name) { - const struct sieve_operand *operand; + struct sieve_operand operand; sieve_code_mark(denv); - operand = sieve_operand_read(denv->sbin, address); - return sieve_opr_stringlist_dump_data(denv, operand, address, field_name); + if ( !sieve_operand_read(denv->sbin, address, &operand) ) { + return FALSE; + } + + return sieve_opr_stringlist_dump_data(denv, &operand, address, field_name); } struct sieve_coded_stringlist *sieve_opr_stringlist_read_data -(const struct sieve_runtime_env *renv, const struct sieve_operand *operand, - sieve_size_t op_address, sieve_size_t *address) +(const struct sieve_runtime_env *renv, const struct sieve_operand *opr, + sieve_size_t *address) { - if ( operand == NULL ) + if ( opr == NULL || opr->def == NULL ) return NULL; - if ( operand->class == &stringlist_class ) { + if ( opr->def->class == &stringlist_class ) { const struct sieve_opr_stringlist_interface *intf = - (const struct sieve_opr_stringlist_interface *) operand->interface; + (const struct sieve_opr_stringlist_interface *) opr->def->interface; if ( intf->read == NULL ) return NULL; return intf->read(renv, address); - } else if ( operand->class == &string_class ) { + } else if ( opr->def->class == &string_class ) { /* Special case, accept single string as string list as well. */ const struct sieve_opr_string_interface *intf = - (const struct sieve_opr_string_interface *) operand->interface; + (const struct sieve_opr_string_interface *) opr->def->interface; - if ( intf->read == NULL || !intf->read(renv, address, NULL) ) { + if ( intf->read == NULL || !intf->read(renv, opr, address, NULL) ) { return NULL; } - return sieve_coded_stringlist_create(renv, op_address, 1, *address); + return sieve_coded_stringlist_create(renv, opr->address, 1, *address); } return NULL; @@ -724,10 +763,13 @@ struct sieve_coded_stringlist *sieve_opr_stringlist_read_data struct sieve_coded_stringlist *sieve_opr_stringlist_read (const struct sieve_runtime_env *renv, sieve_size_t *address) { - sieve_size_t op_address = *address; - const struct sieve_operand *operand = sieve_operand_read(renv->sbin, address); + struct sieve_operand operand; + + if ( !sieve_operand_read(renv->sbin, address, &operand) ) { + return NULL; + } - return sieve_opr_stringlist_read_data(renv, operand, op_address, address); + return sieve_opr_stringlist_read_data(renv, &operand, address); } static bool opr_stringlist_dump @@ -780,12 +822,13 @@ static struct sieve_coded_stringlist *opr_stringlist_read void sieve_opr_catenated_string_emit (struct sieve_binary *sbin, unsigned int elements) { - (void) sieve_operand_emit_code(sbin, &catenated_string_operand); + (void) sieve_operand_emit(sbin, NULL, &catenated_string_operand); (void) sieve_binary_emit_unsigned(sbin, elements); } static bool opr_catenated_string_dump -(const struct sieve_dumptime_env *denv, sieve_size_t *address, +(const struct sieve_dumptime_env *denv, + const struct sieve_operand *operand ATTR_UNUSED, sieve_size_t *address, const char *field_name) { unsigned int elements = 0; @@ -811,7 +854,9 @@ static bool opr_catenated_string_dump } static bool opr_catenated_string_read -(const struct sieve_runtime_env *renv, sieve_size_t *address, string_t **str) +(const struct sieve_runtime_env *renv, + const struct sieve_operand *operand ATTR_UNUSED, sieve_size_t *address, + string_t **str) { unsigned int elements = 0; unsigned int i; @@ -858,22 +903,18 @@ static bool opr_catenated_string_read /* Forward declarations */ static bool opc_jmp_dump - (const struct sieve_operation *op, - const struct sieve_dumptime_env *denv, sieve_size_t *address); + (const struct sieve_dumptime_env *denv, sieve_size_t *address); static int opc_jmp_execute - (const struct sieve_operation *op, - const struct sieve_runtime_env *renv, sieve_size_t *address); + (const struct sieve_runtime_env *renv, sieve_size_t *address); static int opc_jmptrue_execute - (const struct sieve_operation *op, - const struct sieve_runtime_env *renv, sieve_size_t *address); + (const struct sieve_runtime_env *renv, sieve_size_t *address); static int opc_jmpfalse_execute - (const struct sieve_operation *op, - const struct sieve_runtime_env *renv, sieve_size_t *address); + (const struct sieve_runtime_env *renv, sieve_size_t *address); /* Operation objects defined in this file */ -const struct sieve_operation sieve_jmp_operation = { +const struct sieve_operation_def sieve_jmp_operation = { "JMP", NULL, SIEVE_OPERATION_JMP, @@ -881,7 +922,7 @@ const struct sieve_operation sieve_jmp_operation = { opc_jmp_execute }; -const struct sieve_operation sieve_jmptrue_operation = { +const struct sieve_operation_def sieve_jmptrue_operation = { "JMPTRUE", NULL, SIEVE_OPERATION_JMPTRUE, @@ -889,7 +930,7 @@ const struct sieve_operation sieve_jmptrue_operation = { opc_jmptrue_execute }; -const struct sieve_operation sieve_jmpfalse_operation = { +const struct sieve_operation_def sieve_jmpfalse_operation = { "JMPFALSE", NULL, SIEVE_OPERATION_JMPFALSE, @@ -899,18 +940,18 @@ const struct sieve_operation sieve_jmpfalse_operation = { /* Operation objects defined in other files */ -extern const struct sieve_operation cmd_stop_operation; -extern const struct sieve_operation cmd_keep_operation; -extern const struct sieve_operation cmd_discard_operation; -extern const struct sieve_operation cmd_redirect_operation; - -extern const struct sieve_operation tst_address_operation; -extern const struct sieve_operation tst_header_operation; -extern const struct sieve_operation tst_exists_operation; -extern const struct sieve_operation tst_size_over_operation; -extern const struct sieve_operation tst_size_under_operation; - -const struct sieve_operation *sieve_operations[] = { +extern const struct sieve_operation_def cmd_stop_operation; +extern const struct sieve_operation_def cmd_keep_operation; +extern const struct sieve_operation_def cmd_discard_operation; +extern const struct sieve_operation_def cmd_redirect_operation; + +extern const struct sieve_operation_def tst_address_operation; +extern const struct sieve_operation_def tst_header_operation; +extern const struct sieve_operation_def tst_exists_operation; +extern const struct sieve_operation_def tst_size_over_operation; +extern const struct sieve_operation_def tst_size_under_operation; + +const struct sieve_operation_def *sieve_operations[] = { NULL, &sieve_jmp_operation, @@ -936,38 +977,51 @@ const unsigned int sieve_operation_count = * Operation functions */ -sieve_size_t sieve_operation_emit_code -(struct sieve_binary *sbin, const struct sieve_operation *op) +sieve_size_t sieve_operation_emit +(struct sieve_binary *sbin, const struct sieve_extension *ext, + const struct sieve_operation_def *op_def) { sieve_size_t address; - if ( op->extension != NULL ) { - address = sieve_binary_emit_extension - (sbin, op->extension, sieve_operation_count); + if ( ext != NULL ) { + address = sieve_binary_emit_extension + (sbin, ext, sieve_operation_count); - sieve_binary_emit_extension_object - (sbin, &op->extension->operations, op->code); + sieve_binary_emit_extension_object + (sbin, &op_def->ext_def->operations, op_def->code); - return address; - } + return address; + } - return sieve_binary_emit_byte(sbin, op->code); + return sieve_binary_emit_byte(sbin, op_def->code); } -const struct sieve_operation *sieve_operation_read -(struct sieve_binary *sbin, sieve_size_t *address) +bool sieve_operation_read +(struct sieve_binary *sbin, sieve_size_t *address, + struct sieve_operation *oprtn) { - const struct sieve_extension *ext; unsigned int code = sieve_operation_count; - if ( !sieve_binary_read_extension(sbin, address, &code, &ext) ) - return NULL; + oprtn->address = *address; + oprtn->def = NULL; + oprtn->ext = NULL; - if ( !ext ) - return code < sieve_operation_count ? sieve_operations[code] : NULL; + if ( !sieve_binary_read_extension(sbin, address, &code, &oprtn->ext) ) + return FALSE; - return (const struct sieve_operation *) sieve_binary_read_extension_object - (sbin, address, &ext->operations); + if ( !oprtn->ext ) { + if ( code < sieve_operation_count ) { + oprtn->def = sieve_operations[code]; + } + + return ( oprtn->def != NULL ); + } + + oprtn->def = (const struct sieve_operation_def *) + sieve_binary_read_extension_object(sbin, address, + &oprtn->ext->def->operations); + + return ( oprtn->def != NULL ); } /* @@ -977,15 +1031,15 @@ const struct sieve_operation *sieve_operation_read /* Code dump */ static bool opc_jmp_dump -(const struct sieve_operation *op, - const struct sieve_dumptime_env *denv, sieve_size_t *address) +(const struct sieve_dumptime_env *denv, sieve_size_t *address) { + const struct sieve_operation *op = &denv->oprtn; unsigned int pc = *address; int offset; if ( sieve_binary_read_offset(denv->sbin, address, &offset) ) sieve_code_dumpf(denv, "%s %d [%08x]", - op->mnemonic, offset, pc + offset); + sieve_operation_mnemonic(op), offset, pc + offset); else return FALSE; @@ -995,8 +1049,7 @@ static bool opc_jmp_dump /* Code execution */ static int opc_jmp_execute -(const struct sieve_operation *op ATTR_UNUSED, - const struct sieve_runtime_env *renv, sieve_size_t *address ATTR_UNUSED) +(const struct sieve_runtime_env *renv, sieve_size_t *address ATTR_UNUSED) { sieve_runtime_trace(renv, "JMP"); @@ -1004,8 +1057,7 @@ static int opc_jmp_execute } static int opc_jmptrue_execute -(const struct sieve_operation *op ATTR_UNUSED, - const struct sieve_runtime_env *renv, sieve_size_t *address ATTR_UNUSED) +(const struct sieve_runtime_env *renv, sieve_size_t *address ATTR_UNUSED) { bool result = sieve_interpreter_get_test_result(renv->interp); @@ -1015,8 +1067,7 @@ static int opc_jmptrue_execute } static int opc_jmpfalse_execute -(const struct sieve_operation *op ATTR_UNUSED, - const struct sieve_runtime_env *renv, sieve_size_t *address ATTR_UNUSED) +(const struct sieve_runtime_env *renv, sieve_size_t *address ATTR_UNUSED) { bool result = sieve_interpreter_get_test_result(renv->interp); diff --git a/src/lib-sieve/sieve-code.h b/src/lib-sieve/sieve-code.h index fde950862..d6d2dd857 100644 --- a/src/lib-sieve/sieve-code.h +++ b/src/lib-sieve/sieve-code.h @@ -52,20 +52,33 @@ struct sieve_operand_class { const char *name; }; -struct sieve_operand { +struct sieve_operand_def { const char *name; - const struct sieve_extension *extension; + const struct sieve_extension_def *ext_def; unsigned int code; const struct sieve_operand_class *class; const void *interface; }; -sieve_size_t sieve_operand_emit_code - (struct sieve_binary *sbin, const struct sieve_operand *opr); -const struct sieve_operand *sieve_operand_read - (struct sieve_binary *sbin, sieve_size_t *address); +struct sieve_operand { + const struct sieve_operand_def *def; + const struct sieve_extension *ext; + sieve_size_t address; +}; + +#define sieve_operand_name(opr) \ + ( (opr)->def == NULL ? "(NULL)" : (opr)->def->name ) +#define sieve_operand_is(opr, definition) \ + ( (opr)->def == &(definition) ) + +sieve_size_t sieve_operand_emit + (struct sieve_binary *sbin, const struct sieve_extension *ext, + const struct sieve_operand_def *oprnd); +bool sieve_operand_read + (struct sieve_binary *sbin, sieve_size_t *address, + struct sieve_operand *oprnd); bool sieve_operand_optional_present (struct sieve_binary *sbin, sieve_size_t *address); @@ -100,13 +113,13 @@ extern const struct sieve_operand_class stringlist_class; /* Operand objects */ -extern const struct sieve_operand omitted_operand; -extern const struct sieve_operand number_operand; -extern const struct sieve_operand string_operand; -extern const struct sieve_operand stringlist_operand; -extern const struct sieve_operand catenated_string_operand; +extern const struct sieve_operand_def omitted_operand; +extern const struct sieve_operand_def number_operand; +extern const struct sieve_operand_def string_operand; +extern const struct sieve_operand_def stringlist_operand; +extern const struct sieve_operand_def catenated_string_operand; -extern const struct sieve_operand *sieve_operands[]; +extern const struct sieve_operand_def *sieve_operands[]; extern const unsigned int sieve_operand_count; /* Operand object interfaces */ @@ -122,11 +135,11 @@ struct sieve_opr_number_interface { struct sieve_opr_string_interface { bool (*dump) - (const struct sieve_dumptime_env *denv, sieve_size_t *address, - const char *field_name); + (const struct sieve_dumptime_env *denv, const struct sieve_operand *operand, + sieve_size_t *address, const char *field_name); bool (*read) - (const struct sieve_runtime_env *renv, sieve_size_t *address, - string_t **str_r); + (const struct sieve_runtime_env *renv, const struct sieve_operand *operand, + sieve_size_t *address, string_t **str_r); }; struct sieve_opr_stringlist_interface { @@ -148,7 +161,8 @@ void sieve_opr_omitted_emit(struct sieve_binary *sbin); static inline bool sieve_operand_is_omitted (const struct sieve_operand *operand) { - return ( operand != NULL && operand == &omitted_operand ); + return ( operand != NULL && operand->def != NULL && + operand->def == &omitted_operand ); } /* Number */ @@ -170,7 +184,8 @@ bool sieve_opr_number_read static inline bool sieve_operand_is_number (const struct sieve_operand *operand) { - return ( operand != NULL && operand->class == &number_class ); + return ( operand != NULL && operand->def != NULL && + operand->def->class == &number_class ); } /* String */ @@ -197,7 +212,8 @@ bool sieve_opr_string_read_ex static inline bool sieve_operand_is_string (const struct sieve_operand *operand) { - return ( operand != NULL && operand->class == &string_class ); + return ( operand != NULL && operand->def != NULL && + operand->def->class == &string_class ); } /* String list */ @@ -216,15 +232,16 @@ bool sieve_opr_stringlist_dump const char *field_name); struct sieve_coded_stringlist *sieve_opr_stringlist_read_data (const struct sieve_runtime_env *renv, const struct sieve_operand *operand, - sieve_size_t op_address, sieve_size_t *address); + sieve_size_t *address); struct sieve_coded_stringlist *sieve_opr_stringlist_read (const struct sieve_runtime_env *renv, sieve_size_t *address); static inline bool sieve_operand_is_stringlist (const struct sieve_operand *operand) { - return ( operand != NULL && - (operand->class == &stringlist_class || operand->class == &string_class) ); + return ( operand != NULL && operand->def != NULL && + (operand->def->class == &stringlist_class || + operand->def->class == &string_class) ); } /* Catenated string */ @@ -236,26 +253,38 @@ void sieve_opr_catenated_string_emit * Operation object */ -struct sieve_operation { +struct sieve_operation_def { const char *mnemonic; - const struct sieve_extension *extension; + const struct sieve_extension_def *ext_def; unsigned int code; bool (*dump) - (const struct sieve_operation *op, - const struct sieve_dumptime_env *denv, sieve_size_t *address); + (const struct sieve_dumptime_env *denv, sieve_size_t *address); int (*execute) - (const struct sieve_operation *op, - const struct sieve_runtime_env *renv, sieve_size_t *address); + (const struct sieve_runtime_env *renv, sieve_size_t *address); }; -sieve_size_t sieve_operation_emit_code - (struct sieve_binary *sbin, const struct sieve_operation *op); -const struct sieve_operation *sieve_operation_read - (struct sieve_binary *sbin, sieve_size_t *address); +struct sieve_operation { + const struct sieve_operation_def *def; + const struct sieve_extension *ext; + + sieve_size_t address; +}; + +#define sieve_operation_is(oprtn, definition) \ + ( (oprtn)->def == &(definition) ) +#define sieve_operation_mnemonic(oprtn) \ + ( (oprtn)->def == NULL ? "(NULL)" : (oprtn)->def->mnemonic ) + +sieve_size_t sieve_operation_emit + (struct sieve_binary *sbin, const struct sieve_extension *ext, + const struct sieve_operation_def *op_def); +bool sieve_operation_read + (struct sieve_binary *sbin, sieve_size_t *address, + struct sieve_operation *oprtn); const char *sieve_operation_read_string - (struct sieve_binary *sbin, sieve_size_t *address); + (struct sieve_binary *sbin, sieve_size_t *address); /* * Core operations @@ -285,11 +314,11 @@ enum sieve_operation_code { /* Operation objects */ -extern const struct sieve_operation sieve_jmp_operation; -extern const struct sieve_operation sieve_jmptrue_operation; -extern const struct sieve_operation sieve_jmpfalse_operation; +extern const struct sieve_operation_def sieve_jmp_operation; +extern const struct sieve_operation_def sieve_jmptrue_operation; +extern const struct sieve_operation_def sieve_jmpfalse_operation; -extern const struct sieve_operation *sieve_operations[]; +extern const struct sieve_operation_def *sieve_operations[]; extern const unsigned int sieve_operations_count; #endif diff --git a/src/lib-sieve/sieve-commands.c b/src/lib-sieve/sieve-commands.c index a73b5c7fd..5a8bd165f 100644 --- a/src/lib-sieve/sieve-commands.c +++ b/src/lib-sieve/sieve-commands.c @@ -24,36 +24,36 @@ static bool arg_number_generate (const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, - struct sieve_command_context *context); + struct sieve_command *context); static bool arg_string_generate (const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, - struct sieve_command_context *context); + struct sieve_command *context); static bool arg_string_list_validate - (struct sieve_validator *validator, struct sieve_ast_argument **arg, - struct sieve_command_context *context); + (struct sieve_validator *valdtr, struct sieve_ast_argument **arg, + struct sieve_command *context); static bool arg_string_list_generate (const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, - struct sieve_command_context *context); + struct sieve_command *context); /* Argument objects */ -const struct sieve_argument number_argument = { +const struct sieve_argument_def number_argument = { "@number", NULL, NULL, NULL, NULL, arg_number_generate }; -const struct sieve_argument string_argument = { +const struct sieve_argument_def string_argument = { "@string", NULL, NULL, NULL, NULL, arg_string_generate }; -const struct sieve_argument string_list_argument = { +const struct sieve_argument_def string_list_argument = { "@string-list", - NULL, NULL, + NULL, arg_string_list_validate, - NULL, + NULL, NULL, arg_string_list_generate }; @@ -61,7 +61,7 @@ const struct sieve_argument string_list_argument = { static bool arg_number_generate (const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, - struct sieve_command_context *context ATTR_UNUSED) + struct sieve_command *cmd ATTR_UNUSED) { sieve_opr_number_emit(cgenv->sbin, sieve_ast_argument_number(arg)); @@ -70,7 +70,7 @@ static bool arg_number_generate static bool arg_string_generate (const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, - struct sieve_command_context *context ATTR_UNUSED) + struct sieve_command *cmd ATTR_UNUSED) { sieve_opr_string_emit(cgenv->sbin, sieve_ast_argument_str(arg)); @@ -78,14 +78,14 @@ static bool arg_string_generate } static bool arg_string_list_validate -(struct sieve_validator *validator, struct sieve_ast_argument **arg, - struct sieve_command_context *context) +(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, + struct sieve_command *cmd) { struct sieve_ast_argument *stritem; stritem = sieve_ast_strlist_first(*arg); while ( stritem != NULL ) { - if ( !sieve_validator_argument_activate(validator, context, stritem, FALSE) ) + if ( !sieve_validator_argument_activate(valdtr, cmd, stritem, FALSE) ) return FALSE; stritem = sieve_ast_strlist_next(stritem); @@ -96,7 +96,7 @@ static bool arg_string_list_validate static bool emit_string_list_operand (const struct sieve_codegen_env *cgenv, const struct sieve_ast_argument *strlist, - struct sieve_command_context *context) + struct sieve_command *cmd) { void *list_context; struct sieve_ast_argument *stritem; @@ -106,7 +106,7 @@ static bool emit_string_list_operand stritem = sieve_ast_strlist_first(strlist); while ( stritem != NULL ) { - if ( !sieve_generate_argument(cgenv, stritem, context) ) + if ( !sieve_generate_argument(cgenv, stritem, cmd) ) return FALSE; stritem = sieve_ast_strlist_next(stritem); @@ -119,20 +119,20 @@ static bool emit_string_list_operand static bool arg_string_list_generate (const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, - struct sieve_command_context *context) + struct sieve_command *cmd) { if ( sieve_ast_argument_type(arg) == SAAT_STRING ) { - return ( sieve_generate_argument(cgenv, arg, context) ); + return ( sieve_generate_argument(cgenv, arg, cmd) ); } else if ( sieve_ast_argument_type(arg) == SAAT_STRING_LIST ) { bool result = TRUE; if ( sieve_ast_strlist_count(arg) == 1 ) return ( sieve_generate_argument - (cgenv, sieve_ast_strlist_first(arg), context) ); + (cgenv, sieve_ast_strlist_first(arg), cmd) ); else { T_BEGIN { - result=emit_string_list_operand(cgenv, arg, context); + result=emit_string_list_operand(cgenv, arg, cmd); } T_END; } @@ -165,7 +165,7 @@ struct sieve_arg_catenated_string *sieve_arg_catenated_string_create catstr = p_new(pool, struct sieve_arg_catenated_string, 1); catstr->str_parts = arglist; - (orig_arg)->context = (void *) catstr; + (orig_arg)->argument->data = (void *) catstr; return catstr; } @@ -183,11 +183,11 @@ void sieve_arg_catenated_string_add_element bool sieve_arg_catenated_string_generate (const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, - struct sieve_command_context *cmd) + struct sieve_command *cmd) { struct sieve_binary *sbin = cgenv->sbin; struct sieve_arg_catenated_string *catstr = - (struct sieve_arg_catenated_string *) arg->context; + (struct sieve_arg_catenated_string *) arg->argument->data; struct sieve_ast_argument *strpart; if ( _cat_string_count(catstr) == 1 ) @@ -207,11 +207,31 @@ bool sieve_arg_catenated_string_generate return TRUE; } +/* + * Argument creation + */ + +struct sieve_argument *sieve_argument_create +(struct sieve_ast *ast, const struct sieve_argument_def *def, + const struct sieve_extension *ext, int id_code) +{ + struct sieve_argument *arg; + pool_t pool; + + pool = sieve_ast_pool(ast); + arg = p_new(pool, struct sieve_argument, 1); + arg->def = def; + arg->ext = ext; + arg->id_code = id_code; + + return arg; +} + /* * Core tests and commands */ -const struct sieve_command *sieve_core_tests[] = { +const struct sieve_command_def *sieve_core_tests[] = { &tst_false, &tst_true, &tst_not, &tst_anyof, &tst_allof, &tst_address, &tst_header, &tst_exists, &tst_size @@ -219,7 +239,7 @@ const struct sieve_command *sieve_core_tests[] = { const unsigned int sieve_core_tests_count = N_ELEMENTS(sieve_core_tests); -const struct sieve_command *sieve_core_commands[] = { +const struct sieve_command_def *sieve_core_commands[] = { &cmd_require, &cmd_stop, &cmd_if, &cmd_elsif, &cmd_else, &cmd_keep, &cmd_discard, &cmd_redirect @@ -231,49 +251,49 @@ const unsigned int sieve_core_commands_count = N_ELEMENTS(sieve_core_commands); * Command context */ -struct sieve_command_context *sieve_command_prev_context - (struct sieve_command_context *context) +struct sieve_command *sieve_command_prev +(struct sieve_command *cmd) { - struct sieve_ast_node *node = sieve_ast_node_prev(context->ast_node); + struct sieve_ast_node *node = sieve_ast_node_prev(cmd->ast_node); if ( node != NULL ) { - return node->context; + return node->command; } return NULL; } -struct sieve_command_context *sieve_command_parent_context - (struct sieve_command_context *context) +struct sieve_command *sieve_command_parent +(struct sieve_command *cmd) { - struct sieve_ast_node *node = sieve_ast_node_parent(context->ast_node); - - if ( node != NULL ) { - return node->context; - } + struct sieve_ast_node *node = sieve_ast_node_parent(cmd->ast_node); - return NULL; + return ( node != NULL ? node->command : NULL ); } -struct sieve_command_context *sieve_command_context_create - (struct sieve_ast_node *cmd_node, const struct sieve_command *command, - struct sieve_command_registration *reg) +struct sieve_command *sieve_command_create +(struct sieve_ast_node *cmd_node, const struct sieve_extension *ext, + const struct sieve_command_def *cmd_def, + struct sieve_command_registration *cmd_reg) { - struct sieve_command_context *cmd; - - cmd = p_new(sieve_ast_node_pool(cmd_node), struct sieve_command_context, 1); + struct sieve_command *cmd; - cmd->ast_node = cmd_node; - cmd->command = command; - cmd->cmd_reg = reg; + cmd = p_new(sieve_ast_node_pool(cmd_node), struct sieve_command, 1); + + cmd->ast_node = cmd_node; + cmd->def = cmd_def; + cmd->ext = ext; + cmd->reg = cmd_reg; cmd->block_exit_command = NULL; return cmd; } -const char *sieve_command_type_name(const struct sieve_command *command) { - switch ( command->type ) { +const char *sieve_command_def_type_name +(const struct sieve_command_def *cmd_def) +{ + switch ( cmd_def->type ) { case SCT_NONE: return "command of unspecified type (bug)"; case SCT_TEST: return "test"; case SCT_COMMAND: return "command"; @@ -284,8 +304,8 @@ const char *sieve_command_type_name(const struct sieve_command *command) { } struct sieve_ast_argument *sieve_command_add_dynamic_tag -(struct sieve_command_context *cmd, const struct sieve_argument *tag, - int id_code) +(struct sieve_command *cmd, const struct sieve_extension *ext, + const struct sieve_argument_def *tag, int id_code) { struct sieve_ast_argument *arg; @@ -296,20 +316,19 @@ struct sieve_ast_argument *sieve_command_add_dynamic_tag arg = sieve_ast_argument_tag_create (cmd->ast_node, tag->identifier, cmd->ast_node->source_line); - arg->argument = tag; - arg->arg_id_code = id_code; + arg->argument = sieve_argument_create(cmd->ast_node->ast, tag, ext, id_code); return arg; } struct sieve_ast_argument *sieve_command_find_argument -(struct sieve_command_context *cmd, const struct sieve_argument *argument) +(struct sieve_command *cmd, const struct sieve_argument_def *arg_def) { struct sieve_ast_argument *arg = sieve_ast_argument_first(cmd->ast_node); /* Visit tagged and optional arguments */ while ( arg != NULL ) { - if ( arg->argument == argument ) + if ( arg->argument != NULL && arg->argument->def == arg_def ) return arg; arg = sieve_ast_argument_next(arg); @@ -324,9 +343,9 @@ struct sieve_ast_argument *sieve_command_find_argument * necessary. */ void sieve_command_exit_block_unconditionally - (struct sieve_command_context *cmd) + (struct sieve_command *cmd) { - struct sieve_command_context *parent = sieve_command_parent_context(cmd); + struct sieve_command *parent = sieve_command_parent(cmd); /* Only the first unconditional exit is of importance */ if ( parent != NULL && parent->block_exit_command == NULL ) @@ -334,7 +353,7 @@ void sieve_command_exit_block_unconditionally } bool sieve_command_block_exits_unconditionally - (struct sieve_command_context *cmd) + (struct sieve_command *cmd) { return ( cmd->block_exit_command != NULL ); } diff --git a/src/lib-sieve/sieve-commands.h b/src/lib-sieve/sieve-commands.h index 9968c6b57..9df130202 100644 --- a/src/lib-sieve/sieve-commands.h +++ b/src/lib-sieve/sieve-commands.h @@ -10,34 +10,53 @@ #include "sieve-ast.h" /* - * Argument object + * Argument definition */ -struct sieve_argument { +struct sieve_argument_def { const char *identifier; bool (*is_instance_of) - (struct sieve_validator *validator, struct sieve_command_context *cmdctx, - struct sieve_ast_argument *arg); + (struct sieve_validator *valdtr, struct sieve_command *cmd, + const struct sieve_extension *ext, const char *identifier, void **data); - bool (*validate_persistent) // FIXME: this method must be moved down - (struct sieve_validator *validator, struct sieve_command_context *cmdctx); bool (*validate) - (struct sieve_validator *validator, struct sieve_ast_argument **arg, - struct sieve_command_context *context); + (struct sieve_validator *valdtr, struct sieve_ast_argument **arg, + struct sieve_command *cmd); bool (*validate_context) - (struct sieve_validator *validator, struct sieve_ast_argument *arg, - struct sieve_command_context *context); - + (struct sieve_validator *valdtr, struct sieve_ast_argument *arg, + struct sieve_command *cmd); + bool (*validate_persistent) + (struct sieve_validator *valdtr, struct sieve_command *cmd, + const struct sieve_extension *ext); + bool (*generate) (const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, - struct sieve_command_context *context); + struct sieve_command *cmd); +}; + +/* + * Argument instance + */ + +struct sieve_argument { + const struct sieve_argument_def *def; + const struct sieve_extension *ext; + int id_code; + + /* Context data */ + void *data; }; +#define sieve_argument_is(ast_arg, definition) \ + ( (ast_arg)->argument->def == &(definition) ) +#define sieve_argument_ext(ast_arg) \ + ( (ast_arg)->argument->ext ) + /* Utility macros */ #define sieve_argument_is_string_literal(arg) \ - ( (arg)->argument == &string_argument ) + ( (arg)->argument->def == &string_argument ) /* Error handling */ @@ -46,17 +65,23 @@ struct sieve_argument { #define sieve_argument_validate_warning(validator, arg_node, ...) \ sieve_validator_warning(validator, (arg_node)->source_line, __VA_ARGS__) +/* Argument API */ + +struct sieve_argument *sieve_argument_create + (struct sieve_ast *ast, const struct sieve_argument_def *def, + const struct sieve_extension *ext, int id_code); + /* Literal arguments */ -extern const struct sieve_argument number_argument; -extern const struct sieve_argument string_argument; -extern const struct sieve_argument string_list_argument; +extern const struct sieve_argument_def number_argument; +extern const struct sieve_argument_def string_argument; +extern const struct sieve_argument_def string_list_argument; /* Catenated string argument */ bool sieve_arg_catenated_string_generate (const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, - struct sieve_command_context *context); + struct sieve_command *context); struct sieve_arg_catenated_string; @@ -67,7 +92,7 @@ void sieve_arg_catenated_string_add_element struct sieve_ast_argument *element); /* - * Command object + * Command definition */ enum sieve_command_type { @@ -77,7 +102,7 @@ enum sieve_command_type { SCT_HYBRID }; -struct sieve_command { +struct sieve_command_def { const char *identifier; enum sieve_command_type type; @@ -88,28 +113,29 @@ struct sieve_command { bool block_required; bool (*registered) - (struct sieve_validator *validator, + (struct sieve_validator *valdtr, const struct sieve_extension *ext, struct sieve_command_registration *cmd_reg); bool (*pre_validate) - (struct sieve_validator *validator, struct sieve_command_context *context); + (struct sieve_validator *valdtr, struct sieve_command *cmd); bool (*validate) - (struct sieve_validator *validator, struct sieve_command_context *context); + (struct sieve_validator *valdtr, struct sieve_command *cmd); bool (*generate) - (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx); + (const struct sieve_codegen_env *cgenv, struct sieve_command *cmd); bool (*control_generate) - (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx, + (const struct sieve_codegen_env *cgenv, struct sieve_command *cmd, struct sieve_jumplist *jumps, bool jump_true); }; /* - * Command context + * Command instance */ -struct sieve_command_context { - const struct sieve_command *command; +struct sieve_command { + const struct sieve_command_def *def; + const struct sieve_extension *ext; /* The registration of this command in the validator (sieve-validator.h) */ - struct sieve_command_registration *cmd_reg; + struct sieve_command_registration *reg; /* The ast node of this command */ struct sieve_ast_node *ast_node; @@ -118,35 +144,47 @@ struct sieve_command_context { struct sieve_ast_argument *first_positional; /* The child ast node that unconditionally exits this command's block */ - struct sieve_command_context *block_exit_command; + struct sieve_command *block_exit_command; - /* Command-specific context data*/ + /* Context data*/ void *data; }; +#define sieve_command_is(cmd, definition) \ + ( (cmd)->def == &(definition) ) +#define sieve_command_identifier(cmd) \ + ( (cmd)->def->identifier ) +#define sieve_command_type_name(cmd) \ + ( sieve_command_def_type_name((cmd)->def) ) + +#define sieve_commands_equal(cmd1, cmd2) \ + ( (cmd1)->def == (cmd2)->def ) + /* Context API */ -struct sieve_command_context *sieve_command_context_create - (struct sieve_ast_node *cmd_node, const struct sieve_command *command, - struct sieve_command_registration *reg); +struct sieve_command *sieve_command_create + (struct sieve_ast_node *cmd_node, const struct sieve_extension *ext, + const struct sieve_command_def *cmd_def, + struct sieve_command_registration *cmd_reg); -const char *sieve_command_type_name(const struct sieve_command *command); +const char *sieve_command_def_type_name + (const struct sieve_command_def *cmd_def); -struct sieve_command_context *sieve_command_prev_context - (struct sieve_command_context *context); -struct sieve_command_context *sieve_command_parent_context - (struct sieve_command_context *context); +struct sieve_command *sieve_command_prev + (struct sieve_command *cmd); +struct sieve_command *sieve_command_parent + (struct sieve_command *cmd); struct sieve_ast_argument *sieve_command_add_dynamic_tag - (struct sieve_command_context *cmd, const struct sieve_argument *tag, - int id_code); + (struct sieve_command *cmd, const struct sieve_extension *ext, + const struct sieve_argument_def *tag, int id_code); struct sieve_ast_argument *sieve_command_find_argument - (struct sieve_command_context *cmd, const struct sieve_argument *argument); + (struct sieve_command *cmd, const struct sieve_argument_def *argument); void sieve_command_exit_block_unconditionally - (struct sieve_command_context *cmd); + (struct sieve_command *cmd); bool sieve_command_block_exits_unconditionally - (struct sieve_command_context *cmd); + (struct sieve_command *cmd); /* Error handling */ @@ -182,33 +220,33 @@ bool sieve_command_block_exits_unconditionally * Core commands */ -extern const struct sieve_command cmd_require; -extern const struct sieve_command cmd_stop; -extern const struct sieve_command cmd_if; -extern const struct sieve_command cmd_elsif; -extern const struct sieve_command cmd_else; -extern const struct sieve_command cmd_redirect; -extern const struct sieve_command cmd_keep; -extern const struct sieve_command cmd_discard; - -extern const struct sieve_command *sieve_core_commands[]; +extern const struct sieve_command_def cmd_require; +extern const struct sieve_command_def cmd_stop; +extern const struct sieve_command_def cmd_if; +extern const struct sieve_command_def cmd_elsif; +extern const struct sieve_command_def cmd_else; +extern const struct sieve_command_def cmd_redirect; +extern const struct sieve_command_def cmd_keep; +extern const struct sieve_command_def cmd_discard; + +extern const struct sieve_command_def *sieve_core_commands[]; extern const unsigned int sieve_core_commands_count; /* * Core tests */ -extern const struct sieve_command tst_true; -extern const struct sieve_command tst_false; -extern const struct sieve_command tst_not; -extern const struct sieve_command tst_anyof; -extern const struct sieve_command tst_allof; -extern const struct sieve_command tst_address; -extern const struct sieve_command tst_header; -extern const struct sieve_command tst_exists; -extern const struct sieve_command tst_size; - -extern const struct sieve_command *sieve_core_tests[]; +extern const struct sieve_command_def tst_true; +extern const struct sieve_command_def tst_false; +extern const struct sieve_command_def tst_not; +extern const struct sieve_command_def tst_anyof; +extern const struct sieve_command_def tst_allof; +extern const struct sieve_command_def tst_address; +extern const struct sieve_command_def tst_header; +extern const struct sieve_command_def tst_exists; +extern const struct sieve_command_def tst_size; + +extern const struct sieve_command_def *sieve_core_tests[]; extern const unsigned int sieve_core_tests_count; /* diff --git a/src/lib-sieve/sieve-common.h b/src/lib-sieve/sieve-common.h index 50456b2ef..fbd44044a 100644 --- a/src/lib-sieve/sieve-common.h +++ b/src/lib-sieve/sieve-common.h @@ -4,6 +4,8 @@ #ifndef __SIEVE_COMMON_H #define __SIEVE_COMMON_H +#include "lib.h" + #include "sieve-config.h" #include "sieve-types.h" @@ -35,7 +37,9 @@ struct sieve_ast_argument; /* sieve-commands.h */ struct sieve_argument; +struct sieve_argument_def; struct sieve_command; +struct sieve_command_def; struct sieve_command_context; struct sieve_command_registration; @@ -69,10 +73,12 @@ struct sieve_code_dumper; /* sieve-extension.h */ struct sieve_extension; +struct sieve_extension_def; struct sieve_extension_objects; /* sieve-code.h */ struct sieve_operand; +struct sieve_operand_def; struct sieve_operand_class; struct sieve_operation; struct sieve_coded_stringlist; @@ -81,6 +87,7 @@ struct sieve_coded_stringlist; struct sieve_binary; /* sieve-objects.h */ +struct sieve_object_def; struct sieve_object; /* sieve-comparator.h */ @@ -96,6 +103,7 @@ struct sieve_match_context; struct sieve_address; /* sieve-address-parts.h */ +struct sieve_address_part_def; struct sieve_address_part; /* sieve-result.h */ @@ -106,7 +114,9 @@ struct sieve_result_print_env; /* sieve-actions.h */ struct sieve_action_exec_env; struct sieve_action; +struct sieve_action_def; struct sieve_side_effect; +struct sieve_side_effect_def; /* sieve-script.h */ struct sieve_script; @@ -120,4 +130,18 @@ struct sieve_ast *sieve_parse bool sieve_validate (struct sieve_ast *ast, struct sieve_error_handler *ehandler); +/* + * Sieve engine instance + */ + +struct sieve_instance { + pool_t pool; + + const struct sieve_callbacks *callbacks; + + void *context; + + struct sieve_extension_registry *ext_reg; +}; + #endif /* __SIEVE_COMMON_H */ diff --git a/src/lib-sieve/sieve-comparators.c b/src/lib-sieve/sieve-comparators.c index 382db2780..de908b685 100644 --- a/src/lib-sieve/sieve-comparators.c +++ b/src/lib-sieve/sieve-comparators.c @@ -24,31 +24,22 @@ * Core comparators */ -const struct sieve_comparator *sieve_core_comparators[] = { +const struct sieve_comparator_def *sieve_core_comparators[] = { &i_octet_comparator, &i_ascii_casemap_comparator }; const unsigned int sieve_core_comparators_count = N_ELEMENTS(sieve_core_comparators); -/* - * Forward declarations - */ - -static void sieve_opr_comparator_emit - (struct sieve_binary *sbin, const struct sieve_comparator *cmp); - /* * Comparator 'extension' */ -static int ext_my_id = -1; +static bool cmp_validator_load + (const struct sieve_extension *ext, struct sieve_validator *valdtr); -static bool cmp_validator_load(struct sieve_validator *validator); - -const struct sieve_extension comparator_extension = { +const struct sieve_extension_def comparator_extension = { "@comparators", - &ext_my_id, NULL, NULL, cmp_validator_load, NULL, NULL, NULL, NULL, NULL, @@ -56,43 +47,60 @@ const struct sieve_extension comparator_extension = { SIEVE_EXT_DEFINE_NO_OPERANDS /* Defined as core operand */ }; -static const struct sieve_extension *ext_this = &comparator_extension; - /* * Validator context: * name-based comparator registry. */ +static struct sieve_validator_object_registry *_get_object_registry +(struct sieve_validator *valdtr) +{ + struct sieve_instance *svinst; + const struct sieve_extension *mcht_ext; + + svinst = sieve_validator_svinst(valdtr); + mcht_ext = sieve_get_comparator_extension(svinst); + return sieve_validator_object_registry_get(valdtr, mcht_ext); +} + void sieve_comparator_register -(struct sieve_validator *validator, const struct sieve_comparator *cmp) +(struct sieve_validator *valdtr, const struct sieve_extension *ext, + const struct sieve_comparator_def *cmp) { - struct sieve_validator_object_registry *regs = - sieve_validator_object_registry_get(validator, ext_this); + struct sieve_validator_object_registry *regs = _get_object_registry(valdtr); - sieve_validator_object_registry_add(regs, &cmp->object); + sieve_validator_object_registry_add(regs, ext, &cmp->obj_def); } -const struct sieve_comparator *sieve_comparator_find -(struct sieve_validator *validator, const char *identifier) +static struct sieve_comparator *sieve_comparator_create +(struct sieve_validator *valdtr, struct sieve_command *cmd, + const char *identifier) { - struct sieve_validator_object_registry *regs = - sieve_validator_object_registry_get(validator, ext_this); - const struct sieve_object *object = - sieve_validator_object_registry_find(regs, identifier); + struct sieve_validator_object_registry *regs = _get_object_registry(valdtr); + struct sieve_object object; + struct sieve_comparator *cmp; + + if ( !sieve_validator_object_registry_find(regs, identifier, &object) ) + return NULL; + + cmp = p_new(sieve_command_pool(cmd), struct sieve_comparator, 1); + cmp->object = object; + cmp->def = (const struct sieve_comparator_def *) object.def; - return (const struct sieve_comparator *) object; + return cmp; } -bool cmp_validator_load(struct sieve_validator *validator) +bool cmp_validator_load +(const struct sieve_extension *ext, struct sieve_validator *valdtr) { struct sieve_validator_object_registry *regs = - sieve_validator_object_registry_init(validator, ext_this); + sieve_validator_object_registry_init(valdtr, ext); unsigned int i; /* Register core comparators */ for ( i = 0; i < sieve_core_comparators_count; i++ ) { sieve_validator_object_registry_add - (regs, &(sieve_core_comparators[i]->object)); + (regs, NULL, &(sieve_core_comparators[i]->obj_def)); } return TRUE; @@ -101,40 +109,32 @@ bool cmp_validator_load(struct sieve_validator *validator) /* * Comparator tagged argument */ - -/* Context data */ - -struct sieve_comparator_context { - struct sieve_command_context *command_ctx; - const struct sieve_comparator *comparator; -}; - + /* Forward declarations */ static bool tag_comparator_validate - (struct sieve_validator *validator, struct sieve_ast_argument **arg, - struct sieve_command_context *cmd); + (struct sieve_validator *valdtr, struct sieve_ast_argument **arg, + struct sieve_command *cmd); static bool tag_comparator_generate (const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, - struct sieve_command_context *cmd); + struct sieve_command *cmd); /* Argument object */ -const struct sieve_argument comparator_tag = { +const struct sieve_argument_def comparator_tag = { "comparator", - NULL, NULL, + NULL, tag_comparator_validate, - NULL, + NULL, NULL, tag_comparator_generate }; /* Argument implementation */ static bool tag_comparator_validate - (struct sieve_validator *validator, struct sieve_ast_argument **arg, - struct sieve_command_context *cmd) +(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, + struct sieve_command *cmd) { - struct sieve_comparator_context *cmpctx; struct sieve_ast_argument *tag = *arg; const struct sieve_comparator *cmp; @@ -145,30 +145,30 @@ static bool tag_comparator_validate * ":comparator" <comparator-name: string> */ if ( (*arg)->type != SAAT_STRING ) { - sieve_argument_validate_error(validator, *arg, + sieve_argument_validate_error(valdtr, *arg, ":comparator tag requires one string argument, but %s was found", sieve_ast_argument_name(*arg) ); return FALSE; } - if ( !sieve_validator_argument_activate(validator, cmd, *arg, FALSE) ) + if ( !sieve_validator_argument_activate(valdtr, cmd, *arg, FALSE) ) return FALSE; /* FIXME: We can currently only handle string literal argument, so * variables are not allowed. */ if ( !sieve_argument_is_string_literal(*arg) ) { - sieve_argument_validate_error(validator, *arg, + sieve_argument_validate_error(valdtr, *arg, "this Sieve implementation currently only supports " "a literal string argument for the :comparator tag"); return FALSE; } /* Get comparator from registry */ - cmp = sieve_comparator_find(validator, sieve_ast_argument_strc(*arg)); + cmp = sieve_comparator_create(valdtr, cmd, sieve_ast_argument_strc(*arg)); if ( cmp == NULL ) { - sieve_argument_validate_error(validator, *arg, + sieve_argument_validate_error(valdtr, *arg, "unknown comparator '%s'", str_sanitize(sieve_ast_argument_strc(*arg),80)); @@ -180,24 +180,18 @@ static bool tag_comparator_validate */ *arg = sieve_ast_arguments_detach(*arg, 1); - /* Create context */ - cmpctx = p_new(sieve_command_pool(cmd), struct sieve_comparator_context, 1); - cmpctx->command_ctx = cmd; - cmpctx->comparator = cmp; - /* Store comparator in context */ - tag->context = (void *) cmpctx; + tag->argument->data = (void *) cmp; return TRUE; } static bool tag_comparator_generate (const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, - struct sieve_command_context *cmd ATTR_UNUSED) + struct sieve_command *cmd ATTR_UNUSED) { - struct sieve_comparator_context *cmpctx = - (struct sieve_comparator_context *) arg->context; - const struct sieve_comparator *cmp = cmpctx->comparator; + const struct sieve_comparator *cmp = + (const struct sieve_comparator *) arg->argument->data; sieve_opr_comparator_emit(cgenv->sbin, cmp); @@ -207,34 +201,40 @@ static bool tag_comparator_generate /* Functions to enable and evaluate comparator tag for commands */ void sieve_comparators_link_tag -(struct sieve_validator *validator, struct sieve_command_registration *cmd_reg, +(struct sieve_validator *valdtr, struct sieve_command_registration *cmd_reg, int id_code) { - sieve_validator_register_tag(validator, cmd_reg, &comparator_tag, id_code); + struct sieve_instance *svinst; + const struct sieve_extension *mcht_ext; + + svinst = sieve_validator_svinst(valdtr); + mcht_ext = sieve_get_comparator_extension(svinst); + + sieve_validator_register_tag + (valdtr, cmd_reg, mcht_ext, &comparator_tag, id_code); } bool sieve_comparator_tag_is -(struct sieve_ast_argument *tag, const struct sieve_comparator *cmp) +(struct sieve_ast_argument *tag, const struct sieve_comparator_def *cmp_def) { - const struct sieve_comparator_context *cmpctx = - (const struct sieve_comparator_context *) tag->context; + const struct sieve_comparator *cmp; - if ( cmpctx == NULL ) return FALSE; + if ( !sieve_argument_is(tag, comparator_tag) ) + return FALSE; + + cmp = (const struct sieve_comparator *) tag->argument->data; - return ( tag->argument == &comparator_tag && cmpctx->comparator == cmp ); + return ( cmp->def == cmp_def ); } const struct sieve_comparator *sieve_comparator_tag_get (struct sieve_ast_argument *tag) { - const struct sieve_comparator_context *cmpctx; - - if ( tag->argument != &comparator_tag ) + if ( !sieve_argument_is(tag, comparator_tag) ) return NULL; + - cmpctx = (const struct sieve_comparator_context *) tag->context; - - return cmpctx->comparator; + return (const struct sieve_comparator *) tag->argument->data; } /* @@ -247,7 +247,7 @@ const struct sieve_operand_class sieve_comparator_operand_class = static const struct sieve_extension_objects core_comparators = SIEVE_EXT_DEFINE_COMPARATORS(sieve_core_comparators); -const struct sieve_operand comparator_operand = { +const struct sieve_operand_def comparator_operand = { "comparator", NULL, SIEVE_OPERAND_COMPARATOR, diff --git a/src/lib-sieve/sieve-comparators.h b/src/lib-sieve/sieve-comparators.h index 85a28b41e..501ee395f 100644 --- a/src/lib-sieve/sieve-comparators.h +++ b/src/lib-sieve/sieve-comparators.h @@ -20,8 +20,8 @@ enum sieve_comparator_code { SIEVE_COMPARATOR_CUSTOM }; -extern const struct sieve_comparator i_octet_comparator; -extern const struct sieve_comparator i_ascii_casemap_comparator; +extern const struct sieve_comparator_def i_octet_comparator; +extern const struct sieve_comparator_def i_ascii_casemap_comparator; /* * Comparator flags @@ -35,11 +35,11 @@ enum sieve_comparator_flags { }; /* - * Comparator object + * Comparator definition */ -struct sieve_comparator { - struct sieve_object object; +struct sieve_comparator_def { + struct sieve_object_def obj_def; unsigned int flags; @@ -58,30 +58,55 @@ struct sieve_comparator { const char **val, const char *val_end); }; +/* + * Comparator instance + */ + +struct sieve_comparator { + struct sieve_object object; + + const struct sieve_comparator_def *def; +}; + +#define SIEVE_COMPARATOR_DEFAULT(definition) \ + { SIEVE_OBJECT_DEFAULT(definition), &(definition) } + +#define sieve_comparator_is(cmp, definition) \ + ( (cmp)->def == &(definition) ) + +static inline const struct sieve_comparator *sieve_comparator_copy +(pool_t pool, const struct sieve_comparator *cmp_orig) +{ + struct sieve_comparator *cmp = p_new(pool, struct sieve_comparator, 1); + + *cmp = *cmp_orig; + + return cmp; +} + /* * Comparator tagged argument */ -extern const struct sieve_argument comparator_tag; +extern const struct sieve_argument_def comparator_tag; static inline bool sieve_argument_is_comparator (struct sieve_ast_argument *arg) { - return arg->argument == &comparator_tag; + return arg->argument->def == &comparator_tag; } void sieve_comparators_link_tag (struct sieve_validator *validator, struct sieve_command_registration *cmd_reg, int id_code); bool sieve_comparator_tag_is - (struct sieve_ast_argument *tag, const struct sieve_comparator *cmp); + (struct sieve_ast_argument *tag, const struct sieve_comparator_def *cmp); const struct sieve_comparator *sieve_comparator_tag_get (struct sieve_ast_argument *tag); void sieve_comparator_register - (struct sieve_validator *validator, const struct sieve_comparator *cmp); -const struct sieve_comparator *sieve_comparator_find - (struct sieve_validator *validator, const char *identifier); + (struct sieve_validator *validator, const struct sieve_extension *ext, + const struct sieve_comparator_def *cmp); /* * Comparator operand @@ -91,19 +116,24 @@ const struct sieve_comparator *sieve_comparator_find #define SIEVE_EXT_DEFINE_COMPARATORS(OPS) SIEVE_EXT_DEFINE_OBJECTS(OPS) extern const struct sieve_operand_class sieve_comparator_operand_class; -extern const struct sieve_operand comparator_operand; +extern const struct sieve_operand_def comparator_operand; static inline void sieve_opr_comparator_emit (struct sieve_binary *sbin, const struct sieve_comparator *cmp) { - sieve_opr_object_emit(sbin, &cmp->object); + sieve_opr_object_emit(sbin, cmp->object.ext, cmp->object.def); } -static inline const struct sieve_comparator *sieve_opr_comparator_read -(const struct sieve_runtime_env *renv, sieve_size_t *address) +static inline bool sieve_opr_comparator_read +(const struct sieve_runtime_env *renv, sieve_size_t *address, + struct sieve_comparator *cmp) { - return (const struct sieve_comparator *) sieve_opr_object_read - (renv, &sieve_comparator_operand_class, address); + if ( !sieve_opr_object_read + (renv, &sieve_comparator_operand_class, address, &cmp->object) ) + return FALSE; + + cmp->def = (const struct sieve_comparator_def *) cmp->object.def; + return TRUE; } static inline bool sieve_opr_comparator_dump diff --git a/src/lib-sieve/sieve-dump.h b/src/lib-sieve/sieve-dump.h index f102b93a8..00975910d 100644 --- a/src/lib-sieve/sieve-dump.h +++ b/src/lib-sieve/sieve-dump.h @@ -6,6 +6,7 @@ #include "sieve-common.h" +#include "sieve-code.h" #include "sieve-binary-dumper.h" #include "sieve-code-dumper.h" @@ -16,7 +17,12 @@ struct sieve_dumptime_env { struct sieve_binary_dumper *dumper; struct sieve_code_dumper *cdumper; + + struct sieve_instance *svinst; + struct sieve_binary *sbin; + + struct sieve_operation oprtn; struct ostream *stream; }; diff --git a/src/lib-sieve/sieve-extensions.c b/src/lib-sieve/sieve-extensions.c index 9f9fb72ec..f8c68c2a7 100644 --- a/src/lib-sieve/sieve-extensions.c +++ b/src/lib-sieve/sieve-extensions.c @@ -7,6 +7,7 @@ #include "hash.h" #include "array.h" +#include "sieve-common.h" #include "sieve-error.h" #include "sieve-extensions.h" @@ -14,26 +15,37 @@ * Forward declarations */ -static void sieve_extensions_init_registry(void); -static void sieve_extensions_deinit_registry(void); +static void sieve_extension_registry_init(struct sieve_instance *svinst); +static void sieve_extension_registry_deinit(struct sieve_instance *svinst); -static void sieve_extensions_init_capabilities(void); -static void sieve_extensions_deinit_capabilities(void); +static void sieve_capability_registry_init(struct sieve_instance *svinst); +static void sieve_capability_registry_deinit(struct sieve_instance *svinst); -/* - * Pre-loaded 'extensions' +/* + * Instance global context */ -extern const struct sieve_extension comparator_extension; -extern const struct sieve_extension match_type_extension; -extern const struct sieve_extension address_part_extension; +struct sieve_extension_registry { + ARRAY_DEFINE(extensions, struct sieve_extension); + struct hash_table *extension_index; + struct hash_table *capabilities_index; -const struct sieve_extension *sieve_preloaded_extensions[] = { - &comparator_extension, &match_type_extension, &address_part_extension + /* Core language 'extensions' */ + const struct sieve_extension *comparator_extension; + const struct sieve_extension *match_type_extension; + const struct sieve_extension *address_part_extension; + + /* Preloaded extensions */ + ARRAY_DEFINE(preloaded_extensions, const struct sieve_extension *); }; -const unsigned int sieve_preloaded_extensions_count = - N_ELEMENTS(sieve_preloaded_extensions); +/* + * Pre-loaded 'extensions' + */ + +extern const struct sieve_extension_def comparator_extension; +extern const struct sieve_extension_def match_type_extension; +extern const struct sieve_extension_def address_part_extension; /* * Dummy extensions @@ -41,16 +53,16 @@ const unsigned int sieve_preloaded_extensions_count = /* FIXME: This is stupid. Define a comparator-* extension and be done with it */ -static const struct sieve_extension comparator_i_octet_extension = { +static const struct sieve_extension_def comparator_i_octet_extension = { "comparator-i;octet", - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, SIEVE_EXT_DEFINE_NO_OPERATIONS, SIEVE_EXT_DEFINE_NO_OPERANDS }; -static const struct sieve_extension comparator_i_ascii_casemap_extension = { +static const struct sieve_extension_def comparator_i_ascii_casemap_extension = { "comparator-i;ascii-casemap", - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, SIEVE_EXT_DEFINE_NO_OPERATIONS, SIEVE_EXT_DEFINE_NO_OPERANDS }; @@ -59,38 +71,35 @@ static const struct sieve_extension comparator_i_ascii_casemap_extension = { * Core extensions */ -extern const struct sieve_extension fileinto_extension; -extern const struct sieve_extension reject_extension; -extern const struct sieve_extension envelope_extension; -extern const struct sieve_extension encoded_character_extension; +extern const struct sieve_extension_def fileinto_extension; +extern const struct sieve_extension_def reject_extension; +extern const struct sieve_extension_def envelope_extension; +extern const struct sieve_extension_def encoded_character_extension; /* * Native 'plugin' extensions */ -extern const struct sieve_extension vacation_extension; -extern const struct sieve_extension subaddress_extension; -extern const struct sieve_extension comparator_i_ascii_numeric_extension; -extern const struct sieve_extension relational_extension; -extern const struct sieve_extension regex_extension; -extern const struct sieve_extension imap4flags_extension; -extern const struct sieve_extension copy_extension; -extern const struct sieve_extension include_extension; -extern const struct sieve_extension body_extension; -extern const struct sieve_extension variables_extension; -extern const struct sieve_extension enotify_extension; -extern const struct sieve_extension environment_extension; -extern const struct sieve_extension mailbox_extension; -extern const struct sieve_extension date_extension; +extern const struct sieve_extension_def vacation_extension; +extern const struct sieve_extension_def subaddress_extension; +extern const struct sieve_extension_def comparator_i_ascii_numeric_extension; +extern const struct sieve_extension_def relational_extension; +extern const struct sieve_extension_def regex_extension; +extern const struct sieve_extension_def imap4flags_extension; +extern const struct sieve_extension_def copy_extension; +extern const struct sieve_extension_def include_extension; +extern const struct sieve_extension_def body_extension; +extern const struct sieve_extension_def variables_extension; +extern const struct sieve_extension_def enotify_extension; +extern const struct sieve_extension_def environment_extension; +extern const struct sieve_extension_def mailbox_extension; +extern const struct sieve_extension_def date_extension; /* * List of native extensions */ -const struct sieve_extension *sieve_core_extensions[] = { - /* Preloaded 'extensions' */ - &comparator_extension, &match_type_extension, &address_part_extension, - +const struct sieve_extension_def *sieve_core_extensions[] = { /* Dummy extensions */ &comparator_i_octet_extension, &comparator_i_ascii_casemap_extension, @@ -114,10 +123,10 @@ const unsigned int sieve_core_extensions_count = * Deprecated extensions */ -extern const struct sieve_extension imapflags_extension; -extern const struct sieve_extension notify_extension; +extern const struct sieve_extension_def imapflags_extension; +extern const struct sieve_extension_def notify_extension; -const struct sieve_extension *sieve_deprecated_extensions[] = { +const struct sieve_extension_def *sieve_deprecated_extensions[] = { &imapflags_extension, ¬ify_extension }; @@ -131,9 +140,9 @@ const unsigned int sieve_deprecated_extensions_count = #ifdef HAVE_SIEVE_UNFINISHED -extern const struct sieve_extension ereject_extension; +extern const struct sieve_extension_def ereject_extension; -const struct sieve_extension *sieve_unfinished_extensions[] = { +const struct sieve_extension_def *sieve_unfinished_extensions[] = { &ereject_extension, }; @@ -146,27 +155,53 @@ const unsigned int sieve_unfinished_extensions_count = * Extensions init/deinit */ -bool sieve_extensions_init(void) +bool sieve_extensions_init(struct sieve_instance *svinst) { - unsigned int i; - - sieve_extensions_init_registry(); - sieve_extensions_init_capabilities(); - + unsigned int i; + struct sieve_extension_registry *ext_reg = + p_new(svinst->pool, struct sieve_extension_registry, 1); + + svinst->ext_reg = ext_reg; + + sieve_extension_registry_init(svinst); + sieve_capability_registry_init(svinst); + + /* Preloaded 'extensions' */ + ext_reg->comparator_extension = + sieve_extension_register(svinst, &comparator_extension, TRUE); + ext_reg->match_type_extension = + sieve_extension_register(svinst, &match_type_extension, TRUE); + ext_reg->address_part_extension = + sieve_extension_register(svinst, &address_part_extension, TRUE); + + p_array_init(&ext_reg->preloaded_extensions, svinst->pool, 5); + array_append(&ext_reg->preloaded_extensions, + &ext_reg->comparator_extension, 1); + array_append(&ext_reg->preloaded_extensions, + &ext_reg->match_type_extension, 1); + array_append(&ext_reg->preloaded_extensions, + &ext_reg->address_part_extension, 1); + /* Pre-load core extensions */ for ( i = 0; i < sieve_core_extensions_count; i++ ) { - (void)sieve_extension_register(sieve_core_extensions[i], TRUE); + if ( sieve_extension_register + (svinst, sieve_core_extensions[i], TRUE) == NULL ) + return FALSE; } /* Register deprecated extensions */ for ( i = 0; i < sieve_deprecated_extensions_count; i++ ) { - (void)sieve_extension_register(sieve_deprecated_extensions[i], FALSE); + if ( sieve_extension_register + (svinst, sieve_deprecated_extensions[i], FALSE) == NULL ) + return FALSE; } #ifdef HAVE_SIEVE_UNFINISHED /* Register unfinished extensions */ for ( i = 0; i < sieve_unfinished_extensions_count; i++ ) { - (void)sieve_extension_register(sieve_unfinished_extensions[i], FALSE); + if ( sieve_extension_register + (svinst, sieve_unfinished_extensions[i], FALSE) == NULL ) + return FALSE; } #endif @@ -175,178 +210,193 @@ bool sieve_extensions_init(void) return TRUE; } -void sieve_extensions_deinit(void) +void sieve_extensions_deinit(struct sieve_instance *svinst) { - sieve_extensions_deinit_capabilities(); - sieve_extensions_deinit_registry(); + sieve_extension_registry_deinit(svinst); + sieve_capability_registry_deinit(svinst); +} + +/* + * Pre-loaded extensions + */ + +const struct sieve_extension *const *sieve_extensions_get_preloaded +(struct sieve_instance *svinst, unsigned int *count_r) +{ + struct sieve_extension_registry *ext_reg = svinst->ext_reg; + + return array_get(&ext_reg->preloaded_extensions, count_r); } /* * Extension registry */ - -struct sieve_extension_registration { - const struct sieve_extension *extension; - int id; - bool required; - bool loaded; -}; - -static ARRAY_DEFINE(extensions, struct sieve_extension_registration); -static struct hash_table *extension_index; -static void sieve_extensions_init_registry(void) +static void sieve_extension_registry_init(struct sieve_instance *svinst) { - i_array_init(&extensions, 30); - extension_index = hash_table_create + struct sieve_extension_registry *ext_reg = svinst->ext_reg; + + p_array_init(&ext_reg->extensions, svinst->pool, 30); + ext_reg->extension_index = hash_table_create (default_pool, default_pool, 0, str_hash, (hash_cmp_callback_t *)strcmp); } -static bool _sieve_extension_load -(const struct sieve_extension *extension) +static void sieve_extension_registry_deinit(struct sieve_instance *svinst) +{ + struct sieve_extension_registry *ext_reg = svinst->ext_reg; + struct hash_iterate_context *itx; + void *key; + void *value; + + if ( ext_reg->extension_index == NULL ) return; + + itx = hash_table_iterate_init(ext_reg->extension_index); + while ( hash_table_iterate(itx, &key, &value) ) { + struct sieve_extension *ext = (struct sieve_extension *) value; + + if ( ext->def != NULL && ext->def->unload != NULL ) + ext->def->unload(ext); + } + + hash_table_iterate_deinit(&itx); + + hash_table_destroy(&ext_reg->extension_index); +} + +static bool _sieve_extension_load(struct sieve_extension *ext) { /* Call load handler */ - if ( extension->load != NULL && !extension->load() ) { - sieve_sys_error("failed to load '%s' extension support.", - extension->name); + if ( ext->def != NULL && ext->def->load != NULL && + !ext->def->load(ext, &ext->context) ) { + sieve_sys_error("failed to load '%s' extension support.", ext->def->name); return FALSE; } return TRUE; } -static struct sieve_extension_registration *_sieve_extension_register -(const struct sieve_extension *extension, bool load) +static struct sieve_extension *_sieve_extension_register +(struct sieve_instance *svinst, const struct sieve_extension_def *extdef, + bool load, bool required) { - struct sieve_extension_registration *ereg = - (struct sieve_extension_registration *) - hash_table_lookup(extension_index, extension->name); + struct sieve_extension_registry *ext_reg = svinst->ext_reg; + struct sieve_extension *ext = (struct sieve_extension *) + hash_table_lookup(ext_reg->extension_index, extdef->name); /* Register extension if it is not registered already */ - if ( ereg == NULL ) { - int ext_id = array_count(&extensions); + if ( ext == NULL ) { + int ext_id = array_count(&ext_reg->extensions); /* Add extension to the registry */ - ereg = array_append_space(&extensions); - ereg->id = ext_id; + ext = array_append_space(&ext_reg->extensions); + ext->id = ext_id; + ext->def = extdef; + ext->svinst = svinst; - hash_table_insert(extension_index, (void *) extension->name, (void *) ereg); + hash_table_insert + (ext_reg->extension_index, (void *) extdef->name, (void *) ext); } /* Enable extension */ - if ( extension->_id != NULL && load ) { - /* Make sure extension is enabled */ - *(extension->_id) = ereg->id; + if ( load ) { + ext->enabled = TRUE; /* Call load handler if extension was not loaded already */ - if ( !ereg->loaded ) { - if ( !_sieve_extension_load(extension) ) + if ( !ext->loaded ) { + if ( !_sieve_extension_load(ext) ) return NULL; } - ereg->loaded = TRUE; + ext->loaded = TRUE; } - ereg->extension = extension; + ext->required = (ext->required || required ); - return ereg; + return ext; } -int sieve_extension_register -(const struct sieve_extension *extension, bool load) +const struct sieve_extension *sieve_extension_register +(struct sieve_instance *svinst, const struct sieve_extension_def *extdef, + bool load) { - struct sieve_extension_registration *ereg; - - /* Register the extension */ - if ( (ereg=_sieve_extension_register(extension, load)) == NULL ) { - return -1; - } - - return ereg->id; + return _sieve_extension_register(svinst, extdef, load, FALSE); } -int sieve_extension_require(const struct sieve_extension *extension) +const struct sieve_extension *sieve_extension_require +(struct sieve_instance *svinst, const struct sieve_extension_def *extdef) { - struct sieve_extension_registration *ereg; - - /* Register (possibly unknown) extension */ - if ( (ereg=_sieve_extension_register(extension, TRUE)) == NULL ) { - return -1; - } - - ereg->required = TRUE; - return ereg->id; + return _sieve_extension_register(svinst, extdef, TRUE, TRUE); } -int sieve_extensions_get_count(void) +int sieve_extensions_get_count(struct sieve_instance *svinst) { - return array_count(&extensions); + struct sieve_extension_registry *ext_reg = svinst->ext_reg; + + return array_count(&ext_reg->extensions); } -const struct sieve_extension *sieve_extension_get_by_id(unsigned int ext_id) +const struct sieve_extension *sieve_extension_get_by_id +(struct sieve_instance *svinst, unsigned int ext_id) { - const struct sieve_extension_registration *ereg; + struct sieve_extension_registry *ext_reg = svinst->ext_reg; + const struct sieve_extension *ext; - if ( ext_id < array_count(&extensions) ) { - ereg = array_idx(&extensions, ext_id); + if ( ext_id < array_count(&ext_reg->extensions) ) { + ext = array_idx(&ext_reg->extensions, ext_id); - if ( SIEVE_EXT_ENABLED(ereg->extension) ) - return ereg->extension; + if ( ext->enabled ) + return ext; } return NULL; } -const struct sieve_extension *sieve_extension_get_by_name(const char *name) +const struct sieve_extension *sieve_extension_get_by_name +(struct sieve_instance *svinst, const char *name) { - struct sieve_extension_registration *ereg; + struct sieve_extension_registry *ext_reg = svinst->ext_reg; + const struct sieve_extension *ext; if ( *name == '@' ) return NULL; - ereg = (struct sieve_extension_registration *) - hash_table_lookup(extension_index, name); + ext = (const struct sieve_extension *) + hash_table_lookup(ext_reg->extension_index, name); - if ( ereg == NULL || !SIEVE_EXT_ENABLED(ereg->extension) ) + if ( ext == NULL || !ext->enabled ) return NULL; - return ereg->extension; -} - -static inline bool _list_extension - (const struct sieve_extension_registration *ereg) -{ - return - ( SIEVE_EXT_ENABLED(ereg->extension) && - *(ereg->extension->name) != '@' ); + return ext; } -const char *sieve_extensions_get_string(void) +const char *sieve_extensions_get_string(struct sieve_instance *svinst) { - unsigned int i, ext_count; - const struct sieve_extension_registration *eregs; + struct sieve_extension_registry *ext_reg = svinst->ext_reg; string_t *extstr = t_str_new(256); + const struct sieve_extension *exts; + unsigned int i, ext_count; - eregs = array_get(&extensions, &ext_count); + exts = array_get(&ext_reg->extensions, &ext_count); if ( ext_count > 0 ) { i = 0; /* Find first listable extension */ - while ( i < ext_count && !_list_extension(&eregs[i]) ) + while ( i < ext_count && + !( exts[i].enabled && *(exts[i].def->name) != '@' ) ) i++; if ( i < ext_count ) { /* Add first to string */ - str_append(extstr, eregs[i].extension->name); + str_append(extstr, exts[i].def->name); i++; /* Add others */ for ( ; i < ext_count; i++ ) { - if ( _list_extension(&eregs[i]) ) { + if ( exts[i].enabled && *(exts[i].def->name) != '@' ) { str_append_c(extstr, ' '); - str_append(extstr, eregs[i].extension->name); + str_append(extstr, exts[i].def->name); } } } @@ -355,49 +405,48 @@ const char *sieve_extensions_get_string(void) return str_c(extstr); } -static void sieve_extension_enable(struct sieve_extension_registration *ereg) +static void sieve_extension_enable(struct sieve_extension *ext) { - if ( ereg->extension->_id != NULL ) { - *(ereg->extension->_id) = ereg->id; + ext->enabled = TRUE; - if ( !ereg->loaded ) { - (void)_sieve_extension_load(ereg->extension); - } + if ( !ext->loaded ) { + (void)_sieve_extension_load(ext); } - ereg->loaded = TRUE; + ext->loaded = TRUE; } -static void sieve_extension_disable(struct sieve_extension_registration *ereg) +static void sieve_extension_disable(struct sieve_extension *ext) { - if ( ereg->extension->_id != NULL ) - *(ereg->extension->_id) = -1; + ext->enabled = FALSE; } -void sieve_extensions_set_string(const char *ext_string) +void sieve_extensions_set_string +(struct sieve_instance *svinst, const char *ext_string) { + struct sieve_extension_registry *ext_reg = svinst->ext_reg; ARRAY_DEFINE(enabled_extensions, const struct sieve_extension *); ARRAY_DEFINE(disabled_extensions, const struct sieve_extension *); const struct sieve_extension *const *ext_enabled; const struct sieve_extension *const *ext_disabled; - struct sieve_extension_registration *eregs; + struct sieve_extension *exts; const char **ext_names; unsigned int i, ext_count, ena_count, dis_count; bool relative = FALSE; if ( ext_string == NULL ) { /* Enable all */ - eregs = array_get_modifiable(&extensions, &ext_count); + exts = array_get_modifiable(&ext_reg->extensions, &ext_count); for ( i = 0; i < ext_count; i++ ) - sieve_extension_enable(&eregs[i]); + sieve_extension_enable(&exts[i]); return; } T_BEGIN { - t_array_init(&enabled_extensions, array_count(&extensions)); - t_array_init(&disabled_extensions, array_count(&extensions)); + t_array_init(&enabled_extensions, array_count(&ext_reg->extensions)); + t_array_init(&disabled_extensions, array_count(&ext_reg->extensions)); ext_names = t_strsplit_spaces(ext_string, " \t"); @@ -407,7 +456,7 @@ void sieve_extensions_set_string(const char *ext_string) ext_names++; if ( *name != '\0' ) { - const struct sieve_extension_registration *ereg; + const struct sieve_extension *ext; char op = '\0'; /* No add/remove operation */ if ( *name == '+' /* Add to existing config */ @@ -417,12 +466,12 @@ void sieve_extensions_set_string(const char *ext_string) } if ( *name == '@' ) - ereg = NULL; + ext = NULL; else - ereg = (const struct sieve_extension_registration *) - hash_table_lookup(extension_index, name); + ext = (const struct sieve_extension *) + hash_table_lookup(ext_reg->extension_index, name); - if ( ereg == NULL ) { + if ( ext == NULL ) { sieve_sys_warning( "ignored unknown extension '%s' while configuring " "available extensions", name); @@ -430,13 +479,13 @@ void sieve_extensions_set_string(const char *ext_string) } if ( op == '-' ) - array_append(&disabled_extensions, &ereg->extension, 1); + array_append(&disabled_extensions, &ext, 1); else - array_append(&enabled_extensions, &ereg->extension, 1); + array_append(&enabled_extensions, &ext, 1); } } - eregs = array_get_modifiable(&extensions, &ext_count); + exts = array_get_modifiable(&ext_reg->extensions, &ext_count); ext_enabled = array_get(&enabled_extensions, &ena_count); ext_disabled = array_get(&disabled_extensions, &dis_count); @@ -453,15 +502,15 @@ void sieve_extensions_set_string(const char *ext_string) if ( relative ) { /* Enable if core extension */ for ( j = 0; j < sieve_core_extensions_count; j++ ) { - if ( sieve_core_extensions[j] == eregs[i].extension ) { + if ( sieve_core_extensions[j] == exts[i].def ) { disabled = FALSE; break; } - } + } /* Disable if explicitly disabled */ for ( j = 0; j < dis_count; j++ ) { - if ( ext_disabled[j] == eregs[i].extension ) { + if ( ext_disabled[j]->def == exts[i].def ) { disabled = TRUE; break; } @@ -471,7 +520,7 @@ void sieve_extensions_set_string(const char *ext_string) /* Enable if listed with '+' or no prefix */ for ( j = 0; j < ena_count; j++ ) { - if ( ext_enabled[j] == eregs[i].extension ) { + if ( ext_enabled[j]->def == exts[i].def ) { disabled = FALSE; break; } @@ -479,75 +528,93 @@ void sieve_extensions_set_string(const char *ext_string) /* Perform actual activation/deactivation */ - if ( eregs[i].extension->_id != NULL && - *(eregs[i].extension->name) != '@' ) { - if ( disabled && !eregs[i].required ) - sieve_extension_disable(&eregs[i]); + if ( exts[i].enabled && *(exts[i].def->name) != '@' ) { + if ( disabled && !exts[i].required ) + sieve_extension_disable(&exts[i]); else - sieve_extension_enable(&eregs[i]); + sieve_extension_enable(&exts[i]); } } } T_END; } -static void sieve_extensions_deinit_registry(void) +const struct sieve_extension *sieve_get_match_type_extension + (struct sieve_instance *svinst) { - struct hash_iterate_context *itx = - hash_table_iterate_init(extension_index); - void *key; - void *value; - - while ( hash_table_iterate(itx, &key, &value) ) { - struct sieve_extension_registration *ereg = - (struct sieve_extension_registration *) value; - const struct sieve_extension *ext = ereg->extension; - - if ( ext->unload != NULL ) - ext->unload(); - } + return svinst->ext_reg->match_type_extension; +} - hash_table_iterate_deinit(&itx); +const struct sieve_extension *sieve_get_comparator_extension + (struct sieve_instance *svinst) +{ + return svinst->ext_reg->comparator_extension; +} - array_free(&extensions); - hash_table_destroy(&extension_index); +const struct sieve_extension *sieve_get_address_part_extension + (struct sieve_instance *svinst) +{ + return svinst->ext_reg->address_part_extension; } /* * Extension capabilities */ -static struct hash_table *capabilities_index; +struct sieve_capability_registration { + const struct sieve_extension *ext; + const struct sieve_extension_capabilities *capabilities; +}; -static void sieve_extensions_init_capabilities(void) +void sieve_capability_registry_init(struct sieve_instance *svinst) { - capabilities_index = hash_table_create + struct sieve_extension_registry *ext_reg = svinst->ext_reg; + + ext_reg->capabilities_index = hash_table_create (default_pool, default_pool, 0, str_hash, (hash_cmp_callback_t *)strcmp); } -static void sieve_extensions_deinit_capabilities(void) +void sieve_capability_registry_deinit(struct sieve_instance *svinst) { - hash_table_destroy(&capabilities_index); + struct sieve_extension_registry *ext_reg = svinst->ext_reg; + + if ( ext_reg->capabilities_index == NULL ) return; + + hash_table_destroy(&svinst->ext_reg->capabilities_index); } void sieve_extension_capabilities_register - (const struct sieve_extension_capabilities *cap) +(struct sieve_instance *svinst, const struct sieve_extension *ext, + const struct sieve_extension_capabilities *cap) { + struct sieve_extension_registry *ext_reg = svinst->ext_reg; + struct sieve_capability_registration *reg = + p_new(svinst->pool, struct sieve_capability_registration, 1); + + reg->ext = ext; + reg->capabilities = cap; + hash_table_insert - (capabilities_index, (void *) cap->name, (void *) cap); + (ext_reg->capabilities_index, (void *) cap->name, (void *) reg); } const char *sieve_extension_capabilities_get_string - (const char *cap_name) +(struct sieve_instance *svinst, const char *cap_name) { - const struct sieve_extension_capabilities *cap = - (const struct sieve_extension_capabilities *) - hash_table_lookup(capabilities_index, cap_name); + struct sieve_extension_registry *ext_reg = svinst->ext_reg; + const struct sieve_capability_registration *cap_reg = + (const struct sieve_capability_registration *) + hash_table_lookup(ext_reg->capabilities_index, cap_name); + const struct sieve_extension_capabilities *cap; + + if ( cap_reg == NULL || cap_reg->capabilities == NULL ) + return NULL; + + cap = cap_reg->capabilities; - if ( cap == NULL || cap->get_string == NULL || - !SIEVE_EXT_ENABLED(cap->extension) ) + if ( cap->get_string == NULL || !cap_reg->ext->enabled ) return NULL; - return cap->get_string(); + return cap->get_string(cap_reg->ext); } diff --git a/src/lib-sieve/sieve-extensions.h b/src/lib-sieve/sieve-extensions.h index 717dfc145..58c6b3037 100644 --- a/src/lib-sieve/sieve-extensions.h +++ b/src/lib-sieve/sieve-extensions.h @@ -17,38 +17,39 @@ struct sieve_extension_objects { }; /* - * Extension object + * Extension definition */ -struct sieve_extension { +struct sieve_extension_def { const char *name; - int *const _id; - - bool (*load)(void); - void (*unload)(void); + /* Registration */ + bool (*load)(const struct sieve_extension *ext, void **); + void (*unload)(const struct sieve_extension *ext); + /* Compilation */ bool (*validator_load) - (struct sieve_validator *validator); + (const struct sieve_extension *ext, struct sieve_validator *validator); bool (*generator_load) - (const struct sieve_codegen_env *cgenv); + (const struct sieve_extension *ext, const struct sieve_codegen_env *cgenv); bool (*interpreter_load) - (const struct sieve_runtime_env *renv, sieve_size_t *address); + (const struct sieve_extension *ext, const struct sieve_runtime_env *renv, + sieve_size_t *address); bool (*binary_load) - (struct sieve_binary *binary); + (const struct sieve_extension *ext, struct sieve_binary *binary); + /* Code dump */ bool (*binary_dump) - (struct sieve_dumptime_env *denv); + (const struct sieve_extension *ext, struct sieve_dumptime_env *denv); bool (*code_dump) - (const struct sieve_dumptime_env *denv, sieve_size_t *address); + (const struct sieve_extension *ext, const struct sieve_dumptime_env *denv, + sieve_size_t *address); + /* Objects */ struct sieve_extension_objects operations; struct sieve_extension_objects operands; }; -#define SIEVE_EXT_ID(EXT) (*((EXT)->_id)) -#define SIEVE_EXT_ENABLED(EXT) (((EXT)->_id != NULL) && (*((EXT)->_id) >= 0)) - #define SIEVE_EXT_DEFINE_NO_OBJECTS \ { NULL, 0 } #define SIEVE_EXT_DEFINE_OBJECT(OBJ) \ @@ -59,6 +60,25 @@ struct sieve_extension { #define SIEVE_EXT_GET_OBJECTS_COUNT(ext, field) \ ext->field->count; +/* + * Extension instance + */ + +struct sieve_extension { + const struct sieve_extension_def *def; + int id; + + struct sieve_instance *svinst; + void *context; + + unsigned int required:1; + unsigned int loaded:1; + unsigned int enabled:1; +}; + +#define sieve_extension_name(ext) \ + (ext)->def->name + /* * Defining opcodes and operands */ @@ -71,32 +91,46 @@ struct sieve_extension { #define SIEVE_EXT_DEFINE_OPERAND(OP) SIEVE_EXT_DEFINE_OBJECT(OP) #define SIEVE_EXT_DEFINE_OPERANDS(OPS) SIEVE_EXT_DEFINE_OBJECTS(OPS) -/* - * Pre-loaded extensions +/* + * Extensions init/deinit */ -extern const struct sieve_extension *sieve_preloaded_extensions[]; -extern const unsigned int sieve_preloaded_extensions_count; +bool sieve_extensions_init(struct sieve_instance *svinst); +void sieve_extensions_deinit(struct sieve_instance *svinst); -/* - * Extensions init/deinit +/* + * Pre-loaded extensions */ -bool sieve_extensions_init(void); -void sieve_extensions_deinit(void); +const struct sieve_extension *const *sieve_extensions_get_preloaded + (struct sieve_instance *svinst, unsigned int *count_r); /* * Extension registry */ -int sieve_extension_register(const struct sieve_extension *extension, bool load); -int sieve_extension_require(const struct sieve_extension *extension); -int sieve_extensions_get_count(void); -const struct sieve_extension *sieve_extension_get_by_id(unsigned int ext_id); -const struct sieve_extension *sieve_extension_get_by_name(const char *name); - -const char *sieve_extensions_get_string(void); -void sieve_extensions_set_string(const char *ext_string); +const struct sieve_extension *sieve_extension_register + (struct sieve_instance *svinst, const struct sieve_extension_def *extension, + bool load); +const struct sieve_extension *sieve_extension_require + (struct sieve_instance *svinst, const struct sieve_extension_def *extension); +int sieve_extensions_get_count(struct sieve_instance *svinst); +const struct sieve_extension *sieve_extension_get_by_id + (struct sieve_instance *svinst, unsigned int ext_id); +const struct sieve_extension *sieve_extension_get_by_name + (struct sieve_instance *svinst, const char *name); + +const char *sieve_extensions_get_string + (struct sieve_instance *svinst); +void sieve_extensions_set_string + (struct sieve_instance *svinst, const char *ext_string); + +const struct sieve_extension *sieve_get_match_type_extension + (struct sieve_instance *svinst); +const struct sieve_extension *sieve_get_comparator_extension + (struct sieve_instance *svinst); +const struct sieve_extension *sieve_get_address_part_extension + (struct sieve_instance *svinst); /* * Capability registries @@ -105,14 +139,13 @@ void sieve_extensions_set_string(const char *ext_string); struct sieve_extension_capabilities { const char *name; - const struct sieve_extension *extension; - - const char *(*get_string)(void); + const char *(*get_string)(const struct sieve_extension *ext); }; void sieve_extension_capabilities_register - (const struct sieve_extension_capabilities *cap); + (struct sieve_instance *svinst, const struct sieve_extension *ext, + const struct sieve_extension_capabilities *cap); const char *sieve_extension_capabilities_get_string - (const char *cap_name); + (struct sieve_instance *svinst, const char *cap_name); #endif /* __SIEVE_EXTENSIONS_H */ diff --git a/src/lib-sieve/sieve-generator.c b/src/lib-sieve/sieve-generator.c index df5a1d879..8c5bf2b19 100644 --- a/src/lib-sieve/sieve-generator.c +++ b/src/lib-sieve/sieve-generator.c @@ -5,6 +5,7 @@ #include "mempool.h" #include "sieve-common.h" +#include "sieve-script.h" #include "sieve-extensions.h" #include "sieve-commands.h" #include "sieve-code.h" @@ -63,6 +64,8 @@ void sieve_jumplist_resolve(struct sieve_jumplist *jlist) struct sieve_generator { pool_t pool; + + struct sieve_instance *instance; struct sieve_error_handler *ehandler; @@ -72,10 +75,12 @@ struct sieve_generator { }; struct sieve_generator *sieve_generator_create - (struct sieve_ast *ast, struct sieve_error_handler *ehandler) +(struct sieve_ast *ast, struct sieve_error_handler *ehandler) { pool_t pool; struct sieve_generator *gentr; + struct sieve_script *script; + struct sieve_instance *svinst; pool = pool_alloconly_create("sieve_generator", 4096); gentr = p_new(pool, struct sieve_generator, 1); @@ -86,11 +91,16 @@ struct sieve_generator *sieve_generator_create gentr->genenv.gentr = gentr; gentr->genenv.ast = ast; - gentr->genenv.script = sieve_ast_script(ast); sieve_ast_ref(ast); + script = sieve_ast_script(ast); + svinst = sieve_script_svinst(script); + + gentr->genenv.script = script; + gentr->genenv.svinst = svinst; + /* Setup storage for extension contexts */ - p_array_init(&gentr->ext_contexts, pool, sieve_extensions_get_count()); + p_array_init(&gentr->ext_contexts, pool, sieve_extensions_get_count(svinst)); return gentr; } @@ -186,19 +196,20 @@ void sieve_generator_critical void sieve_generator_extension_set_context (struct sieve_generator *gentr, const struct sieve_extension *ext, void *context) { - array_idx_set(&gentr->ext_contexts, (unsigned int) SIEVE_EXT_ID(ext), &context); + if ( ext->id < 0 ) return; + + array_idx_set(&gentr->ext_contexts, (unsigned int) ext->id, &context); } const void *sieve_generator_extension_get_context (struct sieve_generator *gentr, const struct sieve_extension *ext) { - int ext_id = SIEVE_EXT_ID(ext); void * const *ctx; - if ( ext_id < 0 || ext_id >= (int) array_count(&gentr->ext_contexts) ) + if ( ext->id < 0 || ext->id >= (int) array_count(&gentr->ext_contexts) ) return NULL; - ctx = array_idx(&gentr->ext_contexts, (unsigned int) ext_id); + ctx = array_idx(&gentr->ext_contexts, (unsigned int) ext->id); return *ctx; } @@ -209,59 +220,68 @@ const void *sieve_generator_extension_get_context bool sieve_generate_argument (const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, - struct sieve_command_context *cmd) + struct sieve_command *cmd) { - const struct sieve_argument *argument = arg->argument; + const struct sieve_argument_def *arg_def; - if ( argument == NULL ) return FALSE; + if ( arg->argument == NULL || arg->argument->def == NULL ) return FALSE; + + arg_def = arg->argument->def; - return ( argument->generate == NULL || - argument->generate(cgenv, arg, cmd) ); + return ( arg_def->generate == NULL || + arg_def->generate(cgenv, arg, cmd) ); } bool sieve_generate_arguments -(const struct sieve_codegen_env *cgenv, struct sieve_command_context *cmd, - struct sieve_ast_argument **last_arg) +(const struct sieve_codegen_env *cgenv, struct sieve_command *cmd, + struct sieve_ast_argument **last_arg_r) { enum { ARG_START, ARG_OPTIONAL, ARG_POSITIONAL } state = ARG_START; struct sieve_ast_argument *arg = sieve_ast_argument_first(cmd->ast_node); /* Generate all arguments with assigned generator function */ - while ( arg != NULL && arg->argument != NULL) { - const struct sieve_argument *argument = arg->argument; + while ( arg != NULL ) { + const struct sieve_argument *argument; + const struct sieve_argument_def *arg_def; + if ( arg->argument == NULL || arg->argument->def == NULL ) + return FALSE; + + argument = arg->argument; + arg_def = argument->def; + switch ( state ) { case ARG_START: - if ( arg->arg_id_code == 0 ) + if ( argument->id_code == 0 ) state = ARG_POSITIONAL; else { /* Mark start of optional operands with 0 operand identifier */ sieve_binary_emit_byte(cgenv->sbin, SIEVE_OPERAND_OPTIONAL); /* Emit argument id for optional operand */ - sieve_binary_emit_byte(cgenv->sbin, (unsigned char) arg->arg_id_code); + sieve_binary_emit_byte(cgenv->sbin, (unsigned char) argument->id_code); state = ARG_OPTIONAL; } break; case ARG_OPTIONAL: - if ( arg->arg_id_code == 0 ) + if ( argument->id_code == 0 ) state = ARG_POSITIONAL; /* Emit argument id for optional operand (0 marks the end of the optionals) */ - sieve_binary_emit_byte(cgenv->sbin, (unsigned char) arg->arg_id_code); + sieve_binary_emit_byte(cgenv->sbin, (unsigned char) argument->id_code); break; case ARG_POSITIONAL: - if ( arg->arg_id_code != 0 ) + if ( argument->id_code != 0 ) return FALSE; break; } /* Call the generation function for the argument */ - if ( argument->generate != NULL ) { - if ( !argument->generate(cgenv, arg, cmd) ) + if ( arg_def->generate != NULL ) { + if ( !arg_def->generate(cgenv, arg, cmd) ) return FALSE; } else if ( state == ARG_POSITIONAL ) break; @@ -272,27 +292,29 @@ bool sieve_generate_arguments if ( state == ARG_OPTIONAL ) sieve_binary_emit_byte(cgenv->sbin, 0); - if ( last_arg != NULL ) - *last_arg = arg; + if ( last_arg_r != NULL ) + *last_arg_r = arg; return TRUE; } bool sieve_generate_argument_parameters (const struct sieve_codegen_env *cgenv, - struct sieve_command_context *cmd, struct sieve_ast_argument *arg) + struct sieve_command *cmd, struct sieve_ast_argument *arg) { struct sieve_ast_argument *param = arg->parameters; /* Generate all parameters with assigned generator function */ - while ( param != NULL && param->argument != NULL) { - const struct sieve_argument *parameter = param->argument; + while ( param != NULL ) { + if ( param->argument != NULL && param->argument->def != NULL ) { + const struct sieve_argument_def *parameter = param->argument->def; - /* Call the generation function for the parameter */ - if ( parameter->generate != NULL ) { - if ( !parameter->generate(cgenv, param, cmd) ) - return FALSE; + /* Call the generation function for the parameter */ + if ( parameter->generate != NULL ) { + if ( !parameter->generate(cgenv, param, cmd) ) + return FALSE; + } } param = sieve_ast_argument_next(param); @@ -305,24 +327,29 @@ bool sieve_generate_test (const struct sieve_codegen_env *cgenv, struct sieve_ast_node *tst_node, struct sieve_jumplist *jlist, bool jump_true) { - i_assert( tst_node->context != NULL && tst_node->context->command != NULL ); + struct sieve_command *test; + const struct sieve_command_def *tst_def; + + i_assert( tst_node->command != NULL && tst_node->command->def != NULL ); - if ( tst_node->context->command->control_generate != NULL ) { - if ( tst_node->context->command->control_generate - (cgenv, tst_node->context, jlist, jump_true) ) + test = tst_node->command; + tst_def = test->def; + + if ( tst_def->control_generate != NULL ) { + if ( tst_def->control_generate(cgenv, test, jlist, jump_true) ) return TRUE; return FALSE; } - if ( tst_node->context->command->generate != NULL ) { + if ( tst_def->generate != NULL ) { - if ( tst_node->context->command->generate(cgenv, tst_node->context) ) { + if ( tst_def->generate(cgenv, test) ) { if ( jump_true ) - sieve_operation_emit_code(cgenv->sbin, &sieve_jmptrue_operation); + sieve_operation_emit(cgenv->sbin, NULL, &sieve_jmptrue_operation); else - sieve_operation_emit_code(cgenv->sbin, &sieve_jmpfalse_operation); + sieve_operation_emit(cgenv->sbin, NULL, &sieve_jmpfalse_operation); sieve_jumplist_add(jlist, sieve_binary_emit_offset(cgenv->sbin, 0)); return TRUE; @@ -337,10 +364,16 @@ bool sieve_generate_test static bool sieve_generate_command (const struct sieve_codegen_env *cgenv, struct sieve_ast_node *cmd_node) { - i_assert( cmd_node->context != NULL && cmd_node->context->command != NULL ); + struct sieve_command *command; + const struct sieve_command_def *cmd_def; + + i_assert( cmd_node->command != NULL && cmd_node->command->def != NULL ); + + command = cmd_node->command; + cmd_def = command->def; - if ( cmd_node->context->command->generate != NULL ) { - return cmd_node->context->command->generate(cgenv, cmd_node->context); + if ( cmd_def->generate != NULL ) { + return cmd_def->generate(cgenv, command); } return TRUE; @@ -350,13 +383,13 @@ bool sieve_generate_block (const struct sieve_codegen_env *cgenv, struct sieve_ast_node *block) { bool result = TRUE; - struct sieve_ast_node *command; + struct sieve_ast_node *cmd_node; T_BEGIN { - command = sieve_ast_command_first(block); - while ( result && command != NULL ) { - result = sieve_generate_command(cgenv, command); - command = sieve_ast_command_next(command); + cmd_node = sieve_ast_command_first(block); + while ( result && cmd_node != NULL ) { + result = sieve_generate_command(cgenv, cmd_node); + cmd_node = sieve_ast_command_next(cmd_node); } } T_END; @@ -393,7 +426,8 @@ bool sieve_generator_run sieve_binary_emit_extension(*sbin, ext, 0); /* Load */ - if ( ext->generator_load != NULL && !ext->generator_load(&gentr->genenv) ) + if ( ext->def != NULL && ext->def->generator_load != NULL && + !ext->def->generator_load(ext, &gentr->genenv) ) return FALSE; } diff --git a/src/lib-sieve/sieve-generator.h b/src/lib-sieve/sieve-generator.h index 7d65f6c86..2df4f4a30 100644 --- a/src/lib-sieve/sieve-generator.h +++ b/src/lib-sieve/sieve-generator.h @@ -15,7 +15,8 @@ struct sieve_generator; struct sieve_codegen_env { struct sieve_generator *gentr; - struct sieve_script *script; + struct sieve_instance *svinst; + struct sieve_script *script; struct sieve_ast *ast; struct sieve_binary *sbin; }; @@ -86,12 +87,12 @@ void sieve_jumplist_resolve(struct sieve_jumplist *jlist); bool sieve_generate_argument (const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, - struct sieve_command_context *cmd); + struct sieve_command *cmd); bool sieve_generate_arguments - (const struct sieve_codegen_env *cgenv, struct sieve_command_context *cmd, - struct sieve_ast_argument **arg); + (const struct sieve_codegen_env *cgenv, struct sieve_command *cmd, + struct sieve_ast_argument **last_arg_r); bool sieve_generate_argument_parameters - (const struct sieve_codegen_env *cgenv, struct sieve_command_context *cmd, + (const struct sieve_codegen_env *cgenv, struct sieve_command *cmd, struct sieve_ast_argument *arg); bool sieve_generate_block diff --git a/src/lib-sieve/sieve-interpreter.c b/src/lib-sieve/sieve-interpreter.c index 155d92667..7e27c15dc 100644 --- a/src/lib-sieve/sieve-interpreter.c +++ b/src/lib-sieve/sieve-interpreter.c @@ -30,7 +30,9 @@ */ struct sieve_interpreter_extension_reg { - const struct sieve_interpreter_extension *int_ext; + const struct sieve_interpreter_extension *intext; + const struct sieve_extension *ext; + void *context; }; @@ -53,12 +55,6 @@ struct sieve_interpreter { sieve_size_t pc; /* Program counter */ bool interrupted; /* Interpreter interrupt requested */ bool test_result; /* Result of previous test command */ - - /* Current operation */ - const struct sieve_operation *current_op; - - /* Start address of current operation */ - sieve_size_t current_op_addr; /* Runtime environment */ struct sieve_runtime_env runenv; @@ -68,10 +64,11 @@ struct sieve_interpreter *sieve_interpreter_create (struct sieve_binary *sbin, struct sieve_error_handler *ehandler) { unsigned int i, ext_count; - bool success = TRUE; - - pool_t pool; struct sieve_interpreter *interp; + pool_t pool; + struct sieve_instance *svinst; + const struct sieve_extension *const *ext_preloaded; + bool success = TRUE; pool = pool_alloconly_create("sieve_interpreter", 4096); interp = p_new(pool, struct sieve_interpreter, 1); @@ -82,19 +79,25 @@ struct sieve_interpreter *sieve_interpreter_create interp->runenv.interp = interp; interp->runenv.sbin = sbin; - interp->runenv.script = sieve_binary_script(sbin); sieve_binary_ref(sbin); + + svinst = sieve_binary_svinst(sbin); + + interp->runenv.svinst = svinst; + interp->runenv.script = sieve_binary_script(sbin); interp->pc = 0; - p_array_init(&interp->extensions, pool, sieve_extensions_get_count()); + p_array_init(&interp->extensions, pool, sieve_extensions_get_count(svinst)); /* Pre-load core language features implemented as 'extensions' */ - for ( i = 0; i < sieve_preloaded_extensions_count; i++ ) { - const struct sieve_extension *ext = sieve_preloaded_extensions[i]; - - if ( ext->interpreter_load != NULL ) - (void)ext->interpreter_load(&interp->runenv, &interp->pc); + ext_preloaded = sieve_extensions_get_preloaded(svinst, &ext_count); + for ( i = 0; i < ext_count; i++ ) { + const struct sieve_extension_def *ext_def = ext_preloaded[i]->def; + + if ( ext_def != NULL && ext_def->interpreter_load != NULL ) + (void)ext_def->interpreter_load + (ext_preloaded[i], &interp->runenv, &interp->pc); } /* Load other extensions listed in code */ @@ -108,8 +111,8 @@ struct sieve_interpreter *sieve_interpreter_create break; } - if ( ext->interpreter_load != NULL && - !ext->interpreter_load(&interp->runenv, &interp->pc) ) { + if ( ext->def != NULL && ext->def->interpreter_load != NULL && + !ext->def->interpreter_load(ext, &interp->runenv, &interp->pc) ) { success = FALSE; break; } @@ -128,7 +131,7 @@ struct sieve_interpreter *sieve_interpreter_create void sieve_interpreter_free(struct sieve_interpreter **interp) { - const struct sieve_interpreter_extension_reg *extrs; + const struct sieve_interpreter_extension_reg *eregs; unsigned int ext_count, i; sieve_binary_unref(&(*interp)->runenv.sbin); @@ -136,10 +139,10 @@ void sieve_interpreter_free(struct sieve_interpreter **interp) sieve_error_handler_unref(&(*interp)->ehandler); /* Signal registered extensions that the interpreter is being destroyed */ - extrs = array_get(&(*interp)->extensions, &ext_count); + eregs = array_get(&(*interp)->extensions, &ext_count); for ( i = 0; i < ext_count; i++ ) { - if ( extrs[i].int_ext != NULL && extrs[i].int_ext->free != NULL ) - extrs[i].int_ext->free(*interp, extrs[i].context); + if ( eregs[i].intext != NULL && eregs[i].intext->free != NULL ) + eregs[i].intext->free(eregs[i].ext, *interp, eregs[i].context); } pool_unref(&((*interp)->pool)); @@ -167,6 +170,12 @@ struct sieve_error_handler *sieve_interpreter_get_error_handler return interp->ehandler; } +struct sieve_instance *sieve_interpreter_svinst +(struct sieve_interpreter *interp) +{ + return interp->runenv.svinst; +} + /* Do not use this function for normal sieve extensions. This is intended for * the testsuite only. */ @@ -186,10 +195,10 @@ void sieve_interpreter_set_result */ const char *sieve_runtime_location(const struct sieve_runtime_env *runenv) { - const char *op = runenv->interp->current_op == NULL ? - "<<NOOP>>" : runenv->interp->current_op->mnemonic; + const char *op = runenv->oprtn.def == NULL ? + "<<NOOP>>" : runenv->oprtn.def->mnemonic; return t_strdup_printf("%s: #%08llx: %s", sieve_script_name(runenv->script), - (unsigned long long) runenv->interp->current_op_addr, op); + (unsigned long long) runenv->oprtn.address, op); } void sieve_runtime_error @@ -243,7 +252,7 @@ void _sieve_runtime_trace va_list args; va_start(args, fmt); - str_printfa(outbuf, "%08llx: ", (unsigned long long) runenv->interp->current_op_addr); + str_printfa(outbuf, "%08llx: ", (unsigned long long) runenv->oprtn.address); str_vprintfa(outbuf, fmt, args); str_append_c(outbuf, '\n'); va_end(args); @@ -259,8 +268,7 @@ void _sieve_runtime_trace_error va_start(args, fmt); str_printfa(outbuf, "%08llx: [[ERROR: %s: ", - (unsigned long long) runenv->interp->pc, - runenv->interp->current_op->mnemonic); + (unsigned long long) runenv->interp->pc, runenv->oprtn.def->mnemonic); str_vprintfa(outbuf, fmt, args); str_append(outbuf, "]]\n"); va_end(args); @@ -274,39 +282,40 @@ void _sieve_runtime_trace_error */ void sieve_interpreter_extension_register -(struct sieve_interpreter *interp, - const struct sieve_interpreter_extension *int_ext, void *context) +(struct sieve_interpreter *interp, const struct sieve_extension *ext, + const struct sieve_interpreter_extension *intext, void *context) { - struct sieve_interpreter_extension_reg reg = { int_ext, context }; - int ext_id = SIEVE_EXT_ID(int_ext->ext); + struct sieve_interpreter_extension_reg *reg; - if ( ext_id < 0 ) return; + if ( ext->id < 0 ) return; - array_idx_set(&interp->extensions, (unsigned int) ext_id, ®); + reg = array_idx_modifiable(&interp->extensions, (unsigned int) ext->id); + reg->intext = intext; + reg->ext = ext; + reg->context = context; } void sieve_interpreter_extension_set_context (struct sieve_interpreter *interp, const struct sieve_extension *ext, void *context) { - struct sieve_interpreter_extension_reg reg = { NULL, context }; - int ext_id = SIEVE_EXT_ID(ext); + struct sieve_interpreter_extension_reg *reg; - if ( ext_id < 0 ) return; + if ( ext->id < 0 ) return; - array_idx_set(&interp->extensions, (unsigned int) ext_id, ®); + reg = array_idx_modifiable(&interp->extensions, (unsigned int) ext->id); + reg->context = context; } void *sieve_interpreter_extension_get_context (struct sieve_interpreter *interp, const struct sieve_extension *ext) { - int ext_id = SIEVE_EXT_ID(ext); const struct sieve_interpreter_extension_reg *reg; - if ( ext_id < 0 || ext_id >= (int) array_count(&interp->extensions) ) + if ( ext->id < 0 || ext->id >= (int) array_count(&interp->extensions) ) return NULL; - reg = array_idx(&interp->extensions, (unsigned int) ext_id); + reg = array_idx(&interp->extensions, (unsigned int) ext->id); return reg->context; } @@ -394,28 +403,20 @@ int sieve_interpreter_handle_optional_operands } if ( opt_code == SIEVE_OPT_SIDE_EFFECT ) { - void *context = NULL; + struct sieve_side_effect seffect; - if ( list != NULL && *list == NULL ) - *list = sieve_side_effects_list_create(renv->result); + if ( list == NULL ) + return SIEVE_EXEC_BIN_CORRUPT; - const struct sieve_side_effect *seffect = - sieve_opr_side_effect_read(renv, address); - - if ( seffect == NULL ) { + if ( !sieve_opr_side_effect_read(renv, address, &seffect) ) { sieve_runtime_trace_error(renv, "invalid side effect operand"); return SIEVE_EXEC_BIN_CORRUPT; } - if ( list != NULL ) { - if ( seffect->read_context != NULL && !seffect->read_context - (seffect, renv, address, &context) ) { - sieve_runtime_trace_error(renv, "invalid side effect context"); - return SIEVE_EXEC_BIN_CORRUPT; - } - - sieve_side_effects_list_add(*list, seffect, context); - } + if ( *list == NULL ) + *list = sieve_side_effects_list_create(renv->result); + + sieve_side_effects_list_add(*list, &seffect); } } } @@ -429,18 +430,16 @@ int sieve_interpreter_handle_optional_operands static int sieve_interpreter_execute_operation (struct sieve_interpreter *interp) { - const struct sieve_operation *op; + struct sieve_operation *oprtn = &(interp->runenv.oprtn); - interp->current_op_addr = interp->pc; - interp->current_op = op = - sieve_operation_read(interp->runenv.sbin, &(interp->pc)); + if ( sieve_operation_read(interp->runenv.sbin, &(interp->pc), oprtn) ) { + const struct sieve_operation_def *op = oprtn->def; - if ( op != NULL ) { int result = SIEVE_EXEC_OK; if ( op->execute != NULL ) { /* Noop ? */ T_BEGIN { - result = op->execute(op, &(interp->runenv), &(interp->pc)); + result = op->execute(&(interp->runenv), &(interp->pc)); } T_END; } else { sieve_runtime_trace(&interp->runenv, "OP: %s (NOOP)", op->mnemonic); @@ -485,7 +484,7 @@ int sieve_interpreter_start (struct sieve_interpreter *interp, const struct sieve_message_data *msgdata, const struct sieve_script_env *senv, struct sieve_result *result, bool *interrupted) { - const struct sieve_interpreter_extension_reg *extrs; + const struct sieve_interpreter_extension_reg *eregs; unsigned int ext_count, i; interp->runenv.msgdata = msgdata; @@ -500,10 +499,10 @@ int sieve_interpreter_start interp->runenv.exec_status = senv->exec_status; /* Signal registered extensions that the interpreter is being run */ - extrs = array_get(&interp->extensions, &ext_count); + eregs = array_get(&interp->extensions, &ext_count); for ( i = 0; i < ext_count; i++ ) { - if ( extrs[i].int_ext != NULL && extrs[i].int_ext->run != NULL ) - extrs[i].int_ext->run(&interp->runenv, extrs[i].context); + if ( eregs[i].intext != NULL && eregs[i].intext->run != NULL ) + eregs[i].intext->run(eregs[i].ext, &interp->runenv, eregs[i].context); } return sieve_interpreter_continue(interp, interrupted); diff --git a/src/lib-sieve/sieve-interpreter.h b/src/lib-sieve/sieve-interpreter.h index 2da76a906..6b8ca8a31 100644 --- a/src/lib-sieve/sieve-interpreter.h +++ b/src/lib-sieve/sieve-interpreter.h @@ -10,6 +10,7 @@ #include "mail-storage.h" #include "sieve-common.h" +#include "sieve-code.h" /* * Forward declarations @@ -23,6 +24,10 @@ struct sieve_interpreter; struct sieve_runtime_env { struct sieve_interpreter *interp; + struct sieve_instance *svinst; + + struct sieve_binary *sbin; + struct sieve_operation oprtn; struct sieve_script *script; const struct sieve_script_env *scriptenv; @@ -30,7 +35,6 @@ struct sieve_runtime_env { const struct sieve_message_data *msgdata; struct sieve_message_context *msgctx; - struct sieve_binary *sbin; struct sieve_result *result; struct sieve_exec_status *exec_status; @@ -55,6 +59,8 @@ struct sieve_script *sieve_interpreter_script (struct sieve_interpreter *interp); struct sieve_error_handler *sieve_interpreter_get_error_handler (struct sieve_interpreter *interp); +struct sieve_instance *sieve_interpreter_svinst + (struct sieve_interpreter *interp); /* Do not use this function for normal sieve extensions. This is intended for * the testsuite only. @@ -134,15 +140,19 @@ void _sieve_runtime_trace_error */ struct sieve_interpreter_extension { - const struct sieve_extension *ext; - - void (*run)(const struct sieve_runtime_env *renv, void *context); - void (*free)(struct sieve_interpreter *interp, void *context); + const struct sieve_extension_def *ext_def; + + void (*run) + (const struct sieve_extension *ext, const struct sieve_runtime_env *renv, + void *context); + void (*free) + (const struct sieve_extension *ext, struct sieve_interpreter *interp, + void *context); }; void sieve_interpreter_extension_register - (struct sieve_interpreter *interp, - const struct sieve_interpreter_extension *int_ext, void *context); + (struct sieve_interpreter *interp, const struct sieve_extension *ext, + const struct sieve_interpreter_extension *intext, void *context); void sieve_interpreter_extension_set_context (struct sieve_interpreter *interp, const struct sieve_extension *ext, void *context); diff --git a/src/lib-sieve/sieve-match-types.c b/src/lib-sieve/sieve-match-types.c index f07dd10a9..a9a8507c4 100644 --- a/src/lib-sieve/sieve-match-types.c +++ b/src/lib-sieve/sieve-match-types.c @@ -39,7 +39,7 @@ struct sieve_match_values { * Default match types */ -const struct sieve_match_type *sieve_core_match_types[] = { +const struct sieve_match_type_def *sieve_core_match_types[] = { &is_match_type, &contains_match_type, &matches_match_type }; @@ -50,57 +50,80 @@ const unsigned int sieve_core_match_types_count = * Match-type 'extension' */ -static bool mtch_validator_load(struct sieve_validator *validator); +static bool mtch_validator_load +(const struct sieve_extension *ext, struct sieve_validator *valdtr); -static int ext_my_id = -1; - -const struct sieve_extension match_type_extension = { +const struct sieve_extension_def match_type_extension = { "@match-types", - &ext_my_id, NULL, NULL, mtch_validator_load, NULL, NULL, NULL, NULL, NULL, SIEVE_EXT_DEFINE_NO_OPERATIONS, SIEVE_EXT_DEFINE_NO_OPERANDS }; - -static const struct sieve_extension *ext_this = &match_type_extension; /* * Validator context: * name-based match-type registry. */ + +static struct sieve_validator_object_registry *_get_object_registry +(struct sieve_validator *valdtr) +{ + struct sieve_instance *svinst; + const struct sieve_extension *mcht_ext; + + svinst = sieve_validator_svinst(valdtr); + mcht_ext = sieve_get_match_type_extension(svinst); + return sieve_validator_object_registry_get(valdtr, mcht_ext); +} void sieve_match_type_register -(struct sieve_validator *validator, const struct sieve_match_type *mtch) +(struct sieve_validator *valdtr, const struct sieve_extension *ext, + const struct sieve_match_type_def *mcht_def) { - struct sieve_validator_object_registry *regs = - sieve_validator_object_registry_get(validator, ext_this); + struct sieve_validator_object_registry *regs = _get_object_registry(valdtr); - sieve_validator_object_registry_add(regs, &mtch->object); + sieve_validator_object_registry_add(regs, ext, &mcht_def->obj_def); } -const struct sieve_match_type *sieve_match_type_find -(struct sieve_validator *validator, const char *identifier) +static bool sieve_match_type_exists +(struct sieve_validator *valdtr, const char *identifier) { - struct sieve_validator_object_registry *regs = - sieve_validator_object_registry_get(validator, ext_this); - const struct sieve_object *object = - sieve_validator_object_registry_find(regs, identifier); + struct sieve_validator_object_registry *regs = _get_object_registry(valdtr); + + return sieve_validator_object_registry_find(regs, identifier, NULL); +} + +static const struct sieve_match_type *sieve_match_type_create_instance +(struct sieve_validator *valdtr, struct sieve_command *cmd, + const char *identifier) +{ + struct sieve_validator_object_registry *regs = _get_object_registry(valdtr); + struct sieve_object object; + struct sieve_match_type *mcht; + + if ( !sieve_validator_object_registry_find(regs, identifier, &object) ) + return NULL; - return (const struct sieve_match_type *) object; + mcht = p_new(sieve_command_pool(cmd), struct sieve_match_type, 1); + mcht->object = object; + mcht->def = (const struct sieve_match_type_def *) object.def; + + return mcht; } -bool mtch_validator_load(struct sieve_validator *validator) +bool mtch_validator_load +(const struct sieve_extension *ext, struct sieve_validator *valdtr) { struct sieve_validator_object_registry *regs = - sieve_validator_object_registry_init(validator, ext_this); + sieve_validator_object_registry_init(valdtr, ext); unsigned int i; /* Register core match-types */ for ( i = 0; i < sieve_core_match_types_count; i++ ) { sieve_validator_object_registry_add - (regs, &(sieve_core_match_types[i]->object)); + (regs, NULL, &(sieve_core_match_types[i]->obj_def)); } return TRUE; @@ -116,7 +139,8 @@ struct mtch_interpreter_context { }; static void mtch_interpreter_free -(struct sieve_interpreter *interp ATTR_UNUSED, void *context) +(const struct sieve_extension *ext ATTR_UNUSED, + struct sieve_interpreter *interp ATTR_UNUSED, void *context) { struct mtch_interpreter_context *mctx = (struct mtch_interpreter_context *) context; @@ -132,23 +156,26 @@ struct sieve_interpreter_extension mtch_interpreter_extension = { mtch_interpreter_free }; -static inline struct mtch_interpreter_context * -get_interpreter_context(struct sieve_interpreter *interp) +static inline struct mtch_interpreter_context *get_interpreter_context +(struct sieve_interpreter *interp, bool create) { - return (struct mtch_interpreter_context *) - sieve_interpreter_extension_get_context(interp, ext_this); -} - -static struct mtch_interpreter_context * -mtch_interpreter_context_init(struct sieve_interpreter *interp) -{ - pool_t pool = sieve_interpreter_pool(interp); + struct sieve_instance *svinst; + const struct sieve_extension *mcht_ext; struct mtch_interpreter_context *ctx; - - ctx = p_new(pool, struct mtch_interpreter_context, 1); - sieve_interpreter_extension_register - (interp, &mtch_interpreter_extension, (void *) ctx); + svinst = sieve_interpreter_svinst(interp); + mcht_ext = sieve_get_match_type_extension(svinst); + + ctx = (struct mtch_interpreter_context *) + sieve_interpreter_extension_get_context(interp, mcht_ext); + + if ( ctx == NULL && create ) { + pool_t pool = sieve_interpreter_pool(interp); + ctx = p_new(pool, struct mtch_interpreter_context, 1); + + sieve_interpreter_extension_register + (interp, mcht_ext, &mtch_interpreter_extension, (void *) ctx); + } return ctx; } @@ -160,11 +187,9 @@ mtch_interpreter_context_init(struct sieve_interpreter *interp) bool sieve_match_values_set_enabled (struct sieve_interpreter *interp, bool enable) { - struct mtch_interpreter_context *ctx = get_interpreter_context(interp); - - if ( ctx == NULL && enable ) - ctx = mtch_interpreter_context_init(interp); - + struct mtch_interpreter_context *ctx = + get_interpreter_context(interp, enable); + if ( ctx != NULL ) { bool previous = ctx->match_values_enabled; @@ -178,7 +203,8 @@ bool sieve_match_values_set_enabled bool sieve_match_values_are_enabled (struct sieve_interpreter *interp) { - struct mtch_interpreter_context *ctx = get_interpreter_context(interp); + struct mtch_interpreter_context *ctx = + get_interpreter_context(interp, FALSE); return ( ctx == NULL ? FALSE : ctx->match_values_enabled ); } @@ -186,7 +212,8 @@ bool sieve_match_values_are_enabled struct sieve_match_values *sieve_match_values_start (struct sieve_interpreter *interp) { - struct mtch_interpreter_context *ctx = get_interpreter_context(interp); + struct mtch_interpreter_context *ctx = + get_interpreter_context(interp, FALSE); struct sieve_match_values *match_values; if ( ctx == NULL || !ctx->match_values_enabled ) @@ -273,7 +300,7 @@ void sieve_match_values_commit if ( (*mvalues) == NULL ) return; - ctx = get_interpreter_context(interp); + ctx = get_interpreter_context(interp, FALSE); if ( ctx == NULL || !ctx->match_values_enabled ) return; @@ -298,7 +325,8 @@ void sieve_match_values_abort void sieve_match_values_get (struct sieve_interpreter *interp, unsigned int index, string_t **value_r) { - struct mtch_interpreter_context *ctx = get_interpreter_context(interp); + struct mtch_interpreter_context *ctx = + get_interpreter_context(interp, FALSE); struct sieve_match_values *mvalues; if ( ctx == NULL || ctx->match_values == NULL ) { @@ -324,57 +352,59 @@ void sieve_match_values_get /* Forward declarations */ static bool tag_match_type_is_instance_of - (struct sieve_validator *validator, struct sieve_command_context *cmd, - struct sieve_ast_argument *arg); + (struct sieve_validator *valdtr, struct sieve_command *cmd, + const struct sieve_extension *ext, const char *identifier, void **data); static bool tag_match_type_validate - (struct sieve_validator *validator, struct sieve_ast_argument **arg, - struct sieve_command_context *cmd); + (struct sieve_validator *valdtr, struct sieve_ast_argument **arg, + struct sieve_command *cmd); static bool tag_match_type_generate (const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, - struct sieve_command_context *cmd); + struct sieve_command *cmd); /* Argument object */ -const struct sieve_argument match_type_tag = { +const struct sieve_argument_def match_type_tag = { "MATCH-TYPE", tag_match_type_is_instance_of, - NULL, tag_match_type_validate, - NULL, + NULL, NULL, tag_match_type_generate }; /* Argument implementation */ static bool tag_match_type_is_instance_of -(struct sieve_validator *validator, struct sieve_command_context *cmd, - struct sieve_ast_argument *arg) +(struct sieve_validator *valdtr, struct sieve_command *cmd, + const struct sieve_extension *ext ATTR_UNUSED, const char *identifier, + void **data) { - struct sieve_match_type_context *mtctx; - const struct sieve_match_type *mtch = - sieve_match_type_find(validator, sieve_ast_argument_tag(arg)); - - if ( mtch == NULL ) return FALSE; - - /* Create context */ - mtctx = p_new(sieve_command_pool(cmd), struct sieve_match_type_context, 1); - mtctx->match_type = mtch; - mtctx->match_type_arg = arg; - mtctx->command_ctx = cmd; - mtctx->comparator = NULL; /* Can be filled in later */ - - arg->context = (void *) mtctx; + const struct sieve_match_type *mcht; + + if ( data == NULL ) + return sieve_match_type_exists(valdtr, identifier); + + if ( (mcht=sieve_match_type_create_instance + (valdtr, cmd, identifier)) == NULL ) + return FALSE; + *data = (void *) mcht; return TRUE; } static bool tag_match_type_validate -(struct sieve_validator *validator, struct sieve_ast_argument **arg, - struct sieve_command_context *cmd ATTR_UNUSED) +(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, + struct sieve_command *cmd ATTR_UNUSED) { - struct sieve_match_type_context *mtctx = - (struct sieve_match_type_context *) (*arg)->context; - const struct sieve_match_type *mtch = mtctx->match_type; + const struct sieve_match_type *mcht = + (const struct sieve_match_type *) (*arg)->argument->data; + struct sieve_match_type_context *mtctx; + + mtctx = p_new(sieve_command_pool(cmd), struct sieve_match_type_context, 1); + mtctx->match_type = mcht; + mtctx->argument = *arg; + mtctx->comparator = NULL; /* Can be filled in later */ + + (*arg)->argument->data = mtctx; /* Syntax: * ":is" / ":contains" / ":matches" (subject to extension) @@ -387,8 +417,8 @@ static bool tag_match_type_validate * Additional validation can override the match type recorded in the context * for later code generation. */ - if ( mtch->validate != NULL ) { - return mtch->validate(validator, arg, mtctx); + if ( mcht->def != NULL && mcht->def->validate != NULL ) { + return mcht->def->validate(valdtr, arg, mtctx); } return TRUE; @@ -396,10 +426,10 @@ static bool tag_match_type_validate static bool tag_match_type_generate (const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, - struct sieve_command_context *cmd ATTR_UNUSED) + struct sieve_command *cmd ATTR_UNUSED) { struct sieve_match_type_context *mtctx = - (struct sieve_match_type_context *) arg->context; + (struct sieve_match_type_context *) arg->argument->data; (void) sieve_opr_match_type_emit(cgenv->sbin, mtctx->match_type); @@ -407,11 +437,17 @@ static bool tag_match_type_generate } void sieve_match_types_link_tags - (struct sieve_validator *validator, - struct sieve_command_registration *cmd_reg, int id_code) +(struct sieve_validator *valdtr, + struct sieve_command_registration *cmd_reg, int id_code) { + struct sieve_instance *svinst; + const struct sieve_extension *mcht_ext; + + svinst = sieve_validator_svinst(valdtr); + mcht_ext = sieve_get_comparator_extension(svinst); + sieve_validator_register_tag - (validator, cmd_reg, &match_type_tag, id_code); + (valdtr, cmd_reg, mcht_ext, &match_type_tag, id_code); } /* @@ -419,7 +455,7 @@ void sieve_match_types_link_tags */ bool sieve_match_type_validate -(struct sieve_validator *validator, struct sieve_command_context *cmd, +(struct sieve_validator *valdtr, struct sieve_command *cmd, struct sieve_ast_argument *key_arg, const struct sieve_match_type *mcht_default, const struct sieve_comparator *cmp_default) @@ -445,15 +481,17 @@ bool sieve_match_type_validate } /* Verify using the default comparator if none is specified explicitly */ - if ( cmp == NULL ) - cmp = cmp_default; + if ( cmp == NULL ) { + cmp = sieve_comparator_copy(sieve_command_pool(cmd), cmp_default); + } /* Verify the default match type if none is specified explicitly */ - if ( mt_arg == NULL || mt_arg->context == NULL ) { + if ( mt_arg == NULL || mt_arg->argument == NULL || + mt_arg->argument->data == NULL ) { mtctx = NULL; - mcht = mcht_default; + mcht = sieve_match_type_copy(sieve_command_pool(cmd), mcht_default); } else { - mtctx = (struct sieve_match_type_context *) mt_arg->context; + mtctx = (struct sieve_match_type_context *) mt_arg->argument->data; mcht = mtctx->match_type; mtctx->comparator = cmp; } @@ -462,8 +500,9 @@ bool sieve_match_type_validate * Additional validation can override the match type recorded in the context * for later code generation. */ - if ( mcht != NULL && mcht->validate_context != NULL ) { - return mcht->validate_context(validator, mt_arg, mtctx, key_arg); + if ( mcht != NULL && mcht->def != NULL && + mcht->def->validate_context != NULL ) { + return mcht->def->validate_context(valdtr, mt_arg, mtctx, key_arg); } return TRUE; @@ -479,7 +518,7 @@ const struct sieve_operand_class sieve_match_type_operand_class = static const struct sieve_extension_objects core_match_types = SIEVE_EXT_DEFINE_MATCH_TYPES(sieve_core_match_types); -const struct sieve_operand match_type_operand = { +const struct sieve_operand_def match_type_operand = { "match-type", NULL, SIEVE_OPERAND_MATCH_TYPE, @@ -492,20 +531,20 @@ const struct sieve_operand match_type_operand = { */ bool sieve_match_substring_validate_context -(struct sieve_validator *validator, struct sieve_ast_argument *arg, +(struct sieve_validator *valdtr, struct sieve_ast_argument *arg, struct sieve_match_type_context *ctx, struct sieve_ast_argument *key_arg ATTR_UNUSED) { const struct sieve_comparator *cmp = ctx->comparator; - if ( cmp == NULL ) + if ( cmp == NULL || cmp->def == NULL ) return TRUE; - if ( (cmp->flags & SIEVE_COMPARATOR_FLAG_SUBSTRING_MATCH) == 0 ) { - sieve_argument_validate_error(validator, arg, + if ( (cmp->def->flags & SIEVE_COMPARATOR_FLAG_SUBSTRING_MATCH) == 0 ) { + sieve_argument_validate_error(valdtr, arg, "the specified %s comparator does not support " "sub-string matching as required by the :%s match type", - cmp->object.identifier, ctx->match_type->object.identifier ); + cmp->object.def->identifier, ctx->match_type->object.def->identifier ); return FALSE; } diff --git a/src/lib-sieve/sieve-match-types.h b/src/lib-sieve/sieve-match-types.h index aa7c51923..361981635 100644 --- a/src/lib-sieve/sieve-match-types.h +++ b/src/lib-sieve/sieve-match-types.h @@ -27,16 +27,16 @@ enum sieve_match_type_code { SIEVE_MATCH_TYPE_CUSTOM }; -extern const struct sieve_match_type is_match_type; -extern const struct sieve_match_type contains_match_type; -extern const struct sieve_match_type matches_match_type; +extern const struct sieve_match_type_def is_match_type; +extern const struct sieve_match_type_def contains_match_type; +extern const struct sieve_match_type_def matches_match_type; /* - * Match type object + * Match type definition */ -struct sieve_match_type { - struct sieve_object object; +struct sieve_match_type_def { + struct sieve_object_def obj_def; /* Match function called for every key value or should it be called once * for every tested value? (TRUE = first alternative) @@ -49,10 +49,10 @@ struct sieve_match_type { bool allow_key_extract; bool (*validate) - (struct sieve_validator *validator, struct sieve_ast_argument **arg, + (struct sieve_validator *valdtr, struct sieve_ast_argument **arg, struct sieve_match_type_context *ctx); bool (*validate_context) - (struct sieve_validator *validator, struct sieve_ast_argument *arg, + (struct sieve_validator *valdtr, struct sieve_ast_argument *arg, struct sieve_match_type_context *ctx, struct sieve_ast_argument *key_arg); /* @@ -73,9 +73,39 @@ struct sieve_match_type { int (*match_deinit)(struct sieve_match_context *mctx); }; +/* + * Match type instance + */ + +struct sieve_match_type { + struct sieve_object object; + + const struct sieve_match_type_def *def; +}; + +#define SIEVE_MATCH_TYPE_DEFAULT(definition) \ + { SIEVE_OBJECT_DEFAULT(definition), &(definition) } + +#define sieve_match_type_name(mcht) \ + ( (mcht)->object.def->identifier ) + +static inline const struct sieve_match_type *sieve_match_type_copy +(pool_t pool, const struct sieve_match_type *cmp_orig) +{ + struct sieve_match_type *cmp = p_new(pool, struct sieve_match_type, 1); + + *cmp = *cmp_orig; + + return cmp; +} + +/* + * Match type context + */ + struct sieve_match_type_context { - struct sieve_command_context *command_ctx; - struct sieve_ast_argument *match_type_arg; + struct sieve_command *command; + struct sieve_ast_argument *argument; const struct sieve_match_type *match_type; @@ -94,9 +124,8 @@ struct sieve_match_type_context { */ void sieve_match_type_register - (struct sieve_validator *validator, const struct sieve_match_type *mcht); -const struct sieve_match_type *sieve_match_type_find - (struct sieve_validator *validator, const char *identifier); + (struct sieve_validator *valdtr, const struct sieve_extension *ext, + const struct sieve_match_type_def *mcht); /* * Match values @@ -132,16 +161,16 @@ void sieve_match_values_get * Match type tagged argument */ -extern const struct sieve_argument match_type_tag; +extern const struct sieve_argument_def match_type_tag; static inline bool sieve_argument_is_match_type (struct sieve_ast_argument *arg) { - return ( arg->argument == &match_type_tag ); + return ( arg->argument->def == &match_type_tag ); } void sieve_match_types_link_tags - (struct sieve_validator *validator, + (struct sieve_validator *valdtr, struct sieve_command_registration *cmd_reg, int id_code); /* @@ -149,7 +178,7 @@ void sieve_match_types_link_tags */ bool sieve_match_type_validate - (struct sieve_validator *validator, struct sieve_command_context *cmd, + (struct sieve_validator *valdtr, struct sieve_command *cmd, struct sieve_ast_argument *key_arg, const struct sieve_match_type *mcht_default, const struct sieve_comparator *cmp_default); @@ -158,7 +187,7 @@ bool sieve_match_type_validate * Match type operand */ -extern const struct sieve_operand match_type_operand; +extern const struct sieve_operand_def match_type_operand; extern const struct sieve_operand_class sieve_match_type_operand_class; #define SIEVE_EXT_DEFINE_MATCH_TYPE(OP) SIEVE_EXT_DEFINE_OBJECT(OP) @@ -167,21 +196,26 @@ extern const struct sieve_operand_class sieve_match_type_operand_class; static inline bool sieve_operand_is_match_type (const struct sieve_operand *operand) { - return ( operand != NULL && - operand->class == &sieve_match_type_operand_class ); + return ( operand != NULL && operand->def != NULL && + operand->def->class == &sieve_match_type_operand_class ); } static inline void sieve_opr_match_type_emit -(struct sieve_binary *sbin, const struct sieve_match_type *mtch) +(struct sieve_binary *sbin, const struct sieve_match_type *mcht) { - sieve_opr_object_emit(sbin, &mtch->object); + sieve_opr_object_emit(sbin, mcht->object.ext, mcht->object.def); } -static inline const struct sieve_match_type *sieve_opr_match_type_read -(const struct sieve_runtime_env *renv, sieve_size_t *address) +static inline bool sieve_opr_match_type_read +(const struct sieve_runtime_env *renv, sieve_size_t *address, + struct sieve_match_type *mcht) { - return (const struct sieve_match_type *) sieve_opr_object_read - (renv, &sieve_match_type_operand_class, address); + if ( !sieve_opr_object_read + (renv, &sieve_match_type_operand_class, address, &mcht->object) ) + return FALSE; + + mcht->def = (const struct sieve_match_type_def *) mcht->object.def; + return TRUE; } static inline bool sieve_opr_match_type_dump @@ -194,7 +228,7 @@ static inline bool sieve_opr_match_type_dump /* Common validation implementation */ bool sieve_match_substring_validate_context - (struct sieve_validator *validator, struct sieve_ast_argument *arg, + (struct sieve_validator *valdtr, struct sieve_ast_argument *arg, struct sieve_match_type_context *ctx, struct sieve_ast_argument *key_arg); diff --git a/src/lib-sieve/sieve-match.c b/src/lib-sieve/sieve-match.c index 6d5218afa..22037c53f 100644 --- a/src/lib-sieve/sieve-match.c +++ b/src/lib-sieve/sieve-match.c @@ -24,7 +24,7 @@ */ struct sieve_match_context *sieve_match_begin -(struct sieve_interpreter *interp, const struct sieve_match_type *mtch, +(struct sieve_interpreter *interp, const struct sieve_match_type *mcht, const struct sieve_comparator *cmp, const struct sieve_match_key_extractor *kextract, struct sieve_coded_stringlist *key_list) @@ -37,13 +37,13 @@ struct sieve_match_context *sieve_match_begin mctx->pool = pool; mctx->interp = interp; - mctx->match_type = mtch; + mctx->match_type = mcht; mctx->comparator = cmp; mctx->kextract = kextract; mctx->key_list = key_list; - if ( mtch->match_init != NULL ) { - mtch->match_init(mctx); + if ( mcht->def != NULL && mcht->def->match_init != NULL ) { + mcht->def->match_init(mctx); } return mctx; @@ -52,25 +52,24 @@ struct sieve_match_context *sieve_match_begin int sieve_match_value (struct sieve_match_context *mctx, const char *value, size_t val_size) { - const struct sieve_match_type *mtch = mctx->match_type; + const struct sieve_match_type *mcht = mctx->match_type; sieve_coded_stringlist_reset(mctx->key_list); bool ok = TRUE; /* Reject unimplemented match-type */ - if ( mtch->match == NULL ) + if ( mcht->def == NULL || mcht->def->match == NULL ) return FALSE; /* Match to all key values */ - if ( mtch->is_iterative ) { + if ( mcht->def->is_iterative ) { unsigned int key_index = 0; string_t *key_item = NULL; int ret = 0; while ( (ok=sieve_coded_stringlist_next_item(mctx->key_list, &key_item)) - && key_item != NULL ) - { + && key_item != NULL ) { T_BEGIN { - if ( mctx->kextract != NULL && mtch->allow_key_extract ) { + if ( mctx->kextract != NULL && mcht->def->allow_key_extract ) { const struct sieve_match_key_extractor *kext = mctx->kextract; void *kctx; @@ -79,14 +78,14 @@ int sieve_match_value size_t key_size; while ( (ret=kext->extract_key(kctx, &key, &key_size)) > 0 ) { - ret = mtch->match + ret = mcht->def->match (mctx, value, val_size, key, key_size, key_index); if ( ret != 0 ) break; } } } else { - ret = mtch->match(mctx, value, val_size, str_c(key_item), + ret = mcht->def->match(mctx, value, val_size, str_c(key_item), str_len(key_item), key_index); } } T_END; @@ -109,7 +108,7 @@ int sieve_match_value bool result; T_BEGIN { - result = mtch->match(mctx, value, val_size, NULL, 0, -1); + result = mcht->def->match(mctx, value, val_size, NULL, 0, -1); } T_END; return result; @@ -120,15 +119,15 @@ int sieve_match_value int sieve_match_end(struct sieve_match_context **mctx) { - const struct sieve_match_type *mtch = (*mctx)->match_type; + const struct sieve_match_type *mcht = (*mctx)->match_type; int ret = FALSE; - if ( mtch->match_deinit != NULL ) { - ret = mtch->match_deinit(*mctx); + if ( mcht->def != NULL && mcht->def->match_deinit != NULL ) { + ret = mcht->def->match_deinit(*mctx); } - pool_unref(&(*mctx)->pool); - *mctx = NULL; + pool_unref(&(*mctx)->pool); + *mctx = NULL; return ret; } @@ -168,7 +167,7 @@ bool sieve_match_dump_optional_operands int sieve_match_read_optional_operands (const struct sieve_runtime_env *renv, sieve_size_t *address, int *opt_code, - const struct sieve_comparator **cmp_r, const struct sieve_match_type **mtch_r) + struct sieve_comparator *cmp, struct sieve_match_type *mcht) { /* Handle any optional arguments */ if ( *opt_code != SIEVE_MATCH_OPT_END || @@ -183,13 +182,13 @@ int sieve_match_read_optional_operands case SIEVE_MATCH_OPT_END: break; case SIEVE_MATCH_OPT_COMPARATOR: - if ( (*cmp_r = sieve_opr_comparator_read(renv, address)) == NULL ) { + if ( !sieve_opr_comparator_read(renv, address, cmp) ) { sieve_runtime_trace_error(renv, "invalid comparator operand"); return SIEVE_EXEC_BIN_CORRUPT; } break; case SIEVE_MATCH_OPT_MATCH_TYPE: - if ( (*mtch_r = sieve_opr_match_type_read(renv, address)) == NULL ) { + if ( !sieve_opr_match_type_read(renv, address, mcht) ) { sieve_runtime_trace_error(renv, "invalid match type operand"); return SIEVE_EXEC_BIN_CORRUPT; } diff --git a/src/lib-sieve/sieve-match.h b/src/lib-sieve/sieve-match.h index 9f08faf05..65d0c462f 100644 --- a/src/lib-sieve/sieve-match.h +++ b/src/lib-sieve/sieve-match.h @@ -58,7 +58,6 @@ bool sieve_match_dump_optional_operands int sieve_match_read_optional_operands (const struct sieve_runtime_env *renv, sieve_size_t *address, int *opt_code, - const struct sieve_comparator **cmp_r, - const struct sieve_match_type **mtch_r); + struct sieve_comparator *cmp, struct sieve_match_type *mcht); #endif /* __SIEVE_MATCH_H */ diff --git a/src/lib-sieve/sieve-message.c b/src/lib-sieve/sieve-message.c index 8327275ee..2c42ac500 100644 --- a/src/lib-sieve/sieve-message.c +++ b/src/lib-sieve/sieve-message.c @@ -35,6 +35,8 @@ struct sieve_message_context { pool_t pool; int refcount; + struct sieve_instance *svinst; + const struct sieve_message_data *msgdata; /* Normalized envelope addresses */ @@ -49,12 +51,13 @@ struct sieve_message_context { }; struct sieve_message_context *sieve_message_context_create -(const struct sieve_message_data *msgdata) +(struct sieve_instance *svinst, const struct sieve_message_data *msgdata) { struct sieve_message_context *msgctx; msgctx = i_new(struct sieve_message_context, 1); msgctx->refcount = 1; + msgctx->svinst = svinst; msgctx->msgdata = msgdata; @@ -96,7 +99,8 @@ void sieve_message_context_flush(struct sieve_message_context *msgctx) msgctx->envelope_sender = NULL; msgctx->envelope_parsed = FALSE; - p_array_init(&msgctx->ext_contexts, pool, sieve_extensions_get_count()); + p_array_init(&msgctx->ext_contexts, pool, + sieve_extensions_get_count(msgctx->svinst)); } pool_t sieve_message_context_pool(struct sieve_message_context *msgctx) @@ -110,19 +114,20 @@ void sieve_message_context_extension_set (struct sieve_message_context *msgctx, const struct sieve_extension *ext, void *context) { - array_idx_set(&msgctx->ext_contexts, (unsigned int) SIEVE_EXT_ID(ext), &context); + if ( ext->id < 0 ) return; + + array_idx_set(&msgctx->ext_contexts, (unsigned int) ext->id, &context); } const void *sieve_message_context_extension_get (struct sieve_message_context *msgctx, const struct sieve_extension *ext) { - int ext_id = SIEVE_EXT_ID(ext); void * const *ctx; - if ( ext_id < 0 || ext_id >= (int) array_count(&msgctx->ext_contexts) ) + if ( ext->id < 0 || ext->id >= (int) array_count(&msgctx->ext_contexts) ) return NULL; - ctx = array_idx(&msgctx->ext_contexts, (unsigned int) ext_id); + ctx = array_idx(&msgctx->ext_contexts, (unsigned int) ext->id); return *ctx; } diff --git a/src/lib-sieve/sieve-message.h b/src/lib-sieve/sieve-message.h index e2a87096b..2ef98f235 100644 --- a/src/lib-sieve/sieve-message.h +++ b/src/lib-sieve/sieve-message.h @@ -18,7 +18,7 @@ const char *sieve_message_get_new_id struct sieve_message_context; struct sieve_message_context *sieve_message_context_create - (const struct sieve_message_data *msgdata); + (struct sieve_instance *svinst, const struct sieve_message_data *msgdata); void sieve_message_context_ref(struct sieve_message_context *msgctx); void sieve_message_context_unref(struct sieve_message_context **msgctx); diff --git a/src/lib-sieve/sieve-objects.c b/src/lib-sieve/sieve-objects.c index d829d6c0c..0e24439fb 100644 --- a/src/lib-sieve/sieve-objects.c +++ b/src/lib-sieve/sieve-objects.c @@ -15,82 +15,97 @@ */ void sieve_opr_object_emit -(struct sieve_binary *sbin, const struct sieve_object *obj) +(struct sieve_binary *sbin, const struct sieve_extension *ext, + const struct sieve_object_def *obj_def) { struct sieve_extension_objects *objs = - (struct sieve_extension_objects *) obj->operand->interface; + (struct sieve_extension_objects *) obj_def->operand->interface; - (void) sieve_operand_emit_code(sbin, obj->operand); + (void) sieve_operand_emit(sbin, ext, obj_def->operand); if ( objs->count > 1 ) { - (void) sieve_binary_emit_byte(sbin, obj->code); + (void) sieve_binary_emit_byte(sbin, obj_def->code); } } -const struct sieve_object *sieve_opr_object_read_data +bool sieve_opr_object_read_data (struct sieve_binary *sbin, const struct sieve_operand *operand, - const struct sieve_operand_class *opclass, sieve_size_t *address) + const struct sieve_operand_class *opclass, sieve_size_t *address, + struct sieve_object *obj) { const struct sieve_extension_objects *objs; unsigned int obj_code; - if ( operand == NULL || operand->class != opclass ) - return NULL; + if ( operand == NULL || operand->def->class != opclass ) + return FALSE; - objs = (struct sieve_extension_objects *) operand->interface; + objs = (struct sieve_extension_objects *) operand->def->interface; if ( objs == NULL ) - return NULL; + return FALSE; if ( objs->count > 1 ) { if ( !sieve_binary_read_byte(sbin, address, &obj_code) ) - return NULL; + return FALSE; if ( obj_code < objs->count ) { - const struct sieve_object *const *objects = - (const struct sieve_object* const *) objs->objects; - return objects[obj_code]; + const struct sieve_object_def *const *objects = + (const struct sieve_object_def *const *) objs->objects; + + obj->def = objects[obj_code]; + obj->ext = operand->ext; + return TRUE; } } - return (const struct sieve_object *) objs->objects; + obj->def = (const struct sieve_object_def *) objs->objects; + obj->ext = operand->ext; + return TRUE; } -const struct sieve_object *sieve_opr_object_read +bool sieve_opr_object_read (const struct sieve_runtime_env *renv, - const struct sieve_operand_class *opclass, sieve_size_t *address) + const struct sieve_operand_class *opclass, sieve_size_t *address, + struct sieve_object *obj) { - const struct sieve_operand *operand = sieve_operand_read(renv->sbin, address); + struct sieve_operand operand; + + if ( !sieve_operand_read(renv->sbin, address, &operand) ) { + return FALSE; + } - return sieve_opr_object_read_data(renv->sbin, operand, opclass, address); + return sieve_opr_object_read_data + (renv->sbin, &operand, opclass, address, obj); } bool sieve_opr_object_dump (const struct sieve_dumptime_env *denv, const struct sieve_operand_class *opclass, sieve_size_t *address, - const struct sieve_object **object_r) + struct sieve_object *obj) { - const struct sieve_operand *operand; - const struct sieve_object *obj; + struct sieve_operand operand; + struct sieve_object obj_i; const char *class; + if ( obj == NULL ) + obj = &obj_i; + sieve_code_mark(denv); - operand = sieve_operand_read(denv->sbin, address); - obj = sieve_opr_object_read_data(denv->sbin, operand, opclass, address); - - if ( obj == NULL ) + if ( !sieve_operand_read(denv->sbin, address, &operand) ) { return FALSE; - - if ( operand->class == NULL ) + } + + if ( !sieve_opr_object_read_data + (denv->sbin, &operand, opclass, address, obj) ) + return FALSE; + + if ( operand.def->class == NULL ) class = "OBJECT"; else - class = operand->class->name; + class = operand.def->class->name; - sieve_code_dumpf(denv, "%s: %s", class, obj->identifier); - - if ( object_r != NULL ) - *object_r = obj; - + sieve_code_dumpf(denv, "%s: %s", class, obj->def->identifier); + return TRUE; } diff --git a/src/lib-sieve/sieve-objects.h b/src/lib-sieve/sieve-objects.h index 035e35678..cc2b28bc0 100644 --- a/src/lib-sieve/sieve-objects.h +++ b/src/lib-sieve/sieve-objects.h @@ -5,37 +5,62 @@ #define __SIEVE_OBJECTS_H /* - * Object + * Object definition */ -struct sieve_object { +struct sieve_object_def { const char *identifier; - const struct sieve_operand *operand; + const struct sieve_operand_def *operand; unsigned int code; }; #define SIEVE_OBJECT(identifier, operand, code) \ { identifier, operand, code } +/* + * Object instance + */ + +struct sieve_object { + const struct sieve_object_def *def; + const struct sieve_extension *ext; +}; + +#define SIEVE_OBJECT_DEFAULT(_obj) \ + { &((_obj).obj_def), NULL } + +#define SIEVE_OBJECT_EXTENSION(_obj) \ + (_obj->object.ext) + +#define SIEVE_OBJECT_SET_DEF(_obj, def_value) \ + STMT_START { \ + (_obj)->def = def_value; \ + (_obj)->object.def = &(_obj)->def->obj_def; \ + } STMT_END + + /* * Object coding */ void sieve_opr_object_emit - (struct sieve_binary *sbin, const struct sieve_object *obj); + (struct sieve_binary *sbin, const struct sieve_extension *ext, + const struct sieve_object_def *obj_def); -const struct sieve_object *sieve_opr_object_read_data +bool sieve_opr_object_read_data (struct sieve_binary *sbin, const struct sieve_operand *operand, - const struct sieve_operand_class *opclass, sieve_size_t *address); + const struct sieve_operand_class *opclass, sieve_size_t *address, + struct sieve_object *obj); -const struct sieve_object *sieve_opr_object_read +bool sieve_opr_object_read (const struct sieve_runtime_env *renv, - const struct sieve_operand_class *opclass, sieve_size_t *address); + const struct sieve_operand_class *opclass, sieve_size_t *address, + struct sieve_object *obj); bool sieve_opr_object_dump (const struct sieve_dumptime_env *denv, const struct sieve_operand_class *opclass, sieve_size_t *address, - const struct sieve_object **object_r); + struct sieve_object *obj); #endif /* __SIEVE_OBJECTS_H */ diff --git a/src/lib-sieve/sieve-result.c b/src/lib-sieve/sieve-result.c index 34a01e189..446b8fc2f 100644 --- a/src/lib-sieve/sieve-result.c +++ b/src/lib-sieve/sieve-result.c @@ -26,8 +26,7 @@ */ struct sieve_result_action { - struct sieve_result *result; - struct sieve_action_data data; + struct sieve_action action; void *tr_context; bool success; @@ -47,13 +46,13 @@ struct sieve_side_effects_list { }; struct sieve_result_side_effect { - const struct sieve_side_effect *seffect; - void *context; + struct sieve_side_effect seffect; + struct sieve_result_side_effect *prev, *next; }; struct sieve_result_action_context { - const struct sieve_action *action; + const struct sieve_action_def *action; struct sieve_side_effects_list *seffects; }; @@ -65,6 +64,8 @@ struct sieve_result { pool_t pool; int refcount; + struct sieve_instance *svinst; + /* Context data for extensions */ ARRAY_DEFINE(ext_contexts, void *); @@ -72,8 +73,8 @@ struct sieve_result { struct sieve_action_exec_env action_env; - const struct sieve_action *keep_action; - const struct sieve_action *failure_action; + struct sieve_action keep_action; + struct sieve_action failure_action; unsigned int action_count; struct sieve_result_action *first_action; @@ -85,8 +86,8 @@ struct sieve_result { }; struct sieve_result *sieve_result_create -(const struct sieve_message_data *msgdata, const struct sieve_script_env *senv, - struct sieve_error_handler *ehandler) +(struct sieve_instance *svinst, const struct sieve_message_data *msgdata, + const struct sieve_script_env *senv, struct sieve_error_handler *ehandler) { pool_t pool; struct sieve_result *result; @@ -95,6 +96,7 @@ struct sieve_result *sieve_result_create result = p_new(pool, struct sieve_result, 1); result->refcount = 1; result->pool = pool; + result->svinst = svinst; p_array_init(&result->ext_contexts, pool, 4); @@ -105,10 +107,12 @@ struct sieve_result *sieve_result_create result->action_env.result = result; result->action_env.scriptenv = senv; result->action_env.msgdata = msgdata; - result->action_env.msgctx = sieve_message_context_create(msgdata); + result->action_env.msgctx = sieve_message_context_create(svinst, msgdata); - result->keep_action = &act_store; - result->failure_action = &act_store; + result->keep_action.def = &act_store; + result->keep_action.ext = NULL; + result->failure_action.def = &act_store; + result->failure_action.ext = NULL; result->action_count = 0; result->first_action = NULL; @@ -192,20 +196,20 @@ void sieve_result_set_error_handler void sieve_result_extension_set_context (struct sieve_result *result, const struct sieve_extension *ext, void *context) { - array_idx_set(&result->ext_contexts, (unsigned int) SIEVE_EXT_ID(ext), - &context); -} + if ( ext->id < 0 ) return; + + array_idx_set(&result->ext_contexts, (unsigned int) ext->id, &context); +} const void *sieve_result_extension_get_context (struct sieve_result *result, const struct sieve_extension *ext) { - int ext_id = SIEVE_EXT_ID(ext); void * const *ctx; - if ( ext_id < 0 || ext_id >= (int) array_count(&result->ext_contexts) ) + if ( ext->id < 0 || ext->id >= (int) array_count(&result->ext_contexts) ) return NULL; - ctx = array_idx(&result->ext_contexts, (unsigned int) ext_id); + ctx = array_idx(&result->ext_contexts, (unsigned int) ext->id); return *ctx; } @@ -258,10 +262,12 @@ void sieve_result_log */ void sieve_result_add_implicit_side_effect -(struct sieve_result *result, const struct sieve_action *to_action, - bool to_keep, const struct sieve_side_effect *seffect, void *context) +(struct sieve_result *result, const struct sieve_action_def *to_action, + bool to_keep, const struct sieve_extension *ext, + const struct sieve_side_effect_def *seff_def, void *context) { struct sieve_result_action_context *actctx = NULL; + struct sieve_side_effect seffect; to_action = to_keep ? &act_store : to_action; @@ -282,8 +288,13 @@ void sieve_result_add_implicit_side_effect hash_table_insert(result->action_contexts, (void *) to_action, (void *) actctx); } - - sieve_side_effects_list_add(actctx->seffects, seffect, context); + + seffect.object.def = &seff_def->obj_def; + seffect.object.ext = ext; + seffect.def = seff_def; + seffect.context = context; + + sieve_side_effects_list_add(actctx->seffects, &seffect); } static int sieve_result_side_effects_merge @@ -300,17 +311,19 @@ static int sieve_result_side_effects_merge /* Merge existing side effects */ rsef = old_seffects != NULL ? old_seffects->first_effect : NULL; while ( rsef != NULL ) { - const struct sieve_side_effect *seffect = rsef->seffect; + struct sieve_side_effect *seffect = &rsef->seffect; bool found = FALSE; - if ( seffect->merge != NULL ) { + if ( seffect->def != NULL && seffect->def->merge != NULL ) { /* Try to find it among the new */ nrsef = new_seffects != NULL ? new_seffects->first_effect : NULL; while ( nrsef != NULL ) { - if ( nrsef->seffect == seffect ) { - if ( seffect->merge - (renv, action, seffect, &rsef->context, nrsef->context) < 0 ) + struct sieve_side_effect *nseffect = &nrsef->seffect; + + if ( nseffect->def == seffect->def ) { + if ( seffect->def->merge + (renv, action, seffect, nseffect, &seffect->context) < 0 ) return -1; found = TRUE; @@ -321,8 +334,8 @@ static int sieve_result_side_effects_merge } /* Not found? */ - if ( !found && seffect->merge - (renv, action, seffect, &rsef->context, NULL) < 0 ) + if ( !found && seffect->def->merge + (renv, action, seffect, NULL, &rsef->seffect.context) < 0 ) return -1; } @@ -332,15 +345,15 @@ static int sieve_result_side_effects_merge /* Merge new Side effects */ nrsef = new_seffects != NULL ? new_seffects->first_effect : NULL; while ( nrsef != NULL ) { - const struct sieve_side_effect *seffect = nrsef->seffect; + struct sieve_side_effect *nseffect = &nrsef->seffect; bool found = FALSE; - if ( seffect->merge != NULL ) { + if ( nseffect->def != NULL && nseffect->def->merge != NULL ) { /* Try to find it among the exising */ rsef = old_seffects != NULL ? old_seffects->first_effect : NULL; while ( rsef != NULL ) { - if ( rsef->seffect == seffect ) { + if ( rsef->seffect.def == nseffect->def ) { found = TRUE; break; } @@ -351,17 +364,19 @@ static int sieve_result_side_effects_merge if ( !found ) { void *new_context = NULL; - if ( (ret=seffect->merge - (renv, action, seffect, &new_context, nrsef->context)) < 0 ) + if ( (ret=nseffect->def->merge + (renv, action, nseffect, nseffect, &new_context)) < 0 ) return -1; if ( ret != 0 ) { if ( old_action->seffects == NULL ) old_action->seffects = old_seffects = - sieve_side_effects_list_create(old_action->result); + sieve_side_effects_list_create(renv->result); + + nseffect->context = new_context; /* Add side effect */ - sieve_side_effects_list_add(old_seffects, seffect, new_context); + sieve_side_effects_list_add(old_seffects, nseffect); } } } @@ -372,10 +387,9 @@ static int sieve_result_side_effects_merge return 1; } -static void sieve_result_action_detach(struct sieve_result_action *raction) -{ - struct sieve_result *result = raction->result; - +static void sieve_result_action_detach +(struct sieve_result *result, struct sieve_result_action *raction) +{ if ( result->first_action == raction ) result->first_action = raction->next; @@ -396,55 +410,56 @@ static void sieve_result_action_detach(struct sieve_result_action *raction) } static int _sieve_result_add_action -(const struct sieve_runtime_env *renv, - const struct sieve_action *action, struct sieve_side_effects_list *seffects, - unsigned int source_line, void *context, unsigned int instance_limit, - bool keep) +(const struct sieve_runtime_env *renv, const struct sieve_extension *ext, + const struct sieve_action_def *act_def, + struct sieve_side_effects_list *seffects, unsigned int source_line, + void *context, unsigned int instance_limit, bool keep) { int ret = 0; unsigned int instance_count = 0; struct sieve_result *result = renv->result; struct sieve_result_action *raction = NULL, *kaction = NULL; - struct sieve_action_data act_data; + struct sieve_action action; - act_data.action = action; - act_data.location = sieve_error_script_location(renv->script, source_line); - act_data.context = context; - act_data.executed = FALSE; + action.def = act_def; + action.ext = ext; + action.location = sieve_error_script_location(renv->script, source_line); + action.context = context; + action.executed = FALSE; /* First, check for duplicates or conflicts */ raction = result->first_action; while ( raction != NULL ) { - const struct sieve_action *oact = raction->data.action; + const struct sieve_action *oact = &raction->action; if ( keep && raction->keep ) { /* Duplicate keep */ - if ( raction->data.action == NULL || raction->data.executed ) { + if ( raction->action.def == NULL || raction->action.executed ) { /* Keep action from preceeding execution */ /* Detach existing keep action */ - sieve_result_action_detach(raction); + sieve_result_action_detach(result, raction); /* Merge existing side-effects with new keep action */ if ( kaction == NULL ) kaction = raction; if ( (ret=sieve_result_side_effects_merge - (renv, action, kaction, seffects)) <= 0 ) + (renv, &action, kaction, seffects)) <= 0 ) return ret; } else { /* True duplicate */ return sieve_result_side_effects_merge - (renv, action, raction, seffects); + (renv, &action, raction, seffects); } - } if ( action != NULL && raction->data.action == action ) { + } if ( act_def != NULL && raction->action.def == act_def ) { instance_count++; /* Possible duplicate */ - if ( action->check_duplicate != NULL ) { - if ( (ret=action->check_duplicate(renv, &act_data, &raction->data)) + if ( act_def->check_duplicate != NULL ) { + if ( (ret=act_def->check_duplicate(renv, &action, &raction->action)) < 0 ) return ret; @@ -457,12 +472,13 @@ static int _sieve_result_add_action */ if ( (ret=sieve_result_side_effects_merge - (renv, action, raction, seffects)) < 0 ) + (renv, &action, raction, seffects)) < 0 ) return ret; if ( kaction == NULL ) { - raction->data.context = NULL; - raction->data.location = p_strdup(result->pool, act_data.location); + raction->action.context = NULL; + raction->action.location = + p_strdup(result->pool, action.location); /* Note that existing execution status is retained, making sure * that keep is not executed multiple times. @@ -471,28 +487,29 @@ static int _sieve_result_add_action kaction = raction; } else { - sieve_result_action_detach(raction); + sieve_result_action_detach(result, raction); if ( (ret=sieve_result_side_effects_merge - (renv, action, kaction, raction->seffects)) < 0 ) + (renv, &action, kaction, raction->seffects)) < 0 ) return ret; } } else { /* Merge side-effects, but don't add new action */ return sieve_result_side_effects_merge - (renv, action, raction, seffects); + (renv, &action, raction, seffects); } } } } else { - if ( action != NULL && oact != NULL ) { + if ( act_def != NULL && oact->def != NULL ) { /* Check conflict */ - if ( action->check_conflict != NULL && - (ret=action->check_conflict(renv, &act_data, &raction->data)) != 0 ) + if ( act_def->check_conflict != NULL && + (ret=act_def->check_conflict(renv, &action, &raction->action)) != 0 ) return ret; - if ( !raction->data.executed && oact->check_conflict != NULL && - (ret=oact->check_conflict(renv, &raction->data, &act_data)) != 0 ) + if ( !raction->action.executed && oact->def->check_conflict != NULL && + (ret=oact->def->check_conflict + (renv, &raction->action, &action)) != 0 ) return ret; } } @@ -501,15 +518,15 @@ static int _sieve_result_add_action /* Check policy limit on total number of actions */ if ( sieve_max_actions > 0 && result->action_count >= sieve_max_actions ) { - sieve_runtime_error(renv, act_data.location, + sieve_runtime_error(renv, action.location, "total number of actions exceeds policy limit"); return -1; } /* Check policy limit on number of this class of actions */ if ( instance_limit > 0 && instance_count >= instance_limit ) { - sieve_runtime_error(renv, act_data.location, - "number of %s actions exceeds policy limit", action->name); + sieve_runtime_error(renv, action.location, + "number of %s actions exceeds policy limit", act_def->name); return -1; } @@ -519,16 +536,16 @@ static int _sieve_result_add_action } else { /* Create new action object */ raction = p_new(result->pool, struct sieve_result_action, 1); - raction->data.executed = FALSE; - raction->result = result; + raction->action.executed = FALSE; raction->seffects = seffects; raction->tr_context = NULL; raction->success = FALSE; } - raction->data.context = context; - raction->data.action = action; - raction->data.location = p_strdup(result->pool, act_data.location); + raction->action.context = context; + raction->action.def = act_def; + raction->action.ext = ext; + raction->action.location = p_strdup(result->pool, action.location); raction->keep = keep; if ( raction->prev == NULL ) { @@ -552,7 +569,8 @@ static int _sieve_result_add_action /* Check for implicit side effects to this particular action */ actctx = (struct sieve_result_action_context *) - hash_table_lookup(result->action_contexts, keep ? &act_store : action); + hash_table_lookup(result->action_contexts, + ( keep ? &act_store : act_def )); if ( actctx != NULL ) { struct sieve_result_side_effect *iseff; @@ -569,7 +587,7 @@ static int _sieve_result_add_action if ( seffects != NULL ) { seff = seffects->first_effect; while ( seff != NULL ) { - if ( seff->seffect == iseff->seffect ) { + if ( seff->seffect.def == iseff->seffect.def ) { exists = TRUE; break; } @@ -583,8 +601,7 @@ static int _sieve_result_add_action /* If not present, add it */ if ( !exists ) { - sieve_side_effects_list_add - (seffects, iseff->seffect, iseff->context); + sieve_side_effects_list_add(seffects, &iseff->seffect); } iseff = iseff->next; @@ -597,12 +614,13 @@ static int _sieve_result_add_action } int sieve_result_add_action -(const struct sieve_runtime_env *renv, - const struct sieve_action *action, struct sieve_side_effects_list *seffects, - unsigned int source_line, void *context, unsigned int instance_limit) +(const struct sieve_runtime_env *renv, const struct sieve_extension *ext, + const struct sieve_action_def *act_def, + struct sieve_side_effects_list *seffects, unsigned int source_line, + void *context, unsigned int instance_limit) { return _sieve_result_add_action - (renv, action, seffects, source_line, context, instance_limit, FALSE); + (renv, ext, act_def, seffects, source_line, context, instance_limit, FALSE); } int sieve_result_add_keep @@ -610,19 +628,24 @@ int sieve_result_add_keep unsigned int source_line) { return _sieve_result_add_action - (renv, renv->result->keep_action, seffects, source_line, NULL, 0, TRUE); + (renv, renv->result->keep_action.ext, renv->result->keep_action.def, + seffects, source_line, NULL, 0, TRUE); } void sieve_result_set_keep_action -(struct sieve_result *result, const struct sieve_action *action) +(struct sieve_result *result, const struct sieve_extension *ext, + const struct sieve_action_def *act_def) { - result->keep_action = action; + result->keep_action.def = act_def; + result->keep_action.ext = ext; } void sieve_result_set_failure_action -(struct sieve_result *result, const struct sieve_action *action) +(struct sieve_result *result, const struct sieve_extension *ext, + const struct sieve_action_def *act_def) { - result->failure_action = action; + result->failure_action.def = act_def; + result->failure_action.ext = ext; } /* @@ -684,14 +707,16 @@ static void sieve_result_print_side_effects struct sieve_side_effects_list *slist, bool *implicit_keep) { struct sieve_result_side_effect *rsef; - const struct sieve_side_effect *sef; - + /* Print side effects */ rsef = slist != NULL ? slist->first_effect : NULL; while ( rsef != NULL ) { - sef = rsef->seffect; - if ( sef->print != NULL ) - sef->print(sef, action, rpenv, rsef->context, implicit_keep); + if ( rsef->seffect.def != NULL ) { + const struct sieve_side_effect *sef = &rsef->seffect; + + if ( sef->def->print != NULL ) + sef->def->print(sef, action, rpenv, implicit_keep); + } rsef = rsef->next; } } @@ -712,7 +737,7 @@ static void sieve_result_print_implicit_side_effects if ( actctx != NULL && actctx->seffects != NULL ) sieve_result_print_side_effects - (rpenv, result->keep_action, actctx->seffects, &dummy); + (rpenv, &result->keep_action, actctx->seffects, &dummy); } } @@ -720,7 +745,7 @@ bool sieve_result_print (struct sieve_result *result, const struct sieve_script_env *senv, struct ostream *stream, bool *keep) { - const struct sieve_action *act_keep = result->keep_action; + struct sieve_action act_keep = result->keep_action; struct sieve_result_print_env penv; bool implicit_keep = TRUE; struct sieve_result_action *rac, *first_action; @@ -744,15 +769,15 @@ bool sieve_result_print rac = first_action; while ( rac != NULL ) { bool impl_keep = TRUE; - const struct sieve_action *act = rac->data.action; + const struct sieve_action *act = &rac->action; if ( rac->keep && keep != NULL ) *keep = TRUE; - if ( act != NULL ) { - if ( act->print != NULL ) - act->print(act, &penv, rac->data.context, &impl_keep); + if ( act->def != NULL ) { + if ( act->def->print != NULL ) + act->def->print(act, &penv, &impl_keep); else - sieve_result_action_printf(&penv, "%s", act->name); + sieve_result_action_printf(&penv, "%s", act->def->name); } else { if ( rac->keep ) { sieve_result_action_printf(&penv, "keep"); @@ -764,7 +789,7 @@ bool sieve_result_print /* Print side effects */ sieve_result_print_side_effects - (&penv, rac->data.action, rac->seffects, &impl_keep); + (&penv, &rac->action, rac->seffects, &impl_keep); implicit_keep = implicit_keep && impl_keep; @@ -777,30 +802,29 @@ bool sieve_result_print sieve_result_printf(&penv, "\nImplicit keep:\n\n"); if ( implicit_keep ) { - bool dummy = TRUE; - if ( act_keep == NULL ) { + if ( act_keep.def == NULL ) { sieve_result_action_printf(&penv, "keep"); sieve_result_print_implicit_side_effects(&penv); } else { /* Scan for execution of keep-equal actions */ rac = result->first_action; - while ( act_keep != NULL && rac != NULL ) { - if ( rac->data.action == act_keep && act_keep->equals != NULL && - act_keep->equals(senv, NULL, rac->data.context) - && rac->data.executed ) { - act_keep = NULL; + while ( act_keep.def != NULL && rac != NULL ) { + if ( rac->action.def == act_keep.def && act_keep.def->equals != NULL + && act_keep.def->equals(senv, NULL, &rac->action) + && rac->action.executed ) { + act_keep.def = NULL; } rac = rac->next; } - if ( act_keep == NULL ) { + if ( act_keep.def == NULL ) { sieve_result_printf(&penv, " (none; keep or equivalent action executed earlier)\n"); } else { - act_keep->print(act_keep, &penv, NULL, &dummy); + act_keep.def->print(&act_keep, &penv, NULL); sieve_result_print_implicit_side_effects(&penv); } @@ -822,10 +846,9 @@ static bool _sieve_result_implicit_keep { struct sieve_result_action *rac; bool success = TRUE; - bool dummy = TRUE; struct sieve_result_side_effect *rsef, *rsef_first = NULL; void *tr_context = NULL; - const struct sieve_action *act_keep; + struct sieve_action act_keep; if ( rollback ) act_keep = result->failure_action; @@ -833,14 +856,15 @@ static bool _sieve_result_implicit_keep act_keep = result->keep_action; /* If keep is a non-action, return right away */ - if ( act_keep == NULL ) return TRUE; + if ( act_keep.def == NULL ) return TRUE; /* Scan for execution of keep-equal actions */ rac = result->first_action; while ( rac != NULL ) { - if ( rac->data.action == act_keep && act_keep->equals != NULL && - act_keep->equals(result->action_env.scriptenv, NULL, rac->data.context) && - rac->data.executed ) + if ( rac->action.def == act_keep.def && act_keep.def->equals != NULL && + act_keep.def->equals + (result->action_env.scriptenv, NULL, &rac->action) && + rac->action.executed ) return TRUE; rac = rac->next; @@ -852,57 +876,60 @@ static bool _sieve_result_implicit_keep /* Check for implicit side effects to keep action */ actctx = (struct sieve_result_action_context *) - hash_table_lookup(result->action_contexts, act_keep); + hash_table_lookup(result->action_contexts, act_keep.def); if ( actctx != NULL && actctx->seffects != NULL ) rsef_first = actctx->seffects->first_effect; } /* Start keep action */ - if ( act_keep->start != NULL ) - success = act_keep->start - (act_keep, &result->action_env, NULL, &tr_context); + if ( act_keep.def->start != NULL ) + success = act_keep.def->start + (&act_keep, &result->action_env, &tr_context); /* Execute keep action */ if ( success ) { rsef = rsef_first; while ( success && rsef != NULL ) { - const struct sieve_side_effect *sef = rsef->seffect; - if ( sef->pre_execute != NULL ) - success = success && sef->pre_execute - (sef, act_keep, &result->action_env, &rsef->context, tr_context); + struct sieve_side_effect *sef = &rsef->seffect; + + if ( sef->def->pre_execute != NULL ) + success = success && sef->def->pre_execute + (sef, &act_keep, &result->action_env, &sef->context, tr_context); rsef = rsef->next; } - if ( act_keep->execute != NULL ) - success = success && act_keep->execute - (act_keep, &result->action_env, tr_context); + if ( act_keep.def->execute != NULL ) + success = success && act_keep.def->execute + (&act_keep, &result->action_env, tr_context); rsef = rsef_first; while ( success && rsef != NULL ) { - const struct sieve_side_effect *sef = rsef->seffect; - if ( sef->post_execute != NULL ) - success = success && sef->post_execute - (sef, act_keep, &result->action_env, rsef->context, tr_context); + struct sieve_side_effect *sef = &rsef->seffect; + + if ( sef->def->post_execute != NULL ) + success = success && sef->def->post_execute + (sef, &act_keep, &result->action_env, tr_context); rsef = rsef->next; } } /* Finish keep action */ if ( success ) { - if ( act_keep->commit != NULL ) - success = act_keep->commit - (act_keep, &result->action_env, tr_context, &dummy); + bool dummy = TRUE; + + if ( act_keep.def->commit != NULL ) + success = act_keep.def->commit + (&act_keep, &result->action_env, tr_context, &dummy); rsef = rsef_first; while ( rsef != NULL ) { - const struct sieve_side_effect *sef = rsef->seffect; + struct sieve_side_effect *sef = &rsef->seffect; bool keep = TRUE; - if ( sef->post_commit != NULL ) - sef->post_commit - (sef, act_keep, &result->action_env, rsef->context, tr_context, - &keep); + if ( sef->def->post_commit != NULL ) + sef->def->post_commit + (sef, &act_keep, &result->action_env, tr_context, &keep); rsef = rsef->next; } @@ -910,8 +937,9 @@ static bool _sieve_result_implicit_keep } /* Failed, rollback */ - if ( act_keep->rollback != NULL ) - act_keep->rollback(act_keep, &result->action_env, tr_context, success); + if ( act_keep.def->rollback != NULL ) + act_keep.def->rollback + (&act_keep, &result->action_env, tr_context, success); return FALSE; } @@ -938,8 +966,8 @@ void sieve_result_mark_executed(struct sieve_result *result) rac = first_action; while ( rac != NULL ) { - if ( rac->data.action != NULL ) - rac->data.executed = TRUE; + if ( rac->action.def != NULL ) + rac->action.executed = TRUE; rac = rac->next; } @@ -974,21 +1002,19 @@ int sieve_result_execute rac = first_action; while ( success && rac != NULL ) { - const struct sieve_action *act = rac->data.action; + struct sieve_action *act = &rac->action; /* Skip non-actions (inactive keep) and executed ones */ - if ( act == NULL || rac->data.executed ) { + if ( act->def == NULL || act->executed ) { rac = rac->next; continue; } - if ( act->start != NULL ) { - rac->success = act->start(act, &result->action_env, rac->data.context, - &rac->tr_context); + if ( act->def->start != NULL ) { + rac->success = act->def->start + (act, &result->action_env, &rac->tr_context); success = success && rac->success; - } else { - rac->tr_context = rac->data.context; - } + } rac = rac->next; } @@ -1000,12 +1026,12 @@ int sieve_result_execute last_attempted = rac; rac = first_action; while ( success && rac != NULL ) { - const struct sieve_action *act = rac->data.action; + struct sieve_action *act = &rac->action; struct sieve_result_side_effect *rsef; - const struct sieve_side_effect *sef; + struct sieve_side_effect *sef; /* Skip non-actions (inactive keep) and executed ones */ - if ( act == NULL || rac->data.executed ) { + if ( act->def == NULL || act->executed ) { rac = rac->next; continue; } @@ -1013,26 +1039,27 @@ int sieve_result_execute /* Execute pre-execute event of side effects */ rsef = rac->seffects != NULL ? rac->seffects->first_effect : NULL; while ( success && rsef != NULL ) { - sef = rsef->seffect; - if ( sef->pre_execute != NULL ) - success = success & sef->pre_execute - (sef, act, &result->action_env, &rsef->context, rac->tr_context); + sef = &rsef->seffect; + if ( sef->def != NULL && sef->def->pre_execute != NULL ) + success = success & sef->def->pre_execute + (sef, act, &result->action_env, &sef->context, rac->tr_context); rsef = rsef->next; } /* Execute the action itself */ - if ( success && act->execute != NULL ) { - rac->success = act->execute(act, &result->action_env, rac->tr_context); + if ( success && act->def != NULL && act->def->execute != NULL ) { + rac->success = act->def->execute + (act, &result->action_env, rac->tr_context); success = success && rac->success; } /* Execute post-execute event of side effects */ rsef = rac->seffects != NULL ? rac->seffects->first_effect : NULL; while ( success && rsef != NULL ) { - sef = rsef->seffect; - if ( sef->post_execute != NULL ) - success = success && sef->post_execute - (sef, act, &result->action_env, rsef->context, rac->tr_context); + sef = &rsef->seffect; + if ( sef->def != NULL && sef->def->post_execute != NULL ) + success = success && sef->def->post_execute + (sef, act, &result->action_env, rac->tr_context); rsef = rsef->next; } @@ -1046,9 +1073,9 @@ int sieve_result_execute commit_ok = success; rac = first_action; while ( rac != NULL && rac != last_attempted ) { - const struct sieve_action *act = rac->data.action; + struct sieve_action *act = &rac->action; struct sieve_result_side_effect *rsef; - const struct sieve_side_effect *sef; + struct sieve_side_effect *sef; if ( success ) { bool impl_keep = TRUE; @@ -1056,47 +1083,46 @@ int sieve_result_execute if ( rac->keep && keep != NULL ) *keep = TRUE; /* Skip non-actions (inactive keep) and executed ones */ - if ( act == NULL || rac->data.executed ) { + if ( act->def == NULL || act->executed ) { rac = rac->next; continue; } - if ( act->commit != NULL ) { - rac->data.executed = act->commit + if ( act->def->commit != NULL ) { + act->executed = act->def->commit (act, &result->action_env, rac->tr_context, &impl_keep); - commit_ok = rac->data.executed && commit_ok; + commit_ok = act->executed && commit_ok; } /* Execute post_commit event of side effects */ rsef = rac->seffects != NULL ? rac->seffects->first_effect : NULL; while ( rsef != NULL ) { - sef = rsef->seffect; - if ( sef->post_commit != NULL ) - sef->post_commit - (sef, act, &result->action_env, rsef->context, rac->tr_context, - &impl_keep); + sef = &rsef->seffect; + if ( sef->def->post_commit != NULL ) + sef->def->post_commit + (sef, act, &result->action_env, rac->tr_context, &impl_keep); rsef = rsef->next; } implicit_keep = implicit_keep && impl_keep; } else { /* Skip non-actions (inactive keep) and executed ones */ - if ( act == NULL || rac->data.executed ) { + if ( act->def == NULL || act->executed ) { rac = rac->next; continue; } - if ( act->rollback != NULL ) - act->rollback(act, &result->action_env, rac->tr_context, rac->success); + if ( act->def->rollback != NULL ) + act->def->rollback + (act, &result->action_env, rac->tr_context, rac->success); /* Rollback side effects */ rsef = rac->seffects != NULL ? rac->seffects->first_effect : NULL; while ( rsef != NULL ) { - sef = rsef->seffect; - if ( sef->rollback != NULL ) - sef->rollback - (sef, act, &result->action_env, rsef->context, rac->tr_context, - rac->success); + sef = &rsef->seffect; + if ( sef->def && sef->def->rollback != NULL ) + sef->def->rollback + (sef, act, &result->action_env, rac->tr_context, rac->success); rsef = rsef->next; } } @@ -1150,7 +1176,7 @@ struct sieve_result_iterate_context *sieve_result_iterate_init } const struct sieve_action *sieve_result_iterate_next - (struct sieve_result_iterate_context *rictx, bool *keep, void **context) +(struct sieve_result_iterate_context *rictx, bool *keep) { struct sieve_result_action *rac; @@ -1163,11 +1189,8 @@ const struct sieve_action *sieve_result_iterate_next if ( keep != NULL ) *keep = rac->keep; - - if ( context != NULL ) - *context = rac->data.context; - return rac->data.action; + return &rac->action; } return NULL; @@ -1191,23 +1214,21 @@ struct sieve_side_effects_list *sieve_side_effects_list_create }; void sieve_side_effects_list_add -(struct sieve_side_effects_list *list, const struct sieve_side_effect *seffect, - void *context) +(struct sieve_side_effects_list *list, const struct sieve_side_effect *seffect) { struct sieve_result_side_effect *reffect; /* Prevent duplicates */ reffect = list->first_effect; while ( reffect != NULL ) { - if ( reffect->seffect == seffect ) return; + if ( reffect->seffect.def == seffect->def ) return; reffect = reffect->next; } /* Create new side effect object */ reffect = p_new(list->result->pool, struct sieve_result_side_effect, 1); - reffect->seffect = seffect; - reffect->context = context; + reffect->seffect = *seffect; /* Add */ if ( list->first_effect == NULL ) { diff --git a/src/lib-sieve/sieve-result.h b/src/lib-sieve/sieve-result.h index d60a63154..dd45e91ae 100644 --- a/src/lib-sieve/sieve-result.h +++ b/src/lib-sieve/sieve-result.h @@ -19,7 +19,8 @@ struct sieve_side_effects_list; struct sieve_result; struct sieve_result *sieve_result_create - (const struct sieve_message_data *msgdata, const struct sieve_script_env *senv, + (struct sieve_instance *svinst, const struct sieve_message_data *msgdata, + const struct sieve_script_env *senv, struct sieve_error_handler *ehandler); void sieve_result_ref(struct sieve_result *result); @@ -99,11 +100,13 @@ void sieve_result_error */ void sieve_result_add_implicit_side_effect -(struct sieve_result *result, const struct sieve_action *to_action, - bool to_keep, const struct sieve_side_effect *seffect, void *context); +(struct sieve_result *result, const struct sieve_action_def *to_action, + bool to_keep, const struct sieve_extension *ext, + const struct sieve_side_effect_def *seffect, void *context); int sieve_result_add_action - (const struct sieve_runtime_env *renv, const struct sieve_action *action, + (const struct sieve_runtime_env *renv, const struct sieve_extension *ext, + const struct sieve_action_def *act_def, struct sieve_side_effects_list *seffects, unsigned int source_line, void *context, unsigned int instance_limit); int sieve_result_add_keep @@ -111,9 +114,11 @@ int sieve_result_add_keep struct sieve_side_effects_list *seffects, unsigned int source_line); void sieve_result_set_keep_action - (struct sieve_result *result, const struct sieve_action *action); + (struct sieve_result *result, const struct sieve_extension *ext, + const struct sieve_action_def *act_def); void sieve_result_set_failure_action - (struct sieve_result *result, const struct sieve_action *action); + (struct sieve_result *result, const struct sieve_extension *ext, + const struct sieve_action_def *act_def); /* * Result execution @@ -134,7 +139,7 @@ struct sieve_result_iterate_context; struct sieve_result_iterate_context *sieve_result_iterate_init (struct sieve_result *result); const struct sieve_action *sieve_result_iterate_next - (struct sieve_result_iterate_context *rictx, bool *keep, void **context); + (struct sieve_result_iterate_context *rictx, bool *keep); /* * Side effects list @@ -143,7 +148,7 @@ const struct sieve_action *sieve_result_iterate_next struct sieve_side_effects_list *sieve_side_effects_list_create (struct sieve_result *result); void sieve_side_effects_list_add -(struct sieve_side_effects_list *list, const struct sieve_side_effect *seffect, - void *context); + (struct sieve_side_effects_list *list, + const struct sieve_side_effect *seffect); #endif diff --git a/src/lib-sieve/sieve-script-private.h b/src/lib-sieve/sieve-script-private.h index 6da33627a..228ffeb89 100644 --- a/src/lib-sieve/sieve-script-private.h +++ b/src/lib-sieve/sieve-script-private.h @@ -14,6 +14,8 @@ struct sieve_script { pool_t pool; unsigned int refcount; + struct sieve_instance *svinst; + struct stat st; struct stat lnk_st; time_t mtime; @@ -34,7 +36,8 @@ struct sieve_script { }; struct sieve_script *sieve_script_init -(struct sieve_script *script, const char *path, const char *name, - struct sieve_error_handler *ehandler, bool *exists_r); +(struct sieve_script *script, struct sieve_instance *svinst, + const char *path, const char *name, struct sieve_error_handler *ehandler, + bool *exists_r); #endif /* __SIEVE_SCRIPT_PRIVATE_H */ diff --git a/src/lib-sieve/sieve-script.c b/src/lib-sieve/sieve-script.c index d11e679b4..de53dd27e 100644 --- a/src/lib-sieve/sieve-script.c +++ b/src/lib-sieve/sieve-script.c @@ -63,8 +63,9 @@ static inline const char *_sieve_scriptfile_from_name(const char *name) */ struct sieve_script *sieve_script_init -(struct sieve_script *script, const char *path, const char *name, - struct sieve_error_handler *ehandler, bool *exists_r) +(struct sieve_script *script, struct sieve_instance *svinst, + const char *path, const char *name, struct sieve_error_handler *ehandler, + bool *exists_r) { int ret; pool_t pool; @@ -156,6 +157,8 @@ struct sieve_script *sieve_script_init pool = script->pool; script->refcount = 1; + script->svinst = svinst; + script->ehandler = ehandler; sieve_error_handler_ref(ehandler); @@ -178,15 +181,15 @@ struct sieve_script *sieve_script_init } struct sieve_script *sieve_script_create -(const char *path, const char *name, +(struct sieve_instance *svinst, const char *path, const char *name, struct sieve_error_handler *ehandler, bool *exists_r) { - return sieve_script_init(NULL, path, name, ehandler, exists_r); + return sieve_script_init(NULL, svinst, path, name, ehandler, exists_r); } struct sieve_script *sieve_script_create_in_directory -(const char *dirpath, const char *name, - struct sieve_error_handler *ehandler, bool *exists_r) +(struct sieve_instance *svinst, const char *dirpath, const char *name, + struct sieve_error_handler *ehandler, bool *exists_r) { const char *path; @@ -197,7 +200,7 @@ struct sieve_script *sieve_script_create_in_directory path = t_strconcat(dirpath, "/", _sieve_scriptfile_from_name(name), NULL); - return sieve_script_init(NULL, path, name, ehandler, exists_r); + return sieve_script_init(NULL, svinst, path, name, ehandler, exists_r); } void sieve_script_ref(struct sieve_script *script) @@ -256,6 +259,11 @@ mode_t sieve_script_permissions(const struct sieve_script *script) return script->st.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO); } +struct sieve_instance *sieve_script_svinst(const struct sieve_script *script) +{ + return script->svinst; +} + /* * Stream manageement */ diff --git a/src/lib-sieve/sieve-script.h b/src/lib-sieve/sieve-script.h index cd8f629ac..8ec7eb7fb 100644 --- a/src/lib-sieve/sieve-script.h +++ b/src/lib-sieve/sieve-script.h @@ -15,11 +15,11 @@ struct sieve_script; struct sieve_script *sieve_script_create - (const char *path, const char *name, + (struct sieve_instance *svinst, const char *path, const char *name, struct sieve_error_handler *ehandler, bool *exists_r); struct sieve_script *sieve_script_create_in_directory - (const char *dirpath, const char *name, + (struct sieve_instance *svinst, const char *dirpath, const char *name, struct sieve_error_handler *ehandler, bool *exists_r); void sieve_script_ref(struct sieve_script *script); @@ -43,6 +43,8 @@ const char *sieve_script_dirpath(const struct sieve_script *script); mode_t sieve_script_permissions(const struct sieve_script *script); +struct sieve_instance *sieve_script_svinst(const struct sieve_script *script); + /* * Stream management */ diff --git a/src/lib-sieve/sieve-types.h b/src/lib-sieve/sieve-types.h index c0f56cfbb..f268c4b06 100644 --- a/src/lib-sieve/sieve-types.h +++ b/src/lib-sieve/sieve-types.h @@ -15,6 +15,9 @@ * Forward declarations */ +struct sieve_instance; +struct sieve_callbacks; + struct sieve_script; struct sieve_binary; @@ -22,6 +25,14 @@ struct sieve_message_data; struct sieve_script_env; struct sieve_exec_status; +/* + * Callbacks + */ + +struct sieve_callbacks { + const char *(*get_setting)(void *context, const char *identifier); +}; + /* * Message data * diff --git a/src/lib-sieve/sieve-validator.c b/src/lib-sieve/sieve-validator.c index 2bd49741e..c262671e2 100644 --- a/src/lib-sieve/sieve-validator.c +++ b/src/lib-sieve/sieve-validator.c @@ -24,9 +24,9 @@ */ static void sieve_validator_register_core_commands - (struct sieve_validator *validator); + (struct sieve_validator *valdtr); static void sieve_validator_register_core_tests - (struct sieve_validator *validator); + (struct sieve_validator *valdtr); /* * Types @@ -35,7 +35,9 @@ static void sieve_validator_register_core_tests /* Tag registration */ struct sieve_tag_registration { - const struct sieve_argument *tag; + const struct sieve_argument_def *tag_def; + const struct sieve_extension *ext; + const char *identifier; int id_code; }; @@ -43,7 +45,8 @@ struct sieve_tag_registration { /* Command registration */ struct sieve_command_registration { - const struct sieve_command *command; + const struct sieve_command_def *cmd_def; + const struct sieve_extension *ext; ARRAY_DEFINE(normal_tags, struct sieve_tag_registration *); ARRAY_DEFINE(instanced_tags, struct sieve_tag_registration *); @@ -53,7 +56,9 @@ struct sieve_command_registration { /* Default (literal) arguments */ struct sieve_default_argument { - const struct sieve_argument *argument; + const struct sieve_argument_def *arg_def; + const struct sieve_extension *ext; + struct sieve_default_argument *overrides; }; @@ -62,7 +67,8 @@ struct sieve_default_argument { */ struct sieve_validator_extension_reg { - const struct sieve_validator_extension *val_ext; + const struct sieve_validator_extension *valext; + const struct sieve_extension *ext; struct sieve_ast_argument *arg; void *context; @@ -76,6 +82,7 @@ struct sieve_validator_extension_reg { struct sieve_validator { pool_t pool; + struct sieve_instance *svinst; struct sieve_ast *ast; struct sieve_script *script; @@ -103,41 +110,41 @@ struct sieve_validator { */ void sieve_validator_warning -(struct sieve_validator *validator, unsigned int source_line, +(struct sieve_validator *valdtr, unsigned int source_line, const char *fmt, ...) { va_list args; va_start(args, fmt); - sieve_vwarning(validator->ehandler, - sieve_error_script_location(validator->script, source_line), + sieve_vwarning(valdtr->ehandler, + sieve_error_script_location(valdtr->script, source_line), fmt, args); va_end(args); } void sieve_validator_error -(struct sieve_validator *validator, unsigned int source_line, +(struct sieve_validator *valdtr, unsigned int source_line, const char *fmt, ...) { va_list args; va_start(args, fmt); - sieve_verror(validator->ehandler, - sieve_error_script_location(validator->script, source_line), + sieve_verror(valdtr->ehandler, + sieve_error_script_location(valdtr->script, source_line), fmt, args); va_end(args); } void sieve_validator_critical -(struct sieve_validator *validator, unsigned int source_line, +(struct sieve_validator *valdtr, unsigned int source_line, const char *fmt, ...) { va_list args; va_start(args, fmt); - sieve_vcritical(validator->ehandler, - sieve_error_script_location(validator->script, source_line), + sieve_vcritical(valdtr->ehandler, + sieve_error_script_location(valdtr->script, source_line), fmt, args); va_end(args); } @@ -149,98 +156,109 @@ void sieve_validator_critical struct sieve_validator *sieve_validator_create (struct sieve_ast *ast, struct sieve_error_handler *ehandler) { - unsigned int i; pool_t pool; - struct sieve_validator *validator; + struct sieve_validator *valdtr; + const struct sieve_extension *const *ext_preloaded; + unsigned int i, ext_count; pool = pool_alloconly_create("sieve_validator", 8192); - validator = p_new(pool, struct sieve_validator, 1); - validator->pool = pool; + valdtr = p_new(pool, struct sieve_validator, 1); + valdtr->pool = pool; - validator->ehandler = ehandler; + valdtr->ehandler = ehandler; sieve_error_handler_ref(ehandler); - validator->ast = ast; - validator->script = sieve_ast_script(ast); + valdtr->ast = ast; sieve_ast_ref(ast); + valdtr->script = sieve_ast_script(ast); + valdtr->svinst = sieve_script_svinst(valdtr->script); + /* Setup default arguments */ - validator->default_arguments[SAT_NUMBER]. - argument = &number_argument; - validator->default_arguments[SAT_VAR_STRING]. - argument = &string_argument; - validator->default_arguments[SAT_CONST_STRING]. - argument = &string_argument; - validator->default_arguments[SAT_STRING_LIST]. - argument = &string_list_argument; + valdtr->default_arguments[SAT_NUMBER].arg_def = &number_argument; + valdtr->default_arguments[SAT_NUMBER].ext = NULL; + valdtr->default_arguments[SAT_VAR_STRING].arg_def = &string_argument; + valdtr->default_arguments[SAT_VAR_STRING].ext = NULL; + valdtr->default_arguments[SAT_CONST_STRING].arg_def = &string_argument; + valdtr->default_arguments[SAT_CONST_STRING].ext = NULL; + valdtr->default_arguments[SAT_STRING_LIST].arg_def = &string_list_argument; + valdtr->default_arguments[SAT_STRING_LIST].ext = NULL; /* Setup storage for extension contexts */ - p_array_init(&validator->extensions, pool, sieve_extensions_get_count()); + p_array_init(&valdtr->extensions, pool, + sieve_extensions_get_count(valdtr->svinst)); /* Setup command registry */ - validator->commands = hash_table_create + valdtr->commands = hash_table_create (default_pool, pool, 0, strcase_hash, (hash_cmp_callback_t *)strcasecmp); - sieve_validator_register_core_commands(validator); - sieve_validator_register_core_tests(validator); - - /* Pre-load core language features implemented as 'extensions' */ - for ( i = 0; i < sieve_preloaded_extensions_count; i++ ) { - const struct sieve_extension *ext = sieve_preloaded_extensions[i]; + sieve_validator_register_core_commands(valdtr); + sieve_validator_register_core_tests(valdtr); - if ( ext->validator_load != NULL ) - (void)ext->validator_load(validator); + /* Pre-load core language features implemented as 'extensions' */ + ext_preloaded = sieve_extensions_get_preloaded(valdtr->svinst, &ext_count); + for ( i = 0; i < ext_count; i++ ) { + const struct sieve_extension_def *ext_def = ext_preloaded[i]->def; + + if ( ext_def != NULL && ext_def->validator_load != NULL ) + (void)ext_def->validator_load(ext_preloaded[i], valdtr); } - - return validator; + + return valdtr; } -void sieve_validator_free(struct sieve_validator **validator) +void sieve_validator_free(struct sieve_validator **valdtr) { const struct sieve_validator_extension_reg *extrs; unsigned int ext_count, i; - hash_table_destroy(&(*validator)->commands); - sieve_ast_unref(&(*validator)->ast); + hash_table_destroy(&(*valdtr)->commands); + sieve_ast_unref(&(*valdtr)->ast); - sieve_error_handler_unref(&(*validator)->ehandler); + sieve_error_handler_unref(&(*valdtr)->ehandler); /* Signal registered extensions that the validator is being destroyed */ - extrs = array_get(&(*validator)->extensions, &ext_count); + extrs = array_get(&(*valdtr)->extensions, &ext_count); for ( i = 0; i < ext_count; i++ ) { - if ( extrs[i].val_ext != NULL && extrs[i].val_ext->free != NULL ) - extrs[i].val_ext->free(*validator, extrs[i].context); + if ( extrs[i].valext != NULL && extrs[i].valext->free != NULL ) + extrs[i].valext->free(extrs[i].ext, *valdtr, extrs[i].context); } - pool_unref(&(*validator)->pool); + pool_unref(&(*valdtr)->pool); - *validator = NULL; + *valdtr = NULL; } /* * Accessors */ -pool_t sieve_validator_pool(struct sieve_validator *validator) +pool_t sieve_validator_pool(struct sieve_validator *valdtr) { - return validator->pool; + return valdtr->pool; } struct sieve_error_handler *sieve_validator_error_handler -(struct sieve_validator *validator) +(struct sieve_validator *valdtr) { - return validator->ehandler; + return valdtr->ehandler; } struct sieve_ast *sieve_validator_ast -(struct sieve_validator *validator) +(struct sieve_validator *valdtr) { - return validator->ast; + return valdtr->ast; } struct sieve_script *sieve_validator_script -(struct sieve_validator *validator) +(struct sieve_validator *valdtr) { - return validator->script; + return valdtr->script; +} + +struct sieve_instance *sieve_validator_svinst +(struct sieve_validator *valdtr) +{ + return valdtr->svinst; } /* @@ -250,14 +268,14 @@ struct sieve_script *sieve_validator_script /* Dummy command object to mark unknown commands in the registry */ static bool _cmd_unknown_validate -(struct sieve_validator *validator ATTR_UNUSED, - struct sieve_command_context *cmd ATTR_UNUSED) +(struct sieve_validator *valdtr ATTR_UNUSED, + struct sieve_command *cmd ATTR_UNUSED) { i_unreached(); return FALSE; } -static const struct sieve_command unknown_command = { +static const struct sieve_command_def unknown_command = { "", SCT_NONE, 0, 0, FALSE, FALSE , NULL, NULL, _cmd_unknown_validate, NULL, NULL }; @@ -265,22 +283,22 @@ static const struct sieve_command unknown_command = { /* Registration of the core commands of the language */ static void sieve_validator_register_core_tests -(struct sieve_validator *validator) +(struct sieve_validator *valdtr) { unsigned int i; for ( i = 0; i < sieve_core_tests_count; i++ ) { - sieve_validator_register_command(validator, sieve_core_tests[i]); + sieve_validator_register_command(valdtr, NULL, sieve_core_tests[i]); } } static void sieve_validator_register_core_commands -(struct sieve_validator *validator) +(struct sieve_validator *valdtr) { unsigned int i; for ( i = 0; i < sieve_core_commands_count; i++ ) { - sieve_validator_register_command(validator, sieve_core_commands[i]); + sieve_validator_register_command(valdtr, NULL, sieve_core_commands[i]); } } @@ -288,54 +306,61 @@ static void sieve_validator_register_core_commands static struct sieve_command_registration * sieve_validator_find_command_registration -(struct sieve_validator *validator, const char *command) +(struct sieve_validator *valdtr, const char *command) { return (struct sieve_command_registration *) - hash_table_lookup(validator->commands, command); + hash_table_lookup(valdtr->commands, command); } static struct sieve_command_registration *_sieve_validator_register_command -(struct sieve_validator *validator, const struct sieve_command *command, - const char *identifier) +(struct sieve_validator *valdtr, const struct sieve_extension *ext, + const struct sieve_command_def *cmd_def, const char *identifier) { - struct sieve_command_registration *record = - p_new(validator->pool, struct sieve_command_registration, 1); - record->command = command; - hash_table_insert(validator->commands, (void *) identifier, (void *) record); + struct sieve_command_registration *cmd_reg = + p_new(valdtr->pool, struct sieve_command_registration, 1); + + cmd_reg->cmd_def = cmd_def; + cmd_reg->ext = ext; + + hash_table_insert(valdtr->commands, (void *) identifier, (void *) cmd_reg); - return record; + return cmd_reg; } void sieve_validator_register_command -(struct sieve_validator *validator, const struct sieve_command *command) +(struct sieve_validator *valdtr, const struct sieve_extension *ext, + const struct sieve_command_def *cmd_def) { struct sieve_command_registration *cmd_reg = - sieve_validator_find_command_registration(validator, command->identifier); + sieve_validator_find_command_registration(valdtr, cmd_def->identifier); if ( cmd_reg == NULL ) cmd_reg = _sieve_validator_register_command - (validator, command, command->identifier); - else - cmd_reg->command = command; + (valdtr, ext, cmd_def, cmd_def->identifier); + else { + cmd_reg->cmd_def = cmd_def; + cmd_reg->ext = ext; + } - if ( command->registered != NULL ) - command->registered(validator, cmd_reg); + if ( cmd_def->registered != NULL ) + cmd_def->registered(valdtr, ext, cmd_reg); } static void sieve_validator_register_unknown_command -(struct sieve_validator *validator, const char *command) +(struct sieve_validator *valdtr, const char *command) { - (void)_sieve_validator_register_command(validator, &unknown_command, command); + (void)_sieve_validator_register_command + (valdtr, NULL, &unknown_command, command); } -const struct sieve_command *sieve_validator_find_command -(struct sieve_validator *validator, const char *command) +/*const struct sieve_command *sieve_validator_find_command +(struct sieve_validator *valdtr, const char *command) { - struct sieve_command_registration *record = - sieve_validator_find_command_registration(validator, command); + struct sieve_command_registration *cmd_reg = + sieve_validator_find_command_registration(valdtr, command); return ( record == NULL ? NULL : record->command ); -} +}*/ /* * Per-command tagged argument registry @@ -344,147 +369,152 @@ const struct sieve_command *sieve_validator_find_command /* Dummy argument object to mark unknown arguments in the registry */ static bool _unknown_tag_validate -(struct sieve_validator *validator ATTR_UNUSED, +(struct sieve_validator *valdtr ATTR_UNUSED, struct sieve_ast_argument **arg ATTR_UNUSED, - struct sieve_command_context *tst ATTR_UNUSED) + struct sieve_command *tst ATTR_UNUSED) { i_unreached(); return FALSE; } -static const struct sieve_argument _unknown_tag = { +static const struct sieve_argument_def _unknown_tag = { "", - NULL, NULL, + NULL, _unknown_tag_validate, - NULL, NULL + NULL, NULL, NULL }; +static inline bool _tag_registration_is_unknown +(struct sieve_tag_registration *tag_reg) +{ + return ( tag_reg != NULL && tag_reg->tag_def == &_unknown_tag ); +} + /* Registry functions */ static void _sieve_validator_register_tag -(struct sieve_validator *validator, struct sieve_command_registration *cmd_reg, - const struct sieve_argument *tag, const char *identifier, int id_code) +(struct sieve_validator *valdtr, struct sieve_command_registration *cmd_reg, + const struct sieve_extension *ext, const struct sieve_argument_def *tag_def, + const char *identifier, int id_code) { struct sieve_tag_registration *reg; - reg = p_new(validator->pool, struct sieve_tag_registration, 1); - reg->tag = tag; + reg = p_new(valdtr->pool, struct sieve_tag_registration, 1); + reg->ext = ext; + reg->tag_def = tag_def; reg->id_code = id_code; if ( identifier == NULL ) - reg->identifier = tag->identifier; + reg->identifier = tag_def->identifier; else - reg->identifier = p_strdup(validator->pool, identifier); + reg->identifier = p_strdup(valdtr->pool, identifier); if ( !array_is_created(&cmd_reg->normal_tags) ) - p_array_init(&cmd_reg->normal_tags, validator->pool, 4); + p_array_init(&cmd_reg->normal_tags, valdtr->pool, 4); array_append(&cmd_reg->normal_tags, ®, 1); } void sieve_validator_register_persistent_tag -(struct sieve_validator *validator, const struct sieve_argument *tag, - const char *command) -{ - struct sieve_command_registration *cmd_reg = - sieve_validator_find_command_registration(validator, command); - struct sieve_tag_registration *reg = - p_new(validator->pool, struct sieve_tag_registration, 1); - - reg->tag = tag; - reg->id_code = -1; - - if ( cmd_reg == NULL ) { - cmd_reg = _sieve_validator_register_command(validator, NULL, command); - } - +(struct sieve_validator *valdtr, const char *command, + const struct sieve_extension *ext, const struct sieve_argument_def *tag_def) +{ /* Add the tag to the persistent tags list if necessary */ - if ( tag->validate_persistent != NULL ) { + if ( tag_def->validate_persistent != NULL ) { + struct sieve_command_registration *cmd_reg = + sieve_validator_find_command_registration(valdtr, command); + + if ( cmd_reg == NULL ) { + cmd_reg = _sieve_validator_register_command(valdtr, NULL, NULL, command); + } + + struct sieve_tag_registration *reg; + + reg = p_new(valdtr->pool, struct sieve_tag_registration, 1); + reg->ext = ext; + reg->tag_def = tag_def; + reg->id_code = -1; + if ( !array_is_created(&cmd_reg->persistent_tags) ) - p_array_init(&cmd_reg->persistent_tags, validator->pool, 4); + p_array_init(&cmd_reg->persistent_tags, valdtr->pool, 4); array_append(&cmd_reg->persistent_tags, ®, 1); } } void sieve_validator_register_external_tag -(struct sieve_validator *validator, const struct sieve_argument *tag, - const char *command, int id_code) +(struct sieve_validator *valdtr, const char *command, + const struct sieve_extension *ext, const struct sieve_argument_def *tag_def, + int id_code) { struct sieve_command_registration *cmd_reg = - sieve_validator_find_command_registration(validator, command); + sieve_validator_find_command_registration(valdtr, command); if ( cmd_reg == NULL ) { - cmd_reg = _sieve_validator_register_command(validator, NULL, command); + cmd_reg = _sieve_validator_register_command(valdtr, NULL, NULL, command); } _sieve_validator_register_tag - (validator, cmd_reg, tag, NULL, id_code); + (valdtr, cmd_reg, ext, tag_def, NULL, id_code); } void sieve_validator_register_tag -(struct sieve_validator *validator, struct sieve_command_registration *cmd_reg, - const struct sieve_argument *tag, int id_code) +(struct sieve_validator *valdtr, struct sieve_command_registration *cmd_reg, + const struct sieve_extension *ext, const struct sieve_argument_def *tag_def, + int id_code) { - if ( tag->is_instance_of == NULL ) - _sieve_validator_register_tag(validator, cmd_reg, tag, NULL, id_code); + if ( tag_def->is_instance_of == NULL ) + _sieve_validator_register_tag(valdtr, cmd_reg, ext, tag_def, NULL, id_code); else { struct sieve_tag_registration *reg = - p_new(validator->pool, struct sieve_tag_registration, 1); - reg->tag = tag; + p_new(valdtr->pool, struct sieve_tag_registration, 1); + reg->ext = ext; + reg->tag_def = tag_def; reg->id_code = id_code; if ( !array_is_created(&cmd_reg->instanced_tags) ) - p_array_init(&cmd_reg->instanced_tags, validator->pool, 4); + p_array_init(&cmd_reg->instanced_tags, valdtr->pool, 4); array_append(&cmd_reg->instanced_tags, ®, 1); } } static void sieve_validator_register_unknown_tag -(struct sieve_validator *validator, struct sieve_command_registration *cmd_reg, +(struct sieve_validator *valdtr, struct sieve_command_registration *cmd_reg, const char *tag) { - _sieve_validator_register_tag(validator, cmd_reg, &_unknown_tag, tag, 0); + _sieve_validator_register_tag(valdtr, cmd_reg, NULL, &_unknown_tag, tag, 0); } -static const struct sieve_argument *sieve_validator_find_tag -(struct sieve_validator *valdtr, struct sieve_command_context *cmd, - struct sieve_ast_argument *arg, int *id_code) +static struct sieve_tag_registration *_sieve_validator_command_tag_get +(struct sieve_validator *valdtr, struct sieve_command *cmd, + const char *tag, void **data) { - struct sieve_command_registration *cmd_reg = cmd->cmd_reg; - const char *tag = sieve_ast_argument_tag(arg); - unsigned int i; - - if ( id_code != NULL ) - *id_code = 0; - + struct sieve_command_registration *cmd_reg = cmd->reg; + struct sieve_tag_registration * const *regs; + unsigned int i, reg_count; + /* First check normal tags */ if ( array_is_created(&cmd_reg->normal_tags) ) { - for ( i = 0; i < array_count(&cmd_reg->normal_tags); i++ ) { - struct sieve_tag_registration * const *reg = - array_idx(&cmd_reg->normal_tags, i); + regs = array_get(&cmd_reg->normal_tags, ®_count); - if ( (*reg)->tag != NULL && strcasecmp((*reg)->identifier,tag) == 0) { - if ( id_code != NULL ) - *id_code = (*reg)->id_code; + for ( i = 0; i < reg_count; i++ ) { + if ( regs[i]->tag_def != NULL && + strcasecmp(regs[i]->identifier, tag) == 0) { - return (*reg)->tag; + return regs[i]; } } } /* Not found so far, try the instanced tags */ if ( array_is_created(&cmd_reg->instanced_tags) ) { - for ( i = 0; i < array_count(&cmd_reg->instanced_tags); i++ ) { - struct sieve_tag_registration * const *reg = - array_idx(&cmd_reg->instanced_tags, i); - - if ( (*reg)->tag != NULL && - (*reg)->tag->is_instance_of(valdtr, cmd, arg) ) { - if ( id_code != NULL ) - *id_code = (*reg)->id_code; - - return (*reg)->tag; + regs = array_get(&cmd_reg->instanced_tags, ®_count); + + for ( i = 0; i < reg_count; i++ ) { + if ( regs[i]->tag_def != NULL ) { + if ( regs[i]->tag_def->is_instance_of + (valdtr, cmd, regs[i]->ext, tag, data) ) + return regs[i]; } } } @@ -492,18 +522,19 @@ static const struct sieve_argument *sieve_validator_find_tag return NULL; } -static const struct sieve_argument *sieve_validator_find_tag_by_identifier -(struct sieve_validator *valdtr, struct sieve_command_context *cmd, - const char *tag) +static bool sieve_validator_command_tag_exists +(struct sieve_validator *valdtr, struct sieve_command *cmd, const char *tag) { - struct sieve_ast_argument *arg; + return ( _sieve_validator_command_tag_get(valdtr, cmd, tag, NULL) != NULL ); +} - /* Construct dummy argument */ - arg = t_new(struct sieve_ast_argument, 1); - arg->type = SAAT_TAG; - arg->_value.tag = tag; +static struct sieve_tag_registration *sieve_validator_command_tag_get +(struct sieve_validator *valdtr, struct sieve_command *cmd, + struct sieve_ast_argument *arg, void **data) +{ + const char *tag = sieve_ast_argument_tag(arg); - return sieve_validator_find_tag(valdtr, cmd, arg, NULL); + return _sieve_validator_command_tag_get(valdtr, cmd, tag, data); } /* @@ -511,25 +542,25 @@ static const struct sieve_argument *sieve_validator_find_tag_by_identifier */ const struct sieve_extension *sieve_validator_extension_load -(struct sieve_validator *valdtr, struct sieve_command_context *cmd, +(struct sieve_validator *valdtr, struct sieve_command *cmd, struct sieve_ast_argument *ext_arg, string_t *ext_name) { - int ext_id; struct sieve_validator_extension_reg *reg; const struct sieve_extension *ext; + const struct sieve_extension_def *extdef; const char *name = str_c(ext_name); if ( str_len(ext_name) > 128 ) { sieve_argument_validate_error(valdtr, ext_arg, "%s %s: unknown Sieve capability '%s' (name is impossibly long)", - cmd->command->identifier, sieve_command_type_name(cmd->command), + sieve_command_identifier(cmd), sieve_command_type_name(cmd), str_sanitize(name, 128)); return NULL; } - ext = sieve_extension_get_by_name(name); + ext = sieve_extension_get_by_name(valdtr->svinst, name); - if ( ext == NULL ) { + if ( ext == NULL || ext->def == NULL ) { unsigned int i; bool core_test = FALSE; bool core_command = FALSE; @@ -546,14 +577,14 @@ const struct sieve_extension *sieve_validator_extension_load if ( core_test || core_command ) { sieve_argument_validate_error(valdtr, ext_arg, - "%s %s: '%s' is not known as a Sieve capability, " + "%s %s: '%s' is not known as a Sieve capability, " "but it is known as a Sieve %s that is always available", - cmd->command->identifier, sieve_command_type_name(cmd->command), - name, ( core_test ? "test" : "command" )); + sieve_command_identifier(cmd), sieve_command_type_name(cmd), + name, ( core_test ? "test" : "command" )); } else { sieve_argument_validate_error(valdtr, ext_arg, "%s %s: unknown Sieve capability '%s'", - cmd->command->identifier, sieve_command_type_name(cmd->command), + sieve_command_identifier(cmd), sieve_command_type_name(cmd), name); } return NULL; @@ -561,18 +592,21 @@ const struct sieve_extension *sieve_validator_extension_load sieve_ast_extension_link(valdtr->ast, ext); - if ( ext->validator_load != NULL && !ext->validator_load(valdtr) ) { + extdef = ext->def; + + if ( extdef->validator_load != NULL && + !extdef->validator_load(ext, valdtr) ) { sieve_argument_validate_error(valdtr, ext_arg, "%s %s: failed to load Sieve capability '%s'", - cmd->command->identifier, sieve_command_type_name(cmd->command), - ext->name); + sieve_command_identifier(cmd), sieve_command_type_name(cmd), + sieve_extension_name(ext)); return NULL; } - /* Register extension no matter what and store the AST argument registering it */ - ext_id = SIEVE_EXT_ID(ext); - if ( ext_id >= 0 ) { - reg = array_idx_modifiable(&valdtr->extensions, (unsigned int) ext_id); + /* Register extension no matter what and store the AST argument registering it + */ + if ( ext->id >= 0 ) { + reg = array_idx_modifiable(&valdtr->extensions, (unsigned int) ext->id); reg->arg = ext_arg; reg->loaded = TRUE; } @@ -581,29 +615,28 @@ const struct sieve_extension *sieve_validator_extension_load } void sieve_validator_extension_register -(struct sieve_validator *valdtr, - const struct sieve_validator_extension *val_ext, void *context) +(struct sieve_validator *valdtr, const struct sieve_extension *ext, + const struct sieve_validator_extension *valext, void *context) { struct sieve_validator_extension_reg *reg; - int ext_id = SIEVE_EXT_ID(val_ext->ext); - if ( ext_id < 0 ) return; + if ( ext->id < 0 ) return; - reg = array_idx_modifiable(&valdtr->extensions, (unsigned int) ext_id); - reg->val_ext = val_ext; + reg = array_idx_modifiable(&valdtr->extensions, (unsigned int) ext->id); + reg->valext = valext; + reg->ext = ext; reg->context = context; } bool sieve_validator_extension_loaded - (struct sieve_validator *valdtr, const struct sieve_extension *ext) +(struct sieve_validator *valdtr, const struct sieve_extension *ext) { - int ext_id = SIEVE_EXT_ID(ext); const struct sieve_validator_extension_reg *reg; - if ( ext_id < 0 || ext_id >= (int) array_count(&valdtr->extensions)) + if ( ext->id < 0 || ext->id >= (int) array_count(&valdtr->extensions)) return FALSE; - reg = array_idx(&valdtr->extensions, (unsigned int) ext_id); + reg = array_idx(&valdtr->extensions, (unsigned int) ext->id); return ( reg->loaded ); } @@ -613,24 +646,22 @@ void sieve_validator_extension_set_context void *context) { struct sieve_validator_extension_reg *reg; - int ext_id = SIEVE_EXT_ID(ext); - if ( ext_id < 0 ) return; + if ( ext->id < 0 ) return; - reg = array_idx_modifiable(&valdtr->extensions, (unsigned int) ext_id); + reg = array_idx_modifiable(&valdtr->extensions, (unsigned int) ext->id); reg->context = context; } void *sieve_validator_extension_get_context (struct sieve_validator *valdtr, const struct sieve_extension *ext) { - int ext_id = SIEVE_EXT_ID(ext); const struct sieve_validator_extension_reg *reg; - if ( ext_id < 0 || ext_id >= (int) array_count(&valdtr->extensions) ) + if ( ext->id < 0 || ext->id >= (int) array_count(&valdtr->extensions) ) return NULL; - reg = array_idx(&valdtr->extensions, (unsigned int) ext_id); + reg = array_idx(&valdtr->extensions, (unsigned int) ext->id); return reg->context; } @@ -640,70 +671,78 @@ void *sieve_validator_extension_get_context */ void sieve_validator_argument_override -(struct sieve_validator *validator, enum sieve_argument_type type, - const struct sieve_argument *argument) +(struct sieve_validator *valdtr, enum sieve_argument_type type, + const struct sieve_extension *ext, const struct sieve_argument_def *arg_def) { struct sieve_default_argument *arg; - if ( validator->default_arguments[type].argument != NULL ) { - arg = p_new(validator->pool, struct sieve_default_argument, 1); - *arg = validator->default_arguments[type]; + if ( valdtr->default_arguments[type].arg_def != NULL ) { + arg = p_new(valdtr->pool, struct sieve_default_argument, 1); + *arg = valdtr->default_arguments[type]; - validator->default_arguments[type].overrides = arg; + valdtr->default_arguments[type].overrides = arg; } - validator->default_arguments[type].argument = argument; + valdtr->default_arguments[type].arg_def = arg_def; + valdtr->default_arguments[type].ext = ext; } static bool sieve_validator_argument_default_activate -(struct sieve_validator *validator, struct sieve_command_context *cmd, +(struct sieve_validator *valdtr, struct sieve_command *cmd, struct sieve_default_argument *defarg, struct sieve_ast_argument *arg) { bool result = TRUE; struct sieve_default_argument *prev_defarg; - prev_defarg = validator->current_defarg; - validator->current_defarg = defarg; + prev_defarg = valdtr->current_defarg; + valdtr->current_defarg = defarg; - arg->argument = defarg->argument; - if (defarg->argument != NULL && defarg->argument->validate != NULL ) - result = defarg->argument->validate(validator, &arg, cmd); + if ( arg->argument == NULL ) { + arg->argument = sieve_argument_create + (arg->ast, defarg->arg_def, defarg->ext, 0); + } else { + arg->argument->def = defarg->arg_def; + arg->argument->ext = defarg->ext; + } + + if (defarg->arg_def != NULL && defarg->arg_def->validate != NULL ) + result = defarg->arg_def->validate(valdtr, &arg, cmd); - validator->current_defarg = prev_defarg; + valdtr->current_defarg = prev_defarg; return result; } bool sieve_validator_argument_activate_super -(struct sieve_validator *validator, struct sieve_command_context *cmd, +(struct sieve_validator *valdtr, struct sieve_command *cmd, struct sieve_ast_argument *arg, bool constant ATTR_UNUSED) { struct sieve_default_argument *defarg; - if ( validator->current_defarg == NULL || - validator->current_defarg->overrides == NULL ) + if ( valdtr->current_defarg == NULL || + valdtr->current_defarg->overrides == NULL ) return FALSE; - if ( validator->current_defarg->overrides->argument == &string_argument ) { - switch ( validator->current_defarg_type) { + if ( valdtr->current_defarg->overrides->arg_def == &string_argument ) { + switch ( valdtr->current_defarg_type) { case SAT_CONST_STRING: - if ( !validator->current_defarg_constant ) { - validator->current_defarg_type = SAT_VAR_STRING; - defarg = &validator->default_arguments[SAT_VAR_STRING]; + if ( !valdtr->current_defarg_constant ) { + valdtr->current_defarg_type = SAT_VAR_STRING; + defarg = &valdtr->default_arguments[SAT_VAR_STRING]; } else - defarg = validator->current_defarg->overrides; + defarg = valdtr->current_defarg->overrides; break; case SAT_VAR_STRING: - defarg = validator->current_defarg->overrides; + defarg = valdtr->current_defarg->overrides; break; default: return FALSE; } } else - defarg = validator->current_defarg->overrides; + defarg = valdtr->current_defarg->overrides; return sieve_validator_argument_default_activate - (validator, cmd, defarg, arg); + (valdtr, cmd, defarg, arg); } /* @@ -711,38 +750,38 @@ bool sieve_validator_argument_activate_super */ bool sieve_validator_argument_activate -(struct sieve_validator *validator, struct sieve_command_context *cmd, +(struct sieve_validator *valdtr, struct sieve_command *cmd, struct sieve_ast_argument *arg, bool constant) { struct sieve_default_argument *defarg; switch ( sieve_ast_argument_type(arg) ) { case SAAT_NUMBER: - validator->current_defarg_type = SAT_NUMBER; + valdtr->current_defarg_type = SAT_NUMBER; break; case SAAT_STRING: - validator->current_defarg_type = SAT_CONST_STRING; + valdtr->current_defarg_type = SAT_CONST_STRING; break; case SAAT_STRING_LIST: - validator->current_defarg_type = SAT_STRING_LIST; + valdtr->current_defarg_type = SAT_STRING_LIST; break; default: return FALSE; } - validator->current_defarg_constant = constant; - defarg = &validator->default_arguments[validator->current_defarg_type]; + valdtr->current_defarg_constant = constant; + defarg = &valdtr->default_arguments[valdtr->current_defarg_type]; - if ( !constant && defarg->argument == &string_argument ) { - validator->current_defarg_type = SAT_VAR_STRING; - defarg = &validator->default_arguments[SAT_VAR_STRING]; + if ( !constant && defarg->arg_def == &string_argument ) { + valdtr->current_defarg_type = SAT_VAR_STRING; + defarg = &valdtr->default_arguments[SAT_VAR_STRING]; } - return sieve_validator_argument_default_activate(validator, cmd, defarg, arg); + return sieve_validator_argument_default_activate(valdtr, cmd, defarg, arg); } bool sieve_validate_positional_argument -(struct sieve_validator *validator, struct sieve_command_context *cmd, +(struct sieve_validator *valdtr, struct sieve_command *cmd, struct sieve_ast_argument *arg, const char *arg_name, unsigned int arg_pos, enum sieve_ast_argument_type req_type) { @@ -750,9 +789,9 @@ bool sieve_validate_positional_argument (sieve_ast_argument_type(arg) != SAAT_STRING || req_type != SAAT_STRING_LIST) ) { - sieve_argument_validate_error(validator, arg, + sieve_argument_validate_error(valdtr, arg, "the %s %s expects %s as argument %d (%s), but %s was found", - cmd->command->identifier, sieve_command_type_name(cmd->command), + sieve_command_identifier(cmd), sieve_command_type_name(cmd), sieve_ast_argument_type_name(req_type), arg_pos, arg_name, sieve_ast_argument_name(arg)); return FALSE; @@ -762,15 +801,15 @@ bool sieve_validate_positional_argument } bool sieve_validate_tag_parameter -(struct sieve_validator *validator, struct sieve_command_context *cmd, +(struct sieve_validator *valdtr, struct sieve_command *cmd, struct sieve_ast_argument *tag, struct sieve_ast_argument *param, enum sieve_ast_argument_type req_type) { if ( param == NULL ) { - sieve_argument_validate_error(validator, tag, + sieve_argument_validate_error(valdtr, tag, "the :%s tag for the %s %s requires %s as parameter, " "but no more arguments were found", sieve_ast_argument_tag(tag), - cmd->command->identifier, sieve_command_type_name(cmd->command), + sieve_command_identifier(cmd), sieve_command_type_name(cmd), sieve_ast_argument_type_name(req_type)); return FALSE; } @@ -779,17 +818,20 @@ bool sieve_validate_tag_parameter (sieve_ast_argument_type(param) != SAAT_STRING || req_type != SAAT_STRING_LIST) ) { - sieve_argument_validate_error(validator, param, + sieve_argument_validate_error(valdtr, param, "the :%s tag for the %s %s requires %s as parameter, " "but %s was found", sieve_ast_argument_tag(tag), - cmd->command->identifier, sieve_command_type_name(cmd->command), + sieve_command_identifier(cmd), sieve_command_type_name(cmd), sieve_ast_argument_type_name(req_type), sieve_ast_argument_name(param)); return FALSE; } - param->arg_id_code = tag->arg_id_code; + if ( !sieve_validator_argument_activate(valdtr, cmd, param, FALSE) ) + return FALSE; - return sieve_validator_argument_activate(validator, cmd, param, FALSE); + param->argument->id_code = tag->argument->id_code; + + return TRUE; } /* @@ -797,60 +839,64 @@ bool sieve_validate_tag_parameter */ static bool sieve_validate_command_arguments -(struct sieve_validator *validator, struct sieve_command_context *cmd) +(struct sieve_validator *valdtr, struct sieve_command *cmd) { - int arg_count = cmd->command->positional_arguments; + int arg_count = cmd->def->positional_arguments; int real_count = 0; struct sieve_ast_argument *arg; - struct sieve_command_registration *cmd_reg = cmd->cmd_reg; + struct sieve_command_registration *cmd_reg = cmd->reg; /* Validate any tags that might be present */ arg = sieve_ast_argument_first(cmd->ast_node); /* Visit tagged and optional arguments */ while ( sieve_ast_argument_type(arg) == SAAT_TAG ) { - int id_code; - struct sieve_ast_argument *parg; - const struct sieve_argument *tag = - sieve_validator_find_tag(validator, cmd, arg, &id_code); + struct sieve_ast_argument *parg; + void *arg_data = NULL; + struct sieve_tag_registration *tag_reg = + sieve_validator_command_tag_get(valdtr, cmd, arg, &arg_data); + const struct sieve_argument_def *tag_def; - if ( tag == NULL ) { - sieve_argument_validate_error(validator, arg, + if ( tag_reg == NULL ) { + sieve_argument_validate_error(valdtr, arg, "unknown tagged argument ':%s' for the %s %s " "(reported only once at first occurence)", - sieve_ast_argument_tag(arg), cmd->command->identifier, - sieve_command_type_name(cmd->command)); + sieve_ast_argument_tag(arg), sieve_command_identifier(cmd), + sieve_command_type_name(cmd)); sieve_validator_register_unknown_tag - (validator, cmd_reg, sieve_ast_argument_tag(arg)); + (valdtr, cmd_reg, sieve_ast_argument_tag(arg)); return FALSE; } /* Check whether previously tagged as unknown */ - if ( tag->identifier != NULL && *(tag->identifier) == '\0' ) + if ( _tag_registration_is_unknown(tag_reg) ) return FALSE; - /* Assign the tagged argument type to the ast for later reference - * (in generator) - */ - arg->argument = tag; - arg->arg_id_code = id_code; - + tag_def = tag_reg->tag_def; + + /* Assign the tagged argument type to the ast for later reference */ + arg->argument = sieve_argument_create + (arg->ast, tag_def, tag_reg->ext, tag_reg->id_code); + arg->argument->data = arg_data; + /* Scan backwards for any duplicates */ parg = sieve_ast_argument_prev(arg); while ( parg != NULL ) { - if ( (sieve_ast_argument_type(parg) == SAAT_TAG && parg->argument == tag) - || (id_code > 0 && parg->arg_id_code == id_code) ) + if ( (sieve_ast_argument_type(parg) == SAAT_TAG && + parg->argument->def == tag_reg->tag_def) + || (tag_reg->id_code > 0 && parg->argument != NULL && + parg->argument->id_code == tag_reg->id_code) ) { const char *tag_id = sieve_ast_argument_tag(arg); const char *tag_desc = - strcmp(tag->identifier, tag_id) != 0 ? - t_strdup_printf("%s argument (:%s)", tag->identifier, tag_id) : - t_strdup_printf(":%s argument", tag->identifier); + strcmp(tag_def->identifier, tag_id) != 0 ? + t_strdup_printf("%s argument (:%s)", tag_def->identifier, tag_id) : + t_strdup_printf(":%s argument", tag_def->identifier); - sieve_argument_validate_error(validator, arg, + sieve_argument_validate_error(valdtr, arg, "encountered duplicate %s for the %s %s", - tag_desc, cmd->command->identifier, - sieve_command_type_name(cmd->command)); + tag_desc, sieve_command_identifier(cmd), + sieve_command_type_name(cmd)); return FALSE; } @@ -863,11 +909,12 @@ static bool sieve_validate_command_arguments * Let's not whine multiple times about a single command having multiple * bad arguments... */ - if ( tag->validate != NULL ) { - if ( !tag->validate(validator, &arg, cmd) ) + if ( tag_def->validate != NULL ) { + if ( !tag_def->validate(valdtr, &arg, cmd) ) return FALSE; - } else + } else { arg = sieve_ast_argument_next(arg); + } } /* Remaining arguments should be positional (tags are not allowed here) */ @@ -875,11 +922,11 @@ static bool sieve_validate_command_arguments while ( arg != NULL ) { if ( sieve_ast_argument_type(arg) == SAAT_TAG ) { - sieve_argument_validate_error(validator, arg, + sieve_argument_validate_error(valdtr, arg, "encountered an unexpected tagged argument ':%s' " "while validating positional arguments for the %s %s", - sieve_ast_argument_tag(arg), cmd->command->identifier, - sieve_command_type_name(cmd->command)); + sieve_ast_argument_tag(arg), sieve_command_identifier(cmd), + sieve_command_type_name(cmd)); return FALSE; } @@ -890,24 +937,26 @@ static bool sieve_validate_command_arguments /* Check the required count versus the real number of arguments */ if ( arg_count >= 0 && real_count != arg_count ) { - sieve_command_validate_error(validator, cmd, + sieve_command_validate_error(valdtr, cmd, "the %s %s requires %d positional argument(s), but %d is/are specified", - cmd->command->identifier, sieve_command_type_name(cmd->command), + sieve_command_identifier(cmd), sieve_command_type_name(cmd), arg_count, real_count); return FALSE; } /* Call initial validation for persistent arguments */ if ( array_is_created(&cmd_reg->persistent_tags) ) { - unsigned int i; - - for ( i = 0; i < array_count(&cmd_reg->persistent_tags); i++ ) { - struct sieve_tag_registration * const *reg = - array_idx(&cmd_reg->persistent_tags, i); - const struct sieve_argument *tag = (*reg)->tag; + struct sieve_tag_registration * const *regs; + unsigned int i, reg_count; + + regs = array_get(&cmd_reg->persistent_tags, ®_count); + for ( i = 0; i < reg_count; i++ ) { + + const struct sieve_argument_def *tag_def = regs[i]->tag_def; - if ( tag != NULL && tag->validate_persistent != NULL ) { /* To be sure */ - if ( !tag->validate_persistent(validator, cmd) ) + if ( tag_def != NULL && tag_def->validate_persistent != NULL ) { + /* To be sure */ + if ( !tag_def->validate_persistent(valdtr, cmd, regs[i]->ext) ) return FALSE; } } @@ -917,7 +966,7 @@ static bool sieve_validate_command_arguments } static bool sieve_validate_arguments_context -(struct sieve_validator *validator, struct sieve_command_context *cmd) +(struct sieve_validator *valdtr, struct sieve_command *cmd) { struct sieve_ast_argument *arg = sieve_command_first_argument(cmd); @@ -925,8 +974,10 @@ static bool sieve_validate_arguments_context while ( arg != NULL ) { const struct sieve_argument *argument = arg->argument; - if ( argument != NULL && argument->validate_context != NULL ) { - if ( !argument->validate_context(validator, arg, cmd) ) + if ( argument != NULL && argument->def != NULL && + argument->def->validate_context != NULL ) { + + if ( !argument->def->validate_context(valdtr, arg, cmd) ) return FALSE; } @@ -941,7 +992,7 @@ static bool sieve_validate_arguments_context */ static bool sieve_validate_command_subtests -(struct sieve_validator *valdtr, struct sieve_command_context *cmd, +(struct sieve_validator *valdtr, struct sieve_command *cmd, const unsigned int count) { switch ( count ) { @@ -957,25 +1008,25 @@ static bool sieve_validate_command_subtests (valdtr, test->identifier); /* First check what we are dealing with */ - if ( cmd_reg != NULL && cmd_reg->command != NULL ) - ctype = cmd_reg->command->type; + if ( cmd_reg != NULL && cmd_reg->cmd_def != NULL ) + ctype = cmd_reg->cmd_def->type; switch ( ctype ) { case SCT_TEST: /* Spurious test */ case SCT_HYBRID: sieve_command_validate_error(valdtr, cmd, "the %s %s accepts no sub-tests, but tests are specified", - cmd->command->identifier, sieve_command_type_name(cmd->command)); + sieve_command_identifier(cmd), sieve_command_type_name(cmd)); break; case SCT_NONE: /* Unknown command */ /* Is it perhaps a tag for which the ':' was omitted ? */ - if ( sieve_validator_find_tag_by_identifier - (valdtr, cmd, test->identifier) != NULL ) { + if ( sieve_validator_command_tag_exists + (valdtr, cmd, test->identifier) ) { sieve_command_validate_error(valdtr, cmd, "missing colon ':' before ':%s' tag in %s %s", test->identifier, - cmd->command->identifier, sieve_command_type_name(cmd->command)); + sieve_command_identifier(cmd), sieve_command_type_name(cmd)); break; } /* Fall through */ @@ -983,7 +1034,7 @@ static bool sieve_validate_command_subtests case SCT_COMMAND: sieve_command_validate_error(valdtr, cmd, "missing semicolon ';' after %s %s", - cmd->command->identifier, sieve_command_type_name(cmd->command)); + sieve_command_identifier(cmd), sieve_command_type_name(cmd)); break; } return FALSE; @@ -993,7 +1044,7 @@ static bool sieve_validate_command_subtests if ( sieve_ast_test_count(cmd->ast_node) == 0 ) { sieve_command_validate_error(valdtr, cmd, "the %s %s requires one sub-test, but none is specified", - cmd->command->identifier, sieve_command_type_name(cmd->command)); + sieve_command_identifier(cmd), sieve_command_type_name(cmd)); return FALSE; @@ -1002,7 +1053,7 @@ static bool sieve_validate_command_subtests sieve_command_validate_error(valdtr, cmd, "the %s %s requires one sub-test, but a list of tests is specified", - cmd->command->identifier, sieve_command_type_name(cmd->command)); + sieve_command_identifier(cmd), sieve_command_type_name(cmd)); return FALSE; } @@ -1012,7 +1063,7 @@ static bool sieve_validate_command_subtests if ( sieve_ast_test_count(cmd->ast_node) == 0 ) { sieve_command_validate_error(valdtr, cmd, "the %s %s requires a list of sub-tests, but none is specified", - cmd->command->identifier, sieve_command_type_name(cmd->command)); + sieve_command_identifier(cmd), sieve_command_type_name(cmd)); return FALSE; @@ -1022,7 +1073,7 @@ static bool sieve_validate_command_subtests sieve_command_validate_error(valdtr, cmd, "the %s %s requires a list of sub-tests, " "but a single test is specified", - cmd->command->identifier, sieve_command_type_name(cmd->command) ); + sieve_command_identifier(cmd), sieve_command_type_name(cmd) ); return FALSE; } @@ -1033,24 +1084,24 @@ static bool sieve_validate_command_subtests } static bool sieve_validate_command_block -(struct sieve_validator *validator, struct sieve_command_context *cmd, +(struct sieve_validator *valdtr, struct sieve_command *cmd, bool block_allowed, bool block_required) { i_assert( cmd->ast_node->type == SAT_COMMAND ); if ( block_required ) { if ( !cmd->ast_node->block ) { - sieve_command_validate_error(validator, cmd, + sieve_command_validate_error(valdtr, cmd, "the %s command requires a command block, but it is missing", - cmd->command->identifier); + sieve_command_identifier(cmd)); return FALSE; } } else if ( !block_allowed && cmd->ast_node->block ) { - sieve_command_validate_error(validator, cmd, + sieve_command_validate_error(valdtr, cmd, "the %s command does not accept a command block, " "but one is specified anyway", - cmd->command->identifier ); + sieve_command_identifier(cmd) ); return FALSE; } @@ -1063,11 +1114,11 @@ static bool sieve_validate_command_block */ static bool sieve_validate_test_list - (struct sieve_validator *validator, struct sieve_ast_node *test_list); + (struct sieve_validator *valdtr, struct sieve_ast_node *test_list); static bool sieve_validate_block - (struct sieve_validator *validator, struct sieve_ast_node *block); + (struct sieve_validator *valdtr, struct sieve_ast_node *block); static bool sieve_validate_command - (struct sieve_validator *validator, struct sieve_ast_node *cmd_node); + (struct sieve_validator *valdtr, struct sieve_ast_node *cmd_node); static bool sieve_validate_command_context (struct sieve_validator *valdtr, struct sieve_ast_node *cmd_node) @@ -1082,25 +1133,25 @@ static bool sieve_validate_command_context cmd_reg = sieve_validator_find_command_registration (valdtr, cmd_node->identifier); - if ( cmd_reg != NULL && cmd_reg->command != NULL ) { - const struct sieve_command *command = cmd_reg->command; + if ( cmd_reg != NULL && cmd_reg->cmd_def != NULL ) { + const struct sieve_command_def *cmd_def = cmd_reg->cmd_def; /* Identifier = "" when the command was previously marked as unknown */ - if ( *(command->identifier) != '\0' ) { - if ( (command->type == SCT_COMMAND && ast_type == SAT_TEST) - || (command->type == SCT_TEST && ast_type == SAT_COMMAND) ) { + if ( *(cmd_def->identifier) != '\0' ) { + struct sieve_command *cmd; + + if ( (cmd_def->type == SCT_COMMAND && ast_type == SAT_TEST) + || (cmd_def->type == SCT_TEST && ast_type == SAT_COMMAND) ) { sieve_validator_error( valdtr, cmd_node->source_line, "attempted to use %s '%s' as %s", - sieve_command_type_name(command), cmd_node->identifier, + sieve_command_def_type_name(cmd_def), cmd_node->identifier, sieve_ast_type_name(ast_type)); return FALSE; } - struct sieve_command_context *ctx = - sieve_command_context_create(cmd_node, command, cmd_reg); - cmd_node->context = ctx; - + cmd_node->command = cmd = + sieve_command_create(cmd_node, cmd_reg->ext, cmd_def, cmd_reg); } else { return FALSE; } @@ -1123,38 +1174,38 @@ static bool sieve_validate_command (struct sieve_validator *valdtr, struct sieve_ast_node *cmd_node) { enum sieve_ast_type ast_type = sieve_ast_node_type(cmd_node); - struct sieve_command_context *ctx = cmd_node->context; - const struct sieve_command *command = ( ctx != NULL ? ctx->command : NULL ); + struct sieve_command *cmd = cmd_node->command; + const struct sieve_command_def *cmd_def = ( cmd != NULL ? cmd->def : NULL ); bool result = TRUE; i_assert( ast_type == SAT_TEST || ast_type == SAT_COMMAND ); - if ( command != NULL && *(command->identifier) != '\0' ) { + if ( cmd_def != NULL && *(cmd_def->identifier) != '\0' ) { - if ( command->pre_validate == NULL - || command->pre_validate(valdtr, ctx) ) { + if ( cmd_def->pre_validate == NULL + || cmd_def->pre_validate(valdtr, cmd) ) { /* Check argument syntax */ - if ( !sieve_validate_command_arguments(valdtr, ctx) ) { - result = FALSE; + if ( !sieve_validate_command_arguments(valdtr, cmd) ) { + result = FALSE; /* A missing ':' causes a tag to become a test. This can be the cause * of the arguments validation failing. Therefore we must produce an * error for the sub-tests as well if appropriate. */ - (void)sieve_validate_command_subtests(valdtr, ctx, command->subtests); + (void)sieve_validate_command_subtests(valdtr, cmd, cmd_def->subtests); } else if ( - !sieve_validate_command_subtests(valdtr, ctx, command->subtests) || + !sieve_validate_command_subtests(valdtr, cmd, cmd_def->subtests) || (ast_type == SAT_COMMAND && !sieve_validate_command_block - (valdtr, ctx, command->block_allowed, command->block_required)) ) { + (valdtr, cmd, cmd_def->block_allowed, cmd_def->block_required)) ) { result = FALSE; } else { /* Call command validation function if specified */ - if ( command->validate != NULL ) - result = command->validate(valdtr, ctx) && result; + if ( cmd_def->validate != NULL ) + result = cmd_def->validate(valdtr, cmd) && result; } } else { /* If pre-validation fails, don't bother to validate further @@ -1164,7 +1215,7 @@ static bool sieve_validate_command return FALSE; } - result = result && sieve_validate_arguments_context(valdtr, ctx); + result = result && sieve_validate_arguments_context(valdtr, cmd); } @@ -1172,14 +1223,14 @@ static bool sieve_validate_command * Descend further into the AST */ - if ( command != NULL ) { + if ( cmd_def != NULL ) { /* Tests */ - if ( command->subtests > 0 && + if ( cmd_def->subtests > 0 && (result || sieve_errors_more_allowed(valdtr->ehandler)) ) result = sieve_validate_test_list(valdtr, cmd_node) && result; /* Command block */ - if ( command->block_allowed && ast_type == SAT_COMMAND && + if ( cmd_def->block_allowed && ast_type == SAT_COMMAND && (result || sieve_errors_more_allowed(valdtr->ehandler)) ) result = sieve_validate_block(valdtr, cmd_node) && result; } @@ -1212,22 +1263,22 @@ static bool sieve_validate_block (struct sieve_validator *valdtr, struct sieve_ast_node *block) { bool result = TRUE, fatal = FALSE; - struct sieve_ast_node *command, *next; + struct sieve_ast_node *cmd_node, *next; T_BEGIN { - command = sieve_ast_command_first(block); - while ( !fatal && command != NULL + cmd_node = sieve_ast_command_first(block); + while ( !fatal && cmd_node != NULL && (result || sieve_errors_more_allowed(valdtr->ehandler)) ) { bool command_success; - next = sieve_ast_command_next(command); - command_success = sieve_validate_command_context(valdtr, command); + next = sieve_ast_command_next(cmd_node); + command_success = sieve_validate_command_context(valdtr, cmd_node); result = command_success && result; /* Check if this is the first non-require command */ if ( command_success && sieve_ast_node_type(block) == SAT_ROOT - && !valdtr->finished_require && command->context != NULL - && command->context->command != &cmd_require ) { + && !valdtr->finished_require && cmd_node->command != NULL + && !sieve_command_is(cmd_node->command, cmd_require) ) { const struct sieve_validator_extension_reg *extrs; unsigned int ext_count, i; @@ -1236,91 +1287,107 @@ static bool sieve_validate_block /* Validate all 'require'd extensions */ extrs = array_get(&valdtr->extensions, &ext_count); for ( i = 0; i < ext_count; i++ ) { - if ( extrs[i].val_ext != NULL - && extrs[i].val_ext->validate != NULL ) { + if ( extrs[i].valext != NULL + && extrs[i].valext->validate != NULL ) { - if ( !extrs[i].val_ext->validate - (valdtr, extrs[i].context, extrs[i].arg) ) + if ( !extrs[i].valext->validate + (extrs[i].ext, valdtr, extrs[i].context, extrs[i].arg) ) fatal = TRUE; break; } } } - result = !fatal && sieve_validate_command(valdtr, command) && result; + result = !fatal && sieve_validate_command(valdtr, cmd_node) && result; - command = next; + cmd_node = next; } } T_END; return result && !fatal; } -bool sieve_validator_run(struct sieve_validator *validator) +bool sieve_validator_run(struct sieve_validator *valdtr) { - return sieve_validate_block(validator, sieve_ast_root(validator->ast)); + return sieve_validate_block(valdtr, sieve_ast_root(valdtr->ast)); } /* * Validator object registry */ +struct sieve_validator_object_reg { + const struct sieve_object_def *obj_def; + const struct sieve_extension *ext; +}; + struct sieve_validator_object_registry { - struct sieve_validator *validator; - ARRAY_DEFINE(registrations, const struct sieve_object *); + struct sieve_validator *valdtr; + ARRAY_DEFINE(registrations, struct sieve_validator_object_reg); }; struct sieve_validator_object_registry *sieve_validator_object_registry_get -(struct sieve_validator *validator, const struct sieve_extension *ext) +(struct sieve_validator *valdtr, const struct sieve_extension *ext) { return (struct sieve_validator_object_registry *) - sieve_validator_extension_get_context(validator, ext); + sieve_validator_extension_get_context(valdtr, ext); } void sieve_validator_object_registry_add -(struct sieve_validator_object_registry *regs, - const struct sieve_object *object) +(struct sieve_validator_object_registry *regs, + const struct sieve_extension *ext, const struct sieve_object_def *obj_def) { - array_append(®s->registrations, &object, 1); + struct sieve_validator_object_reg *reg; + + reg = array_append_space(®s->registrations); + reg->ext = ext; + reg->obj_def = obj_def; } -const struct sieve_object *sieve_validator_object_registry_find -(struct sieve_validator_object_registry *regs, const char *identifier) +bool sieve_validator_object_registry_find +(struct sieve_validator_object_registry *regs, const char *identifier, + struct sieve_object *obj) { unsigned int i; for ( i = 0; i < array_count(®s->registrations); i++ ) { - const struct sieve_object * const *obj = array_idx(®s->registrations, i); + const struct sieve_validator_object_reg *reg = + array_idx(®s->registrations, i); - if ( strcasecmp((*obj)->identifier, identifier) == 0) - return *obj; + if ( strcasecmp(reg->obj_def->identifier, identifier) == 0) { + if ( obj != NULL ) { + obj->def = reg->obj_def; + obj->ext = reg->ext; + } + return TRUE; + } } - return NULL; + return FALSE; } struct sieve_validator_object_registry *sieve_validator_object_registry_create -(struct sieve_validator *validator) +(struct sieve_validator *valdtr) { - pool_t pool = validator->pool; + pool_t pool = valdtr->pool; struct sieve_validator_object_registry *regs = p_new(pool, struct sieve_validator_object_registry, 1); /* Setup registry */ - p_array_init(®s->registrations, validator->pool, 4); + p_array_init(®s->registrations, valdtr->pool, 4); - regs->validator = validator; + regs->valdtr = valdtr; return regs; } struct sieve_validator_object_registry *sieve_validator_object_registry_init -(struct sieve_validator *validator, const struct sieve_extension *ext) +(struct sieve_validator *valdtr, const struct sieve_extension *ext) { struct sieve_validator_object_registry *regs = - sieve_validator_object_registry_create(validator); + sieve_validator_object_registry_create(valdtr); - sieve_validator_extension_set_context(validator, ext, regs); + sieve_validator_extension_set_context(valdtr, ext, regs); return regs; } diff --git a/src/lib-sieve/sieve-validator.h b/src/lib-sieve/sieve-validator.h index 7b0fab3cd..6d37583ac 100644 --- a/src/lib-sieve/sieve-validator.h +++ b/src/lib-sieve/sieve-validator.h @@ -31,34 +31,36 @@ struct sieve_validator; struct sieve_validator *sieve_validator_create (struct sieve_ast *ast, struct sieve_error_handler *ehandler); -void sieve_validator_free(struct sieve_validator **validator); -pool_t sieve_validator_pool(struct sieve_validator *validator); +void sieve_validator_free(struct sieve_validator **valdtr); +pool_t sieve_validator_pool(struct sieve_validator *valdtr); -bool sieve_validator_run(struct sieve_validator *validator); +bool sieve_validator_run(struct sieve_validator *valdtr); /* * Accessors */ struct sieve_error_handler *sieve_validator_error_handler - (struct sieve_validator *validator); + (struct sieve_validator *valdtr); struct sieve_ast *sieve_validator_ast - (struct sieve_validator *validator); + (struct sieve_validator *valdtr); struct sieve_script *sieve_validator_script - (struct sieve_validator *validator); + (struct sieve_validator *valdtr); +struct sieve_instance *sieve_validator_svinst + (struct sieve_validator *valdtr); /* * Error handling */ void sieve_validator_warning - (struct sieve_validator *validator, unsigned int source_line, + (struct sieve_validator *valdtr, unsigned int source_line, const char *fmt, ...) ATTR_FORMAT(3, 4); void sieve_validator_error - (struct sieve_validator *validator, unsigned int source_line, + (struct sieve_validator *valdtr, unsigned int source_line, const char *fmt, ...) ATTR_FORMAT(3, 4); void sieve_validator_critical - (struct sieve_validator *validator, unsigned int source_line, + (struct sieve_validator *valdtr, unsigned int source_line, const char *fmt, ...) ATTR_FORMAT(3, 4); /* @@ -66,35 +68,35 @@ void sieve_validator_critical */ void sieve_validator_register_command - (struct sieve_validator *validator, const struct sieve_command *command); -const struct sieve_command *sieve_validator_find_command - (struct sieve_validator *validator, const char *command); + (struct sieve_validator *valdtr, const struct sieve_extension *ext, + const struct sieve_command_def *command); -void sieve_validator_register_external_tag - (struct sieve_validator *validator, const struct sieve_argument *tag, - const char *command, int id_code); - /* * Per-command tagged argument registry */ void sieve_validator_register_tag - (struct sieve_validator *validator, - struct sieve_command_registration *cmd_reg, - const struct sieve_argument *argument, int id_code); + (struct sieve_validator *valdtr, struct sieve_command_registration *cmd_reg, + const struct sieve_extension *ext, const struct sieve_argument_def *tag_def, + int id_code); +void sieve_validator_register_external_tag + (struct sieve_validator *valdtr, const char *command, + const struct sieve_extension *ext, const struct sieve_argument_def *tag_def, + int id_code); void sieve_validator_register_persistent_tag - (struct sieve_validator *validator, const struct sieve_argument *tag, - const char *command); + (struct sieve_validator *valdtr, const char *command, + const struct sieve_extension *ext, + const struct sieve_argument_def *tag_def); /* * Overriding the default literal arguments */ void sieve_validator_argument_override -(struct sieve_validator *validator, enum sieve_argument_type type, - const struct sieve_argument *argument); +(struct sieve_validator *valdtr, enum sieve_argument_type type, + const struct sieve_extension *ext, const struct sieve_argument_def *arg_def); bool sieve_validator_argument_activate_super -(struct sieve_validator *validator, struct sieve_command_context *cmd, +(struct sieve_validator *valdtr, struct sieve_command *cmd, struct sieve_ast_argument *arg, bool constant); /* @@ -102,38 +104,41 @@ bool sieve_validator_argument_activate_super */ bool sieve_validate_positional_argument - (struct sieve_validator *validator, struct sieve_command_context *cmd, - struct sieve_ast_argument *arg, const char *arg_name, unsigned int arg_pos, - enum sieve_ast_argument_type req_type); + (struct sieve_validator *valdtr, struct sieve_command *cmd, + struct sieve_ast_argument *arg, const char *arg_name, unsigned int arg_pos, + enum sieve_ast_argument_type req_type); bool sieve_validator_argument_activate -(struct sieve_validator *validator, struct sieve_command_context *cmd, - struct sieve_ast_argument *arg, bool constant); + (struct sieve_validator *valdtr, struct sieve_command *cmd, + struct sieve_ast_argument *arg, bool constant); bool sieve_validate_tag_parameter - (struct sieve_validator *validator, struct sieve_command_context *cmd, - struct sieve_ast_argument *tag, struct sieve_ast_argument *param, - enum sieve_ast_argument_type req_type); + (struct sieve_validator *valdtr, struct sieve_command *cmd, + struct sieve_ast_argument *tag, struct sieve_ast_argument *param, + enum sieve_ast_argument_type req_type); /* * Extension support */ struct sieve_validator_extension { - const struct sieve_extension *ext; + const struct sieve_extension_def *ext; - bool (*validate)(struct sieve_validator *valdtr, void *context, - struct sieve_ast_argument *require_arg); + bool (*validate) + (const struct sieve_extension *ext, struct sieve_validator *valdtr, + void *context, struct sieve_ast_argument *require_arg); - void (*free)(struct sieve_validator *valdtr, void *context); + void (*free) + (const struct sieve_extension *ext, struct sieve_validator *valdtr, + void *context); }; const struct sieve_extension *sieve_validator_extension_load - (struct sieve_validator *validator, struct sieve_command_context *cmd, + (struct sieve_validator *valdtr, struct sieve_command *cmd, struct sieve_ast_argument *ext_arg, string_t *ext_name); void sieve_validator_extension_register - (struct sieve_validator *valdtr, - const struct sieve_validator_extension *val_ext, void *context); + (struct sieve_validator *valdtr, const struct sieve_extension *ext, + const struct sieve_validator_extension *valext, void *context); bool sieve_validator_extension_loaded (struct sieve_validator *valdtr, const struct sieve_extension *ext); @@ -150,15 +155,16 @@ void *sieve_validator_extension_get_context struct sieve_validator_object_registry; struct sieve_validator_object_registry *sieve_validator_object_registry_get - (struct sieve_validator *validator, const struct sieve_extension *ext); + (struct sieve_validator *valdtr, const struct sieve_extension *ext); void sieve_validator_object_registry_add (struct sieve_validator_object_registry *regs, - const struct sieve_object *object); -const struct sieve_object *sieve_validator_object_registry_find - (struct sieve_validator_object_registry *regs, const char *identifier); + const struct sieve_extension *ext, const struct sieve_object_def *obj_def); +bool sieve_validator_object_registry_find + (struct sieve_validator_object_registry *regs, const char *identifier, + struct sieve_object *obj); struct sieve_validator_object_registry *sieve_validator_object_registry_create - (struct sieve_validator *validator); + (struct sieve_validator *valdtr); struct sieve_validator_object_registry *sieve_validator_object_registry_init - (struct sieve_validator *validator, const struct sieve_extension *ext); + (struct sieve_validator *valdtr, const struct sieve_extension *ext); #endif /* __SIEVE_VALIDATOR_H */ diff --git a/src/lib-sieve/sieve.c b/src/lib-sieve/sieve.c index 4f7cac448..a4da11a2f 100644 --- a/src/lib-sieve/sieve.c +++ b/src/lib-sieve/sieve.c @@ -36,29 +36,48 @@ * Main Sieve library interface */ -bool sieve_init(sieve_settings_func_t settings_func) +struct sieve_instance *sieve_init +(const struct sieve_callbacks *callbacks, void *context) { - sieve_settings_init(settings_func); + struct sieve_instance *svinst; + pool_t pool; + + pool = pool_alloconly_create("sieve", 8192); + svinst = p_new(pool, struct sieve_instance, 1); + svinst->pool = pool; + svinst->callbacks = callbacks; + svinst->context = context; + + if ( !sieve_extensions_init(svinst) ) { + sieve_deinit(&svinst); + return NULL; + } - return sieve_extensions_init(); + return svinst; } -void sieve_deinit(void) +void sieve_deinit(struct sieve_instance **svinst) { - sieve_extensions_deinit(); + sieve_extensions_deinit(*svinst); + + pool_unref(&(*svinst)->pool); + + *svinst = NULL; } -void sieve_set_extensions(const char *extensions) +void sieve_set_extensions +(struct sieve_instance *svinst, const char *extensions) { - sieve_extensions_set_string(extensions); + sieve_extensions_set_string(svinst, extensions); } -const char *sieve_get_capabilities(const char *name) +const char *sieve_get_capabilities +(struct sieve_instance *svinst, const char *name) { if ( name == NULL || *name == '\0' ) - return sieve_extensions_get_string(); - - return sieve_extension_capabilities_get_string(name); + return sieve_extensions_get_string(svinst); + + return sieve_extension_capabilities_get_string(svinst, name); } /* @@ -66,7 +85,7 @@ const char *sieve_get_capabilities(const char *name) */ struct sieve_ast *sieve_parse - (struct sieve_script *script, struct sieve_error_handler *ehandler) +(struct sieve_script *script, struct sieve_error_handler *ehandler) { struct sieve_parser *parser; struct sieve_ast *ast = NULL; @@ -85,7 +104,8 @@ struct sieve_ast *sieve_parse return ast; } -bool sieve_validate(struct sieve_ast *ast, struct sieve_error_handler *ehandler) +bool sieve_validate +(struct sieve_ast *ast, struct sieve_error_handler *ehandler) { bool result = TRUE; struct sieve_validator *validator = sieve_validator_create(ast, ehandler); @@ -99,7 +119,7 @@ bool sieve_validate(struct sieve_ast *ast, struct sieve_error_handler *ehandler) } static struct sieve_binary *sieve_generate - (struct sieve_ast *ast, struct sieve_error_handler *ehandler) +(struct sieve_ast *ast, struct sieve_error_handler *ehandler) { struct sieve_generator *generator = sieve_generator_create(ast, ehandler); struct sieve_binary *sbin = NULL; @@ -150,14 +170,14 @@ struct sieve_binary *sieve_compile_script } struct sieve_binary *sieve_compile -(const char *script_path, const char *script_name, - struct sieve_error_handler *ehandler) +(struct sieve_instance *svinst, const char *script_path, + const char *script_name, struct sieve_error_handler *ehandler) { struct sieve_script *script; struct sieve_binary *sbin; if ( (script = sieve_script_create - (script_path, script_name, ehandler, NULL)) == NULL ) + (svinst, script_path, script_name, ehandler, NULL)) == NULL ) return NULL; sbin = sieve_compile_script(script, ehandler); @@ -189,7 +209,8 @@ static int sieve_run /* Create result object */ if ( *result == NULL ) - *result = sieve_result_create(msgdata, senv, ehandler); + *result = sieve_result_create + (sieve_binary_svinst(sbin), msgdata, senv, ehandler); else { sieve_result_ref(*result); sieve_result_set_error_handler(*result, ehandler); @@ -209,15 +230,16 @@ static int sieve_run */ struct sieve_binary *sieve_open -(const char *script_path, const char *script_name, - struct sieve_error_handler *ehandler, bool *exists_r) +(struct sieve_instance *svinst, const char *script_path, + const char *script_name, struct sieve_error_handler *ehandler, bool *exists_r) { struct sieve_script *script; struct sieve_binary *sbin; const char *binpath; /* First open the scriptfile itself */ - script = sieve_script_create(script_path, script_name, ehandler, exists_r); + script = sieve_script_create + (svinst, script_path, script_name, ehandler, exists_r); if ( script == NULL ) { /* Failed */ @@ -227,7 +249,7 @@ struct sieve_binary *sieve_open T_BEGIN { /* Then try to open the matching binary */ binpath = sieve_script_binpath(script); - sbin = sieve_binary_open(binpath, script); + sbin = sieve_binary_open(svinst, binpath, script); if (sbin != NULL) { /* Ok, it exists; now let's see if it is up to date */ @@ -269,9 +291,9 @@ bool sieve_save } struct sieve_binary *sieve_load -(const char *bin_path) +(struct sieve_instance *svinst, const char *bin_path) { - struct sieve_binary *sbin = sieve_binary_open(bin_path, NULL); + struct sieve_binary *sbin = sieve_binary_open(svinst, bin_path, NULL); if ( sbin != NULL && !sieve_binary_load(sbin) ) { sieve_binary_unref(&sbin); @@ -370,6 +392,7 @@ int sieve_execute */ struct sieve_multiscript { + struct sieve_instance *svinst; struct sieve_result *result; const struct sieve_message_data *msgdata; const struct sieve_script_env *scriptenv; @@ -383,18 +406,20 @@ struct sieve_multiscript { }; struct sieve_multiscript *sieve_multiscript_start_execute -(const struct sieve_message_data *msgdata, const struct sieve_script_env *senv) +(struct sieve_instance *svinst, const struct sieve_message_data *msgdata, + const struct sieve_script_env *senv) { pool_t pool; struct sieve_result *result; struct sieve_multiscript *mscript; - result = sieve_result_create(msgdata, senv, NULL); + result = sieve_result_create(svinst, msgdata, senv, NULL); pool = sieve_result_pool(result); - sieve_result_set_keep_action(result, NULL); + sieve_result_set_keep_action(result, NULL, NULL); mscript = p_new(pool, struct sieve_multiscript, 1); + mscript->svinst = svinst; mscript->result = result; mscript->msgdata = msgdata; mscript->scriptenv = senv; @@ -406,11 +431,11 @@ struct sieve_multiscript *sieve_multiscript_start_execute } struct sieve_multiscript *sieve_multiscript_start_test -(const struct sieve_message_data *msgdata, const struct sieve_script_env *senv, - struct ostream *stream) +(struct sieve_instance *svinst, const struct sieve_message_data *msgdata, + const struct sieve_script_env *senv, struct ostream *stream) { struct sieve_multiscript *mscript = - sieve_multiscript_start_execute(msgdata, senv); + sieve_multiscript_start_execute(svinst, msgdata, senv); mscript->teststream = stream; @@ -460,7 +485,7 @@ bool sieve_multiscript_run if ( !mscript->active ) return FALSE; if ( final ) - sieve_result_set_keep_action(mscript->result, &act_store); + sieve_result_set_keep_action(mscript->result, NULL, &act_store); /* Run the script */ mscript->status = sieve_run(sbin, &mscript->result, mscript->msgdata, diff --git a/src/lib-sieve/sieve.h b/src/lib-sieve/sieve.h index fbdcacd1a..6272fc16f 100644 --- a/src/lib-sieve/sieve.h +++ b/src/lib-sieve/sieve.h @@ -22,22 +22,25 @@ struct sieve_binary; * Initializes the sieve engine. Must be called before any sieve functionality * is used. */ -bool sieve_init(sieve_settings_func_t settings_func); +struct sieve_instance *sieve_init + (const struct sieve_callbacks *callbacks, void *context); /* sieve_deinit(): * Frees all memory allocated by the sieve engine. */ -void sieve_deinit(void); +void sieve_deinit(struct sieve_instance **svinst); /* sieve_get_capabilities(): * */ -const char *sieve_get_capabilities(const char *name); +const char *sieve_get_capabilities + (struct sieve_instance *svinst, const char *name); /* sieve_set_extensions(): * */ -void sieve_set_extensions(const char *extensions); +void sieve_set_extensions + (struct sieve_instance *svinst, const char *extensions); /* * Script compilation @@ -53,8 +56,8 @@ struct sieve_binary *sieve_compile_script * Compiles the script into a binary. */ struct sieve_binary *sieve_compile - (const char *script_path, const char *script_name, - struct sieve_error_handler *ehandler); + (struct sieve_instance *svinst, const char *script_path, + const char *script_name, struct sieve_error_handler *ehandler); /* * Reading/writing Sieve binaries @@ -69,8 +72,9 @@ struct sieve_binary *sieve_compile * */ struct sieve_binary *sieve_open - (const char *scriptpath, const char *script_name, - struct sieve_error_handler *ehandler, bool *exists_r); + (struct sieve_instance *svinst, const char *script_path, + const char *script_name, struct sieve_error_handler *ehandler, + bool *exists_r); /* sieve_save: * @@ -86,7 +90,7 @@ bool sieve_save * Loads the sieve binary indicated by the provided path. */ struct sieve_binary *sieve_load - (const char *bin_path); + (struct sieve_instance *svinst, const char *bin_path); /* sieve_close: * @@ -133,10 +137,11 @@ int sieve_execute struct sieve_multiscript; struct sieve_multiscript *sieve_multiscript_start_execute - (const struct sieve_message_data *msgdata, const struct sieve_script_env *senv); + (struct sieve_instance *svinst, const struct sieve_message_data *msgdata, + const struct sieve_script_env *senv); struct sieve_multiscript *sieve_multiscript_start_test - (const struct sieve_message_data *msgdata, const struct sieve_script_env *senv, - struct ostream *stream); + (struct sieve_instance *svinst, const struct sieve_message_data *msgdata, + const struct sieve_script_env *senv, struct ostream *stream); bool sieve_multiscript_run (struct sieve_multiscript *mscript, struct sieve_binary *sbin, diff --git a/src/lib-sieve/tst-address.c b/src/lib-sieve/tst-address.c index 70bb3d0f0..c633f00a6 100644 --- a/src/lib-sieve/tst-address.c +++ b/src/lib-sieve/tst-address.c @@ -27,13 +27,14 @@ */ static bool tst_address_registered - (struct sieve_validator *valdtr, struct sieve_command_registration *cmd_reg); + (struct sieve_validator *valdtr, const struct sieve_extension *ext, + struct sieve_command_registration *cmd_reg); static bool tst_address_validate - (struct sieve_validator *valdtr, struct sieve_command_context *tst); + (struct sieve_validator *valdtr, struct sieve_command *tst); static bool tst_address_generate - (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx); + (const struct sieve_codegen_env *cgenv, struct sieve_command *ctx); -const struct sieve_command tst_address = { +const struct sieve_command_def tst_address = { "address", SCT_TEST, 2, 0, FALSE, FALSE, @@ -49,13 +50,11 @@ const struct sieve_command tst_address = { */ static bool tst_address_operation_dump - (const struct sieve_operation *op, - const struct sieve_dumptime_env *denv, sieve_size_t *address); + (const struct sieve_dumptime_env *denv, sieve_size_t *address); static int tst_address_operation_execute - (const struct sieve_operation *op, - const struct sieve_runtime_env *renv, sieve_size_t *address); + (const struct sieve_runtime_env *renv, sieve_size_t *address); -const struct sieve_operation tst_address_operation = { +const struct sieve_operation_def tst_address_operation = { "ADDRESS", NULL, SIEVE_OPERATION_ADDRESS, @@ -68,7 +67,8 @@ const struct sieve_operation tst_address_operation = { */ static bool tst_address_registered - (struct sieve_validator *valdtr, struct sieve_command_registration *cmd_reg) +(struct sieve_validator *valdtr, const struct sieve_extension *ext ATTR_UNUSED, + struct sieve_command_registration *cmd_reg) { /* The order of these is not significant */ sieve_comparators_link_tag(valdtr, cmd_reg, SIEVE_AM_OPT_COMPARATOR ); @@ -136,10 +136,14 @@ static int _header_is_allowed } static bool tst_address_validate - (struct sieve_validator *valdtr, struct sieve_command_context *tst) +(struct sieve_validator *valdtr, struct sieve_command *tst) { struct sieve_ast_argument *arg = tst->first_positional; struct sieve_ast_argument *header; + struct sieve_comparator cmp_default = + SIEVE_COMPARATOR_DEFAULT(i_ascii_casemap_comparator); + struct sieve_match_type mcht_default = + SIEVE_MATCH_TYPE_DEFAULT(is_match_type); if ( !sieve_validate_positional_argument (valdtr, tst, arg, "header list", 1, SAAT_STRING_LIST) ) { @@ -177,7 +181,7 @@ static bool tst_address_validate /* Validate the key argument to a specified match type */ return sieve_match_type_validate - (valdtr, tst, arg, &is_match_type, &i_ascii_casemap_comparator); + (valdtr, tst, arg, &mcht_default, &cmp_default); } /* @@ -185,12 +189,12 @@ static bool tst_address_validate */ static bool tst_address_generate -(const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx) +(const struct sieve_codegen_env *cgenv, struct sieve_command *tst) { - sieve_operation_emit_code(cgenv->sbin, &tst_address_operation); + sieve_operation_emit(cgenv->sbin, NULL, &tst_address_operation); /* Generate arguments */ - return sieve_generate_arguments(cgenv, ctx, NULL); + return sieve_generate_arguments(cgenv, tst, NULL); } /* @@ -198,8 +202,7 @@ static bool tst_address_generate */ static bool tst_address_operation_dump -(const struct sieve_operation *op ATTR_UNUSED, - const struct sieve_dumptime_env *denv, sieve_size_t *address) +(const struct sieve_dumptime_env *denv, sieve_size_t *address) { sieve_code_dumpf(denv, "ADDRESS"); sieve_code_descend(denv); @@ -218,13 +221,15 @@ static bool tst_address_operation_dump */ static int tst_address_operation_execute -(const struct sieve_operation *op ATTR_UNUSED, - const struct sieve_runtime_env *renv, sieve_size_t *address) +(const struct sieve_runtime_env *renv, sieve_size_t *address) { bool result = TRUE; - const struct sieve_comparator *cmp = &i_ascii_casemap_comparator; - const struct sieve_match_type *mtch = &is_match_type; - const struct sieve_address_part *addrp = &all_address_part; + struct sieve_comparator cmp = + SIEVE_COMPARATOR_DEFAULT(i_ascii_casemap_comparator); + struct sieve_match_type mcht = + SIEVE_MATCH_TYPE_DEFAULT(is_match_type); + struct sieve_address_part addrp = + SIEVE_ADDRESS_PART_DEFAULT(all_address_part); struct sieve_match_context *mctx; struct sieve_coded_stringlist *hdr_list; struct sieve_coded_stringlist *key_list; @@ -234,7 +239,7 @@ static int tst_address_operation_execute /* Read optional operands */ if ( (ret=sieve_addrmatch_default_get_optionals - (renv, address, &addrp, &mtch, &cmp)) <= 0 ) + (renv, address, &addrp, &mcht, &cmp)) <= 0 ) return ret; /* Read header-list */ @@ -252,7 +257,7 @@ static int tst_address_operation_execute sieve_runtime_trace(renv, "ADDRESS test"); /* Initialize match context */ - mctx = sieve_match_begin(renv->interp, mtch, cmp, NULL, key_list); + mctx = sieve_match_begin(renv->interp, &mcht, &cmp, NULL, key_list); /* Iterate through all requested headers to match */ hdr_item = NULL; @@ -262,11 +267,12 @@ static int tst_address_operation_execute && hdr_item != NULL ) { const char *const *headers; - if ( mail_get_headers_utf8(renv->msgdata->mail, str_c(hdr_item), &headers) >= 0 ) { + if ( mail_get_headers_utf8 + (renv->msgdata->mail, str_c(hdr_item), &headers) >= 0 ) { int i; for ( i = 0; !matched && headers[i] != NULL; i++ ) { - if ( (ret=sieve_address_match(addrp, mctx, headers[i])) < 0 ) { + if ( (ret=sieve_address_match(&addrp, mctx, headers[i])) < 0 ) { result = FALSE; break; } diff --git a/src/lib-sieve/tst-allof.c b/src/lib-sieve/tst-allof.c index da82fef3f..527568d79 100644 --- a/src/lib-sieve/tst-allof.c +++ b/src/lib-sieve/tst-allof.c @@ -17,11 +17,10 @@ */ static bool tst_allof_generate - (const struct sieve_codegen_env *cgenv, - struct sieve_command_context *ctx, + (const struct sieve_codegen_env *cgenv, struct sieve_command *ctx, struct sieve_jumplist *jumps, bool jump_true); -const struct sieve_command tst_allof = { +const struct sieve_command_def tst_allof = { "allof", SCT_TEST, 0, 2, FALSE, FALSE, @@ -34,8 +33,7 @@ const struct sieve_command tst_allof = { */ static bool tst_allof_generate -(const struct sieve_codegen_env *cgenv, - struct sieve_command_context *ctx, +(const struct sieve_codegen_env *cgenv, struct sieve_command *ctx, struct sieve_jumplist *jumps, bool jump_true) { struct sieve_binary *sbin = cgenv->sbin; @@ -69,7 +67,7 @@ static bool tst_allof_generate if ( jump_true ) { /* All tests succeeded, jump to case TRUE */ - sieve_operation_emit_code(cgenv->sbin, &sieve_jmp_operation); + sieve_operation_emit(cgenv->sbin, NULL, &sieve_jmp_operation); sieve_jumplist_add(jumps, sieve_binary_emit_offset(sbin, 0)); /* All false exits jump here */ diff --git a/src/lib-sieve/tst-anyof.c b/src/lib-sieve/tst-anyof.c index e560aa8a7..effec4c15 100644 --- a/src/lib-sieve/tst-anyof.c +++ b/src/lib-sieve/tst-anyof.c @@ -17,10 +17,10 @@ */ static bool tst_anyof_generate - (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx, + (const struct sieve_codegen_env *cgenv, struct sieve_command *ctx, struct sieve_jumplist *jumps, bool jump_true); -const struct sieve_command tst_anyof = { +const struct sieve_command_def tst_anyof = { "anyof", SCT_TEST, 0, 2, FALSE, FALSE, @@ -33,7 +33,7 @@ const struct sieve_command tst_anyof = { */ static bool tst_anyof_generate - (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx, + (const struct sieve_codegen_env *cgenv, struct sieve_command *ctx, struct sieve_jumplist *jumps, bool jump_true) { struct sieve_binary *sbin = cgenv->sbin; @@ -67,7 +67,7 @@ static bool tst_anyof_generate if ( !jump_true ) { /* All tests failed, jump to case FALSE */ - sieve_operation_emit_code(sbin, &sieve_jmp_operation); + sieve_operation_emit(sbin, NULL, &sieve_jmp_operation); sieve_jumplist_add(jumps, sieve_binary_emit_offset(sbin, 0)); /* All true exits jump here */ diff --git a/src/lib-sieve/tst-exists.c b/src/lib-sieve/tst-exists.c index ee064e9e9..737992b8c 100644 --- a/src/lib-sieve/tst-exists.c +++ b/src/lib-sieve/tst-exists.c @@ -17,11 +17,11 @@ */ static bool tst_exists_validate - (struct sieve_validator *valdtr, struct sieve_command_context *tst); + (struct sieve_validator *valdtr, struct sieve_command *tst); static bool tst_exists_generate - (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx); + (const struct sieve_codegen_env *cgenv, struct sieve_command *tst); -const struct sieve_command tst_exists = { +const struct sieve_command_def tst_exists = { "exists", SCT_TEST, 1, 0, FALSE, FALSE, @@ -37,13 +37,11 @@ const struct sieve_command tst_exists = { */ static bool tst_exists_operation_dump - (const struct sieve_operation *op, - const struct sieve_dumptime_env *denv, sieve_size_t *address); + (const struct sieve_dumptime_env *denv, sieve_size_t *address); static int tst_exists_operation_execute - (const struct sieve_operation *op, - const struct sieve_runtime_env *renv, sieve_size_t *address); + (const struct sieve_runtime_env *renv, sieve_size_t *address); -const struct sieve_operation tst_exists_operation = { +const struct sieve_operation_def tst_exists_operation = { "EXISTS", NULL, SIEVE_OPERATION_EXISTS, @@ -56,7 +54,7 @@ const struct sieve_operation tst_exists_operation = { */ static bool tst_exists_validate - (struct sieve_validator *valdtr, struct sieve_command_context *tst) + (struct sieve_validator *valdtr, struct sieve_command *tst) { struct sieve_ast_argument *arg = tst->first_positional; @@ -76,12 +74,12 @@ static bool tst_exists_validate */ static bool tst_exists_generate -(const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx) +(const struct sieve_codegen_env *cgenv, struct sieve_command *tst) { - sieve_operation_emit_code(cgenv->sbin, &tst_exists_operation); + sieve_operation_emit(cgenv->sbin, NULL, &tst_exists_operation); /* Generate arguments */ - return sieve_generate_arguments(cgenv, ctx, NULL); + return sieve_generate_arguments(cgenv, tst, NULL); } /* @@ -89,8 +87,7 @@ static bool tst_exists_generate */ static bool tst_exists_operation_dump -(const struct sieve_operation *op ATTR_UNUSED, - const struct sieve_dumptime_env *denv, sieve_size_t *address) +(const struct sieve_dumptime_env *denv, sieve_size_t *address) { sieve_code_dumpf(denv, "EXISTS"); sieve_code_descend(denv); @@ -103,8 +100,7 @@ static bool tst_exists_operation_dump */ static int tst_exists_operation_execute -(const struct sieve_operation *op ATTR_UNUSED, - const struct sieve_runtime_env *renv, sieve_size_t *address) +(const struct sieve_runtime_env *renv, sieve_size_t *address) { bool result = TRUE; struct sieve_coded_stringlist *hdr_list; diff --git a/src/lib-sieve/tst-header.c b/src/lib-sieve/tst-header.c index 424332561..8e9370309 100644 --- a/src/lib-sieve/tst-header.c +++ b/src/lib-sieve/tst-header.c @@ -21,15 +21,16 @@ */ static bool tst_header_registered - (struct sieve_validator *valdtr, struct sieve_command_registration *cmd_reg); + (struct sieve_validator *valdtr, const struct sieve_extension *ext, + struct sieve_command_registration *cmd_reg); static bool tst_header_validate - (struct sieve_validator *valdtr, struct sieve_command_context *tst); + (struct sieve_validator *valdtr, struct sieve_command *tst); static bool tst_header_generate - (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx); + (const struct sieve_codegen_env *cgenv, struct sieve_command *tst); -const struct sieve_command tst_header = { +const struct sieve_command_def tst_header = { "header", - SCT_TEST, + SCT_TEST, 2, 0, FALSE, FALSE, tst_header_registered, NULL, @@ -43,13 +44,11 @@ const struct sieve_command tst_header = { */ static bool tst_header_operation_dump - (const struct sieve_operation *op, - const struct sieve_dumptime_env *denv, sieve_size_t *address); + (const struct sieve_dumptime_env *denv, sieve_size_t *address); static int tst_header_operation_execute - (const struct sieve_operation *op, - const struct sieve_runtime_env *renv, sieve_size_t *address); + (const struct sieve_runtime_env *renv, sieve_size_t *address); -const struct sieve_operation tst_header_operation = { +const struct sieve_operation_def tst_header_operation = { "HEADER", NULL, SIEVE_OPERATION_HEADER, @@ -62,7 +61,8 @@ const struct sieve_operation tst_header_operation = { */ static bool tst_header_registered - (struct sieve_validator *valdtr, struct sieve_command_registration *cmd_reg) +(struct sieve_validator *valdtr, const struct sieve_extension *ext ATTR_UNUSED, + struct sieve_command_registration *cmd_reg) { /* The order of these is not significant */ sieve_comparators_link_tag(valdtr, cmd_reg, SIEVE_MATCH_OPT_COMPARATOR); @@ -76,9 +76,13 @@ static bool tst_header_registered */ static bool tst_header_validate - (struct sieve_validator *valdtr, struct sieve_command_context *tst) +(struct sieve_validator *valdtr, struct sieve_command *tst) { struct sieve_ast_argument *arg = tst->first_positional; + struct sieve_comparator cmp_default = + SIEVE_COMPARATOR_DEFAULT(i_ascii_casemap_comparator); + struct sieve_match_type mcht_default = + SIEVE_COMPARATOR_DEFAULT(is_match_type); if ( !sieve_validate_positional_argument (valdtr, tst, arg, "header names", 1, SAAT_STRING_LIST) ) { @@ -103,7 +107,7 @@ static bool tst_header_validate /* Validate the key argument to a specified match type */ return sieve_match_type_validate - (valdtr, tst, arg, &is_match_type, &i_ascii_casemap_comparator); + (valdtr, tst, arg, &mcht_default, &cmp_default); } /* @@ -111,12 +115,12 @@ static bool tst_header_validate */ static bool tst_header_generate - (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx) +(const struct sieve_codegen_env *cgenv, struct sieve_command *tst) { - sieve_operation_emit_code(cgenv->sbin, &tst_header_operation); + sieve_operation_emit(cgenv->sbin, NULL, &tst_header_operation); /* Generate arguments */ - return sieve_generate_arguments(cgenv, ctx, NULL); + return sieve_generate_arguments(cgenv, tst, NULL); } /* @@ -124,8 +128,7 @@ static bool tst_header_generate */ static bool tst_header_operation_dump -(const struct sieve_operation *op ATTR_UNUSED, - const struct sieve_dumptime_env *denv, sieve_size_t *address) +(const struct sieve_dumptime_env *denv, sieve_size_t *address) { int opt_code = 0; @@ -163,13 +166,14 @@ static inline string_t *_header_right_trim(const char *raw) } static int tst_header_operation_execute -(const struct sieve_operation *op ATTR_UNUSED, - const struct sieve_runtime_env *renv, sieve_size_t *address) +(const struct sieve_runtime_env *renv, sieve_size_t *address) { bool result = TRUE; int opt_code = 0; - const struct sieve_comparator *cmp = &i_ascii_casemap_comparator; - const struct sieve_match_type *mtch = &is_match_type; + struct sieve_comparator cmp = + SIEVE_COMPARATOR_DEFAULT(i_ascii_casemap_comparator); + struct sieve_match_type mcht = + SIEVE_COMPARATOR_DEFAULT(is_match_type); struct sieve_match_context *mctx; struct sieve_coded_stringlist *hdr_list; struct sieve_coded_stringlist *key_list; @@ -179,7 +183,7 @@ static int tst_header_operation_execute /* Handle match-type and comparator operands */ if ( (ret=sieve_match_read_optional_operands - (renv, address, &opt_code, &cmp, &mtch)) <= 0 ) + (renv, address, &opt_code, &cmp, &mcht)) <= 0 ) return ret; /* Check whether we neatly finished the list of optional operands*/ @@ -203,7 +207,7 @@ static int tst_header_operation_execute sieve_runtime_trace(renv, "HEADER test"); /* Initialize match */ - mctx = sieve_match_begin(renv->interp, mtch, cmp, NULL, key_list); + mctx = sieve_match_begin(renv->interp, &mcht, &cmp, NULL, key_list); /* Iterate through all requested headers to match */ hdr_item = NULL; diff --git a/src/lib-sieve/tst-not.c b/src/lib-sieve/tst-not.c index be9490437..2147778d2 100644 --- a/src/lib-sieve/tst-not.c +++ b/src/lib-sieve/tst-not.c @@ -14,10 +14,10 @@ */ static bool tst_not_generate - (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx, + (const struct sieve_codegen_env *cgenv, struct sieve_command *ctx, struct sieve_jumplist *jumps, bool jump_true); -const struct sieve_command tst_not = { +const struct sieve_command_def tst_not = { "not", SCT_TEST, 0, 1, FALSE, FALSE, @@ -30,7 +30,7 @@ const struct sieve_command tst_not = { */ static bool tst_not_generate -(const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx, +(const struct sieve_codegen_env *cgenv, struct sieve_command *ctx, struct sieve_jumplist *jumps, bool jump_true) { struct sieve_ast_node *test; diff --git a/src/lib-sieve/tst-size.c b/src/lib-sieve/tst-size.c index fa89486c7..817b50a94 100644 --- a/src/lib-sieve/tst-size.c +++ b/src/lib-sieve/tst-size.c @@ -9,7 +9,7 @@ #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-interpreter.h" -#include "sieve-code-dumper.h" +#include "sieve-dump.h" /* * Size test @@ -19,16 +19,16 @@ */ static bool tst_size_registered - (struct sieve_validator *validator, + (struct sieve_validator *valdtr, const struct sieve_extension *ext, struct sieve_command_registration *cmd_reg); static bool tst_size_pre_validate - (struct sieve_validator *validator, struct sieve_command_context *tst); + (struct sieve_validator *valdtr, struct sieve_command *tst); static bool tst_size_validate - (struct sieve_validator *validator, struct sieve_command_context *tst); + (struct sieve_validator *valdtr, struct sieve_command *tst); static bool tst_size_generate - (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx); + (const struct sieve_codegen_env *cgenv, struct sieve_command *ctx); -const struct sieve_command tst_size = { +const struct sieve_command_def tst_size = { "size", SCT_TEST, 1, 0, FALSE, FALSE, @@ -44,13 +44,11 @@ const struct sieve_command tst_size = { */ static bool tst_size_operation_dump - (const struct sieve_operation *op, - const struct sieve_dumptime_env *denv, sieve_size_t *address); + (const struct sieve_dumptime_env *denv, sieve_size_t *address); static int tst_size_operation_execute - (const struct sieve_operation *op, - const struct sieve_runtime_env *renv, sieve_size_t *address); + (const struct sieve_runtime_env *renv, sieve_size_t *address); -const struct sieve_operation tst_size_over_operation = { +const struct sieve_operation_def tst_size_over_operation = { "SIZE-OVER", NULL, SIEVE_OPERATION_SIZE_OVER, @@ -58,7 +56,7 @@ const struct sieve_operation tst_size_over_operation = { tst_size_operation_execute }; -const struct sieve_operation tst_size_under_operation = { +const struct sieve_operation_def tst_size_under_operation = { "SIZE-UNDER", NULL, SIEVE_OPERATION_SIZE_UNDER, @@ -83,14 +81,14 @@ struct tst_size_context_data { */ static bool tst_size_validate_over_tag -(struct sieve_validator *validator, struct sieve_ast_argument **arg, - struct sieve_command_context *tst) +(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, + struct sieve_command *tst) { struct tst_size_context_data *ctx_data = (struct tst_size_context_data *) tst->data; if ( ctx_data->type != SIZE_UNASSIGNED ) { - sieve_argument_validate_error(validator, *arg, TST_SIZE_ERROR_DUP_TAG); + sieve_argument_validate_error(valdtr, *arg, TST_SIZE_ERROR_DUP_TAG); return FALSE; } @@ -103,14 +101,14 @@ static bool tst_size_validate_over_tag } static bool tst_size_validate_under_tag -(struct sieve_validator *validator, struct sieve_ast_argument **arg ATTR_UNUSED, - struct sieve_command_context *tst) +(struct sieve_validator *valdtr, struct sieve_ast_argument **arg ATTR_UNUSED, + struct sieve_command *tst) { struct tst_size_context_data *ctx_data = (struct tst_size_context_data *) tst->data; if ( ctx_data->type != SIZE_UNASSIGNED ) { - sieve_argument_validate_error(validator, *arg, TST_SIZE_ERROR_DUP_TAG); + sieve_argument_validate_error(valdtr, *arg, TST_SIZE_ERROR_DUP_TAG); return FALSE; } @@ -126,26 +124,27 @@ static bool tst_size_validate_under_tag * Test registration */ -static const struct sieve_argument size_over_tag = { +static const struct sieve_argument_def size_over_tag = { "over", - NULL, NULL, + NULL, tst_size_validate_over_tag, - NULL, NULL + NULL, NULL, NULL }; -static const struct sieve_argument size_under_tag = { +static const struct sieve_argument_def size_under_tag = { "under", - NULL, NULL, + NULL, tst_size_validate_under_tag, - NULL, NULL + NULL, NULL, NULL }; static bool tst_size_registered -(struct sieve_validator *validator, struct sieve_command_registration *cmd_reg) +(struct sieve_validator *valdtr, const struct sieve_extension *ext ATTR_UNUSED, + struct sieve_command_registration *cmd_reg) { /* Register our tags */ - sieve_validator_register_tag(validator, cmd_reg, &size_over_tag, 0); - sieve_validator_register_tag(validator, cmd_reg, &size_under_tag, 0); + sieve_validator_register_tag(valdtr, cmd_reg, NULL, &size_over_tag, 0); + sieve_validator_register_tag(valdtr, cmd_reg, NULL, &size_under_tag, 0); return TRUE; } @@ -155,8 +154,8 @@ static bool tst_size_registered */ static bool tst_size_pre_validate -(struct sieve_validator *validator ATTR_UNUSED, - struct sieve_command_context *tst) +(struct sieve_validator *valdtr ATTR_UNUSED, + struct sieve_command *tst) { struct tst_size_context_data *ctx_data; @@ -169,25 +168,25 @@ static bool tst_size_pre_validate } static bool tst_size_validate - (struct sieve_validator *validator, struct sieve_command_context *tst) + (struct sieve_validator *valdtr, struct sieve_command *tst) { struct tst_size_context_data *ctx_data = (struct tst_size_context_data *) tst->data; struct sieve_ast_argument *arg = tst->first_positional; if ( ctx_data->type == SIZE_UNASSIGNED ) { - sieve_command_validate_error(validator, tst, + sieve_command_validate_error(valdtr, tst, "the size test requires either the :under or the :over tag " "to be specified"); return FALSE; } if ( !sieve_validate_positional_argument - (validator, tst, arg, "limit", 1, SAAT_NUMBER) ) { + (valdtr, tst, arg, "limit", 1, SAAT_NUMBER) ) { return FALSE; } - return sieve_validator_argument_activate(validator, tst, arg, FALSE); + return sieve_validator_argument_activate(valdtr, tst, arg, FALSE); } /* @@ -195,18 +194,18 @@ static bool tst_size_validate */ bool tst_size_generate -(const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx) +(const struct sieve_codegen_env *cgenv, struct sieve_command *tst) { struct tst_size_context_data *ctx_data = - (struct tst_size_context_data *) ctx->data; + (struct tst_size_context_data *) tst->data; if ( ctx_data->type == SIZE_OVER ) - sieve_operation_emit_code(cgenv->sbin, &tst_size_over_operation); + sieve_operation_emit(cgenv->sbin, NULL, &tst_size_over_operation); else - sieve_operation_emit_code(cgenv->sbin, &tst_size_under_operation); + sieve_operation_emit(cgenv->sbin, NULL, &tst_size_under_operation); /* Generate arguments */ - if ( !sieve_generate_arguments(cgenv, ctx, NULL) ) + if ( !sieve_generate_arguments(cgenv, tst, NULL) ) return FALSE; return TRUE; @@ -217,10 +216,10 @@ bool tst_size_generate */ static bool tst_size_operation_dump -(const struct sieve_operation *op, - const struct sieve_dumptime_env *denv, sieve_size_t *address) +(const struct sieve_dumptime_env *denv, sieve_size_t *address) { - sieve_code_dumpf(denv, "%s", op->mnemonic); + const struct sieve_operation *op = &denv->oprtn; + sieve_code_dumpf(denv, "%s", sieve_operation_mnemonic(op)); sieve_code_descend(denv); return @@ -245,9 +244,9 @@ static inline bool tst_size_get } static int tst_size_operation_execute -(const struct sieve_operation *op, - const struct sieve_runtime_env *renv, sieve_size_t *address) +(const struct sieve_runtime_env *renv, sieve_size_t *address) { + const struct sieve_operation *op = &renv->oprtn; sieve_number_t mail_size, limit; /* Read size limit */ @@ -256,7 +255,7 @@ static int tst_size_operation_execute return SIEVE_EXEC_BIN_CORRUPT; } - sieve_runtime_trace(renv, "%s test", op->mnemonic); + sieve_runtime_trace(renv, "%s test", sieve_operation_mnemonic(op)); /* Get the size of the message */ if ( !tst_size_get(renv, &mail_size) ) { @@ -266,7 +265,7 @@ static int tst_size_operation_execute } /* Perform the test */ - if ( op == &tst_size_over_operation ) + if ( sieve_operation_is(op, tst_size_over_operation) ) sieve_interpreter_set_test_result(renv->interp, (mail_size > limit)); else sieve_interpreter_set_test_result(renv->interp, (mail_size < limit)); diff --git a/src/lib-sieve/tst-truefalse.c b/src/lib-sieve/tst-truefalse.c index 17deee35b..08bb1e5de 100644 --- a/src/lib-sieve/tst-truefalse.c +++ b/src/lib-sieve/tst-truefalse.c @@ -15,13 +15,13 @@ */ static bool tst_false_generate - (const struct sieve_codegen_env *cgenv, struct sieve_command_context *cmd, + (const struct sieve_codegen_env *cgenv, struct sieve_command *cmd, struct sieve_jumplist *jumps, bool jump_true); static bool tst_true_generate - (const struct sieve_codegen_env *cgenv, struct sieve_command_context *cmd, + (const struct sieve_codegen_env *cgenv, struct sieve_command *cmd, struct sieve_jumplist *jumps, bool jump_true); -const struct sieve_command tst_false = { +const struct sieve_command_def tst_false = { "false", SCT_TEST, 0, 0, FALSE, FALSE, @@ -29,7 +29,7 @@ const struct sieve_command tst_false = { tst_false_generate }; -const struct sieve_command tst_true = { +const struct sieve_command_def tst_true = { "true", SCT_TEST, 0, 0, FALSE, FALSE, @@ -39,11 +39,11 @@ const struct sieve_command tst_true = { static bool tst_false_generate (const struct sieve_codegen_env *cgenv, - struct sieve_command_context *cmd ATTR_UNUSED, + struct sieve_command *cmd ATTR_UNUSED, struct sieve_jumplist *jumps, bool jump_true) { if ( !jump_true ) { - sieve_operation_emit_code(cgenv->sbin, &sieve_jmp_operation); + sieve_operation_emit(cgenv->sbin, NULL, &sieve_jmp_operation); sieve_jumplist_add(jumps, sieve_binary_emit_offset(cgenv->sbin, 0)); } @@ -52,11 +52,11 @@ static bool tst_false_generate static bool tst_true_generate (const struct sieve_codegen_env *cgenv, - struct sieve_command_context *cmd ATTR_UNUSED, + struct sieve_command *cmd ATTR_UNUSED, struct sieve_jumplist *jumps, bool jump_true) { if ( jump_true ) { - sieve_operation_emit_code(cgenv->sbin, &sieve_jmp_operation); + sieve_operation_emit(cgenv->sbin, NULL, &sieve_jmp_operation); sieve_jumplist_add(jumps, sieve_binary_emit_offset(cgenv->sbin, 0)); } diff --git a/src/plugins/lda-sieve/lda-sieve-plugin.c b/src/plugins/lda-sieve/lda-sieve-plugin.c index c7240d1b2..1b4126c4a 100644 --- a/src/plugins/lda-sieve/lda-sieve-plugin.c +++ b/src/plugins/lda-sieve/lda-sieve-plugin.c @@ -34,20 +34,27 @@ */ static deliver_mail_func_t *next_deliver_mail; -struct mail_user *lda_sieve_mail_user = NULL; /* * Settings handling */ -static const char *lda_sieve_setting_get(const char *identifier) +static const char *lda_sieve_get_setting +(void *context, const char *identifier) { - if ( lda_sieve_mail_user == NULL ) + struct mail_user *mail_user = (struct mail_user *) context; + + if ( mail_user == NULL ) return NULL; - return mail_user_plugin_getenv(lda_sieve_mail_user, identifier); + return mail_user_plugin_getenv(mail_user, identifier); } +static const struct sieve_callbacks lda_sieve_callbacks = { + lda_sieve_get_setting +}; + + /* * Mail transmission */ @@ -74,6 +81,8 @@ static bool lda_sieve_smtp_close */ struct lda_sieve_run_context { + struct sieve_instance *svinst; + struct mail_deliver_context *mdctx; const char *const *script_files; @@ -183,6 +192,7 @@ static int lda_sieve_open (struct lda_sieve_run_context *srctx, unsigned int script_index, struct sieve_binary **sbin) { + struct sieve_instance *svinst = srctx->svinst; const char *script_path = srctx->script_files[script_index]; const char *script_name = ( script_path == srctx->main_script ? "main_script" : NULL ); @@ -201,7 +211,7 @@ static int lda_sieve_open sieve_error_handler_reset(ehandler); - if ( (*sbin=sieve_open(script_path, script_name, ehandler, &exists)) + if ( (*sbin=sieve_open(svinst, script_path, script_name, ehandler, &exists)) == NULL ) { ret = sieve_get_errors(ehandler) > 0 ? -1 : 0; @@ -231,6 +241,7 @@ static int lda_sieve_open static struct sieve_binary *lda_sieve_recompile (struct lda_sieve_run_context *srctx, unsigned int script_index) { + struct sieve_instance *svinst = srctx->svinst; const char *script_path = srctx->script_files[script_index]; const char *script_name = ( script_path == srctx->main_script ? "main_script" : NULL ); @@ -249,7 +260,8 @@ static struct sieve_binary *lda_sieve_recompile else ehandler = srctx->master_ehandler; - if ( (sbin=sieve_compile(script_path, script_name, ehandler)) == NULL ) { + if ( (sbin=sieve_compile + (svinst, script_path, script_name, ehandler)) == NULL ) { if ( script_path == srctx->user_script && srctx->userlog != NULL ) { sieve_sys_error @@ -366,6 +378,7 @@ static int lda_sieve_singlescript_execute static int lda_sieve_multiscript_execute (struct lda_sieve_run_context *srctx) { + struct sieve_instance *svinst = srctx->svinst; const char *const *scripts = srctx->script_files; unsigned int count = srctx->script_count; struct sieve_multiscript *mscript; @@ -378,7 +391,8 @@ static int lda_sieve_multiscript_execute /* Start execution */ - mscript = sieve_multiscript_start_execute(srctx->msgdata, srctx->scriptenv); + mscript = sieve_multiscript_start_execute + (svinst, srctx->msgdata, srctx->scriptenv); /* Execute scripts before main script */ @@ -462,18 +476,30 @@ static int lda_sieve_run const ARRAY_TYPE (const_string) *scripts_after, struct mail_storage **storage_r) { + struct sieve_instance *svinst; ARRAY_TYPE (const_string) scripts; struct lda_sieve_run_context srctx; struct sieve_message_data msgdata; struct sieve_script_env scriptenv; struct sieve_exec_status estatus; + const char *extensions = NULL; int ret = 0; *storage_r = NULL; + /* Initialize Sieve engine */ + svinst = sieve_init(&lda_sieve_callbacks, mdctx->dest_user); + + extensions = mail_user_plugin_getenv + (mdctx->dest_user, "sieve_extensions"); + if ( extensions != NULL ) { + sieve_set_extensions(svinst, extensions); + } + /* Initialize */ memset(&srctx, 0, sizeof(srctx)); + srctx.svinst = svinst; srctx.mdctx = mdctx; /* Compose execution sequence */ @@ -501,10 +527,12 @@ static int lda_sieve_run if ( user_script != NULL ) { srctx.userlog = t_strconcat(user_script, ".log", NULL); - srctx.user_ehandler = sieve_logfile_ehandler_create(srctx.userlog, LDA_SIEVE_MAX_USER_ERRORS); + srctx.user_ehandler = sieve_logfile_ehandler_create + (srctx.userlog, LDA_SIEVE_MAX_USER_ERRORS); } - srctx.master_ehandler = sieve_master_ehandler_create(LDA_SIEVE_MAX_SYSTEM_ERRORS); + srctx.master_ehandler = + sieve_master_ehandler_create(LDA_SIEVE_MAX_SYSTEM_ERRORS); sieve_error_handler_accept_infolog(srctx.master_ehandler, TRUE); /* Collect necessary message data */ @@ -562,6 +590,9 @@ static int lda_sieve_run sieve_error_handler_unref(&srctx.user_ehandler); sieve_error_handler_unref(&srctx.master_ehandler); + /* Deinitialize Sieve engine */ + sieve_deinit(&svinst); + return ret; } @@ -577,13 +608,6 @@ static int lda_sieve_deliver_mail *storage_r = NULL; - lda_sieve_mail_user = mdctx->dest_user; - - extensions = sieve_setting_get("extensions"); - if ( extensions != NULL ) { - sieve_set_extensions(extensions); - } - T_BEGIN { struct stat st; @@ -677,9 +701,6 @@ static int lda_sieve_deliver_mail void sieve_plugin_init(void) { - /* Initialize Sieve engine */ - sieve_init(lda_sieve_setting_get); - /* Hook into the delivery process */ next_deliver_mail = deliver_mail; deliver_mail = lda_sieve_deliver_mail; @@ -689,7 +710,4 @@ void sieve_plugin_deinit(void) { /* Remove hook */ deliver_mail = next_deliver_mail; - - /* Deinitialize Sieve engine */ - sieve_deinit(); } diff --git a/src/sieve-tools/debug/cmd-debug-print.c b/src/sieve-tools/debug/cmd-debug-print.c index 22c043e4a..87b998f1b 100644 --- a/src/sieve-tools/debug/cmd-debug-print.c +++ b/src/sieve-tools/debug/cmd-debug-print.c @@ -21,11 +21,11 @@ */ static bool cmd_debug_print_validate - (struct sieve_validator *validator, struct sieve_command_context *tst); + (struct sieve_validator *valdtr, struct sieve_command *tst); static bool cmd_debug_print_generate - (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx); + (const struct sieve_codegen_env *cgenv, struct sieve_command *ctx); -const struct sieve_command debug_print_command = { +const struct sieve_command_def debug_print_command = { "debug_print", SCT_COMMAND, 1, 0, FALSE, FALSE, @@ -40,13 +40,11 @@ const struct sieve_command debug_print_command = { */ static bool cmd_debug_print_operation_dump - (const struct sieve_operation *op, - const struct sieve_dumptime_env *denv, sieve_size_t *address); + (const struct sieve_dumptime_env *denv, sieve_size_t *address); static int cmd_debug_print_operation_execute - (const struct sieve_operation *op, - const struct sieve_runtime_env *renv, sieve_size_t *address); + (const struct sieve_runtime_env *renv, sieve_size_t *address); -const struct sieve_operation debug_print_operation = { +const struct sieve_operation_def debug_print_operation = { "debug_print", &debug_extension, 0, @@ -59,16 +57,16 @@ const struct sieve_operation debug_print_operation = { */ static bool cmd_debug_print_validate -(struct sieve_validator *validator, struct sieve_command_context *tst) +(struct sieve_validator *valdtr, struct sieve_command *tst) { struct sieve_ast_argument *arg = tst->first_positional; if ( !sieve_validate_positional_argument - (validator, tst, arg, "message", 1, SAAT_STRING) ) { + (valdtr, tst, arg, "message", 1, SAAT_STRING) ) { return FALSE; } - return sieve_validator_argument_activate(validator, tst, arg, FALSE); + return sieve_validator_argument_activate(valdtr, tst, arg, FALSE); } /* @@ -76,12 +74,12 @@ static bool cmd_debug_print_validate */ static bool cmd_debug_print_generate - (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx) +(const struct sieve_codegen_env *cgenv, struct sieve_command *cmd) { - (void)sieve_operation_emit_code(cgenv->sbin, &debug_print_operation); + (void)sieve_operation_emit(cgenv->sbin, cmd->ext, &debug_print_operation); /* Generate arguments */ - return sieve_generate_arguments(cgenv, ctx, NULL); + return sieve_generate_arguments(cgenv, cmd, NULL); } /* @@ -89,8 +87,7 @@ static bool cmd_debug_print_generate */ static bool cmd_debug_print_operation_dump -(const struct sieve_operation *op ATTR_UNUSED, - const struct sieve_dumptime_env *denv, sieve_size_t *address) +(const struct sieve_dumptime_env *denv, sieve_size_t *address) { sieve_code_dumpf(denv, "DEBUG_PRINT"); sieve_code_descend(denv); @@ -103,8 +100,7 @@ static bool cmd_debug_print_operation_dump */ static int cmd_debug_print_operation_execute -(const struct sieve_operation *op ATTR_UNUSED, - const struct sieve_runtime_env *renv, sieve_size_t *address) +(const struct sieve_runtime_env *renv, sieve_size_t *address) { string_t *message; int ret = SIEVE_EXEC_OK; diff --git a/src/sieve-tools/debug/ext-debug-common.h b/src/sieve-tools/debug/ext-debug-common.h index 79bde2f45..f99eca51a 100644 --- a/src/sieve-tools/debug/ext-debug-common.h +++ b/src/sieve-tools/debug/ext-debug-common.h @@ -10,12 +10,12 @@ * Commands */ -extern const struct sieve_command debug_print_command; +extern const struct sieve_command_def debug_print_command; /* * Operations */ -extern const struct sieve_operation debug_print_operation; +extern const struct sieve_operation_def debug_print_operation; #endif /* __EXT_DEBUG_COMMON_H */ diff --git a/src/sieve-tools/debug/ext-debug.c b/src/sieve-tools/debug/ext-debug.c index 500090d7b..36d3e5d89 100644 --- a/src/sieve-tools/debug/ext-debug.c +++ b/src/sieve-tools/debug/ext-debug.c @@ -32,13 +32,11 @@ * Extension */ -static bool ext_debug_validator_load(struct sieve_validator *validator); +static bool ext_debug_validator_load +(const struct sieve_extension *ext, struct sieve_validator *validator); -int ext_debug_my_id = -1; - -const struct sieve_extension debug_extension = { +const struct sieve_extension_def debug_extension = { "vnd.dovecot.debug", - &ext_debug_my_id, NULL, NULL, ext_debug_validator_load, NULL, NULL, NULL, NULL, NULL, @@ -46,10 +44,11 @@ const struct sieve_extension debug_extension = { SIEVE_EXT_DEFINE_NO_OPERANDS }; -static bool ext_debug_validator_load(struct sieve_validator *validator) +static bool ext_debug_validator_load +(const struct sieve_extension *ext, struct sieve_validator *validator) { /* Register new test */ - sieve_validator_register_command(validator, &debug_print_command); + sieve_validator_register_command(validator, ext, &debug_print_command); return TRUE; } diff --git a/src/sieve-tools/debug/sieve-ext-debug.h b/src/sieve-tools/debug/sieve-ext-debug.h index 31b317826..12cdf670a 100644 --- a/src/sieve-tools/debug/sieve-ext-debug.h +++ b/src/sieve-tools/debug/sieve-ext-debug.h @@ -8,6 +8,6 @@ * Extension */ -extern const struct sieve_extension debug_extension; +extern const struct sieve_extension_def debug_extension; #endif /* __SIEVE_EXT_DEBUG_H */ diff --git a/src/sieve-tools/sieve-filter.c b/src/sieve-tools/sieve-filter.c index 9b72f8261..6f1ce2691 100644 --- a/src/sieve-tools/sieve-filter.c +++ b/src/sieve-tools/sieve-filter.c @@ -277,11 +277,11 @@ int main(int argc, char **argv) } if ( extensions != NULL ) { - sieve_set_extensions(extensions); + sieve_set_extensions(sieve_instance, extensions); } /* Register tool-specific extensions */ - (void) sieve_extension_register(&debug_extension, TRUE); + (void) sieve_extension_register(sieve_instance, &debug_extension, TRUE); /* Create error handler */ ehandler = sieve_stderr_ehandler_create(0); diff --git a/src/sieve-tools/sieve-test.c b/src/sieve-tools/sieve-test.c index 4ad590911..56d3d5f58 100644 --- a/src/sieve-tools/sieve-test.c +++ b/src/sieve-tools/sieve-test.c @@ -204,11 +204,11 @@ int main(int argc, char **argv) } if ( extensions != NULL ) { - sieve_set_extensions(extensions); + sieve_set_extensions(sieve_instance, extensions); } /* Register tool-specific extensions */ - (void) sieve_extension_register(&debug_extension, TRUE); + (void) sieve_extension_register(sieve_instance, &debug_extension, TRUE); /* Create error handler */ ehandler = sieve_stderr_ehandler_create(0); @@ -331,10 +331,10 @@ int main(int argc, char **argv) if ( execute ) mscript = sieve_multiscript_start_execute - (&msgdata, &scriptenv); + (sieve_instance, &msgdata, &scriptenv); else mscript = sieve_multiscript_start_test - (&msgdata, &scriptenv, teststream); + (sieve_instance, &msgdata, &scriptenv, teststream); /* Execute scripts sequentially */ sfiles = array_get(&scriptfiles, &count); diff --git a/src/sieve-tools/sievec.c b/src/sieve-tools/sievec.c index 5143a4c74..2de0e9570 100644 --- a/src/sieve-tools/sievec.c +++ b/src/sieve-tools/sievec.c @@ -75,11 +75,11 @@ int main(int argc, char **argv) { outfile = "-"; if ( extensions != NULL ) { - sieve_set_extensions(extensions); + sieve_set_extensions(sieve_instance, extensions); } /* Register tool-specific extensions */ - (void) sieve_extension_register(&debug_extension, TRUE); + (void) sieve_extension_register(sieve_instance, &debug_extension, TRUE); if ( stat(scriptfile, &st) == 0 && S_ISDIR(st.st_mode) ) { /* Script directory */ diff --git a/src/sieve-tools/sieved.c b/src/sieve-tools/sieved.c index 1b1e7c90e..3b2d5321c 100644 --- a/src/sieve-tools/sieved.c +++ b/src/sieve-tools/sieved.c @@ -65,13 +65,13 @@ int main(int argc, char **argv) { } if ( extensions != NULL ) { - sieve_set_extensions(extensions); + sieve_set_extensions(sieve_instance, extensions); } /* Register tool-specific extensions */ - (void) sieve_extension_register(&debug_extension, TRUE); + (void) sieve_extension_register(sieve_instance, &debug_extension, TRUE); - sbin = sieve_load(binfile); + sbin = sieve_load(sieve_instance, binfile); if ( sbin != NULL ) { sieve_tool_dump_binary_to(sbin, outfile == NULL ? "-" : outfile); diff --git a/src/testsuite/cmd-test-binary.c b/src/testsuite/cmd-test-binary.c index b72c92388..b9321a782 100644 --- a/src/testsuite/cmd-test-binary.c +++ b/src/testsuite/cmd-test-binary.c @@ -22,14 +22,14 @@ */ static bool cmd_test_binary_registered - (struct sieve_validator *valdtr, + (struct sieve_validator *valdtr, const struct sieve_extension *ext, struct sieve_command_registration *cmd_reg); static bool cmd_test_binary_validate - (struct sieve_validator *valdtr, struct sieve_command_context *cmd); + (struct sieve_validator *valdtr, struct sieve_command *cmd); static bool cmd_test_binary_generate - (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx); + (const struct sieve_codegen_env *cgenv, struct sieve_command *ctx); -const struct sieve_command cmd_test_binary = { +const struct sieve_command_def cmd_test_binary = { "test_binary", SCT_COMMAND, 1, 0, FALSE, FALSE, @@ -45,15 +45,13 @@ const struct sieve_command cmd_test_binary = { */ static bool cmd_test_binary_operation_dump - (const struct sieve_operation *op, - const struct sieve_dumptime_env *denv, sieve_size_t *address); + (const struct sieve_dumptime_env *denv, sieve_size_t *address); static int cmd_test_binary_operation_execute - (const struct sieve_operation *op, - const struct sieve_runtime_env *renv, sieve_size_t *address); + (const struct sieve_runtime_env *renv, sieve_size_t *address); /* test_binary_create operation */ -const struct sieve_operation test_binary_load_operation = { +const struct sieve_operation_def test_binary_load_operation = { "TEST_BINARY_LOAD", &testsuite_extension, TESTSUITE_OPERATION_TEST_BINARY_LOAD, @@ -63,7 +61,7 @@ const struct sieve_operation test_binary_load_operation = { /* test_binary_delete operation */ -const struct sieve_operation test_binary_save_operation = { +const struct sieve_operation_def test_binary_save_operation = { "TEST_BINARY_SAVE", &testsuite_extension, TESTSUITE_OPERATION_TEST_BINARY_SAVE, @@ -81,7 +79,7 @@ enum test_binary_operation { BINARY_OP_LAST }; -const struct sieve_operation *test_binary_operations[] = { +const struct sieve_operation_def *test_binary_operations[] = { &test_binary_load_operation, &test_binary_save_operation }; @@ -97,35 +95,36 @@ struct cmd_test_binary_context_data { static bool cmd_test_binary_validate_tag (struct sieve_validator *valdtr, struct sieve_ast_argument **arg, - struct sieve_command_context *cmd); + struct sieve_command *cmd); -static const struct sieve_argument test_binary_load_tag = { +static const struct sieve_argument_def test_binary_load_tag = { "load", - NULL, NULL, + NULL, cmd_test_binary_validate_tag, - NULL, NULL + NULL, NULL, NULL, }; -static const struct sieve_argument test_binary_save_tag = { +static const struct sieve_argument_def test_binary_save_tag = { "save", - NULL, NULL, + NULL, cmd_test_binary_validate_tag, - NULL, NULL + NULL, NULL, NULL, }; static bool cmd_test_binary_registered -(struct sieve_validator *valdtr, struct sieve_command_registration *cmd_reg) +(struct sieve_validator *valdtr, const struct sieve_extension *ext, + struct sieve_command_registration *cmd_reg) { /* Register our tags */ - sieve_validator_register_tag(valdtr, cmd_reg, &test_binary_load_tag, 0); - sieve_validator_register_tag(valdtr, cmd_reg, &test_binary_save_tag, 0); + sieve_validator_register_tag(valdtr, cmd_reg, ext, &test_binary_load_tag, 0); + sieve_validator_register_tag(valdtr, cmd_reg, ext, &test_binary_save_tag, 0); return TRUE; } static bool cmd_test_binary_validate_tag (struct sieve_validator *valdtr, struct sieve_ast_argument **arg, - struct sieve_command_context *cmd) + struct sieve_command *cmd) { struct cmd_test_binary_context_data *ctx_data = (struct cmd_test_binary_context_data *) cmd->data; @@ -141,7 +140,7 @@ static bool cmd_test_binary_validate_tag (sieve_command_pool(cmd), struct cmd_test_binary_context_data, 1); cmd->data = ctx_data; - if ( (*arg)->argument == &test_binary_load_tag ) + if ( sieve_argument_is(*arg, test_binary_load_tag) ) ctx_data->binary_op = BINARY_OP_LOAD; else ctx_data->binary_op = BINARY_OP_SAVE; @@ -157,8 +156,8 @@ static bool cmd_test_binary_validate_tag */ static bool cmd_test_binary_validate -(struct sieve_validator *valdtr, struct sieve_command_context *cmd) -{ +(struct sieve_validator *valdtr, struct sieve_command *cmd) +{ struct sieve_ast_argument *arg = cmd->first_positional; if ( cmd->data == NULL ) { @@ -181,7 +180,7 @@ static bool cmd_test_binary_validate */ static bool cmd_test_binary_generate -(const struct sieve_codegen_env *cgenv, struct sieve_command_context *cmd) +(const struct sieve_codegen_env *cgenv, struct sieve_command *cmd) { struct cmd_test_binary_context_data *ctx_data = (struct cmd_test_binary_context_data *) cmd->data; @@ -189,7 +188,7 @@ static bool cmd_test_binary_generate i_assert( ctx_data->binary_op < BINARY_OP_LAST ); /* Emit operation */ - sieve_operation_emit_code(cgenv->sbin, + sieve_operation_emit(cgenv->sbin, cmd->ext, test_binary_operations[ctx_data->binary_op]); /* Generate arguments */ @@ -204,10 +203,11 @@ static bool cmd_test_binary_generate */ static bool cmd_test_binary_operation_dump -(const struct sieve_operation *op, - const struct sieve_dumptime_env *denv, sieve_size_t *address) +(const struct sieve_dumptime_env *denv, sieve_size_t *address) { - sieve_code_dumpf(denv, "%s:", op->mnemonic); + const struct sieve_operation *op = &denv->oprtn; + + sieve_code_dumpf(denv, "%s:", sieve_operation_mnemonic(op)); sieve_code_descend(denv); @@ -220,9 +220,9 @@ static bool cmd_test_binary_operation_dump */ static int cmd_test_binary_operation_execute -(const struct sieve_operation *op, - const struct sieve_runtime_env *renv, sieve_size_t *address) +(const struct sieve_runtime_env *renv, sieve_size_t *address) { + const struct sieve_operation *op = &renv->oprtn; string_t *binary_name = NULL; /* @@ -240,9 +240,10 @@ static int cmd_test_binary_operation_execute * Perform operation */ - sieve_runtime_trace(renv, "%s %s:", op->mnemonic, str_c(binary_name)); + sieve_runtime_trace + (renv, "%s %s:", sieve_operation_mnemonic(op), str_c(binary_name)); - if ( op == &test_binary_load_operation ) { + if ( sieve_operation_is(op, test_binary_load_operation) ) { struct sieve_binary *sbin = testsuite_binary_load(str_c(binary_name)); if ( sbin != NULL ) { @@ -254,7 +255,7 @@ static int cmd_test_binary_operation_execute return SIEVE_EXEC_FAILURE; } - } else if ( op == &test_binary_save_operation ) { + } else if ( sieve_operation_is(op, test_binary_save_operation) ) { struct sieve_binary *sbin = testsuite_script_get_binary(); if ( sbin != NULL ) @@ -263,6 +264,8 @@ static int cmd_test_binary_operation_execute sieve_sys_error("no compiled binary to save as %s", str_c(binary_name)); return SIEVE_EXEC_FAILURE; } + } else { + i_unreached(); } return SIEVE_EXEC_OK; diff --git a/src/testsuite/cmd-test-fail.c b/src/testsuite/cmd-test-fail.c index c1185e91f..685e1ec51 100644 --- a/src/testsuite/cmd-test-fail.c +++ b/src/testsuite/cmd-test-fail.c @@ -20,11 +20,11 @@ */ static bool cmd_test_fail_validate - (struct sieve_validator *validator, struct sieve_command_context *cmd); + (struct sieve_validator *valdtr, struct sieve_command *cmd); static bool cmd_test_fail_generate - (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx); + (const struct sieve_codegen_env *cgenv, struct sieve_command *ctx); -const struct sieve_command cmd_test_fail = { +const struct sieve_command_def cmd_test_fail = { "test_fail", SCT_COMMAND, 1, 0, FALSE, FALSE, @@ -39,13 +39,11 @@ const struct sieve_command cmd_test_fail = { */ static bool cmd_test_fail_operation_dump - (const struct sieve_operation *op, - const struct sieve_dumptime_env *denv, sieve_size_t *address); + (const struct sieve_dumptime_env *denv, sieve_size_t *address); static int cmd_test_fail_operation_execute - (const struct sieve_operation *op, - const struct sieve_runtime_env *renv, sieve_size_t *address); + (const struct sieve_runtime_env *renv, sieve_size_t *address); -const struct sieve_operation test_fail_operation = { +const struct sieve_operation_def test_fail_operation = { "TEST_FAIL", &testsuite_extension, TESTSUITE_OPERATION_TEST_FAIL, @@ -58,7 +56,7 @@ const struct sieve_operation test_fail_operation = { */ static bool cmd_test_fail_validate -(struct sieve_validator *valdtr ATTR_UNUSED, struct sieve_command_context *cmd) +(struct sieve_validator *valdtr ATTR_UNUSED, struct sieve_command *cmd) { struct sieve_ast_argument *arg = cmd->first_positional; @@ -78,19 +76,19 @@ static inline struct testsuite_generator_context * _get_generator_context(struct sieve_generator *gentr) { return (struct testsuite_generator_context *) - sieve_generator_extension_get_context(gentr, &testsuite_extension); + sieve_generator_extension_get_context(gentr, testsuite_ext); } static bool cmd_test_fail_generate -(const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx) +(const struct sieve_codegen_env *cgenv, struct sieve_command *cmd) { struct testsuite_generator_context *genctx = _get_generator_context(cgenv->gentr); - sieve_operation_emit_code(cgenv->sbin, &test_fail_operation); + sieve_operation_emit(cgenv->sbin, cmd->ext, &test_fail_operation); /* Generate arguments */ - if ( !sieve_generate_arguments(cgenv, ctx, NULL) ) + if ( !sieve_generate_arguments(cgenv, cmd, NULL) ) return FALSE; sieve_jumplist_add(genctx->exit_jumps, @@ -104,8 +102,7 @@ static bool cmd_test_fail_generate */ static bool cmd_test_fail_operation_dump -(const struct sieve_operation *op ATTR_UNUSED, - const struct sieve_dumptime_env *denv, sieve_size_t *address) +(const struct sieve_dumptime_env *denv, sieve_size_t *address) { unsigned int pc; int offset; @@ -131,8 +128,7 @@ static bool cmd_test_fail_operation_dump */ static int cmd_test_fail_operation_execute -(const struct sieve_operation *op ATTR_UNUSED, - const struct sieve_runtime_env *renv, sieve_size_t *address) +(const struct sieve_runtime_env *renv, sieve_size_t *address) { string_t *reason; diff --git a/src/testsuite/cmd-test-mailbox.c b/src/testsuite/cmd-test-mailbox.c index f1ad7e12d..d1f585da7 100644 --- a/src/testsuite/cmd-test-mailbox.c +++ b/src/testsuite/cmd-test-mailbox.c @@ -21,14 +21,14 @@ */ static bool cmd_test_mailbox_registered - (struct sieve_validator *valdtr, + (struct sieve_validator *valdtr, const struct sieve_extension *ext, struct sieve_command_registration *cmd_reg); static bool cmd_test_mailbox_validate - (struct sieve_validator *valdtr, struct sieve_command_context *cmd); + (struct sieve_validator *valdtr, struct sieve_command *cmd); static bool cmd_test_mailbox_generate - (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx); + (const struct sieve_codegen_env *cgenv, struct sieve_command *ctx); -const struct sieve_command cmd_test_mailbox = { +const struct sieve_command_def cmd_test_mailbox = { "test_mailbox", SCT_COMMAND, 1, 0, FALSE, FALSE, @@ -44,15 +44,13 @@ const struct sieve_command cmd_test_mailbox = { */ static bool cmd_test_mailbox_operation_dump - (const struct sieve_operation *op, - const struct sieve_dumptime_env *denv, sieve_size_t *address); + (const struct sieve_dumptime_env *denv, sieve_size_t *address); static int cmd_test_mailbox_operation_execute - (const struct sieve_operation *op, - const struct sieve_runtime_env *renv, sieve_size_t *address); + (const struct sieve_runtime_env *renv, sieve_size_t *address); /* Test_mailbox_create operation */ -const struct sieve_operation test_mailbox_create_operation = { +const struct sieve_operation_def test_mailbox_create_operation = { "TEST_MAILBOX_CREATE", &testsuite_extension, TESTSUITE_OPERATION_TEST_MAILBOX_CREATE, @@ -62,7 +60,7 @@ const struct sieve_operation test_mailbox_create_operation = { /* Test_mailbox_delete operation */ -const struct sieve_operation test_mailbox_delete_operation = { +const struct sieve_operation_def test_mailbox_delete_operation = { "TEST_MAILBOX_DELETE", &testsuite_extension, TESTSUITE_OPERATION_TEST_MAILBOX_DELETE, @@ -80,7 +78,7 @@ enum test_mailbox_operation { MAILBOX_OP_LAST }; -const struct sieve_operation *test_mailbox_operations[] = { +const struct sieve_operation_def *test_mailbox_operations[] = { &test_mailbox_create_operation, &test_mailbox_delete_operation }; @@ -96,35 +94,38 @@ struct cmd_test_mailbox_context_data { static bool cmd_test_mailbox_validate_tag (struct sieve_validator *valdtr, struct sieve_ast_argument **arg, - struct sieve_command_context *cmd); + struct sieve_command *cmd); -static const struct sieve_argument test_mailbox_create_tag = { +static const struct sieve_argument_def test_mailbox_create_tag = { "create", - NULL, NULL, + NULL, cmd_test_mailbox_validate_tag, - NULL, NULL + NULL, NULL, NULL }; -static const struct sieve_argument test_mailbox_delete_tag = { +static const struct sieve_argument_def test_mailbox_delete_tag = { "delete", - NULL, NULL, + NULL, cmd_test_mailbox_validate_tag, - NULL, NULL + NULL, NULL, NULL }; static bool cmd_test_mailbox_registered -(struct sieve_validator *valdtr, struct sieve_command_registration *cmd_reg) +(struct sieve_validator *valdtr, const struct sieve_extension *ext, + struct sieve_command_registration *cmd_reg) { /* Register our tags */ - sieve_validator_register_tag(valdtr, cmd_reg, &test_mailbox_create_tag, 0); - sieve_validator_register_tag(valdtr, cmd_reg, &test_mailbox_delete_tag, 0); + sieve_validator_register_tag + (valdtr, cmd_reg, ext, &test_mailbox_create_tag, 0); + sieve_validator_register_tag + (valdtr, cmd_reg, ext, &test_mailbox_delete_tag, 0); return TRUE; } static bool cmd_test_mailbox_validate_tag (struct sieve_validator *valdtr, struct sieve_ast_argument **arg, - struct sieve_command_context *cmd) + struct sieve_command *cmd) { struct cmd_test_mailbox_context_data *ctx_data = (struct cmd_test_mailbox_context_data *) cmd->data; @@ -140,7 +141,7 @@ static bool cmd_test_mailbox_validate_tag (sieve_command_pool(cmd), struct cmd_test_mailbox_context_data, 1); cmd->data = ctx_data; - if ( (*arg)->argument == &test_mailbox_create_tag ) + if ( sieve_argument_is(*arg, test_mailbox_create_tag) ) ctx_data->mailbox_op = MAILBOX_OP_CREATE; else ctx_data->mailbox_op = MAILBOX_OP_DELETE; @@ -156,7 +157,7 @@ static bool cmd_test_mailbox_validate_tag */ static bool cmd_test_mailbox_validate -(struct sieve_validator *valdtr, struct sieve_command_context *cmd) +(struct sieve_validator *valdtr, struct sieve_command *cmd) { struct sieve_ast_argument *arg = cmd->first_positional; @@ -180,7 +181,7 @@ static bool cmd_test_mailbox_validate */ static bool cmd_test_mailbox_generate -(const struct sieve_codegen_env *cgenv, struct sieve_command_context *cmd) +(const struct sieve_codegen_env *cgenv, struct sieve_command *cmd) { struct cmd_test_mailbox_context_data *ctx_data = (struct cmd_test_mailbox_context_data *) cmd->data; @@ -188,7 +189,7 @@ static bool cmd_test_mailbox_generate i_assert( ctx_data->mailbox_op < MAILBOX_OP_LAST ); /* Emit operation */ - sieve_operation_emit_code(cgenv->sbin, + sieve_operation_emit(cgenv->sbin, cmd->ext, test_mailbox_operations[ctx_data->mailbox_op]); /* Generate arguments */ @@ -203,10 +204,11 @@ static bool cmd_test_mailbox_generate */ static bool cmd_test_mailbox_operation_dump -(const struct sieve_operation *op, - const struct sieve_dumptime_env *denv, sieve_size_t *address) +(const struct sieve_dumptime_env *denv, sieve_size_t *address) { - sieve_code_dumpf(denv, "%s:", op->mnemonic); + const struct sieve_operation *op = &denv->oprtn; + + sieve_code_dumpf(denv, "%s:", sieve_operation_mnemonic(op)); sieve_code_descend(denv); @@ -219,9 +221,9 @@ static bool cmd_test_mailbox_operation_dump */ static int cmd_test_mailbox_operation_execute -(const struct sieve_operation *op, - const struct sieve_runtime_env *renv, sieve_size_t *address) +(const struct sieve_runtime_env *renv, sieve_size_t *address) { + const struct sieve_operation *op = &renv->oprtn; string_t *mailbox = NULL; /* @@ -239,9 +241,10 @@ static int cmd_test_mailbox_operation_execute * Perform operation */ - sieve_runtime_trace(renv, "%s %s:", op->mnemonic, str_c(mailbox)); + sieve_runtime_trace + (renv, "%s %s:", sieve_operation_mnemonic(op), str_c(mailbox)); - if ( op == &test_mailbox_create_operation ) + if ( sieve_operation_is(op, test_mailbox_create_operation) ) testsuite_mailstore_mailbox_create(renv, str_c(mailbox)); return SIEVE_EXEC_OK; diff --git a/src/testsuite/cmd-test-message.c b/src/testsuite/cmd-test-message.c index 735f6a6a3..c239c7e36 100644 --- a/src/testsuite/cmd-test-message.c +++ b/src/testsuite/cmd-test-message.c @@ -22,14 +22,14 @@ */ static bool cmd_test_message_registered - (struct sieve_validator *valdtr, + (struct sieve_validator *valdtr, const struct sieve_extension *ext, struct sieve_command_registration *cmd_reg); static bool cmd_test_message_validate - (struct sieve_validator *valdtr, struct sieve_command_context *cmd); + (struct sieve_validator *valdtr, struct sieve_command *cmd); static bool cmd_test_message_generate - (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx); + (const struct sieve_codegen_env *cgenv, struct sieve_command *ctx); -const struct sieve_command cmd_test_message = { +const struct sieve_command_def cmd_test_message = { "test_message", SCT_HYBRID, 1, 0, FALSE, FALSE, @@ -47,13 +47,11 @@ const struct sieve_command cmd_test_message = { /* Test_message_smtp operation */ static bool cmd_test_message_smtp_operation_dump - (const struct sieve_operation *op, - const struct sieve_dumptime_env *denv, sieve_size_t *address); + (const struct sieve_dumptime_env *denv, sieve_size_t *address); static int cmd_test_message_smtp_operation_execute - (const struct sieve_operation *op, - const struct sieve_runtime_env *renv, sieve_size_t *address); + (const struct sieve_runtime_env *renv, sieve_size_t *address); -const struct sieve_operation test_message_smtp_operation = { +const struct sieve_operation_def test_message_smtp_operation = { "TEST_MESSAGE_SMTP", &testsuite_extension, TESTSUITE_OPERATION_TEST_MESSAGE_SMTP, @@ -64,13 +62,11 @@ const struct sieve_operation test_message_smtp_operation = { /* Test_message_mailbox operation */ static bool cmd_test_message_mailbox_operation_dump - (const struct sieve_operation *op, - const struct sieve_dumptime_env *denv, sieve_size_t *address); + (const struct sieve_dumptime_env *denv, sieve_size_t *address); static int cmd_test_message_mailbox_operation_execute - (const struct sieve_operation *op, - const struct sieve_runtime_env *renv, sieve_size_t *address); + (const struct sieve_runtime_env *renv, sieve_size_t *address); -const struct sieve_operation test_message_mailbox_operation = { +const struct sieve_operation_def test_message_mailbox_operation = { "TEST_MESSAGE_MAILBOX", &testsuite_extension, TESTSUITE_OPERATION_TEST_MESSAGE_MAILBOX, @@ -88,7 +84,7 @@ enum test_message_source { MSG_SOURCE_LAST }; -const struct sieve_operation *test_message_operations[] = { +const struct sieve_operation_def *test_message_operations[] = { &test_message_smtp_operation, &test_message_mailbox_operation }; @@ -108,38 +104,41 @@ struct cmd_test_message_context_data { static bool cmd_test_message_validate_smtp_tag (struct sieve_validator *valdtr, struct sieve_ast_argument **arg, - struct sieve_command_context *cmd); + struct sieve_command *cmd); static bool cmd_test_message_validate_folder_tag (struct sieve_validator *valdtr, struct sieve_ast_argument **arg, - struct sieve_command_context *cmd); + struct sieve_command *cmd); -static const struct sieve_argument test_message_smtp_tag = { +static const struct sieve_argument_def test_message_smtp_tag = { "smtp", - NULL, NULL, + NULL, cmd_test_message_validate_smtp_tag, - NULL, NULL + NULL, NULL, NULL }; -static const struct sieve_argument test_message_folder_tag = { +static const struct sieve_argument_def test_message_folder_tag = { "folder", - NULL, NULL, + NULL, cmd_test_message_validate_folder_tag, - NULL, NULL + NULL, NULL, NULL }; static bool cmd_test_message_registered -(struct sieve_validator *valdtr, struct sieve_command_registration *cmd_reg) +(struct sieve_validator *valdtr, const struct sieve_extension *ext, + struct sieve_command_registration *cmd_reg) { /* Register our tags */ - sieve_validator_register_tag(valdtr, cmd_reg, &test_message_folder_tag, 0); - sieve_validator_register_tag(valdtr, cmd_reg, &test_message_smtp_tag, 0); + sieve_validator_register_tag + (valdtr, cmd_reg, ext, &test_message_folder_tag, 0); + sieve_validator_register_tag + (valdtr, cmd_reg, ext, &test_message_smtp_tag, 0); return TRUE; } static struct cmd_test_message_context_data *cmd_test_message_validate_tag (struct sieve_validator *valdtr, struct sieve_ast_argument **arg, - struct sieve_command_context *cmd) + struct sieve_command *cmd) { struct cmd_test_message_context_data *ctx_data = (struct cmd_test_message_context_data *) cmd->data; @@ -162,7 +161,7 @@ static struct cmd_test_message_context_data *cmd_test_message_validate_tag static bool cmd_test_message_validate_smtp_tag (struct sieve_validator *valdtr, struct sieve_ast_argument **arg, - struct sieve_command_context *cmd) + struct sieve_command *cmd) { struct cmd_test_message_context_data *ctx_data = cmd_test_message_validate_tag(valdtr, arg, cmd); @@ -178,7 +177,7 @@ static bool cmd_test_message_validate_smtp_tag static bool cmd_test_message_validate_folder_tag (struct sieve_validator *valdtr, struct sieve_ast_argument **arg, - struct sieve_command_context *cmd) + struct sieve_command *cmd) { struct sieve_ast_argument *tag = *arg; struct cmd_test_message_context_data *ctx_data = @@ -209,7 +208,7 @@ static bool cmd_test_message_validate_folder_tag */ static bool cmd_test_message_validate -(struct sieve_validator *valdtr, struct sieve_command_context *cmd) +(struct sieve_validator *valdtr, struct sieve_command *cmd) { struct sieve_ast_argument *arg = cmd->first_positional; @@ -233,7 +232,7 @@ static bool cmd_test_message_validate */ static bool cmd_test_message_generate -(const struct sieve_codegen_env *cgenv, struct sieve_command_context *cmd) +(const struct sieve_codegen_env *cgenv, struct sieve_command *cmd) { struct cmd_test_message_context_data *ctx_data = (struct cmd_test_message_context_data *) cmd->data; @@ -241,7 +240,7 @@ static bool cmd_test_message_generate i_assert( ctx_data->msg_source < MSG_SOURCE_LAST ); /* Emit operation */ - sieve_operation_emit_code(cgenv->sbin, + sieve_operation_emit(cgenv->sbin, cmd->ext, test_message_operations[ctx_data->msg_source]); /* Emit is_test flag */ @@ -259,12 +258,11 @@ static bool cmd_test_message_generate */ static bool cmd_test_message_smtp_operation_dump -(const struct sieve_operation *op ATTR_UNUSED, - const struct sieve_dumptime_env *denv, sieve_size_t *address) +(const struct sieve_dumptime_env *denv, sieve_size_t *address) { unsigned int is_test; - if ( !sieve_binary_read_byte(denv->sbin, address, &is_test) ) + if ( !sieve_binary_read_byte(denv->sbin, address, &is_test) ) return FALSE; sieve_code_dumpf(denv, "TEST_MESSAGE_SMTP (%s):", @@ -276,12 +274,11 @@ static bool cmd_test_message_smtp_operation_dump } static bool cmd_test_message_mailbox_operation_dump -(const struct sieve_operation *op ATTR_UNUSED, - const struct sieve_dumptime_env *denv, sieve_size_t *address) +(const struct sieve_dumptime_env *denv, sieve_size_t *address) { unsigned int is_test; - if ( !sieve_binary_read_byte(denv->sbin, address, &is_test) ) + if ( !sieve_binary_read_byte(denv->sbin, address, &is_test) ) return FALSE; sieve_code_dumpf(denv, "TEST_MESSAGE_MAILBOX (%s):", @@ -299,11 +296,10 @@ static bool cmd_test_message_mailbox_operation_dump */ static int cmd_test_message_smtp_operation_execute -(const struct sieve_operation *op ATTR_UNUSED, - const struct sieve_runtime_env *renv, sieve_size_t *address) +(const struct sieve_runtime_env *renv, sieve_size_t *address) { sieve_number_t msg_index; - unsigned int is_test = -1; + unsigned int is_test = -1; bool result; /* @@ -312,7 +308,7 @@ static int cmd_test_message_smtp_operation_execute /* Is test */ - if ( !sieve_binary_read_byte(renv->sbin, address, &is_test) ) { + if ( !sieve_binary_read_byte(renv->sbin, address, &is_test) ) { sieve_runtime_trace_error(renv, "invalid is_test flag"); return SIEVE_EXEC_BIN_CORRUPT; } @@ -345,8 +341,7 @@ static int cmd_test_message_smtp_operation_execute } static int cmd_test_message_mailbox_operation_execute -(const struct sieve_operation *op ATTR_UNUSED, - const struct sieve_runtime_env *renv, sieve_size_t *address) +(const struct sieve_runtime_env *renv, sieve_size_t *address) { string_t *folder; sieve_number_t msg_index; @@ -358,7 +353,7 @@ static int cmd_test_message_mailbox_operation_execute */ /* Is test */ - if ( !sieve_binary_read_byte(renv->sbin, address, &is_test) ) { + if ( !sieve_binary_read_byte(renv->sbin, address, &is_test) ) { sieve_runtime_trace_error(renv, "invalid is_test flag"); return SIEVE_EXEC_BIN_CORRUPT; } diff --git a/src/testsuite/cmd-test-result-print.c b/src/testsuite/cmd-test-result-print.c index 576619073..df3d4a500 100644 --- a/src/testsuite/cmd-test-result-print.c +++ b/src/testsuite/cmd-test-result-print.c @@ -23,9 +23,9 @@ */ static bool cmd_test_result_print_generate - (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx); + (const struct sieve_codegen_env *cgenv, struct sieve_command *cmd); -const struct sieve_command cmd_test_result_print = { +const struct sieve_command_def cmd_test_result_print = { "test_result_print", SCT_COMMAND, 0, 0, FALSE, FALSE, @@ -39,10 +39,9 @@ const struct sieve_command cmd_test_result_print = { */ static int cmd_test_result_print_operation_execute - (const struct sieve_operation *op, - const struct sieve_runtime_env *renv, sieve_size_t *address); + (const struct sieve_runtime_env *renv, sieve_size_t *address); -const struct sieve_operation test_result_print_operation = { +const struct sieve_operation_def test_result_print_operation = { "TEST_RESULT_PRINT", &testsuite_extension, TESTSUITE_OPERATION_TEST_RESULT_PRINT, @@ -55,10 +54,9 @@ const struct sieve_operation test_result_print_operation = { */ static bool cmd_test_result_print_generate -(const struct sieve_codegen_env *cgenv, - struct sieve_command_context *tst ATTR_UNUSED) +(const struct sieve_codegen_env *cgenv, struct sieve_command *cmd) { - sieve_operation_emit_code(cgenv->sbin, &test_result_print_operation); + sieve_operation_emit(cgenv->sbin, cmd->ext, &test_result_print_operation); return TRUE; } @@ -68,9 +66,7 @@ static bool cmd_test_result_print_generate */ static int cmd_test_result_print_operation_execute -(const struct sieve_operation *op ATTR_UNUSED, - const struct sieve_runtime_env *renv, - sieve_size_t *address ATTR_UNUSED) +(const struct sieve_runtime_env *renv, sieve_size_t *address ATTR_UNUSED) { testsuite_result_print(renv); diff --git a/src/testsuite/cmd-test-result-reset.c b/src/testsuite/cmd-test-result-reset.c index 7e2f16dcb..bf1b2e316 100644 --- a/src/testsuite/cmd-test-result-reset.c +++ b/src/testsuite/cmd-test-result-reset.c @@ -24,9 +24,9 @@ */ static bool cmd_test_result_reset_generate - (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx); + (const struct sieve_codegen_env *cgenv, struct sieve_command *cmd); -const struct sieve_command cmd_test_result_reset = { +const struct sieve_command_def cmd_test_result_reset = { "test_result_reset", SCT_COMMAND, 0, 0, FALSE, FALSE, @@ -40,10 +40,9 @@ const struct sieve_command cmd_test_result_reset = { */ static int cmd_test_result_reset_operation_execute - (const struct sieve_operation *op, - const struct sieve_runtime_env *renv, sieve_size_t *address); + (const struct sieve_runtime_env *renv, sieve_size_t *address); -const struct sieve_operation test_result_reset_operation = { +const struct sieve_operation_def test_result_reset_operation = { "TEST_RESULT_RESET", &testsuite_extension, TESTSUITE_OPERATION_TEST_RESULT_RESET, @@ -56,10 +55,9 @@ const struct sieve_operation test_result_reset_operation = { */ static bool cmd_test_result_reset_generate -(const struct sieve_codegen_env *cgenv, - struct sieve_command_context *tst ATTR_UNUSED) +(const struct sieve_codegen_env *cgenv, struct sieve_command *tst) { - sieve_operation_emit_code(cgenv->sbin, &test_result_reset_operation); + sieve_operation_emit(cgenv->sbin, tst->ext, &test_result_reset_operation); return TRUE; } @@ -69,9 +67,7 @@ static bool cmd_test_result_reset_generate */ static int cmd_test_result_reset_operation_execute -(const struct sieve_operation *op ATTR_UNUSED, - const struct sieve_runtime_env *renv, - sieve_size_t *address ATTR_UNUSED) +(const struct sieve_runtime_env *renv, sieve_size_t *address ATTR_UNUSED) { testsuite_result_reset(renv); testsuite_smtp_reset(); diff --git a/src/testsuite/cmd-test-set.c b/src/testsuite/cmd-test-set.c index d6b98819c..84f2c817a 100644 --- a/src/testsuite/cmd-test-set.c +++ b/src/testsuite/cmd-test-set.c @@ -30,11 +30,11 @@ */ static bool cmd_test_set_validate - (struct sieve_validator *validator, struct sieve_command_context *cmd); + (struct sieve_validator *valdtr, struct sieve_command *cmd); static bool cmd_test_set_generate - (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx); + (const struct sieve_codegen_env *cgenv, struct sieve_command *cmd); -const struct sieve_command cmd_test_set = { +const struct sieve_command_def cmd_test_set = { "test_set", SCT_COMMAND, 2, 0, FALSE, FALSE, @@ -49,13 +49,11 @@ const struct sieve_command cmd_test_set = { */ static bool cmd_test_set_operation_dump - (const struct sieve_operation *op, - const struct sieve_dumptime_env *denv, sieve_size_t *address); + (const struct sieve_dumptime_env *denv, sieve_size_t *address); static int cmd_test_set_operation_execute - (const struct sieve_operation *op, - const struct sieve_runtime_env *renv, sieve_size_t *address); + (const struct sieve_runtime_env *renv, sieve_size_t *address); -const struct sieve_operation test_set_operation = { +const struct sieve_operation_def test_set_operation = { "TEST_SET", &testsuite_extension, TESTSUITE_OPERATION_TEST_SET, @@ -68,7 +66,7 @@ const struct sieve_operation test_set_operation = { */ static bool cmd_test_set_validate -(struct sieve_validator *valdtr, struct sieve_command_context *cmd) +(struct sieve_validator *valdtr, struct sieve_command *cmd) { struct sieve_ast_argument *arg = cmd->first_positional; @@ -97,12 +95,12 @@ static bool cmd_test_set_validate */ static bool cmd_test_set_generate -(const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx) +(const struct sieve_codegen_env *cgenv, struct sieve_command *cmd) { - sieve_operation_emit_code(cgenv->sbin, &test_set_operation); + sieve_operation_emit(cgenv->sbin, cmd->ext, &test_set_operation); /* Generate arguments */ - return sieve_generate_arguments(cgenv, ctx, NULL); + return sieve_generate_arguments(cgenv, cmd, NULL); } /* @@ -110,8 +108,7 @@ static bool cmd_test_set_generate */ static bool cmd_test_set_operation_dump -(const struct sieve_operation *op ATTR_UNUSED, - const struct sieve_dumptime_env *denv, sieve_size_t *address) +(const struct sieve_dumptime_env *denv, sieve_size_t *address) { sieve_code_dumpf(denv, "TEST SET:"); sieve_code_descend(denv); @@ -126,15 +123,14 @@ static bool cmd_test_set_operation_dump */ static int cmd_test_set_operation_execute -(const struct sieve_operation *op ATTR_UNUSED, - const struct sieve_runtime_env *renv, sieve_size_t *address) +(const struct sieve_runtime_env *renv, sieve_size_t *address) { - const struct testsuite_object *object; + struct testsuite_object tobj; string_t *value; int member_id; - if ( (object=testsuite_object_read_member(renv->sbin, address, &member_id)) - == NULL ) { + if ( !testsuite_object_read_member + (renv->sbin, address, &tobj, &member_id) ) { sieve_runtime_trace_error(renv, "invalid testsuite object member"); return SIEVE_EXEC_BIN_CORRUPT; } @@ -145,14 +141,14 @@ static int cmd_test_set_operation_execute } sieve_runtime_trace(renv, "TEST SET command (%s = \"%s\")", - testsuite_object_member_name(object, member_id), str_c(value)); + testsuite_object_member_name(&tobj, member_id), str_c(value)); - if ( object->set_member == NULL ) { + if ( tobj.def == NULL || tobj.def->set_member == NULL ) { sieve_runtime_trace_error(renv, "unimplemented testsuite object"); return SIEVE_EXEC_FAILURE; } - object->set_member(renv, member_id, value); + tobj.def->set_member(renv, member_id, value); return SIEVE_EXEC_OK; } diff --git a/src/testsuite/cmd-test.c b/src/testsuite/cmd-test.c index 7180aa1fd..df2844dd4 100644 --- a/src/testsuite/cmd-test.c +++ b/src/testsuite/cmd-test.c @@ -20,11 +20,11 @@ */ static bool cmd_test_validate - (struct sieve_validator *validator, struct sieve_command_context *cmd); + (struct sieve_validator *valdtr, struct sieve_command *cmd); static bool cmd_test_generate - (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx); + (const struct sieve_codegen_env *cgenv, struct sieve_command *md); -const struct sieve_command cmd_test = { +const struct sieve_command_def cmd_test = { "test", SCT_COMMAND, 1, 0, TRUE, TRUE, @@ -41,13 +41,11 @@ const struct sieve_command cmd_test = { /* Test operation */ static bool cmd_test_operation_dump - (const struct sieve_operation *op, - const struct sieve_dumptime_env *denv, sieve_size_t *address); + (const struct sieve_dumptime_env *denv, sieve_size_t *address); static int cmd_test_operation_execute - (const struct sieve_operation *op, - const struct sieve_runtime_env *renv, sieve_size_t *address); + (const struct sieve_runtime_env *renv, sieve_size_t *address); -const struct sieve_operation test_operation = { +const struct sieve_operation_def test_operation = { "TEST", &testsuite_extension, TESTSUITE_OPERATION_TEST, @@ -58,10 +56,9 @@ const struct sieve_operation test_operation = { /* Test_finish operation */ static int cmd_test_finish_operation_execute - (const struct sieve_operation *op, - const struct sieve_runtime_env *renv, sieve_size_t *address); + (const struct sieve_runtime_env *renv, sieve_size_t *address); -const struct sieve_operation test_finish_operation = { +const struct sieve_operation_def test_finish_operation = { "TEST-FINISH", &testsuite_extension, TESTSUITE_OPERATION_TEST_FINISH, @@ -74,7 +71,7 @@ const struct sieve_operation test_finish_operation = { */ static bool cmd_test_validate -(struct sieve_validator *valdtr ATTR_UNUSED, struct sieve_command_context *cmd) +(struct sieve_validator *valdtr ATTR_UNUSED, struct sieve_command *cmd) { struct sieve_ast_argument *arg = cmd->first_positional; @@ -99,32 +96,32 @@ static bool cmd_test_validate */ static inline struct testsuite_generator_context * - _get_generator_context(struct sieve_generator *gentr) +_get_generator_context(struct sieve_generator *gentr) { return (struct testsuite_generator_context *) - sieve_generator_extension_get_context(gentr, &testsuite_extension); + sieve_generator_extension_get_context(gentr, testsuite_ext); } static bool cmd_test_generate - (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx) + (const struct sieve_codegen_env *cgenv, struct sieve_command *cmd) { struct testsuite_generator_context *genctx = _get_generator_context(cgenv->gentr); - sieve_operation_emit_code(cgenv->sbin, &test_operation); + sieve_operation_emit(cgenv->sbin, cmd->ext, &test_operation); /* Generate arguments */ - if ( !sieve_generate_arguments(cgenv, ctx, NULL) ) + if ( !sieve_generate_arguments(cgenv, cmd, NULL) ) return FALSE; /* Prepare jumplist */ sieve_jumplist_reset(genctx->exit_jumps); /* Test body */ - if ( !sieve_generate_block(cgenv, ctx->ast_node) ) + if ( !sieve_generate_block(cgenv, cmd->ast_node) ) return FALSE; - sieve_operation_emit_code(cgenv->sbin, &test_finish_operation); + sieve_operation_emit(cgenv->sbin, cmd->ext, &test_finish_operation); /* Resolve exit jumps to this point */ sieve_jumplist_resolve(genctx->exit_jumps); @@ -137,8 +134,7 @@ static bool cmd_test_generate */ static bool cmd_test_operation_dump -(const struct sieve_operation *op ATTR_UNUSED, - const struct sieve_dumptime_env *denv, sieve_size_t *address) +(const struct sieve_dumptime_env *denv, sieve_size_t *address) { sieve_code_dumpf(denv, "TEST:"); sieve_code_descend(denv); @@ -152,8 +148,7 @@ static bool cmd_test_operation_dump */ static int cmd_test_operation_execute -(const struct sieve_operation *op ATTR_UNUSED, - const struct sieve_runtime_env *renv, sieve_size_t *address) +(const struct sieve_runtime_env *renv, sieve_size_t *address) { string_t *test_name; @@ -169,8 +164,7 @@ static int cmd_test_operation_execute } static int cmd_test_finish_operation_execute -(const struct sieve_operation *op ATTR_UNUSED, - const struct sieve_runtime_env *renv ATTR_UNUSED, +(const struct sieve_runtime_env *renv ATTR_UNUSED, sieve_size_t *address ATTR_UNUSED) { sieve_runtime_trace(renv, "TEST FINISHED"); diff --git a/src/testsuite/ext-testsuite.c b/src/testsuite/ext-testsuite.c index 42100b5b7..e5fd9ef91 100644 --- a/src/testsuite/ext-testsuite.c +++ b/src/testsuite/ext-testsuite.c @@ -20,14 +20,14 @@ * extension .svtest by convention to distinguish them from any normal * sieve scripts that may reside in the same directory. * - * WARNING: Although this code can serve as an example on how to write extensions - * to the Sieve interpreter, it is generally _NOT_ to be used as a source - * for ideas on new Sieve extensions. Many of the commands and tests that - * this extension introduces conflict with the goal and the implied - * restrictions of the Sieve language. These restrictions were put in - * place with good reason. Therefore, do _NOT_ export functionality - * provided by this testsuite extension to your custom extensions that are - * to be put to general use. + * WARNING: Although this code can serve as an example on how to write + * extensions to the Sieve interpreter, it is generally _NOT_ to be + * used as a source for ideas on new Sieve extensions. Many of the + * commands and tests that this extension introduces conflict with the + * goal and the implied restrictions of the Sieve language. These + * restrictions were put in place with good reason. Therefore, do + * _NOT_ export functionality provided by this testsuite extension to + * your custom extensions that are to be put to general use. * * Thank you. */ @@ -51,7 +51,7 @@ * Operations */ -const struct sieve_operation *testsuite_operations[] = { +const struct sieve_operation_def *testsuite_operations[] = { &test_operation, &test_finish_operation, &test_fail_operation, @@ -76,7 +76,7 @@ const struct sieve_operation *testsuite_operations[] = { * Operands */ -const struct sieve_operand *testsuite_operands[] = { +const struct sieve_operand_def *testsuite_operands[] = { &testsuite_object_operand, &testsuite_substitution_operand }; @@ -87,17 +87,17 @@ const struct sieve_operand *testsuite_operands[] = { /* Forward declarations */ -static bool ext_testsuite_validator_load(struct sieve_validator *valdtr); -static bool ext_testsuite_generator_load(const struct sieve_codegen_env *cgenv); -static bool ext_testsuite_binary_load(struct sieve_binary *sbin); +static bool ext_testsuite_validator_load + (const struct sieve_extension *ext, struct sieve_validator *valdtr); +static bool ext_testsuite_generator_load + (const struct sieve_extension *ext, const struct sieve_codegen_env *cgenv); +static bool ext_testsuite_binary_load + (const struct sieve_extension *ext, struct sieve_binary *sbin); /* Extension object */ -static int ext_my_id = -1; - -const struct sieve_extension testsuite_extension = { +const struct sieve_extension_def testsuite_extension = { "vnd.dovecot.testsuite", - &ext_my_id, NULL, NULL, ext_testsuite_validator_load, ext_testsuite_generator_load, @@ -110,36 +110,40 @@ const struct sieve_extension testsuite_extension = { /* Extension implementation */ -static bool ext_testsuite_validator_load(struct sieve_validator *valdtr) +static bool ext_testsuite_validator_load +(const struct sieve_extension *ext, struct sieve_validator *valdtr) { - sieve_validator_register_command(valdtr, &cmd_test); - sieve_validator_register_command(valdtr, &cmd_test_fail); - sieve_validator_register_command(valdtr, &cmd_test_set); - sieve_validator_register_command(valdtr, &cmd_test_result_print); - sieve_validator_register_command(valdtr, &cmd_test_result_reset); - sieve_validator_register_command(valdtr, &cmd_test_message); - sieve_validator_register_command(valdtr, &cmd_test_mailbox); - sieve_validator_register_command(valdtr, &cmd_test_binary); - - sieve_validator_register_command(valdtr, &tst_test_script_compile); - sieve_validator_register_command(valdtr, &tst_test_script_run); - sieve_validator_register_command(valdtr, &tst_test_multiscript); - sieve_validator_register_command(valdtr, &tst_test_error); - sieve_validator_register_command(valdtr, &tst_test_result); - sieve_validator_register_command(valdtr, &tst_test_result_execute); - - sieve_validator_argument_override(valdtr, SAT_VAR_STRING, - &testsuite_string_argument); + sieve_validator_register_command(valdtr, ext, &cmd_test); + sieve_validator_register_command(valdtr, ext, &cmd_test_fail); + sieve_validator_register_command(valdtr, ext, &cmd_test_set); + sieve_validator_register_command(valdtr, ext, &cmd_test_result_print); + sieve_validator_register_command(valdtr, ext, &cmd_test_result_reset); + sieve_validator_register_command(valdtr, ext, &cmd_test_message); + sieve_validator_register_command(valdtr, ext, &cmd_test_mailbox); + sieve_validator_register_command(valdtr, ext, &cmd_test_binary); + + sieve_validator_register_command(valdtr, ext, &tst_test_script_compile); + sieve_validator_register_command(valdtr, ext, &tst_test_script_run); + sieve_validator_register_command(valdtr, ext, &tst_test_multiscript); + sieve_validator_register_command(valdtr, ext, &tst_test_error); + sieve_validator_register_command(valdtr, ext, &tst_test_result); + sieve_validator_register_command(valdtr, ext, &tst_test_result_execute); + +/* sieve_validator_argument_override(valdtr, SAT_VAR_STRING, ext, + &testsuite_string_argument);*/ return testsuite_validator_context_initialize(valdtr); } -static bool ext_testsuite_generator_load(const struct sieve_codegen_env *cgenv) +static bool ext_testsuite_generator_load +(const struct sieve_extension *ext, const struct sieve_codegen_env *cgenv) { - return testsuite_generator_context_initialize(cgenv->gentr); + return testsuite_generator_context_initialize(cgenv->gentr, ext); } -static bool ext_testsuite_binary_load(struct sieve_binary *sbin ATTR_UNUSED) +static bool ext_testsuite_binary_load +(const struct sieve_extension *ext ATTR_UNUSED, + struct sieve_binary *sbin ATTR_UNUSED) { return TRUE; } diff --git a/src/testsuite/testsuite-arguments.c b/src/testsuite/testsuite-arguments.c index ba77785ef..caf106a4f 100644 --- a/src/testsuite/testsuite-arguments.c +++ b/src/testsuite/testsuite-arguments.c @@ -26,19 +26,19 @@ static bool arg_testsuite_string_validate (struct sieve_validator *validator, struct sieve_ast_argument **arg, - struct sieve_command_context *context); + struct sieve_command *context); -const struct sieve_argument testsuite_string_argument = { +const struct sieve_argument_def testsuite_string_argument = { "@testsuite-string", - NULL, NULL, - arg_testsuite_string_validate, NULL, + arg_testsuite_string_validate, + NULL, NULL, sieve_arg_catenated_string_generate, }; static bool arg_testsuite_string_validate (struct sieve_validator *valdtr, struct sieve_ast_argument **arg, - struct sieve_command_context *cmd) + struct sieve_command *cmd) { enum { ST_NONE, ST_OPEN, ST_SUBSTITUTION, ST_PARAM, ST_CLOSE } state = ST_NONE; diff --git a/src/testsuite/testsuite-arguments.h b/src/testsuite/testsuite-arguments.h index 171fa3ec1..43018613d 100644 --- a/src/testsuite/testsuite-arguments.h +++ b/src/testsuite/testsuite-arguments.h @@ -4,6 +4,6 @@ #ifndef __TESTSUITE_ARGUMENTS_H #define __TESTSUITE_ARGUMENTS_H -extern const struct sieve_argument testsuite_string_argument; +extern const struct sieve_argument_def testsuite_string_argument; #endif diff --git a/src/testsuite/testsuite-binary.c b/src/testsuite/testsuite-binary.c index 6bf3ac207..3fd00296f 100644 --- a/src/testsuite/testsuite-binary.c +++ b/src/testsuite/testsuite-binary.c @@ -67,7 +67,8 @@ bool testsuite_binary_save(struct sieve_binary *sbin, const char *name) struct sieve_binary *testsuite_binary_load(const char *name) { - return sieve_load(t_strdup_printf("%s/%s.svbin", testsuite_binary_tmp, name)); + return sieve_load(sieve_instance, + t_strdup_printf("%s/%s.svbin", testsuite_binary_tmp, name)); } diff --git a/src/testsuite/testsuite-common.c b/src/testsuite/testsuite-common.c index 21f573a9c..5cc5e457b 100644 --- a/src/testsuite/testsuite-common.c +++ b/src/testsuite/testsuite-common.c @@ -50,6 +50,10 @@ static string_t *test_name; unsigned int test_index; unsigned int test_failures; +/* Extension */ + +const struct sieve_extension *testsuite_ext; + /* * Validator context */ @@ -64,7 +68,7 @@ bool testsuite_validator_context_initialize(struct sieve_validator *valdtr) ctx->object_registrations = sieve_validator_object_registry_create(valdtr); testsuite_register_core_objects(ctx); - sieve_validator_extension_set_context(valdtr, &testsuite_extension, ctx); + sieve_validator_extension_set_context(valdtr, testsuite_ext, ctx); return TRUE; } @@ -73,14 +77,15 @@ struct testsuite_validator_context *testsuite_validator_context_get (struct sieve_validator *valdtr) { return (struct testsuite_validator_context *) - sieve_validator_extension_get_context(valdtr, &testsuite_extension); + sieve_validator_extension_get_context(valdtr, testsuite_ext); } /* * Generator context */ -bool testsuite_generator_context_initialize(struct sieve_generator *gentr) +bool testsuite_generator_context_initialize +(struct sieve_generator *gentr, const struct sieve_extension *this_ext) { pool_t pool = sieve_generator_pool(gentr); struct sieve_binary *sbin = sieve_generator_get_binary(gentr); @@ -90,7 +95,7 @@ bool testsuite_generator_context_initialize(struct sieve_generator *gentr) /* Setup exit jumplist */ ctx->exit_jumps = sieve_jumplist_create(pool, sbin); - sieve_generator_extension_set_context(gentr, &testsuite_extension, ctx); + sieve_generator_extension_set_context(gentr, this_ext, ctx); return TRUE; } @@ -227,7 +232,7 @@ const char *testsuite_tmp_dir_get(void) * Main testsuite init/deinit */ -void testsuite_init(void) +void testsuite_init(struct sieve_instance *svinst) { testsuite_test_context_init(); testsuite_log_init(); @@ -236,6 +241,9 @@ void testsuite_init(void) testsuite_script_init(); testsuite_binary_init(); testsuite_smtp_init(); + + testsuite_ext = sieve_extension_register + (svinst, &testsuite_extension, TRUE); } void testsuite_deinit(void) diff --git a/src/testsuite/testsuite-common.h b/src/testsuite/testsuite-common.h index 398b4b441..0a0fa6229 100644 --- a/src/testsuite/testsuite-common.h +++ b/src/testsuite/testsuite-common.h @@ -6,11 +6,17 @@ #include "sieve-common.h" +#include "sieve-tool.h" + /* * Extension */ -extern const struct sieve_extension testsuite_extension; +/* Extension */ + +extern const struct sieve_extension_def testsuite_extension; + +extern const struct sieve_extension *testsuite_ext; extern const struct sieve_script_env *testsuite_scriptenv; @@ -34,31 +40,32 @@ struct testsuite_generator_context { struct sieve_jumplist *exit_jumps; }; -bool testsuite_generator_context_initialize(struct sieve_generator *gentr); +bool testsuite_generator_context_initialize + (struct sieve_generator *gentr, const struct sieve_extension *this_ext); /* * Commands */ -extern const struct sieve_command cmd_test; -extern const struct sieve_command cmd_test_fail; -extern const struct sieve_command cmd_test_set; -extern const struct sieve_command cmd_test_result_reset; -extern const struct sieve_command cmd_test_result_print; -extern const struct sieve_command cmd_test_message; -extern const struct sieve_command cmd_test_mailbox; -extern const struct sieve_command cmd_test_binary; +extern const struct sieve_command_def cmd_test; +extern const struct sieve_command_def cmd_test_fail; +extern const struct sieve_command_def cmd_test_set; +extern const struct sieve_command_def cmd_test_result_reset; +extern const struct sieve_command_def cmd_test_result_print; +extern const struct sieve_command_def cmd_test_message; +extern const struct sieve_command_def cmd_test_mailbox; +extern const struct sieve_command_def cmd_test_binary; /* * Tests */ -extern const struct sieve_command tst_test_script_compile; -extern const struct sieve_command tst_test_script_run; -extern const struct sieve_command tst_test_multiscript; -extern const struct sieve_command tst_test_error; -extern const struct sieve_command tst_test_result; -extern const struct sieve_command tst_test_result_execute; +extern const struct sieve_command_def tst_test_script_compile; +extern const struct sieve_command_def tst_test_script_run; +extern const struct sieve_command_def tst_test_multiscript; +extern const struct sieve_command_def tst_test_error; +extern const struct sieve_command_def tst_test_result; +extern const struct sieve_command_def tst_test_result_execute; /* * Operations @@ -85,31 +92,31 @@ enum testsuite_operation_code { TESTSUITE_OPERATION_TEST_BINARY_SAVE, }; -extern const struct sieve_operation test_operation; -extern const struct sieve_operation test_finish_operation; -extern const struct sieve_operation test_fail_operation; -extern const struct sieve_operation test_set_operation; -extern const struct sieve_operation test_script_compile_operation; -extern const struct sieve_operation test_script_run_operation; -extern const struct sieve_operation test_multiscript_operation; -extern const struct sieve_operation test_error_operation; -extern const struct sieve_operation test_result_operation; -extern const struct sieve_operation test_result_execute_operation; -extern const struct sieve_operation test_result_reset_operation; -extern const struct sieve_operation test_result_print_operation; -extern const struct sieve_operation test_message_smtp_operation; -extern const struct sieve_operation test_message_mailbox_operation; -extern const struct sieve_operation test_mailbox_create_operation; -extern const struct sieve_operation test_mailbox_delete_operation; -extern const struct sieve_operation test_binary_load_operation; -extern const struct sieve_operation test_binary_save_operation; +extern const struct sieve_operation_def test_operation; +extern const struct sieve_operation_def test_finish_operation; +extern const struct sieve_operation_def test_fail_operation; +extern const struct sieve_operation_def test_set_operation; +extern const struct sieve_operation_def test_script_compile_operation; +extern const struct sieve_operation_def test_script_run_operation; +extern const struct sieve_operation_def test_multiscript_operation; +extern const struct sieve_operation_def test_error_operation; +extern const struct sieve_operation_def test_result_operation; +extern const struct sieve_operation_def test_result_execute_operation; +extern const struct sieve_operation_def test_result_reset_operation; +extern const struct sieve_operation_def test_result_print_operation; +extern const struct sieve_operation_def test_message_smtp_operation; +extern const struct sieve_operation_def test_message_mailbox_operation; +extern const struct sieve_operation_def test_mailbox_create_operation; +extern const struct sieve_operation_def test_mailbox_delete_operation; +extern const struct sieve_operation_def test_binary_load_operation; +extern const struct sieve_operation_def test_binary_save_operation; /* * Operands */ -extern const struct sieve_operand testsuite_object_operand; -extern const struct sieve_operand testsuite_substitution_operand; +extern const struct sieve_operand_def testsuite_object_operand; +extern const struct sieve_operand_def testsuite_substitution_operand; enum testsuite_operand_code { TESTSUITE_OPERAND_OBJECT, @@ -140,7 +147,7 @@ const char *testsuite_tmp_dir_get(void); * Testsuite init/deinit */ -void testsuite_init(void); +void testsuite_init(struct sieve_instance *svinst); void testsuite_deinit(void); #endif /* __TESTSUITE_COMMON_H */ diff --git a/src/testsuite/testsuite-objects.c b/src/testsuite/testsuite-objects.c index 5cc734f7a..ea3701c40 100644 --- a/src/testsuite/testsuite-objects.c +++ b/src/testsuite/testsuite-objects.c @@ -29,7 +29,7 @@ enum testsuite_object_code { TESTSUITE_OBJECT_ENVELOPE }; -const struct testsuite_object *testsuite_core_objects[] = { +const struct testsuite_object_def *testsuite_core_objects[] = { &message_testsuite_object, &envelope_testsuite_object }; @@ -39,38 +39,55 @@ const unsigned int testsuite_core_objects_count = /* * Testsuite object registry */ + +static inline struct sieve_validator_object_registry *_get_object_registry +(struct sieve_validator *valdtr) +{ + struct testsuite_validator_context *ctx = + testsuite_validator_context_get(valdtr); + + return ctx->object_registrations; +} void testsuite_object_register -(struct sieve_validator *valdtr, const struct testsuite_object *tobj) +(struct sieve_validator *valdtr, const struct sieve_extension *ext, + const struct testsuite_object_def *tobj_def) { - struct testsuite_validator_context *ctx = testsuite_validator_context_get - (valdtr); + struct sieve_validator_object_registry *regs = _get_object_registry(valdtr); - sieve_validator_object_registry_add - (ctx->object_registrations, &tobj->object); + sieve_validator_object_registry_add(regs, ext, &tobj_def->obj_def); } -const struct testsuite_object *testsuite_object_find -(struct sieve_validator *valdtr, const char *identifier) +static const struct testsuite_object *testsuite_object_create +(struct sieve_validator *valdtr, struct sieve_command *cmd, + const char *identifier) { - struct testsuite_validator_context *ctx = testsuite_validator_context_get - (valdtr); - const struct sieve_object *object = - sieve_validator_object_registry_find - (ctx->object_registrations, identifier); + struct sieve_validator_object_registry *regs = _get_object_registry(valdtr); + struct sieve_object object; + struct testsuite_object *tobj; + + if ( !sieve_validator_object_registry_find(regs, identifier, &object) ) + return NULL; - return (const struct testsuite_object *) object; + tobj = p_new(sieve_command_pool(cmd), struct testsuite_object, 1); + tobj->object = object; + tobj->def = (const struct testsuite_object_def *) object.def; + + return tobj; } void testsuite_register_core_objects - (struct testsuite_validator_context *ctx) +(struct testsuite_validator_context *ctx) { + struct sieve_validator_object_registry *regs = ctx->object_registrations; unsigned int i; /* Register core testsuite objects */ for ( i = 0; i < testsuite_core_objects_count; i++ ) { + const struct testsuite_object_def *tobj_def = testsuite_core_objects[i]; + sieve_validator_object_registry_add - (ctx->object_registrations, &(testsuite_core_objects[i]->object)); + (regs, testsuite_ext, &tobj_def->obj_def); } } @@ -84,7 +101,7 @@ const struct sieve_operand_class sieve_testsuite_object_operand_class = static const struct sieve_extension_objects core_testsuite_objects = SIEVE_EXT_DEFINE_OBJECTS(testsuite_core_objects); -const struct sieve_operand testsuite_object_operand = { +const struct sieve_operand_def testsuite_object_operand = { "testsuite-object", &testsuite_extension, TESTSUITE_OPERAND_OBJECT, @@ -93,74 +110,82 @@ const struct sieve_operand testsuite_object_operand = { }; static void testsuite_object_emit -(struct sieve_binary *sbin, const struct testsuite_object *obj, - int member_id) +(struct sieve_binary *sbin, const struct testsuite_object *tobj, int member_id) { - sieve_opr_object_emit(sbin, &obj->object); + sieve_opr_object_emit(sbin, tobj->object.ext, tobj->object.def); - if ( obj->get_member_id != NULL ) { + if ( tobj->def != NULL && tobj->def->get_member_id != NULL ) { (void) sieve_binary_emit_byte(sbin, (unsigned char) member_id); } } -const struct testsuite_object *testsuite_object_read -(struct sieve_binary *sbin, sieve_size_t *address) +bool testsuite_object_read +(struct sieve_binary *sbin, sieve_size_t *address, + struct testsuite_object *tobj) { - const struct sieve_operand *operand = sieve_operand_read(sbin, address); + struct sieve_operand operand; + + if ( !sieve_operand_read(sbin, address, &operand) ) + return FALSE; - return (const struct testsuite_object *) sieve_opr_object_read_data - (sbin, operand, &sieve_testsuite_object_operand_class, address); + if ( !sieve_opr_object_read_data + (sbin, &operand, &sieve_testsuite_object_operand_class, address, + &tobj->object) ) + return FALSE; + + tobj->def = (const struct testsuite_object_def *) tobj->object.def; + + return TRUE; } -const struct testsuite_object *testsuite_object_read_member -(struct sieve_binary *sbin, sieve_size_t *address, int *member_id) -{ - const struct testsuite_object *object; - - if ( (object = testsuite_object_read(sbin, address)) == NULL ) - return NULL; +bool testsuite_object_read_member +(struct sieve_binary *sbin, sieve_size_t *address, + struct testsuite_object *tobj, int *member_id_r) +{ + if ( !testsuite_object_read(sbin, address, tobj) ) + return FALSE; - *member_id = -1; - if ( object->get_member_id != NULL ) { - if ( !sieve_binary_read_code(sbin, address, member_id) ) - return NULL; + *member_id_r = -1; + if ( tobj->def != NULL && tobj->def->get_member_id != NULL ) { + if ( !sieve_binary_read_code(sbin, address, member_id_r) ) + return FALSE; } - return object; + return TRUE; } const char *testsuite_object_member_name (const struct testsuite_object *object, int member_id) { + const struct testsuite_object_def *obj_def = object->def; const char *member = NULL; - if ( object->get_member_id != NULL ) { - if ( object->get_member_name != NULL ) - member = object->get_member_name(member_id); + if ( obj_def->get_member_id != NULL ) { + if ( obj_def->get_member_name != NULL ) + member = obj_def->get_member_name(member_id); } else - return object->object.identifier; + return obj_def->obj_def.identifier; if ( member == NULL ) - return t_strdup_printf("%s.%d", object->object.identifier, member_id); + return t_strdup_printf("%s.%d", obj_def->obj_def.identifier, member_id); - return t_strdup_printf("%s.%s", object->object.identifier, member); + return t_strdup_printf("%s.%s", obj_def->obj_def.identifier, member); } bool testsuite_object_dump (const struct sieve_dumptime_env *denv, sieve_size_t *address) { - const struct testsuite_object *object; + struct testsuite_object object; int member_id; sieve_code_mark(denv); - if ( (object = testsuite_object_read_member(denv->sbin, address, &member_id)) - == NULL ) + if ( !testsuite_object_read_member(denv->sbin, address, &object, &member_id) ) return FALSE; sieve_code_dumpf(denv, "%s: %s", sieve_testsuite_object_operand_class.name, - testsuite_object_member_name(object, member_id)); + testsuite_object_member_name(&object, member_id)); return TRUE; } @@ -171,9 +196,9 @@ bool testsuite_object_dump static bool arg_testsuite_object_generate (const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, - struct sieve_command_context *cmd); + struct sieve_command *cmd); -const struct sieve_argument testsuite_object_argument = { +const struct sieve_argument_def testsuite_object_argument = { "testsuite-object", NULL, NULL, NULL, NULL, arg_testsuite_object_generate @@ -186,10 +211,10 @@ struct testsuite_object_argctx { bool testsuite_object_argument_activate (struct sieve_validator *valdtr, struct sieve_ast_argument *arg, - struct sieve_command_context *cmd) + struct sieve_command *cmd) { const char *objname = sieve_ast_argument_strc(arg); - const struct testsuite_object *object; + const struct testsuite_object *tobj; int member_id; const char *member; struct testsuite_object_argctx *ctx; @@ -204,8 +229,8 @@ bool testsuite_object_argument_activate /* Find the object */ - object = testsuite_object_find(valdtr, objname); - if ( object == NULL ) { + tobj = testsuite_object_create(valdtr, cmd, objname); + if ( tobj == NULL ) { sieve_argument_validate_error(valdtr, arg, "unknown testsuite object '%s'", objname); return FALSE; @@ -215,8 +240,8 @@ bool testsuite_object_argument_activate member_id = -1; if ( member != NULL ) { - if ( object->get_member_id == NULL || - (member_id=object->get_member_id(member)) == -1 ) { + if ( tobj->def == NULL || tobj->def->get_member_id == NULL || + (member_id=tobj->def->get_member_id(member)) == -1 ) { sieve_argument_validate_error(valdtr, arg, "member '%s' does not exist for testsuite object '%s'", member, objname); return FALSE; @@ -226,21 +251,22 @@ bool testsuite_object_argument_activate /* Assign argument context */ ctx = p_new(sieve_command_pool(cmd), struct testsuite_object_argctx, 1); - ctx->object = object; + ctx->object = tobj; ctx->member = member_id; - arg->argument = &testsuite_object_argument; - arg->context = (void *) ctx; + arg->argument = sieve_argument_create + (arg->ast, &testsuite_object_argument, testsuite_ext, 0); + arg->argument->data = (void *) ctx; return TRUE; } static bool arg_testsuite_object_generate (const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, - struct sieve_command_context *cmd ATTR_UNUSED) + struct sieve_command *cmd ATTR_UNUSED) { struct testsuite_object_argctx *ctx = - (struct testsuite_object_argctx *) arg->context; + (struct testsuite_object_argctx *) arg->argument->data; testsuite_object_emit(cgenv->sbin, ctx->object, ctx->member); @@ -259,14 +285,14 @@ static const char *tsto_envelope_get_member_name(int id); static bool tsto_envelope_set_member (const struct sieve_runtime_env *renv, int id, string_t *value); -const struct testsuite_object message_testsuite_object = { +const struct testsuite_object_def message_testsuite_object = { SIEVE_OBJECT("message", &testsuite_object_operand, TESTSUITE_OBJECT_MESSAGE), NULL, NULL, tsto_message_set_member, NULL }; -const struct testsuite_object envelope_testsuite_object = { +const struct testsuite_object_def envelope_testsuite_object = { SIEVE_OBJECT("envelope", &testsuite_object_operand, TESTSUITE_OBJECT_ENVELOPE), tsto_envelope_get_member_id, tsto_envelope_get_member_name, diff --git a/src/testsuite/testsuite-objects.h b/src/testsuite/testsuite-objects.h index 71a7683af..743923fe6 100644 --- a/src/testsuite/testsuite-objects.h +++ b/src/testsuite/testsuite-objects.h @@ -23,26 +23,33 @@ extern const struct sieve_operand_class testsuite_object_oprclass; * Testsuite object access */ -struct testsuite_object { - struct sieve_object object; +struct testsuite_object_def { + struct sieve_object_def obj_def; int (*get_member_id)(const char *identifier); const char *(*get_member_name)(int id); - bool (*set_member)(const struct sieve_runtime_env *renv, int id, string_t *value); - string_t *(*get_member)(const struct sieve_runtime_env *renv, int id); + bool (*set_member) + (const struct sieve_runtime_env *renv, int id, string_t *value); + string_t *(*get_member) + (const struct sieve_runtime_env *renv, int id); +}; + +struct testsuite_object { + struct sieve_object object; + + const struct testsuite_object_def *def; }; /* * Testsuite object registration */ -const struct testsuite_object *testsuite_object_find - (struct sieve_validator *valdtr, const char *identifier); -void testsuite_object_register - (struct sieve_validator *valdtr, const struct testsuite_object *tobj); void testsuite_register_core_objects (struct testsuite_validator_context *ctx); +void testsuite_object_register + (struct sieve_validator *valdtr, const struct sieve_extension *ext, + const struct testsuite_object_def *tobj_def); /* * Testsuite object argument @@ -50,26 +57,30 @@ void testsuite_register_core_objects bool testsuite_object_argument_activate (struct sieve_validator *valdtr, struct sieve_ast_argument *arg, - struct sieve_command_context *cmd); + struct sieve_command *cmd); /* * Testsuite object code */ -const struct testsuite_object *testsuite_object_read - (struct sieve_binary *sbin, sieve_size_t *address); -const struct testsuite_object *testsuite_object_read_member - (struct sieve_binary *sbin, sieve_size_t *address, int *member_id); -const char *testsuite_object_member_name - (const struct testsuite_object *object, int member_id); +bool testsuite_object_read + (struct sieve_binary *sbin, sieve_size_t *address, + struct testsuite_object *tobj); +bool testsuite_object_read_member + (struct sieve_binary *sbin, sieve_size_t *address, + struct testsuite_object *tobj, int *member_id_r); + bool testsuite_object_dump (const struct sieve_dumptime_env *denv, sieve_size_t *address); +const char *testsuite_object_member_name + (const struct testsuite_object *object, int member_id); + /* * Testsuite core objects */ -extern const struct testsuite_object message_testsuite_object; -extern const struct testsuite_object envelope_testsuite_object; +extern const struct testsuite_object_def message_testsuite_object; +extern const struct testsuite_object_def envelope_testsuite_object; #endif /* __TESTSUITE_OBJECTS_H */ diff --git a/src/testsuite/testsuite-result.c b/src/testsuite/testsuite-result.c index d1175db42..b333b2238 100644 --- a/src/testsuite/testsuite-result.c +++ b/src/testsuite/testsuite-result.c @@ -21,7 +21,8 @@ static struct sieve_result *_testsuite_result; void testsuite_result_init(void) { _testsuite_result = sieve_result_create - (&testsuite_msgdata, testsuite_scriptenv, testsuite_log_ehandler); + (sieve_instance, &testsuite_msgdata, testsuite_scriptenv, + testsuite_log_ehandler); } void testsuite_result_deinit(void) @@ -39,7 +40,8 @@ void testsuite_result_reset } _testsuite_result = sieve_result_create - (&testsuite_msgdata, testsuite_scriptenv, testsuite_log_ehandler); + (sieve_instance, &testsuite_msgdata, testsuite_scriptenv, + testsuite_log_ehandler); sieve_interpreter_set_result(renv->interp, _testsuite_result); } diff --git a/src/testsuite/testsuite-script.c b/src/testsuite/testsuite-script.c index 27d51022e..6bcb05c02 100644 --- a/src/testsuite/testsuite-script.c +++ b/src/testsuite/testsuite-script.c @@ -54,7 +54,8 @@ static struct sieve_binary *_testsuite_script_compile(const char *script_path) testsuite_setting_set ("sieve_global_dir", t_strconcat(sieve_dir, "included-global", NULL)); - if ( (sbin = sieve_compile(script_path, NULL, testsuite_log_ehandler)) == NULL ) + if ( (sbin = sieve_compile + (sieve_instance, script_path, NULL, testsuite_log_ehandler)) == NULL ) return NULL; return sbin; @@ -147,7 +148,6 @@ bool testsuite_script_multiscript { struct sieve_script_env scriptenv; struct sieve_multiscript *mscript; - struct sieve_result *result; const char *const *scripts; unsigned int count, i; bool more = TRUE; @@ -168,12 +168,11 @@ bool testsuite_script_multiscript scriptenv.duplicate_check = NULL; scriptenv.namespaces = renv->scriptenv->namespaces; scriptenv.trace_stream = renv->scriptenv->trace_stream; - - result = testsuite_result_get(); /* Start execution */ - mscript = sieve_multiscript_start_execute(renv->msgdata, &scriptenv); + mscript = sieve_multiscript_start_execute + (sieve_instance, renv->msgdata, &scriptenv); /* Execute scripts before main script */ diff --git a/src/testsuite/testsuite-substitutions.c b/src/testsuite/testsuite-substitutions.c index 991005577..0333d2977 100644 --- a/src/testsuite/testsuite-substitutions.c +++ b/src/testsuite/testsuite-substitutions.c @@ -30,23 +30,18 @@ void testsuite_opr_substitution_emit enum { TESTSUITE_SUBSTITUTION_FILE, - TESTSUITE_SUBSTITUTION_MAILBOX, - TESTSUITE_SUBSTITUTION_SMTPOUT }; -static const struct testsuite_substitution testsuite_file_substitution; -static const struct testsuite_substitution testsuite_mailbox_substitution; -static const struct testsuite_substitution testsuite_smtpout_substitution; +static const struct testsuite_substitution_def testsuite_file_substitution; -static const struct testsuite_substitution *substitutions[] = { +static const struct testsuite_substitution_def *substitutions[] = { &testsuite_file_substitution, - &testsuite_mailbox_substitution, - &testsuite_smtpout_substitution }; static const unsigned int substitutions_count = N_ELEMENTS(substitutions); -static inline const struct testsuite_substitution *testsuite_substitution_get +static inline const struct testsuite_substitution_def * +testsuite_substitution_get (unsigned int code) { if ( code > substitutions_count ) @@ -55,14 +50,23 @@ static inline const struct testsuite_substitution *testsuite_substitution_get return substitutions[code]; } -const struct testsuite_substitution *testsuite_substitution_find -(const char *identifier) +static const struct testsuite_substitution *testsuite_substitution_create +(struct sieve_ast *ast, const char *identifier) { unsigned int i; for ( i = 0; i < substitutions_count; i++ ) { - if ( strcasecmp(substitutions[i]->object.identifier, identifier) == 0 ) - return substitutions[i]; + if ( strcasecmp(substitutions[i]->obj_def.identifier, identifier) == 0 ) { + const struct testsuite_substitution_def *tsub_def = substitutions[i]; + struct testsuite_substitution *tsub; + + tsub = p_new(sieve_ast_pool(ast), struct testsuite_substitution, 1); + tsub->object.def = &tsub_def->obj_def; + tsub->object.ext = testsuite_ext; + tsub->def = tsub_def; + + return tsub; + } } return NULL; @@ -74,21 +78,21 @@ const struct testsuite_substitution *testsuite_substitution_find static bool arg_testsuite_substitution_generate (const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, - struct sieve_command_context *context); + struct sieve_command *context); struct _testsuite_substitution_context { const struct testsuite_substitution *tsub; const char *param; }; -const struct sieve_argument testsuite_substitution_argument = { +const struct sieve_argument_def testsuite_substitution_argument = { "@testsuite-substitution", NULL, NULL, NULL, NULL, arg_testsuite_substitution_generate }; struct sieve_ast_argument *testsuite_substitution_argument_create -(struct sieve_validator *validator ATTR_UNUSED, struct sieve_ast *ast, +(struct sieve_validator *valdtr ATTR_UNUSED, struct sieve_ast *ast, unsigned int source_line, const char *substitution, const char *param) { const struct testsuite_substitution *tsub; @@ -96,29 +100,31 @@ struct sieve_ast_argument *testsuite_substitution_argument_create struct sieve_ast_argument *arg; pool_t pool; - tsub = testsuite_substitution_find(substitution); + tsub = testsuite_substitution_create(ast, substitution); if ( tsub == NULL ) return NULL; arg = sieve_ast_argument_create(ast, source_line); arg->type = SAAT_STRING; - arg->argument = &testsuite_substitution_argument; pool = sieve_ast_pool(ast); tsctx = p_new(pool, struct _testsuite_substitution_context, 1); tsctx->tsub = tsub; tsctx->param = p_strdup(pool, param); - arg->context = (void *) tsctx; - + + arg->argument = sieve_argument_create + (ast, &testsuite_substitution_argument, testsuite_ext, 0); + arg->argument->data = (void *) tsctx; + return arg; } static bool arg_testsuite_substitution_generate (const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, - struct sieve_command_context *context ATTR_UNUSED) + struct sieve_command *context ATTR_UNUSED) { struct _testsuite_substitution_context *tsctx = - (struct _testsuite_substitution_context *) arg->context; + (struct _testsuite_substitution_context *) arg->argument->data; testsuite_opr_substitution_emit(cgenv->sbin, tsctx->tsub, tsctx->param); @@ -130,17 +136,18 @@ static bool arg_testsuite_substitution_generate */ static bool opr_substitution_dump - (const struct sieve_dumptime_env *denv, sieve_size_t *address, - const char *field_name); + (const struct sieve_dumptime_env *denv, const struct sieve_operand *opr, + sieve_size_t *address, const char *field_name); static bool opr_substitution_read_value - (const struct sieve_runtime_env *renv, sieve_size_t *address, string_t **str); + (const struct sieve_runtime_env *renv, const struct sieve_operand *opr, + sieve_size_t *address, string_t **str); const struct sieve_opr_string_interface testsuite_substitution_interface = { opr_substitution_dump, opr_substitution_read_value }; -const struct sieve_operand testsuite_substitution_operand = { +const struct sieve_operand_def testsuite_substitution_operand = { "test-substitution", &testsuite_extension, TESTSUITE_OPERAND_SUBSTITUTION, @@ -153,17 +160,19 @@ void testsuite_opr_substitution_emit const char *param) { /* Default variable storage */ - (void) sieve_operand_emit_code(sbin, &testsuite_substitution_operand); - (void) sieve_binary_emit_unsigned(sbin, tsub->object.code); + (void) sieve_operand_emit + (sbin, testsuite_ext, &testsuite_substitution_operand); + (void) sieve_binary_emit_unsigned(sbin, tsub->object.def->code); (void) sieve_binary_emit_cstring(sbin, param); } static bool opr_substitution_dump -(const struct sieve_dumptime_env *denv, sieve_size_t *address, +(const struct sieve_dumptime_env *denv, + const struct sieve_operand *opr ATTR_UNUSED, sieve_size_t *address, const char *field_name) { unsigned int code = 0; - const struct testsuite_substitution *tsub; + const struct testsuite_substitution_def *tsub; string_t *param; if ( !sieve_binary_read_unsigned(denv->sbin, address, &code) ) @@ -178,17 +187,19 @@ static bool opr_substitution_dump if ( field_name != NULL ) sieve_code_dumpf(denv, "%s: TEST_SUBS %%{%s:%s}", - field_name, tsub->object.identifier, str_c(param)); + field_name, tsub->obj_def.identifier, str_c(param)); else sieve_code_dumpf(denv, "TEST_SUBS %%{%s:%s}", - tsub->object.identifier, str_c(param)); + tsub->obj_def.identifier, str_c(param)); return TRUE; } static bool opr_substitution_read_value -(const struct sieve_runtime_env *renv, sieve_size_t *address, string_t **str) +(const struct sieve_runtime_env *renv, + const struct sieve_operand *opr ATTR_UNUSED, sieve_size_t *address, + string_t **str) { - const struct testsuite_substitution *tsub; + const struct testsuite_substitution_def *tsub; unsigned int code = 0; string_t *param; @@ -217,12 +228,8 @@ static bool opr_substitution_read_value static bool testsuite_file_substitution_get_value (const char *param, string_t **result); -static bool testsuite_mailbox_substitution_get_value - (const char *param, string_t **result); -static bool testsuite_smtpout_substitution_get_value - (const char *param, string_t **result); -static const struct testsuite_substitution testsuite_file_substitution = { +static const struct testsuite_substitution_def testsuite_file_substitution = { SIEVE_OBJECT( "file", &testsuite_substitution_operand, @@ -231,24 +238,6 @@ static const struct testsuite_substitution testsuite_file_substitution = { testsuite_file_substitution_get_value }; -static const struct testsuite_substitution testsuite_mailbox_substitution = { - SIEVE_OBJECT( - "mailbox", - &testsuite_substitution_operand, - TESTSUITE_SUBSTITUTION_MAILBOX - ), - testsuite_mailbox_substitution_get_value -}; - -static const struct testsuite_substitution testsuite_smtpout_substitution = { - SIEVE_OBJECT( - "smtpout", - &testsuite_substitution_operand, - TESTSUITE_SUBSTITUTION_SMTPOUT - ), - testsuite_smtpout_substitution_get_value -}; - static bool testsuite_file_substitution_get_value (const char *param, string_t **result) { @@ -258,20 +247,3 @@ static bool testsuite_file_substitution_get_value return TRUE; } -static bool testsuite_mailbox_substitution_get_value - (const char *param, string_t **result) -{ - *result = t_str_new(256); - - str_printfa(*result, "[MAILBOX: %s]", param); - return TRUE; -} - -static bool testsuite_smtpout_substitution_get_value - (const char *param, string_t **result) -{ - *result = t_str_new(256); - - str_printfa(*result, "[SMTPOUT: %s]", param); - return TRUE; -} diff --git a/src/testsuite/testsuite-substitutions.h b/src/testsuite/testsuite-substitutions.h index a9e775f0c..2e87395bb 100644 --- a/src/testsuite/testsuite-substitutions.h +++ b/src/testsuite/testsuite-substitutions.h @@ -7,17 +7,20 @@ #include "sieve-common.h" #include "sieve-objects.h" -struct testsuite_substitution { - struct sieve_object object; +struct testsuite_substitution_def { + struct sieve_object_def obj_def; bool (*get_value)(const char *param, string_t **result); }; -const struct testsuite_substitution *testsuite_substitution_find - (const char *identifier); +struct testsuite_substitution { + struct sieve_object object; + + const struct testsuite_substitution_def *def; +}; struct sieve_ast_argument *testsuite_substitution_argument_create - (struct sieve_validator *validator, struct sieve_ast *ast, + (struct sieve_validator *valdtr, struct sieve_ast *ast, unsigned int source_line, const char *substitution, const char *param); #endif /* __TESTSUITE_SUBSTITUTIONS_H */ diff --git a/src/testsuite/testsuite.c b/src/testsuite/testsuite.c index 0b851f48c..82ee2af0e 100644 --- a/src/testsuite/testsuite.c +++ b/src/testsuite/testsuite.c @@ -57,10 +57,9 @@ static void testsuite_tool_init(const char *extensions) sieve_tool_init(testsuite_setting_get, FALSE); - sieve_extensions_set_string(extensions); - (void) sieve_extension_register(&testsuite_extension, TRUE); + sieve_extensions_set_string(sieve_instance, extensions); - testsuite_init(); + testsuite_init(sieve_instance); } static void testsuite_tool_deinit(void) diff --git a/src/testsuite/tst-test-error.c b/src/testsuite/tst-test-error.c index b3f4ddda6..8be2361f4 100644 --- a/src/testsuite/tst-test-error.c +++ b/src/testsuite/tst-test-error.c @@ -26,13 +26,14 @@ */ static bool tst_test_error_registered - (struct sieve_validator *validator, struct sieve_command_registration *cmd_reg); + (struct sieve_validator *valdtr, const struct sieve_extension *ext, + struct sieve_command_registration *cmd_reg); static bool tst_test_error_validate - (struct sieve_validator *validator, struct sieve_command_context *cmd); + (struct sieve_validator *valdtr, struct sieve_command *cmd); static bool tst_test_error_generate - (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx); + (const struct sieve_codegen_env *cgenv, struct sieve_command *ctx); -const struct sieve_command tst_test_error = { +const struct sieve_command_def tst_test_error = { "test_error", SCT_TEST, 1, 0, FALSE, FALSE, @@ -48,13 +49,11 @@ const struct sieve_command tst_test_error = { */ static bool tst_test_error_operation_dump - (const struct sieve_operation *op, - const struct sieve_dumptime_env *denv, sieve_size_t *address); + (const struct sieve_dumptime_env *denv, sieve_size_t *address); static int tst_test_error_operation_execute - (const struct sieve_operation *op, - const struct sieve_runtime_env *renv, sieve_size_t *address); + (const struct sieve_runtime_env *renv, sieve_size_t *address); -const struct sieve_operation test_error_operation = { +const struct sieve_operation_def test_error_operation = { "TEST_ERROR", &testsuite_extension, TESTSUITE_OPERATION_TEST_ERROR, @@ -71,14 +70,14 @@ const struct sieve_operation test_error_operation = { */ static bool tst_test_error_validate_index_tag - (struct sieve_validator *validator, struct sieve_ast_argument **arg, - struct sieve_command_context *cmd); + (struct sieve_validator *valdtr, struct sieve_ast_argument **arg, + struct sieve_command *cmd); -static const struct sieve_argument test_error_index_tag = { +static const struct sieve_argument_def test_error_index_tag = { "index", - NULL, NULL, + NULL, tst_test_error_validate_index_tag, - NULL, NULL + NULL, NULL, NULL }; enum tst_test_error_optional { @@ -91,8 +90,8 @@ enum tst_test_error_optional { */ static bool tst_test_error_validate_index_tag -(struct sieve_validator *validator, struct sieve_ast_argument **arg, - struct sieve_command_context *cmd) +(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, + struct sieve_command *cmd) { struct sieve_ast_argument *tag = *arg; @@ -103,7 +102,7 @@ static bool tst_test_error_validate_index_tag * :index number */ if ( !sieve_validate_tag_parameter - (validator, cmd, tag, *arg, SAAT_NUMBER) ) { + (valdtr, cmd, tag, *arg, SAAT_NUMBER) ) { return FALSE; } @@ -118,14 +117,15 @@ static bool tst_test_error_validate_index_tag */ static bool tst_test_error_registered -(struct sieve_validator *validator, struct sieve_command_registration *cmd_reg) +(struct sieve_validator *valdtr, const struct sieve_extension *ext, + struct sieve_command_registration *cmd_reg) { /* The order of these is not significant */ - sieve_comparators_link_tag(validator, cmd_reg, SIEVE_MATCH_OPT_COMPARATOR); - sieve_match_types_link_tags(validator, cmd_reg, SIEVE_MATCH_OPT_MATCH_TYPE); + sieve_comparators_link_tag(valdtr, cmd_reg, SIEVE_MATCH_OPT_COMPARATOR); + sieve_match_types_link_tags(valdtr, cmd_reg, SIEVE_MATCH_OPT_MATCH_TYPE); sieve_validator_register_tag - (validator, cmd_reg, &test_error_index_tag, OPT_INDEX); + (valdtr, cmd_reg, ext, &test_error_index_tag, OPT_INDEX); return TRUE; } @@ -135,10 +135,14 @@ static bool tst_test_error_registered */ static bool tst_test_error_validate -(struct sieve_validator *valdtr ATTR_UNUSED, struct sieve_command_context *tst) +(struct sieve_validator *valdtr ATTR_UNUSED, struct sieve_command *tst) { struct sieve_ast_argument *arg = tst->first_positional; - + struct sieve_comparator cmp_default = + SIEVE_COMPARATOR_DEFAULT(i_octet_comparator); + struct sieve_match_type mcht_default = + SIEVE_COMPARATOR_DEFAULT(is_match_type); + if ( !sieve_validate_positional_argument (valdtr, tst, arg, "key list", 2, SAAT_STRING_LIST) ) { return FALSE; @@ -149,24 +153,17 @@ static bool tst_test_error_validate /* Validate the key argument to a specified match type */ return sieve_match_type_validate - (valdtr, tst, arg, &is_match_type, &i_octet_comparator); + (valdtr, tst, arg, &mcht_default, &cmp_default); } /* * Code generation */ -static inline struct testsuite_generator_context * -_get_generator_context(struct sieve_generator *gentr) -{ - return (struct testsuite_generator_context *) - sieve_generator_extension_get_context(gentr, &testsuite_extension); -} - static bool tst_test_error_generate -(const struct sieve_codegen_env *cgenv, struct sieve_command_context *tst) +(const struct sieve_codegen_env *cgenv, struct sieve_command *tst) { - sieve_operation_emit_code(cgenv->sbin, &test_error_operation); + sieve_operation_emit(cgenv->sbin, tst->ext, &test_error_operation); /* Generate arguments */ return sieve_generate_arguments(cgenv, tst, NULL); @@ -177,8 +174,7 @@ static bool tst_test_error_generate */ static bool tst_test_error_operation_dump -(const struct sieve_operation *op ATTR_UNUSED, - const struct sieve_dumptime_env *denv, sieve_size_t *address) +(const struct sieve_dumptime_env *denv, sieve_size_t *address) { int opt_code = 0; @@ -210,13 +206,12 @@ static bool tst_test_error_operation_dump */ static int tst_test_error_operation_execute -(const struct sieve_operation *op ATTR_UNUSED, - const struct sieve_runtime_env *renv, sieve_size_t *address) +(const struct sieve_runtime_env *renv, sieve_size_t *address) { int opt_code = 0; bool result = TRUE; - const struct sieve_comparator *cmp = &i_octet_comparator; - const struct sieve_match_type *mtch = &is_match_type; + struct sieve_comparator cmp = SIEVE_COMPARATOR_DEFAULT(i_octet_comparator); + struct sieve_match_type mcht = SIEVE_COMPARATOR_DEFAULT(is_match_type); struct sieve_match_context *mctx; struct sieve_coded_stringlist *key_list; bool matched; @@ -233,7 +228,7 @@ static int tst_test_error_operation_execute sieve_number_t number; if ( (ret=sieve_match_read_optional_operands - (renv, address, &opt_code, &cmp, &mtch)) <= 0 ) + (renv, address, &opt_code, &cmp, &mcht)) <= 0 ) return ret; switch ( opt_code ) { @@ -267,7 +262,7 @@ static int tst_test_error_operation_execute testsuite_log_get_error_init(); /* Initialize match */ - mctx = sieve_match_begin(renv->interp, mtch, cmp, NULL, key_list); + mctx = sieve_match_begin(renv->interp, &mcht, &cmp, NULL, key_list); /* Iterate through all errors to match */ error = NULL; diff --git a/src/testsuite/tst-test-multiscript.c b/src/testsuite/tst-test-multiscript.c index e01315968..e736b1c38 100644 --- a/src/testsuite/tst-test-multiscript.c +++ b/src/testsuite/tst-test-multiscript.c @@ -23,11 +23,11 @@ */ static bool tst_test_multiscript_validate - (struct sieve_validator *validator, struct sieve_command_context *cmd); + (struct sieve_validator *validator, struct sieve_command *cmd); static bool tst_test_multiscript_generate - (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx); + (const struct sieve_codegen_env *cgenv, struct sieve_command *tst); -const struct sieve_command tst_test_multiscript = { +const struct sieve_command_def tst_test_multiscript = { "test_multiscript", SCT_TEST, 1, 0, FALSE, FALSE, @@ -42,13 +42,11 @@ const struct sieve_command tst_test_multiscript = { */ static bool tst_test_multiscript_operation_dump - (const struct sieve_operation *op, - const struct sieve_dumptime_env *denv, sieve_size_t *address); + (const struct sieve_dumptime_env *denv, sieve_size_t *address); static int tst_test_multiscript_operation_execute - (const struct sieve_operation *op, - const struct sieve_runtime_env *renv, sieve_size_t *address); + (const struct sieve_runtime_env *renv, sieve_size_t *address); -const struct sieve_operation test_multiscript_operation = { +const struct sieve_operation_def test_multiscript_operation = { "TEST_MULTISCRIPT", &testsuite_extension, TESTSUITE_OPERATION_TEST_MULTISCRIPT, @@ -61,7 +59,7 @@ const struct sieve_operation test_multiscript_operation = { */ static bool tst_test_multiscript_validate -(struct sieve_validator *valdtr ATTR_UNUSED, struct sieve_command_context *tst) +(struct sieve_validator *valdtr, struct sieve_command *tst) { struct sieve_ast_argument *arg = tst->first_positional; @@ -77,17 +75,10 @@ static bool tst_test_multiscript_validate * Code generation */ -static inline struct testsuite_generator_context * - _get_generator_context(struct sieve_generator *gentr) -{ - return (struct testsuite_generator_context *) - sieve_generator_extension_get_context(gentr, &testsuite_extension); -} - static bool tst_test_multiscript_generate -(const struct sieve_codegen_env *cgenv, struct sieve_command_context *tst) +(const struct sieve_codegen_env *cgenv, struct sieve_command *tst) { - sieve_operation_emit_code(cgenv->sbin, &test_multiscript_operation); + sieve_operation_emit(cgenv->sbin, tst->ext, &test_multiscript_operation); /* Generate arguments */ return sieve_generate_arguments(cgenv, tst, NULL); @@ -98,8 +89,7 @@ static bool tst_test_multiscript_generate */ static bool tst_test_multiscript_operation_dump -(const struct sieve_operation *op ATTR_UNUSED, - const struct sieve_dumptime_env *denv, sieve_size_t *address) +(const struct sieve_dumptime_env *denv, sieve_size_t *address) { sieve_code_dumpf(denv, "TEST_MULTISCRIPT:"); sieve_code_descend(denv); @@ -115,8 +105,7 @@ static bool tst_test_multiscript_operation_dump */ static int tst_test_multiscript_operation_execute -(const struct sieve_operation *op ATTR_UNUSED, - const struct sieve_runtime_env *renv, sieve_size_t *address) +(const struct sieve_runtime_env *renv, sieve_size_t *address) { struct sieve_coded_stringlist *scripts_list; string_t *script_name; diff --git a/src/testsuite/tst-test-result-execute.c b/src/testsuite/tst-test-result-execute.c index 830227fdd..afbb67d44 100644 --- a/src/testsuite/tst-test-result-execute.c +++ b/src/testsuite/tst-test-result-execute.c @@ -23,9 +23,9 @@ */ static bool tst_test_result_execute_generate - (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx); + (const struct sieve_codegen_env *cgenv, struct sieve_command *cmd); -const struct sieve_command tst_test_result_execute = { +const struct sieve_command_def tst_test_result_execute = { "test_result_execute", SCT_TEST, 0, 0, FALSE, FALSE, @@ -39,10 +39,9 @@ const struct sieve_command tst_test_result_execute = { */ static int tst_test_result_execute_operation_execute - (const struct sieve_operation *op, - const struct sieve_runtime_env *renv, sieve_size_t *address); + (const struct sieve_runtime_env *renv, sieve_size_t *address); -const struct sieve_operation test_result_execute_operation = { +const struct sieve_operation_def test_result_execute_operation = { "TEST_RESULT_EXECUTE", &testsuite_extension, TESTSUITE_OPERATION_TEST_RESULT_EXECUTE, @@ -55,10 +54,9 @@ const struct sieve_operation test_result_execute_operation = { */ static bool tst_test_result_execute_generate -(const struct sieve_codegen_env *cgenv, - struct sieve_command_context *tst ATTR_UNUSED) +(const struct sieve_codegen_env *cgenv, struct sieve_command *tst) { - sieve_operation_emit_code(cgenv->sbin, &test_result_execute_operation); + sieve_operation_emit(cgenv->sbin, tst->ext, &test_result_execute_operation); return TRUE; } @@ -68,9 +66,7 @@ static bool tst_test_result_execute_generate */ static int tst_test_result_execute_operation_execute -(const struct sieve_operation *op ATTR_UNUSED, - const struct sieve_runtime_env *renv, - sieve_size_t *address ATTR_UNUSED) +(const struct sieve_runtime_env *renv, sieve_size_t *address ATTR_UNUSED) { bool result = TRUE; diff --git a/src/testsuite/tst-test-result.c b/src/testsuite/tst-test-result.c index 025ae2322..15b5ea585 100644 --- a/src/testsuite/tst-test-result.c +++ b/src/testsuite/tst-test-result.c @@ -34,13 +34,14 @@ */ static bool tst_test_result_registered - (struct sieve_validator *validator, struct sieve_command_registration *cmd_reg); + (struct sieve_validator *validator, const struct sieve_extension *ext, + struct sieve_command_registration *cmd_reg); static bool tst_test_result_validate - (struct sieve_validator *validator, struct sieve_command_context *cmd); + (struct sieve_validator *validator, struct sieve_command *cmd); static bool tst_test_result_generate - (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx); + (const struct sieve_codegen_env *cgenv, struct sieve_command *ctx); -const struct sieve_command tst_test_result = { +const struct sieve_command_def tst_test_result = { "test_result", SCT_TEST, 1, 0, FALSE, FALSE, @@ -56,13 +57,11 @@ const struct sieve_command tst_test_result = { */ static bool tst_test_result_operation_dump - (const struct sieve_operation *op, - const struct sieve_dumptime_env *denv, sieve_size_t *address); + (const struct sieve_dumptime_env *denv, sieve_size_t *address); static int tst_test_result_operation_execute - (const struct sieve_operation *op, - const struct sieve_runtime_env *renv, sieve_size_t *address); + (const struct sieve_runtime_env *renv, sieve_size_t *address); -const struct sieve_operation test_result_operation = { +const struct sieve_operation_def test_result_operation = { "test_result", &testsuite_extension, TESTSUITE_OPERATION_TEST_RESULT, @@ -74,21 +73,17 @@ const struct sieve_operation test_result_operation = { * Tagged arguments */ -/* NOTE: This will be merged with the date-index extension when it is - * implemented. - */ - -/* FIXME: at least merge this with the test_error version of this tag */ +/* FIXME: merge this with the test_error version of this tag */ static bool tst_test_result_validate_index_tag (struct sieve_validator *validator, struct sieve_ast_argument **arg, - struct sieve_command_context *cmd); + struct sieve_command *cmd); -static const struct sieve_argument test_result_index_tag = { +static const struct sieve_argument_def test_result_index_tag = { "index", - NULL, NULL, + NULL, tst_test_result_validate_index_tag, - NULL, NULL + NULL, NULL, NULL }; enum tst_test_result_optional { @@ -101,7 +96,7 @@ enum tst_test_result_optional { static bool tst_test_result_validate_index_tag (struct sieve_validator *validator, struct sieve_ast_argument **arg, - struct sieve_command_context *cmd) + struct sieve_command *cmd) { struct sieve_ast_argument *tag = *arg; @@ -127,14 +122,15 @@ static bool tst_test_result_validate_index_tag */ static bool tst_test_result_registered -(struct sieve_validator *validator, struct sieve_command_registration *cmd_reg) +(struct sieve_validator *validator, const struct sieve_extension *ext, + struct sieve_command_registration *cmd_reg) { /* The order of these is not significant */ sieve_comparators_link_tag(validator, cmd_reg, SIEVE_MATCH_OPT_COMPARATOR); sieve_match_types_link_tags(validator, cmd_reg, SIEVE_MATCH_OPT_MATCH_TYPE); sieve_validator_register_tag - (validator, cmd_reg, &test_result_index_tag, OPT_INDEX); + (validator, cmd_reg, ext, &test_result_index_tag, OPT_INDEX); return TRUE; } @@ -144,9 +140,13 @@ static bool tst_test_result_registered */ static bool tst_test_result_validate -(struct sieve_validator *valdtr ATTR_UNUSED, struct sieve_command_context *tst) +(struct sieve_validator *valdtr ATTR_UNUSED, struct sieve_command *tst) { struct sieve_ast_argument *arg = tst->first_positional; + struct sieve_comparator cmp_default = + SIEVE_COMPARATOR_DEFAULT(i_octet_comparator); + struct sieve_match_type mcht_default = + SIEVE_COMPARATOR_DEFAULT(is_match_type); if ( !sieve_validate_positional_argument (valdtr, tst, arg, "key list", 2, SAAT_STRING_LIST) ) { @@ -158,24 +158,17 @@ static bool tst_test_result_validate /* Validate the key argument to a specified match type */ return sieve_match_type_validate - (valdtr, tst, arg, &is_match_type, &i_octet_comparator); + (valdtr, tst, arg, &mcht_default, &cmp_default); } /* * Code generation */ -static inline struct testsuite_generator_context * -_get_generator_context(struct sieve_generator *gentr) -{ - return (struct testsuite_generator_context *) - sieve_generator_extension_get_context(gentr, &testsuite_extension); -} - static bool tst_test_result_generate -(const struct sieve_codegen_env *cgenv, struct sieve_command_context *tst) +(const struct sieve_codegen_env *cgenv, struct sieve_command *tst) { - sieve_operation_emit_code(cgenv->sbin, &test_result_operation); + sieve_operation_emit(cgenv->sbin, tst->ext, &test_result_operation); /* Generate arguments */ return sieve_generate_arguments(cgenv, tst, NULL); @@ -186,8 +179,7 @@ static bool tst_test_result_generate */ static bool tst_test_result_operation_dump -(const struct sieve_operation *op ATTR_UNUSED, - const struct sieve_dumptime_env *denv, sieve_size_t *address) +(const struct sieve_dumptime_env *denv, sieve_size_t *address) { int opt_code = 0; @@ -219,13 +211,12 @@ static bool tst_test_result_operation_dump */ static int tst_test_result_operation_execute -(const struct sieve_operation *op ATTR_UNUSED, - const struct sieve_runtime_env *renv, sieve_size_t *address) +(const struct sieve_runtime_env *renv, sieve_size_t *address) { int opt_code = 0; bool result = TRUE; - const struct sieve_comparator *cmp = &i_octet_comparator; - const struct sieve_match_type *mtch = &is_match_type; + struct sieve_comparator cmp = SIEVE_COMPARATOR_DEFAULT(i_octet_comparator); + struct sieve_match_type mcht = SIEVE_COMPARATOR_DEFAULT(is_match_type); struct sieve_match_context *mctx; struct sieve_coded_stringlist *key_list; bool matched; @@ -244,7 +235,7 @@ static int tst_test_result_operation_execute sieve_number_t number; if ( (ret=sieve_match_read_optional_operands - (renv, address, &opt_code, &cmp, &mtch)) <= 0 ) + (renv, address, &opt_code, &cmp, &mcht)) <= 0 ) return ret; switch ( opt_code ) { @@ -278,20 +269,21 @@ static int tst_test_result_operation_execute rictx = testsuite_result_iterate_init(); /* Initialize match */ - mctx = sieve_match_begin(renv->interp, mtch, cmp, NULL, key_list); + mctx = sieve_match_begin(renv->interp, &mcht, &cmp, NULL, key_list); /* Iterate through all errors to match */ matched = FALSE; cur_index = 1; ret = 0; while ( result && !matched && - (action=sieve_result_iterate_next(rictx, &keep, NULL)) != NULL ) { + (action=sieve_result_iterate_next(rictx, &keep)) != NULL ) { const char *act_name; if ( keep ) act_name = "keep"; else - act_name = ( action == NULL || action->name == NULL ) ? "" : action->name; + act_name = ( action == NULL || action->def == NULL || + action->def->name == NULL ) ? "" : action->def->name; if ( index == 0 || index == cur_index ) { if ( (ret=sieve_match_value(mctx, act_name, strlen(act_name))) < 0 ) { diff --git a/src/testsuite/tst-test-script-compile.c b/src/testsuite/tst-test-script-compile.c index 307a04857..4dad6b00d 100644 --- a/src/testsuite/tst-test-script-compile.c +++ b/src/testsuite/tst-test-script-compile.c @@ -23,11 +23,11 @@ */ static bool tst_test_script_compile_validate - (struct sieve_validator *validator, struct sieve_command_context *cmd); + (struct sieve_validator *valdtr, struct sieve_command *cmd); static bool tst_test_script_compile_generate - (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx); + (const struct sieve_codegen_env *cgenv, struct sieve_command *cmd); -const struct sieve_command tst_test_script_compile = { +const struct sieve_command_def tst_test_script_compile = { "test_script_compile", SCT_TEST, 1, 0, FALSE, FALSE, @@ -42,13 +42,11 @@ const struct sieve_command tst_test_script_compile = { */ static bool tst_test_script_compile_operation_dump - (const struct sieve_operation *op, - const struct sieve_dumptime_env *denv, sieve_size_t *address); + (const struct sieve_dumptime_env *denv, sieve_size_t *address); static int tst_test_script_compile_operation_execute - (const struct sieve_operation *op, - const struct sieve_runtime_env *renv, sieve_size_t *address); + (const struct sieve_runtime_env *renv, sieve_size_t *address); -const struct sieve_operation test_script_compile_operation = { +const struct sieve_operation_def test_script_compile_operation = { "TEST_SCRIPT_COMPILE", &testsuite_extension, TESTSUITE_OPERATION_TEST_SCRIPT_COMPILE, @@ -61,7 +59,7 @@ const struct sieve_operation test_script_compile_operation = { */ static bool tst_test_script_compile_validate -(struct sieve_validator *valdtr ATTR_UNUSED, struct sieve_command_context *tst) +(struct sieve_validator *valdtr ATTR_UNUSED, struct sieve_command *tst) { struct sieve_ast_argument *arg = tst->first_positional; @@ -77,17 +75,10 @@ static bool tst_test_script_compile_validate * Code generation */ -static inline struct testsuite_generator_context * - _get_generator_context(struct sieve_generator *gentr) -{ - return (struct testsuite_generator_context *) - sieve_generator_extension_get_context(gentr, &testsuite_extension); -} - static bool tst_test_script_compile_generate -(const struct sieve_codegen_env *cgenv, struct sieve_command_context *tst) +(const struct sieve_codegen_env *cgenv, struct sieve_command *tst) { - sieve_operation_emit_code(cgenv->sbin, &test_script_compile_operation); + sieve_operation_emit(cgenv->sbin, tst->ext, &test_script_compile_operation); /* Generate arguments */ return sieve_generate_arguments(cgenv, tst, NULL); @@ -98,8 +89,7 @@ static bool tst_test_script_compile_generate */ static bool tst_test_script_compile_operation_dump -(const struct sieve_operation *op ATTR_UNUSED, - const struct sieve_dumptime_env *denv, sieve_size_t *address) +(const struct sieve_dumptime_env *denv, sieve_size_t *address) { sieve_code_dumpf(denv, "TEST_SCRIPT_COMPILE:"); sieve_code_descend(denv); @@ -115,8 +105,7 @@ static bool tst_test_script_compile_operation_dump */ static int tst_test_script_compile_operation_execute -(const struct sieve_operation *op ATTR_UNUSED, - const struct sieve_runtime_env *renv, sieve_size_t *address) +(const struct sieve_runtime_env *renv, sieve_size_t *address) { string_t *script_name; const char *script_path; diff --git a/src/testsuite/tst-test-script-run.c b/src/testsuite/tst-test-script-run.c index 111e15225..802a9cc83 100644 --- a/src/testsuite/tst-test-script-run.c +++ b/src/testsuite/tst-test-script-run.c @@ -24,11 +24,12 @@ */ static bool tst_test_script_run_registered -(struct sieve_validator *validator, struct sieve_command_registration *cmd_reg); +(struct sieve_validator *validator, const struct sieve_extension *ext, + struct sieve_command_registration *cmd_reg); static bool tst_test_script_run_generate - (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx); + (const struct sieve_codegen_env *cgenv, struct sieve_command *cmd); -const struct sieve_command tst_test_script_run = { +const struct sieve_command_def tst_test_script_run = { "test_script_run", SCT_TEST, 0, 0, FALSE, FALSE, @@ -43,13 +44,11 @@ const struct sieve_command tst_test_script_run = { */ static bool tst_test_script_run_operation_dump - (const struct sieve_operation *op, - const struct sieve_dumptime_env *denv, sieve_size_t *address); + (const struct sieve_dumptime_env *denv, sieve_size_t *address); static int tst_test_script_run_operation_execute - (const struct sieve_operation *op, - const struct sieve_runtime_env *renv, sieve_size_t *address); + (const struct sieve_runtime_env *renv, sieve_size_t *address); -const struct sieve_operation test_script_run_operation = { +const struct sieve_operation_def test_script_run_operation = { "test_script_run", &testsuite_extension, TESTSUITE_OPERATION_TEST_SCRIPT_RUN, @@ -70,16 +69,17 @@ enum cmd_vacation_optional { /* Tags */ -static const struct sieve_argument append_result_tag = { +static const struct sieve_argument_def append_result_tag = { "append_result", NULL, NULL, NULL, NULL, NULL }; static bool tst_test_script_run_registered -(struct sieve_validator *validator, struct sieve_command_registration *cmd_reg) +(struct sieve_validator *validator, const struct sieve_extension *ext, + struct sieve_command_registration *cmd_reg) { sieve_validator_register_tag - (validator, cmd_reg, &append_result_tag, OPT_APPEND_RESULT); + (validator, cmd_reg, ext, &append_result_tag, OPT_APPEND_RESULT); return TRUE; } @@ -90,10 +90,9 @@ static bool tst_test_script_run_registered */ static bool tst_test_script_run_generate -(const struct sieve_codegen_env *cgenv, - struct sieve_command_context *tst) +(const struct sieve_codegen_env *cgenv, struct sieve_command *tst) { - sieve_operation_emit_code(cgenv->sbin, &test_script_run_operation); + sieve_operation_emit(cgenv->sbin, tst->ext, &test_script_run_operation); return sieve_generate_arguments(cgenv, tst, NULL); } @@ -103,8 +102,7 @@ static bool tst_test_script_run_generate */ static bool tst_test_script_run_operation_dump -(const struct sieve_operation *op ATTR_UNUSED, - const struct sieve_dumptime_env *denv, sieve_size_t *address) +(const struct sieve_dumptime_env *denv, sieve_size_t *address) { int opt_code = 1; @@ -141,9 +139,7 @@ static bool tst_test_script_run_operation_dump */ static int tst_test_script_run_operation_execute -(const struct sieve_operation *op ATTR_UNUSED, - const struct sieve_runtime_env *renv, - sieve_size_t *address ATTR_UNUSED) +(const struct sieve_runtime_env *renv, sieve_size_t *address) { bool append_result = FALSE; int opt_code = 1; diff --git a/tests/compile/errors/typos.sieve b/tests/compile/errors/typos.sieve index cdc8b252c..cd678a2dd 100644 --- a/tests/compile/errors/typos.sieve +++ b/tests/compile/errors/typos.sieve @@ -1,5 +1,5 @@ /* - * This test is primarily meant to check the compiler's handing of typos + * This test is primarily meant to check the compiler's handling of typos * at various locations. */ diff --git a/tests/extensions/environment/basic.svtest b/tests/extensions/environment/basic.svtest index cb6094587..eea129418 100644 --- a/tests/extensions/environment/basic.svtest +++ b/tests/extensions/environment/basic.svtest @@ -1,13 +1,18 @@ require "vnd.dovecot.testsuite"; require "environment"; +require "variables"; test "Name" { if not environment :contains "name" "dovecot" { - test_fail "name environment returned invalid value"; + if environment :matches "name" "*" { set "env_name" "${1}"; } + + test_fail "name environment returned invalid value(1): ${env_name}"; } if not environment :contains "name" "sieve" { - test_fail "name environment returned invalid value"; + if environment :matches "name" "*" { set "env_name" "${1}"; } + + test_fail "name environment returned invalid value(2): ${env_name}"; } if environment :contains "name" "cyrus" { diff --git a/tests/extensions/imap4flags/multiscript.svtest b/tests/extensions/imap4flags/multiscript.svtest index 98f5a2ac2..35fcabc5e 100644 --- a/tests/extensions/imap4flags/multiscript.svtest +++ b/tests/extensions/imap4flags/multiscript.svtest @@ -26,9 +26,9 @@ Test message. ; test "Internal Flags" { - if hasflag :comparator "i;ascii-numeric" :count "ge" "1" { - test_fail "some flags or keywords are already set"; - } + if hasflag :comparator "i;ascii-numeric" :count "ge" "1" { + test_fail "some flags or keywords are already set"; + } if not test_multiscript [ "multiscript/setflag.sieve", @@ -37,23 +37,19 @@ test "Internal Flags" { test_fail "failed multiscript execution"; } - if not test_result_execute { - test_fail "failed to execute first result"; - } - test_result_reset; test_message :folder "folder" 0; + + if not hasflag "\\answered" { + test_fail "\\answered flag not stored for message"; + } - if not hasflag "\\answered" { - test_fail "\\answered flag not stored for message"; - } - - if not hasflag "$label1" { - test_fail "$label1 keyword not stored for message"; - } + if not hasflag "$label1" { + test_fail "$label1 keyword not stored for message"; + } - if not hasflag :comparator "i;ascii-numeric" :count "eq" "2" { - test_fail "invalid number of flags set for message"; - } + if not hasflag :comparator "i;ascii-numeric" :count "eq" "2" { + test_fail "invalid number of flags set for message"; + } } -- GitLab