From 4b8dc91a2b21f158863799822465613005cc993c Mon Sep 17 00:00:00 2001
From: Stephan Bosch <stephan@rename-it.nl>
Date: Mon, 24 Mar 2008 22:07:07 +0100
Subject: [PATCH] Include: moved implementation of binary extension to separate
 file.

---
 src/lib-sieve/plugins/include/Makefile.am     |   4 +-
 src/lib-sieve/plugins/include/cmd-export.c    |   2 +-
 .../plugins/include/ext-include-binary.c      | 274 ++++++++++++++++++
 .../plugins/include/ext-include-binary.h      |  18 ++
 .../plugins/include/ext-include-common.c      | 235 +--------------
 .../plugins/include/ext-include-common.h      |   8 +-
 src/lib-sieve/plugins/include/ext-include.c   |   8 -
 7 files changed, 303 insertions(+), 246 deletions(-)
 create mode 100644 src/lib-sieve/plugins/include/ext-include-binary.c
 create mode 100644 src/lib-sieve/plugins/include/ext-include-binary.h

diff --git a/src/lib-sieve/plugins/include/Makefile.am b/src/lib-sieve/plugins/include/Makefile.am
index ad6985690..585fac85b 100644
--- a/src/lib-sieve/plugins/include/Makefile.am
+++ b/src/lib-sieve/plugins/include/Makefile.am
@@ -17,7 +17,9 @@ cmds = \
 libsieve_ext_include_la_SOURCES = \
 	$(cmds) \
 	ext-include-common.c \
+	ext-include-binary.c \
 	ext-include.c
 
 noinst_HEADERS = \
-	ext-include-common.h
+	ext-include-common.h \
+	ext-include-binary.h
diff --git a/src/lib-sieve/plugins/include/cmd-export.c b/src/lib-sieve/plugins/include/cmd-export.c
index 049717abf..94d450ffd 100644
--- a/src/lib-sieve/plugins/include/cmd-export.c
+++ b/src/lib-sieve/plugins/include/cmd-export.c
@@ -59,7 +59,7 @@ static bool cmd_export_validate
 		return FALSE;
 	}
 	
-	/* Register imported variable */
+	/* Register exported variable */
 	if ( sieve_ast_argument_type(arg) == SAAT_STRING ) {
 		/* Single string */
 		const char *variable = sieve_ast_argument_strc(arg);
diff --git a/src/lib-sieve/plugins/include/ext-include-binary.c b/src/lib-sieve/plugins/include/ext-include-binary.c
new file mode 100644
index 000000000..5a4d42669
--- /dev/null
+++ b/src/lib-sieve/plugins/include/ext-include-binary.c
@@ -0,0 +1,274 @@
+#include "sieve-common.h"
+#include "sieve-error.h"
+#include "sieve-script.h"
+#include "sieve-binary.h"
+#include "sieve-generator.h"
+#include "sieve-interpreter.h"
+
+#include "ext-include-common.h"
+#include "ext-include-binary.h"
+
+/*
+ * Types
+ */
+ 
+struct _included_script {
+	struct sieve_script *script;
+	enum ext_include_script_location location;
+	
+	unsigned int block_id;
+};
+ 
+struct ext_include_binary_context {
+	struct sieve_binary *binary;
+	unsigned int dependency_block;
+	
+	struct hash_table *included_scripts;
+};
+
+/*
+ * Forward declarations
+ */
+ 
+static bool ext_include_binary_save(struct sieve_binary *sbin);
+static bool ext_include_binary_open(struct sieve_binary *sbin);
+static bool ext_include_binary_up_to_date(struct sieve_binary *sbin);
+static void ext_include_binary_free(struct sieve_binary *sbin);
+
+/* 
+ * Binary include extension
+ */
+ 
+const struct sieve_binary_extension include_binary_ext = {
+	&include_extension,
+	ext_include_binary_save,
+	ext_include_binary_open,
+	ext_include_binary_free,
+	ext_include_binary_up_to_date
+};
+
+/*
+ * Binary context management
+ */
+ 
+static struct ext_include_binary_context *ext_include_binary_create_context
+(struct sieve_binary *sbin)
+{
+	pool_t pool = sieve_binary_pool(sbin);
+	
+	struct ext_include_binary_context *ctx = 
+		p_new(pool, struct ext_include_binary_context, 1);
+	
+	ctx->binary = sbin;			
+	ctx->included_scripts = hash_create(pool, pool, 0, 
+		(hash_callback_t *) sieve_script_hash, 
+		(hash_cmp_callback_t *) sieve_script_cmp);
+	
+	return ctx;
+}
+
+static inline struct ext_include_binary_context *ext_include_binary_get_context
+(struct sieve_binary *sbin)
+{	
+	struct ext_include_binary_context *ctx = (struct ext_include_binary_context *)
+		sieve_binary_extension_get_context(sbin, ext_include_my_id);
+	
+	if ( ctx == NULL ) {
+		ctx = ext_include_binary_create_context(sbin);
+		sieve_binary_extension_set_context(sbin, ext_include_my_id, ctx);
+	};
+	
+	return ctx;
+}
+
+/* 
+ * Binary include implementation 
+ */
+ 
+struct ext_include_binary_context *ext_include_binary_init
+	(struct sieve_binary *sbin)
+{
+	struct ext_include_binary_context *ctx;
+	
+	/* Get/create our context from the binary we are working on */
+	ctx = ext_include_binary_get_context(sbin);
+	
+	/* Create dependency block */
+	if ( ctx->dependency_block == 0 )
+		ctx->dependency_block = 
+			sieve_binary_extension_create_block(sbin, ext_include_my_id);
+			
+	return ctx;
+}
+
+void ext_include_binary_script_include
+(struct ext_include_binary_context *binctx, struct sieve_script *script,
+	enum ext_include_script_location location, unsigned int block_id)
+{
+	pool_t pool = sieve_binary_pool(binctx->binary);
+	struct _included_script *incscript;
+	
+	incscript = p_new(pool, struct _included_script, 1);
+	incscript->script = script;
+	incscript->location = location;
+	incscript->block_id = block_id;
+	
+	printf("INCLUDE: %s\n", sieve_script_path(script));
+	
+	/* Unreferenced on binary_free */
+	sieve_script_ref(script);
+	
+	hash_insert(binctx->included_scripts, (void *) script, (void *) incscript);
+}
+
+bool ext_include_binary_script_is_included
+(struct ext_include_binary_context *binctx, struct sieve_script *script,
+	unsigned int *block_id)
+{
+	struct _included_script *incscript = (struct _included_script *)
+		hash_lookup(binctx->included_scripts, script);
+		
+	if ( incscript == 0 )
+		return FALSE;
+				
+	*block_id = incscript->block_id;
+	return TRUE;
+}
+
+static bool ext_include_binary_save(struct sieve_binary *sbin)
+{
+	struct ext_include_binary_context *binctx = 
+		ext_include_binary_get_context(sbin);
+	struct hash_iterate_context *hctx = 
+		hash_iterate_init(binctx->included_scripts);
+	void *key, *value;
+	unsigned int prvblk;
+	
+	sieve_binary_block_clear(sbin, binctx->dependency_block);
+	if ( !sieve_binary_block_set_active(sbin, binctx->dependency_block, &prvblk) )	
+		return FALSE;
+			
+	sieve_binary_emit_integer(sbin, hash_count(binctx->included_scripts));	
+	while ( hash_iterate(hctx, &key, &value) ) {
+		struct _included_script *incscript = (struct _included_script *) value;
+
+		sieve_binary_emit_integer(sbin, incscript->block_id);
+		sieve_binary_emit_byte(sbin, incscript->location);
+		sieve_binary_emit_cstring(sbin, sieve_script_name(incscript->script));
+	}
+	
+	(void) sieve_binary_block_set_active(sbin, prvblk, NULL);
+
+	hash_iterate_deinit(&hctx);
+	
+	return TRUE;
+}
+
+static bool ext_include_binary_open(struct sieve_binary *sbin)
+{
+	struct ext_include_binary_context *binctx; 
+	unsigned int block, prvblk, depcount, i;
+	sieve_size_t offset;
+	
+	block = sieve_binary_extension_get_block(sbin, ext_include_my_id);
+	
+	if ( !sieve_binary_block_set_active(sbin, block, &prvblk) )
+		return FALSE; 
+		
+	offset = 0;	
+		
+	if ( !sieve_binary_read_integer(sbin, &offset, &depcount) ) {
+		i_error("sieve: include: failed to read include count "
+			"for dependency block %d of binary %s", block, sieve_binary_path(sbin)); 
+		return FALSE;
+	}
+	
+	binctx = ext_include_binary_get_context(sbin);
+		
+	/* Read dependencies */
+	for ( i = 0; i < depcount; i++ ) {
+		unsigned int block_id;
+		enum ext_include_script_location location;
+		string_t *script_name;
+		const char *script_path;
+		struct sieve_script *script;
+		
+		if ( 
+			!sieve_binary_read_integer(sbin, &offset, &block_id) ||
+			!sieve_binary_read_byte(sbin, &offset, &location) ||
+			!sieve_binary_read_string(sbin, &offset, &script_name) ) {
+			/* Binary is corrupt, recompile */
+			i_error("sieve: include: failed to read included script "
+				"from dependency block %d of binary %s", block, sieve_binary_path(sbin)); 
+			return FALSE;
+		}
+		
+		printf("SCRIPT: %d %d %s\n", block_id, location, str_c(script_name));
+	
+		if ( location >= EXT_INCLUDE_LOCATION_INVALID ) {
+			/* Binary is corrupt, recompile */
+			i_error("sieve: include: dependency block %d of binary %s "
+				"reports invalid script location (id %d).", 
+				block, sieve_binary_path(sbin), location); 
+			return FALSE;
+		}		
+		
+		/* Can we find/open the script dependency ? */
+		script_path = ext_include_get_script_path(location, str_c(script_name));		
+		if ( script_path == NULL || 
+			!(script=sieve_script_create(script_path, str_c(script_name), NULL, NULL)) ) {
+			/* No, recompile */
+			return FALSE;
+		}
+		
+		ext_include_binary_script_include(binctx, script, location, block_id);
+				
+		sieve_script_unref(&script);
+	}
+	
+	/* Restore previously active block */
+	(void)sieve_binary_block_set_active(sbin, prvblk, NULL);
+
+	return TRUE;	
+}
+
+static bool ext_include_binary_up_to_date(struct sieve_binary *sbin)
+{
+	struct ext_include_binary_context *binctx = 
+		ext_include_binary_get_context(sbin);
+	struct hash_iterate_context *hctx;
+	void *key, *value;
+		
+	/* Release references to all included script objects */
+	hctx = hash_iterate_init(binctx->included_scripts);
+	while ( hash_iterate(hctx, &key, &value) ) {
+		struct _included_script *incscript = (struct _included_script *) value;
+		
+		/* Is the binary newer than this dependency? */
+		if ( !sieve_binary_script_older(sbin, incscript->script) ) {
+			/* No, recompile */
+			return FALSE;
+		}
+	}
+	hash_iterate_deinit(&hctx);
+
+	return TRUE;
+}
+
+static void ext_include_binary_free(struct sieve_binary *sbin)
+{
+	struct ext_include_binary_context *binctx = 
+		ext_include_binary_get_context(sbin);
+	struct hash_iterate_context *hctx;
+	void *key, *value;
+		
+	/* Release references to all included script objects */
+	hctx = hash_iterate_init(binctx->included_scripts);
+	while ( hash_iterate(hctx, &key, &value) ) {
+		struct _included_script *incscript = (struct _included_script *) value;
+		
+		sieve_script_unref(&incscript->script);
+	}
+	hash_iterate_deinit(&hctx);
+}
+
diff --git a/src/lib-sieve/plugins/include/ext-include-binary.h b/src/lib-sieve/plugins/include/ext-include-binary.h
new file mode 100644
index 000000000..0a2cfbc26
--- /dev/null
+++ b/src/lib-sieve/plugins/include/ext-include-binary.h
@@ -0,0 +1,18 @@
+#ifndef __EXT_INCLUDE_BINARY_H
+#define __EXT_INCLUDE_BINARY_H
+
+#include "sieve-common.h"
+
+struct ext_include_binary_context;
+
+struct ext_include_binary_context *ext_include_binary_init
+	(struct sieve_binary *sbin);
+void ext_include_binary_script_include
+	(struct ext_include_binary_context *binctx, struct sieve_script *script,
+		enum ext_include_script_location location, unsigned int block_id);
+bool ext_include_binary_script_is_included
+	(struct ext_include_binary_context *binctx, struct sieve_script *script,
+		unsigned int *block_id);
+		
+#endif
+
diff --git a/src/lib-sieve/plugins/include/ext-include-common.c b/src/lib-sieve/plugins/include/ext-include-common.c
index 4aacb8405..93c67d62b 100644
--- a/src/lib-sieve/plugins/include/ext-include-common.c
+++ b/src/lib-sieve/plugins/include/ext-include-common.c
@@ -9,6 +9,7 @@
 #include "sieve-ext-variables.h"
 
 #include "ext-include-common.h"
+#include "ext-include-binary.h"
 
 /*
  * Forward declarations
@@ -34,15 +35,6 @@ static inline struct ext_include_generator_context *
 	ext_include_get_generator_context
 	(struct sieve_generator *gentr);
 
-/* Binary context */
-
-struct ext_include_binary_context {
-	struct sieve_binary *binary;
-	unsigned int dependency_block;
-	
-	struct hash_table *included_scripts;
-};
-
 /* Interpreter context */
 
 struct ext_include_interpreter_context {
@@ -207,217 +199,6 @@ void ext_include_register_generator_context
 	}
 }
 
