dovecot-2.0: Added imap-zlib plugin for enabling COMPRESS=DEFLAT...
dovecot at dovecot.org
dovecot at dovecot.org
Sat Feb 13 05:46:27 EET 2010
details: http://hg.dovecot.org/dovecot-2.0/rev/29f5567e0a9a
changeset: 10699:29f5567e0a9a
user: Timo Sirainen <tss at iki.fi>
date: Sat Feb 13 05:46:17 2010 +0200
description:
Added imap-zlib plugin for enabling COMPRESS=DEFLATE extension.
diffstat:
configure.in | 1 +
src/plugins/Makefile.am | 2 +-
src/plugins/imap-zlib/Makefile.am | 26 +++++
src/plugins/imap-zlib/imap-zlib-plugin.c | 157 +++++++++++++++++++++++++++++++
src/plugins/imap-zlib/imap-zlib-plugin.h | 11 ++
src/plugins/zlib/zlib-plugin.c | 61 +++++------
src/plugins/zlib/zlib-plugin.h | 12 ++
7 files changed, 236 insertions(+), 34 deletions(-)
diffs (truncated from 386 to 300 lines):
diff -r 15feca627630 -r 29f5567e0a9a configure.in
--- a/configure.in Sat Feb 13 05:45:23 2010 +0200
+++ b/configure.in Sat Feb 13 05:46:17 2010 +0200
@@ -2669,6 +2669,7 @@
src/plugins/trash/Makefile
src/plugins/virtual/Makefile
src/plugins/zlib/Makefile
+src/plugins/imap-zlib/Makefile
stamp.h
dovecot-config.in])
diff -r 15feca627630 -r 29f5567e0a9a src/plugins/Makefile.am
--- a/src/plugins/Makefile.am Sat Feb 13 05:45:23 2010 +0200
+++ b/src/plugins/Makefile.am Sat Feb 13 05:46:17 2010 +0200
@@ -1,5 +1,5 @@
if BUILD_ZLIB_PLUGIN
-ZLIB = zlib
+ZLIB = zlib imap-zlib
endif
if BUILD_LUCENE
diff -r 15feca627630 -r 29f5567e0a9a src/plugins/imap-zlib/Makefile.am
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/plugins/imap-zlib/Makefile.am Sat Feb 13 05:46:17 2010 +0200
@@ -0,0 +1,26 @@
+AM_CPPFLAGS = \
+ -I$(top_srcdir)/src/lib \
+ -I$(top_srcdir)/src/lib-mail \
+ -I$(top_srcdir)/src/lib-imap \
+ -I$(top_srcdir)/src/lib-index \
+ -I$(top_srcdir)/src/lib-storage \
+ -I$(top_srcdir)/src/imap \
+ -I$(top_srcdir)/src/plugins/zlib
+
+imap_moduledir = $(moduledir)
+
+lib30_imap_zlib_plugin_la_LDFLAGS = -module -avoid-version
+
+imap_module_LTLIBRARIES = \
+ lib30_imap_zlib_plugin.la
+
+if PLUGIN_DEPS
+lib30_imap_zlib_plugin_la_LIBADD = \
+ ../zlib/lib20_zlib_plugin.la
+endif
+
+lib30_imap_zlib_plugin_la_SOURCES = \
+ imap-zlib-plugin.c
+
+noinst_HEADERS = \
+ imap-zlib-plugin.h
diff -r 15feca627630 -r 29f5567e0a9a src/plugins/imap-zlib/imap-zlib-plugin.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/plugins/imap-zlib/imap-zlib-plugin.c Sat Feb 13 05:46:17 2010 +0200
@@ -0,0 +1,157 @@
+/* Copyright (c) 2010 Dovecot authors, see the included COPYING file */
+
+#include "imap-common.h"
+#include "str.h"
+#include "istream.h"
+#include "ostream.h"
+#include "module-context.h"
+#include "imap-commands.h"
+#include "zlib-plugin.h"
+#include "imap-zlib-plugin.h"
+
+#include <stdlib.h>
+
+#define IMAP_COMPRESS_DEFAULT_LEVEL 6
+
+#define IMAP_ZLIB_IMAP_CONTEXT(obj) \
+ MODULE_CONTEXT(obj, imap_zlib_imap_module)
+
+struct zlib_client {
+ union imap_module_context module_ctx;
+
+ const struct zlib_handler *handler;
+};
+
+const char *imap_zlib_plugin_version = DOVECOT_VERSION;
+
+static struct module *imap_zlib_module;
+static void (*next_hook_client_created)(struct client **client);
+
+static MODULE_CONTEXT_DEFINE_INIT(imap_zlib_imap_module,
+ &imap_module_register);
+
+static void client_skip_line(struct client *client)
+{
+ const unsigned char *data;
+ size_t data_size;
+
+ data = i_stream_get_data(client->input, &data_size);
+ i_assert(data_size > 0);
+ if (data[0] == '\n')
+ i_stream_skip(client->input, 1);
+ else if (data[0] == '\r' && data_size > 1 && data[1] == '\n')
+ i_stream_skip(client->input, 2);
+ else
+ i_unreached();
+ client->input_skip_line = FALSE;
+}
+
+static void client_update_imap_parser_streams(struct client *client)
+{
+ struct client_command_context *cmd;
+
+ if (client->free_parser != NULL) {
+ imap_parser_set_streams(client->free_parser,
+ client->input, client->output);
+ }
+
+ for (cmd = client->command_queue; cmd != NULL; cmd = cmd->next) {
+ imap_parser_set_streams(cmd->parser,
+ client->input, client->output);
+ }
+}
+
+static bool cmd_compress(struct client_command_context *cmd)
+{
+ struct client *client = cmd->client;
+ struct zlib_client *zclient = IMAP_ZLIB_IMAP_CONTEXT(client);
+ const struct zlib_handler *handler;
+ const struct imap_arg *args;
+ struct istream *old_input;
+ struct ostream *old_output;
+ const char *mechanism, *value;
+ int level;
+
+ /* <mechanism> */
+ if (!client_read_args(cmd, 0, 0, &args))
+ return FALSE;
+
+ mechanism = imap_arg_string(&args[0]);
+ if (mechanism == NULL || args[1].type != IMAP_ARG_EOL) {
+ client_send_command_error(cmd, "Invalid arguments.");
+ return TRUE;
+ }
+ if (zclient->handler != NULL) {
+ client_send_tagline(cmd, t_strdup_printf(
+ "NO [COMPRESSIONACTIVE] COMPRESSION=%s already enabled.",
+ t_str_ucase(zclient->handler->name)));
+ return TRUE;
+ }
+ if (client->tls_compression) {
+ client_send_tagline(cmd,
+ "NO [COMPRESSIONACTIVE] TLS compression already enabled.");
+ return TRUE;
+ }
+
+
+ handler = zlib_find_zlib_handler(t_str_lcase(mechanism));
+ if (handler == NULL || handler->create_istream == NULL) {
+ client_send_tagline(cmd, "NO Unknown compression mechanism.");
+ return TRUE;
+ }
+
+ client_skip_line(client);
+ client_send_tagline(cmd, "OK Begin compression.");
+
+ value = mail_user_plugin_getenv(client->user,
+ "imap_zlib_compress_level");
+ level = value == NULL ? 0 : atoi(value);
+ if (level <= 0 || level > 9)
+ level = IMAP_COMPRESS_DEFAULT_LEVEL;
+
+ old_input = client->input;
+ old_output = client->output;
+ client->input = handler->create_istream(old_input);
+ client->output = handler->create_ostream(old_output, level);
+ i_stream_unref(&old_input);
+ o_stream_unref(&old_output);
+
+ client_update_imap_parser_streams(client);
+ zclient->handler = handler;
+ return TRUE;
+}
+
+static void imap_zlib_client_created(struct client **clientp)
+{
+ struct client *client = *clientp;
+ struct zlib_client *zclient;
+
+ if (mail_user_is_plugin_loaded(client->user, imap_zlib_module) &&
+ zlib_find_zlib_handler("deflate") != NULL) {
+ zclient = p_new(client->pool, struct zlib_client, 1);
+ MODULE_CONTEXT_SET(client, imap_zlib_imap_module, zclient);
+
+ str_append(client->capability_string, " COMPRESS=DEFLATE");
+ }
+
+ if (next_hook_client_created != NULL)
+ next_hook_client_created(clientp);
+}
+
+void imap_zlib_plugin_init(struct module *module)
+{
+ command_register("COMPRESS", cmd_compress, 0);
+
+ imap_zlib_module = module;
+ next_hook_client_created = hook_client_created;
+ hook_client_created = imap_zlib_client_created;
+}
+
+void imap_zlib_plugin_deinit(void)
+{
+ command_unregister("COMPRESS");
+
+ hook_client_created = next_hook_client_created;
+}
+
+const char *imap_zlib_plugin_dependencies[] = { "zlib", NULL };
diff -r 15feca627630 -r 29f5567e0a9a src/plugins/imap-zlib/imap-zlib-plugin.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/plugins/imap-zlib/imap-zlib-plugin.h Sat Feb 13 05:46:17 2010 +0200
@@ -0,0 +1,11 @@
+#ifndef IMAP_ZLIB_PLUGIN_H
+#define IMAP_ZLIB_PLUGIN_H
+
+struct module;
+
+extern const char *imap_zlib_plugin_dependencies[];
+
+void imap_zlib_plugin_init(struct module *module);
+void imap_zlib_plugin_deinit(void);
+
+#endif
diff -r 15feca627630 -r 29f5567e0a9a src/plugins/zlib/zlib-plugin.c
--- a/src/plugins/zlib/zlib-plugin.c Sat Feb 13 05:45:23 2010 +0200
+++ b/src/plugins/zlib/zlib-plugin.c Sat Feb 13 05:46:17 2010 +0200
@@ -34,14 +34,6 @@
#define MAX_INBUF_SIZE (1024*1024)
-struct zlib_handler {
- const char *name;
- const char *ext;
- bool (*is_compressed)(struct istream *input);
- struct istream *(*create_istream)(struct istream *input);
- struct ostream *(*create_ostream)(struct ostream *output, int level);
-};
-
struct zlib_transaction_context {
union mailbox_transaction_module_context module_ctx;
@@ -51,7 +43,7 @@
struct zlib_user {
union mail_user_module_context module_ctx;
- struct zlib_handler *save_handler;
+ const struct zlib_handler *save_handler;
int save_level;
};
@@ -95,40 +87,37 @@
return memcmp(data + 4, "\x31\x41\x59\x26\x53\x59", 6) == 0;
}
-static struct zlib_handler zlib_handlers[] = {
- { "gz", ".gz", is_compressed_zlib,
- i_stream_create_gz, o_stream_create_gz },
- { "bz2", ".bz2", is_compressed_bzlib,
- i_stream_create_bz2, o_stream_create_bz2 }
-};
-
-static struct zlib_handler *zlib_find_zlib_handler(const char *name)
+const struct zlib_handler *zlib_find_zlib_handler(const char *name)
{
unsigned int i;
- for (i = 0; i < N_ELEMENTS(zlib_handlers); i++) {
+ for (i = 0; zlib_handlers[i].name != NULL; i++) {
if (strcmp(name, zlib_handlers[i].name) == 0)
return &zlib_handlers[i];
}
return NULL;
}
-static struct zlib_handler *zlib_get_zlib_handler(struct istream *input)
+static const struct zlib_handler *zlib_get_zlib_handler(struct istream *input)
{
unsigned int i;
- for (i = 0; i < N_ELEMENTS(zlib_handlers); i++) {
- if (zlib_handlers[i].is_compressed(input))
+ for (i = 0; zlib_handlers[i].name != NULL; i++) {
+ if (zlib_handlers[i].is_compressed != NULL &&
+ zlib_handlers[i].is_compressed(input))
return &zlib_handlers[i];
}
return NULL;
}
-static struct zlib_handler *zlib_get_zlib_handler_ext(const char *name)
+static const struct zlib_handler *zlib_get_zlib_handler_ext(const char *name)
{
unsigned int i, len, name_len = strlen(name);
- for (i = 0; i < N_ELEMENTS(zlib_handlers); i++) {
+ for (i = 0; zlib_handlers[i].name != NULL; i++) {
More information about the dovecot-cvs
mailing list