From ba261b2d3d3abd1d7abff39e74c5219ce2614177 Mon Sep 17 00:00:00 2001 From: Stephan Bosch <stephan@rename-it.nl> Date: Sat, 1 Dec 2007 21:02:00 +0100 Subject: [PATCH] Added conflict and duplicate checking to vacation and reject actions. --- sieve/errors/action-conflicts.sieve | 8 ++ sieve/errors/action-duplicates.sieve | 4 + src/lib-sieve/cmd-discard.c | 7 +- src/lib-sieve/cmd-keep.c | 9 ++- src/lib-sieve/cmd-redirect.c | 14 ++-- src/lib-sieve/ext-fileinto.c | 5 +- src/lib-sieve/ext-reject.c | 77 ++++++++++++++----- src/lib-sieve/plugins/vacation/ext-vacation.c | 49 +++++++++--- src/lib-sieve/sieve-actions.c | 12 +-- src/lib-sieve/sieve-actions.h | 17 ++-- src/lib-sieve/sieve-commands-private.h | 5 ++ src/lib-sieve/sieve-interpreter.c | 49 +++++++++++- src/lib-sieve/sieve-interpreter.h | 7 ++ src/lib-sieve/sieve-result.c | 21 ++--- src/lib-sieve/sieve-result.h | 2 +- 15 files changed, 216 insertions(+), 70 deletions(-) create mode 100644 sieve/errors/action-conflicts.sieve create mode 100644 sieve/errors/action-duplicates.sieve diff --git a/sieve/errors/action-conflicts.sieve b/sieve/errors/action-conflicts.sieve new file mode 100644 index 000000000..03949471d --- /dev/null +++ b/sieve/errors/action-conflicts.sieve @@ -0,0 +1,8 @@ +require "fileinto"; +require "reject"; +require "vacation"; + +#fileinto "frop"; +reject "No nonsense in my mailbox."; +vacation "I am gone for a while."; +redirect "stephan@example.com"; diff --git a/sieve/errors/action-duplicates.sieve b/sieve/errors/action-duplicates.sieve new file mode 100644 index 000000000..6d5370d76 --- /dev/null +++ b/sieve/errors/action-duplicates.sieve @@ -0,0 +1,4 @@ +require "reject"; + +reject "Message is not appreciated."; +reject "No, really, it is not appreciated."; diff --git a/src/lib-sieve/cmd-discard.c b/src/lib-sieve/cmd-discard.c index d165b8228..232f4e5a1 100644 --- a/src/lib-sieve/cmd-discard.c +++ b/src/lib-sieve/cmd-discard.c @@ -53,7 +53,8 @@ static bool act_discard_commit const struct sieve_action act_discard = { "discard", - NULL, NULL, + 0, + NULL, NULL, act_discard_print, NULL, NULL, act_discard_commit, @@ -85,9 +86,7 @@ static bool opc_discard_execute { printf(">> DISCARD\n"); - (void) sieve_result_add_action(renv, &act_discard, NULL, NULL); - - return TRUE; + return ( sieve_result_add_action(renv, &act_discard, NULL, NULL) >= 0 ); } /* diff --git a/src/lib-sieve/cmd-keep.c b/src/lib-sieve/cmd-keep.c index 87b369562..e7f243c52 100644 --- a/src/lib-sieve/cmd-keep.c +++ b/src/lib-sieve/cmd-keep.c @@ -66,18 +66,19 @@ static bool opc_keep_execute sieve_size_t *address ATTR_UNUSED) { struct sieve_side_effects_list *slist = NULL; - + int ret = 0; + printf(">> KEEP\n"); if ( !sieve_interpreter_handle_optional_operands(renv, address, &slist) ) return FALSE; if ( renv->mailenv != NULL && renv->mailenv->inbox != NULL ) - (void) sieve_act_store_add_to_result(renv, slist, renv->mailenv->inbox); + ret = sieve_act_store_add_to_result(renv, slist, renv->mailenv->inbox); else - (void) sieve_act_store_add_to_result(renv, slist, "INBOX"); + ret = sieve_act_store_add_to_result(renv, slist, "INBOX"); - return TRUE; + return ret >= 0; } diff --git a/src/lib-sieve/cmd-redirect.c b/src/lib-sieve/cmd-redirect.c index 608179435..0bc9adf04 100644 --- a/src/lib-sieve/cmd-redirect.c +++ b/src/lib-sieve/cmd-redirect.c @@ -55,7 +55,7 @@ const struct sieve_opcode cmd_redirect_opcode = { /* Redirect action */ -static bool act_redirect_check_duplicate +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 @@ -70,6 +70,7 @@ struct act_redirect_context { const struct sieve_action act_redirect = { "redirect", + SIEVE_ACTFLAG_TRIES_DELIVER, act_redirect_check_duplicate, NULL, act_redirect_print, @@ -140,6 +141,7 @@ static bool cmd_redirect_opcode_execute struct act_redirect_context *act; string_t *redirect; pool_t pool; + int ret = 0; if ( !sieve_interpreter_handle_optional_operands(renv, address, &slist) ) return FALSE; @@ -158,17 +160,17 @@ static bool cmd_redirect_opcode_execute act = p_new(pool, struct act_redirect_context, 1); act->to_address = p_strdup(pool, str_c(redirect)); - (void) sieve_result_add_action(renv, &act_redirect, slist, (void *) act); + ret = sieve_result_add_action(renv, &act_redirect, slist, (void *) act); t_pop(); - return TRUE; + return (ret >= 0); } /* * Action */ -static bool act_redirect_check_duplicate +static int act_redirect_check_duplicate (const struct sieve_runtime_env *renv ATTR_UNUSED, const struct sieve_action *action1 ATTR_UNUSED, void *context1, void *context2) @@ -177,9 +179,9 @@ static bool act_redirect_check_duplicate struct act_redirect_context *ctx2 = (struct act_redirect_context *) context2; if ( strcmp(ctx1->to_address, ctx2->to_address) == 0 ) - return TRUE; + return 1; - return FALSE; + return 0; } static void act_redirect_print diff --git a/src/lib-sieve/ext-fileinto.c b/src/lib-sieve/ext-fileinto.c index 052fd577a..08b7012e5 100644 --- a/src/lib-sieve/ext-fileinto.c +++ b/src/lib-sieve/ext-fileinto.c @@ -149,6 +149,7 @@ static bool ext_fileinto_opcode_execute { struct sieve_side_effects_list *slist = NULL; string_t *folder; + int ret = 0; if ( !sieve_interpreter_handle_optional_operands(renv, address, &slist) ) return FALSE; @@ -162,10 +163,10 @@ static bool ext_fileinto_opcode_execute printf(">> FILEINTO \"%s\"\n", str_c(folder)); - (void) sieve_act_store_add_to_result(renv, slist, str_c(folder)); + ret = sieve_act_store_add_to_result(renv, slist, str_c(folder)); t_pop(); - return TRUE; + return ( ret >= 0 ); } diff --git a/src/lib-sieve/ext-reject.c b/src/lib-sieve/ext-reject.c index c8ef054d7..5aebe2e6d 100644 --- a/src/lib-sieve/ext-reject.c +++ b/src/lib-sieve/ext-reject.c @@ -90,11 +90,17 @@ struct sieve_opcode reject_opcode = { /* Reject action */ +static int act_reject_check_duplicate + (const struct sieve_runtime_env *renv, const struct sieve_action *action1, + void *context1, void *context2); +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, void *context, bool *keep); static bool act_reject_commit -(const struct sieve_action *action ATTR_UNUSED, - const struct sieve_action_exec_env *aenv, void *tr_context, bool *keep); + (const struct sieve_action *action ATTR_UNUSED, + const struct sieve_action_exec_env *aenv, void *tr_context, bool *keep); struct act_reject_context { const char *reason; @@ -102,8 +108,9 @@ struct act_reject_context { const struct sieve_action act_reject = { "reject", - NULL, - NULL, + SIEVE_ACTFLAG_SENDS_RESPONSE, + act_reject_check_duplicate, + act_reject_check_conflict, act_reject_print, NULL, NULL, act_reject_commit, @@ -178,6 +185,7 @@ static bool ext_reject_opcode_execute struct act_reject_context *act; string_t *reason; pool_t pool; + int ret; t_push(); @@ -196,15 +204,46 @@ static bool ext_reject_opcode_execute act = p_new(pool, struct act_reject_context, 1); act->reason = p_strdup(pool, str_c(reason)); - (void) sieve_result_add_action(renv, &act_reject, slist, (void *) act); + ret = sieve_result_add_action(renv, &act_reject, slist, (void *) act); t_pop(); - return TRUE; + return ( ret >= 0 ); } /* * Action */ + +static int act_reject_check_duplicate +(const struct sieve_runtime_env *renv ATTR_UNUSED, + const struct sieve_action *action1 ATTR_UNUSED, + void *context1 ATTR_UNUSED, void *context2 ATTR_UNUSED) +{ + sieve_runtime_error(renv, "duplicate 'reject' action not allowed."); + return -1; +} + +int act_reject_check_conflict +(const struct sieve_runtime_env *renv, + const struct sieve_action *action ATTR_UNUSED, + const struct sieve_action *other_action, void *context ATTR_UNUSED) +{ + if ( (other_action->flags & SIEVE_ACTFLAG_TRIES_DELIVER) > 0 ) { + sieve_runtime_error(renv, "'reject' action conflicts with other action: " + "'%s' action tries to deliver the message.", + other_action->name); + return -1; + } + + if ( (other_action->flags & SIEVE_ACTFLAG_SENDS_RESPONSE) > 0 ) { + sieve_runtime_error(renv, "'reject' action conflicts with other action: " + "'%s' sends a response to the sender.", + other_action->name); + return -1; + } + + return 0; +} static void act_reject_print (const struct sieve_action *action ATTR_UNUSED, void *context, bool *keep) @@ -224,7 +263,7 @@ static bool act_reject_send struct istream *input; void *smtp_handle; struct message_size hdr_size; - FILE *f; + FILE *f; const char *new_msgid, *boundary; const unsigned char *data; const char *header; @@ -239,18 +278,18 @@ static bool act_reject_send smtp_handle = mailenv->smtp_open(msgdata->return_path, NULL, &f); - new_msgid = sieve_get_new_message_id(mailenv); + new_msgid = sieve_get_new_message_id(mailenv); boundary = t_strdup_printf("%s/%s", my_pid, mailenv->hostname); fprintf(f, "Message-ID: %s\r\n", new_msgid); fprintf(f, "Date: %s\r\n", message_date_create(ioloop_time)); fprintf(f, "From: Mail Delivery Subsystem <%s>\r\n", - mailenv->postmaster_address); + mailenv->postmaster_address); fprintf(f, "To: <%s>\r\n", msgdata->return_path); fprintf(f, "MIME-Version: 1.0\r\n"); fprintf(f, "Content-Type: " - "multipart/report; report-type=disposition-notification;\r\n" - "\tboundary=\"%s\"\r\n", boundary); + "multipart/report; report-type=disposition-notification;\r\n" + "\tboundary=\"%s\"\r\n", boundary); fprintf(f, "Subject: Automatically rejected mail\r\n"); fprintf(f, "Auto-Submitted: auto-replied (rejected)\r\n"); fprintf(f, "Precedence: bulk\r\n"); @@ -266,7 +305,7 @@ static bool act_reject_send fprintf(f, "Your message to <%s> was automatically rejected:\r\n" "%s\r\n", msgdata->to_address, ctx->reason); - /* MDN status report */ + /* MDN status report */ fprintf(f, "--%s\r\n" "Content-Type: message/disposition-notification\r\n\r\n", boundary); fprintf(f, "Reporting-UA: %s; Dovecot Mail Delivery Agent\r\n", @@ -284,7 +323,7 @@ static bool act_reject_send /* original message's headers */ fprintf(f, "--%s\r\nContent-Type: message/rfc822\r\n\r\n", boundary); - if (mail_get_stream(msgdata->mail, &hdr_size, NULL, &input) == 0) { + if (mail_get_stream(msgdata->mail, &hdr_size, NULL, &input) == 0) { /* Note: If you add more headers, they need to be sorted. We'll drop Content-Type because we're not including the message body, and having a multipart Content-Type may confuse some @@ -321,18 +360,18 @@ static bool act_reject_commit struct act_reject_context *ctx = (struct act_reject_context *) tr_context; if ( msgdata->return_path == NULL || *(msgdata->return_path) == '\0' ) { - sieve_result_log(aenv, "discarded reject to <>"); + sieve_result_log(aenv, "discarded reject to <>"); - *keep = FALSE; - return TRUE; - } + *keep = FALSE; + return TRUE; + } if ( act_reject_send(aenv, ctx) ) { sieve_result_log(aenv, "rejected"); *keep = FALSE; - return TRUE; - } + return TRUE; + } return FALSE; } diff --git a/src/lib-sieve/plugins/vacation/ext-vacation.c b/src/lib-sieve/plugins/vacation/ext-vacation.c index b3f749cd2..f46ff8806 100644 --- a/src/lib-sieve/plugins/vacation/ext-vacation.c +++ b/src/lib-sieve/plugins/vacation/ext-vacation.c @@ -30,7 +30,6 @@ #include <stdio.h> - /* Forward declarations */ static bool ext_vacation_load(int ext_id); @@ -102,11 +101,17 @@ const struct sieve_opcode vacation_opcode = { /* Vacation action */ +static int act_vacation_check_duplicate + (const struct sieve_runtime_env *renv, const struct sieve_action *action1, + void *context1, void *context2); +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, void *context, bool *keep); static bool act_vacation_commit -(const struct sieve_action *action ATTR_UNUSED, - const struct sieve_action_exec_env *aenv, void *tr_context, bool *keep); + (const struct sieve_action *action, const struct sieve_action_exec_env *aenv, + void *tr_context, bool *keep); struct act_vacation_context { const char *reason; @@ -121,8 +126,9 @@ struct act_vacation_context { const struct sieve_action act_vacation = { "vacation", - NULL, - NULL, + SIEVE_ACTFLAG_SENDS_RESPONSE, + act_vacation_check_duplicate, + act_vacation_check_conflict, act_vacation_print, NULL, NULL, act_vacation_commit, @@ -435,14 +441,36 @@ static bool ext_vacation_opcode_execute /* FIXME: :addresses is ignored */ - (void) sieve_result_add_action(renv, &act_vacation, slist, (void *) act); - - return TRUE; + return ( sieve_result_add_action(renv, &act_vacation, slist, (void *) act) >= 0 ); } /* * Action */ + +static int act_vacation_check_duplicate +(const struct sieve_runtime_env *renv ATTR_UNUSED, + const struct sieve_action *action1 ATTR_UNUSED, + void *context1 ATTR_UNUSED, void *context2 ATTR_UNUSED) +{ + sieve_runtime_error(renv, "duplicate 'vacation' action not allowed."); + return -1; +} + +int act_vacation_check_conflict +(const struct sieve_runtime_env *renv, + const struct sieve_action *action ATTR_UNUSED, + const struct sieve_action *other_action, void *context ATTR_UNUSED) +{ + if ( (other_action->flags & SIEVE_ACTFLAG_SENDS_RESPONSE) > 0 ) { + sieve_runtime_error(renv, "'vacation' action conflicts with other action: " + "'%s' action sends a response back to the sender.", + other_action->name); + return -1; + } + + return 0; +} static void act_vacation_print (const struct sieve_action *action ATTR_UNUSED, void *context, @@ -649,8 +677,9 @@ static bool act_vacation_commit } /* Did whe respond to this user before? */ - if (mailenv->duplicate_check(dupl_hash, sizeof(dupl_hash), mailenv->username)) - { + act_vacation_hash(msgdata, ctx, dupl_hash); + if (mailenv->duplicate_check(dupl_hash, sizeof(dupl_hash), mailenv->username)) + { sieve_result_log(aenv, "discarded duplicate vacation response to <%s>", str_sanitize(msgdata->return_path, 80)); return TRUE; diff --git a/src/lib-sieve/sieve-actions.c b/src/lib-sieve/sieve-actions.c index 6590abc89..6f4854683 100644 --- a/src/lib-sieve/sieve-actions.c +++ b/src/lib-sieve/sieve-actions.c @@ -16,6 +16,7 @@ /* * Message transmission (FIXME: place this somewhere more appropriate) */ + const char *sieve_get_new_message_id (const struct sieve_mail_environment *mailenv) { @@ -137,7 +138,7 @@ const struct sieve_side_effect *sieve_opr_side_effect_read /* Store action */ -static bool act_store_check_duplicate +static int act_store_check_duplicate (const struct sieve_runtime_env *renv ATTR_UNUSED, const struct sieve_action *action1 ATTR_UNUSED, void *context1, void *context2); @@ -159,6 +160,7 @@ static void act_store_rollback const struct sieve_action act_store = { "store", + SIEVE_ACTFLAG_TRIES_DELIVER, act_store_check_duplicate, NULL, act_store_print, @@ -168,7 +170,7 @@ const struct sieve_action act_store = { act_store_rollback, }; -bool sieve_act_store_add_to_result +int sieve_act_store_add_to_result (const struct sieve_runtime_env *renv, struct sieve_side_effects_list *seffects, const char *folder) { @@ -185,7 +187,7 @@ bool sieve_act_store_add_to_result /* Store action implementation */ -static bool act_store_check_duplicate +static int act_store_check_duplicate (const struct sieve_runtime_env *renv ATTR_UNUSED, const struct sieve_action *action1 ATTR_UNUSED, void *context1, void *context2) @@ -194,9 +196,9 @@ static bool act_store_check_duplicate struct act_store_context *ctx2 = (struct act_store_context *) context2; if ( strcmp(ctx1->folder, ctx2->folder) == 0 ) - return TRUE; + return 1; - return FALSE; + return 0; } static void act_store_print diff --git a/src/lib-sieve/sieve-actions.h b/src/lib-sieve/sieve-actions.h index 91548f3ae..0717c76af 100644 --- a/src/lib-sieve/sieve-actions.h +++ b/src/lib-sieve/sieve-actions.h @@ -14,16 +14,23 @@ struct sieve_action_exec_env { const struct sieve_mail_environment *mailenv; }; +enum sieve_action_flags { + SIEVE_ACTFLAG_TRIES_DELIVER = (1 << 0), + SIEVE_ACTFLAG_SENDS_RESPONSE = (1 << 1) +}; + struct sieve_action { const char *name; + unsigned int flags; - bool (*check_duplicate) + int (*check_duplicate) (const struct sieve_runtime_env *renv, const struct sieve_action *action, void *context1, void *context2); - bool (*check_conflict) + int (*check_conflict) (const struct sieve_runtime_env *renv, - const struct sieve_action *action1, const struct sieve_action *action2, - void *context1); + const struct sieve_action *action, + const struct sieve_action *other_action, + void *context); void (*print) (const struct sieve_action *action, void *context, bool *keep); @@ -124,7 +131,7 @@ struct act_store_transaction { const char *error; }; -bool sieve_act_store_add_to_result +int sieve_act_store_add_to_result (const struct sieve_runtime_env *renv, struct sieve_side_effects_list *seffects, const char *folder); diff --git a/src/lib-sieve/sieve-commands-private.h b/src/lib-sieve/sieve-commands-private.h index 423a53f1f..085a65011 100644 --- a/src/lib-sieve/sieve-commands-private.h +++ b/src/lib-sieve/sieve-commands-private.h @@ -25,6 +25,11 @@ extern const struct sieve_command tst_not; extern const struct sieve_command tst_anyof; extern const struct sieve_command tst_allof; +/* Core actions */ + +extern const struct sieve_action act_redirect; +extern const struct sieve_action act_store; + /* Lists */ extern const struct sieve_command *sieve_core_commands[]; diff --git a/src/lib-sieve/sieve-interpreter.c b/src/lib-sieve/sieve-interpreter.c index 9bf9b7332..435bbef4b 100644 --- a/src/lib-sieve/sieve-interpreter.c +++ b/src/lib-sieve/sieve-interpreter.c @@ -25,9 +25,12 @@ struct sieve_interpreter { /* Execution status */ - sieve_size_t pc; /* Program counter */ - bool stopped; /* Explicit successful stop requested */ - bool test_result; /* Result of previous test command */ + sieve_size_t pc; /* Program counter */ + bool stopped; /* Explicit successful stop requested */ + bool test_result; /* Result of previous test command */ + + const struct sieve_opcode *current_op; /* Current opcode */ + sieve_size_t current_op_addr; /* Start address of current opcode */ /* Runtime environment environment */ struct sieve_runtime_env runenv; @@ -84,6 +87,41 @@ inline pool_t sieve_interpreter_pool(struct sieve_interpreter *interp) return interp->pool; } +/* Error handling */ + +/* FIXME: Add support to send errors elsewhere */ + +void sieve_runtime_log + (const struct sieve_runtime_env *runenv, const char *fmt, ...) +{ + const char *op = runenv->interp->current_op == NULL ? + "<<NOOP>>" : runenv->interp->current_op->mnemonic; + va_list args; + va_start(args, fmt); + + + /* Kludgy, needs explict support from liblib.a (something like i_vinfo) */ + i_info("%s at #%08x: %s", op, runenv->interp->current_op_addr, + t_strdup_vprintf(fmt, args)); + + va_end(args); +} + +void sieve_runtime_error + (const struct sieve_runtime_env *runenv, const char *fmt, ...) +{ + const char *op = runenv->interp->current_op == NULL ? + "<<NOOP>>" : runenv->interp->current_op->mnemonic; + va_list args; + va_start(args, fmt); + + /* Kludgy, needs explict support from liblib.a (something like i_vinfo) */ + i_error("%s at #%08x: %s", op, runenv->interp->current_op_addr, + t_strdup_vprintf(fmt, args)); + + va_end(args); +} + /* Extension support */ @@ -253,7 +291,10 @@ void sieve_interpreter_dump_code(struct sieve_interpreter *interp) bool sieve_interpreter_execute_operation (struct sieve_interpreter *interp) { - const struct sieve_opcode *opcode = + const struct sieve_opcode *opcode; + + interp->current_op_addr = interp->pc; + interp->current_op = opcode = sieve_operation_read(interp->runenv.sbin, &(interp->pc)); if ( opcode != NULL ) { diff --git a/src/lib-sieve/sieve-interpreter.h b/src/lib-sieve/sieve-interpreter.h index 8f37fb63b..886ac4cfa 100644 --- a/src/lib-sieve/sieve-interpreter.h +++ b/src/lib-sieve/sieve-interpreter.h @@ -39,6 +39,13 @@ inline void sieve_interpreter_set_test_result inline bool sieve_interpreter_get_test_result (struct sieve_interpreter *interp); +/* Error handling */ + +void sieve_runtime_log + (const struct sieve_runtime_env *runenv, const char *fmt, ...); +void sieve_runtime_error + (const struct sieve_runtime_env *runenv, const char *fmt, ...); + /* Extension support */ inline void sieve_interpreter_extension_set_context diff --git a/src/lib-sieve/sieve-result.c b/src/lib-sieve/sieve-result.c index e0afc5fb2..57e2a2025 100644 --- a/src/lib-sieve/sieve-result.c +++ b/src/lib-sieve/sieve-result.c @@ -113,11 +113,12 @@ void sieve_result_error /* Result composition */ -bool sieve_result_add_action +int sieve_result_add_action (const struct sieve_runtime_env *renv, const struct sieve_action *action, struct sieve_side_effects_list *seffects, void *context) { + int ret = 0; struct sieve_result *result = renv->result; struct sieve_result_action *raction; @@ -129,20 +130,20 @@ bool sieve_result_add_action if ( raction->action == action ) { /* Possible duplicate */ if ( action->check_duplicate != NULL ) { - if ( action->check_duplicate - (renv, action, raction->context, context) ) - return FALSE; + if ( (ret=action->check_duplicate + (renv, action, raction->context, context)) != 0 ) + return ret; } else - return FALSE; + return 1; } else { /* Check conflict */ if ( action->check_conflict != NULL && - action->check_conflict(renv, action, oact, context) ) - return FALSE; + (ret=action->check_conflict(renv, action, oact, context)) != 0 ) + return ret; if ( oact->check_conflict != NULL && - oact->check_conflict(renv, oact, action, raction->context) ) - return FALSE; + (ret=oact->check_conflict(renv, oact, action, raction->context)) != 0 ) + return ret; } raction = raction->next; } @@ -169,7 +170,7 @@ bool sieve_result_add_action raction->next = NULL; } - return TRUE; + return 0; } bool sieve_result_print(struct sieve_result *result) diff --git a/src/lib-sieve/sieve-result.h b/src/lib-sieve/sieve-result.h index f982a1ed9..166a4b8bf 100644 --- a/src/lib-sieve/sieve-result.h +++ b/src/lib-sieve/sieve-result.h @@ -17,7 +17,7 @@ void sieve_result_log void sieve_result_error (const struct sieve_action_exec_env *aenv, const char *fmt, ...); -bool sieve_result_add_action +int sieve_result_add_action (const struct sieve_runtime_env *renv, const struct sieve_action *action, struct sieve_side_effects_list *seffects, void *context); -- GitLab