zlib-plugin.c revision 1d2b188f0eedc3cab6e27ceac5425a037f38042e
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen/* Copyright (c) 2005-2009 Dovecot authors, see the included COPYING file */
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen#include "lib.h"
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen#include "array.h"
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen#include "istream-zlib.h"
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen#include "istream.h"
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen#include "maildir/maildir-storage.h"
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen#include "maildir/maildir-uidlist.h"
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen#include "index-mail.h"
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen#include "zlib-plugin.h"
82eadbc4311faf7719d5db33fddaa06cb3a7010bTimo Sirainen
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen#include <fcntl.h>
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen#define ZLIB_CONTEXT(obj) \
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen MODULE_CONTEXT(obj, zlib_storage_module)
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen#define ZLIB_MAIL_CONTEXT(obj) \
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen MODULE_CONTEXT(obj, zlib_mail_module)
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen#ifndef HAVE_ZLIB
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen# define i_stream_create_zlib NULL
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen#endif
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen#ifndef HAVE_BZLIB
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen# define i_stream_create_bzlib NULL
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen#endif
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainenstruct zlib_handler {
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen const char *ext;
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen bool (*is_compressed)(struct istream *input);
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen struct istream *(*create_istream)(int fd);
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen};
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainenconst char *zlib_plugin_version = PACKAGE_VERSION;
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainenstatic void (*zlib_next_hook_mail_storage_created)
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen (struct mail_storage *storage);
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainenstatic MODULE_CONTEXT_DEFINE_INIT(zlib_storage_module,
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen &mail_storage_module_register);
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainenstatic MODULE_CONTEXT_DEFINE_INIT(zlib_mail_module, &mail_module_register);
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainenstatic bool is_compressed_zlib(struct istream *input)
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen{
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen const unsigned char *data;
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen size_t size;
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen /* Peek in to the stream and see if it looks like it's compressed
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen (based on its header). This also means that users can try to exploit
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen security holes in the uncompression library by APPENDing a specially
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen crafted mail. So let's hope zlib is free of holes. */
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen if (i_stream_read_data(input, &data, &size, 1) <= 0)
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen return FALSE;
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen i_assert(size >= 2);
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen
a9b3887f4d9ed75a76fed964c1930432bf84f4f5Timo Sirainen return data[0] == 31 && data[1] == 139;
a9b3887f4d9ed75a76fed964c1930432bf84f4f5Timo Sirainen}
a9b3887f4d9ed75a76fed964c1930432bf84f4f5Timo Sirainen
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainenstatic bool is_compressed_bzlib(struct istream *input)
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen{
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen const unsigned char *data;
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen size_t size;
a9b3887f4d9ed75a76fed964c1930432bf84f4f5Timo Sirainen
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen if (i_stream_read_data(input, &data, &size, 4+6 - 1) <= 0)
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen return FALSE;
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen if (data[0] != 'B' || data[1] != 'Z')
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen return FALSE;
a9b3887f4d9ed75a76fed964c1930432bf84f4f5Timo Sirainen if (data[2] != 'h' && data[2] != '0')
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen return FALSE;
a9b3887f4d9ed75a76fed964c1930432bf84f4f5Timo Sirainen if (data[3] < '1' || data[3] > '9')
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen return FALSE;
a9b3887f4d9ed75a76fed964c1930432bf84f4f5Timo Sirainen return memcmp(data + 4, "\x31\x41\x59\x26\x53\x59", 6) == 0;
a9b3887f4d9ed75a76fed964c1930432bf84f4f5Timo Sirainen}
a9b3887f4d9ed75a76fed964c1930432bf84f4f5Timo Sirainen
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainenstatic struct zlib_handler zlib_handlers[] = {
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen { ".gz", is_compressed_zlib, i_stream_create_zlib },
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen { ".bz2", is_compressed_bzlib, i_stream_create_bzlib }
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen};
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainenstatic struct zlib_handler *zlib_get_zlib_handler(struct istream *input)
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen{
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen unsigned int i;
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen for (i = 0; i < N_ELEMENTS(zlib_handlers); i++) {
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen if (zlib_handlers[i].is_compressed(input))
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen return &zlib_handlers[i];
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen }
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen return NULL;
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen}
a9b3887f4d9ed75a76fed964c1930432bf84f4f5Timo Sirainen
a9b3887f4d9ed75a76fed964c1930432bf84f4f5Timo Sirainenstatic struct zlib_handler *zlib_get_zlib_handler_ext(const char *name)
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen{
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen unsigned int i, len, name_len = strlen(name);
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen for (i = 0; i < N_ELEMENTS(zlib_handlers); i++) {
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen len = strlen(zlib_handlers[i].ext);
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen if (name_len > len &&
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen strcmp(name + name_len - len, zlib_handlers[i].ext) == 0)
82eadbc4311faf7719d5db33fddaa06cb3a7010bTimo Sirainen return &zlib_handlers[i];
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen }
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen return NULL;
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen}
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainenstatic int zlib_maildir_get_stream(struct mail *_mail,
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen struct message_size *hdr_size,
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen struct message_size *body_size,
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen struct istream **stream_r)
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen{
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen struct mail_private *mail = (struct mail_private *)_mail;
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen struct index_mail *imail = (struct index_mail *)mail;
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen union mail_module_context *zmail = ZLIB_MAIL_CONTEXT(mail);
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen struct istream *input;
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen struct zlib_handler *handler;
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen int fd;
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen if (imail->data.stream != NULL) {
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen return zmail->super.get_stream(_mail, hdr_size, body_size,
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen stream_r);
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen }
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen if (zmail->super.get_stream(_mail, NULL, NULL, &input) < 0)
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen return -1;
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen i_assert(input == imail->data.stream);
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen handler = zlib_get_zlib_handler(imail->data.stream);
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen if (handler != NULL) {
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen if (handler->create_istream == NULL) {
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen mail_storage_set_critical(_mail->box->storage,
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen "zlib plugin: Detected %s compression "
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen "but support not compiled in", handler->ext);
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen fd = -1;
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen } else {
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen fd = dup(i_stream_get_fd(imail->data.stream));
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen if (fd == -1) {
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen mail_storage_set_critical(_mail->box->storage,
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen "zlib plugin: dup() failed: %m");
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen }
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen }
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen imail->data.destroying_stream = TRUE;
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen i_stream_unref(&imail->data.stream);
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen i_assert(!imail->data.destroying_stream);
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen if (fd == -1)
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen return -1;
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen imail->data.stream = handler->create_istream(fd);
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen }
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen return index_mail_init_stream(imail, hdr_size, body_size, stream_r);
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen}
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainenstatic struct mail *
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainenzlib_maildir_mail_alloc(struct mailbox_transaction_context *t,
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen enum mail_fetch_field wanted_fields,
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen struct mailbox_header_lookup_ctx *wanted_headers)
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen{
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen union mailbox_module_context *zbox = ZLIB_CONTEXT(t->box);
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen union mail_module_context *zmail;
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen struct mail *_mail;
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen struct mail_private *mail;
82eadbc4311faf7719d5db33fddaa06cb3a7010bTimo Sirainen
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen _mail = zbox->super.mail_alloc(t, wanted_fields, wanted_headers);
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen mail = (struct mail_private *)_mail;
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen zmail = p_new(mail->pool, union mail_module_context, 1);
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen zmail->super = mail->v;
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen mail->v.get_stream = zlib_maildir_get_stream;
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen MODULE_CONTEXT_SET_SELF(mail, zlib_mail_module, zmail);
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen return _mail;
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen}
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainenstatic void zlib_maildir_open_init(struct mailbox *box)
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen{
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen union mailbox_module_context *zbox;
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen zbox = p_new(box->pool, union mailbox_module_context, 1);
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen zbox->super = box->v;
82eadbc4311faf7719d5db33fddaa06cb3a7010bTimo Sirainen box->v.mail_alloc = zlib_maildir_mail_alloc;
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen MODULE_CONTEXT_SET_SELF(box, zlib_storage_module, zbox);
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen}
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainenstatic struct istream *
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainenzlib_mailbox_open_input(struct mail_storage *storage, struct mailbox_list *list,
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen const char *name)
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen{
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen struct zlib_handler *handler;
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen const char *path;
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen int fd;
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen
a6f1ded5a5df8ba467c4026e9cd9c15e6880997bTimo Sirainen handler = zlib_get_zlib_handler_ext(name);
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen if (handler == NULL || handler->create_istream == NULL)
a6f1ded5a5df8ba467c4026e9cd9c15e6880997bTimo Sirainen return NULL;
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen if (mail_storage_is_mailbox_file(storage)) {
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen /* looks like a compressed single file mailbox. we should be
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen able to handle this. */
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen path = mailbox_list_get_path(list, name,
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen MAILBOX_LIST_PATH_TYPE_MAILBOX);
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen fd = open(path, O_RDONLY);
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen if (fd != -1)
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen return handler->create_istream(fd);
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen }
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen return NULL;
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen}
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainenstatic struct mailbox *
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainenzlib_mailbox_alloc(struct mail_storage *storage, struct mailbox_list *list,
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen const char *name, struct istream *input,
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen enum mailbox_flags flags)
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen{
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen union mail_storage_module_context *qstorage = ZLIB_CONTEXT(storage);
82eadbc4311faf7719d5db33fddaa06cb3a7010bTimo Sirainen struct mailbox *box;
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen struct istream *zlib_input = NULL;
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen if (input == NULL && strcmp(storage->name, "mbox") == 0) {
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen input = zlib_input =
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen zlib_mailbox_open_input(storage, list, name);
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen }
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen box = qstorage->super.mailbox_alloc(storage, list, name, input, flags);
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen if (zlib_input != NULL)
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen i_stream_unref(&zlib_input);
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen if (strcmp(box->storage->name, "maildir") == 0)
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen zlib_maildir_open_init(box);
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen return box;
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen}
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainenstatic void zlib_mail_storage_created(struct mail_storage *storage)
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen{
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen union mail_storage_module_context *qstorage;
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen qstorage = p_new(storage->pool, union mail_storage_module_context, 1);
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen qstorage->super = storage->v;
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen storage->v.mailbox_alloc = zlib_mailbox_alloc;
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen MODULE_CONTEXT_SET_SELF(storage, zlib_storage_module, qstorage);
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen if (zlib_next_hook_mail_storage_created != NULL)
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen zlib_next_hook_mail_storage_created(storage);
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen}
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainenvoid zlib_plugin_init(void)
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen{
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen zlib_next_hook_mail_storage_created =
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen hook_mail_storage_created;
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen hook_mail_storage_created = zlib_mail_storage_created;
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen}
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainenvoid zlib_plugin_deinit(void)
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen{
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen hook_mail_storage_created =
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen zlib_next_hook_mail_storage_created;
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen}
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen