From 3bd3f8c4b4a41b156ebaed388e002c120307f984 Mon Sep 17 00:00:00 2001
From: Stephan Bosch <stephan@rename-it.nl>
Date: Fri, 16 Nov 2007 23:36:03 +0100
Subject: [PATCH] Finished implementation of subaddress extension.

---
 .../plugins/subaddress/ext-subaddress.c       | 43 +++++++++++++++----
 .../plugins/subaddress/subaddress.sieve       |  5 ++-
 src/lib-sieve/sieve-address-parts.c           |  6 ++-
 src/lib-sieve/sieve-common.h                  |  2 +
 4 files changed, 43 insertions(+), 13 deletions(-)

diff --git a/src/lib-sieve/plugins/subaddress/ext-subaddress.c b/src/lib-sieve/plugins/subaddress/ext-subaddress.c
index 25f881471..d22ec9778 100644
--- a/src/lib-sieve/plugins/subaddress/ext-subaddress.c
+++ b/src/lib-sieve/plugins/subaddress/ext-subaddress.c
@@ -1,5 +1,16 @@
-#include <stdio.h>
-
+/* Extension subaddress 
+ * --------------------
+ *
+ * Author: Stephan Bosch
+ * Specification: RFC 3598
+ * Implementation: full, but not configurable
+ * Status: experimental, largely untested
+ * 
+ * FIXME: This extension is not configurable in any way. The separation 
+ * character is currently only configurable for compilation and not at runtime. 
+ *
+ */
+ 
 #include "sieve-common.h"
 
 #include "sieve-code.h"
@@ -10,7 +21,14 @@
 #include "sieve-generator.h"
 #include "sieve-interpreter.h"
 
+#include <string.h>
+
+/* Config */
+
+#define SUBADDRESS_DEFAULT_SEP_CHAR '+'
+
 /* Forward declarations */
+
 static bool ext_subaddress_load(int ext_id);
 static bool ext_subaddress_validator_load(struct sieve_validator *validator);
 static bool ext_subaddress_interpreter_load
@@ -18,7 +36,7 @@ static bool ext_subaddress_interpreter_load
 
 /* Extension definitions */
 
-int ext_my_id;
+static int ext_my_id;
 
 const struct sieve_extension subaddress_extension = { 
 	"subaddress", 
@@ -37,22 +55,30 @@ static bool ext_subaddress_load(int ext_id)
 	return TRUE;
 }
 
-/* */
+/* Actual extension implementation */
 
 static const char *subaddress_user_extract_from
 	(const struct message_address *address)
 {
-	i_info("subaddress: user: %s.", address->mailbox);
-	return address->mailbox;
+	const char *sep = strchr(address->mailbox, SUBADDRESS_DEFAULT_SEP_CHAR);
+	
+	if ( sep == NULL ) return address->mailbox;
+	
+	return t_strdup_until(address->mailbox, sep);
 }
 
 static const char *subaddress_detail_extract_from
 	(const struct message_address *address)
 {
-	i_info("subaddress: detail: %s.", address->mailbox);
-	return address->mailbox;
+	const char *sep = strchr(address->mailbox, SUBADDRESS_DEFAULT_SEP_CHAR);
+
+	if ( sep == NULL ) return NULL;
+		
+	return sep+1;
 }
 
+/* Extension access structures */
+
 enum ext_subaddress_address_part {
   SUBADDRESS_USER,
   SUBADDRESS_DETAIL
@@ -91,7 +117,6 @@ static const struct sieve_address_part *ext_subaddress_get_part
 
 const struct sieve_address_part_extension subaddress_addrp_extension = { 
 	NULL, 
-	
 	ext_subaddress_get_part
 };
 
diff --git a/src/lib-sieve/plugins/subaddress/subaddress.sieve b/src/lib-sieve/plugins/subaddress/subaddress.sieve
index 76031f7e3..1b4a0c715 100644
--- a/src/lib-sieve/plugins/subaddress/subaddress.sieve
+++ b/src/lib-sieve/plugins/subaddress/subaddress.sieve
@@ -4,10 +4,11 @@ require "fileinto";
 if address :comparator "i;ascii-casemap" :user "from" "STEPHAN" {
 	discard;
 
-	if address :domain :comparator "i;octet" "from" "drunksnipers.com" {
+	if address :detail :comparator "i;octet" "from" "sieve" {
 		keep;
+		stop;
 	}
-	stop;
+	fileinto "INBOX.frop";
 }
 
 keep;
diff --git a/src/lib-sieve/sieve-address-parts.c b/src/lib-sieve/sieve-address-parts.c
index e553ed9fa..40b2f3d75 100644
--- a/src/lib-sieve/sieve-address-parts.c
+++ b/src/lib-sieve/sieve-address-parts.c
@@ -105,6 +105,8 @@ const struct sieve_address_part *sieve_address_part_find
 	struct addrp_validator_registration *reg =
 		(struct addrp_validator_registration *) 
 			hash_lookup(ctx->registrations, identifier);
+			
+	if ( reg == NULL ) return NULL;
 
 	if ( ext_id != NULL ) *ext_id = reg->ext_id;
 
@@ -159,7 +161,7 @@ static inline struct addrp_interpreter_context *
 		sieve_interpreter_extension_get_context(interpreter, ext_my_id);
 }
 
-const struct sieve_address_part_extension *sieve_address_part_extension_get
+static const struct sieve_address_part_extension *sieve_address_part_extension_get
 	(struct sieve_interpreter *interpreter, int ext_id)
 {
 	struct addrp_interpreter_context *ctx = get_interpreter_context(interpreter);
@@ -382,7 +384,7 @@ bool sieve_address_stringlist_match
 
 			part = addrp->extract_from(addr);
 			
-			if ( sieve_stringlist_match(key_list, part, cmp) )
+			if ( part != NULL && sieve_stringlist_match(key_list, part, cmp) )
 				matched = TRUE;				
 		} 
 
diff --git a/src/lib-sieve/sieve-common.h b/src/lib-sieve/sieve-common.h
index e6ed4eb58..e3abdb544 100644
--- a/src/lib-sieve/sieve-common.h
+++ b/src/lib-sieve/sieve-common.h
@@ -1,6 +1,8 @@
 #ifndef __SIEVE_COMMON_H
 #define __SIEVE_COMMON_H
 
+#include <sys/types.h>
+
 /*
  * Predeclarations
  */
-- 
GitLab