Skip to content

Commit

Permalink
lib-sieve: Added support for running the Sieve interpreter without an…
Browse files Browse the repository at this point in the history
… envelope.
  • Loading branch information
stephanbosch committed Mar 27, 2016
1 parent 4dce44b commit b190d77
Show file tree
Hide file tree
Showing 4 changed files with 260 additions and 4 deletions.
77 changes: 76 additions & 1 deletion src/lib-sieve/ext-envelope.c
Expand Up @@ -45,23 +45,98 @@ const struct sieve_extension_def envelope_extension;
*/

static bool ext_envelope_validator_load
(const struct sieve_extension *ext, struct sieve_validator *valdtr);
(const struct sieve_extension *ext, struct sieve_validator *valdtr);
static bool ext_envelope_interpreter_load
(const struct sieve_extension *ext,
const struct sieve_runtime_env *renv,
sieve_size_t *address);

static bool ext_envelope_validator_validate
(const struct sieve_extension *ext,
struct sieve_validator *valdtr, void *context,
struct sieve_ast_argument *require_arg,
bool required);
static int ext_envelope_interpreter_run
(const struct sieve_extension *this_ext,
const struct sieve_runtime_env *renv,
void *context, bool deferred);

const struct sieve_extension_def envelope_extension = {
.name = "envelope",
.interpreter_load = ext_envelope_interpreter_load,
.validator_load = ext_envelope_validator_load,
SIEVE_EXT_DEFINE_OPERATION(envelope_operation)
};
const struct sieve_validator_extension
envelope_validator_extension = {
.ext = &envelope_extension,
.validate = ext_envelope_validator_validate
};
const struct sieve_interpreter_extension
envelope_interpreter_extension = {
.ext_def = &envelope_extension,
.run = ext_envelope_interpreter_run
};

static bool ext_envelope_validator_load
(const struct sieve_extension *ext, struct sieve_validator *valdtr)
{
/* Register new test */
sieve_validator_register_command(valdtr, ext, &envelope_test);

sieve_validator_extension_register
(valdtr, ext, &envelope_validator_extension, NULL);
return TRUE;
}

static bool ext_envelope_interpreter_load
(const struct sieve_extension *ext,
const struct sieve_runtime_env *renv,
sieve_size_t *address ATTR_UNUSED)
{
sieve_interpreter_extension_register
(renv->interp, ext, &envelope_interpreter_extension, NULL);
return TRUE;
}

static bool ext_envelope_validator_validate
(const struct sieve_extension *ext,
struct sieve_validator *valdtr, void *context ATTR_UNUSED,
struct sieve_ast_argument *require_arg,
bool required)
{
if (required) {
enum sieve_compile_flags flags =
sieve_validator_compile_flags(valdtr);

if ( (flags & SIEVE_COMPILE_FLAG_NO_ENVELOPE) != 0 ) {
sieve_argument_validate_error(valdtr, require_arg,
"the %s extension cannot be used in this context "
"(needs access to message envelope)",
sieve_extension_name(ext));
return FALSE;
}
}
return TRUE;
}

static int ext_envelope_interpreter_run
(const struct sieve_extension *ext,
const struct sieve_runtime_env *renv,
void *context ATTR_UNUSED, bool deferred)
{
if ( (renv->flags & SIEVE_EXECUTE_FLAG_NO_ENVELOPE) != 0 ) {
if ( !deferred ) {
sieve_runtime_error(renv, NULL,
"the %s extension cannot be used in this context "
"(needs access to message envelope)",
sieve_extension_name(ext));
}
return SIEVE_EXEC_FAILURE;
}
return SIEVE_EXEC_OK;
}

/*
* Envelope test
*
Expand Down
106 changes: 104 additions & 2 deletions src/lib-sieve/ext-reject.c
Expand Up @@ -50,46 +50,148 @@ static const struct sieve_operation_def ereject_operation;
* Extensions
*/

static bool ext_reject_validator_validate
(const struct sieve_extension *ext,
struct sieve_validator *valdtr, void *context,
struct sieve_ast_argument *require_arg,
bool required);
static int ext_reject_interpreter_run
(const struct sieve_extension *this_ext,
const struct sieve_runtime_env *renv,
void *context, bool deferred);

/* Reject */

