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=
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
/* 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)
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);
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;
return i_stream_create(&zstream->istream, NULL, fd);
}
+#endif
#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)
&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,
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) {
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");
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);
}