1
/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
6
#include "sieve-common.h"
7
#include "sieve-commands.h"
8
#include "sieve-code.h"
9
#include "sieve-comparators.h"
10
#include "sieve-match-types.h"
11
#include "sieve-validator.h"
12
#include "sieve-generator.h"
13
#include "sieve-interpreter.h"
14
#include "sieve-dump.h"
15
#include "sieve-match.h"
17
#include "ext-enotify-common.h"
23
* notify_method_capability [COMPARATOR] [MATCH-TYPE]
24
* <notification-uri: string>
25
* <notification-capability: string>
26
* <key-list: string-list>
29
static bool tst_notifymc_registered
30
(struct sieve_validator *validator, struct sieve_command_registration *cmd_reg);
31
static bool tst_notifymc_validate
32
(struct sieve_validator *validator, struct sieve_command_context *tst);
33
static bool tst_notifymc_generate
34
(const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx);
36
const struct sieve_command notify_method_capability_test = {
37
"notify_method_capability",
40
tst_notifymc_registered,
42
tst_notifymc_validate,
43
tst_notifymc_generate,
51
static bool tst_notifymc_operation_dump
52
(const struct sieve_operation *op,
53
const struct sieve_dumptime_env *denv, sieve_size_t *address);
54
static int tst_notifymc_operation_execute
55
(const struct sieve_operation *op,
56
const struct sieve_runtime_env *renv, sieve_size_t *address);
58
const struct sieve_operation notify_method_capability_operation = {
59
"NOTIFY_METHOD_CAPABILITY",
61
EXT_ENOTIFY_OPERATION_NOTIFY_METHOD_CAPABILITY,
62
tst_notifymc_operation_dump,
63
tst_notifymc_operation_execute
70
enum tst_notifymc_optional {
80
static bool tst_notifymc_registered
81
(struct sieve_validator *validator, struct sieve_command_registration *cmd_reg)
83
/* The order of these is not significant */
84
sieve_comparators_link_tag(validator, cmd_reg, OPT_COMPARATOR);
85
sieve_match_types_link_tags(validator, cmd_reg, OPT_MATCH_TYPE);
94
static bool tst_notifymc_validate
95
(struct sieve_validator *validator, struct sieve_command_context *tst)
97
struct sieve_ast_argument *arg = tst->first_positional;
99
if ( !sieve_validate_positional_argument
100
(validator, tst, arg, "notification-uri", 1, SAAT_STRING) ) {
104
if ( !sieve_validator_argument_activate(validator, tst, arg, FALSE) )
107
arg = sieve_ast_argument_next(arg);
109
if ( !sieve_validate_positional_argument
110
(validator, tst, arg, "notification-capability", 2, SAAT_STRING) ) {
114
if ( !sieve_validator_argument_activate(validator, tst, arg, FALSE) )
117
arg = sieve_ast_argument_next(arg);
119
if ( !sieve_validate_positional_argument
120
(validator, tst, arg, "key-list", 3, SAAT_STRING_LIST) ) {
124
if ( !sieve_validator_argument_activate(validator, tst, arg, FALSE) )
127
/* Validate the key argument to a specified match type */
128
return sieve_match_type_validate
129
(validator, tst, arg, &is_match_type, &i_ascii_casemap_comparator);
136
static bool tst_notifymc_generate
137
(const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx)
139
sieve_operation_emit_code(cgenv->sbin, ¬ify_method_capability_operation);
141
/* Generate arguments */
142
return sieve_generate_arguments(cgenv, ctx, NULL);
149
static bool tst_notifymc_operation_dump
150
(const struct sieve_operation *op ATTR_UNUSED,
151
const struct sieve_dumptime_env *denv, sieve_size_t *address)
155
sieve_code_dumpf(denv, "NOTIFY_METHOD_CAPABILITY");
156
sieve_code_descend(denv);
158
/* Handle any optional arguments */
159
if ( !sieve_match_dump_optional_operands(denv, address, &opt_code) )
162
if ( opt_code != SIEVE_MATCH_OPT_END )
166
sieve_opr_string_dump(denv, address, "notify uri") &&
167
sieve_opr_string_dump(denv, address, "notify capability") &&
168
sieve_opr_stringlist_dump(denv, address, "key list");
175
static int tst_notifymc_operation_execute
176
(const struct sieve_operation *op ATTR_UNUSED,
177
const struct sieve_runtime_env *renv, sieve_size_t *address)
182
const struct sieve_comparator *cmp = &i_octet_comparator;
183
const struct sieve_match_type *mtch = &is_match_type;
184
struct sieve_match_context *mctx;
185
string_t *notify_uri, *notify_capability;
186
struct sieve_coded_stringlist *key_list;
187
const char *cap_value;
194
/* Handle match-type and comparator operands */
195
if ( (ret=sieve_match_read_optional_operands
196
(renv, address, &opt_code, &cmp, &mtch)) <= 0 )
199
/* Check whether we neatly finished the list of optional operands */
200
if ( opt_code != SIEVE_MATCH_OPT_END) {
201
sieve_runtime_trace_error(renv, "invalid optional operand");
202
return SIEVE_EXEC_BIN_CORRUPT;
205
/* Read notify uri */
206
if ( !sieve_opr_string_read(renv, address, ¬ify_uri) ) {
207
sieve_runtime_trace_error(renv, "invalid notify-uri operand");
208
return SIEVE_EXEC_BIN_CORRUPT;
211
/* Read notify capability */
212
if ( !sieve_opr_string_read(renv, address, ¬ify_capability) ) {
213
sieve_runtime_trace_error(renv, "invalid notify-uri operand");
214
return SIEVE_EXEC_BIN_CORRUPT;
218
if ( (key_list=sieve_opr_stringlist_read(renv, address)) == NULL ) {
219
sieve_runtime_trace_error(renv, "invalid key-list operand");
220
return SIEVE_EXEC_BIN_CORRUPT;
227
sieve_runtime_trace(renv, "NOTIFY_METHOD_CAPABILITY test");
229
cap_value = ext_enotify_runtime_get_method_capability
230
(renv, 0 /* FIXME */, notify_uri, str_c(notify_capability));
232
if ( cap_value != NULL ) {
233
mctx = sieve_match_begin(renv->interp, mtch, cmp, NULL, key_list);
235
if ( (mret=sieve_match_value(mctx, cap_value, strlen(cap_value))) < 0 )
237
matched = ( mret > 0 );
239
if ( (mret=sieve_match_end(&mctx)) < 0 )
241
matched = ( mret > 0 ) || matched;
247
sieve_interpreter_set_test_result(renv->interp, matched);
248
return SIEVE_EXEC_OK;
251
sieve_runtime_trace_error(renv, "invalid string list item");
252
return SIEVE_EXEC_BIN_CORRUPT;