From d88b39dcab82935548b03052c96198d35bdaf6a1 Mon Sep 17 00:00:00 2001 From: Stephan Bosch <stephan@rename-it.nl> Date: Sun, 19 Jul 2009 23:18:34 +0200 Subject: [PATCH] Added compilation support for ereject extension. It is unfinished right now and performs exactly the same action as reject. --- src/lib-sieve/ext-reject.c | 156 ++++++++++++++++++++++--------- src/lib-sieve/sieve-extensions.c | 10 +- 2 files changed, 123 insertions(+), 43 deletions(-) diff --git a/src/lib-sieve/ext-reject.c b/src/lib-sieve/ext-reject.c index cbaf09075..a08ebfcf7 100644 --- a/src/lib-sieve/ext-reject.c +++ b/src/lib-sieve/ext-reject.c @@ -5,9 +5,9 @@ * ---------------- * * Authors: Stephan Bosch - * Specification: RFC5228, draft-ietf-sieve-refuse-reject-04 + * Specification: RFC5429 * Implementation: full - * Status: experimental, largely untested + * Status: experimental * */ @@ -41,20 +41,24 @@ */ static const struct sieve_command reject_command; -struct sieve_operation reject_operation; -struct sieve_extension reject_extension; +static const struct sieve_operation reject_operation; + +static const struct sieve_command ereject_command; +static const struct sieve_operation ereject_operation; /* - * Extension + * Extensions */ +/* Reject */ + static bool ext_reject_validator_load(struct sieve_validator *validator); -static int ext_my_id = -1; +static int ext_reject_my_id = -1; -struct sieve_extension reject_extension = { +const struct sieve_extension reject_extension = { "reject", - &ext_my_id, + &ext_reject_my_id, NULL, NULL, ext_reject_validator_load, NULL, NULL, NULL, NULL, NULL, @@ -70,18 +74,47 @@ static bool ext_reject_validator_load(struct sieve_validator *validator) return TRUE; } +/* EReject */ + +static bool ext_ereject_validator_load(struct sieve_validator *validator); + +static int ext_ereject_my_id = -1; + +const struct sieve_extension ereject_extension = { + "ereject", + &ext_ereject_my_id, + NULL, NULL, + ext_ereject_validator_load, + NULL, NULL, NULL, NULL, NULL, + SIEVE_EXT_DEFINE_OPERATION(ereject_operation), + SIEVE_EXT_DEFINE_NO_OPERANDS +}; + +static bool ext_ereject_validator_load(struct sieve_validator *validator) +{ + /* Register new command */ + sieve_validator_register_command(validator, &ereject_command); + + return TRUE; +} + /* - * Reject command - * - * Syntax: - * reject <reason: string> + * Commands */ +/* Forward declarations */ + static bool cmd_reject_validate (struct sieve_validator *validator, struct sieve_command_context *cmd); static bool cmd_reject_generate (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx); +/* Reject command + * + * Syntax: + * reject <reason: string> + */ + static const struct sieve_command reject_command = { "reject", SCT_COMMAND, @@ -92,10 +125,28 @@ static const struct sieve_command reject_command = { NULL }; -/* - * Reject operation +/* EReject command + * + * Syntax: + * ereject <reason: string> */ +static const struct sieve_command ereject_command = { + "ereject", + SCT_COMMAND, + 1, 0, FALSE, FALSE, + NULL, NULL, + cmd_reject_validate, + cmd_reject_generate, + NULL +}; + +/* + * Operations + */ + +/* Forward declarations */ + static bool ext_reject_operation_dump (const struct sieve_operation *op, const struct sieve_dumptime_env *denv, sieve_size_t *address); @@ -103,7 +154,9 @@ static int ext_reject_operation_execute (const struct sieve_operation *op, const struct sieve_runtime_env *renv, sieve_size_t *address); -struct sieve_operation reject_operation = { +/* Reject operation */ + +static const struct sieve_operation reject_operation = { "REJECT", &reject_extension, 0, @@ -111,6 +164,16 @@ struct sieve_operation reject_operation = { ext_reject_operation_execute }; +/* EReject operation */ + +static const struct sieve_operation ereject_operation = { + "EREJECT", + &ereject_extension, + 0, + ext_reject_operation_dump, + ext_reject_operation_execute +}; + /* * Reject action */ @@ -144,6 +207,7 @@ const struct sieve_action act_reject = { struct act_reject_context { const char *reason; + bool ereject; }; /* @@ -170,7 +234,10 @@ static bool cmd_reject_validate static bool cmd_reject_generate (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx) { - sieve_operation_emit_code(cgenv->sbin, &reject_operation); + if ( ctx->command == &reject_command ) + sieve_operation_emit_code(cgenv->sbin, &reject_operation); + else + sieve_operation_emit_code(cgenv->sbin, &ereject_operation); /* Emit line number */ sieve_code_source_line_emit(cgenv->sbin, sieve_command_source_line(ctx)); @@ -184,10 +251,10 @@ static bool cmd_reject_generate */ static bool ext_reject_operation_dump -(const struct sieve_operation *op ATTR_UNUSED, +(const struct sieve_operation *op, const struct sieve_dumptime_env *denv, sieve_size_t *address) { - sieve_code_dumpf(denv, "REJECT"); + sieve_code_dumpf(denv, "%s", op->mnemonic); sieve_code_descend(denv); /* Source line */ @@ -197,8 +264,7 @@ static bool ext_reject_operation_dump if ( !sieve_code_dumper_print_optional_operands(denv, address) ) return FALSE; - return - sieve_opr_string_dump(denv, address, "reason"); + return sieve_opr_string_dump(denv, address, "reason"); } /* @@ -206,7 +272,7 @@ static bool ext_reject_operation_dump */ static int ext_reject_operation_execute -(const struct sieve_operation *op ATTR_UNUSED, +(const struct sieve_operation *op, const struct sieve_runtime_env *renv, sieve_size_t *address) { struct sieve_side_effects_list *slist = NULL; @@ -233,12 +299,13 @@ static int ext_reject_operation_execute return SIEVE_EXEC_BIN_CORRUPT; } - sieve_runtime_trace(renv, "REJECT action (\"%s\")", str_sanitize(str_c(reason), 64)); + sieve_runtime_trace(renv, "%s action (\"%s\")", op->mnemonic, str_sanitize(str_c(reason), 64)); /* Add reject action to the result */ pool = sieve_result_pool(renv->result); act = p_new(pool, struct act_reject_context, 1); act->reason = p_strdup(pool, str_c(reason)); + act->ereject = ( op == &ereject_operation ); ret = sieve_result_add_action (renv, &act_reject, slist, source_line, (void *) act, 0); @@ -257,7 +324,7 @@ static int act_reject_check_duplicate { if ( !act_other->executed ) { sieve_runtime_error(renv, act->location, - "duplicate reject action not allowed " + "duplicate reject/ereject action not allowed " "(previously triggered one was here: %s)", act_other->location); return -1; } @@ -273,7 +340,7 @@ int act_reject_check_conflict if ( (act_other->action->flags & SIEVE_ACTFLAG_TRIES_DELIVER) > 0 ) { if ( !act_other->executed ) { sieve_runtime_error(renv, act->location, - "reject action conflicts with other action: " + "reject/ereject action conflicts with other action: " "the %s action (%s) tries to deliver the message", act_other->action->name, act_other->location); return -1; @@ -285,12 +352,15 @@ int act_reject_check_conflict if ( !act_other->executed ) { sieve_runtime_error(renv, act->location, - "reject action conflicts with other action: " + "reject/ereject action conflicts with other action: " "the %s action (%s) also sends a response to the sender", act_other->action->name, act_other->location); return -1; } + /* Conflicting action was already executed, transform reject into discard + * equivalent. + */ rj_ctx = (struct act_reject_context *) act->context; rj_ctx->reason = NULL; } @@ -386,23 +456,24 @@ static bool act_reject_send fprintf(f, "--%s\r\nContent-Type: message/rfc822\r\n\r\n", boundary); 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 - MIME parsers when they don't see the message boundaries. */ - static const char *const exclude_headers[] = { - "Content-Type" - }; - - input = i_stream_create_header_filter(input, - HEADER_FILTER_EXCLUDE | HEADER_FILTER_NO_CR | HEADER_FILTER_HIDE_BODY, - exclude_headers, N_ELEMENTS(exclude_headers), - null_header_filter_callback, NULL); + /* 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 + * MIME parsers when they don't see the message boundaries. + */ + static const char *const exclude_headers[] = { + "Content-Type" + }; + + input = i_stream_create_header_filter(input, + HEADER_FILTER_EXCLUDE | HEADER_FILTER_NO_CR | HEADER_FILTER_HIDE_BODY, + exclude_headers, N_ELEMENTS(exclude_headers), + null_header_filter_callback, NULL); while ((ret = i_stream_read_data(input, &data, &size, 0)) > 0) { if (fwrite(data, size, 1, f) == 0) break; - i_stream_skip(input, size); + i_stream_skip(input, size); } i_stream_unref(&input); @@ -430,22 +501,23 @@ static bool act_reject_commit struct act_reject_context *rj_ctx = (struct act_reject_context *) tr_context; if ( rj_ctx->reason == NULL ) { - sieve_result_log(aenv, "discarded reject (would cause second response to sender)"); + sieve_result_log(aenv, "not sending reject message (would cause second response to sender)"); *keep = FALSE; return TRUE; } if ( msgdata->return_path == NULL || *(msgdata->return_path) == '\0' ) { - sieve_result_log(aenv, "discarded reject to <>"); + sieve_result_log(aenv, "not sending reject message to <>"); *keep = FALSE; return TRUE; } if ( act_reject_send(aenv, rj_ctx) ) { - sieve_result_log(aenv, "rejected message from <%s>", - str_sanitize(msgdata->return_path, 80)); + sieve_result_log(aenv, "rejected message from <%s> (%s)", + str_sanitize(msgdata->return_path, 80), + ( rj_ctx->ereject ? "ereject" : "reject" )); *keep = FALSE; return TRUE; diff --git a/src/lib-sieve/sieve-extensions.c b/src/lib-sieve/sieve-extensions.c index bb3cfffc5..368fb6caa 100644 --- a/src/lib-sieve/sieve-extensions.c +++ b/src/lib-sieve/sieve-extensions.c @@ -85,7 +85,11 @@ extern const struct sieve_extension environment_extension; * Extensions under development */ -// None +#ifdef HAVE_SIEVE_UNFINISHED + +extern const struct sieve_extension ereject_extension; + +#endif /* * List of native extensions @@ -103,6 +107,10 @@ const struct sieve_extension *sieve_core_extensions[] = { &encoded_character_extension, /* Extensions under development */ + +#ifdef HAVE_SIEVE_UNFINISHED + &ereject_extension, +#endif /* 'Plugins' */ &vacation_extension, &subaddress_extension, -- GitLab