From 81a4e22d82fa47f1ce2049182e4e1bf9b72a2cd0 Mon Sep 17 00:00:00 2001 From: Stephan Bosch <stephan@rename-it.nl> Date: Sun, 26 Jul 2009 02:37:58 +0200 Subject: [PATCH] Implemented skeleton of the mailbox extension. --- configure.in | 1 + src/lib-sieve/Makefile.am | 4 +- src/lib-sieve/plugins/mailbox/Makefile.am | 23 +++ .../plugins/mailbox/cmd-mailboxexists.c | 145 ++++++++++++++++++ .../plugins/mailbox/ext-mailbox-common.h | 40 +++++ src/lib-sieve/plugins/mailbox/ext-mailbox.c | 62 ++++++++ .../plugins/mailbox/tag-mailbox-create.c | 125 +++++++++++++++ src/lib-sieve/sieve-extensions.c | 4 +- 8 files changed, 402 insertions(+), 2 deletions(-) create mode 100644 src/lib-sieve/plugins/mailbox/Makefile.am create mode 100644 src/lib-sieve/plugins/mailbox/cmd-mailboxexists.c create mode 100644 src/lib-sieve/plugins/mailbox/ext-mailbox-common.h create mode 100644 src/lib-sieve/plugins/mailbox/ext-mailbox.c create mode 100644 src/lib-sieve/plugins/mailbox/tag-mailbox-create.c diff --git a/configure.in b/configure.in index 208a1113a..98f8cb729 100644 --- a/configure.in +++ b/configure.in @@ -115,6 +115,7 @@ src/lib-sieve/plugins/variables/Makefile src/lib-sieve/plugins/enotify/Makefile src/lib-sieve/plugins/notify/Makefile src/lib-sieve/plugins/environment/Makefile +src/lib-sieve/plugins/mailbox/Makefile src/lib-sieve-tool/Makefile src/plugins/Makefile src/plugins/lda-sieve/Makefile diff --git a/src/lib-sieve/Makefile.am b/src/lib-sieve/Makefile.am index ce9d26726..ed89d64c1 100644 --- a/src/lib-sieve/Makefile.am +++ b/src/lib-sieve/Makefile.am @@ -56,7 +56,9 @@ plugins = \ ./plugins/variables/libsieve_ext_variables.la \ ./plugins/enotify/libsieve_ext_enotify.la \ ./plugins/notify/libsieve_ext_notify.la \ - ./plugins/environment/libsieve_ext_environment.la + ./plugins/environment/libsieve_ext_environment.la \ + ./plugins/mailbox/libsieve_ext_mailbox.la + libsieve_la_DEPENDENCIES = $(plugins) libsieve_la_LIBADD = $(plugins) diff --git a/src/lib-sieve/plugins/mailbox/Makefile.am b/src/lib-sieve/plugins/mailbox/Makefile.am new file mode 100644 index 000000000..7e93fa984 --- /dev/null +++ b/src/lib-sieve/plugins/mailbox/Makefile.am @@ -0,0 +1,23 @@ +noinst_LTLIBRARIES = libsieve_ext_mailbox.la + +AM_CPPFLAGS = \ + -I../../ \ + -I$(dovecot_incdir) \ + -I$(dovecot_incdir)/src/lib \ + -I$(dovecot_incdir)/src/lib-mail \ + -I$(dovecot_incdir)/src/lib-storage + +tags = \ + tag-mailbox-create.c + +commands = \ + cmd-mailboxexists.c + +libsieve_ext_mailbox_la_SOURCES = \ + ext-mailbox-commonc \ + $(tags) \ + $(commands) \ + ext-mailbox.c + +noinst_HEADERS = \ + ext-mailbox-common.h diff --git a/src/lib-sieve/plugins/mailbox/cmd-mailboxexists.c b/src/lib-sieve/plugins/mailbox/cmd-mailboxexists.c new file mode 100644 index 000000000..94dc893bc --- /dev/null +++ b/src/lib-sieve/plugins/mailbox/cmd-mailboxexists.c @@ -0,0 +1,145 @@ +/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file + */ + +#include "sieve-common.h" +#include "sieve-commands.h" +#include "sieve-code.h" +#include "sieve-validator.h" +#include "sieve-generator.h" +#include "sieve-interpreter.h" +#include "sieve-dump.h" + +#include "ext-mailbox-common.h" + +/* + * Mailboxexists command + * + * Syntax: + * mailboxexists <mailbox-names: string-list> + */ + +static bool tst_mailboxexists_validate + (struct sieve_validator *validator, struct sieve_command_context *tst); +static bool tst_mailboxexists_generate + (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx); + +const struct sieve_command mailboxexists_test = { + "mailboxexists", + SCT_TEST, + 1, 0, FALSE, FALSE, + NULL, NULL, + tst_mailboxexists_validate, + tst_mailboxexists_generate, + NULL +}; + +/* + * Mailboxexists operation + */ + +static bool tst_mailboxexists_operation_dump + (const struct sieve_operation *op, + const struct sieve_dumptime_env *denv, sieve_size_t *address); +static int tst_mailboxexists_operation_execute + (const struct sieve_operation *op, + const struct sieve_runtime_env *renv, sieve_size_t *address); + +const struct sieve_operation mailboxexists_operation = { + "MAILBOXEXISTS", + &mailbox_extension, + 0, + tst_mailboxexists_operation_dump, + tst_mailboxexists_operation_execute +}; + +/* + * Test validation + */ + +static bool tst_mailboxexists_validate + (struct sieve_validator *validator, struct sieve_command_context *tst) +{ + struct sieve_ast_argument *arg = tst->first_positional; + + if ( !sieve_validate_positional_argument + (validator, tst, arg, "mailbox-names", 1, SAAT_STRING_LIST) ) { + return FALSE; + } + + return sieve_validator_argument_activate(validator, tst, arg, FALSE); +} + +/* + * Test generation + */ + +static bool tst_mailboxexists_generate + (const struct sieve_codegen_env *cgenv, struct sieve_command_context *tst) +{ + sieve_operation_emit_code(cgenv->sbin, &mailboxexists_operation); + + /* Generate arguments */ + return sieve_generate_arguments(cgenv, tst, NULL); +} + +/* + * Code dump + */ + +static bool tst_mailboxexists_operation_dump +(const struct sieve_operation *op ATTR_UNUSED, + const struct sieve_dumptime_env *denv, sieve_size_t *address) +{ + sieve_code_dumpf(denv, "MAILBOXEXISTS"); + sieve_code_descend(denv); + + return + sieve_opr_stringlist_dump(denv, address, "mailbox-names"); +} + +/* + * Code execution + */ + +static int tst_mailboxexists_operation_execute +(const struct sieve_operation *op ATTR_UNUSED, + const struct sieve_runtime_env *renv, sieve_size_t *address) +{ + struct sieve_coded_stringlist *mailbox_names; + string_t *uri_item; + bool result = TRUE, all_exist = TRUE; + + /* + * Read operands + */ + + /* Read notify uris */ + if ( (mailbox_names=sieve_opr_stringlist_read(renv, address)) == NULL ) { + sieve_runtime_trace_error(renv, "invalid mailbox-names operand"); + return SIEVE_EXEC_BIN_CORRUPT; + } + + /* + * Perform operation + */ + + sieve_runtime_trace(renv, "MAILBOXEXISTS command"); + + uri_item = NULL; + while ( (result=sieve_coded_stringlist_next_item(mailbox_names, &uri_item)) + && uri_item != NULL ) { + + if ( TRUE ) { + all_exist = FALSE; + break; + } + } + + if ( !result ) { + sieve_runtime_trace_error(renv, "invalid mailbox name item"); + return SIEVE_EXEC_BIN_CORRUPT; + } + + sieve_interpreter_set_test_result(renv->interp, all_exist); + return SIEVE_EXEC_OK; +} diff --git a/src/lib-sieve/plugins/mailbox/ext-mailbox-common.h b/src/lib-sieve/plugins/mailbox/ext-mailbox-common.h new file mode 100644 index 000000000..4b593fd65 --- /dev/null +++ b/src/lib-sieve/plugins/mailbox/ext-mailbox-common.h @@ -0,0 +1,40 @@ +/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file + */ + +#ifndef __EXT_MAILBOX_COMMON_H +#define __EXT_MAILBOX_COMMON_H + +#include "sieve-common.h" + +/* + * Tagged arguments + */ + +extern const struct sieve_argument mailbox_create_tag; + +/* + * Commands + */ + +extern const struct sieve_command mailboxexists_test; + +/* + * Operands + */ + +extern const struct sieve_operand mailbox_create_operand; + +/* + * Operations + */ + +extern const struct sieve_operation mailboxexists_operation; + +/* + * Extension + */ + +extern const struct sieve_extension mailbox_extension; + +#endif /* __EXT_MAILBOX_COMMON_H */ + diff --git a/src/lib-sieve/plugins/mailbox/ext-mailbox.c b/src/lib-sieve/plugins/mailbox/ext-mailbox.c new file mode 100644 index 000000000..c0fc6e8b4 --- /dev/null +++ b/src/lib-sieve/plugins/mailbox/ext-mailbox.c @@ -0,0 +1,62 @@ +/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file + */ + +/* Extension mailbox + * ------------------ + * + * Authors: Stephan Bosch + * Specification: RFC 5490 + * Implementation: skeleton + * Status: under development + * + */ + +#include <stdio.h> + +#include "sieve-common.h" + +#include "sieve-code.h" +#include "sieve-extensions.h" +#include "sieve-actions.h" +#include "sieve-commands.h" +#include "sieve-validator.h" +#include "sieve-generator.h" +#include "sieve-interpreter.h" +#include "sieve-result.h" + +#include "ext-mailbox-common.h" + +/* + * Extension + */ + +static bool ext_mailbox_validator_load(struct sieve_validator *valdtr); + +static int ext_my_id = -1; + +const struct sieve_extension mailbox_extension = { + "mailbox", + &ext_my_id, + NULL, NULL, + ext_mailbox_validator_load, + NULL, NULL, NULL, NULL, NULL, + SIEVE_EXT_DEFINE_OPERATION(mailboxexists_operation), + SIEVE_EXT_DEFINE_OPERAND(mailbox_create_operand) +}; + +static bool ext_mailbox_validator_load(struct sieve_validator *valdtr) +{ + /* Register :create tag with fileinto command and we don't care whether this + * command is registered or even whether it will be registered at all. The + * validator handles either situation gracefully + */ + sieve_validator_register_external_tag + (valdtr, &mailbox_create_tag, "fileinto", -1); + + /* Register new test */ + sieve_validator_register_command(valdtr, &mailboxexists_test); + + return TRUE; +} + + diff --git a/src/lib-sieve/plugins/mailbox/tag-mailbox-create.c b/src/lib-sieve/plugins/mailbox/tag-mailbox-create.c new file mode 100644 index 000000000..d6a70424d --- /dev/null +++ b/src/lib-sieve/plugins/mailbox/tag-mailbox-create.c @@ -0,0 +1,125 @@ +/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file + */ + +#include "lib.h" + +#include "sieve-common.h" +#include "sieve-commands.h" +#include "sieve-code.h" +#include "sieve-actions.h" +#include "sieve-result.h" +#include "sieve-generator.h" + +#include "ext-mailbox-common.h" + +/* + * Tagged argument + */ + +static bool tag_mailbox_create_validate + (struct sieve_validator *validator, struct sieve_ast_argument **arg, + struct sieve_command_context *cmd); +static bool tag_mailbox_create_generate + (const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, + struct sieve_command_context *context); + +const struct sieve_argument mailbox_create_tag = { + "create", + NULL, NULL, + tag_mailbox_create_validate, + NULL, + tag_mailbox_create_generate +}; + +/* + * Side effect + */ + +static void seff_mailbox_create_print + (const struct sieve_side_effect *seffect, const struct sieve_action *action, + const struct sieve_result_print_env *rpenv, void *se_context, bool *keep); +static void seff_mailbox_create_post_commit + (const struct sieve_side_effect *seffect, const struct sieve_action *action, + const struct sieve_action_exec_env *aenv, void *se_context, + void *tr_context, bool *keep); + +const struct sieve_side_effect mailbox_create_side_effect = { + SIEVE_OBJECT("create", &mailbox_create_operand, 0), + &act_store, + NULL, NULL, NULL, + seff_mailbox_create_print, + NULL, NULL, + seff_mailbox_create_post_commit, + NULL +}; + +/* + * Operand + */ + +static const struct sieve_extension_objects ext_side_effects = + SIEVE_EXT_DEFINE_SIDE_EFFECT(mailbox_create_side_effect); + +const struct sieve_operand mailbox_create_operand = { + "create operand", + &mailbox_extension, + 0, + &sieve_side_effect_operand_class, + &ext_side_effects +}; + +/* + * Tag validation + */ + +static bool tag_mailbox_create_validate + (struct sieve_validator *validator ATTR_UNUSED, + struct sieve_ast_argument **arg ATTR_UNUSED, + struct sieve_command_context *cmd ATTR_UNUSED) +{ + *arg = sieve_ast_argument_next(*arg); + + return TRUE; +} + +/* + * Code generation + */ + +static bool tag_mailbox_create_generate +(const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, + struct sieve_command_context *context ATTR_UNUSED) +{ + if ( sieve_ast_argument_type(arg) != SAAT_TAG ) { + return FALSE; + } + + sieve_opr_side_effect_emit(cgenv->sbin, &mailbox_create_side_effect); + + return TRUE; +} + +/* + * Side effect implementation + */ + +static void seff_mailbox_create_print +(const struct sieve_side_effect *seffect ATTR_UNUSED, + const struct sieve_action *action ATTR_UNUSED, + const struct sieve_result_print_env *rpenv, + void *se_context ATTR_UNUSED, bool *keep ATTR_UNUSED) +{ + sieve_result_seffect_printf(rpenv, "create mailbox if it does not exist"); +} + +static void seff_mailbox_create_post_commit +(const struct sieve_side_effect *seffect ATTR_UNUSED, + const struct sieve_action *action ATTR_UNUSED, + const struct sieve_action_exec_env *aenv ATTR_UNUSED, + void *se_context ATTR_UNUSED, void *tr_context ATTR_UNUSED, + bool *keep ATTR_UNUSED) +{ +} + + + diff --git a/src/lib-sieve/sieve-extensions.c b/src/lib-sieve/sieve-extensions.c index 368fb6caa..897f7071f 100644 --- a/src/lib-sieve/sieve-extensions.c +++ b/src/lib-sieve/sieve-extensions.c @@ -80,6 +80,7 @@ extern const struct sieve_extension body_extension; extern const struct sieve_extension variables_extension; extern const struct sieve_extension enotify_extension; extern const struct sieve_extension environment_extension; +extern const struct sieve_extension mailbox_extension; /* * Extensions under development @@ -117,7 +118,8 @@ const struct sieve_extension *sieve_core_extensions[] = { &comparator_i_ascii_numeric_extension, &relational_extension, ®ex_extension, &imap4flags_extension, ©_extension, &include_extension, &body_extension, - &variables_extension, &enotify_extension, &environment_extension + &variables_extension, &enotify_extension, &environment_extension, + &mailbox_extension }; const unsigned int sieve_core_extensions_count = -- GitLab