From 4e78793dc6be6364a392cb77501ccb8bb458952b Mon Sep 17 00:00:00 2001 From: Stephan Bosch <stephan@rename-it.nl> Date: Mon, 14 Jul 2008 19:57:37 +0200 Subject: [PATCH] Built result print functions thus removing various printf()s. --- TODO | 10 +-- src/lib-sieve/cmd-discard.c | 6 +- src/lib-sieve/cmd-redirect.c | 6 +- src/lib-sieve/ext-reject.c | 6 +- src/lib-sieve/plugins/copy/ext-copy.c | 7 +- .../imapflags/imapflags-implicit.sieve | 29 +++++++ src/lib-sieve/plugins/imapflags/tag-flags.c | 61 ++++++++------- src/lib-sieve/plugins/vacation/cmd-vacation.c | 19 ++--- src/lib-sieve/sieve-actions.c | 6 +- src/lib-sieve/sieve-actions.h | 6 +- src/lib-sieve/sieve-ast.h | 2 +- src/lib-sieve/sieve-common.h | 1 + src/lib-sieve/sieve-result.c | 75 ++++++++++++++++--- src/lib-sieve/sieve-result.h | 18 ++++- src/lib-sieve/sieve-validator.c | 6 +- src/lib-sieve/sieve.c | 4 +- src/lib-sieve/sieve.h | 4 +- src/sieve-bin/sieve-test.c | 9 ++- src/testsuite/testsuite.c | 7 +- 19 files changed, 199 insertions(+), 83 deletions(-) create mode 100644 src/lib-sieve/plugins/imapflags/imapflags-implicit.sieve diff --git a/TODO b/TODO index 4aa084eff..abf1cf31e 100644 --- a/TODO +++ b/TODO @@ -1,18 +1,18 @@ Next (in order of descending priority/precedence): * Get rid of all <stdio.h> printf()s in the library; use trace macro instead +* Emit line numbers for certain action commands to provide useful runtime error + messages. * Revise extension support for comparators, match-types, address-parts and side-effects. Current implementation emits redundant bytes and associated code is not very neat. -* Emit line numbers for certain action commands to provide useful runtime error - messages. * Improve handling of old/corrupt binaries. -* Full security review. Enforce limits on number of created objects, script - size, execution time, etc... * Full standards compliance review for the engine and all fully implemented - sieve extensions. + sieve extensions.\ * Code cleanup * Make sure cmusieve can be replaced seamlessly with the new plugin. +* Full security review. Enforce limits on number of created objects, script + size, execution time, etc... * Make simple test suite for the base functionality * ## MAKE A FIRST RELEASE ## diff --git a/src/lib-sieve/cmd-discard.c b/src/lib-sieve/cmd-discard.c index 42af9c156..f972c35d8 100644 --- a/src/lib-sieve/cmd-discard.c +++ b/src/lib-sieve/cmd-discard.c @@ -46,7 +46,7 @@ const struct sieve_operation cmd_discard_operation = { /* discard action */ static void act_discard_print - (const struct sieve_action *action, struct sieve_result *result, + (const struct sieve_action *action, const struct sieve_result_print_env *rpenv, void *context, bool *keep); static bool act_discard_commit (const struct sieve_action *action, @@ -96,10 +96,10 @@ static bool cmd_discard_operation_execute static void act_discard_print (const struct sieve_action *action ATTR_UNUSED, - struct sieve_result *result ATTR_UNUSED, void *context ATTR_UNUSED, + const struct sieve_result_print_env *rpenv, void *context ATTR_UNUSED, bool *keep) { - printf("* discard\n"); + sieve_result_action_printf(rpenv, "discard"); *keep = FALSE; } diff --git a/src/lib-sieve/cmd-redirect.c b/src/lib-sieve/cmd-redirect.c index 342bb87a4..46831a2a8 100644 --- a/src/lib-sieve/cmd-redirect.c +++ b/src/lib-sieve/cmd-redirect.c @@ -67,7 +67,7 @@ static int act_redirect_check_duplicate (const struct sieve_runtime_env *renv, const struct sieve_action *action1, void *context1, void *context2); static void act_redirect_print - (const struct sieve_action *action, struct sieve_result *result, + (const struct sieve_action *action, const struct sieve_result_print_env *rpenv, void *context, bool *keep); static bool act_redirect_commit (const struct sieve_action *action ATTR_UNUSED, @@ -210,11 +210,11 @@ static int act_redirect_check_duplicate static void act_redirect_print (const struct sieve_action *action ATTR_UNUSED, - struct sieve_result *result ATTR_UNUSED, void *context, bool *keep) + const struct sieve_result_print_env *rpenv, void *context, bool *keep) { struct act_redirect_context *ctx = (struct act_redirect_context *) context; - printf("* redirect message to: %s\n", ctx->to_address); + sieve_result_action_printf(rpenv, "redirect message to: %s", ctx->to_address); *keep = FALSE; } diff --git a/src/lib-sieve/ext-reject.c b/src/lib-sieve/ext-reject.c index bd044cbbc..69118395a 100644 --- a/src/lib-sieve/ext-reject.c +++ b/src/lib-sieve/ext-reject.c @@ -99,7 +99,7 @@ int act_reject_check_conflict (const struct sieve_runtime_env *renv, const struct sieve_action *action, const struct sieve_action *other_action, void *context); static void act_reject_print - (const struct sieve_action *action, struct sieve_result *result, + (const struct sieve_action *action, const struct sieve_result_print_env *rpenv, void *context, bool *keep); static bool act_reject_commit (const struct sieve_action *action ATTR_UNUSED, @@ -256,11 +256,11 @@ int act_reject_check_conflict static void act_reject_print (const struct sieve_action *action ATTR_UNUSED, - struct sieve_result *result ATTR_UNUSED, void *context, bool *keep) + const struct sieve_result_print_env *rpenv, void *context, bool *keep) { struct act_reject_context *ctx = (struct act_reject_context *) context; - printf("* reject message with reason: %s\n", ctx->reason); + sieve_result_action_printf(rpenv, "reject message with reason: %s", ctx->reason); *keep = FALSE; } diff --git a/src/lib-sieve/plugins/copy/ext-copy.c b/src/lib-sieve/plugins/copy/ext-copy.c index a7e659dee..27daac377 100644 --- a/src/lib-sieve/plugins/copy/ext-copy.c +++ b/src/lib-sieve/plugins/copy/ext-copy.c @@ -55,7 +55,7 @@ const struct sieve_side_effect_extension ext_copy_side_effect; static void seff_copy_print (const struct sieve_side_effect *seffect, const struct sieve_action *action, - struct sieve_result *result, void *se_context, bool *keep); + const struct sieve_result_print_env *rpenv, void *se_context, bool *keep); static bool seff_copy_post_commit (const struct sieve_side_effect *seffect, const struct sieve_action *action, const struct sieve_action_exec_env *aenv, void *se_context, @@ -126,10 +126,10 @@ static const struct sieve_argument copy_tag = { static void seff_copy_print (const struct sieve_side_effect *seffect ATTR_UNUSED, const struct sieve_action *action ATTR_UNUSED, - struct sieve_result *result ATTR_UNUSED, + const struct sieve_result_print_env *rpenv, void *se_context ATTR_UNUSED, bool *keep) { - printf(" + preserve implicit keep\n"); + sieve_result_seffect_printf(rpenv, "preserve implicit keep"); *keep = TRUE; } @@ -140,7 +140,6 @@ static bool seff_copy_post_commit const struct sieve_action_exec_env *aenv ATTR_UNUSED, void *se_context ATTR_UNUSED, void *tr_context ATTR_UNUSED, bool *keep) { - sieve_result_log(aenv, "implicit keep preserved after %s action.", action->name); *keep = TRUE; return TRUE; } diff --git a/src/lib-sieve/plugins/imapflags/imapflags-implicit.sieve b/src/lib-sieve/plugins/imapflags/imapflags-implicit.sieve new file mode 100644 index 000000000..8754fad5c --- /dev/null +++ b/src/lib-sieve/plugins/imapflags/imapflags-implicit.sieve @@ -0,0 +1,29 @@ +require "imap4flags"; +require "fileinto"; +require "relational"; +require "comparator-i;ascii-numeric"; +require "copy"; + +setflag "\\Seen"; +addflag "$DSNRequired"; +removeflag "$DSNRequired"; + +if header :contains "from" "boss@frobnitzm.example.edu" { + setflag "\\Flagged"; + fileinto :copy "From Boss"; +} + +if header :contains "Disposition-Notification-To" "mel@example.com" { + addflag "$MDNRequired"; +} + +if header :contains "from" "imap@cac.washington.example.edu" { + removeflag "$MDNRequired \\Flagged \\Seen \\Deleted"; + fileinto :copy "imap-list"; +} + +if hasflag :count "ge" :comparator "i;ascii-numeric" "2" { + fileinto :copy "imap-twoflags"; +} + +fileinto :copy :flags "MDNRequired \\Draft" "imap-draft"; diff --git a/src/lib-sieve/plugins/imapflags/tag-flags.c b/src/lib-sieve/plugins/imapflags/tag-flags.c index 5f1e6c5b8..dd062ab28 100644 --- a/src/lib-sieve/plugins/imapflags/tag-flags.c +++ b/src/lib-sieve/plugins/imapflags/tag-flags.c @@ -42,8 +42,8 @@ static bool seff_flags_read_context const struct sieve_runtime_env *renv, sieve_size_t *address, void **se_context); static void seff_flags_print - (const struct sieve_side_effect *seffect, const struct sieve_action *action, - struct sieve_result *result, void *se_context, bool *keep); + (const struct sieve_side_effect *seffect, const struct sieve_action *action, + const struct sieve_result_print_env *rpenv, void *se_context, bool *keep); static bool seff_flags_pre_execute (const struct sieve_side_effect *seffect, const struct sieve_action *action, const struct sieve_action_exec_env *aenv, @@ -168,7 +168,10 @@ static bool seff_flags_read_context while ( (flag=ext_imapflags_iter_get_flag(&flit)) != NULL ) { if (flag != NULL && *flag != '\\') { /* keyword */ - array_append(&ctx->keywords, &flag, 1); + const char *keyword = p_strdup(pool, flag); + + array_append(&ctx->keywords, &keyword, 1); + } else { /* system flag */ if (flag == NULL || strcasecmp(flag, "\\flagged") == 0) @@ -210,7 +213,8 @@ static struct seff_flags_context *seff_flags_get_implicit_context while ( (flag=ext_imapflags_iter_get_flag(&flit)) != NULL ) { if (flag != NULL && *flag != '\\') { /* keyword */ - array_append(&ctx->keywords, &flag, 1); + const char *keyword = p_strdup(pool, flag); + array_append(&ctx->keywords, &keyword, 1); } else { /* system flag */ if (flag == NULL || strcasecmp(flag, "\\flagged") == 0) @@ -234,40 +238,43 @@ static struct seff_flags_context *seff_flags_get_implicit_context static void seff_flags_print (const struct sieve_side_effect *seffect ATTR_UNUSED, const struct sieve_action *action ATTR_UNUSED, - struct sieve_result *result, - void *se_context ATTR_UNUSED, bool *keep ATTR_UNUSED) + const struct sieve_result_print_env *rpenv, + void *se_context, bool *keep ATTR_UNUSED) { + struct sieve_result *result = rpenv->result; struct seff_flags_context *ctx = (struct seff_flags_context *) se_context; unsigned int i; if ( ctx == NULL ) ctx = seff_flags_get_implicit_context(result); - if ( ctx->flags != 0 || array_count(&ctx->keywords) ) { - printf(" + add flags:"); - - if ( (ctx->flags & MAIL_FLAGGED) > 0 ) - printf(" \\flagged\n"); - - if ( (ctx->flags & MAIL_ANSWERED) > 0 ) - printf(" \\answered"); + if ( ctx->flags != 0 || array_count(&ctx->keywords) > 0 ) { + T_BEGIN { + string_t *flags = t_str_new(128); + + if ( (ctx->flags & MAIL_FLAGGED) > 0 ) + str_printfa(flags, " \\flagged\n"); + + if ( (ctx->flags & MAIL_ANSWERED) > 0 ) + str_printfa(flags, " \\answered"); - if ( (ctx->flags & MAIL_DELETED) > 0 ) - printf(" \\deleted"); + if ( (ctx->flags & MAIL_DELETED) > 0 ) + str_printfa(flags, " \\deleted"); - if ( (ctx->flags & MAIL_SEEN) > 0 ) - printf(" \\seen"); - - if ( (ctx->flags & MAIL_DRAFT) > 0 ) - printf(" \\draft"); + if ( (ctx->flags & MAIL_SEEN) > 0 ) + str_printfa(flags, " \\seen"); + + if ( (ctx->flags & MAIL_DRAFT) > 0 ) + str_printfa(flags, " \\draft"); + + for ( i = 0; i < array_count(&ctx->keywords); i++ ) { + const char *const *keyword = array_idx(&ctx->keywords, i); + str_printfa(flags, " %s", *keyword); + } - for ( i = 0; i < array_count(&ctx->keywords); i++ ) { - const char *const *keyword = array_idx(&ctx->keywords, i); - printf(" %s", *keyword); - }; + sieve_result_seffect_printf(rpenv, "add flags:%s", str_c(flags)); + } T_END; } - - printf("\n"); } static bool seff_flags_pre_execute diff --git a/src/lib-sieve/plugins/vacation/cmd-vacation.c b/src/lib-sieve/plugins/vacation/cmd-vacation.c index ac7b0c30f..7fee60230 100644 --- a/src/lib-sieve/plugins/vacation/cmd-vacation.c +++ b/src/lib-sieve/plugins/vacation/cmd-vacation.c @@ -56,7 +56,7 @@ int act_vacation_check_conflict (const struct sieve_runtime_env *renv, const struct sieve_action *action, const struct sieve_action *other_action, void *context); static void act_vacation_print - (const struct sieve_action *action, struct sieve_result *result, + (const struct sieve_action *action, const struct sieve_result_print_env *rpenv, void *context, bool *keep); static bool act_vacation_commit (const struct sieve_action *action, const struct sieve_action_exec_env *aenv, @@ -469,20 +469,21 @@ int act_vacation_check_conflict } static void act_vacation_print -(const struct sieve_action *action ATTR_UNUSED, struct sieve_result *result ATTR_UNUSED, - void *context, bool *keep ATTR_UNUSED) +(const struct sieve_action *action ATTR_UNUSED, + const struct sieve_result_print_env *rpenv, void *context, + bool *keep ATTR_UNUSED) { struct act_vacation_context *ctx = (struct act_vacation_context *) context; - printf( "* send vacation message:\n" - " => days : %d\n", ctx->days); + sieve_result_action_printf( rpenv, "send vacation message:"); + sieve_result_printf(rpenv, " => days : %d\n", ctx->days); if ( ctx->subject != NULL ) - printf( " => subject: %s\n", ctx->subject); + sieve_result_printf(rpenv, " => subject: %s\n", ctx->subject); if ( ctx->from != NULL ) - printf( " => from : %s\n", ctx->from); + sieve_result_printf(rpenv, " => from : %s\n", ctx->from); if ( ctx->handle != NULL ) - printf( " => handle : %s\n", ctx->handle); - printf( "\nSTART MESSAGE\n%s\nEND MESSAGE\n", ctx->reason); + sieve_result_printf(rpenv, " => handle : %s\n", ctx->handle); + sieve_result_printf(rpenv, "\nSTART MESSAGE\n%s\nEND MESSAGE\n", ctx->reason); } static const char * const _list_headers[] = { diff --git a/src/lib-sieve/sieve-actions.c b/src/lib-sieve/sieve-actions.c index c5cb0f7e7..cae579a3d 100644 --- a/src/lib-sieve/sieve-actions.c +++ b/src/lib-sieve/sieve-actions.c @@ -183,7 +183,7 @@ static int act_store_check_duplicate (const struct sieve_runtime_env *renv, const struct sieve_action *action1, void *context1, void *context2); static void act_store_print - (const struct sieve_action *action, struct sieve_result *result, + (const struct sieve_action *action, const struct sieve_result_print_env *rpenv, void *context, bool *keep); static bool act_store_start @@ -244,11 +244,11 @@ static int act_store_check_duplicate static void act_store_print (const struct sieve_action *action ATTR_UNUSED, - struct sieve_result *result ATTR_UNUSED, void *context, bool *keep) + const struct sieve_result_print_env *rpenv, void *context, bool *keep) { struct act_store_context *ctx = (struct act_store_context *) context; - printf("* store message in folder: %s\n", ctx->folder); + sieve_result_action_printf(rpenv, "store message in folder: %s", ctx->folder); *keep = FALSE; } diff --git a/src/lib-sieve/sieve-actions.h b/src/lib-sieve/sieve-actions.h index b17ffe838..2f40d5a37 100644 --- a/src/lib-sieve/sieve-actions.h +++ b/src/lib-sieve/sieve-actions.h @@ -34,8 +34,8 @@ struct sieve_action { void *context); void (*print) - (const struct sieve_action *action, struct sieve_result *result, - void *context, bool *keep); + (const struct sieve_action *action, + const struct sieve_result_print_env *penv, void *context, bool *keep); bool (*start) (const struct sieve_action *action, @@ -73,7 +73,7 @@ struct sieve_side_effect { void (*print) (const struct sieve_side_effect *seffect, const struct sieve_action *action, - struct sieve_result *result, void *se_context, bool *keep); + const struct sieve_result_print_env *penv, void *se_context, bool *keep); bool (*pre_execute) (const struct sieve_side_effect *seffect, const struct sieve_action *action, diff --git a/src/lib-sieve/sieve-ast.h b/src/lib-sieve/sieve-ast.h index ca76da300..0e0b5758a 100644 --- a/src/lib-sieve/sieve-ast.h +++ b/src/lib-sieve/sieve-ast.h @@ -82,7 +82,7 @@ struct sieve_ast_argument { /* Argument associated with this ast element */ const struct sieve_argument *argument; - unsigned int arg_id_code; + int arg_id_code; /* Parameters to this (tag) argument */ struct sieve_ast_argument *parameters; diff --git a/src/lib-sieve/sieve-common.h b/src/lib-sieve/sieve-common.h index 7ce1f2360..a8a49af02 100644 --- a/src/lib-sieve/sieve-common.h +++ b/src/lib-sieve/sieve-common.h @@ -84,6 +84,7 @@ struct sieve_address_part; /* sieve-result.h */ struct sieve_result; struct sieve_side_effects_list; +struct sieve_result_print_env; /* sieve-actions.h */ struct sieve_action_exec_env; diff --git a/src/lib-sieve/sieve-result.c b/src/lib-sieve/sieve-result.c index a27dd83f7..8eab847c3 100644 --- a/src/lib-sieve/sieve-result.c +++ b/src/lib-sieve/sieve-result.c @@ -1,6 +1,8 @@ #include "lib.h" #include "mempool.h" +#include "ostream.h" #include "hash.h" +#include "str.h" #include "strfuncs.h" #include "str-sanitize.h" @@ -289,25 +291,77 @@ int sieve_result_add_action } return 0; -} +} + +/* + * Result printing + */ + +void sieve_result_printf +(const struct sieve_result_print_env *penv, const char *fmt, ...) +{ + string_t *outbuf = t_str_new(128); + va_list args; + + va_start(args, fmt); + str_vprintfa(outbuf, fmt, args); + va_end(args); + + o_stream_send(penv->stream, str_data(outbuf), str_len(outbuf)); +} -bool sieve_result_print(struct sieve_result *result) +void sieve_result_action_printf +(const struct sieve_result_print_env *penv, const char *fmt, ...) +{ + string_t *outbuf = t_str_new(128); + va_list args; + + va_start(args, fmt); + str_append(outbuf, "\n * "); + str_vprintfa(outbuf, fmt, args); + str_append_c(outbuf, '\n'); + va_end(args); + + o_stream_send(penv->stream, str_data(outbuf), str_len(outbuf)); +} + +void sieve_result_seffect_printf +(const struct sieve_result_print_env *penv, const char *fmt, ...) +{ + string_t *outbuf = t_str_new(128); + va_list args; + + va_start(args, fmt); + str_append(outbuf, " + "); + str_vprintfa(outbuf, fmt, args); + str_append_c(outbuf, '\n'); + va_end(args); + + o_stream_send(penv->stream, str_data(outbuf), str_len(outbuf)); +} + +bool sieve_result_print +(struct sieve_result *result, struct ostream *stream) { + struct sieve_result_print_env penv; bool implicit_keep = TRUE; - struct sieve_result_action *rac = result->first_action; + struct sieve_result_action *rac; + + penv.result = result; + penv.stream = stream; - printf("\nPerformed actions:\n"); + sieve_result_printf(&penv, "\nPerformed actions:\n"); + rac = result->first_action; while ( rac != NULL ) { bool keep = TRUE; const struct sieve_action *act = rac->action; struct sieve_result_side_effect *rsef; const struct sieve_side_effect *sef; - if ( act->print != NULL ) { - act->print(act, result, rac->context, &keep); + act->print(act, &penv, rac->context, &keep); } else { - printf("* %s\n", act->name); + sieve_result_action_printf(&penv, act->name); } /* Print side effects */ @@ -316,15 +370,16 @@ bool sieve_result_print(struct sieve_result *result) sef = rsef->seffect; if ( sef->print != NULL ) sef->print - (sef, act, result, rsef->context, &keep); + (sef, act, &penv, rsef->context, &keep); rsef = rsef->next; } - + implicit_keep = implicit_keep && keep; rac = rac->next; } - printf("\nImplicit keep: %s\n", implicit_keep ? "yes" : "no"); + sieve_result_printf + (&penv, "\nImplicit keep: %s\n", implicit_keep ? "yes" : "no"); return TRUE; } diff --git a/src/lib-sieve/sieve-result.h b/src/lib-sieve/sieve-result.h index f5917cc8a..d476326ec 100644 --- a/src/lib-sieve/sieve-result.h +++ b/src/lib-sieve/sieve-result.h @@ -18,6 +18,22 @@ void sieve_result_extension_set_context const void *sieve_result_extension_get_context (struct sieve_result *result, int ext_id); +/* Printing */ + +struct sieve_result_print_env { + struct sieve_result *result; + struct ostream *stream; +}; + +void sieve_result_printf + (const struct sieve_result_print_env *penv, const char *fmt, ...); +void sieve_result_action_printf + (const struct sieve_result_print_env *penv, const char *fmt, ...); +void sieve_result_seffect_printf + (const struct sieve_result_print_env *penv, const char *fmt, ...); + +bool sieve_result_print(struct sieve_result *result, struct ostream *stream); + /* Error handling */ void sieve_result_log @@ -36,8 +52,6 @@ int sieve_result_add_action const struct sieve_action *action, struct sieve_side_effects_list *seffects, void *context); -bool sieve_result_print(struct sieve_result *result); - void sieve_result_cancel_implicit_keep(struct sieve_result *result); int sieve_result_execute diff --git a/src/lib-sieve/sieve-validator.c b/src/lib-sieve/sieve-validator.c index 505d9703a..aaa3caa7b 100644 --- a/src/lib-sieve/sieve-validator.c +++ b/src/lib-sieve/sieve-validator.c @@ -371,7 +371,7 @@ static void sieve_validator_register_unknown_tag static const struct sieve_argument *sieve_validator_find_tag (struct sieve_validator *validator, struct sieve_command_context *cmd, - struct sieve_ast_argument *arg, unsigned int *id_code) + struct sieve_ast_argument *arg, int *id_code) { const char *tag; unsigned int i; @@ -609,7 +609,7 @@ static bool sieve_validate_command_arguments /* Visit tagged and optional arguments */ while ( sieve_ast_argument_type(arg) == SAAT_TAG ) { - unsigned int id_code; + int id_code; struct sieve_ast_argument *parg; const struct sieve_argument *tag = sieve_validator_find_tag(validator, cmd, arg, &id_code); @@ -639,7 +639,7 @@ static bool sieve_validate_command_arguments parg = sieve_ast_argument_prev(arg); while ( parg != NULL ) { if ( (sieve_ast_argument_type(parg) == SAAT_TAG && parg->argument == tag) - || parg->arg_id_code == id_code ) + || (id_code > 0 && parg->arg_id_code == id_code) ) { const char *tag_id = sieve_ast_argument_tag(arg); const char *tag_desc = diff --git a/src/lib-sieve/sieve.c b/src/lib-sieve/sieve.c index 15304adf2..688d1211f 100644 --- a/src/lib-sieve/sieve.c +++ b/src/lib-sieve/sieve.c @@ -189,7 +189,7 @@ void sieve_dump(struct sieve_binary *sbin, struct ostream *stream) int sieve_test (struct sieve_binary *sbin, const struct sieve_message_data *msgdata, - const struct sieve_script_env *senv, + const struct sieve_script_env *senv, struct ostream *stream, struct sieve_error_handler *ehandler) { struct sieve_result *sres = sieve_result_create(ehandler); @@ -200,7 +200,7 @@ int sieve_test ret = sieve_interpreter_run(interp, msgdata, senv, &sres); if ( ret > 0 ) - ret = sieve_result_print(sres); + ret = sieve_result_print(sres, stream); sieve_interpreter_free(&interp); sieve_result_unref(&sres); diff --git a/src/lib-sieve/sieve.h b/src/lib-sieve/sieve.h index a81c79a7a..444d9f6e5 100644 --- a/src/lib-sieve/sieve.h +++ b/src/lib-sieve/sieve.h @@ -88,11 +88,11 @@ bool sieve_save /* sieve_test: * - * Executes the bytecode, but only prints the result to stdout. + * Executes the bytecode, but only prints the result to the given stream. */ int sieve_test (struct sieve_binary *sbin, const struct sieve_message_data *msgdata, - const struct sieve_script_env *senv, + const struct sieve_script_env *senv, struct ostream *stream, struct sieve_error_handler *ehandler); /* sieve_execute: diff --git a/src/sieve-bin/sieve-test.c b/src/sieve-bin/sieve-test.c index 35ac5a398..d6b63f5f5 100644 --- a/src/sieve-bin/sieve-test.c +++ b/src/sieve-bin/sieve-test.c @@ -37,6 +37,7 @@ int main(int argc, char **argv) struct sieve_message_data msgdata; struct sieve_script_env scriptenv; struct sieve_error_handler *ehandler; + struct ostream *teststream; bool force_compile = FALSE; bin_init(); @@ -128,9 +129,13 @@ int main(int argc, char **argv) scriptenv.username = user; ehandler = sieve_stderr_ehandler_create(0); - + + teststream = o_stream_create_fd(1, 0, FALSE); + /* Run the test */ - (void) sieve_test(sbin, &msgdata, &scriptenv, ehandler); + (void) sieve_test(sbin, &msgdata, &scriptenv, teststream, ehandler); + + o_stream_destroy(&teststream); sieve_close(&sbin); sieve_error_handler_unref(&ehandler); diff --git a/src/testsuite/testsuite.c b/src/testsuite/testsuite.c index 51b5e0116..df45c84d6 100644 --- a/src/testsuite/testsuite.c +++ b/src/testsuite/testsuite.c @@ -143,6 +143,7 @@ int main(int argc, char **argv) struct sieve_binary *sbin; struct sieve_script_env scriptenv; struct sieve_error_handler *ehandler; + struct ostream *teststream; testsuite_init(); @@ -183,9 +184,13 @@ int main(int argc, char **argv) scriptenv.username = user; ehandler = sieve_stderr_ehandler_create(0); + + teststream = o_stream_create_fd(1, 0, FALSE); /* Run the test */ - (void) sieve_test(sbin, &testsuite_msgdata, &scriptenv, ehandler); + (void) sieve_test(sbin, &testsuite_msgdata, &scriptenv, teststream, ehandler); + + o_stream_destroy(&teststream); sieve_close(&sbin); sieve_error_handler_unref(&ehandler); -- GitLab