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 void sieve_index_stringlist_set_trace (struct sieve_stringlist *_strlist, bool trace) { struct sieve_index_stringlist *strlist = (struct sieve_index_stringlist *)_strlist; sieve_stringlist_set_trace(strlist->source, trace); }
int sieve_match (const struct sieve_runtime_env *renv, const struct sieve_match_type *mcht, const struct sieve_comparator *cmp, struct sieve_stringlist *value_list, struct sieve_stringlist *key_list, int *exec_status) { struct sieve_match_context *mctx; string_t *value_item = NULL; int match, ret; if ( (mctx=sieve_match_begin(renv, mcht, cmp)) == NULL ) return 0; /* Match value to keys */ sieve_stringlist_reset(value_list); if ( mctx->trace ) sieve_stringlist_set_trace(value_list, TRUE); if ( mcht->def->match != NULL ) { /* Call match-type's match handler */ match = mctx->match_status = mcht->def->match(mctx, value_list, key_list); } else { /* Default value match loop */ match = 0; while ( match == 0 && (ret=sieve_stringlist_next_item(value_list, &value_item)) > 0 ) { match = sieve_match_value (mctx, str_c(value_item), str_len(value_item), key_list); } if ( ret < 0 ) { mctx->exec_status = value_list->exec_status; match = -1; } } (void)sieve_match_end(&mctx, exec_status); return match; }