dovecot-2.2-pigeonhole: lib-sieve: environment extension: Finall...
pigeonhole at rename-it.nl
pigeonhole at rename-it.nl
Thu Apr 11 23:40:13 EEST 2013
details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/9d38ca755000
changeset: 1750:9d38ca755000
user: Stephan Bosch <stephan at rename-it.nl>
date: Thu Apr 11 22:40:07 2013 +0200
description:
lib-sieve: environment extension: Finally finished this extension a much as possible.
Some environment items in the base specification are not (yet) applicable to Dovecot and are therefore not supported.
diffstat:
README | 2 +-
src/lib-sieve-tool/sieve-tool.c | 4 +-
src/lib-sieve/plugins/environment/ext-environment-common.c | 86 +++++++++----
src/lib-sieve/sieve-common.h | 3 +
src/lib-sieve/sieve-types.h | 27 ++++-
src/lib-sieve/sieve.c | 27 ++++-
src/plugins/lda-sieve/lda-sieve-plugin.c | 2 +
tests/extensions/environment/basic.svtest | 8 +-
tests/extensions/environment/rfc.svtest | 2 +-
9 files changed, 128 insertions(+), 33 deletions(-)
diffs (truncated from 328 to 300 lines):
diff -r 1a3a4545fa10 -r 9d38ca755000 README
--- a/README Thu Apr 11 20:42:41 2013 +0200
+++ b/README Thu Apr 11 22:40:07 2013 +0200
@@ -102,7 +102,7 @@
body (RFC 5173): almost fully supported, but the text body-transform
implementation is simple and some issues make it still not completely
RFC compliant.
- environment (RFC 5183): basic support is provided (v0.1.5+).
+ environment (RFC 5183): fully supported (v0.1.5+).
variables (RFC 5229): fully supported.
vacation (RFC 5230): fully supported.
+ vacation-seconds (RFC 6131): fully supported (v0.2.3+).
diff -r 1a3a4545fa10 -r 9d38ca755000 src/lib-sieve-tool/sieve-tool.c
--- a/src/lib-sieve-tool/sieve-tool.c Thu Apr 11 20:42:41 2013 +0200
+++ b/src/lib-sieve-tool/sieve-tool.c Thu Apr 11 22:40:07 2013 +0200
@@ -271,8 +271,10 @@
memset((void *)&svenv, 0, sizeof(svenv));
svenv.username = username;
(void)mail_user_get_home(tool->mail_user_dovecot, &svenv.home_dir);
- svenv.hostname = "host.example.com";
+ svenv.hostname = my_hostdomain();
svenv.base_dir = tool->mail_user_dovecot->set->base_dir;
+ svenv.location = SIEVE_ENV_LOCATION_MS;
+ svenv.delivery_phase = SIEVE_DELIVERY_PHASE_POST;
/* Initialize Sieve Engine */
if ( (tool->svinst=sieve_init
diff -r 1a3a4545fa10 -r 9d38ca755000 src/lib-sieve/plugins/environment/ext-environment-common.c
--- a/src/lib-sieve/plugins/environment/ext-environment-common.c Thu Apr 11 20:42:41 2013 +0200
+++ b/src/lib-sieve/plugins/environment/ext-environment-common.c Thu Apr 11 22:40:07 2013 +0200
@@ -102,11 +102,8 @@
if ( item->value != NULL )
return item->value;
- if ( item->get_value != NULL ) {
- const char *value = item->get_value(ext->svinst, senv);
-
- return ( value == NULL ? "" : value );
- }
+ if ( item->get_value != NULL )
+ return item->get_value(ext->svinst, senv);
return NULL;
}
@@ -120,10 +117,17 @@
* The primary DNS domain associated with the Sieve execution context, usually
* but not always a proper suffix of the host name.
*/
+
+static const char *envit_domain_get_value
+(struct sieve_instance *svinst,
+ const struct sieve_script_env *senv ATTR_UNUSED)
+{
+ return svinst->domainname;
+}
+
const struct sieve_environment_item domain_env_item = {
- "domain",
- NULL,
- NULL,
+ .name = "domain",
+ .get_value = envit_domain_get_value,
};
/* "host":
@@ -133,15 +137,15 @@
*/
static const char *envit_host_get_value
-(struct sieve_instance *svinst, const struct sieve_script_env *senv ATTR_UNUSED)
+(struct sieve_instance *svinst,
+ const struct sieve_script_env *senv ATTR_UNUSED)
{
return svinst->hostname;
}
const struct sieve_environment_item host_env_item = {
- "host",
- NULL,
- envit_host_get_value,
+ .name = "host",
+ .get_value = envit_host_get_value,
};
/* "location":
@@ -151,13 +155,30 @@
* service that is evaluating the script. Possible values are:
* "MTA" - the Sieve script is being evaluated by a Message Transfer Agent
* "MDA" - evaluation is being performed by a Mail Delivery Agent
- * "MUA" - evaluation is being performed by a Mail User Agent
+ * "MUA" - evaluation is being performed by a Mail User Agent (right...)
* "MS" - evaluation is being performed by a Message Store
*/
+
+static const char *envit_location_get_value
+(struct sieve_instance *svinst,
+ const struct sieve_script_env *senv ATTR_UNUSED)
+{
+ switch ( svinst->env_location ) {
+ case SIEVE_ENV_LOCATION_MDA:
+ return "MDA";
+ case SIEVE_ENV_LOCATION_MTA:
+ return "MTA";
+ case SIEVE_ENV_LOCATION_MS:
+ return "MS";
+ default:
+ break;
+ }
+ return NULL;
+}
+
const struct sieve_environment_item location_env_item = {
- "location",
- NULL,
- NULL,
+ .name = "location",
+ .get_value = envit_location_get_value
};
/* "phase":
@@ -168,20 +189,36 @@
* taken place.
*/
+static const char *envit_phase_get_value
+(struct sieve_instance *svinst,
+ const struct sieve_script_env *senv ATTR_UNUSED)
+{
+ switch ( svinst->delivery_phase ) {
+ case SIEVE_DELIVERY_PHASE_PRE:
+ return "pre";
+ case SIEVE_DELIVERY_PHASE_DURING:
+ return "during";
+ case SIEVE_DELIVERY_PHASE_POST:
+ return "post";
+ default:
+ break;
+ }
+ return NULL;
+}
+
const struct sieve_environment_item phase_env_item = {
- "phase",
- NULL,
- NULL,
+ .name = "phase",
+ .get_value = envit_phase_get_value
};
/* "name":
*
* The product name associated with the Sieve interpreter.
*/
+
const struct sieve_environment_item name_env_item = {
- "name",
- PIGEONHOLE_NAME" Sieve",
- NULL,
+ .name = "name",
+ .value = PIGEONHOLE_NAME" Sieve"
};
/* "version":
@@ -192,9 +229,8 @@
*/
const struct sieve_environment_item version_env_item = {
- "version",
- PIGEONHOLE_VERSION,
- NULL,
+ .name = "version",
+ .value = PIGEONHOLE_VERSION,
};
diff -r 1a3a4545fa10 -r 9d38ca755000 src/lib-sieve/sieve-common.h
--- a/src/lib-sieve/sieve-common.h Thu Apr 11 20:42:41 2013 +0200
+++ b/src/lib-sieve/sieve-common.h Thu Apr 11 22:40:07 2013 +0200
@@ -157,6 +157,7 @@
/* System environment */
const char *hostname;
+ const char *domainname;
const char *base_dir;
/* User environment */
@@ -181,6 +182,8 @@
/* Plugin modules */
struct sieve_plugin *plugins;
+ enum sieve_env_location env_location;
+ enum sieve_delivery_phase delivery_phase;
/* Limits */
size_t max_script_size;
diff -r 1a3a4545fa10 -r 9d38ca755000 src/lib-sieve/sieve-types.h
--- a/src/lib-sieve/sieve-types.h Thu Apr 11 20:42:41 2013 +0200
+++ b/src/lib-sieve/sieve-types.h Thu Apr 11 22:40:07 2013 +0200
@@ -31,14 +31,39 @@
SIEVE_FLAG_HOME_RELATIVE = (1 << 0),
};
+/* Sieve evaluation can be performed at various different points as messages
+ are processed. */
+enum sieve_env_location {
+ /* Unknown */
+ SIEVE_ENV_LOCATION_UNKNOWN = 0,
+ /* "MDA" - evaluation is being performed by a Mail Delivery Agent */
+ SIEVE_ENV_LOCATION_MDA,
+ /* "MTA" - the Sieve script is being evaluated by a Message Transfer Agent */
+ SIEVE_ENV_LOCATION_MTA,
+ /* "MS" - evaluation is being performed by a Message Store */
+ SIEVE_ENV_LOCATION_MS
+};
+
+/* The point relative to final delivery where the Sieve script is being
+ evaluated. */
+enum sieve_delivery_phase {
+ SIEVE_DELIVERY_PHASE_UNKNOWN = 0,
+ SIEVE_DELIVERY_PHASE_PRE,
+ SIEVE_DELIVERY_PHASE_DURING,
+ SIEVE_DELIVERY_PHASE_POST,
+};
+
struct sieve_environment {
const char *hostname;
+ const char *domainname;
+
const char *base_dir;
-
const char *username;
const char *home_dir;
enum sieve_flag flags;
+ enum sieve_env_location location;
+ enum sieve_delivery_phase delivery_phase;
};
/*
diff -r 1a3a4545fa10 -r 9d38ca755000 src/lib-sieve/sieve.c
--- a/src/lib-sieve/sieve.c Thu Apr 11 20:42:41 2013 +0200
+++ b/src/lib-sieve/sieve.c Thu Apr 11 22:40:07 2013 +0200
@@ -49,6 +49,7 @@
struct sieve_instance *svinst;
unsigned long long int uint_setting;
size_t size_setting;
+ const char *domain;
pool_t pool;
/* Create Sieve engine instance */
@@ -58,11 +59,35 @@
svinst->callbacks = callbacks;
svinst->context = context;
svinst->debug = debug;
- svinst->hostname = p_strdup_empty(pool, env->hostname);
svinst->base_dir = p_strdup_empty(pool, env->base_dir);
svinst->username = p_strdup_empty(pool, env->username);
svinst->home_dir = p_strdup_empty(pool, env->home_dir);
svinst->flags = env->flags;
+ svinst->env_location = env->location;
+ svinst->delivery_phase = env->delivery_phase;
+
+ /* Determine domain */
+ if ( env->domainname != NULL && *(env->domainname) != '\0' ) {
+ domain = env->domainname;
+ } else {
+ /* Fall back to parsing username localpart at domain */
+ domain = strchr(svinst->username, '@');
+ if ( domain == NULL || *(domain+1) == '\0' ) {
+ /* Fall back to parsing hostname host.domain */
+ domain = ( env->hostname != NULL ? strchr(env->hostname, '.') : NULL );
+ if ( domain == NULL || *(domain+1) == '\0'
+ || strchr(domain+1, '.') == NULL ) {
+ /* Fall back to bare hostname */
+ domain = env->hostname;
+ } else {
+ domain++;
+ }
+ } else {
+ domain++;
+ }
+ }
+ svinst->hostname = p_strdup_empty(pool, env->hostname);
+ svinst->domainname = p_strdup(pool, domain);
sieve_errors_init(svinst);
diff -r 1a3a4545fa10 -r 9d38ca755000 src/plugins/lda-sieve/lda-sieve-plugin.c
--- a/src/plugins/lda-sieve/lda-sieve-plugin.c Thu Apr 11 20:42:41 2013 +0200
+++ b/src/plugins/lda-sieve/lda-sieve-plugin.c Thu Apr 11 22:40:07 2013 +0200
@@ -622,6 +622,8 @@
svenv.hostname = mdctx->set->hostname;
svenv.base_dir = mdctx->dest_user->set->base_dir;
svenv.flags = SIEVE_FLAG_HOME_RELATIVE;
+ svenv.location = SIEVE_ENV_LOCATION_MDA;
+ svenv.delivery_phase = SIEVE_DELIVERY_PHASE_DURING;
svinst = sieve_init(&svenv, &lda_sieve_callbacks, mdctx, debug);
diff -r 1a3a4545fa10 -r 9d38ca755000 tests/extensions/environment/basic.svtest
More information about the dovecot-cvs
mailing list