Mercurial > dovecot > original-hg > dovecot-1.2
changeset 7981:bb9d3aabcb61 HEAD
zlib plugin supports now bzip2 also.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Tue, 08 Jul 2008 21:11:23 +0530 |
parents | b37d5d9b4c0c |
children | 140d9f439c0f |
files | configure.in src/plugins/Makefile.am src/plugins/zlib/Makefile.am src/plugins/zlib/istream-bzlib.c src/plugins/zlib/istream-zlib.c src/plugins/zlib/istream-zlib.h src/plugins/zlib/zlib-plugin.c |
diffstat | 7 files changed, 126 insertions(+), 22 deletions(-) [+] |
line wrap: on
line diff
--- a/configure.in Tue Jul 08 21:10:38 2008 +0530 +++ b/configure.in Tue Jul 08 21:11:23 2008 +0530 @@ -2176,12 +2176,21 @@ 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 RPCGEN= @@ -2255,6 +2264,7 @@ 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
--- 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_PLUGIN ZLIB = zlib endif
--- 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 = \ 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
--- /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
--- 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" +#ifdef BZLIB_INCLUDE +# define BUILD_SOURCE +#else +# include "lib.h" +# include "istream-internal.h" +# include "istream-zlib.h" +# include <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 @@ 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 @@ 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 @@ return i_stream_create(&zstream->istream, NULL, fd); } +#endif
--- 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
--- 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 @@ &mail_storage_module_register); static MODULE_CONTEXT_DEFINE_INIT(zlib_mail_module, &mail_module_register); -static int zlib_mail_is_compressed(struct istream *mail) +#ifdef HAVE_ZLIB +static bool is_compressed_zlib(struct istream *input) { - const unsigned char *zheader; - size_t header_size; + 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(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; - /* 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 - 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); + 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 - return header_size >= 2 && zheader && - zheader[0] == 31 && zheader[1] == 139; +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 @@ 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 @@ 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 @@ 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); }