dovecot-1.0: If maildir file has a "Z" flag, open it with zlib.

dovecot at dovecot.org dovecot at dovecot.org
Thu Oct 25 21:04:46 EEST 2007


details:   http://hg.dovecot.org/dovecot-1.0/rev/c09d0d958b33
changeset: 5428:c09d0d958b33
user:      Timo Sirainen <tss at iki.fi>
date:      Thu Oct 25 21:04:13 2007 +0300
description:
If maildir file has a "Z" flag, open it with zlib.

diffstat:

1 file changed, 86 insertions(+), 3 deletions(-)
src/plugins/zlib/zlib-plugin.c |   89 ++++++++++++++++++++++++++++++++++++++--

diffs (126 lines):

diff -r 8f43fd31eb40 -r c09d0d958b33 src/plugins/zlib/zlib-plugin.c
--- a/src/plugins/zlib/zlib-plugin.c	Sun Oct 21 03:00:08 2007 +0300
+++ b/src/plugins/zlib/zlib-plugin.c	Thu Oct 25 21:04:13 2007 +0300
@@ -5,13 +5,23 @@
 #include "istream-zlib.h"
 #include "home-expand.h"
 #include "istream.h"
-#include "mail-storage-private.h"
+#include "maildir/maildir-storage.h"
+#include "maildir/maildir-uidlist.h"
+#include "index-mail.h"
 #include "zlib-plugin.h"
 
 #include <fcntl.h>
 
 struct zlib_mail_storage {
 	struct mail_storage_vfuncs super;
+};
+
+struct zlib_mailbox {
+	struct mailbox_vfuncs super;
+};
+
+struct zlib_mail {
+	struct mail_vfuncs super;
 };
 
 #define ZLIB_CONTEXT(obj) \
@@ -29,6 +39,76 @@ static unsigned int zlib_storage_module_
 static unsigned int zlib_storage_module_id = 0;
 static bool zlib_storage_module_id_set = FALSE;
 
+static struct istream *
+zlib_maildir_get_stream(struct mail *_mail, struct message_size *hdr_size,
+			struct message_size *body_size)
+{
+	struct maildir_mailbox *mbox = (struct maildir_mailbox *)_mail->box;
+	struct mail_private *mail = (struct mail_private *)_mail;
+	struct index_mail *imail = (struct index_mail *)mail;
+	struct zlib_mail *zmail = ZLIB_CONTEXT(mail);
+	struct istream *input;
+	const char *fname, *p;
+        enum maildir_uidlist_rec_flag flags;
+	int fd;
+
+	if (imail->data.stream != NULL)
+		return zmail->super.get_stream(_mail, hdr_size, body_size);
+
+	input = zmail->super.get_stream(_mail, NULL, NULL);
+	if (input == NULL)
+		return NULL;
+	i_assert(input == imail->data.stream);
+
+	fname = maildir_uidlist_lookup(mbox->uidlist, _mail->uid, &flags);
+	i_assert(fname != NULL);
+	p = strstr(fname, ":2,");
+	if (p != NULL && strchr(p + 3, 'Z') != NULL) {
+		/* has a Z flag - it's compressed */
+		fd = dup(i_stream_get_fd(imail->data.stream));
+		if (fd == -1)
+			i_error("zlib plugin: dup() failed: %m");
+		i_stream_unref(&imail->data.stream);
+
+		if (fd == -1)
+			return NULL;
+		imail->data.stream = i_stream_create_zlib(fd, default_pool);
+	}
+	return index_mail_init_stream(imail, hdr_size, body_size);
+}
+
+static struct mail *
+zlib_maildir_mail_alloc(struct mailbox_transaction_context *t,
+			enum mail_fetch_field wanted_fields,
+			struct mailbox_header_lookup_ctx *wanted_headers)
+{
+	struct zlib_mailbox *zbox = ZLIB_CONTEXT(t->box);
+	struct zlib_mail *zmail;
+	struct mail *_mail;
+	struct mail_private *mail;
+
+	_mail = zbox->super.mail_alloc(t, wanted_fields, wanted_headers);
+	mail = (struct mail_private *)_mail;
+
+	zmail = p_new(mail->pool, struct zlib_mail, 1);
+	zmail->super = mail->v;
+
+	mail->v.get_stream = zlib_maildir_get_stream;
+	array_idx_set(&mail->module_contexts, zlib_storage_module_id, &zmail);
+	return _mail;
+}
+
+static void zlib_maildir_open_init(struct mailbox *box)
+{
+	struct zlib_mailbox *zbox;
+
+	zbox = p_new(box->pool, struct zlib_mailbox, 1);
+	zbox->super = box->v;
+	box->v.mail_alloc = zlib_maildir_mail_alloc;
+
+	array_idx_set(&box->module_contexts, zlib_storage_module_id, &zbox);
+}
+
 static struct mailbox *
 zlib_mailbox_open(struct mail_storage *storage, const char *name,
 		  struct istream *input, enum mailbox_open_flags flags)
@@ -38,8 +118,9 @@ zlib_mailbox_open(struct mail_storage *s
 	struct istream *zlib_input = NULL;
 	size_t len = strlen(name);
 
-	if (input == NULL && len > 3 && strcmp(name + len - 3, ".gz") == 0) {
-		/* Looks like a .gz file */
+	if (input == NULL && len > 3 && strcmp(name + len - 3, ".gz") == 0 &&
+	    strcmp(storage->name, "mbox") == 0) {
+		/* Looks like a .gz mbox file */
 		const char *path;
 		bool is_file;
 
@@ -61,6 +142,8 @@ zlib_mailbox_open(struct mail_storage *s
 	if (zlib_input != NULL)
 		i_stream_unref(&zlib_input);
 
+	if (strcmp(storage->name, "maildir") == 0) 
+		zlib_maildir_open_init(box);
 	return box;
 }
 


More information about the dovecot-cvs mailing list