-/* 
- * Binary context functions 
- */
-
-struct _included_script {
-	struct sieve_script *script;
-	enum ext_include_script_location location;
-	
-	unsigned int block_id;
-};
-
-static struct ext_include_binary_context *ext_include_create_binary_context
-(struct sieve_binary *sbin)
-{
-	pool_t pool = sieve_binary_pool(sbin);
-	
-	struct ext_include_binary_context *ctx = 
-		p_new(pool, struct ext_include_binary_context, 1);
-	
-	ctx->binary = sbin;			
-	ctx->included_scripts = hash_create(pool, pool, 0, 
-		(hash_callback_t *) sieve_script_hash, 
-		(hash_cmp_callback_t *) sieve_script_cmp);
-	
-	return ctx;
-}
-
-static inline struct ext_include_binary_context *ext_include_get_binary_context
-(struct sieve_binary *sbin)
-{	
-	struct ext_include_binary_context *ctx = (struct ext_include_binary_context *)
-		sieve_binary_extension_get_context(sbin, ext_include_my_id);
-	
-	if ( ctx == NULL ) {
-		ctx = ext_include_create_binary_context(sbin);
-		sieve_binary_extension_set_context(sbin, ext_include_my_id, ctx);
-	};
-	
-	return ctx;
-}
-
-static void ext_include_script_include
-(struct ext_include_binary_context *binctx, struct sieve_script *script,
-	enum ext_include_script_location location, unsigned int block_id)
-{
-	pool_t pool = sieve_binary_pool(binctx->binary);
-	struct _included_script *incscript;
-	
-	incscript = p_new(pool, struct _included_script, 1);
-	incscript->script = script;
-	incscript->location = location;
-	incscript->block_id = block_id;
-	
-	printf("INCLUDE: %s\n", sieve_script_path(script));
-	
-	/* Unreferenced on binary_free */
-	sieve_script_ref(script);
-	
-	hash_insert(binctx->included_scripts, (void *) script, (void *) incscript);
-}
-
-static bool ext_include_script_is_included
-(struct ext_include_binary_context *binctx, struct sieve_script *script,
-	unsigned int *block_id)
-{
-	struct _included_script *incscript = (struct _included_script *)
-		hash_lookup(binctx->included_scripts, script);
-		
-	if ( incscript == 0 )
-		return FALSE;
-				
-	*block_id = incscript->block_id;
-	return TRUE;
-}
-
-bool ext_include_binary_save(struct sieve_binary *sbin)
-{
-	struct ext_include_binary_context *binctx = 
-		ext_include_get_binary_context(sbin);
-	struct hash_iterate_context *hctx = 
-		hash_iterate_init(binctx->included_scripts);
-	void *key, *value;
-	unsigned int prvblk;
-	
-	sieve_binary_block_clear(sbin, binctx->dependency_block);
-	if ( !sieve_binary_block_set_active(sbin, binctx->dependency_block, &prvblk) )	
-		return FALSE;
-			
-	sieve_binary_emit_integer(sbin, hash_count(binctx->included_scripts));	
-	while ( hash_iterate(hctx, &key, &value) ) {
-		struct _included_script *incscript = (struct _included_script *) value;
-
-		sieve_binary_emit_integer(sbin, incscript->block_id);
-		sieve_binary_emit_byte(sbin, incscript->location);
-		sieve_binary_emit_cstring(sbin, sieve_script_name(incscript->script));
-	}
-	
-	(void) sieve_binary_block_set_active(sbin, prvblk, NULL);
-
-	hash_iterate_deinit(&hctx);
-	
-	return TRUE;
-}
-
-bool ext_include_binary_open(struct sieve_binary *sbin)
-{
-	struct ext_include_binary_context *binctx; 
-	unsigned int block, prvblk, depcount, i;
-	sieve_size_t offset;
-	
-	block = sieve_binary_extension_get_block(sbin, ext_include_my_id);
-	
-	if ( !sieve_binary_block_set_active(sbin, block, &prvblk) )
-		return FALSE; 
-		
-	offset = 0;	
-		
-	if ( !sieve_binary_read_integer(sbin, &offset, &depcount) ) {
-		i_error("sieve: include: failed to read include count "
-			"for dependency block %d of binary %s", block, sieve_binary_path(sbin)); 
-		return FALSE;
-	}
-	
-	binctx = ext_include_get_binary_context(sbin);
-		
-	/* Read dependencies */
-	for ( i = 0; i < depcount; i++ ) {
-		unsigned int block_id;
-		enum ext_include_script_location location;
-		string_t *script_name;
-		const char *script_path;
-		struct sieve_script *script;
-		
-		if ( 
-			!sieve_binary_read_integer(sbin, &offset, &block_id) ||
-			!sieve_binary_read_byte(sbin, &offset, &location) ||
-			!sieve_binary_read_string(sbin, &offset, &script_name) ) {
-			/* Binary is corrupt, recompile */
-			i_error("sieve: include: failed to read included script "
-				"from dependency block %d of binary %s", block, sieve_binary_path(sbin)); 
-			return FALSE;
-		}
-		
-		printf("SCRIPT: %d %d %s\n", block_id, location, str_c(script_name));
-	
-		if ( location >= EXT_INCLUDE_LOCATION_INVALID ) {
-			/* Binary is corrupt, recompile */
-			i_error("sieve: include: dependency block %d of binary %s "
-				"reports invalid script location (id %d).", 
-				block, sieve_binary_path(sbin), location); 
-			return FALSE;
-		}		
-		
-		/* Can we find/open the script dependency ? */
-		script_path = ext_include_get_script_path(location, str_c(script_name));		
-		if ( script_path == NULL || 
-			!(script=sieve_script_create(script_path, str_c(script_name), NULL, NULL)) ) {
-			/* No, recompile */
-			return FALSE;
-		}
-		
-		ext_include_script_include(binctx, script, location, block_id);
-				
-		sieve_script_unref(&script);
-	}
-	
-	/* Restore previously active block */
-	(void)sieve_binary_block_set_active(sbin, prvblk, NULL);
-
-	return TRUE;	
-}
-
-bool ext_include_binary_up_to_date(struct sieve_binary *sbin)
-{
-	struct ext_include_binary_context *binctx = 
-		ext_include_get_binary_context(sbin);
-	struct hash_iterate_context *hctx;
-	void *key, *value;
-		
-	/* Release references to all included script objects */
-	hctx = hash_iterate_init(binctx->included_scripts);
-	while ( hash_iterate(hctx, &key, &value) ) {
-		struct _included_script *incscript = (struct _included_script *) value;
-		
-		/* Is the binary newer than this dependency? */
-		if ( !sieve_binary_script_older(sbin, incscript->script) ) {
-			/* No, recompile */
-			return FALSE;
-		}
-	}
-	hash_iterate_deinit(&hctx);
-
-	return TRUE;
-}
-
-void ext_include_binary_free(struct sieve_binary *sbin)
-{
-	struct ext_include_binary_context *binctx = 
-		ext_include_get_binary_context(sbin);
-	struct hash_iterate_context *hctx;
-	void *key, *value;
-		
-	/* Release references to all included script objects */
-	hctx = hash_iterate_init(binctx->included_scripts);
-	while ( hash_iterate(hctx, &key, &value) ) {
-		struct _included_script *incscript = (struct _included_script *) value;
-		
-		sieve_script_unref(&incscript->script);
-	}
-	hash_iterate_deinit(&hctx);
-}
 
 /* 
  * Interpreter context management 
@@ -531,22 +312,18 @@ bool ext_include_generate_include
 		pctx = pctx->parent;
 	}	
 
-	/* Get/create our context from the binary we are working on */
-	binctx = ext_include_get_binary_context(sbin);
-	
-	/* Create dependency block */
-	if ( binctx->dependency_block == 0 )
-		binctx->dependency_block = 
-			sieve_binary_extension_create_block(sbin, ext_include_my_id);
+	/* Initialize binary context */
+	binctx = ext_include_binary_init(sbin);
 
 	/* Is the script already compiled into the current binary? */
