diff --git a/TODO b/TODO index f08f95e12977b470d3860d8083dfe60abb122624..0b54d5b213aa6b730b0cdae11297f471bcae62ee 100644 --- a/TODO +++ b/TODO @@ -1,14 +1,12 @@ Current activities: -* Improve debugging support in the sieve-test tool: - - Improve trace debugging towards something more intuitively readable. +* Cleanup the test suite + - Make uniform command implementations + - Cleanup test scripts Next (in order of descending priority/precedence): * Update man pages to match style of Dovecot man pages. -* Cleanup the test suite - - Make uniform command implementations - - Cleanup test scripts * Improve error handling and logging - Detect permission errors when writing global script binaries and advise the administrator on using sievec to precompile the scripts. diff --git a/src/lib-sieve/cmd-discard.c b/src/lib-sieve/cmd-discard.c index 69a6821a6577a6b7915b9dfe18d8f1bba720adb3..089cbc59f491812349a4fe1c9fa55e1c10cf8026 100644 --- a/src/lib-sieve/cmd-discard.c +++ b/src/lib-sieve/cmd-discard.c @@ -110,7 +110,8 @@ 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; cancel implicit keep"); + 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-redirect.c b/src/lib-sieve/cmd-redirect.c index 7f77b0fe9cb677943b22efa568d9e11d06dfe2cb..4d439b4a1e1dc4c93da8280f82955a5a72502c40 100644 --- a/src/lib-sieve/cmd-redirect.c +++ b/src/lib-sieve/cmd-redirect.c @@ -219,9 +219,12 @@ 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; forward message to address `%s'", - str_sanitize(str_c(redirect), 64)); + if ( sieve_runtime_trace_active(renv, SIEVE_TRLVL_ACTIONS) ) { + sieve_runtime_trace(renv, 0, "redirect action"); + sieve_runtime_trace_descend(renv); + sieve_runtime_trace(renv, 0, "forward message to address `%s'", + str_sanitize(str_c(redirect), 80)); + } /* Add redirect action to the result */ diff --git a/src/lib-sieve/cmd-stop.c b/src/lib-sieve/cmd-stop.c index a28f9c2ca5e50ac780eaa7eedacaa6b880487363..41e158d4215deddb4d4ca5c7e8089c6a8562e7f7 100644 --- a/src/lib-sieve/cmd-stop.c +++ b/src/lib-sieve/cmd-stop.c @@ -77,7 +77,8 @@ 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 command; end all script execution"); sieve_interpreter_interrupt(renv->interp); diff --git a/src/lib-sieve/ext-envelope.c b/src/lib-sieve/ext-envelope.c index 7b7465abd51774c154d219c81188718a9a31a767..f50698ba5ae79dafdb0b595eecc14ecacc66bc13 100644 --- a/src/lib-sieve/ext-envelope.c +++ b/src/lib-sieve/ext-envelope.c @@ -328,6 +328,12 @@ static int sieve_envelope_address_list_next_item if ( (ret=sieve_stringlist_next_item(addrlist->env_parts, &envp_item)) <= 0 ) return ret; + + if ( _addrlist->strlist.trace ) { + sieve_runtime_trace(_addrlist->strlist.runenv, 0, + "getting `%s' part from message envelope", + str_sanitize(str_c(envp_item), 80)); + } if ( (epart=_envelope_part_find(str_c(envp_item))) != NULL ) { addrlist->value_index = 0; diff --git a/src/lib-sieve/ext-fileinto.c b/src/lib-sieve/ext-fileinto.c index 810889633afdfa4a316eb320e94b0bb5a275fbe1..da5607a7c9ef8a7026138622ba8a76d127bea3f6 100644 --- a/src/lib-sieve/ext-fileinto.c +++ b/src/lib-sieve/ext-fileinto.c @@ -178,8 +178,13 @@ static int ext_fileinto_operation_execute */ mailbox = str_sanitize(str_c(folder), 64); - sieve_runtime_trace(renv, SIEVE_TRLVL_ACTIONS, - "fileinto action; store message in mailbox `%s'", mailbox); + + if ( sieve_runtime_trace_active(renv, SIEVE_TRLVL_ACTIONS) ) { + sieve_runtime_trace(renv, 0, "fileinto action"); + sieve_runtime_trace_descend(renv); + sieve_runtime_trace(renv, 0, "store message in mailbox `%s'", + str_sanitize(mailbox, 80)); + } /* 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 a872a3f450cedd38c978b7b07e6eec7361b3fb1d..5ca7ed783a9fcac865b5667446eda42a6720f9b0 100644 --- a/src/lib-sieve/ext-reject.c +++ b/src/lib-sieve/ext-reject.c @@ -290,12 +290,16 @@ static int ext_reject_operation_execute * Perform operation */ - if ( sieve_operation_is(oprtn, ereject_operation) ) - sieve_runtime_trace(renv, SIEVE_TRLVL_ACTIONS, - "ereject action; reject message with reason `%s'", str_sanitize(str_c(reason), 64)); - else - sieve_runtime_trace(renv, SIEVE_TRLVL_ACTIONS, - "reject action; reject message with reason `%s'", str_sanitize(str_c(reason), 64)); + if ( sieve_runtime_trace_active(renv, SIEVE_TRLVL_ACTIONS) ) { + if ( sieve_operation_is(oprtn, ereject_operation) ) + sieve_runtime_trace(renv, 0, "ereject action"); + else + sieve_runtime_trace(renv, 0, "reject action"); + + sieve_runtime_trace_descend(renv); + sieve_runtime_trace(renv, 0, "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/plugins/enotify/cmd-notify.c b/src/lib-sieve/plugins/enotify/cmd-notify.c index 6be5703ca844f6ca61ffb1583c654b7429449ebd..69a4f0530627c26b6a1769cebf018019800b9668 100644 --- a/src/lib-sieve/plugins/enotify/cmd-notify.c +++ b/src/lib-sieve/plugins/enotify/cmd-notify.c @@ -2,6 +2,7 @@ */ #include "lib.h" +#include "str-sanitize.h" #include "sieve-common.h" #include "sieve-error.h" @@ -465,7 +466,12 @@ static int cmd_notify_operation_execute /* Trace */ - sieve_runtime_trace(renv, SIEVE_TRLVL_ACTIONS, "notify action"); + if ( sieve_runtime_trace_active(renv, SIEVE_TRLVL_ACTIONS) ) { + sieve_runtime_trace(renv, 0, "notify action"); + sieve_runtime_trace_descend(renv); + sieve_runtime_trace(renv, 0, "notify with uri `%s'", + str_sanitize(str_c(method_uri), 80)); + } /* Check operands */ diff --git a/src/lib-sieve/plugins/imap4flags/cmd-flag.c b/src/lib-sieve/plugins/imap4flags/cmd-flag.c index 0fbde66ce7599238afb79e620904ed6ba1bebb5e..71471d352f708fee0695010f27dfe1569eab9508 100644 --- a/src/lib-sieve/plugins/imap4flags/cmd-flag.c +++ b/src/lib-sieve/plugins/imap4flags/cmd-flag.c @@ -177,12 +177,10 @@ static int cmd_flag_operation_execute { const struct sieve_operation *op = renv->oprtn; struct sieve_operand operand; - string_t *flag_item; struct sieve_stringlist *flag_list; struct sieve_variable_storage *storage; unsigned int var_index; ext_imapflag_flag_operation_t flag_op; - int ret; /* * Read operands @@ -241,7 +239,8 @@ static int cmd_flag_operation_execute i_unreached(); } + sieve_runtime_trace_descend(renv); + /* Perform requested operation */ - return flag_op(renv, storage, var_index, flag_list); } diff --git a/src/lib-sieve/plugins/imap4flags/ext-imap4flags-common.c b/src/lib-sieve/plugins/imap4flags/ext-imap4flags-common.c index 3c42ebe6d1f3054634a237b036274c3befd8e605..51ba9602defe2dd7a33c7c05ecacfac2311f2b35 100644 --- a/src/lib-sieve/plugins/imap4flags/ext-imap4flags-common.c +++ b/src/lib-sieve/plugins/imap4flags/ext-imap4flags-common.c @@ -463,84 +463,109 @@ static void flags_list_clear_flags str_truncate(flags_list, 0); } -int ext_imap4flags_set_flags +static string_t *ext_imap4flags_get_flag_variable (const struct sieve_runtime_env *renv, struct sieve_variable_storage *storage, - unsigned int var_index, struct sieve_stringlist *flags) + unsigned int var_index) { - string_t *cur_flags; + string_t *flags; if ( storage != NULL ) { - if ( !sieve_variable_get_modifiable(storage, var_index, &cur_flags) ) - return SIEVE_EXEC_BIN_CORRUPT; + if ( sieve_runtime_trace_active(renv, SIEVE_TRLVL_COMMANDS) ) { + const char *var_name, *var_id; + + (void)sieve_variable_get_identifier(storage, var_index, &var_name); + var_id = sieve_variable_get_varid(storage, var_index); + + sieve_runtime_trace(renv, 0, "update variable `%s' [%s]", + var_name, var_id); + } + + if ( !sieve_variable_get_modifiable(storage, var_index, &flags) ) + return NULL; } else { - cur_flags = _get_flags_string(renv->oprtn->ext, renv->result); + flags = _get_flags_string(renv->oprtn->ext, renv->result); } - + + return flags; +} + +int ext_imap4flags_set_flags +(const struct sieve_runtime_env *renv, struct sieve_variable_storage *storage, + unsigned int var_index, struct sieve_stringlist *flags) +{ + string_t *cur_flags = ext_imap4flags_get_flag_variable + (renv, storage, var_index); + if ( cur_flags != NULL ) { string_t *flags_item; int ret; flags_list_clear_flags(cur_flags); while ( (ret=sieve_stringlist_next_item(flags, &flags_item)) > 0 ) { + sieve_runtime_trace(renv, SIEVE_TRLVL_COMMANDS, + "set flags `%s'", str_c(flags_item)); + flags_list_add_flags(cur_flags, flags_item); } if ( ret < 0 ) return SIEVE_EXEC_BIN_CORRUPT; + + return SIEVE_EXEC_OK; } - return SIEVE_EXEC_OK; + return SIEVE_EXEC_BIN_CORRUPT; } int ext_imap4flags_add_flags (const struct sieve_runtime_env *renv, struct sieve_variable_storage *storage, unsigned int var_index, struct sieve_stringlist *flags) { - string_t *cur_flags; - - if ( storage != NULL ) { - if ( !sieve_variable_get_modifiable(storage, var_index, &cur_flags) ) - return SIEVE_EXEC_BIN_CORRUPT; - } else - cur_flags = _get_flags_string(renv->oprtn->ext, renv->result); - + string_t *cur_flags = ext_imap4flags_get_flag_variable + (renv, storage, var_index); + if ( cur_flags != NULL ) { string_t *flags_item; int ret; while ( (ret=sieve_stringlist_next_item(flags, &flags_item)) > 0 ) { + sieve_runtime_trace(renv, SIEVE_TRLVL_COMMANDS, + "add flags `%s'", str_c(flags_item)); + flags_list_add_flags(cur_flags, flags_item); } if ( ret < 0 ) return SIEVE_EXEC_BIN_CORRUPT; + + return SIEVE_EXEC_OK; } - return SIEVE_EXEC_OK; + return SIEVE_EXEC_BIN_CORRUPT; } int ext_imap4flags_remove_flags (const struct sieve_runtime_env *renv, struct sieve_variable_storage *storage, unsigned int var_index, struct sieve_stringlist *flags) { - string_t *cur_flags; - - if ( storage != NULL ) { - if ( !sieve_variable_get_modifiable(storage, var_index, &cur_flags) ) - return SIEVE_EXEC_BIN_CORRUPT; - } else - cur_flags = _get_flags_string(renv->oprtn->ext, renv->result); - + string_t *cur_flags = ext_imap4flags_get_flag_variable + (renv, storage, var_index); + if ( cur_flags != NULL ) { string_t *flags_item; int ret; while ( (ret=sieve_stringlist_next_item(flags, &flags_item)) > 0 ) { + sieve_runtime_trace(renv, SIEVE_TRLVL_COMMANDS, + "remove flags `%s'", str_c(flags_item)); + flags_list_remove_flags(cur_flags, flags_item); } if ( ret < 0 ) return SIEVE_EXEC_BIN_CORRUPT; + + return SIEVE_EXEC_OK; } - return SIEVE_EXEC_OK; + return SIEVE_EXEC_BIN_CORRUPT; } /* Flag stringlist */ diff --git a/src/lib-sieve/plugins/mailbox/tst-mailboxexists.c b/src/lib-sieve/plugins/mailbox/tst-mailboxexists.c index aead5b0d5fb5b776f4efb8daff9f60ddd6ffd0cf..972e987d7c5159b9542d659ba74b17dfbbbb3349 100644 --- a/src/lib-sieve/plugins/mailbox/tst-mailboxexists.c +++ b/src/lib-sieve/plugins/mailbox/tst-mailboxexists.c @@ -2,6 +2,7 @@ */ #include "lib.h" +#include "str-sanitize.h" #include "mail-storage.h" #include "mail-namespace.h" @@ -108,6 +109,7 @@ static int tst_mailboxexists_operation_execute { struct sieve_stringlist *mailbox_names; string_t *mailbox_item; + bool trace = FALSE; bool all_exist = TRUE; /* @@ -123,7 +125,12 @@ static int tst_mailboxexists_operation_execute * Perform operation */ - sieve_runtime_trace(renv, SIEVE_TRLVL_TESTS, "mailboxexists test"); + if ( sieve_runtime_trace_active(renv, SIEVE_TRLVL_TESTS) ) { + sieve_runtime_trace(renv, 0, "mailboxexists test"); + sieve_runtime_trace_descend(renv); + + trace = sieve_runtime_trace_active(renv, SIEVE_TRLVL_MATCHING); + } if ( renv->scriptenv->user != NULL ) { int ret; @@ -138,6 +145,11 @@ static int tst_mailboxexists_operation_execute /* Find the namespace */ ns = mail_namespace_find(renv->scriptenv->user->namespaces, &mailbox); if ( ns == NULL) { + if ( trace ) { + sieve_runtime_trace(renv, 0, "mailbox `%s' not found", + str_sanitize(mailbox, 80)); + } + all_exist = FALSE; break; } @@ -145,17 +157,35 @@ static int tst_mailboxexists_operation_execute /* Open the box */ box = mailbox_alloc(ns->list, mailbox, 0); if ( mailbox_open(box) < 0 ) { + if ( trace ) { + sieve_runtime_trace(renv, 0, "mailbox `%s' cannot be opened", + str_sanitize(mailbox, 80)); + } + all_exist = FALSE; mailbox_free(&box); break; } /* Also fail when it is readonly */ - if ( mailbox_is_readonly(box) ) + if ( mailbox_is_readonly(box) ) { + if ( trace ) { + sieve_runtime_trace(renv, 0, "mailbox `%s' is read-only", + str_sanitize(mailbox, 80)); + } + all_exist = FALSE; + mailbox_free(&box); + break; + } /* FIXME: check acl for 'p' or 'i' ACL permissions as required by RFC */ + if ( trace ) { + sieve_runtime_trace(renv, 0, "mailbox `%s' exists", + str_sanitize(mailbox, 80)); + } + /* Close mailbox */ mailbox_free(&box); } @@ -165,6 +195,13 @@ static int tst_mailboxexists_operation_execute return SIEVE_EXEC_BIN_CORRUPT; } } + + if ( trace ) { + if ( all_exist ) + sieve_runtime_trace(renv, 0, "all mailboxes are available"); + else + sieve_runtime_trace(renv, 0, "some mailboxes are unavailable"); + } sieve_interpreter_set_test_result(renv->interp, all_exist); return SIEVE_EXEC_OK; diff --git a/src/lib-sieve/plugins/regex/mcht-regex.c b/src/lib-sieve/plugins/regex/mcht-regex.c index 793edcbf3309d4518793cb6d43d454c936bf7e42..7a6b28df0b8693fbd7b82bdc4c509568f6883b37 100644 --- a/src/lib-sieve/plugins/regex/mcht-regex.c +++ b/src/lib-sieve/plugins/regex/mcht-regex.c @@ -320,7 +320,7 @@ static int mcht_regex_match_keys if ( trace ) { sieve_runtime_trace(renv, 0, - " with regex `%s' [id=%d] => %d", + "with regex `%s' [id=%d] => %d", str_sanitize(str_c(key_item), 80), array_count(&ctx->reg_expressions)-1, result); } @@ -347,7 +347,7 @@ static int mcht_regex_match_keys if ( trace ) { sieve_runtime_trace(renv, 0, - " with compiled regex [id=%d] => %d", i, result); + "with compiled regex [id=%d] => %d", i, result); } } diff --git a/src/lib-sieve/plugins/relational/mcht-count.c b/src/lib-sieve/plugins/relational/mcht-count.c index 9ec75274b9b802054e1b9b3261feae62b7019ce4..98b417319c76f54b577737d08681a4eb41e626e0 100644 --- a/src/lib-sieve/plugins/relational/mcht-count.c +++ b/src/lib-sieve/plugins/relational/mcht-count.c @@ -83,9 +83,11 @@ static int mcht_count_match if ( trace ) { sieve_runtime_trace(renv, 0, - " matching count value `%s'", str_sanitize(str_c(value), 80)); + "matching count value `%s'", str_sanitize(str_c(value), 80)); } + sieve_runtime_trace_descend(renv); + /* Match to all key values */ key_item = NULL; ret = 0; @@ -97,10 +99,12 @@ static int mcht_count_match if ( trace ) { sieve_runtime_trace(renv, 0, - " with key `%s' => %d", str_sanitize(str_c(key_item), 80), ret); + "with key `%s' => %d", str_sanitize(str_c(key_item), 80), ret); } } + sieve_runtime_trace_ascend(renv); + return ret; } diff --git a/src/lib-sieve/plugins/vacation/cmd-vacation.c b/src/lib-sieve/plugins/vacation/cmd-vacation.c index 01aaab83677ff5bca655cba0a8ee8e9f51a90173..ec2d452f8ffdb77a58ebcf8cd4a77630a2bfe6f2 100644 --- a/src/lib-sieve/plugins/vacation/cmd-vacation.c +++ b/src/lib-sieve/plugins/vacation/cmd-vacation.c @@ -608,8 +608,13 @@ static int ext_vacation_operation_execute days = 1; /* Trace */ - - sieve_runtime_trace(renv, SIEVE_TRLVL_ACTIONS, "vacation action"); + + if ( sieve_runtime_trace_active(renv, SIEVE_TRLVL_ACTIONS) ) { + sieve_runtime_trace(renv, 0, "vacation action"); + sieve_runtime_trace_descend(renv); + sieve_runtime_trace(renv, 0, "auto-reply with message `%s'", + str_sanitize(str_c(reason), 80)); + } /* Check and normalize :from address */ if ( from != NULL ) { diff --git a/src/lib-sieve/plugins/variables/cmd-set.c b/src/lib-sieve/plugins/variables/cmd-set.c index 1f1e515643d4eb5dba9a68ccd27ce116f5fa13a1..aafcb523e134436502cae8621c3ae379205c59cb 100644 --- a/src/lib-sieve/plugins/variables/cmd-set.c +++ b/src/lib-sieve/plugins/variables/cmd-set.c @@ -307,7 +307,8 @@ static int cmd_set_operation_execute * Determine and assign the value */ - sieve_runtime_trace(renv, SIEVE_TRLVL_COMMANDS, "set:"); + sieve_runtime_trace(renv, SIEVE_TRLVL_COMMANDS, "set command"); + sieve_runtime_trace_descend(renv); /* Hold value within limits */ if ( str_len(value) > EXT_VARIABLES_MAX_VARIABLE_SIZE ) @@ -334,7 +335,7 @@ static int cmd_set_operation_execute } sieve_runtime_trace_here - (renv, SIEVE_TRLVL_COMMANDS, " :%s \"%s\" => \"%s\"", + (renv, SIEVE_TRLVL_COMMANDS, "modify :%s \"%s\" => \"%s\"", sieve_variables_modifier_name(&modf), str_c(value), str_c(new_value)); value = new_value; @@ -359,7 +360,7 @@ static int cmd_set_operation_execute (void)sieve_variable_get_identifier(storage, var_index, &var_name); var_id = sieve_variable_get_varid(storage, var_index); - sieve_runtime_trace_here(renv, 0, " %s [%s] = \"%s\"", + sieve_runtime_trace_here(renv, 0, "assign `%s' [%s] = \"%s\"", var_name, var_id, str_c(value)); } } diff --git a/src/lib-sieve/sieve-address-parts.c b/src/lib-sieve/sieve-address-parts.c index 540faf4ffa10d5d5bb0ab2340a024e3f66e7425c..5971dbf76b2fc663d2ae024f36b80960bef2057d 100644 --- a/src/lib-sieve/sieve-address-parts.c +++ b/src/lib-sieve/sieve-address-parts.c @@ -236,6 +236,8 @@ static void sieve_address_part_stringlist_reset (struct sieve_stringlist *_strlist); static int sieve_address_part_stringlist_get_length (struct sieve_stringlist *_strlist); +static void sieve_address_part_stringlist_set_trace +(struct sieve_stringlist *_strlist, bool trace); struct sieve_address_part_stringlist { struct sieve_stringlist strlist; @@ -255,6 +257,7 @@ struct sieve_stringlist *sieve_address_part_stringlist_create strlist->strlist.next_item = sieve_address_part_stringlist_next_item; strlist->strlist.reset = sieve_address_part_stringlist_reset; strlist->strlist.get_length = sieve_address_part_stringlist_get_length; + strlist->strlist.set_trace = sieve_address_part_stringlist_set_trace; strlist->addrp = addrp; strlist->addresses = addresses; @@ -280,6 +283,13 @@ static int sieve_address_part_stringlist_next_item if ( item.local_part == NULL ) { if ( item_unparsed != NULL ) { + if ( _strlist->trace ) { + sieve_runtime_trace(_strlist->runenv, 0, + "extracting `%s' part from non-address value `%s'", + sieve_address_part_name(strlist->addrp), + str_sanitize(str_c(item_unparsed), 80)); + } + if ( str_len(item_unparsed) == 0 || sieve_address_part_is(strlist->addrp, all_address_part) ) *str_r = item_unparsed; @@ -288,6 +298,13 @@ static int sieve_address_part_stringlist_next_item const struct sieve_address_part *addrp = strlist->addrp; const char *part = NULL; + if ( _strlist->trace ) { + sieve_runtime_trace(_strlist->runenv, 0, + "extracting `%s' part from address `%s'", + sieve_address_part_name(strlist->addrp), + str_sanitize(sieve_address_to_string(&item), 80)); + } + if ( addrp->def != NULL && addrp->def->extract_from ) part = addrp->def->extract_from(addrp, &item); @@ -317,6 +334,15 @@ static int sieve_address_part_stringlist_get_length return sieve_address_list_get_length(strlist->addresses); } +static void sieve_address_part_stringlist_set_trace +(struct sieve_stringlist *_strlist, bool trace) +{ + struct sieve_address_part_stringlist *strlist = + (struct sieve_address_part_stringlist *)_strlist; + + sieve_address_list_set_trace(strlist->addresses, trace); +} + /* * Default ADDRESS-PART, MATCH-TYPE, COMPARATOR access */ diff --git a/src/lib-sieve/sieve-address-parts.h b/src/lib-sieve/sieve-address-parts.h index c72bb1a81778f8ff704d6ca168633510062c015d..8c8797e01d379339d746b57a20a3907b0b08a052 100644 --- a/src/lib-sieve/sieve-address-parts.h +++ b/src/lib-sieve/sieve-address-parts.h @@ -35,6 +35,8 @@ struct sieve_address_part { #define SIEVE_ADDRESS_PART_DEFAULT(definition) \ { SIEVE_OBJECT_DEFAULT(definition), &(definition) }; +#define sieve_address_part_name(addrp) \ + ( (addrp)->object.def->identifier ) #define sieve_address_part_is(addrp, definition) \ ( (addrp)->def == &(definition) ) diff --git a/src/lib-sieve/sieve-address.c b/src/lib-sieve/sieve-address.c index ca7b70d59b96bd952467260c5b43f34903fefdbf..e89b40a5e824eb27c527a2e1ae85d20992043616 100644 --- a/src/lib-sieve/sieve-address.c +++ b/src/lib-sieve/sieve-address.c @@ -8,6 +8,7 @@ #include "message-address.h" #include "sieve-common.h" +#include "sieve-runtime-trace.h" #include "sieve-address.h" @@ -26,6 +27,8 @@ static int sieve_header_address_list_next_item string_t **unparsed_r); static void sieve_header_address_list_reset (struct sieve_stringlist *_strlist); +static void sieve_header_address_list_set_trace + (struct sieve_stringlist *_strlist, bool trace); /* Stringlist object */ @@ -46,6 +49,7 @@ struct sieve_address_list *sieve_header_address_list_create addrlist->addrlist.strlist.next_item = sieve_header_address_list_next_string_item; addrlist->addrlist.strlist.reset = sieve_header_address_list_reset; + addrlist->addrlist.strlist.set_trace = sieve_header_address_list_set_trace; addrlist->addrlist.next_item = sieve_header_address_list_next_item; addrlist->field_values = field_values; @@ -74,6 +78,12 @@ static int sieve_header_address_list_next_item <= 0 ) return ret; + if ( _addrlist->strlist.trace ) { + sieve_runtime_trace(_addrlist->strlist.runenv, 0, + "parsing address header value `%s'", + str_sanitize(str_c(value_item), 80)); + } + addrlist->cur_address = message_address_parse (pool_datastack_create(), (const unsigned char *) str_data(value_item), str_len(value_item), 256, FALSE); @@ -149,6 +159,15 @@ static void sieve_header_address_list_reset addrlist->cur_address = NULL; } +static void sieve_header_address_list_set_trace +(struct sieve_stringlist *_strlist, bool trace) +{ + struct sieve_header_address_list *addrlist = + (struct sieve_header_address_list *)_strlist; + + sieve_stringlist_set_trace(addrlist->field_values, trace); +} + /* * RFC 2822 addresses */ diff --git a/src/lib-sieve/sieve-address.h b/src/lib-sieve/sieve-address.h index 9ae4c2cc94a523ab45e86f3838c6538660768bc4..95bc2308a0abd132fe82418b0c0134bb2ccab9cd 100644 --- a/src/lib-sieve/sieve-address.h +++ b/src/lib-sieve/sieve-address.h @@ -22,10 +22,12 @@ struct sieve_address { static inline const char *sieve_address_to_string (const struct sieve_address *address) { - if ( address == NULL || address->local_part == NULL || - address->domain == NULL ) + if ( address == NULL || address->local_part == NULL ) return NULL; + if ( address->domain == NULL ) + return address->local_part; + return t_strconcat(address->local_part, "@", address->domain, NULL); } @@ -60,6 +62,12 @@ static inline int sieve_address_list_get_length return sieve_stringlist_get_length(&addrlist->strlist); } +static inline void sieve_address_list_set_trace +(struct sieve_address_list *addrlist, bool trace) +{ + return sieve_stringlist_set_trace(&addrlist->strlist, trace); +} + /* * Header address list */ diff --git a/src/lib-sieve/sieve-code.c b/src/lib-sieve/sieve-code.c index fb81d13ec0955d04988d83db0b42d21831bcd64c..d64f77d4b98a7ebf1d914c39cb9f2b4b240181ca 100644 --- a/src/lib-sieve/sieve-code.c +++ b/src/lib-sieve/sieve-code.c @@ -1047,6 +1047,7 @@ static int opc_jmptrue_execute bool result = sieve_interpreter_get_test_result(renv->interp); sieve_runtime_trace(renv, SIEVE_TRLVL_COMMANDS, "jump if result is true"); + sieve_runtime_trace_descend(renv); return sieve_interpreter_program_jump(renv->interp, result); } @@ -1057,6 +1058,7 @@ static int opc_jmpfalse_execute bool result = sieve_interpreter_get_test_result(renv->interp); sieve_runtime_trace(renv, SIEVE_TRLVL_COMMANDS, "jump if result is false"); - + sieve_runtime_trace_descend(renv); + return sieve_interpreter_program_jump(renv->interp, !result); } diff --git a/src/lib-sieve/sieve-common.h b/src/lib-sieve/sieve-common.h index 260d461103869d417ecbbaaea11ed1676dbd56c8..dab8d5d77263feb7bdbae7919cde811d677d91dd 100644 --- a/src/lib-sieve/sieve-common.h +++ b/src/lib-sieve/sieve-common.h @@ -64,8 +64,10 @@ struct sieve_jumplist; struct sieve_generator; struct sieve_codegen_env; -/* sieve-interpreter.h */ +/* sieve-runtime.h */ struct sieve_runtime_env; + +/* sieve-interpreter.h */ struct sieve_interpreter; /* sieve-dump.h */ diff --git a/src/lib-sieve/sieve-interpreter.c b/src/lib-sieve/sieve-interpreter.c index 6f7c4ff16bb795c3fd9e2b01795df951b83eb8b7..4a0e9a1162b2ffc60f3eaa9fa0c22266154e26e4 100644 --- a/src/lib-sieve/sieve-interpreter.c +++ b/src/lib-sieve/sieve-interpreter.c @@ -20,6 +20,7 @@ #include "sieve-binary.h" #include "sieve-result.h" #include "sieve-comparators.h" +#include "sieve-runtime-trace.h" #include "sieve-interpreter.h" @@ -58,6 +59,7 @@ struct sieve_interpreter { /* Runtime environment */ struct sieve_runtime_env runenv; + struct sieve_runtime_trace trace; /* Current operation */ struct sieve_operation oprtn; @@ -99,8 +101,13 @@ static struct sieve_interpreter *_sieve_interpreter_create interp->runenv.svinst = svinst; interp->runenv.msgdata = msgdata; interp->runenv.scriptenv = senv; - interp->runenv.trace_stream = senv->trace_stream; - interp->runenv.trace_config = senv->trace_config; + + if ( senv->trace_stream != NULL ) { + interp->trace.stream = senv->trace_stream; + interp->trace.config = senv->trace_config; + interp->trace.indent = 0; + interp->runenv.trace = &interp->trace; + } if ( senv->exec_status == NULL ) interp->runenv.exec_status = p_new(interp->pool, struct sieve_exec_status, 1); @@ -431,7 +438,7 @@ int sieve_interpreter_program_jump unsigned int jmp_line = sieve_runtime_get_source_location(renv, jmp_addr); - if ( (renv->trace_config.flags & SIEVE_TRFLG_ADDRESSES) > 0 ) { + if ( sieve_runtime_trace_hasflag(renv, SIEVE_TRFLG_ADDRESSES) ) { sieve_runtime_trace(renv, 0, "jumping to line %d [%08llx]", jmp_line, (long long unsigned int) jmp_addr); } else { @@ -477,6 +484,8 @@ static int sieve_interpreter_operation_execute struct sieve_operation *oprtn = &(interp->oprtn); sieve_size_t *address = &(interp->runenv.pc); + sieve_runtime_trace_toplevel(&interp->runenv); + /* Read the operation */ if ( sieve_operation_read(interp->runenv.sblock, address, oprtn) ) { const struct sieve_operation_def *op = oprtn->def; diff --git a/src/lib-sieve/sieve-match.c b/src/lib-sieve/sieve-match.c index b0b2acda23ce5b74334d97447c6edac21030be8c..19c0a2e36739fce0f6a9b5d6c5dcf954e3045b4e 100644 --- a/src/lib-sieve/sieve-match.c +++ b/src/lib-sieve/sieve-match.c @@ -50,8 +50,9 @@ struct sieve_match_context *sieve_match_begin /* Trace */ if ( mctx->trace ) { + sieve_runtime_trace_descend(renv); sieve_runtime_trace(renv, 0, - " starting `:%s' match with `%s' comparator:", + "starting `:%s' match with `%s' comparator:", sieve_match_type_name(mcht), sieve_comparator_name(cmp)); } @@ -73,13 +74,18 @@ int sieve_match_value if ( mctx->trace ) { sieve_runtime_trace(renv, 0, - " matching value `%s'", str_sanitize(value, 80)); + "matching value `%s'", str_sanitize(value, 80)); } /* Match to key values */ sieve_stringlist_reset(key_list); + if ( mctx->trace ) + sieve_stringlist_set_trace(key_list, TRUE); + + sieve_runtime_trace_descend(renv); + if ( mcht->def->match_keys != NULL ) { /* Call match-type's own key match handler */ result = mcht->def->match_keys(mctx, value, value_size, key_list); @@ -96,7 +102,7 @@ int sieve_match_value if ( mctx->trace ) { sieve_runtime_trace(renv, 0, - " with key `%s' => %d", str_sanitize(str_c(key_item), 80), + "with key `%s' => %d", str_sanitize(str_c(key_item), 80), result); } } T_END; @@ -105,6 +111,8 @@ int sieve_match_value if ( ret < 0 ) result = -1; } + sieve_runtime_trace_ascend(renv); + if ( mctx->status < 0 || result < 0 ) mctx->status = -1; else @@ -124,8 +132,9 @@ int sieve_match_end(struct sieve_match_context **mctx) pool_unref(&(*mctx)->pool); sieve_runtime_trace(renv, SIEVE_TRLVL_MATCHING, - " finishing match with result: %s", + "finishing match with result: %s", ( result > 0 ? "matched" : ( result < 0 ? "error" : "not matched" ) )); + sieve_runtime_trace_ascend(renv); return result; } @@ -148,9 +157,12 @@ int sieve_match sieve_stringlist_reset(value_list); + if ( mctx->trace ) + sieve_stringlist_set_trace(value_list, TRUE); + if ( mcht->def->match != NULL ) { /* Call match-type's match handler */ - result = mcht->def->match(mctx, value_list, key_list); + result = mctx->status = mcht->def->match(mctx, value_list, key_list); } else { /* Default value match loop */ diff --git a/src/lib-sieve/sieve-message.c b/src/lib-sieve/sieve-message.c index a5f890c73885b44c365c8525d2e1100466d8e818..30b7472695e99ba3724febdba5d4a0d368c195ad 100644 --- a/src/lib-sieve/sieve-message.c +++ b/src/lib-sieve/sieve-message.c @@ -6,6 +6,7 @@ #include "mempool.h" #include "array.h" #include "str.h" +#include "str-sanitize.h" #include "mail-storage.h" #include "sieve-common.h" @@ -13,6 +14,7 @@ #include "sieve-error.h" #include "sieve-extensions.h" #include "sieve-runtime.h" +#include "sieve-runtime-trace.h" #include "sieve-address.h" #include "sieve-message.h" @@ -275,6 +277,12 @@ static int sieve_message_header_stringlist_next_item <= 0 ) return ret; + if ( _strlist->trace ) { + sieve_runtime_trace(renv, 0, + "extracting `%s' headers from message", + str_sanitize(str_c(hdr_item), 80)); + } + /* Fetch all matching headers from the e-mail */ if ( mail_get_headers_utf8(mail, str_c(hdr_item), &strlist->headers) < 0 || ( strlist->headers != NULL && strlist->headers[0] == NULL ) ) { diff --git a/src/lib-sieve/sieve-runtime-trace.c b/src/lib-sieve/sieve-runtime-trace.c index 7a29b8445b88c723a1c5cb9d8ad4f397cfe49a89..07e7a4746900b25167dc70a9cea9ff163a6398e1 100644 --- a/src/lib-sieve/sieve-runtime-trace.c +++ b/src/lib-sieve/sieve-runtime-trace.c @@ -14,15 +14,19 @@ static inline string_t *_trace_line_new (const struct sieve_runtime_env *renv, sieve_size_t address, unsigned int cmd_line) { string_t *trline; + unsigned int i; trline = t_str_new(128); - if ( (renv->trace_config.flags & SIEVE_TRFLG_ADDRESSES) > 0 ) + 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 str_append(trline, " "); + for ( i = 0; i < renv->trace->indent; i++ ) + str_append(trline, " "); + return trline; } @@ -31,13 +35,13 @@ static inline void _trace_line_print { str_append_c(trline, '\n'); - o_stream_send(renv->trace_stream, str_data(trline), str_len(trline)); + o_stream_send(renv->trace->stream, str_data(trline), str_len(trline)); } static inline void _trace_line_print_empty (const struct sieve_runtime_env *renv) { - o_stream_send_str(renv->trace_stream, "\n"); + o_stream_send_str(renv->trace->stream, "\n"); } /* @@ -59,8 +63,8 @@ void _sieve_runtime_trace_operand_error (const struct sieve_runtime_env *renv, const struct sieve_operand *oprnd, const char *field_name, const char *fmt, va_list args) { - string_t *trline = _trace_line_new - (renv, oprnd->address, sieve_runtime_get_source_location(renv, oprnd->address)); + string_t *trline = _trace_line_new(renv, oprnd->address, + sieve_runtime_get_source_location(renv, oprnd->address)); str_printfa(trline, "%s: #ERROR#: ", sieve_operation_mnemonic(renv->oprtn)); diff --git a/src/lib-sieve/sieve-runtime-trace.h b/src/lib-sieve/sieve-runtime-trace.h index 00c4a2c47eac629eca8d37d501e1d157f77d55a0..a22088eff0396ccafc805425269d03f65f91bd11 100644 --- a/src/lib-sieve/sieve-runtime-trace.h +++ b/src/lib-sieve/sieve-runtime-trace.h @@ -8,13 +8,44 @@ * Runtime trace */ +struct sieve_runtime_trace { + struct sieve_trace_config config; + struct ostream *stream; + unsigned int indent; +}; + /* Trace configuration */ static inline bool sieve_runtime_trace_active (const struct sieve_runtime_env *renv, sieve_trace_level_t trace_level) { - return ( renv->trace_stream != NULL && - trace_level <= renv->trace_config.level ); + return ( renv->trace != NULL && trace_level <= renv->trace->config.level ); +} + +static inline bool sieve_runtime_trace_hasflag +(const struct sieve_runtime_env *renv, unsigned int flag) +{ + return ( renv->trace != NULL && (renv->trace->config.flags & flag) != 0 ); +} + +/* Trace indent */ + +static inline void sieve_runtime_trace_descend +(const struct sieve_runtime_env *renv) +{ + if ( renv->trace != NULL ) renv->trace->indent++; +} + +static inline void sieve_runtime_trace_ascend +(const struct sieve_runtime_env *renv) +{ + if ( renv->trace != NULL ) renv->trace->indent--; +} + +static inline void sieve_runtime_trace_toplevel +(const struct sieve_runtime_env *renv) +{ + if ( renv->trace != NULL ) renv->trace->indent = 0; } /* Trace errors */ @@ -40,8 +71,7 @@ static inline void sieve_runtime_trace_error va_list args; va_start(args, fmt); - if ( renv->trace_stream != NULL && - renv->trace_config.level > SIEVE_TRLVL_NONE ) + if ( renv->trace != NULL ) _sieve_runtime_trace_error(renv, fmt, args); va_end(args); } @@ -53,8 +83,7 @@ static inline void sieve_runtime_trace_operand_error va_list args; va_start(args, fmt); - if ( renv->trace_stream != NULL && - renv->trace_config.level > SIEVE_TRLVL_NONE ) + if ( renv->trace != NULL ) _sieve_runtime_trace_operand_error(renv, oprnd, field_name, fmt, args); va_end(args); } @@ -76,7 +105,7 @@ static inline void sieve_runtime_trace va_start(args, fmt); - if ( renv->trace_stream != NULL && trace_level <= renv->trace_config.level ) { + if ( renv->trace != NULL && trace_level <= renv->trace->config.level ) { _sieve_runtime_trace(renv, fmt, args); } @@ -99,7 +128,7 @@ static inline void sieve_runtime_trace_address va_start(args, fmt); - if ( renv->trace_stream != NULL && trace_level <= renv->trace_config.level ) { + if ( renv->trace != NULL && trace_level <= renv->trace->config.level ) { _sieve_runtime_trace_address(renv, address, fmt, args); } @@ -114,7 +143,7 @@ static inline void sieve_runtime_trace_here va_start(args, fmt); - if ( renv->trace_stream != NULL && trace_level <= renv->trace_config.level ) { + if ( renv->trace != NULL && trace_level <= renv->trace->config.level ) { _sieve_runtime_trace_address(renv, renv->pc, fmt, args); } @@ -130,21 +159,21 @@ void _sieve_runtime_trace_sep(const struct sieve_runtime_env *renv); static inline void sieve_runtime_trace_begin (const struct sieve_runtime_env *renv) { - if ( renv->trace_stream != NULL ) + if ( renv->trace != NULL ) _sieve_runtime_trace_begin(renv); } static inline void sieve_runtime_trace_end (const struct sieve_runtime_env *renv) { - if ( renv->trace_stream != NULL ) + if ( renv->trace != NULL ) _sieve_runtime_trace_end(renv); } static inline void sieve_runtime_trace_sep (const struct sieve_runtime_env *renv) { - if ( renv->trace_stream != NULL ) + if ( renv->trace != NULL ) _sieve_runtime_trace_sep(renv); } diff --git a/src/lib-sieve/sieve-runtime.h b/src/lib-sieve/sieve-runtime.h index 26659674ccec313b3b5717537b2cdcd0c2d5ff1d..15b4c1a6b5f5a458060cca5c6da94f99e0f10ed5 100644 --- a/src/lib-sieve/sieve-runtime.h +++ b/src/lib-sieve/sieve-runtime.h @@ -36,8 +36,7 @@ struct sieve_runtime_env { struct sieve_result *result; /* Runtime tracing */ - struct ostream *trace_stream; - struct sieve_trace_config trace_config; + struct sieve_runtime_trace *trace; }; #endif /* __SIEVE_RUNTIME_H */ diff --git a/src/lib-sieve/sieve-stringlist.h b/src/lib-sieve/sieve-stringlist.h index c9e1ebaced539ae457a627b3f51a9b00d7d6fa78..9729bdb0f7781f9dae8e6b1e4c956da9bcc122e8 100644 --- a/src/lib-sieve/sieve-stringlist.h +++ b/src/lib-sieve/sieve-stringlist.h @@ -6,8 +6,6 @@ */ struct sieve_stringlist { - const struct sieve_runtime_env *runenv; - int (*next_item) (struct sieve_stringlist *strlist, string_t **str_r); void (*reset) @@ -18,8 +16,23 @@ struct sieve_stringlist { bool (*read_all) (struct sieve_stringlist *strlist, pool_t pool, const char * const **list_r); + + void (*set_trace) + (struct sieve_stringlist *strlist, bool trace); + + const struct sieve_runtime_env *runenv; + unsigned int trace:1; }; +static inline void sieve_stringlist_set_trace +(struct sieve_stringlist *strlist, bool trace) +{ + strlist->trace = trace; + + if ( strlist->set_trace != NULL ) + strlist->set_trace(strlist, trace); +} + static inline int sieve_stringlist_next_item (struct sieve_stringlist *strlist, string_t **str_r) { diff --git a/src/lib-sieve/tst-exists.c b/src/lib-sieve/tst-exists.c index 6231f4c35ac60fd7355555665a85b871c51ad398..4aa6c55aaa10913f3257d6dd601646b50734977f 100644 --- a/src/lib-sieve/tst-exists.c +++ b/src/lib-sieve/tst-exists.c @@ -125,7 +125,8 @@ static int tst_exists_operation_execute */ sieve_runtime_trace(renv, SIEVE_TRLVL_TESTS, "exists test"); - + sieve_runtime_trace_descend(renv); + /* Iterate through all requested headers to match (must find all specified) */ hdr_item = NULL; matched = TRUE; @@ -140,9 +141,14 @@ static int tst_exists_operation_execute } sieve_runtime_trace(renv, SIEVE_TRLVL_MATCHING, - " header `%s' %s", str_sanitize(str_c(hdr_item), 80), - ( matched ? "exists" : "missing" )); + "header `%s' %s", str_sanitize(str_c(hdr_item), 80), + ( matched ? "exists" : "is missing" )); } + + if ( matched ) + sieve_runtime_trace(renv, SIEVE_TRLVL_MATCHING, "all headers exist"); + else + sieve_runtime_trace(renv, SIEVE_TRLVL_MATCHING, "headers are missing"); /* Set test result for subsequent conditional jump */ if ( ret >= 0 ) { diff --git a/src/lib-sieve/tst-size.c b/src/lib-sieve/tst-size.c index d5fd31a563b61cffd0b93ab6d82e7c10cff25756..d92430745e25c706a0971551d0c1e51aa3bc0242 100644 --- a/src/lib-sieve/tst-size.c +++ b/src/lib-sieve/tst-size.c @@ -269,11 +269,29 @@ static int tst_size_operation_execute /* Perform the test */ if ( sieve_operation_is(renv->oprtn, tst_size_over_operation) ) { sieve_runtime_trace(renv, SIEVE_TRLVL_TESTS, "size :over test"); + + if ( sieve_runtime_trace_active(renv, SIEVE_TRLVL_MATCHING) ) { + sieve_runtime_trace_descend(renv); + + sieve_runtime_trace(renv, 0, + "comparing message size %"PRIuSIZE_T, mail_size); + sieve_runtime_trace(renv, 0, + "with upper limit %"PRIuSIZE_T, limit); + } sieve_interpreter_set_test_result(renv->interp, (mail_size > limit)); } else { sieve_runtime_trace(renv, SIEVE_TRLVL_TESTS, "size :under test"); + if ( sieve_runtime_trace_active(renv, SIEVE_TRLVL_MATCHING) ) { + sieve_runtime_trace_descend(renv); + + sieve_runtime_trace(renv, 0, + "comparing message size %"PRIuSIZE_T, mail_size); + sieve_runtime_trace(renv, 0, + "with lower limit %"PRIuSIZE_T, limit); + } + sieve_interpreter_set_test_result(renv->interp, (mail_size < limit)); } diff --git a/src/testsuite/cmd-test-binary.c b/src/testsuite/cmd-test-binary.c index 6f9d48608ae7affd1a5e46317188d9eb756fa84e..a8aef73278275c241406c38f799ca419612bce92 100644 --- a/src/testsuite/cmd-test-binary.c +++ b/src/testsuite/cmd-test-binary.c @@ -239,8 +239,11 @@ static int cmd_test_binary_operation_execute if ( sieve_operation_is(oprtn, test_binary_load_operation) ) { struct sieve_binary *sbin = testsuite_binary_load(str_c(binary_name)); - sieve_runtime_trace(renv, SIEVE_TRLVL_COMMANDS, - "binary :load %s", str_c(binary_name)); + if ( sieve_runtime_trace_active(renv, SIEVE_TRLVL_COMMANDS) ) { + sieve_runtime_trace(renv, 0, "testsuite: test_binary command"); + sieve_runtime_trace_descend(renv); + sieve_runtime_trace(renv, 0, "load binary `%s'", str_c(binary_name)); + } if ( sbin != NULL ) { testsuite_script_set_binary(sbin); @@ -254,8 +257,11 @@ static int cmd_test_binary_operation_execute } else if ( sieve_operation_is(oprtn, test_binary_save_operation) ) { struct sieve_binary *sbin = testsuite_script_get_binary(); - sieve_runtime_trace(renv, SIEVE_TRLVL_COMMANDS, - "binary :save %s", str_c(binary_name)); + if ( sieve_runtime_trace_active(renv, SIEVE_TRLVL_COMMANDS) ) { + sieve_runtime_trace(renv, 0, "testsuite: test_binary command"); + sieve_runtime_trace_descend(renv); + sieve_runtime_trace(renv, 0, "save binary `%s'", str_c(binary_name)); + } if ( sbin != NULL ) testsuite_binary_save(sbin, str_c(binary_name)); diff --git a/src/testsuite/cmd-test-config.c b/src/testsuite/cmd-test-config.c index 5082bc9b94beb13cde0036c0add621988d14c923..91d2ca61e2a31f66e0999992feb5c1db4d16c93c 100644 --- a/src/testsuite/cmd-test-config.c +++ b/src/testsuite/cmd-test-config.c @@ -335,8 +335,13 @@ static int cmd_test_config_set_operation_execute * Perform operation */ - sieve_runtime_trace(renv, SIEVE_TRLVL_COMMANDS, - "test_config :set %s = `%s'", str_c(setting), str_c(value)); + if ( sieve_runtime_trace_active(renv, SIEVE_TRLVL_COMMANDS) ) { + sieve_runtime_trace(renv, 0, + "testsuite: test_config command"); + sieve_runtime_trace_descend(renv); + sieve_runtime_trace(renv, 0, "set config `%s' = `%s'", + str_c(setting), str_c(value)); + } testsuite_setting_set(str_c(setting), str_c(value)); @@ -360,8 +365,12 @@ static int cmd_test_config_unset_operation_execute * Perform operation */ - sieve_runtime_trace(renv, SIEVE_TRLVL_COMMANDS, - "test_config :unset `%s'", str_c(setting)); + if ( sieve_runtime_trace_active(renv, SIEVE_TRLVL_COMMANDS) ) { + sieve_runtime_trace(renv, 0, + "testsuite: test_config command"); + sieve_runtime_trace_descend(renv); + sieve_runtime_trace(renv, 0, "unset config `%s'", str_c(setting)); + } testsuite_setting_unset(str_c(setting)); @@ -385,9 +394,14 @@ static int cmd_test_config_reload_operation_execute /* * Perform operation */ - - sieve_runtime_trace(renv, SIEVE_TRLVL_COMMANDS, - "test_config :reload `%s'", str_c(extension)); + + if ( sieve_runtime_trace_active(renv, SIEVE_TRLVL_COMMANDS) ) { + sieve_runtime_trace(renv, 0, + "testsuite: test_config command"); + sieve_runtime_trace_descend(renv); + sieve_runtime_trace(renv, 0, "reload configuration for extension `%s'", + str_c(extension)); + } ext = sieve_extension_get_by_name(renv->svinst, str_c(extension)); if ( ext == NULL ) { diff --git a/src/testsuite/cmd-test-fail.c b/src/testsuite/cmd-test-fail.c index 2ee26f3a96b681e3c193a1fe34df44641c452e5c..238acc05315cab80989161f521e181a77ebc5630 100644 --- a/src/testsuite/cmd-test-fail.c +++ b/src/testsuite/cmd-test-fail.c @@ -135,7 +135,8 @@ static int cmd_test_fail_operation_execute if ( !sieve_opr_string_read(renv, address, "reason", &reason) ) return SIEVE_EXEC_BIN_CORRUPT; - sieve_runtime_trace(renv, SIEVE_TRLVL_COMMANDS, "TEST FAIL"); + sieve_runtime_trace(renv, SIEVE_TRLVL_COMMANDS, + "testsuite: test_fail command; FAIL current test"); testsuite_test_fail(reason); diff --git a/src/testsuite/cmd-test-mailbox.c b/src/testsuite/cmd-test-mailbox.c index ce6db518f0e960d8eb2f2889cc5188a05680e7ad..8ab5cc345855e627c14c0aba455dbe6ac5124409 100644 --- a/src/testsuite/cmd-test-mailbox.c +++ b/src/testsuite/cmd-test-mailbox.c @@ -238,8 +238,11 @@ static int cmd_test_mailbox_operation_execute */ if ( sieve_operation_is(oprtn, test_mailbox_create_operation) ) { - sieve_runtime_trace(renv, SIEVE_TRLVL_COMMANDS, - "test_mailbox :create `%s'", str_c(mailbox)); + if ( sieve_runtime_trace_active(renv, SIEVE_TRLVL_COMMANDS) ) { + sieve_runtime_trace(renv, 0, "testsuite/test_mailbox command"); + sieve_runtime_trace_descend(renv); + sieve_runtime_trace(renv, 0, "create mailbox `%s'", str_c(mailbox)); + } testsuite_mailstore_mailbox_create(renv, str_c(mailbox)); } diff --git a/src/testsuite/cmd-test-message.c b/src/testsuite/cmd-test-message.c index c4ea11c258a9960bf21d0257dacfa78dfad9396c..2623e4e35e0094d72aab7d6e5df8d49f738090fe 100644 --- a/src/testsuite/cmd-test-message.c +++ b/src/testsuite/cmd-test-message.c @@ -321,13 +321,24 @@ static int cmd_test_message_smtp_operation_execute /* * Perform operation */ - - if ( is_test ) - sieve_runtime_trace(renv, SIEVE_TRLVL_TESTS, - "test_message test [smtp index=%d]", msg_index); - else - sieve_runtime_trace(renv, SIEVE_TRLVL_COMMANDS, - "text_message command [smtp index=%d]", msg_index); + + if ( is_test ) { + if ( sieve_runtime_trace_active(renv, SIEVE_TRLVL_TESTS) ) { + sieve_runtime_trace(renv, 0, + "testsuite: test_message test"); + sieve_runtime_trace_descend(renv); + sieve_runtime_trace(renv, 0, + "check and retrieve smtp message [index=%d]", msg_index); + } + } else { + if ( sieve_runtime_trace_active(renv, SIEVE_TRLVL_COMMANDS) ) { + sieve_runtime_trace(renv, 0, + "testsuite: test_message command"); + sieve_runtime_trace_descend(renv); + sieve_runtime_trace(renv, 0, + "retrieve smtp message [index=%d]", msg_index); + } + } result = testsuite_smtp_get(renv, msg_index); @@ -371,13 +382,26 @@ static int cmd_test_message_mailbox_operation_execute /* * Perform operation */ - - if ( is_test ) - sieve_runtime_trace(renv, SIEVE_TRLVL_TESTS, - "test_message test [mailbox=`%s' index=%d]", str_c(folder), msg_index); - else - sieve_runtime_trace(renv, SIEVE_TRLVL_COMMANDS, - "test_message command [mailbox=`%s' index=%d]", str_c(folder), msg_index); + + if ( is_test ) { + if ( sieve_runtime_trace_active(renv, SIEVE_TRLVL_TESTS) ) { + sieve_runtime_trace(renv, 0, + "testsuite: test_message test"); + sieve_runtime_trace_descend(renv); + sieve_runtime_trace(renv, 0, + "check and retrieve mailbox message [mailbox=`%s' index=%d]", + str_c(folder), msg_index); + } + } else { + if ( sieve_runtime_trace_active(renv, SIEVE_TRLVL_COMMANDS) ) { + sieve_runtime_trace(renv, 0, + "testsuite: test_message command"); + sieve_runtime_trace_descend(renv); + sieve_runtime_trace(renv, 0, + "retrieve mailbox message [mailbox=`%s' index=%d]", + str_c(folder), msg_index); + } + } result = testsuite_mailstore_mail_index(renv, str_c(folder), msg_index); diff --git a/src/testsuite/cmd-test-result-print.c b/src/testsuite/cmd-test-result-print.c index 4af964976e7a3237de11fe211e9202e1a5a38103..6858cc0889288ea1c7b3a7361c68a79367c2f8c5 100644 --- a/src/testsuite/cmd-test-result-print.c +++ b/src/testsuite/cmd-test-result-print.c @@ -68,6 +68,9 @@ static bool cmd_test_result_print_generate static int cmd_test_result_print_operation_execute (const struct sieve_runtime_env *renv, sieve_size_t *address ATTR_UNUSED) { + sieve_runtime_trace(renv, SIEVE_TRLVL_COMMANDS, + "testsuite: test_result_print command; print script result "); + testsuite_result_print(renv); return SIEVE_EXEC_OK; diff --git a/src/testsuite/cmd-test-result-reset.c b/src/testsuite/cmd-test-result-reset.c index 285afee2acade0cbbe76359c5bc95b4fb909b50f..df2f46c80e993be96b31c1739d431a74022f254c 100644 --- a/src/testsuite/cmd-test-result-reset.c +++ b/src/testsuite/cmd-test-result-reset.c @@ -69,6 +69,9 @@ static bool cmd_test_result_reset_generate static int cmd_test_result_reset_operation_execute (const struct sieve_runtime_env *renv, sieve_size_t *address ATTR_UNUSED) { + sieve_runtime_trace(renv, SIEVE_TRLVL_COMMANDS, + "testsuite: test_result_reset command; reset script result"); + testsuite_result_reset(renv); testsuite_smtp_reset(); diff --git a/src/testsuite/cmd-test-set.c b/src/testsuite/cmd-test-set.c index 459e4e86fa7b257991121f1c933ec9583733a216..32077d6c80f4c582b90bd9fecee5fa8184edfa09 100644 --- a/src/testsuite/cmd-test-set.c +++ b/src/testsuite/cmd-test-set.c @@ -138,9 +138,13 @@ static int cmd_test_set_operation_execute if ( !sieve_opr_string_read(renv, address, "string", &value) ) return SIEVE_EXEC_BIN_CORRUPT; - sieve_runtime_trace(renv, SIEVE_TRLVL_COMMANDS, - "test_set '%s' = \"%s\"", - testsuite_object_member_name(&tobj, member_id), str_c(value)); + if ( sieve_runtime_trace_active(renv, SIEVE_TRLVL_COMMANDS) ) { + sieve_runtime_trace(renv, 0, "testsuite: test_set command"); + sieve_runtime_trace_descend(renv); + sieve_runtime_trace(renv, 0, + "set test parameter '%s' = \"%s\"", + testsuite_object_member_name(&tobj, member_id), str_c(value)); + } if ( tobj.def == NULL || tobj.def->set_member == NULL ) { sieve_runtime_trace_error(renv, "unimplemented testsuite object"); diff --git a/src/testsuite/cmd-test.c b/src/testsuite/cmd-test.c index dd6a786448b5d5e9d90039437ce2d725cee87cbf..40fb7f5c958c4dc074be57ac2b187d2ed0d4622d 100644 --- a/src/testsuite/cmd-test.c +++ b/src/testsuite/cmd-test.c @@ -157,7 +157,7 @@ static int cmd_test_operation_execute sieve_runtime_trace_sep(renv); sieve_runtime_trace(renv, SIEVE_TRLVL_NONE, - "** Test start: \"%s\"", str_c(test_name)); + "** Testsuite test start: \"%s\"", str_c(test_name)); testsuite_test_start(test_name); return SIEVE_EXEC_OK; @@ -167,7 +167,8 @@ static int cmd_test_finish_operation_execute (const struct sieve_runtime_env *renv ATTR_UNUSED, sieve_size_t *address ATTR_UNUSED) { - sieve_runtime_trace(renv, SIEVE_TRLVL_NONE, "** Test end"); + sieve_runtime_trace(renv, SIEVE_TRLVL_NONE, + "** Testsuite test end"); sieve_runtime_trace_sep(renv); testsuite_test_succeed(NULL); diff --git a/src/testsuite/testsuite-script.c b/src/testsuite/testsuite-script.c index c82031e4022eb1523627460708ee9078e2c452d5..fe264f0965925a5f06d670b12d3019d8094c4249 100644 --- a/src/testsuite/testsuite-script.c +++ b/src/testsuite/testsuite-script.c @@ -8,6 +8,7 @@ #include "sieve-script.h" #include "sieve-binary.h" #include "sieve-interpreter.h" +#include "sieve-runtime-trace.h" #include "sieve-result.h" #include "testsuite-common.h" @@ -35,11 +36,21 @@ void testsuite_script_deinit(void) } } -static struct sieve_binary *_testsuite_script_compile(const char *script_path) +static struct sieve_binary *_testsuite_script_compile +(const struct sieve_runtime_env *renv, const char *script) { struct sieve_instance *svinst = testsuite_sieve_instance; struct sieve_binary *sbin; const char *sieve_dir; + const char *script_path; + + sieve_runtime_trace(renv, SIEVE_TRLVL_TESTS, "compile script `%s'", script); + + script_path = sieve_script_dirpath(renv->script); + if ( script_path == NULL ) + return SIEVE_EXEC_FAILURE; + + script_path = t_strconcat(script_path, "/", script, NULL); /* Initialize environment */ sieve_dir = strrchr(script_path, '/'); @@ -61,13 +72,14 @@ static struct sieve_binary *_testsuite_script_compile(const char *script_path) return sbin; } -bool testsuite_script_compile(const char *script_path) +bool testsuite_script_compile +(const struct sieve_runtime_env *renv, const char *script) { struct sieve_binary *sbin; testsuite_log_clear_messages(); - if ( (sbin=_testsuite_script_compile(script_path)) == NULL ) + if ( (sbin=_testsuite_script_compile(renv, script)) == NULL ) return FALSE; if ( _testsuite_compiled_script != NULL ) { @@ -152,7 +164,7 @@ bool testsuite_script_multiscript const char *const *scripts; unsigned int count, i; bool more = TRUE; - int ret; + bool result = TRUE; testsuite_log_clear_messages(); @@ -168,6 +180,7 @@ bool testsuite_script_multiscript scriptenv.duplicate_check = NULL; scriptenv.user = renv->scriptenv->user; scriptenv.trace_stream = renv->scriptenv->trace_stream; + scriptenv.trace_config = renv->scriptenv->trace_config; /* Start execution */ @@ -179,22 +192,25 @@ bool testsuite_script_multiscript for ( i = 0; i < count && more; i++ ) { struct sieve_binary *sbin = NULL; - const char *script_path = scripts[i]; + const char *script = scripts[i]; bool final = ( i == count - 1 ); /* Open */ - if ( (sbin=_testsuite_script_compile(script_path)) == NULL ) + if ( (sbin=_testsuite_script_compile(renv, script)) == NULL ) { + result = FALSE; break; + } /* Execute */ + sieve_runtime_trace(renv, SIEVE_TRLVL_TESTS, "run script `%s'", script); + more = sieve_multiscript_run(mscript, sbin, testsuite_log_ehandler, final); sieve_close(&sbin); } - ret = sieve_multiscript_finish(&mscript, testsuite_log_ehandler, NULL); - - return ( ret > 0 ); + return ( sieve_multiscript_finish(&mscript, testsuite_log_ehandler, NULL) > 0 + && result ); } diff --git a/src/testsuite/testsuite-script.h b/src/testsuite/testsuite-script.h index 7ad7c3467fc8b3c067d3e091b3e390d73d801872..9e6ce19c23053d10c82254b745b003a0fe632d79 100644 --- a/src/testsuite/testsuite-script.h +++ b/src/testsuite/testsuite-script.h @@ -9,10 +9,13 @@ void testsuite_script_init(void); void testsuite_script_deinit(void); -bool testsuite_script_compile(const char *script_path); -bool testsuite_script_run(const struct sieve_runtime_env *renv); +bool testsuite_script_compile + (const struct sieve_runtime_env *renv, const char *script); +bool testsuite_script_run + (const struct sieve_runtime_env *renv); bool testsuite_script_multiscript -(const struct sieve_runtime_env *renv, ARRAY_TYPE (const_string) *scriptfiles); + (const struct sieve_runtime_env *renv, + ARRAY_TYPE (const_string) *scriptfiles); struct sieve_binary *testsuite_script_get_binary(void); void testsuite_script_set_binary(struct sieve_binary *sbin); diff --git a/src/testsuite/tst-test-error.c b/src/testsuite/tst-test-error.c index f182203e02e8ca8296b9550f59f3eda53f504d92..9d7f1e58afd34066e912487b1c0d51436d70e823 100644 --- a/src/testsuite/tst-test-error.c +++ b/src/testsuite/tst-test-error.c @@ -251,10 +251,10 @@ static int tst_test_error_operation_execute if ( index > 0 ) sieve_runtime_trace(renv, SIEVE_TRLVL_TESTS, - "test_error test [index=%d]", index); + "testsuite: test_error test; match error message [index=%d]", index); else sieve_runtime_trace(renv, SIEVE_TRLVL_TESTS, - "test_error test"); + "testsuite: test_error test; match error messages"); /* Create value stringlist */ value_list = testsuite_log_stringlist_create(renv, index); diff --git a/src/testsuite/tst-test-multiscript.c b/src/testsuite/tst-test-multiscript.c index 555e13c6a0a41f197c36c4dff775e1083ef50ee8..156bf434ac6a4a5cb02793f6fbaad1f26c19ce1a 100644 --- a/src/testsuite/tst-test-multiscript.c +++ b/src/testsuite/tst-test-multiscript.c @@ -110,7 +110,6 @@ static int tst_test_multiscript_operation_execute { struct sieve_stringlist *scripts_list; string_t *script_name; - const char *script_path; ARRAY_TYPE (const_string) scriptfiles; bool result = TRUE; int ret; @@ -127,26 +126,22 @@ static int tst_test_multiscript_operation_execute * Perform operation */ - sieve_runtime_trace(renv, SIEVE_TRLVL_TESTS, "test_multiscript test"); + sieve_runtime_trace(renv, SIEVE_TRLVL_TESTS, + "testsuite: test_multiscript test"); + sieve_runtime_trace_descend(renv); t_array_init(&scriptfiles, 16); - script_path = sieve_script_dirpath(renv->script); - if ( script_path == NULL ) - return SIEVE_EXEC_FAILURE; - script_name = NULL; while ( result && (ret=sieve_stringlist_next_item(scripts_list, &script_name)) > 0 ) { + const char *script = t_strdup(str_c(script_name)); - const char *path = - t_strconcat(script_path, "/", str_c(script_name), NULL); - - /* Attempt script compile */ - array_append(&scriptfiles, &path, 1); + array_append(&scriptfiles, &script, 1); } - result = result && (ret >= 0) && testsuite_script_multiscript(renv, &scriptfiles); + result = result && (ret >= 0) && + testsuite_script_multiscript(renv, &scriptfiles); /* Set result */ sieve_interpreter_set_test_result(renv->interp, result); diff --git a/src/testsuite/tst-test-result-execute.c b/src/testsuite/tst-test-result-execute.c index 21e4c7dfe7c965c5e965a6b48c5c8b5ef378bb24..515a9aeba3c8aee79633e80fe4b1ca0db0e9feaf 100644 --- a/src/testsuite/tst-test-result-execute.c +++ b/src/testsuite/tst-test-result-execute.c @@ -74,10 +74,17 @@ static int tst_test_result_execute_operation_execute * Perform operation */ - sieve_runtime_trace(renv, SIEVE_TRLVL_TESTS, "test_result_execute"); + sieve_runtime_trace(renv, SIEVE_TRLVL_TESTS, + "testsuite: test_result_execute test"); result = testsuite_result_execute(renv); + if ( sieve_runtime_trace_active(renv, SIEVE_TRLVL_TESTS) ) { + sieve_runtime_trace_descend(renv); + sieve_runtime_trace(renv, 0, "execution of result %s", + ( result ? "succeeded" : "failed" )); + } + /* Set result */ sieve_interpreter_set_test_result(renv->interp, result); diff --git a/src/testsuite/tst-test-result.c b/src/testsuite/tst-test-result.c index 1470454f73bf2227003b12506d3385b72d100ab7..9a9889bd9c70524712da11c188567c18d2d9dd99 100644 --- a/src/testsuite/tst-test-result.c +++ b/src/testsuite/tst-test-result.c @@ -255,7 +255,7 @@ static int tst_test_result_operation_execute */ sieve_runtime_trace(renv, SIEVE_TRLVL_TESTS, - "test_result test (index: %d)", index); + "testsuite: test_result test; match result name (index: %d)", index); /* Create value stringlist */ value_list = testsuite_result_stringlist_create(renv, index); diff --git a/src/testsuite/tst-test-script-compile.c b/src/testsuite/tst-test-script-compile.c index c76699e9db95266537862eba026e708db2596038..58ec3f413bd611a7f1d83918339bbe6bfc532f02 100644 --- a/src/testsuite/tst-test-script-compile.c +++ b/src/testsuite/tst-test-script-compile.c @@ -108,7 +108,6 @@ static int tst_test_script_compile_operation_execute (const struct sieve_runtime_env *renv, sieve_size_t *address) { string_t *script_name; - const char *script_path; bool result = TRUE; /* @@ -122,18 +121,14 @@ static int tst_test_script_compile_operation_execute * Perform operation */ - sieve_runtime_trace(renv, SIEVE_TRLVL_TESTS, - "testsuite: compile script '%s'", str_c(script_name)); - - script_path = sieve_script_dirpath(renv->script); - if ( script_path == NULL ) - return SIEVE_EXEC_FAILURE; - - script_path = t_strconcat(script_path, "/", str_c(script_name), NULL); + if ( sieve_runtime_trace_active(renv, SIEVE_TRLVL_TESTS) ) { + sieve_runtime_trace(renv, 0, "testsuite: test_script_compile test"); + sieve_runtime_trace_descend(renv); + } /* Attempt script compile */ - result = testsuite_script_compile(script_path); + result = testsuite_script_compile(renv, str_c(script_name)); /* Set result */ sieve_interpreter_set_test_result(renv->interp, result); diff --git a/src/testsuite/tst-test-script-run.c b/src/testsuite/tst-test-script-run.c index 262da7ed934fa05dc2862e1a73501d1c2ef70c12..c59d91013e53e0ab953d5979a009f168d339c2e0 100644 --- a/src/testsuite/tst-test-script-run.c +++ b/src/testsuite/tst-test-script-run.c @@ -170,8 +170,9 @@ static int tst_test_script_run_operation_execute * Perform operation */ - sieve_runtime_trace(renv, SIEVE_TRLVL_COMMANDS, - "testsuite: run compiled script"); + sieve_runtime_trace(renv, SIEVE_TRLVL_TESTS, + "testsuite: run compiled script [append_result=%s]", + ( append_result ? "yes" : "no" )); /* Reset result object */ if ( !append_result ) @@ -180,6 +181,12 @@ static int tst_test_script_run_operation_execute /* Run script */ result = testsuite_script_run(renv); + if ( sieve_runtime_trace_active(renv, SIEVE_TRLVL_TESTS) ) { + sieve_runtime_trace_descend(renv); + sieve_runtime_trace(renv, 0, "execution of script %s", + ( result ? "succeeded" : "failed" )); + } + /* Indicate test status */ sieve_interpreter_set_test_result(renv->interp, result);