From 230cd1f3a4af96ec97328f030621a37876de0b6c Mon Sep 17 00:00:00 2001
From: Stephan Bosch <stephan@rename-it.nl>
Date: Thu, 29 Nov 2007 01:22:17 +0100
Subject: [PATCH] Added support for reading side effect operands.

---
 src/lib-sieve/plugins/copy/ext-copy.c |  6 +++--
 src/lib-sieve/sieve-actions.c         | 36 +++++++++++++++++++++++++++
 src/lib-sieve/sieve-actions.h         |  4 +++
 src/lib-sieve/sieve-address-parts.c   |  1 +
 src/lib-sieve/sieve-binary.h          |  4 +--
 src/lib-sieve/sieve-code.c            | 15 +++++++++--
 6 files changed, 60 insertions(+), 6 deletions(-)

diff --git a/src/lib-sieve/plugins/copy/ext-copy.c b/src/lib-sieve/plugins/copy/ext-copy.c
index 1960f7ced..1655ae9c9 100644
--- a/src/lib-sieve/plugins/copy/ext-copy.c
+++ b/src/lib-sieve/plugins/copy/ext-copy.c
@@ -74,9 +74,11 @@ static bool tag_copy_validate
 	struct sieve_ast_argument **arg ATTR_UNUSED, 
 	struct sieve_command_context *cmd ATTR_UNUSED)
 {
-	/* FIXME: currently not generated */
+	/* FIXME: currently not generated * /
 	*arg = sieve_ast_arguments_detach(*arg,1);
-		
+	*/	
+	*arg = sieve_ast_argument_next(*arg);
+
 	return TRUE;
 }
 
diff --git a/src/lib-sieve/sieve-actions.c b/src/lib-sieve/sieve-actions.c
index 41de0063c..6a00bf1f3 100644
--- a/src/lib-sieve/sieve-actions.c
+++ b/src/lib-sieve/sieve-actions.c
@@ -79,6 +79,42 @@ void sieve_opr_side_effect_emit
 		seffect->extension->side_effects_count > 1)
 }
 
+/* FIXME: Duplicated */
+const struct sieve_side_effect *sieve_opr_side_effect_read
+(struct sieve_binary *sbin, sieve_size_t *address)
+{
+	unsigned int seffect_code;
+	const struct sieve_operand *operand = sieve_operand_read(sbin, address);
+	
+	if ( operand == NULL || operand->class != &side_effect_class ) 
+		return NULL;
+	
+	if ( sieve_binary_read_byte(sbin, address, &seffect_code) ) {
+		int ext_id = -1;
+		const struct sieve_side_effect_extension *se_ext;
+
+		if ( sieve_binary_extension_get_by_index(sbin,
+			seffect_code, &ext_id) == NULL )
+			return NULL; 
+
+		se_ext = sieve_side_effect_extension_get(sbin, ext_id); 
+
+		if ( se_ext != NULL ) {  	
+			unsigned int code;
+			if ( se_ext->side_effects_count == 1 )
+				return se_ext->side_effects.single;
+	  	
+			if ( sieve_binary_read_byte(sbin, address, &code) )
+				return se_ext->side_effects.list[code];
+		} else {
+			i_info("Unknown action side-effect %d.", seffect_code); 
+		}
+	}		
+		
+	return NULL; 
+}
+
+
 /*
  * Actions common to multiple core commands 
  */
diff --git a/src/lib-sieve/sieve-actions.h b/src/lib-sieve/sieve-actions.h
index 64cdbd169..cdf12ff7a 100644
--- a/src/lib-sieve/sieve-actions.h
+++ b/src/lib-sieve/sieve-actions.h
@@ -86,6 +86,8 @@ struct sieve_side_effect_extension {
 #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
+
 void sieve_side_effect_extension_set
 	(struct sieve_binary *sbin, int ext_id,
 		const struct sieve_side_effect_extension *ext);
@@ -93,6 +95,8 @@ void sieve_side_effect_extension_set
 void sieve_opr_side_effect_emit
 	(struct sieve_binary *sbin, const struct sieve_side_effect *seffect, 
 		int ext_id);
+const struct sieve_side_effect *sieve_opr_side_effect_read
+	(struct sieve_binary *sbin, sieve_size_t *address);
 
 /* Actions common to multiple commands */
 
diff --git a/src/lib-sieve/sieve-address-parts.c b/src/lib-sieve/sieve-address-parts.c
index 4414a6521..f8155eb23 100644
--- a/src/lib-sieve/sieve-address-parts.c
+++ b/src/lib-sieve/sieve-address-parts.c
@@ -255,6 +255,7 @@ static void opr_address_part_emit_ext
 		(void) sieve_binary_emit_byte(sbin, addrp->ext_code);
 }
 
+/* FIXME: Duplicated */
 const struct sieve_address_part *sieve_opr_address_part_read
 (struct sieve_binary *sbin, sieve_size_t *address)
 {
diff --git a/src/lib-sieve/sieve-binary.h b/src/lib-sieve/sieve-binary.h
index 2daa12b3c..8f2fafc2f 100644
--- a/src/lib-sieve/sieve-binary.h
+++ b/src/lib-sieve/sieve-binary.h
@@ -88,7 +88,8 @@ void sieve_binary_registry_set_object
 	(struct sieve_binary *sbin, int ext_id, int id, const void *object);
 void sieve_binary_registry_init(struct sieve_binary *sbin, int ext_id);
 
-/* */
+/* These macros are not a very nice solution to the code duplication. I really
+ * need to think about this more */
 
 #define sieve_binary_emit_extension(sbin, obj, ext_id, base, operand, mult)   \
 	unsigned char code = base + sieve_binary_extension_get_index(sbin, ext_id); \
@@ -98,5 +99,4 @@ void sieve_binary_registry_init(struct sieve_binary *sbin, int ext_id);
 	if ( mult )                                                                 \
 		(void) sieve_binary_emit_byte(sbin, obj->ext_code);                       
 
-
 #endif
diff --git a/src/lib-sieve/sieve-code.c b/src/lib-sieve/sieve-code.c
index 6f61f6a9f..371d4fb6c 100644
--- a/src/lib-sieve/sieve-code.c
+++ b/src/lib-sieve/sieve-code.c
@@ -3,6 +3,7 @@
 
 #include "sieve-common.h"
 #include "sieve-extensions.h"
+#include "sieve-actions.h"
 #include "sieve-binary.h"
 #include "sieve-generator.h"
 #include "sieve-interpreter.h"
@@ -141,9 +142,19 @@ bool sieve_operand_optional_read(struct sieve_binary *sbin, sieve_size_t *addres
 {
 	unsigned int id;
 
-	if ( sieve_binary_read_byte(sbin, address, &id) ) {
+	while ( sieve_binary_read_byte(sbin, address, &id) ) {
 		*id_code = (int) id;
-		return TRUE;
+		
+		if ( *id_code == SIEVE_OPT_SIDE_EFFECT ) {
+			const struct sieve_side_effect *seffect = 
+				sieve_opr_side_effect_read(sbin, address);
+
+			printf("SIDE_EFFECT!!!\n");
+			if ( seffect == NULL ) return FALSE;
+			
+			printf("        : SIDE_EFFECT: %s\n", seffect->name);
+		} else 
+			return TRUE;
 	}
 	
 	*id_code = 0;
-- 
GitLab