-
Stephan Bosch authoredStephan Bosch authored
sieve-actions.h 7.94 KiB
#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