static bool ext_reject_validator_load
(const struct sieve_extension *ext, struct sieve_validator *valdtr);
(const struct sieve_extension *ext, struct sieve_validator *valdtr);
static bool ext_reject_interpreter_load
(const struct sieve_extension *ext,
const struct sieve_runtime_env *renv, sieve_size_t *address);

const struct sieve_extension_def reject_extension = {
.name = "reject",
.validator_load = ext_reject_validator_load,
.interpreter_load = ext_reject_interpreter_load,
SIEVE_EXT_DEFINE_OPERATION(reject_operation)
};
const struct sieve_validator_extension
reject_validator_extension = {
.ext = &reject_extension,
.validate = ext_reject_validator_validate
};
const struct sieve_interpreter_extension
reject_interpreter_extension = {
.ext_def = &reject_extension,
.run = ext_reject_interpreter_run
};

static bool ext_reject_validator_load
(const struct sieve_extension *ext, struct sieve_validator *valdtr)
{
/* Register new command */
sieve_validator_register_command(valdtr, ext, &reject_command);

sieve_validator_extension_register
(valdtr, ext, &reject_validator_extension, NULL);
return TRUE;
}

static bool ext_reject_interpreter_load
(const struct sieve_extension *ext,
const struct sieve_runtime_env *renv,
sieve_size_t *address ATTR_UNUSED)
{
sieve_interpreter_extension_register
(renv->interp, ext, &reject_interpreter_extension, NULL);
return TRUE;
}

/* EReject */

static bool ext_ereject_validator_load
(const struct sieve_extension *ext, struct sieve_validator *valdtr);
(const struct sieve_extension *ext, struct sieve_validator *valdtr);
static bool ext_ereject_interpreter_load
(const struct sieve_extension *ext,
const struct sieve_runtime_env *renv, sieve_size_t *address);

const struct sieve_extension_def ereject_extension = {
.name = "ereject",
.validator_load = ext_ereject_validator_load,
.interpreter_load = ext_ereject_interpreter_load,
SIEVE_EXT_DEFINE_OPERATION(ereject_operation)
};
const struct sieve_validator_extension
ereject_validator_extension = {
.ext = &ereject_extension,
.validate = ext_reject_validator_validate
};
const struct sieve_interpreter_extension
ereject_interpreter_extension = {
.ext_def = &ereject_extension,
.run = ext_reject_interpreter_run
};

static bool ext_ereject_validator_load
(const struct sieve_extension *ext, struct sieve_validator *valdtr)
{
/* Register new command */
sieve_validator_register_command(valdtr, ext, &ereject_command);

sieve_validator_extension_register
(valdtr, ext, &ereject_validator_extension, NULL);
return TRUE;
}

static bool ext_ereject_interpreter_load
(const struct sieve_extension *ext,
const struct sieve_runtime_env *renv,
sieve_size_t *address ATTR_UNUSED)
{
sieve_interpreter_extension_register
(renv->interp, ext, &ereject_interpreter_extension, NULL);
return TRUE;
}

/* Environment checking */

static bool ext_reject_validator_validate
(const struct sieve_extension *ext,
struct sieve_validator *valdtr, void *context ATTR_UNUSED,
struct sieve_ast_argument *require_arg,
bool required)
{
if (required) {
enum sieve_compile_flags flags =
sieve_validator_compile_flags(valdtr);

if ( (flags & SIEVE_COMPILE_FLAG_NO_ENVELOPE) != 0 ) {
sieve_argument_validate_error(valdtr, require_arg,
"the %s extension cannot be used in this context "
"(needs access to message envelope)",
sieve_extension_name(ext));
return FALSE;
}
}
return TRUE;
}

static int ext_reject_interpreter_run
(const struct sieve_extension *ext,
const struct sieve_runtime_env *renv,
void *context ATTR_UNUSED, bool deferred)
{
if ( (renv->flags & SIEVE_EXECUTE_FLAG_NO_ENVELOPE) != 0 ) {
if ( !deferred ) {
sieve_runtime_error(renv, NULL,
"the %s extension cannot be used in this context "
"(needs access to message envelope)",
sieve_extension_name(ext));
}
return SIEVE_EXEC_FAILURE;
}
return SIEVE_EXEC_OK;
}

/*
* Commands
*/
Expand Down
75 changes: 75 additions & 0 deletions src/lib-sieve/plugins/vacation/ext-vacation.c
Expand Up @@ -30,20 +30,95 @@

