dovecot-2.2-pigeonhole: lib-sieve: Added version numbers to Siev...

pigeonhole at rename-it.nl pigeonhole at rename-it.nl
Tue Sep 18 15:38:15 EEST 2012


details:   http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/47c3b3dd8cf4
changeset: 1664:47c3b3dd8cf4
user:      Stephan Bosch <stephan at rename-it.nl>
date:      Tue Sep 18 14:37:55 2012 +0200
description:
lib-sieve: Added version numbers to Sieve extensions.
Those version numbers are now also stored in the binary, making sure it is recompiled
when a new version of an extension is used. This avoids updating the binary version
for minor changes to extensions and also makes this work for plugins.

diffstat:

 src/lib-sieve/sieve-binary-file.c |  47 +++++++++++++++++++++++++-------------
 src/lib-sieve/sieve-binary.h      |   4 +-
 src/lib-sieve/sieve-extensions.h  |   9 ++++++-
 3 files changed, 41 insertions(+), 19 deletions(-)

diffs (152 lines):

diff -r a80af8740468 -r 47c3b3dd8cf4 src/lib-sieve/sieve-binary-file.c
--- a/src/lib-sieve/sieve-binary-file.c	Tue Sep 18 14:02:12 2012 +0200
+++ b/src/lib-sieve/sieve-binary-file.c	Tue Sep 18 14:37:55 2012 +0200
@@ -233,11 +233,11 @@
 		sizeof(struct sieve_binary_block_index) * blk_count, &block_index) )
 		return FALSE;
 
-	/* Create block containing all used extensions
-	 *   FIXME: Per-extension this should also store binary version numbers.
-	 */
+	/* Create block containing all used extensions */
+
 	ext_block = sieve_binary_block_get(sbin, SBIN_SYSBLOCK_EXTENSIONS);
 	i_assert( ext_block != NULL );
+	sieve_binary_block_clear(ext_block);
 
 	ext_count = array_count(&sbin->linked_extensions);
 	sieve_binary_emit_unsigned(ext_block, ext_count);
@@ -248,6 +248,8 @@
 
 		sieve_binary_emit_cstring
 			(ext_block, sieve_extension_name((*ext)->extension));
+		sieve_binary_emit_unsigned
+			(ext_block, sieve_extension_version((*ext)->extension));
 		sieve_binary_emit_unsigned(ext_block, (*ext)->block_id);
 	}
 
@@ -719,38 +721,48 @@
 	return TRUE;
 }
 
-static bool _read_extensions(struct sieve_binary_block *sblock)
+static int _read_extensions(struct sieve_binary_block *sblock)
 {
 	struct sieve_binary *sbin = sblock->sbin;
 	sieve_size_t offset = 0;
 	unsigned int i, count;
-	bool result = TRUE;
+	bool result = 1;
 
 	if ( !sieve_binary_read_unsigned(sblock, &offset, &count) )
-		return FALSE;
+		return -1;
 
-	for ( i = 0; result && i < count; i++ ) {
+	for ( i = 0; result > 0 && i < count; i++ ) {
 		T_BEGIN {
 			string_t *extension;
 			const struct sieve_extension *ext;
+			unsigned int version;
 
 			if ( sieve_binary_read_string(sblock, &offset, &extension) ) {
 				ext = sieve_extension_get_by_name(sbin->svinst, str_c(extension));
 
 				if ( ext == NULL ) {
 					sieve_sys_error(sbin->svinst,
-						"binary open: binary %s requires unknown extension '%s'",
+						"binary open: binary %s requires unknown extension `%s'",
 						sbin->path, str_sanitize(str_c(extension), 128));
-					result = FALSE;
+					result = 0;
 				} else {
 					struct sieve_binary_extension_reg *ereg = NULL;
 
 					(void) sieve_binary_extension_register(sbin, ext, &ereg);
-					if ( !sieve_binary_read_unsigned(sblock, &offset, &ereg->block_id) )
-						result = FALSE;
+					if ( !sieve_binary_read_unsigned(sblock, &offset, &version) ||
+						!sieve_binary_read_unsigned(sblock, &offset, &ereg->block_id) ) {
+						result = -1;
+					} else if ( !sieve_extension_version_is(ext, version) ) {
+						sieve_sys_debug(sbin->svinst,
+							"binary open: binary %s was compiled with different version "
+							"of the `%s' extension (compiled v%d, expected v%d;"
+							"automatically fixed when re-compiled)", sbin->path,
+							sieve_extension_name(ext), version, sieve_extension_version(ext));
+						result = 0;
+					}
 				}
 			}	else
-				result = FALSE;
+				result = -1;
 		} T_END;
 	}
 
@@ -764,6 +776,7 @@
 	const struct sieve_binary_header *header;
 	struct sieve_binary_block *ext_block;
 	unsigned int i, blk_count;
+	int ret;
 
 	/* Verify header */
 
@@ -838,10 +851,12 @@
 		ext_block = sieve_binary_block_get(sbin, SBIN_SYSBLOCK_EXTENSIONS);
 		if ( ext_block == NULL ) {
 			result = FALSE;
-		} else if ( !_read_extensions(ext_block) ) {
-			sieve_sys_error(sbin->svinst,
-				"binary open: binary %s is corrupt: failed to load extension block",
-				sbin->path);
+		} else if ( (ret=_read_extensions(ext_block)) <= 0 ) {
+			if ( ret < 0 ) {
+				sieve_sys_error(sbin->svinst,
+					"binary open: binary %s is corrupt: failed to load extension block",
+					sbin->path);
+			}
 			result = FALSE;
 		}
 	} T_END;
diff -r a80af8740468 -r 47c3b3dd8cf4 src/lib-sieve/sieve-binary.h
--- a/src/lib-sieve/sieve-binary.h	Tue Sep 18 14:02:12 2012 +0200
+++ b/src/lib-sieve/sieve-binary.h	Tue Sep 18 14:37:55 2012 +0200
@@ -12,8 +12,8 @@
  * Config
  */
 
-#define SIEVE_BINARY_VERSION_MAJOR     0
-#define SIEVE_BINARY_VERSION_MINOR     4
+#define SIEVE_BINARY_VERSION_MAJOR     1
+#define SIEVE_BINARY_VERSION_MINOR     0
 
 /*
  * Binary object
diff -r a80af8740468 -r 47c3b3dd8cf4 src/lib-sieve/sieve-extensions.h
--- a/src/lib-sieve/sieve-extensions.h	Tue Sep 18 14:02:12 2012 +0200
+++ b/src/lib-sieve/sieve-extensions.h	Tue Sep 18 14:37:55 2012 +0200
@@ -23,6 +23,9 @@
 struct sieve_extension_def {
 	const char *name;
 
+	/* Version */
+	unsigned int version;
+
 	/* Registration */
 	bool (*load)(const struct sieve_extension *ext, void **context);
 	void (*unload)(const struct sieve_extension *ext);
@@ -97,9 +100,13 @@
 #define sieve_extension_is(ext, definition) \
 	( (ext)->def == &(definition) )
 #define sieve_extension_name(ext) \
-	(ext)->def->name
+	((ext)->def->name)
 #define sieve_extension_name_is(ext, _name) \
 	( strcmp((ext)->def->name, (_name)) == 0 )
+#define sieve_extension_version(ext) \
+	((ext)->def->version)
+#define sieve_extension_version_is(ext, _version) \
+	((ext)->def->version == (_version))
 
 /*
  * Extensions init/deinit


More information about the dovecot-cvs mailing list