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