1
/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
6
#include "sieve-code.h"
7
#include "sieve-commands.h"
8
#include "sieve-validator.h"
9
#include "sieve-generator.h"
10
#include "sieve-interpreter.h"
11
#include "sieve-dump.h"
13
#include "ext-imap4flags-common.h"
19
/* Forward declarations */
21
static bool cmd_flag_generate
22
(const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx);
27
* setflag [<variablename: string>] <list-of-flags: string-list>
30
const struct sieve_command cmd_setflag = {
33
-1, /* We check positional arguments ourselves */
36
ext_imap4flags_command_validate,
44
* addflag [<variablename: string>] <list-of-flags: string-list>
47
const struct sieve_command cmd_addflag = {
50
-1, /* We check positional arguments ourselves */
53
ext_imap4flags_command_validate,
62
* removeflag [<variablename: string>] <list-of-flags: string-list>
65
const struct sieve_command cmd_removeflag = {
68
-1, /* We check positional arguments ourselves */
71
ext_imap4flags_command_validate,
80
/* Forward declarations */
82
bool cmd_flag_operation_dump
83
(const struct sieve_operation *op,
84
const struct sieve_dumptime_env *denv, sieve_size_t *address);
85
static int cmd_flag_operation_execute
86
(const struct sieve_operation *op,
87
const struct sieve_runtime_env *renv, sieve_size_t *address);
89
/* Setflag operation */
91
const struct sieve_operation setflag_operation = {
93
&imap4flags_extension,
94
ext_imap4flags_OPERATION_SETFLAG,
95
cmd_flag_operation_dump,
96
cmd_flag_operation_execute
99
/* Addflag operation */
101
const struct sieve_operation addflag_operation = {
103
&imap4flags_extension,
104
ext_imap4flags_OPERATION_ADDFLAG,
105
cmd_flag_operation_dump,
106
cmd_flag_operation_execute
109
/* Removeflag operation */
111
const struct sieve_operation removeflag_operation = {
113
&imap4flags_extension,
114
ext_imap4flags_OPERATION_REMOVEFLAG,
115
cmd_flag_operation_dump,
116
cmd_flag_operation_execute
123
static bool cmd_flag_generate
124
(const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx)
126
const struct sieve_command *command = ctx->command;
129
if ( command == &cmd_setflag )
130
sieve_operation_emit_code(cgenv->sbin, &setflag_operation);
131
else if ( command == &cmd_addflag )
132
sieve_operation_emit_code(cgenv->sbin, &addflag_operation);
133
else if ( command == &cmd_removeflag )
134
sieve_operation_emit_code(cgenv->sbin, &removeflag_operation);
136
/* Generate arguments */
137
if ( !sieve_generate_arguments(cgenv, ctx, NULL) )
147
bool cmd_flag_operation_dump
148
(const struct sieve_operation *op,
149
const struct sieve_dumptime_env *denv, sieve_size_t *address)
151
const struct sieve_operand *operand;
153
sieve_code_dumpf(denv, "%s", op->mnemonic);
154
sieve_code_descend(denv);
156
sieve_code_mark(denv);
157
operand = sieve_operand_read(denv->sbin, address);
158
if ( operand == NULL ) {
159
sieve_code_dumpf(denv, "ERROR: INVALID OPERAND");
163
if ( sieve_operand_is_variable(operand) ) {
165
sieve_opr_string_dump_data(denv, operand, address,
167
sieve_opr_stringlist_dump(denv, address,
172
sieve_opr_stringlist_dump_data(denv, operand, address,
180
static int cmd_flag_operation_execute
181
(const struct sieve_operation *op,
182
const struct sieve_runtime_env *renv, sieve_size_t *address)
184
const struct sieve_operand *operand;
185
sieve_size_t op_address = *address;
188
struct sieve_coded_stringlist *flag_list;
189
struct sieve_variable_storage *storage;
190
unsigned int var_index;
191
ext_imapflag_flag_operation_t flag_op;
198
operand = sieve_operand_read(renv->sbin, address);
199
if ( operand == NULL ) {
200
sieve_runtime_trace_error(renv, "invalid operand");
201
return SIEVE_EXEC_BIN_CORRUPT;
204
if ( sieve_operand_is_variable(operand) ) {
206
/* Read the variable operand */
207
if ( !sieve_variable_operand_read_data
208
(renv, operand, address, &storage, &var_index) ) {
209
sieve_runtime_trace_error(renv, "invalid variable operand");
210
return SIEVE_EXEC_BIN_CORRUPT;
214
if ( (flag_list=sieve_opr_stringlist_read(renv, address)) == NULL ) {
215
sieve_runtime_trace_error(renv, "invalid flag-list operand");
216
return SIEVE_EXEC_BIN_CORRUPT;
219
} else if ( sieve_operand_is_stringlist(operand) ) {
224
if ( (flag_list=sieve_opr_stringlist_read_data
225
(renv, operand, op_address, address)) == NULL ) {
226
sieve_runtime_trace_error(renv, "invalid flag-list operand");
227
return SIEVE_EXEC_BIN_CORRUPT;
231
sieve_runtime_trace_error(renv, "unexpected operand '%s'",
233
return SIEVE_EXEC_BIN_CORRUPT;
240
sieve_runtime_trace(renv, "%s command", op->mnemonic);
242
/* Determine what to do */
244
if ( op == &setflag_operation )
245
flag_op = ext_imap4flags_set_flags;
246
else if ( op == &addflag_operation )
247
flag_op = ext_imap4flags_add_flags;
248
else if ( op == &removeflag_operation )
249
flag_op = ext_imap4flags_remove_flags;
253
/* Iterate through all flags and perform requested operation */
255
while ( (result=sieve_coded_stringlist_next_item(flag_list, &flag_item)) &&
256
flag_item != NULL ) {
258
if ( (ret=flag_op(renv, storage, var_index, flag_item)) <= 0)
263
sieve_runtime_trace_error(renv, "invalid flag-list item");
264
return SIEVE_EXEC_BIN_CORRUPT;
267
return SIEVE_EXEC_OK;