dovecot-1.2: zlib plugin supports now bzip2 also.

dovecot at dovecot.org dovecot at dovecot.org
Tue Jul 8 18:41:31 EEST 2008


details:   http://hg.dovecot.org/dovecot-1.2/rev/bb9d3aabcb61
changeset: 7981:bb9d3aabcb61
user:      Timo Sirainen <tss at iki.fi>
date:      Tue Jul 08 21:11:23 2008 +0530
description:
zlib plugin supports now bzip2 also.

diffstat:

7 files changed, 130 insertions(+), 26 deletions(-)
configure.in                     |   12 +++++
src/plugins/Makefile.am          |    2 
src/plugins/zlib/Makefile.am     |   10 ++++
src/plugins/zlib/istream-bzlib.c |   20 +++++++++
src/plugins/zlib/istream-zlib.c  |   32 ++++++++++++---
src/plugins/zlib/istream-zlib.h  |    1 
src/plugins/zlib/zlib-plugin.c   |   79 ++++++++++++++++++++++++++++++--------

diffs (276 lines):

diff -r b37d5d9b4c0c -r bb9d3aabcb61 configure.in
--- a/configure.in	Tue Jul 08 21:10:38 2008 +0530
+++ b/configure.in	Tue Jul 08 21:11:23 2008 +0530
@@ -2176,11 +2176,20 @@ dnl ** Plugins
 dnl ** Plugins
 dnl **
 
-have_zlib=no
 AC_CHECK_HEADER(zlib.h, [
   have_zlib=yes
+  have_zlib_plugin=yes
+  AC_DEFINE(HAVE_ZLIB,, Define if you have zlib library)
 ])
 AM_CONDITIONAL(BUILD_ZLIB, test "$have_zlib" = "yes")
+
+AC_CHECK_HEADER(bzlib.h, [
+  have_bzlib=yes
+  have_zlib_plugin=yes
+  AC_DEFINE(HAVE_BZLIB,, Define if you have zlib library)
+])
+AM_CONDITIONAL(BUILD_BZLIB, test "$have_bzlib" = "yes")
+AM_CONDITIONAL(BUILD_ZLIB_PLUGIN, test "$have_zlib_plugin" = "yes")
 
 RPCGEN=${RPCGEN-rpcgen}
 if ! $RPCGEN -c /dev/null > /dev/null; then
@@ -2255,6 +2264,7 @@ src/plugins/expire/Makefile
 src/plugins/expire/Makefile
 src/plugins/fts/Makefile
 src/plugins/fts-lucene/Makefile
+src/plugins/fts-proxy/Makefile
 src/plugins/fts-squat/Makefile
 src/plugins/lazy-expunge/Makefile
 src/plugins/mail-log/Makefile
diff -r b37d5d9b4c0c -r bb9d3aabcb61 src/plugins/Makefile.am
--- a/src/plugins/Makefile.am	Tue Jul 08 21:10:38 2008 +0530
+++ b/src/plugins/Makefile.am	Tue Jul 08 21:11:23 2008 +0530
@@ -1,4 +1,4 @@ if BUILD_ZLIB
-if BUILD_ZLIB
+if BUILD_ZLIB_PLUGIN
 ZLIB = zlib
 endif
 
diff -r b37d5d9b4c0c -r bb9d3aabcb61 src/plugins/zlib/Makefile.am
--- a/src/plugins/zlib/Makefile.am	Tue Jul 08 21:10:38 2008 +0530
+++ b/src/plugins/zlib/Makefile.am	Tue Jul 08 21:11:23 2008 +0530
@@ -12,10 +12,18 @@ imap_module_LTLIBRARIES = \
 imap_module_LTLIBRARIES = \
 	lib20_zlib_plugin.la
 
+if BUILD_ZLIB
+ZLIB_LIB = -lz
+endif
+if BUILD_BZLIB
+BZLIB_LIB = -lbz2
+endif
+
 lib20_zlib_plugin_la_LIBADD = \
-	-lz
+	$(ZLIB_LIB) $(BZLIB_LIB)
 
 lib20_zlib_plugin_la_SOURCES = \
+	istream-bzlib.c \
 	istream-zlib.c \
 	zlib-plugin.c
 
