diff --git a/doc/man/sieve-test.1 b/doc/man/sieve-test.1 index f46113b10f00b3e9fa1f83a13dc710231849b37b..03d270e6faef7d93b79b18e596d39f57dda9c30f 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 edb3e40f0b281af7031e41462b5bb9243345c86a..86ea2835e815ae72dada99013a14ae70965b0a12 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 f1051917882c13d235ac56d27e9a925172232e1d..3e3e0bb56a62923ba2331b58f5d1a878013f0ba2 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 d037b165ae36706ead6048153477f831579c7f57..a6f9963229acb804321127c8121c89ebf9b90e7f 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 55e393fd3131275f11823ff6c221d1ff6b539a31..2dc7198afd0b37ced616d4c910048654a9aacddb 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 346328352f39a9548c843131ed93e882643eeac9..aa47978ea37846a8dfc22bd699cbbf1c0bbc8693 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 aae1e785d4ed17cb400abc2f2fe893cbb649d960..4da049d560119530322bf2c7393cb331d2a3b6c9 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 33fab785a2f58a2eaa7b3e4e632cf2f49517c304..d0fed85f53fe3b3aacb5e0919d93a7c1cc460142 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 6dea89aefbe29f0e5905dcc22b17093646f4d92a..35b3497fb6589521fb51136f7f5601195dde591b 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 c9a358f4bc8854845993257dc64a40ac169bc6a4..e0e79e9001cd045e7b5653874b9b6f2cbc38e324 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 d0f8da97f790ad6f6ed3d9947c0d26c0a5952a6b..d8feb1877f5c56cfaebb548bded6a46154ea60f2 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 4556a8cf945d5d996c3f8fd6544080ae3ebeb400..993fec5b5738e65d73f1107c1cfcdca687ec7a6e 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 9f3490120bae6fd426ad654536bcaebfde740767..86581d7b4eff557b37ecdc8b06dcfd3e5807e694 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 d7ca68d88ff2874114b6a1e2e463fb81661a3676..4739cc07fb117358cf652b69194d74ae00342186 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);