diff options
Diffstat (limited to 'pigeonhole/src/lib-sieve/sieve-actions.h')
-rw-r--r-- | pigeonhole/src/lib-sieve/sieve-actions.h | 311 |
1 files changed, 311 insertions, 0 deletions
diff --git a/pigeonhole/src/lib-sieve/sieve-actions.h b/pigeonhole/src/lib-sieve/sieve-actions.h new file mode 100644 index 0000000..f1a447f --- /dev/null +++ b/pigeonhole/src/lib-sieve/sieve-actions.h @@ -0,0 +1,311 @@ +#ifndef SIEVE_ACTIONS_H +#define SIEVE_ACTIONS_H + +#include "lib.h" +#include "mail-types.h" +#include "mail-error.h" + +#include "sieve-common.h" +#include "sieve-objects.h" +#include "sieve-extensions.h" +#include "sieve-execute.h" + +/* + * Action execution environment + */ + +struct sieve_action_exec_env { + const struct sieve_execute_env *exec_env; + struct sieve_result_execution *rexec; + const struct sieve_action *action; + struct event *event; + + struct sieve_result *result; + struct sieve_error_handler *ehandler; + + struct sieve_message_context *msgctx; +}; + +struct event_passthrough * +sieve_action_create_finish_event(const struct sieve_action_exec_env *aenv); + +/* + * Action flags + */ + +enum sieve_action_flags { + SIEVE_ACTFLAG_TRIES_DELIVER = (1 << 0), + SIEVE_ACTFLAG_SENDS_RESPONSE = (1 << 1), + SIEVE_ACTFLAG_MAIL_STORAGE = (1 << 2) +}; + +/* + * Action definition + */ + +struct sieve_action_def { + const char *name; + unsigned int flags; + + bool (*equals)(const struct sieve_script_env *senv, + const struct sieve_action *act1, + const struct sieve_action *act2); + + /* Result verification */ + int (*check_duplicate)(const struct sieve_runtime_env *renv, + const struct sieve_action *act, + const struct sieve_action *act_other); + int (*check_conflict)(const struct sieve_runtime_env *renv, + const struct sieve_action *act, + const struct sieve_action *act_other); + + /* Result printing */ + void (*print)(const struct sieve_action *action, + const struct sieve_result_print_env *penv, bool *keep); + + /* Result execution */ + int (*start)(const struct sieve_action_exec_env *aenv, + void **tr_context); + int (*execute)(const struct sieve_action_exec_env *aenv, + void *tr_context, bool *keep); + int (*commit)(const struct sieve_action_exec_env *aenv, + void *tr_context); + void (*rollback)(const struct sieve_action_exec_env *aenv, + void *tr_context, bool success); + void (*finish)(const struct sieve_action_exec_env *aenv, + void *tr_context, int status); +}; + +/* + * Action instance + */ + +struct sieve_action { + const struct sieve_action_def *def; + const struct sieve_extension *ext; + struct event *event; + + const char *name; + const char *location; + unsigned int exec_seq; + void *context; + struct mail *mail; + + bool keep:1; +}; + +#define sieve_action_is(act, definition) ((act)->def == &(definition)) +#define sieve_action_name(act) ((act)->name) + +bool sieve_action_is_executed(const struct sieve_action *act, + struct sieve_result *result); + +/* + * Action side effects + */ + +/* Side effect object */ + +struct sieve_side_effect_def { + struct sieve_object_def obj_def; + + /* Precedence (side effects with higher value are executed first) */ + + unsigned int precedence; + + /* The action it is supposed to link to */ + const struct sieve_action_def *to_action; + + /* Context coding */ + bool (*dump_context)(const struct sieve_side_effect *seffect, + const struct sieve_dumptime_env *renv, + sieve_size_t *address); + int (*read_context)(const struct sieve_side_effect *seffect, + const struct sieve_runtime_env *renv, + sieve_size_t *address, void **se_context); + + /* Result verification */ + int (*merge)(const struct sieve_runtime_env *renv, + const struct sieve_action *action, + const struct sieve_side_effect *old_seffect, + const struct sieve_side_effect *new_seffect, + void **old_context); + + /* Result printing */ + void (*print)(const struct sieve_side_effect *seffect, + const struct sieve_action *action, + const struct sieve_result_print_env *penv, bool *keep); + + /* Result execution */ + + int (*pre_execute)(const struct sieve_side_effect *seffect, + const struct sieve_action_exec_env *aenv, + void *tr_context, void **se_tr_context); + int (*post_execute)(const struct sieve_side_effect *seffect, + const struct sieve_action_exec_env *aenv, + void *tr_context, void *se_tr_context, bool *keep); + void (*post_commit)(const struct sieve_side_effect *seffect, + const struct sieve_action_exec_env *aenv, + void *tr_context, void *se_tr_context, + int commit_status); + void (*rollback)(const struct sieve_side_effect *seffect, + const struct sieve_action_exec_env *aenv, + void *tr_context, void *se_tr_context, bool success); +}; + +struct sieve_side_effect { + struct sieve_object object; + + const struct sieve_side_effect_def *def; + + void *context; +}; + +/* + * Side effect operand + */ + +#define SIEVE_EXT_DEFINE_SIDE_EFFECT(SEF) SIEVE_EXT_DEFINE_OBJECT(SEF) +#define SIEVE_EXT_DEFINE_SIDE_EFFECTS(SEFS) SIEVE_EXT_DEFINE_OBJECTS(SEFS) + +#define SIEVE_OPT_SIDE_EFFECT (-1) + +extern const struct sieve_operand_class sieve_side_effect_operand_class; + +static inline void +sieve_opr_side_effect_emit(struct sieve_binary_block *sblock, + const struct sieve_extension *ext, + const struct sieve_side_effect_def *seff) +{ + sieve_opr_object_emit(sblock, ext, &seff->obj_def); +} + +bool sieve_opr_side_effect_dump(const struct sieve_dumptime_env *denv, + sieve_size_t *address); +int sieve_opr_side_effect_read(const struct sieve_runtime_env *renv, + sieve_size_t *address, + struct sieve_side_effect *seffect); + +/* + * Optional operands + */ + +int sieve_action_opr_optional_dump(const struct sieve_dumptime_env *denv, + sieve_size_t *address, signed int *opt_code); + +int sieve_action_opr_optional_read(const struct sieve_runtime_env *renv, + sieve_size_t *address, signed int *opt_code, + int *exec_status, + struct sieve_side_effects_list **list); + +/* + * Core actions + */ + +extern const struct sieve_action_def act_redirect; +extern const struct sieve_action_def act_store; +extern const struct sieve_action_def act_discard; + +/* + * Store action + */ + +struct act_store_context { + /* Folder name represented in utf-8 */ + const char *mailbox; +}; + +struct act_store_transaction { + struct act_store_context *context; + struct mailbox *box; + struct mailbox_transaction_context *mail_trans; + + const char *mailbox_name; + const char *mailbox_identifier; + + const char *error; + enum mail_error error_code; + + enum mail_flags flags; + ARRAY_TYPE(const_string) keywords; + + bool flags_altered:1; + bool disabled:1; + bool redundant:1; +}; + +int sieve_act_store_add_to_result(const struct sieve_runtime_env *renv, + const char *name, + struct sieve_side_effects_list *seffects, + const char *folder); + +void sieve_act_store_add_flags(const struct sieve_action_exec_env *aenv, + void *tr_context, const char *const *keywords, + enum mail_flags flags); + +void sieve_act_store_get_storage_error(const struct sieve_action_exec_env *aenv, + struct act_store_transaction *trans); + +/* + * Redirect action + */ + +struct act_redirect_context { + const struct smtp_address *to_address; +}; + +int sieve_act_redirect_add_to_result(const struct sieve_runtime_env *renv, + const char *name, + struct sieve_side_effects_list *seffects, + const struct smtp_address *to_address); + +/* + * Checking for duplicates + */ + +static inline bool +sieve_action_duplicate_check_available(const struct sieve_action_exec_env *aenv) +{ + const struct sieve_execute_env *eenv = aenv->exec_env; + + return sieve_execute_duplicate_check_available(eenv); +} + +static inline int +sieve_action_duplicate_check(const struct sieve_action_exec_env *aenv, + const void *id, size_t id_size, + bool *duplicate_r) +{ + const struct sieve_execute_env *eenv = aenv->exec_env; + + return sieve_execute_duplicate_check(eenv, id, id_size, + duplicate_r); +} + +static inline void +sieve_action_duplicate_mark(const struct sieve_action_exec_env *aenv, + const void *id, size_t id_size, time_t time) +{ + const struct sieve_execute_env *eenv = aenv->exec_env; + + return sieve_execute_duplicate_mark(eenv, id, id_size, time); +} + +/* + * Action utility functions + */ + +/* Rejecting mail */ + +int sieve_action_reject_mail(const struct sieve_action_exec_env *aenv, + const struct smtp_address *recipient, + const char *reason); + +/* + * Mailbox + */ + +// FIXME: move this to a more appropriate location +bool sieve_mailbox_check_name(const char *mailbox, const char **error_r); + +#endif |