1
/* Copyright (c) 2002-2011 Pigeonhole authors, see the included COPYING file
7
#include "sieve-common.h"
8
#include "sieve-extensions.h"
9
#include "sieve-commands.h"
10
#include "sieve-validator.h"
11
#include "sieve-generator.h"
13
#include "ext-ihave-common.h"
19
* ihave <capabilities: string-list>
22
static bool tst_ihave_validate
23
(struct sieve_validator *valdtr, struct sieve_command *tst);
24
static bool tst_ihave_validate_const
25
(struct sieve_validator *valdtr, struct sieve_command *tst,
26
int *const_current, int const_next);
28
const struct sieve_command_def ihave_test = {
34
tst_ihave_validate_const,
42
static bool tst_ihave_validate
43
(struct sieve_validator *valdtr, struct sieve_command *tst)
46
const struct sieve_extension *ext;
47
struct sieve_ast_argument *arg;
50
struct sieve_ast_argument *arg = tst->first_positional;
51
struct sieve_ast_argument *stritem;
52
ARRAY_DEFINE(capabilities, struct _capability);
53
struct _capability capability;
54
const struct _capability *caps;
55
unsigned int i, count;
56
bool all_known = TRUE;
58
t_array_init(&capabilities, 64);
60
tst->data = (void *) FALSE;
62
/* Check stringlist argument */
63
if ( !sieve_validate_positional_argument
64
(valdtr, tst, arg, "capabilities", 1, SAAT_STRING_LIST) ) {
68
switch ( sieve_ast_argument_type(arg) ) {
72
capability.ext = sieve_extension_get_by_name
73
(tst->ext->svinst, sieve_ast_argument_strc(arg));
74
array_append(&capabilities, &capability, 1);
76
if ( capability.ext == NULL ) {
79
ext_ihave_ast_add_missing_extension
80
(tst->ext, tst->ast_node->ast, sieve_ast_argument_strc(arg));
85
case SAAT_STRING_LIST:
87
stritem = sieve_ast_strlist_first(arg);
89
while ( stritem != NULL ) {
90
capability.arg = stritem;
91
capability.ext = sieve_extension_get_by_name
92
(tst->ext->svinst, sieve_ast_argument_strc(stritem));
93
array_append(&capabilities, &capability, 1);
95
if ( capability.ext == NULL ) {
98
ext_ihave_ast_add_missing_extension
99
(tst->ext, tst->ast_node->ast, sieve_ast_argument_strc(stritem));
102
stritem = sieve_ast_strlist_next(stritem);
113
/* RFC 5463, Section 4, page 4:
115
* The "ihave" extension is designed to be used with other extensions
116
* that add tests, actions, comparators, or arguments. Implementations
117
* MUST NOT allow it to be used with extensions that change the
118
* underlying Sieve grammar, or extensions like encoded-character
119
* [RFC5228], or variables [RFC5229] that change how the content of
120
* Sieve scripts are interpreted. The test MUST fail and the extension
121
* MUST NOT be enabled if such usage is attempted.
123
* FIXME: current implementation of this restriction is hardcoded and
124
* therefore highly inflexible
126
caps = array_get(&capabilities, &count);
127
for ( i = 0; i < count; i++ ) {
128
if ( sieve_extension_name_is(caps[i].ext, "variables") ||
129
sieve_extension_name_is(caps[i].ext, "encoded-character") )
133
/* Load all extensions */
134
caps = array_get(&capabilities, &count);
135
for ( i = 0; i < count; i++ ) {
136
if ( !sieve_validator_extension_load
137
(valdtr, tst, caps[i].arg, caps[i].ext) )
141
tst->data = (void *) TRUE;
145
static bool tst_ihave_validate_const
146
(struct sieve_validator *valdtr ATTR_UNUSED, struct sieve_command *tst,
147
int *const_current, int const_next ATTR_UNUSED)
149
if ( (bool)tst->data == TRUE )