int sieve_match_value (struct sieve_match_context *mctx, const char *value, size_t value_size, struct sieve_stringlist *key_list) { const struct sieve_match_type *mcht = mctx->match_type; const struct sieve_runtime_env *renv = mctx->runenv; int match, ret; if ( mctx->trace ) { sieve_runtime_trace(renv, 0, "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 */ match = mcht->def->match_keys(mctx, value, value_size, key_list); } else { string_t *key_item = NULL; /* Default key match loop */ match = 0; while ( match == 0 && (ret=sieve_stringlist_next_item(key_list, &key_item)) > 0 ) { T_BEGIN { match = mcht->def->match_key (mctx, value, value_size, str_c(key_item), str_len(key_item)); if ( mctx->trace ) { sieve_runtime_trace(renv, 0, "with key `%s' => %d", str_sanitize(str_c(key_item), 80), match); } } T_END; } if ( ret < 0 ) { mctx->exec_status = key_list->exec_status; match = -1; } } sieve_runtime_trace_ascend(renv); if ( mctx->match_status < 0 || match < 0 ) mctx->match_status = -1; else mctx->match_status = ( mctx->match_status > match ? mctx->match_status : match ); return match; }
static int mcht_count_match (struct sieve_match_context *mctx, struct sieve_stringlist *value_list, struct sieve_stringlist *key_list) { const struct sieve_runtime_env *renv = mctx->runenv; bool trace = sieve_runtime_trace_active(renv, SIEVE_TRLVL_MATCHING); int count; string_t *key_item; int match, ret; if ( (count=sieve_stringlist_get_length(value_list)) < 0 ) { mctx->exec_status = value_list->exec_status; return -1; } sieve_stringlist_reset(key_list); string_t *value = t_str_new(20); str_printfa(value, "%d", count); if ( trace ) { sieve_runtime_trace(renv, 0, "matching count value `%s'", str_sanitize(str_c(value), 80)); } sieve_runtime_trace_descend(renv); /* Match to all key values */ key_item = NULL; match = 0; while ( match == 0 && (ret=sieve_stringlist_next_item(key_list, &key_item)) > 0 ) { match = mcht_value_match_key (mctx, str_c(value), str_len(value), str_c(key_item), str_len(key_item)); if ( trace ) { sieve_runtime_trace(renv, 0, "with key `%s' => %d", str_sanitize(str_c(key_item), 80), ret); } } sieve_runtime_trace_ascend(renv); if ( ret < 0 ) { mctx->exec_status = key_list->exec_status; match = -1; } return match; }
int sieve_match_end(struct sieve_match_context **mctx, int *exec_status) { const struct sieve_match_type *mcht = (*mctx)->match_type; const struct sieve_runtime_env *renv = (*mctx)->runenv; int match = (*mctx)->match_status; if ( mcht->def != NULL && mcht->def->match_deinit != NULL ) mcht->def->match_deinit(*mctx); if ( exec_status != NULL ) *exec_status = (*mctx)->exec_status; pool_unref(&(*mctx)->pool); sieve_runtime_trace(renv, SIEVE_TRLVL_MATCHING, "finishing match with result: %s", ( match > 0 ? "matched" : ( match < 0 ? "error" : "not matched" ) )); sieve_runtime_trace_ascend(renv); return match; }
static int tst_spamvirustest_operation_execute (const struct sieve_runtime_env *renv, sieve_size_t *address) { const struct sieve_operation *op = renv->oprtn; const struct sieve_extension *this_ext = op->ext; int opt_code = 0; struct sieve_match_type mcht = SIEVE_MATCH_TYPE_DEFAULT(is_match_type); struct sieve_comparator cmp = SIEVE_COMPARATOR_DEFAULT(i_ascii_casemap_comparator); bool percent = FALSE; struct sieve_stringlist *value_list, *key_list; const char *score_value; int match, ret; /* Read optional operands */ for (;;) { int opt; if ( (opt=sieve_match_opr_optional_read (renv, address, &opt_code, &ret, &cmp, &mcht)) < 0 ) return ret; if ( opt == 0 ) break; switch ( opt_code ) { case OPT_SPAMTEST_PERCENT: percent = TRUE; break; default: sieve_runtime_trace_error(renv, "unknown optional operand"); return SIEVE_EXEC_BIN_CORRUPT; } } /* Read value part */ if ( (ret=sieve_opr_stringlist_read(renv, address, "value", &key_list)) <= 0 ) return ret; /* Perform test */ if ( sieve_operation_is(op, spamtest_operation) ) { sieve_runtime_trace (renv, SIEVE_TRLVL_TESTS, "spamtest test [percent=%s]", ( percent ? "true" : "false" )); } else { sieve_runtime_trace (renv, SIEVE_TRLVL_TESTS, "virustest test"); } /* Get score value */ sieve_runtime_trace_descend(renv); if ( (ret=ext_spamvirustest_get_value (renv, this_ext, percent, &score_value)) <= 0 ) return ret; sieve_runtime_trace_ascend(renv); /* Construct value list */ value_list = sieve_single_stringlist_create_cstr(renv, score_value, TRUE); /* Perform match */ if ( (match=sieve_match(renv, &mcht, &cmp, value_list, key_list, &ret)) < 0 ) return ret; /* Set test result for subsequent conditional jump */ sieve_interpreter_set_test_result(renv->interp, match > 0); return SIEVE_EXEC_OK; }