-	if ( !ext_include_script_is_included(binctx, script, &inc_block_id) )	{	
+	if ( !ext_include_binary_script_is_included(binctx, script, &inc_block_id) )	
+	{	
 		const char *script_name = sieve_script_name(script);
 		
 		/* No, allocate a new block in the binary and mark the script as included.
 		 */
 		inc_block_id = sieve_binary_block_create(sbin);
-		ext_include_script_include(binctx, script, location, inc_block_id);
+		ext_include_binary_script_include(binctx, script, location, inc_block_id);
 		
 		/* Parse */
 		if ( (ast = sieve_parse(script, ehandler)) == NULL ) {
diff --git a/src/lib-sieve/plugins/include/ext-include-common.h b/src/lib-sieve/plugins/include/ext-include-common.h
index cb389e53e..ff238ce69 100644
--- a/src/lib-sieve/plugins/include/ext-include-common.h
+++ b/src/lib-sieve/plugins/include/ext-include-common.h
@@ -14,6 +14,7 @@
 
 extern int ext_include_my_id;
 extern const struct sieve_extension include_extension;
+extern const struct sieve_binary_extension include_binary_ext;
 
 /* Commands */
 
@@ -58,13 +59,6 @@ bool ext_include_generate_include
 		enum ext_include_script_location location, struct sieve_script *script, 
 		unsigned *blk_id_r);
 
-/* Binary */
-
-bool ext_include_binary_save(struct sieve_binary *sbin);
-bool ext_include_binary_open(struct sieve_binary *sbin);
-bool ext_include_binary_up_to_date(struct sieve_binary *sbin);
-void ext_include_binary_free(struct sieve_binary *sbin);
-
 /* Interpreter */
 
 void ext_include_register_interpreter_context(struct sieve_interpreter *interp);
diff --git a/src/lib-sieve/plugins/include/ext-include.c b/src/lib-sieve/plugins/include/ext-include.c
index 2d12ebb6e..28536ef93 100644
--- a/src/lib-sieve/plugins/include/ext-include.c
+++ b/src/lib-sieve/plugins/include/ext-include.c
@@ -69,14 +69,6 @@ static bool ext_include_load(int ext_id)
 	return TRUE;
 }
 
-const struct sieve_binary_extension include_binary_ext = {
-	&include_extension,
-	ext_include_binary_save,
-	ext_include_binary_open,
-	ext_include_binary_free,
-	ext_include_binary_up_to_date
-};
-
 /* Load extension into validator */
 
 static bool ext_include_validator_load(struct sieve_validator *validator)
-- 
GitLab