From b18527bd5355257b64b1302971f0a8c5ee8a8a3c Mon Sep 17 00:00:00 2001 From: Stephan Bosch <stephan@rename-it.nl> Date: Wed, 21 Nov 2007 12:26:35 +0100 Subject: [PATCH] Made basic execution implementation of the envelope extension. --- sieve/tests/envelope.sieve | 14 +++ src/lib-sieve/ext-envelope.c | 138 +++++++++++++++++++++------- src/lib-sieve/sieve-address-parts.c | 65 +++++++++++++ src/lib-sieve/sieve-address-parts.h | 17 ++++ src/lib-sieve/sieve.h | 2 +- src/lib-sieve/tst-address.c | 66 ++----------- src/sieve-bin/sieve_test.c | 2 +- 7 files changed, 210 insertions(+), 94 deletions(-) create mode 100644 sieve/tests/envelope.sieve diff --git a/sieve/tests/envelope.sieve b/sieve/tests/envelope.sieve new file mode 100644 index 000000000..4bc2f978c --- /dev/null +++ b/sieve/tests/envelope.sieve @@ -0,0 +1,14 @@ +require "envelope"; + +if envelope :domain "to" "example.com" { + discard; + stop; +} + +if envelope :domain "from" "example.com" { + discard; + stop; +} + +keep; + diff --git a/src/lib-sieve/ext-envelope.c b/src/lib-sieve/ext-envelope.c index 82e5c1e2b..c7ef709f0 100644 --- a/src/lib-sieve/ext-envelope.c +++ b/src/lib-sieve/ext-envelope.c @@ -1,5 +1,8 @@ #include <stdio.h> +#include "lib.h" +#include "array.h" + #include "sieve-extensions.h" #include "sieve-commands.h" #include "sieve-comparators.h" @@ -17,6 +20,8 @@ static bool ext_envelope_validator_load(struct sieve_validator *validator); static bool ext_envelope_opcode_dump (struct sieve_interpreter *interp, struct sieve_binary *sbin, sieve_size_t *address); +static bool ext_envelope_opcode_execute + (struct sieve_interpreter *interp, struct sieve_binary *sbin, sieve_size_t *address); static bool tst_envelope_registered (struct sieve_validator *validator, struct sieve_command_registration *cmd_reg); @@ -30,7 +35,7 @@ static bool tst_envelope_generate static int ext_my_id; const struct sieve_opcode envelope_opcode = - { ext_envelope_opcode_dump, NULL }; + { ext_envelope_opcode_dump, ext_envelope_opcode_execute }; const struct sieve_extension envelope_extension = { "envelope", @@ -65,22 +70,13 @@ static const struct sieve_command envelope_test = { NULL }; -/* Optional arguments */ - -enum tst_envelope_optional { - OPT_END, - OPT_COMPARATOR, - OPT_ADDRESS_PART, - OPT_MATCH_TYPE -}; - /* Command Registration */ static bool tst_envelope_registered(struct sieve_validator *validator, struct sieve_command_registration *cmd_reg) { /* The order of these is not significant */ - sieve_comparators_link_tag(validator, cmd_reg, OPT_COMPARATOR); - sieve_address_parts_link_tags(validator, cmd_reg, OPT_ADDRESS_PART); - sieve_match_types_link_tags(validator, cmd_reg, OPT_MATCH_TYPE); + sieve_comparators_link_tag(validator, cmd_reg, SIEVE_AM_OPT_COMPARATOR); + sieve_address_parts_link_tags(validator, cmd_reg, SIEVE_AM_OPT_ADDRESS_PART); + sieve_match_types_link_tags(validator, cmd_reg, SIEVE_AM_OPT_MATCH_TYPE); return TRUE; } @@ -132,45 +128,117 @@ static bool tst_envelope_generate (void)sieve_generator_emit_opcode_ext(generator, ext_my_id); /* Generate arguments */ - if ( !sieve_generate_arguments(generator, ctx, NULL) ) - return FALSE; + if ( !sieve_generate_arguments(generator, ctx, NULL) ) + return FALSE; return TRUE; } /* - * Code dump + * Code dump */ static bool ext_envelope_opcode_dump (struct sieve_interpreter *interp, struct sieve_binary *sbin, sieve_size_t *address) { - unsigned opt_code; - printf("ENVELOPE\n"); /* Handle any optional arguments */ - if ( sieve_operand_optional_present(sbin, address) ) { - while ( (opt_code=sieve_operand_optional_read(sbin, address)) ) { - switch ( opt_code ) { - case OPT_COMPARATOR: - sieve_opr_comparator_dump(interp, sbin, address); - break; - case OPT_MATCH_TYPE: - sieve_opr_match_type_dump(interp, sbin, address); - break; - case OPT_ADDRESS_PART: - sieve_opr_address_part_dump(interp, sbin, address); - break; - default: - return FALSE; - } - } - } + if ( !sieve_addrmatch_default_dump_optionals(interp, sbin, address) ) + return FALSE; return sieve_opr_stringlist_dump(sbin, address) && sieve_opr_stringlist_dump(sbin, address); } +static int ext_envelope_get_field +(struct sieve_message_data *msgdata, const char *field, + const char *const **value_r) +{ + const char *value; + ARRAY_DEFINE(envelope_values, const char *); + + p_array_init(&envelope_values, pool_datastack_create(), 2); + + if ( strncmp(field, "from", 4) == 0 ) + value = msgdata->return_path; + else if ( strncmp(field, "to", 2) == 0 ) + value = msgdata->to_address; + else if ( strncmp(field, "to", 2) == 0 ) + value = msgdata->auth_user; + + printf("SIZEOF: %d\n", sizeof(value)); + + if ( value != NULL ) + array_append(&envelope_values, &value, 1); + + value = NULL; + array_append(&envelope_values, &value, 1); + *value_r = array_idx(&envelope_values, 0); + + return 0; +} + +static bool ext_envelope_opcode_execute + (struct sieve_interpreter *interp, struct sieve_binary *sbin, sieve_size_t *address) +{ + struct sieve_message_data *msgdata = sieve_interpreter_get_msgdata(interp); + + const struct sieve_comparator *cmp = &i_octet_comparator; + const struct sieve_match_type *mtch = &is_match_type; + const struct sieve_address_part *addrp = &all_address_part; + struct sieve_match_context *mctx; + struct sieve_coded_stringlist *hdr_list; + struct sieve_coded_stringlist *key_list; + string_t *hdr_item; + bool matched; + + printf("?? ENVELOPE\n"); + + if ( !sieve_addrmatch_default_get_optionals + (interp, sbin, address, &addrp, &mtch, &cmp) ) + return FALSE; + + t_push(); + + /* Read header-list */ + if ( (hdr_list=sieve_opr_stringlist_read(sbin, address)) == NULL ) { + t_pop(); + return FALSE; + } + + /* Read key-list */ + if ( (key_list=sieve_opr_stringlist_read(sbin, address)) == NULL ) { + t_pop(); + return FALSE; + } + + /* Initialize match context */ + mctx = sieve_match_begin(mtch, cmp, key_list); + + /* Iterate through all requested headers to match */ + hdr_item = NULL; + matched = FALSE; + while ( !matched && sieve_coded_stringlist_next_item(hdr_list, &hdr_item) && hdr_item != NULL ) { + const char *const *fields; + + if ( ext_envelope_get_field(msgdata, str_c(hdr_item), &fields) >= 0 ) { + + int i; + for ( i = 0; !matched && fields[i] != NULL; i++ ) { + if ( sieve_address_match(addrp, mctx, fields[i]) ) + matched = TRUE; + } + } + } + + matched = sieve_match_end(mctx) || matched; + + t_pop(); + + sieve_interpreter_set_test_result(interp, matched); + + return TRUE; +} diff --git a/src/lib-sieve/sieve-address-parts.c b/src/lib-sieve/sieve-address-parts.c index 7a5acd1e3..abe288140 100644 --- a/src/lib-sieve/sieve-address-parts.c +++ b/src/lib-sieve/sieve-address-parts.c @@ -404,6 +404,71 @@ bool sieve_address_match return matched; } +/* + * Default ADDRESS-PART, MATCH-TYPE, COMPARATOR access + */ + +bool sieve_addrmatch_default_dump_optionals +(struct sieve_interpreter *interp, + struct sieve_binary *sbin, sieve_size_t *address) +{ + unsigned int opt_code; + + if ( sieve_operand_optional_present(sbin, address) ) { + while ( (opt_code=sieve_operand_optional_read(sbin, address)) ) { + switch ( opt_code ) { + case SIEVE_AM_OPT_COMPARATOR: + if ( !sieve_opr_comparator_dump(interp, sbin, address) ) + return FALSE; + break; + case SIEVE_AM_OPT_MATCH_TYPE: + if ( !sieve_opr_match_type_dump(interp, sbin, address) ) + return FALSE; + break; + case SIEVE_AM_OPT_ADDRESS_PART: + if ( !sieve_opr_address_part_dump(interp, sbin, address) ) + return FALSE; + break; + default: + return FALSE; + } + } + } + + return TRUE; +} + +bool sieve_addrmatch_default_get_optionals +(struct sieve_interpreter *interp, struct sieve_binary *sbin, + sieve_size_t *address, const struct sieve_address_part **addrp, + const struct sieve_match_type **mtch, const struct sieve_comparator **cmp) +{ + unsigned int opt_code; + + if ( sieve_operand_optional_present(sbin, address) ) { + while ( (opt_code=sieve_operand_optional_read(sbin, address)) ) { + switch ( opt_code ) { + case SIEVE_AM_OPT_COMPARATOR: + if ( (*cmp = sieve_opr_comparator_read(interp, sbin, address)) == NULL ) + return FALSE; + break; + case SIEVE_AM_OPT_MATCH_TYPE: + if ( (*mtch = sieve_opr_match_type_read(interp, sbin, address)) == NULL ) + return FALSE; + break; + case SIEVE_AM_OPT_ADDRESS_PART: + if ( (*addrp = sieve_opr_address_part_read(interp, sbin, address)) == NULL ) + return FALSE; + break; + default: + return FALSE; + } + } + } + + return TRUE; +} + /* * Core address-part modifiers */ diff --git a/src/lib-sieve/sieve-address-parts.h b/src/lib-sieve/sieve-address-parts.h index 5fe765bfd..728023138 100644 --- a/src/lib-sieve/sieve-address-parts.h +++ b/src/lib-sieve/sieve-address-parts.h @@ -67,8 +67,25 @@ bool sieve_opr_address_part_dump (struct sieve_interpreter *interpreter, struct sieve_binary *sbin, sieve_size_t *address); +/* Match utility */ + bool sieve_address_match (const struct sieve_address_part *addrp, struct sieve_match_context *mctx, const char *data); +enum sieve_addrmatch_opt_operand { + SIEVE_AM_OPT_END, + SIEVE_AM_OPT_COMPARATOR, + SIEVE_AM_OPT_ADDRESS_PART, + SIEVE_AM_OPT_MATCH_TYPE +}; + +bool sieve_addrmatch_default_dump_optionals +(struct sieve_interpreter *interp, + struct sieve_binary *sbin, sieve_size_t *address); +bool sieve_addrmatch_default_get_optionals + (struct sieve_interpreter *interp, struct sieve_binary *sbin, + sieve_size_t *address, const struct sieve_address_part **addp, + const struct sieve_match_type **mtch, const struct sieve_comparator **cmp); + #endif /* __SIEVE_ADDRESS_PARTS_H */ diff --git a/src/lib-sieve/sieve.h b/src/lib-sieve/sieve.h index e7b10fcbb..beb591927 100644 --- a/src/lib-sieve/sieve.h +++ b/src/lib-sieve/sieve.h @@ -9,7 +9,7 @@ struct sieve_binary; struct sieve_message_data { struct mail *mail; const char *return_path; - const char *rcpt_address; + const char *to_address; const char *auth_user; }; diff --git a/src/lib-sieve/tst-address.c b/src/lib-sieve/tst-address.c index d0aef5d48..044acd142 100644 --- a/src/lib-sieve/tst-address.c +++ b/src/lib-sieve/tst-address.c @@ -46,24 +46,15 @@ const struct sieve_command tst_address = { NULL }; -/* Optional arguments */ - -enum tst_address_optional { - OPT_END, - OPT_COMPARATOR, - OPT_ADDRESS_PART, - OPT_MATCH_TYPE -}; - /* Test registration */ static bool tst_address_registered (struct sieve_validator *validator, struct sieve_command_registration *cmd_reg) { /* The order of these is not significant */ - sieve_comparators_link_tag(validator, cmd_reg, OPT_COMPARATOR ); - sieve_address_parts_link_tags(validator, cmd_reg, OPT_ADDRESS_PART); - sieve_match_types_link_tags(validator, cmd_reg, OPT_MATCH_TYPE); + sieve_comparators_link_tag(validator, cmd_reg, SIEVE_AM_OPT_COMPARATOR ); + sieve_address_parts_link_tags(validator, cmd_reg, SIEVE_AM_OPT_ADDRESS_PART); + sieve_match_types_link_tags(validator, cmd_reg, SIEVE_AM_OPT_MATCH_TYPE); return TRUE; } @@ -115,31 +106,11 @@ static bool tst_address_opcode_dump (struct sieve_interpreter *interp, struct sieve_binary *sbin, sieve_size_t *address) { - unsigned int opt_code; - printf("ADDRESS\n"); - /* Handle any optional arguments */ - if ( sieve_operand_optional_present(sbin, address) ) { - while ( (opt_code=sieve_operand_optional_read(sbin, address)) ) { - switch ( opt_code ) { - case OPT_COMPARATOR: - if ( !sieve_opr_comparator_dump(interp, sbin, address) ) - return FALSE; - break; - case OPT_MATCH_TYPE: - if ( !sieve_opr_match_type_dump(interp, sbin, address) ) - return FALSE; - break; - case OPT_ADDRESS_PART: - if ( !sieve_opr_address_part_dump(interp, sbin, address) ) - return FALSE; - break; - default: - return FALSE; - } - } - } + //* Handle any optional arguments */ + if ( !sieve_addrmatch_default_dump_optionals(interp, sbin, address) ) + return FALSE; return sieve_opr_stringlist_dump(sbin, address) && @@ -156,7 +127,6 @@ static bool tst_address_opcode_execute const struct sieve_comparator *cmp = &i_octet_comparator; const struct sieve_match_type *mtch = &is_match_type; const struct sieve_address_part *addrp = &all_address_part; - unsigned int opt_code; struct sieve_match_context *mctx; struct sieve_coded_stringlist *hdr_list; struct sieve_coded_stringlist *key_list; @@ -165,27 +135,9 @@ static bool tst_address_opcode_execute printf("?? ADDRESS\n"); - /* Handle any optional arguments */ - if ( sieve_operand_optional_present(sbin, address) ) { - while ( (opt_code=sieve_operand_optional_read(sbin, address)) ) { - switch ( opt_code ) { - case OPT_COMPARATOR: - if ( (cmp = sieve_opr_comparator_read(interp, sbin, address)) == NULL ) - return FALSE; - break; - case OPT_MATCH_TYPE: - if ( (mtch = sieve_opr_match_type_read(interp, sbin, address)) == NULL ) - return FALSE; - break; - case OPT_ADDRESS_PART: - if ( (addrp = sieve_opr_address_part_read(interp, sbin, address)) == NULL ) - return FALSE; - break; - default: - return FALSE; - } - } - } + if ( !sieve_addrmatch_default_get_optionals + (interp, sbin, address, &addrp, &mtch, &cmp) ) + return FALSE; t_push(); diff --git a/src/sieve-bin/sieve_test.c b/src/sieve-bin/sieve_test.c index 83498fe5b..c6ed48bef 100644 --- a/src/sieve-bin/sieve_test.c +++ b/src/sieve-bin/sieve_test.c @@ -237,7 +237,7 @@ int main(int argc, char **argv) msgdata.mail = mail; msgdata.return_path = "nico@example.com"; - msgdata.rcpt_address = "sirius+sieve@rename-it.nl"; + msgdata.to_address = "sirius+sieve@rename-it.nl"; msgdata.auth_user = "stephan"; sieve_test(sbin, &msgdata); -- GitLab