diff -r b37d5d9b4c0c -r bb9d3aabcb61 src/plugins/zlib/istream-bzlib.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/plugins/zlib/istream-bzlib.c	Tue Jul 08 21:11:23 2008 +0530
@@ -0,0 +1,20 @@
+/* Copyright (c) 2005-2008 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "istream-internal.h"
+#include "istream-zlib.h"
+
+#ifdef HAVE_BZLIB
+#include <bzlib.h>
+
+#define BZLIB_INCLUDE
+
+#define gzFile BZFILE
+#define gzdopen BZ2_bzdopen
+#define gzclose BZ2_bzclose
+#define gzread BZ2_bzread
+#define gzseek BZ2_bzseek
+
+#define i_stream_create_zlib i_stream_create_bzlib
+#include "istream-zlib.c"
+#endif
diff -r b37d5d9b4c0c -r bb9d3aabcb61 src/plugins/zlib/istream-zlib.c
--- a/src/plugins/zlib/istream-zlib.c	Tue Jul 08 21:10:38 2008 +0530
+++ b/src/plugins/zlib/istream-zlib.c	Tue Jul 08 21:11:23 2008 +0530
@@ -1,11 +1,20 @@
 /* Copyright (c) 2005-2008 Dovecot authors, see the included COPYING file */
 
-#include "lib.h"
-#include "istream-internal.h"
-#include "istream-zlib.h"
-
-#include <zlib.h>
-
+#ifdef BZLIB_INCLUDE
+#  define BUILD_SOURCE
+#else
+#  include "lib.h"
+#  include "istream-internal.h"
+#  include "istream-zlib.h"
+#  include <zlib.h>
+
+#  ifdef HAVE_ZLIB
+#    define BUILD_SOURCE
+#    define HAVE_GZSEEK
+#  endif
+#endif
+
+#ifdef BUILD_SOURCE
 /* Default maximum buffer size. Seeking backwards is very expensive, so keep
    this pretty large */
 #define DEFAULT_MAX_BUFFER_SIZE (1024*1024)
