1
/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
8
#include "mail-storage.h"
11
#include "sieve-code.h"
12
#include "sieve-commands.h"
13
#include "sieve-extensions.h"
14
#include "sieve-validator.h"
15
#include "sieve-generator.h"
16
#include "sieve-binary.h"
17
#include "sieve-dump.h"
19
#include "testsuite-common.h"
20
#include "testsuite-objects.h"
21
#include "testsuite-message.h"
24
* Testsuite core objects
27
enum testsuite_object_code {
28
TESTSUITE_OBJECT_MESSAGE,
29
TESTSUITE_OBJECT_ENVELOPE
32
const struct testsuite_object *testsuite_core_objects[] = {
33
&message_testsuite_object, &envelope_testsuite_object
36
const unsigned int testsuite_core_objects_count =
37
N_ELEMENTS(testsuite_core_objects);
40
* Testsuite object registry
43
void testsuite_object_register
44
(struct sieve_validator *valdtr, const struct testsuite_object *tobj)
46
struct testsuite_validator_context *ctx = testsuite_validator_context_get
49
sieve_validator_object_registry_add
50
(ctx->object_registrations, &tobj->object);
53
const struct testsuite_object *testsuite_object_find
54
(struct sieve_validator *valdtr, const char *identifier)
56
struct testsuite_validator_context *ctx = testsuite_validator_context_get
58
const struct sieve_object *object =
59
sieve_validator_object_registry_find
60
(ctx->object_registrations, identifier);
62
return (const struct testsuite_object *) object;
65
void testsuite_register_core_objects
66
(struct testsuite_validator_context *ctx)
70
/* Register core testsuite objects */
71
for ( i = 0; i < testsuite_core_objects_count; i++ ) {
72
sieve_validator_object_registry_add
73
(ctx->object_registrations, &(testsuite_core_objects[i]->object));
78
* Testsuite object code
81
const struct sieve_operand_class sieve_testsuite_object_operand_class =
82
{ "testsuite object" };
84
static const struct sieve_extension_objects core_testsuite_objects =
85
SIEVE_EXT_DEFINE_OBJECTS(testsuite_core_objects);
87
const struct sieve_operand testsuite_object_operand = {
90
TESTSUITE_OPERAND_OBJECT,
91
&sieve_testsuite_object_operand_class,
92
&core_testsuite_objects
95
static void testsuite_object_emit
96
(struct sieve_binary *sbin, const struct testsuite_object *obj,
99
sieve_opr_object_emit(sbin, &obj->object);
101
if ( obj->get_member_id != NULL ) {
102
(void) sieve_binary_emit_byte(sbin, (unsigned char) member_id);
106
const struct testsuite_object *testsuite_object_read
107
(struct sieve_binary *sbin, sieve_size_t *address)
109
const struct sieve_operand *operand = sieve_operand_read(sbin, address);
111
return (const struct testsuite_object *) sieve_opr_object_read_data
112
(sbin, operand, &sieve_testsuite_object_operand_class, address);
115
const struct testsuite_object *testsuite_object_read_member
116
(struct sieve_binary *sbin, sieve_size_t *address, int *member_id)
118
const struct testsuite_object *object;
120
if ( (object = testsuite_object_read(sbin, address)) == NULL )
124
if ( object->get_member_id != NULL ) {
125
if ( !sieve_binary_read_code(sbin, address, member_id) )
132
const char *testsuite_object_member_name
133
(const struct testsuite_object *object, int member_id)
135
const char *member = NULL;
137
if ( object->get_member_id != NULL ) {
138
if ( object->get_member_name != NULL )
139
member = object->get_member_name(member_id);
141
return object->object.identifier;
143
if ( member == NULL )
144
return t_strdup_printf("%s.%d", object->object.identifier, member_id);
146
return t_strdup_printf("%s.%s", object->object.identifier, member);
149
bool testsuite_object_dump
150
(const struct sieve_dumptime_env *denv, sieve_size_t *address)
152
const struct testsuite_object *object;
155
sieve_code_mark(denv);
157
if ( (object = testsuite_object_read_member(denv->sbin, address, &member_id))
161
sieve_code_dumpf(denv, "%s: %s",
162
sieve_testsuite_object_operand_class.name,
163
testsuite_object_member_name(object, member_id));
169
* Testsuite object argument
172
static bool arg_testsuite_object_generate
173
(const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg,
174
struct sieve_command_context *cmd);
176
const struct sieve_argument testsuite_object_argument = {
178
NULL, NULL, NULL, NULL,
179
arg_testsuite_object_generate
182
struct testsuite_object_argctx {
183
const struct testsuite_object *object;
187
bool testsuite_object_argument_activate
188
(struct sieve_validator *valdtr, struct sieve_ast_argument *arg,
189
struct sieve_command_context *cmd)
191
const char *objname = sieve_ast_argument_strc(arg);
192
const struct testsuite_object *object;
195
struct testsuite_object_argctx *ctx;
197
/* Parse the object specifier */
199
member = strchr(objname, '.');
200
if ( member != NULL ) {
201
objname = t_strdup_until(objname, member);
205
/* Find the object */
207
object = testsuite_object_find(valdtr, objname);
208
if ( object == NULL ) {
209
sieve_argument_validate_error(valdtr, arg,
210
"unknown testsuite object '%s'", objname);
214
/* Find the object member */
217
if ( member != NULL ) {
218
if ( object->get_member_id == NULL ||
219
(member_id=object->get_member_id(member)) == -1 ) {
220
sieve_argument_validate_error(valdtr, arg,
221
"member '%s' does not exist for testsuite object '%s'", member, objname);
226
/* Assign argument context */
228
ctx = p_new(sieve_command_pool(cmd), struct testsuite_object_argctx, 1);
229
ctx->object = object;
230
ctx->member = member_id;
232
arg->argument = &testsuite_object_argument;
233
arg->context = (void *) ctx;
238
static bool arg_testsuite_object_generate
239
(const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg,
240
struct sieve_command_context *cmd ATTR_UNUSED)
242
struct testsuite_object_argctx *ctx =
243
(struct testsuite_object_argctx *) arg->context;
245
testsuite_object_emit(cgenv->sbin, ctx->object, ctx->member);
251
* Testsuite core object implementation
254
static bool tsto_message_set_member
255
(const struct sieve_runtime_env *renv, int id, string_t *value);
257
static int tsto_envelope_get_member_id(const char *identifier);
258
static const char *tsto_envelope_get_member_name(int id);
259
static bool tsto_envelope_set_member
260
(const struct sieve_runtime_env *renv, int id, string_t *value);
262
const struct testsuite_object message_testsuite_object = {
263
SIEVE_OBJECT("message", &testsuite_object_operand, TESTSUITE_OBJECT_MESSAGE),
265
tsto_message_set_member,
269
const struct testsuite_object envelope_testsuite_object = {
270
SIEVE_OBJECT("envelope", &testsuite_object_operand, TESTSUITE_OBJECT_ENVELOPE),
271
tsto_envelope_get_member_id,
272
tsto_envelope_get_member_name,
273
tsto_envelope_set_member,
277
enum testsuite_object_envelope_field {
278
TESTSUITE_OBJECT_ENVELOPE_FROM,
279
TESTSUITE_OBJECT_ENVELOPE_TO,
280
TESTSUITE_OBJECT_ENVELOPE_AUTH_USER
283
static bool tsto_message_set_member
284
(const struct sieve_runtime_env *renv, int id, string_t *value)
286
if ( id != -1 ) return FALSE;
288
testsuite_message_set_string(renv, value);
293
static int tsto_envelope_get_member_id(const char *identifier)
295
if ( strcasecmp(identifier, "from") == 0 )
296
return TESTSUITE_OBJECT_ENVELOPE_FROM;
297
if ( strcasecmp(identifier, "to") == 0 )
298
return TESTSUITE_OBJECT_ENVELOPE_TO;
299
if ( strcasecmp(identifier, "auth") == 0 )
300
return TESTSUITE_OBJECT_ENVELOPE_AUTH_USER;
305
static const char *tsto_envelope_get_member_name(int id)
308
case TESTSUITE_OBJECT_ENVELOPE_FROM:
310
case TESTSUITE_OBJECT_ENVELOPE_TO:
312
case TESTSUITE_OBJECT_ENVELOPE_AUTH_USER:
319
static bool tsto_envelope_set_member
320
(const struct sieve_runtime_env *renv, int id, string_t *value)
323
case TESTSUITE_OBJECT_ENVELOPE_FROM:
324
testsuite_envelope_set_sender(renv, str_c(value));
326
case TESTSUITE_OBJECT_ENVELOPE_TO:
327
testsuite_envelope_set_recipient(renv, str_c(value));
329
case TESTSUITE_OBJECT_ENVELOPE_AUTH_USER:
330
testsuite_envelope_set_auth_user(renv, str_c(value));