From 60f2c55f91e628070743687a8dda577f83f8e767 Mon Sep 17 00:00:00 2001 From: Stephan Bosch <stephan@rename-it.nl> Date: Fri, 14 May 2010 22:57:06 +0200 Subject: [PATCH] Added debug mode to the Sieve engine. --- doc/man/sieve-test.1 | 10 ++-- src/lib-sieve-tool/sieve-tool.c | 4 +- src/lib-sieve-tool/sieve-tool.h | 2 +- src/lib-sieve/sieve-common.h | 3 ++ src/lib-sieve/sieve.c | 36 +++++++++++--- src/lib-sieve/sieve.h | 2 +- src/managesieve/managesieve-capabilities.c | 2 +- src/managesieve/managesieve-client.c | 2 +- src/plugins/lda-sieve/lda-sieve-plugin.c | 16 ++++--- src/sieve-tools/sieve-filter.c | 56 +++++++++++----------- src/sieve-tools/sieve-test.c | 11 +++-- src/sieve-tools/sievec.c | 2 +- src/sieve-tools/sieved.c | 2 +- src/testsuite/testsuite.c | 20 ++++---- 14 files changed, 104 insertions(+), 64 deletions(-) diff --git a/doc/man/sieve-test.1 b/doc/man/sieve-test.1 index f46113b10..03d270e6f 100644 --- a/doc/man/sieve-test.1 +++ b/doc/man/sieve-test.1 @@ -3,7 +3,8 @@ sieve\-test \- Sieve script tester for the Dovecot secure IMAP server .SH SYNOPSIS sieve\-test -[\fB\-c\fR] +[\fB\-C\fR] +[\fB\-D\fR] [\fB\-d\fR \fIdump\-file\fR] [\fB\-e\fR] [\fB\-f\fR \fIenvelope\-sender\fR] @@ -39,17 +40,20 @@ script to (compile and) execute, and the \fImail\-file\fP argument, which specif containing the e\-mail message to filter. Note that this tool looks for a pre\-compiled binary file with a \fI.svbin\fP extension and -with basename and path identical to the specified script. Use the \fB\-c\fP option to disable this +with basename and path identical to the specified script. Use the \fB\-C\fP option to disable this behavior by forcing the script to be compiled into a new binary. .SH OPTIONS .TP -\fB\-c\fP +\fB\-C\fP Force compilation. By default, the compiled binary is stored on disk. When this binary is found during the next execution of \fBsieve\-test\fP and its modification time is more recent than the script file, it is used and the script is not compiled again. This option forces the script to be compiled, thus ignoring any present binary. Refer to \fBsievec\fP(1) for more information about Sieve compilation. .TP +\fB\-D\fP +Enable Sieve debugging. +.TP \fB\-d\fP \fIdump\-file\fP Causes a dump of the generated code to be written to the specified file. This is identical to the dump produced by \fBsieved\fR(1). Using '\-' as filename causes the dump to be written to \fBstdout\fP. diff --git a/src/lib-sieve-tool/sieve-tool.c b/src/lib-sieve-tool/sieve-tool.c index edb3e40f0..86ea2835e 100644 --- a/src/lib-sieve-tool/sieve-tool.c +++ b/src/lib-sieve-tool/sieve-tool.c @@ -95,11 +95,11 @@ void sieve_tool_init(bool init_lib) } } -void sieve_tool_sieve_init(const struct sieve_environment *env) +void sieve_tool_sieve_init(const struct sieve_environment *env, bool debug) { if ( env == NULL ) env = &sieve_tool_sieve_env; - if ( (sieve_instance=sieve_init(env, NULL)) == NULL ) + if ( (sieve_instance=sieve_init(env, NULL, debug)) == NULL ) i_fatal("failed to initialize sieve implementation\n"); } diff --git a/src/lib-sieve-tool/sieve-tool.h b/src/lib-sieve-tool/sieve-tool.h index f10519178..3e3e0bb56 100644 --- a/src/lib-sieve-tool/sieve-tool.h +++ b/src/lib-sieve-tool/sieve-tool.h @@ -24,7 +24,7 @@ extern const struct sieve_environment sieve_tool_env; */ void sieve_tool_init(bool init_lib); -void sieve_tool_sieve_init(const struct sieve_environment *env); +void sieve_tool_sieve_init(const struct sieve_environment *env, bool debug); void sieve_tool_deinit(void); /* diff --git a/src/lib-sieve/sieve-common.h b/src/lib-sieve/sieve-common.h index d037b165a..a6f996322 100644 --- a/src/lib-sieve/sieve-common.h +++ b/src/lib-sieve/sieve-common.h @@ -149,6 +149,9 @@ struct sieve_instance { const struct sieve_environment *env; void *context; + /* Engine debug */ + bool debug; + /* Extension registry */ struct sieve_extension_registry *ext_reg; diff --git a/src/lib-sieve/sieve.c b/src/lib-sieve/sieve.c index 55e393fd3..2dc7198af 100644 --- a/src/lib-sieve/sieve.c +++ b/src/lib-sieve/sieve.c @@ -40,7 +40,7 @@ */ struct sieve_instance *sieve_init -(const struct sieve_environment *env, void *context) +(const struct sieve_environment *env, void *context, bool debug) { struct sieve_instance *svinst; unsigned long long int uint_setting; @@ -53,6 +53,7 @@ struct sieve_instance *sieve_init svinst->pool = pool; svinst->env = env; svinst->context = context; + svinst->debug = debug; /* Read limits from configuration */ @@ -215,6 +216,10 @@ struct sieve_binary *sieve_compile sbin = sieve_compile_script(script, ehandler); sieve_script_unref(&script); + + if ( svinst->debug && sbin != NULL ) { + sieve_sys_debug("script file %s successfully compiled", script_path); + } return sbin; } @@ -266,7 +271,7 @@ struct sieve_binary *sieve_open { struct sieve_script *script; struct sieve_binary *sbin; - const char *binpath; + const char *bin_path; /* First open the scriptfile itself */ script = sieve_script_create @@ -279,15 +284,19 @@ struct sieve_binary *sieve_open T_BEGIN { /* Then try to open the matching binary */ - binpath = sieve_script_binpath(script); - sbin = sieve_binary_open(svinst, binpath, script); + bin_path = sieve_script_binpath(script); + sbin = sieve_binary_open(svinst, bin_path, script); if (sbin != NULL) { /* Ok, it exists; now let's see if it is up to date */ if ( !sieve_binary_up_to_date(sbin) ) { /* Not up to date */ + if ( svinst->debug ) + sieve_sys_debug("script binary %s is not up-to-date", bin_path); + sieve_binary_unref(&sbin); sbin = NULL; + } else if ( !sieve_binary_load(sbin) ) { /* Failed to load */ sieve_binary_unref(&sbin); @@ -298,12 +307,25 @@ struct sieve_binary *sieve_open /* If the binary does not exist, is not up-to-date or fails to load, we need * to (re-)compile. */ - if ( sbin == NULL ) { + if ( sbin != NULL ) { + if ( svinst->debug ) + sieve_sys_debug("script binary %s successfully loaded", bin_path); + + } else { sbin = sieve_compile_script(script, ehandler); /* Save the binary if compile was successful */ - if ( sbin != NULL ) - (void) sieve_binary_save(sbin, binpath); + if ( sbin != NULL ) { + if ( svinst->debug ) + sieve_sys_debug("script %s successfully compiled", script_path); + + if ( sieve_binary_save(sbin, bin_path) ) { + if ( svinst->debug ) { + sieve_sys_debug + ("compiled script saved as binary file %s", bin_path); + } + } + } } } T_END; diff --git a/src/lib-sieve/sieve.h b/src/lib-sieve/sieve.h index 346328352..aa47978ea 100644 --- a/src/lib-sieve/sieve.h +++ b/src/lib-sieve/sieve.h @@ -22,7 +22,7 @@ struct sieve_binary; * is used. */ struct sieve_instance *sieve_init - (const struct sieve_environment *env, void *context); + (const struct sieve_environment *env, void *context, bool debug); /* sieve_deinit(): * Frees all memory allocated by the sieve engine. diff --git a/src/managesieve/managesieve-capabilities.c b/src/managesieve/managesieve-capabilities.c index aae1e785d..4da049d56 100644 --- a/src/managesieve/managesieve-capabilities.c +++ b/src/managesieve/managesieve-capabilities.c @@ -130,7 +130,7 @@ void managesieve_capabilities_dump(void) /* Initialize Sieve engine */ - svinst = sieve_init(&sieve_env, (void *) global_plugin_settings); + svinst = sieve_init(&sieve_env, (void *) global_plugin_settings, FALSE); extensions = plugin_settings_get(global_plugin_settings, "sieve_extensions"); if ( extensions != NULL ) { diff --git a/src/managesieve/managesieve-client.c b/src/managesieve/managesieve-client.c index 33fab785a..d0fed85f5 100644 --- a/src/managesieve/managesieve-client.c +++ b/src/managesieve/managesieve-client.c @@ -122,7 +122,7 @@ struct client *client_create /* Initialize Sieve instance */ - svinst = sieve_init(&managesieve_sieve_env, (void *) user); + svinst = sieve_init(&managesieve_sieve_env, (void *) user, set->mail_debug); extensions = mail_user_plugin_getenv(user, "sieve_extensions"); if ( extensions != NULL ) { diff --git a/src/plugins/lda-sieve/lda-sieve-plugin.c b/src/plugins/lda-sieve/lda-sieve-plugin.c index 6dea89aef..35b3497fb 100644 --- a/src/plugins/lda-sieve/lda-sieve-plugin.c +++ b/src/plugins/lda-sieve/lda-sieve-plugin.c @@ -520,12 +520,13 @@ static int lda_sieve_run struct sieve_script_env scriptenv; struct sieve_exec_status estatus; const char *extensions = NULL; + bool debug = mdctx->dest_user->mail_debug; int ret = 0; *storage_r = NULL; /* Initialize Sieve engine */ - svinst = sieve_init(&lda_sieve_env, mdctx->dest_user); + svinst = sieve_init(&lda_sieve_env, mdctx->dest_user, debug); extensions = mail_user_plugin_getenv (mdctx->dest_user, "sieve_extensions"); @@ -626,7 +627,6 @@ static int lda_sieve_run /* Clean up */ - if ( srctx.user_ehandler != NULL ) sieve_error_handler_unref(&srctx.user_ehandler); @@ -662,8 +662,8 @@ static int lda_sieve_deliver_mail switch ( errno ) { case ENOENT: - if (getenv("DEBUG") != NULL) - sieve_sys_info("user's script path %s doesn't exist " + if ( debug ) + sieve_sys_debug("user's script path %s doesn't exist " "(using global script path in stead)", user_script); break; case EACCES: @@ -712,12 +712,14 @@ static int lda_sieve_deliver_mail scriptfiles = array_get(&scripts_before, &count); for ( i = 0; i < count; i ++ ) { - sieve_sys_debug("executed before user's script(%d): %s", i+1, scriptfiles[i]); + sieve_sys_debug("executed before user's script(%d): %s", + i+1, scriptfiles[i]); } scriptfiles = array_get(&scripts_after, &count); for ( i = 0; i < count; i ++ ) { - sieve_sys_debug("executed after user's script(%d): %s", i+1, scriptfiles[i]); + sieve_sys_debug("executed after user's script(%d): %s", + i+1, scriptfiles[i]); } } @@ -738,7 +740,7 @@ static int lda_sieve_deliver_mail /* Run the script(s) */ ret = lda_sieve_run - (mdctx, user_script, default_script, &scripts_before, &scripts_after, + (mdctx, user_script, default_script, &scripts_before, &scripts_after, storage_r); } diff --git a/src/sieve-tools/sieve-filter.c b/src/sieve-tools/sieve-filter.c index c9a358f4b..e0e79e900 100644 --- a/src/sieve-tools/sieve-filter.c +++ b/src/sieve-tools/sieve-filter.c @@ -221,39 +221,39 @@ static int filter_mailbox int main(int argc, char **argv) { - enum mail_storage_service_flags service_flags = 0; - struct mail_storage_service_ctx *storage_service; - struct mail_storage_service_user *service_user; - struct mail_storage_service_input service_input; - struct mail_user *mail_user_dovecot = NULL; + enum mail_storage_service_flags service_flags = 0; + struct mail_storage_service_ctx *storage_service; + struct mail_storage_service_user *service_user; + struct mail_storage_service_input service_input; + struct mail_user *mail_user_dovecot = NULL; struct mail_user *mail_user = NULL; - ARRAY_TYPE (const_string) plugins; + ARRAY_TYPE (const_string) plugins; const char *scriptfile, *recipient, *sender, *extensions, - *src_mailbox, *dst_mailbox, *src_mailstore, *dst_mailstore; - const char *user, *home, *errstr; - struct mail_namespace_settings ns_set; + *src_mailbox, *dst_mailbox, *src_mailstore, *dst_mailstore; + const char *user, *home, *errstr; + struct mail_namespace_settings ns_set; struct mail_namespace *src_ns = NULL, *dst_ns = NULL; struct mail_storage *dst_storage, *src_storage; - struct sieve_binary *main_sbin; - struct sieve_script_env scriptenv; - struct sieve_error_handler *ehandler; - bool force_compile = FALSE; - enum mailbox_flags open_flags = - MAILBOX_FLAG_KEEP_RECENT | MAILBOX_FLAG_IGNORE_ACLS; + struct sieve_binary *main_sbin; + struct sieve_script_env scriptenv; + struct sieve_error_handler *ehandler; + bool force_compile = FALSE, debug = FALSE; + enum mailbox_flags open_flags = + MAILBOX_FLAG_KEEP_RECENT | MAILBOX_FLAG_IGNORE_ACLS; enum mail_error error; struct discard_action discard_action = - { DISCARD_ACTION_KEEP, "Trash" }; + { DISCARD_ACTION_KEEP, "Trash" }; struct mailbox *src_box; - int c; + int c; - master_service = master_service_init("sieve-test", - MASTER_SERVICE_FLAG_STANDALONE, &argc, &argv, "m:x:cP:"); + master_service = master_service_init("sieve-test", + MASTER_SERVICE_FLAG_STANDALONE, &argc, &argv, "m:x:P:CD"); - sieve_tool_init(FALSE); + sieve_tool_init(FALSE); - t_array_init(&plugins, 4); + t_array_init(&plugins, 4); - user = getenv("USER"); + user = getenv("USER"); /* Parse arguments */ scriptfile = recipient = sender = extensions = src_mailstore = dst_mailstore @@ -270,9 +270,6 @@ int main(int argc, char **argv) /* extensions */ extensions = optarg; break; - case 'c': - force_compile = TRUE; - break; case 'P': /* Plugin */ { @@ -282,7 +279,12 @@ int main(int argc, char **argv) array_append(&plugins, &plugin, 1); } break; - + case 'C': + force_compile = TRUE; + break; + case 'D': + debug = TRUE; + break; default: print_help(); i_fatal_status(EX_USAGE, "Unknown argument: %c", c); @@ -313,7 +315,7 @@ int main(int argc, char **argv) i_fatal_status(EX_USAGE, "Unknown argument: %s", argv[optind]); } - sieve_tool_sieve_init(NULL); + sieve_tool_sieve_init(NULL, debug); if ( array_count(&plugins) > 0 ) { sieve_tool_load_plugins(&plugins); diff --git a/src/sieve-tools/sieve-test.c b/src/sieve-tools/sieve-test.c index d0f8da97f..d8feb1877 100644 --- a/src/sieve-tools/sieve-test.c +++ b/src/sieve-tools/sieve-test.c @@ -123,12 +123,12 @@ int main(int argc, char **argv) struct sieve_error_handler *ehandler; struct ostream *teststream = NULL; bool force_compile = FALSE, execute = FALSE; - bool trace = FALSE; + bool debug = FALSE, trace = FALSE; int exit_status = EXIT_SUCCESS; int ret, c; master_service = master_service_init("sieve-test", - MASTER_SERVICE_FLAG_STANDALONE, &argc, &argv, "r:f:m:d:l:x:s:ectP:"); + MASTER_SERVICE_FLAG_STANDALONE, &argc, &argv, "r:f:m:d:l:x:s:P:eCtD"); sieve_tool_init(FALSE); @@ -187,12 +187,15 @@ int main(int argc, char **argv) case 'e': execute = TRUE; break; - case 'c': + case 'C': force_compile = TRUE; break; case 't': trace = TRUE; break; + case 'D': + debug = TRUE; + break; default: print_help(); i_fatal_status(EX_USAGE, "Unknown argument: %c", c); @@ -219,7 +222,7 @@ int main(int argc, char **argv) i_fatal_status(EX_USAGE, "Unknown argument: %s", argv[optind]); } - sieve_tool_sieve_init(NULL); + sieve_tool_sieve_init(NULL, debug); if ( array_count(&plugins) > 0 ) { sieve_tool_load_plugins(&plugins); diff --git a/src/sieve-tools/sievec.c b/src/sieve-tools/sievec.c index 4556a8cf9..993fec5b5 100644 --- a/src/sieve-tools/sievec.c +++ b/src/sieve-tools/sievec.c @@ -94,7 +94,7 @@ int main(int argc, char **argv) if ( outfile == NULL && dump ) outfile = "-"; - sieve_tool_sieve_init(NULL); + sieve_tool_sieve_init(NULL, FALSE); if ( array_count(&plugins) > 0 ) { sieve_tool_load_plugins(&plugins); diff --git a/src/sieve-tools/sieved.c b/src/sieve-tools/sieved.c index 9f3490120..86581d7b4 100644 --- a/src/sieve-tools/sieved.c +++ b/src/sieve-tools/sieved.c @@ -84,7 +84,7 @@ int main(int argc, char **argv) i_fatal_status(EX_USAGE, "missing <sieve-binary> argument"); } - sieve_tool_sieve_init(NULL); + sieve_tool_sieve_init(NULL, FALSE); if ( array_count(&plugins) > 0 ) { sieve_tool_load_plugins(&plugins); diff --git a/src/testsuite/testsuite.c b/src/testsuite/testsuite.c index d7ca68d88..4739cc07f 100644 --- a/src/testsuite/testsuite.c +++ b/src/testsuite/testsuite.c @@ -119,11 +119,11 @@ int main(int argc, char **argv) ARRAY_TYPE(const_string) plugins; struct sieve_binary *sbin; const char *sieve_dir; - bool trace = FALSE, log_stdout = FALSE; + bool trace = FALSE, log_stdout = FALSE, debug = FALSE; int ret, c; master_service = master_service_init - ("testsuite", MASTER_SERVICE_FLAG_STANDALONE, &argc, &argv, "d:x:tP:E"); + ("testsuite", MASTER_SERVICE_FLAG_STANDALONE, &argc, &argv, "d:x:P:tED"); user = getenv("USER"); @@ -141,11 +141,8 @@ int main(int argc, char **argv) dumpfile = optarg; break; case 'x': - /* destination address */ - extensions = optarg; - break; - case 't': - trace = TRUE; + /* destination address */ + extensions = optarg; break; case 'P': /* Plugin */ @@ -156,9 +153,15 @@ int main(int argc, char **argv) array_append(&plugins, &plugin, 1); } break; + case 't': + trace = TRUE; + break; case 'E': log_stdout = TRUE; break; + case 'D': + debug = TRUE; + break; default: print_help(); i_fatal_status(EX_USAGE, @@ -202,7 +205,8 @@ int main(int argc, char **argv) /* Initialize testsuite */ testsuite_settings_init(); - sieve_tool_sieve_init(&testsuite_sieve_env); + + sieve_tool_sieve_init(&testsuite_sieve_env, debug); sieve_tool_load_plugins(&plugins); sieve_extensions_set_string(sieve_instance, extensions); testsuite_init(sieve_instance, log_stdout); -- GitLab