@@ -113,6 +122,12 @@ i_stream_zlib_seek(struct istream_privat
 
 	stream->istream.stream_errno = 0;
 
+#ifndef HAVE_GZSEEK
+	if (v_offset < start_offset) {
+		gzclose(zstream->file);
+		zstream->file = gzdopen(zstream->fd, "r");
+	}
+#else
 	if (v_offset < start_offset) {
 		/* have to seek backwards */
 		gzseek(zstream->file, v_offset, SEEK_SET);
@@ -120,7 +135,9 @@ i_stream_zlib_seek(struct istream_privat
 
 		stream->skip = stream->pos = 0;
 		stream->istream.v_offset = v_offset;
-	} else if (v_offset <= start_offset + stream->pos) {
+	} else
+#endif
+	if (v_offset <= start_offset + stream->pos) {
 		/* seeking backwards within what's already cached */
 		stream->skip = v_offset - start_offset;
 		stream->istream.v_offset = v_offset;
@@ -220,3 +237,4 @@ struct istream *i_stream_create_zlib(int
 
 	return i_stream_create(&zstream->istream, NULL, fd);
 }
+#endif
diff -r b37d5d9b4c0c -r bb9d3aabcb61 src/plugins/zlib/istream-zlib.h
--- a/src/plugins/zlib/istream-zlib.h	Tue Jul 08 21:10:38 2008 +0530
+++ b/src/plugins/zlib/istream-zlib.h	Tue Jul 08 21:11:23 2008 +0530
@@ -2,5 +2,6 @@
 #define ISTREAM_ZLIB_H
 
 struct istream *i_stream_create_zlib(int fd);
+struct istream *i_stream_create_bzlib(int fd);
 
 #endif
diff -r b37d5d9b4c0c -r bb9d3aabcb61 src/plugins/zlib/zlib-plugin.c
--- a/src/plugins/zlib/zlib-plugin.c	Tue Jul 08 21:10:38 2008 +0530
+++ b/src/plugins/zlib/zlib-plugin.c	Tue Jul 08 21:11:23 2008 +0530
@@ -17,6 +17,11 @@
 #define ZLIB_MAIL_CONTEXT(obj) \
 	MODULE_CONTEXT(obj, zlib_mail_module)
 
+struct zlib_handler {
+	bool (*is_compressed)(struct istream *input);
+	struct istream *(*create_istream)(int fd);
+};
+
 const char *zlib_plugin_version = PACKAGE_VERSION;
 
 static void (*zlib_next_hook_mail_storage_created)
@@ -26,21 +31,61 @@ static MODULE_CONTEXT_DEFINE_INIT(zlib_s
 				  &mail_storage_module_register);
 static MODULE_CONTEXT_DEFINE_INIT(zlib_mail_module, &mail_module_register);
 
-static int zlib_mail_is_compressed(struct istream *mail)
-{
-	const unsigned char *zheader;
-	size_t header_size;
-
-	/* Peek in to the mail and see if it looks like it's compressed
-	   (it has the correct 2 byte zlib header). This also means that users
-	   can try to exploit security holes in zlib by APPENDing a specially
+#ifdef HAVE_ZLIB
+static bool is_compressed_zlib(struct istream *input)
+{
+	const unsigned char *data;
+	size_t size;
+
+	/* Peek in to the stream and see if it looks like it's compressed
+	   (based on its header). This also means that users can try to exploit
+	   security holes in the uncompression library by APPENDing a specially
 	   crafted mail. So let's hope zlib is free of holes. */
-	if (i_stream_read_data(mail, &zheader, &header_size, 2) <= 0)
-		return 0;
-	i_stream_seek(mail, 0);
-
-	return header_size >= 2 && zheader &&
-		zheader[0] == 31 && zheader[1] == 139;
+	if (i_stream_read_data(input, &data, &size, 1) <= 0)
+		return FALSE;
+	i_assert(size >= 2);
+
+	return data[0] == 31 && data[1] == 139;
+}
+#endif
+
+#ifdef HAVE_ZLIB
+static bool is_compressed_bzlib(struct istream *input)
+{
+	const unsigned char *data;
+	size_t size;
+
+	if (i_stream_read_data(input, &data, &size, 4+6 - 1) <= 0)
+		return FALSE;
+	if (data[0] != 'B' || data[1] != 'Z')
+		return FALSE;
+	if (data[2] != 'h' && data[2] != '0')
+		return FALSE;
+	if (data[3] < '1' || data[3] > '9')
+		return FALSE;
+	return memcmp(data + 4, "\x31\x41\x59\x26\x53\x59", 6) == 0;
+}
+#endif
+
+static struct zlib_handler zlib_handlers[] = {
+#ifdef HAVE_ZLIB
+	{ is_compressed_zlib, i_stream_create_zlib },
+#endif
+#ifdef HAVE_BZLIB
+	{ is_compressed_bzlib, i_stream_create_bzlib },
+#endif
+	{ NULL, NULL }
+};
+
+static struct zlib_handler *zlib_get_zlib_handler(struct istream *input)
+{
+	unsigned int i;
+
+	for (i = 0; i < N_ELEMENTS(zlib_handlers)-1; i++) {
+		if (zlib_handlers[i].is_compressed(input))
+			return &zlib_handlers[i];
+	}
+	return NULL;
 }
 
 static int zlib_maildir_get_stream(struct mail *_mail,
@@ -52,6 +97,7 @@ static int zlib_maildir_get_stream(struc
 	struct index_mail *imail = (struct index_mail *)mail;
 	union mail_module_context *zmail = ZLIB_MAIL_CONTEXT(mail);
 	struct istream *input;
+	struct zlib_handler *handler;
 	int fd;
 
 	if (imail->data.stream != NULL) {
@@ -63,7 +109,8 @@ static int zlib_maildir_get_stream(struc
 		return -1;
 	i_assert(input == imail->data.stream);
 
-	if (zlib_mail_is_compressed(imail->data.stream)) {
+	handler = zlib_get_zlib_handler(imail->data.stream);
+	if (handler != NULL) {
 		fd = dup(i_stream_get_fd(imail->data.stream));
 		if (fd == -1)
 			i_error("zlib plugin: dup() failed: %m");
@@ -74,7 +121,7 @@ static int zlib_maildir_get_stream(struc
 
 		if (fd == -1)
 			return -1;
-		imail->data.stream = i_stream_create_zlib(fd);
+		imail->data.stream = handler->create_istream(fd);
 	}
 	return index_mail_init_stream(imail, hdr_size, body_size, stream_r);
 }


More information about the dovecot-cvs mailing list