1
/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
4
#include "sieve-common.h"
5
#include "sieve-commands.h"
6
#include "sieve-validator.h"
7
#include "sieve-generator.h"
8
#include "sieve-interpreter.h"
9
#include "sieve-code.h"
10
#include "sieve-binary.h"
11
#include "sieve-dump.h"
13
#include "testsuite-common.h"
14
#include "testsuite-binary.h"
15
#include "testsuite-script.h"
21
* test_binary ( :load / :save ) <mailbox: string>
24
static bool cmd_test_binary_registered
25
(struct sieve_validator *valdtr,
26
struct sieve_command_registration *cmd_reg);
27
static bool cmd_test_binary_validate
28
(struct sieve_validator *valdtr, struct sieve_command_context *cmd);
29
static bool cmd_test_binary_generate
30
(const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx);
32
const struct sieve_command cmd_test_binary = {
36
cmd_test_binary_registered,
38
cmd_test_binary_validate,
39
cmd_test_binary_generate,
47
static bool cmd_test_binary_operation_dump
48
(const struct sieve_operation *op,
49
const struct sieve_dumptime_env *denv, sieve_size_t *address);
50
static int cmd_test_binary_operation_execute
51
(const struct sieve_operation *op,
52
const struct sieve_runtime_env *renv, sieve_size_t *address);
54
/* test_binary_create operation */
56
const struct sieve_operation test_binary_load_operation = {
59
TESTSUITE_OPERATION_TEST_BINARY_LOAD,
60
cmd_test_binary_operation_dump,
61
cmd_test_binary_operation_execute
64
/* test_binary_delete operation */
66
const struct sieve_operation test_binary_save_operation = {
69
TESTSUITE_OPERATION_TEST_BINARY_SAVE,
70
cmd_test_binary_operation_dump,
71
cmd_test_binary_operation_execute
75
* Compiler context data
78
enum test_binary_operation {
84
const struct sieve_operation *test_binary_operations[] = {
85
&test_binary_load_operation,
86
&test_binary_save_operation
89
struct cmd_test_binary_context_data {
90
enum test_binary_operation binary_op;
98
static bool cmd_test_binary_validate_tag
99
(struct sieve_validator *valdtr, struct sieve_ast_argument **arg,
100
struct sieve_command_context *cmd);
102
static const struct sieve_argument test_binary_load_tag = {
105
cmd_test_binary_validate_tag,
109
static const struct sieve_argument test_binary_save_tag = {
112
cmd_test_binary_validate_tag,
116
static bool cmd_test_binary_registered
117
(struct sieve_validator *valdtr, struct sieve_command_registration *cmd_reg)
119
/* Register our tags */
120
sieve_validator_register_tag(valdtr, cmd_reg, &test_binary_load_tag, 0);
121
sieve_validator_register_tag(valdtr, cmd_reg, &test_binary_save_tag, 0);
126
static bool cmd_test_binary_validate_tag
127
(struct sieve_validator *valdtr, struct sieve_ast_argument **arg,
128
struct sieve_command_context *cmd)
130
struct cmd_test_binary_context_data *ctx_data =
131
(struct cmd_test_binary_context_data *) cmd->data;
133
if ( ctx_data != NULL ) {
134
sieve_argument_validate_error
135
(valdtr, *arg, "exactly one of the ':load' or ':save' tags must be "
136
"specified for the test_binary command, but more were found");
141
(sieve_command_pool(cmd), struct cmd_test_binary_context_data, 1);
142
cmd->data = ctx_data;
144
if ( (*arg)->argument == &test_binary_load_tag )
145
ctx_data->binary_op = BINARY_OP_LOAD;
147
ctx_data->binary_op = BINARY_OP_SAVE;
149
/* Delete this tag */
150
*arg = sieve_ast_arguments_detach(*arg, 1);
159
static bool cmd_test_binary_validate
160
(struct sieve_validator *valdtr, struct sieve_command_context *cmd)
162
struct sieve_ast_argument *arg = cmd->first_positional;
164
if ( cmd->data == NULL ) {
165
sieve_command_validate_error(valdtr, cmd,
166
"the test_binary command requires either the :load or the :save tag "
171
if ( !sieve_validate_positional_argument
172
(valdtr, cmd, arg, "binary-name", 1, SAAT_STRING) ) {
176
return sieve_validator_argument_activate(valdtr, cmd, arg, FALSE);
183
static bool cmd_test_binary_generate
184
(const struct sieve_codegen_env *cgenv, struct sieve_command_context *cmd)
186
struct cmd_test_binary_context_data *ctx_data =
187
(struct cmd_test_binary_context_data *) cmd->data;
189
i_assert( ctx_data->binary_op < BINARY_OP_LAST );
192
sieve_operation_emit_code(cgenv->sbin,
193
test_binary_operations[ctx_data->binary_op]);
195
/* Generate arguments */
196
if ( !sieve_generate_arguments(cgenv, cmd, NULL) )
206
static bool cmd_test_binary_operation_dump
207
(const struct sieve_operation *op,
208
const struct sieve_dumptime_env *denv, sieve_size_t *address)
210
sieve_code_dumpf(denv, "%s:", op->mnemonic);
212
sieve_code_descend(denv);
214
return sieve_opr_string_dump(denv, address, "binary-name");
222
static int cmd_test_binary_operation_execute
223
(const struct sieve_operation *op,
224
const struct sieve_runtime_env *renv, sieve_size_t *address)
226
string_t *binary_name = NULL;
234
if ( !sieve_opr_string_read(renv, address, &binary_name) ) {
235
sieve_runtime_trace_error(renv, "invalid mailbox operand");
236
return SIEVE_EXEC_BIN_CORRUPT;
243
sieve_runtime_trace(renv, "%s %s:", op->mnemonic, str_c(binary_name));
245
if ( op == &test_binary_load_operation ) {
246
struct sieve_binary *sbin = testsuite_binary_load(str_c(binary_name));
248
if ( sbin != NULL ) {
249
testsuite_script_set_binary(sbin);
251
sieve_binary_unref(&sbin);
253
sieve_sys_error("failed to load binary %s", str_c(binary_name));
254
return SIEVE_EXEC_FAILURE;
257
} else if ( op == &test_binary_save_operation ) {
258
struct sieve_binary *sbin = testsuite_script_get_binary();
261
testsuite_binary_save(sbin, str_c(binary_name));
263
sieve_sys_error("no compiled binary to save as %s", str_c(binary_name));
264
return SIEVE_EXEC_FAILURE;
268
return SIEVE_EXEC_OK;