static bool ext_vacation_validator_load
(const struct sieve_extension *ext, struct sieve_validator *valdtr);
static bool ext_vacation_interpreter_load
(const struct sieve_extension *ext,
const struct sieve_runtime_env *renv,
sieve_size_t *address);

static bool ext_vacation_validator_validate
(const struct sieve_extension *ext,
struct sieve_validator *valdtr, void *context,
struct sieve_ast_argument *require_arg,
bool required);
static int ext_vacation_interpreter_run
(const struct sieve_extension *this_ext,
const struct sieve_runtime_env *renv,
void *context, bool deferred);

const struct sieve_extension_def vacation_extension = {
.name = "vacation",
.load = ext_vacation_load,
.unload = ext_vacation_unload,
.validator_load = ext_vacation_validator_load,
.interpreter_load = ext_vacation_interpreter_load,
SIEVE_EXT_DEFINE_OPERATION(vacation_operation)
};
const struct sieve_validator_extension
vacation_validator_extension = {
.ext = &vacation_extension,
.validate = ext_vacation_validator_validate
};
const struct sieve_interpreter_extension
vacation_interpreter_extension = {
.ext_def = &vacation_extension,
.run = ext_vacation_interpreter_run
};

static bool ext_vacation_validator_load
(const struct sieve_extension *ext, struct sieve_validator *valdtr)
{
/* Register new command */
sieve_validator_register_command(valdtr, ext, &vacation_command);

sieve_validator_extension_register
(valdtr, ext, &vacation_validator_extension, NULL);
return TRUE;
}

static bool ext_vacation_interpreter_load
(const struct sieve_extension *ext,
const struct sieve_runtime_env *renv,
sieve_size_t *address ATTR_UNUSED)
{
sieve_interpreter_extension_register(renv->interp,
ext, &vacation_interpreter_extension, NULL);
return TRUE;
}

static bool ext_vacation_validator_validate
(const struct sieve_extension *ext,
struct sieve_validator *valdtr, void *context ATTR_UNUSED,
struct sieve_ast_argument *require_arg,
bool required)
{
if (required) {
enum sieve_compile_flags flags =
sieve_validator_compile_flags(valdtr);

if ( (flags & SIEVE_COMPILE_FLAG_NO_ENVELOPE) != 0 ) {
sieve_argument_validate_error(valdtr, require_arg,
"the %s extension cannot be used in this context "
"(needs access to message envelope)",
sieve_extension_name(ext));
return FALSE;
}
}
return TRUE;
}

static int ext_vacation_interpreter_run
(const struct sieve_extension *ext,
const struct sieve_runtime_env *renv,
void *context ATTR_UNUSED, bool deferred)
{
if ( (renv->flags & SIEVE_EXECUTE_FLAG_NO_ENVELOPE) != 0 ) {
if ( !deferred ) {
sieve_runtime_error(renv, NULL,
"the %s extension cannot be used in this context "
"(needs access to message envelope)",
sieve_extension_name(ext));
}
return SIEVE_EXEC_FAILURE;
}
return SIEVE_EXEC_OK;
}
6 changes: 5 additions & 1 deletion src/lib-sieve/sieve-types.h
Expand Up @@ -116,6 +116,8 @@ enum sieve_compile_flags {
SIEVE_COMPILE_FLAG_UPLOADED = (1<<1),
/* Script is being activated (usually through ManageSieve) */
SIEVE_COMPILE_FLAG_ACTIVATED = (1<<2),
/* Compiled for environment with no access to envelope */
SIEVE_COMPILE_FLAG_NO_ENVELOPE = (1<<3)
};

/*
Expand Down Expand Up @@ -143,7 +145,9 @@ enum sieve_execute_flags {
*/
SIEVE_EXECUTE_FLAG_NOGLOBAL = (1<<0),
/* Do not execute (implicit keep) at the end */
SIEVE_EXECUTE_FLAG_DEFER_KEEP = (1<<1)
SIEVE_EXECUTE_FLAG_DEFER_KEEP = (1<<1),
/* There is no envelope */
SIEVE_EXECUTE_FLAG_NO_ENVELOPE = (1<<2)
};

/*
Expand Down

0 comments on commit b190d77

Please sign in to comment.