]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
zlib plugin supports now bzip2 also.
authorTimo Sirainen <tss@iki.fi>
Tue, 8 Jul 2008 15:41:23 +0000 (21:11 +0530)
committerTimo Sirainen <tss@iki.fi>
Tue, 8 Jul 2008 15:41:23 +0000 (21:11 +0530)
--HG--
branch : HEAD

configure.in
src/plugins/Makefile.am
src/plugins/zlib/Makefile.am
src/plugins/zlib/istream-bzlib.c [new file with mode: 0644]
src/plugins/zlib/istream-zlib.c
src/plugins/zlib/istream-zlib.h
src/plugins/zlib/zlib-plugin.c

index 22f508d8a4e121b4da4474602273cee5bc752dd1..757cc2c5ccc46c636e379da633b3a4eb292952b0 100644 (file)
@@ -2176,12 +2176,21 @@ dnl **
 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/convert/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
index 6921c1e4030045909ae17ba5fb4a5c0de67aeb0d..59187a3703e142a06776aeecb36021f97ed596de 100644 (file)
@@ -1,4 +1,4 @@
-if BUILD_ZLIB
+if BUILD_ZLIB_PLUGIN
 ZLIB = zlib
 endif
 
index 82bc884dcf0977ff5f236fe9c01bc1017dceba39..0aa9696f12ead9d9882eb0a76a70ed817ee6065c 100644 (file)
@@ -12,10 +12,18 @@ lib20_zlib_plugin_la_LDFLAGS = -module -avoid-version
 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 --git a/src/plugins/zlib/istream-bzlib.c b/src/plugins/zlib/istream-bzlib.c
new file mode 100644 (file)
index 0000000..e75b78f
--- /dev/null
@@ -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
index c4818d9aa32a1cd6405d514b326a2bab2f1d4368..5d7a6a4c16b9141a1824a87e2c2588f869dbaf93 100644 (file)
@@ -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_private *stream, uoff_t v_offset, bool mark)
 
        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_private *stream, uoff_t v_offset, bool mark)
 
                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 fd)
 
        return i_stream_create(&zstream->istream, NULL, fd);
 }
+#endif
index f740bb8bbe8f25f7f07a8211e3bad475eb8a3cef..0f4ed03b4c2d14382d0717e84add3e4e63c1b68e 100644 (file)
@@ -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
index acf1a4be1bebcdbbb1da04bfce250f6e26677ac7..28b6a83c3dde81431d75affb904e70073f7d3caf 100644 (file)
 #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_storage_module,
                                  &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 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
+       /* 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);
+       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;
 
-       return header_size >= 2 && zheader &&
-               zheader[0] == 31 && zheader[1] == 139;
+       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(struct mail *_mail,
        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(struct mail *_mail,
                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(struct mail *_mail,
 
                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);
 }