diff --git a/TODO b/TODO index 16492e0046d80e47e46ebdd2935d14323298b66a..5b936e9616cb58b5cfc2dca7b7e9a92284df7ac6 100644 --- a/TODO +++ b/TODO @@ -2,8 +2,6 @@ Current activities: * Improve debugging support in the sieve-test tool: - Improve trace debugging towards something more intuitively readable. - - Give trace debugging multiple levels of verbosity (e.g. to include more - messy output like value matching). Next (in order of descending priority/precedence): diff --git a/src/lib-sieve/cmd-discard.c b/src/lib-sieve/cmd-discard.c index 1d43cb26c7924966930885e3bd764f62e9b0021e..69a6821a6577a6b7915b9dfe18d8f1bba720adb3 100644 --- a/src/lib-sieve/cmd-discard.c +++ b/src/lib-sieve/cmd-discard.c @@ -110,7 +110,7 @@ static int cmd_discard_operation_execute /* Source line */ source_line = sieve_runtime_get_command_location(renv); - sieve_runtime_trace(renv, SIEVE_TRLVL_ACTIONS, "discard action"); + sieve_runtime_trace(renv, SIEVE_TRLVL_ACTIONS, "discard action; cancel implicit keep"); return ( sieve_result_add_action (renv, NULL, &act_discard, NULL, source_line, NULL, 0) >= 0 ); diff --git a/src/lib-sieve/cmd-keep.c b/src/lib-sieve/cmd-keep.c index 2838fd892a969240b1f6a0ba416dbc65423723d7..27f3782c98a0f03f783e8a103a91f2bfc4ec0990 100644 --- a/src/lib-sieve/cmd-keep.c +++ b/src/lib-sieve/cmd-keep.c @@ -102,7 +102,8 @@ static int cmd_keep_operation_execute * Perform operation */ - sieve_runtime_trace(renv, SIEVE_TRLVL_ACTIONS, "keep action"); + sieve_runtime_trace(renv, SIEVE_TRLVL_ACTIONS, + "keep action; store message in default mailbox"); /* Add keep action to result. */ diff --git a/src/lib-sieve/cmd-redirect.c b/src/lib-sieve/cmd-redirect.c index 98f26ae9e4a9f85d751480a151ab005ed0794d76..7f77b0fe9cb677943b22efa568d9e11d06dfe2cb 100644 --- a/src/lib-sieve/cmd-redirect.c +++ b/src/lib-sieve/cmd-redirect.c @@ -219,7 +219,8 @@ static int cmd_redirect_operation_execute /* FIXME: perform address normalization if the string is not a string literal */ - sieve_runtime_trace(renv, SIEVE_TRLVL_ACTIONS, "redirect action (\"%s\")", + sieve_runtime_trace(renv, SIEVE_TRLVL_ACTIONS, + "redirect action; forward message to address `%s'", str_sanitize(str_c(redirect), 64)); /* Add redirect action to the result */ diff --git a/src/lib-sieve/cmd-stop.c b/src/lib-sieve/cmd-stop.c index f908285e78df2c87a829fa47eb22cc64b7eca294..a28f9c2ca5e50ac780eaa7eedacaa6b880487363 100644 --- a/src/lib-sieve/cmd-stop.c +++ b/src/lib-sieve/cmd-stop.c @@ -77,7 +77,7 @@ static bool cmd_stop_generate static int opc_stop_execute (const struct sieve_runtime_env *renv, sieve_size_t *address ATTR_UNUSED) { - sieve_runtime_trace(renv, SIEVE_TRLVL_COMMANDS, "STOP"); + sieve_runtime_trace(renv, SIEVE_TRLVL_COMMANDS, "stop"); sieve_interpreter_interrupt(renv->interp); diff --git a/src/lib-sieve/ext-envelope.c b/src/lib-sieve/ext-envelope.c index e81cdbc74e59dfed0697c80f781bef566c85b3ad..97f8fe4726d441b92d6adb1a7bc75ade0bdf326a 100644 --- a/src/lib-sieve/ext-envelope.c +++ b/src/lib-sieve/ext-envelope.c @@ -458,6 +458,9 @@ static int ext_envelope_operation_execute (result=sieve_coded_stringlist_next_item(envp_list, &envp_item)) && envp_item != NULL ) { const struct sieve_envelope_part *epart; + + sieve_runtime_trace(renv, SIEVE_TRLVL_MATCHING, + " matching envelope part `%s'", str_sanitize(str_c(envp_item), 80)); if ( (epart=_envelope_part_find(str_c(envp_item))) != NULL ) { const struct sieve_address * const *addresses = NULL; diff --git a/src/lib-sieve/ext-fileinto.c b/src/lib-sieve/ext-fileinto.c index 0197c55033a65c6c5703ac75df7040dd6a3576b7..9a1b453ca6f2374549942e2d8a668d17fcf897ee 100644 --- a/src/lib-sieve/ext-fileinto.c +++ b/src/lib-sieve/ext-fileinto.c @@ -179,7 +179,7 @@ static int ext_fileinto_operation_execute mailbox = str_sanitize(str_c(folder), 64); sieve_runtime_trace(renv, SIEVE_TRLVL_ACTIONS, - "fileinto action (\"%s\")", mailbox); + "fileinto action; store message in mailbox `%s'", mailbox); /* Add action to result */ ret = sieve_act_store_add_to_result diff --git a/src/lib-sieve/ext-reject.c b/src/lib-sieve/ext-reject.c index 8736b65375b7afc8b9fda49ab5cb8dfd7b291f7c..7251ebffeccfddf99a78efaeee64ced70c07e45a 100644 --- a/src/lib-sieve/ext-reject.c +++ b/src/lib-sieve/ext-reject.c @@ -292,10 +292,10 @@ static int ext_reject_operation_execute if ( sieve_operation_is(oprtn, ereject_operation) ) sieve_runtime_trace(renv, SIEVE_TRLVL_ACTIONS, - "ereject action (\"%s\")", str_sanitize(str_c(reason), 64)); + "ereject action; reject message with reason `%s'", str_sanitize(str_c(reason), 64)); else sieve_runtime_trace(renv, SIEVE_TRLVL_ACTIONS, - "reject action (\"%s\")", str_sanitize(str_c(reason), 64)); + "reject action; reject message with reason `%s'", str_sanitize(str_c(reason), 64)); /* Add reject action to the result */ pool = sieve_result_pool(renv->result); diff --git a/src/lib-sieve/sieve-address-parts.c b/src/lib-sieve/sieve-address-parts.c index d163e8ce79b5f0d574a32723ed5075842b869d2b..9cae114ab05390c45023b515802f9f87f4c43104 100644 --- a/src/lib-sieve/sieve-address-parts.c +++ b/src/lib-sieve/sieve-address-parts.c @@ -7,6 +7,7 @@ #include "hash.h" #include "array.h" #include "message-address.h" +#include "str-sanitize.h" #include "sieve-extensions.h" #include "sieve-code.h" @@ -234,9 +235,13 @@ int sieve_address_match (const struct sieve_address_part *addrp, struct sieve_match_context *mctx, const char *data) { + const struct sieve_runtime_env *renv = mctx->runenv; int result = FALSE; const struct message_address *addr; + sieve_runtime_trace(renv, SIEVE_TRLVL_MATCHING, + " matching addresses `%s'", str_sanitize(data, 80)); + T_BEGIN { bool valid = TRUE; const struct message_address *aitem; diff --git a/src/lib-sieve/sieve-code.c b/src/lib-sieve/sieve-code.c index 6f15607ac30625aa39a79fb23acb1b4e953b5afd..02cb48415cce1253b3360ce2fd9da441eb28ff5b 100644 --- a/src/lib-sieve/sieve-code.c +++ b/src/lib-sieve/sieve-code.c @@ -1058,8 +1058,7 @@ static int opc_jmptrue_execute { bool result = sieve_interpreter_get_test_result(renv->interp); - sieve_runtime_trace(renv, SIEVE_TRLVL_COMMANDS, "jump if true (%s)", - result ? "true" : "false"); + sieve_runtime_trace(renv, SIEVE_TRLVL_COMMANDS, "jump if result is true"); return sieve_interpreter_program_jump(renv->interp, result); } @@ -1069,8 +1068,7 @@ static int opc_jmpfalse_execute { bool result = sieve_interpreter_get_test_result(renv->interp); - sieve_runtime_trace(renv, SIEVE_TRLVL_COMMANDS, "jump if false (%s)", - result ? "true" : "false" ); + sieve_runtime_trace(renv, SIEVE_TRLVL_COMMANDS, "jump if result is false"); return sieve_interpreter_program_jump(renv->interp, !result); } diff --git a/src/lib-sieve/sieve-interpreter.c b/src/lib-sieve/sieve-interpreter.c index 68260ea5b61f3efc09db91d7a7662ee61915103b..3b2c9a074f70d3bd9f180734f7e1fcdda5ea6e12 100644 --- a/src/lib-sieve/sieve-interpreter.c +++ b/src/lib-sieve/sieve-interpreter.c @@ -425,10 +425,23 @@ int sieve_interpreter_program_jump jmp_start + jmp_offset > 0 ) { if ( jump ) { - sieve_runtime_trace_here(renv, SIEVE_TRLVL_COMMANDS, "jump to #%08llx", - (long long unsigned int) jmp_start + jmp_offset); + sieve_size_t jmp_addr = jmp_start + jmp_offset; + + if ( sieve_runtime_trace_active(renv, SIEVE_TRLVL_COMMANDS) ) { + unsigned int jmp_line = + sieve_runtime_get_source_location(renv, jmp_addr); + + if ( (renv->trace_config.flags & SIEVE_TRFLG_ADDRESSES) > 0 ) { + sieve_runtime_trace(renv, 0, "jumping to line %d [%08llx]", + jmp_line, (long long unsigned int) jmp_addr); + } else { + sieve_runtime_trace(renv, 0, "jumping to line %d", jmp_line); + } + } - *address = jmp_start + jmp_offset; + *address = jmp_addr; + } else { + sieve_runtime_trace(renv, 0, "not jumping"); } return SIEVE_EXEC_OK; diff --git a/src/lib-sieve/sieve-match.c b/src/lib-sieve/sieve-match.c index 523e1791e81d33d062014267b81a13b5d0191f3e..0d4c8bb937b948efc2e01d0e193f4f170a5556d2 100644 --- a/src/lib-sieve/sieve-match.c +++ b/src/lib-sieve/sieve-match.c @@ -61,20 +61,25 @@ int sieve_match_value const struct sieve_runtime_env *renv = mctx->runenv; const struct sieve_match_type *mcht = mctx->match_type; sieve_coded_stringlist_reset(mctx->key_list); + bool trace = sieve_runtime_trace_active(renv, SIEVE_TRLVL_MATCHING); bool ok = TRUE; + int ret = 0; /* Reject unimplemented match-type */ - if ( mcht->def == NULL || mcht->def->match == NULL ) + if ( mcht->def == NULL || mcht->def->match == NULL ) { + mctx->status = FALSE; return FALSE; + } - sieve_runtime_trace(renv, SIEVE_TRLVL_MATCHING, - " matching value `%s'", str_sanitize(value, 80)); + if ( trace ) { + sieve_runtime_trace(renv, 0, + " matching value `%s'", str_sanitize(value, 80)); + } /* Match to all key values */ 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 ) { @@ -91,8 +96,10 @@ int sieve_match_value ret = mcht->def->match (mctx, value, val_size, key, key_size, key_index); - sieve_runtime_trace(renv, SIEVE_TRLVL_MATCHING, - " with key `%s' => %d", str_sanitize(key, 80), ret); + if ( trace ) { + sieve_runtime_trace(renv, 0, + " with key `%s' => %d", str_sanitize(key, 80), ret); + } if ( ret != 0 ) break; } @@ -101,8 +108,10 @@ int sieve_match_value ret = mcht->def->match(mctx, value, val_size, str_c(key_item), str_len(key_item), key_index); - sieve_runtime_trace(renv, SIEVE_TRLVL_MATCHING, - " with key `%s' => %d", str_sanitize(str_c(key_item), 80), ret); + if ( trace ) { + sieve_runtime_trace(renv, 0, + " with key `%s' => %d", str_sanitize(str_c(key_item), 80), ret); + } } } T_END; @@ -112,31 +121,23 @@ int sieve_match_value key_index++; } - if ( !ok ) - return -1; - - if ( ret < 0 ) - return ret; - if ( ret > 0 ) - return TRUE; + if ( !ok ) ret = -1; } else { - int ret; - T_BEGIN { ret = mcht->def->match(mctx, value, val_size, NULL, 0, -1); } T_END; - - return ret; } - return FALSE; + mctx->status = ret; + return ret; } int sieve_match_end(struct sieve_match_context **mctx) { const struct sieve_runtime_env *renv = (*mctx)->runenv; const struct sieve_match_type *mcht = (*mctx)->match_type; + int status = (*mctx)->status; int ret = FALSE; if ( mcht->def != NULL && mcht->def->match_deinit != NULL ) { @@ -146,9 +147,11 @@ int sieve_match_end(struct sieve_match_context **mctx) pool_unref(&(*mctx)->pool); *mctx = NULL; + if ( ret < 0 ) status = ret; + sieve_runtime_trace(renv, SIEVE_TRLVL_MATCHING, " finishing match with result: %s", - ( ret > 0 ? "true" : ( ret < 0 ? "error" : "false" ) )); + ( status > 0 ? "true" : ( status < 0 ? "error" : "false" ) )); return ret; } diff --git a/src/lib-sieve/sieve-match.h b/src/lib-sieve/sieve-match.h index cd79c9a00fbba1fda4f8a828ab0b9c1c72fa057c..ed3c1d79c8a1df2f144f0c61b966d68c591646f8 100644 --- a/src/lib-sieve/sieve-match.h +++ b/src/lib-sieve/sieve-match.h @@ -25,7 +25,7 @@ struct sieve_match_context { struct sieve_coded_stringlist *key_list; - + int status; void *data; }; diff --git a/src/lib-sieve/sieve-runtime-trace.c b/src/lib-sieve/sieve-runtime-trace.c index b570fa01782390efb4e0f6200bc11054d14c0470..a4bdd8426b8d44c8b8b1ea179499f9e6e4b9a8cc 100644 --- a/src/lib-sieve/sieve-runtime-trace.c +++ b/src/lib-sieve/sieve-runtime-trace.c @@ -11,12 +11,13 @@ #include "sieve-runtime-trace.h" static inline string_t *_trace_line_new -(sieve_size_t address, unsigned int cmd_line) +(const struct sieve_runtime_env *renv, sieve_size_t address, unsigned int cmd_line) { string_t *trline; trline = t_str_new(128); - str_printfa(trline, "%08llx: ", (unsigned long long) address); + if ( (renv->trace_config.flags & SIEVE_TRFLG_ADDRESSES) > 0 ) + str_printfa(trline, "%08llx: ", (unsigned long long) address); if ( cmd_line > 0 ) str_printfa(trline, "%4d: ", cmd_line); else @@ -46,7 +47,7 @@ static inline void _trace_line_print_empty void _sieve_runtime_trace_error (const struct sieve_runtime_env *renv, const char *fmt, va_list args) { - string_t *trline = _trace_line_new(renv->pc, 0); + string_t *trline = _trace_line_new(renv, renv->pc, 0); str_printfa(trline, "%s: #ERROR#: ", sieve_operation_mnemonic(renv->oprtn)); str_vprintfa(trline, fmt, args); @@ -59,7 +60,7 @@ void _sieve_runtime_trace_operand_error const char *field_name, const char *fmt, va_list args) { string_t *trline = _trace_line_new - (oprnd->address, sieve_runtime_get_source_location(renv, oprnd->address)); + (renv, oprnd->address, sieve_runtime_get_source_location(renv, oprnd->address)); str_printfa(trline, "%s: #ERROR#: ", sieve_operation_mnemonic(renv->oprtn)); @@ -79,7 +80,7 @@ static inline void _sieve_runtime_trace_vprintf (const struct sieve_runtime_env *renv, sieve_size_t address, unsigned int cmd_line, const char *fmt, va_list args) { - string_t *trline = _trace_line_new(address, cmd_line); + string_t *trline = _trace_line_new(renv, address, cmd_line); str_vprintfa(trline, fmt, args); diff --git a/src/lib-sieve/tst-address.c b/src/lib-sieve/tst-address.c index bdecded82a4dd77dbe43ddd46f4ca8081f9a7662..bf6d83feb81b7da4611e85dc81f0e544bc7eda87 100644 --- a/src/lib-sieve/tst-address.c +++ b/src/lib-sieve/tst-address.c @@ -264,6 +264,9 @@ static int tst_address_operation_execute (result=sieve_coded_stringlist_next_item(hdr_list, &hdr_item)) && hdr_item != NULL ) { const char *const *headers; + + sieve_runtime_trace(renv, SIEVE_TRLVL_MATCHING, + " matching header `%s'", str_sanitize(str_c(hdr_item), 80)); if ( mail_get_headers_utf8 (renv->msgdata->mail, str_c(hdr_item), &headers) >= 0 ) { diff --git a/src/lib-sieve/tst-exists.c b/src/lib-sieve/tst-exists.c index ee3851ac685f57bc2754499944373f273df96fee..278faf80ceaa69210470494ae4ee35b8eef0dee8 100644 --- a/src/lib-sieve/tst-exists.c +++ b/src/lib-sieve/tst-exists.c @@ -1,6 +1,9 @@ /* Copyright (c) 2002-2010 Dovecot Sieve authors, see the included COPYING file */ +#include "lib.h" +#include "str-sanitize.h" + #include "sieve-common.h" #include "sieve-commands.h" #include "sieve-code.h" @@ -132,9 +135,13 @@ static int tst_exists_operation_execute if ( mail_get_headers (renv->msgdata->mail, str_c(hdr_item), &headers) < 0 || - headers[0] == NULL ) { + headers[0] == NULL ) { matched = FALSE; - } + } + + sieve_runtime_trace(renv, SIEVE_TRLVL_MATCHING, + " header `%s' %s", str_sanitize(str_c(hdr_item), 80), + ( matched ? "exists" : "missing" )); } /* Set test result for subsequent conditional jump */ diff --git a/src/lib-sieve/tst-header.c b/src/lib-sieve/tst-header.c index 438b2e42eb2adf0f329b35dbd0f558ec44adaba9..26ce9311f87be65d2105313bb67559a86a9c56d8 100644 --- a/src/lib-sieve/tst-header.c +++ b/src/lib-sieve/tst-header.c @@ -1,6 +1,9 @@ /* Copyright (c) 2002-2010 Dovecot Sieve authors, see the included COPYING file */ +#include "lib.h" +#include "str-sanitize.h" + #include "sieve-common.h" #include "sieve-commands.h" #include "sieve-code.h" @@ -219,6 +222,9 @@ static int tst_header_operation_execute (result=sieve_coded_stringlist_next_item(hdr_list, &hdr_item)) && hdr_item != NULL ) { const char *const *headers; + + sieve_runtime_trace(renv, SIEVE_TRLVL_MATCHING, + " matching header `%s'", str_sanitize(str_c(hdr_item), 80)); if ( mail_get_headers_utf8 (renv->msgdata->mail, str_c(hdr_item), &headers) >= 0 ) { diff --git a/src/sieve-tools/sieve-test.c b/src/sieve-tools/sieve-test.c index fe5aa36e49f542d3f9e9742e5190a354e05c12d2..55c05771e1f82ec9313bc76f2bb29a9a9cd5259f 100644 --- a/src/sieve-tools/sieve-test.c +++ b/src/sieve-tools/sieve-test.c @@ -120,9 +120,9 @@ static void parse_trace_option i_fatal_status(EX_USAGE, "Unknown -tlevel= trace level: %s", lvl); } } else if ( strcmp(tr_option, "debug") == 0 ) { - tr_config->flags = SIEVE_TRFLG_DEBUG; + tr_config->flags |= SIEVE_TRFLG_DEBUG; } else if ( strcmp(tr_option, "addresses") == 0 ) { - tr_config->flags = SIEVE_TRFLG_ADDRESSES; + tr_config->flags |= SIEVE_TRFLG_ADDRESSES; } else { i_fatal_status(EX_USAGE, "Unknown -t trace option value: %s", tr_option); }