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