dovecot-1.2: Added listescape plugin.
dovecot at dovecot.org
dovecot at dovecot.org
Sat Oct 18 23:45:50 EEST 2008
details: http://hg.dovecot.org/dovecot-1.2/rev/0d1bd98a6387
changeset: 8297:0d1bd98a6387
user: Timo Sirainen <tss at iki.fi>
date: Sat Oct 18 23:45:41 2008 +0300
description:
Added listescape plugin.
diffstat:
5 files changed, 363 insertions(+)
configure.in | 1
src/plugins/Makefile.am | 1
src/plugins/listescape/Makefile.am | 25 ++
src/plugins/listescape/listescape-plugin.c | 329 ++++++++++++++++++++++++++++
src/plugins/listescape/listescape-plugin.h | 7
diffs (truncated from 395 to 300 lines):
diff -r 698fca0d8b0a -r 0d1bd98a6387 configure.in
--- a/configure.in Sat Oct 18 22:51:20 2008 +0300
+++ b/configure.in Sat Oct 18 23:45:41 2008 +0300
@@ -2448,6 +2448,7 @@ src/plugins/fts-solr/Makefile
src/plugins/fts-solr/Makefile
src/plugins/fts-squat/Makefile
src/plugins/lazy-expunge/Makefile
+src/plugins/listescape/Makefile
src/plugins/mail-log/Makefile
src/plugins/mbox-snarf/Makefile
src/plugins/quota/Makefile
diff -r 698fca0d8b0a -r 0d1bd98a6387 src/plugins/Makefile.am
--- a/src/plugins/Makefile.am Sat Oct 18 22:51:20 2008 +0300
+++ b/src/plugins/Makefile.am Sat Oct 18 23:45:41 2008 +0300
@@ -18,6 +18,7 @@ SUBDIRS = \
fts \
fts-squat \
lazy-expunge \
+ listescape \
mail-log \
mbox-snarf \
quota \
diff -r 698fca0d8b0a -r 0d1bd98a6387 src/plugins/listescape/Makefile.am
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/plugins/listescape/Makefile.am Sat Oct 18 23:45:41 2008 +0300
@@ -0,0 +1,25 @@
+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
+
+lib20_listescape_plugin_la_LDFLAGS = -module -avoid-version
+
+module_LTLIBRARIES = \
+ lib20_listescape_plugin.la
+
+lib20_listescape_plugin_la_SOURCES = \
+ listescape-plugin.c
+
+noinst_HEADERS = \
+ listescape-plugin.h
+
+install-exec-local:
+ for d in imap pop3 lda; do \
+ $(mkdir_p) $(DESTDIR)$(moduledir)/$$d; \
+ rm -f $(DESTDIR)$(moduledir)/$$d/lib20_listescape_plugin$(MODULE_SUFFIX); \
+ $(LN_S) ../lib20_listescape_plugin$(MODULE_SUFFIX) $(DESTDIR)$(moduledir)/$$d; \
+ done
+
diff -r 698fca0d8b0a -r 0d1bd98a6387 src/plugins/listescape/listescape-plugin.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/plugins/listescape/listescape-plugin.c Sat Oct 18 23:45:41 2008 +0300
@@ -0,0 +1,329 @@
+/* Copyright (C) 2007-2008 Timo Sirainen, LGPLv2.1 */
+
+#include "lib.h"
+#include "array.h"
+#include "str.h"
+#include "module-context.h"
+#include "mail-storage-private.h"
+#include "mailbox-list-private.h"
+#include "listescape-plugin.h"
+
+#include <stdlib.h>
+#include <ctype.h>
+
+#define DEFAULT_ESCAPE_CHAR '\\'
+
+#define LIST_ESCAPE_CONTEXT(obj) \
+ MODULE_CONTEXT(obj, listescape_storage_module)
+#define LIST_ESCAPE_LIST_CONTEXT(obj) \
+ MODULE_CONTEXT(obj, listescape_list_module)
+
+struct listescape_mail_storage {
+ union mail_storage_module_context module_ctx;
+};
+
+struct listescape_mailbox_list {
+ union mailbox_list_module_context module_ctx;
+ struct mailbox_info info;
+ string_t *list_name;
+ bool name_escaped;
+};
+
+const char *listescape_plugin_version = PACKAGE_VERSION;
+
+static void (*listescape_next_hook_mail_storage_created)
+ (struct mail_storage *storage);
+static void (*listescape_next_hook_mailbox_list_created)
+ (struct mailbox_list *list);
+static void (*listescape_next_hook_mail_namespaces_created)
+ (struct mail_namespace *namespaces);
+static char escape_char = DEFAULT_ESCAPE_CHAR;
+
+static MODULE_CONTEXT_DEFINE_INIT(listescape_storage_module,
+ &mail_storage_module_register);
+static MODULE_CONTEXT_DEFINE_INIT(listescape_list_module,
+ &mailbox_list_module_register);
+
+static const char *list_escape(struct mail_namespace *ns,
+ const char *str, bool change_sep)
+{
+ string_t *esc = t_str_new(64);
+
+ if (*str == '~') {
+ str_printfa(esc, "%c%02x", escape_char, *str);
+ str++;
+ }
+ for (; *str != '\0'; str++) {
+ if (*str == ns->sep && change_sep)
+ str_append_c(esc, ns->list->hierarchy_sep);
+ else if (*str == ns->list->hierarchy_sep ||
+ *str == escape_char || *str == '/')
+ str_printfa(esc, "%c%02x", escape_char, *str);
+ else
+ str_append_c(esc, *str);
+ }
+ return str_c(esc);
+}
+
+static void list_unescape_str(struct mail_namespace *ns,
+ const char *str, string_t *dest)
+{
+ unsigned int num;
+
+ for (; *str != '\0'; str++) {
+ if (*str == escape_char &&
+ i_isxdigit(str[1]) && i_isxdigit(str[2])) {
+ if (str[1] >= '0' && str[1] <= '9')
+ num = str[1] - '0';
+ else
+ num = i_toupper(str[1]) - 'A' + 10;
+ num *= 16;
+ if (str[2] >= '0' && str[2] <= '9')
+ num += str[2] - '0';
+ else
+ num += i_toupper(str[2]) - 'A' + 10;
+
+ str_append_c(dest, num);
+ str += 2;
+ } else if (*str == ns->list->hierarchy_sep)
+ str_append_c(dest, ns->sep);
+ else
+ str_append_c(dest, *str);
+ }
+}
+
+static struct mailbox_list_iterate_context *
+listescape_mailbox_list_iter_init(struct mailbox_list *list,
+ const char *const *patterns,
+ enum mailbox_list_iter_flags flags)
+{
+ struct listescape_mailbox_list *mlist = LIST_ESCAPE_LIST_CONTEXT(list);
+ struct mailbox_list_iterate_context *ctx;
+ const char **escaped_patterns;
+ unsigned int i;
+
+ t_push();
+ if ((flags & MAILBOX_LIST_ITER_VIRTUAL_NAMES) != 0) {
+ escaped_patterns = t_new(const char *,
+ str_array_length(patterns) + 1);
+ for (i = 0; patterns[i] != NULL; i++) {
+ escaped_patterns[i] =
+ list_escape(list->ns, patterns[i], FALSE);
+ }
+ patterns = escaped_patterns;
+ }
+
+ /* Listing breaks if ns->real_sep isn't correct, but with everything
+ else we need real_sep == virtual_sep. maybe some day lib-storage
+ API gets changed so that it sees only virtual mailbox names and
+ convers them internally and we don't have this problem. */
+ list->ns->real_sep = list->hierarchy_sep;
+ ctx = mlist->module_ctx.super.iter_init(list, patterns, flags);
+ list->ns->real_sep = list->ns->sep;
+ t_pop();
+ return ctx;
+}
+
+static const struct mailbox_info *
+listescape_mailbox_list_iter_next(struct mailbox_list_iterate_context *ctx)
+{
+ struct listescape_mailbox_list *mlist =
+ LIST_ESCAPE_LIST_CONTEXT(ctx->list);
+ const struct mailbox_info *info;
+
+ ctx->list->ns->real_sep = ctx->list->hierarchy_sep;
+ info = mlist->module_ctx.super.iter_next(ctx);
+ ctx->list->ns->real_sep = ctx->list->ns->sep;
+ if (info == NULL || (ctx->flags & MAILBOX_LIST_ITER_VIRTUAL_NAMES) == 0)
+ return info;
+
+ str_truncate(mlist->list_name, 0);
+ list_unescape_str(ctx->list->ns, info->name, mlist->list_name);
+ mlist->info = *info;
+ mlist->info.name = str_c(mlist->list_name);
+ return &mlist->info;
+}
+
+static int
+listescape_mailbox_list_iter_deinit(struct mailbox_list_iterate_context *ctx)
+{
+ struct mailbox_list *list = ctx->list;
+ struct listescape_mailbox_list *mlist =
+ LIST_ESCAPE_LIST_CONTEXT(ctx->list);
+ int ret;
+
+ list->ns->real_sep = list->hierarchy_sep;
+ ret = mlist->module_ctx.super.iter_deinit(ctx);
+ list->ns->real_sep = list->ns->sep;
+ return ret;
+}
+
+static struct mailbox *
+listescape_mailbox_open(struct mail_storage *storage, const char *name,
+ struct istream *input, enum mailbox_open_flags flags)
+{
+ struct listescape_mail_storage *mstorage =
+ LIST_ESCAPE_CONTEXT(storage);
+ struct listescape_mailbox_list *mlist =
+ LIST_ESCAPE_LIST_CONTEXT(storage->list);
+
+ if (!mlist->name_escaped)
+ name = list_escape(storage->ns, name, TRUE);
+ return mstorage->module_ctx.super.
+ mailbox_open(storage, name, input, flags);
+}
+
+static int
+listescape_mailbox_create(struct mail_storage *storage, const char *name,
+ bool directory)
+{
+ struct listescape_mail_storage *mstorage =
+ LIST_ESCAPE_CONTEXT(storage);
+
+ name = list_escape(storage->ns, name, TRUE);
+ return mstorage->module_ctx.super.
+ mailbox_create(storage, name, directory);
+}
+
+static int
+listescape_delete_mailbox(struct mailbox_list *list, const char *name)
+{
+ struct listescape_mailbox_list *mlist = LIST_ESCAPE_LIST_CONTEXT(list);
+ int ret;
+
+ /* at least quota plugin opens the mailbox when deleting it */
+ name = list_escape(list->ns, name, TRUE);
+ mlist->name_escaped = TRUE;
+ ret = mlist->module_ctx.super.delete_mailbox(list, name);
+ mlist->name_escaped = FALSE;
+ return ret;
+}
+
+static int
+listescape_rename_mailbox(struct mailbox_list *list, const char *oldname,
+ const char *newname)
+{
+ struct listescape_mailbox_list *mlist = LIST_ESCAPE_LIST_CONTEXT(list);
+
+ oldname = list_escape(list->ns, oldname, TRUE);
+ newname = list_escape(list->ns, newname, TRUE);
+ return mlist->module_ctx.super.rename_mailbox(list, oldname, newname);
+}
+
+static int listescape_set_subscribed(struct mailbox_list *list,
+ const char *name, bool set)
+{
+ struct listescape_mailbox_list *mlist = LIST_ESCAPE_LIST_CONTEXT(list);
+
+ name = list_escape(list->ns, name, TRUE);
+ return mlist->module_ctx.super.set_subscribed(list, name, set);
+}
+
+static int listescape_get_mailbox_name_status(struct mailbox_list *list,
+ const char *name,
+ enum mailbox_name_status *status)
+{
+ struct listescape_mailbox_list *mlist = LIST_ESCAPE_LIST_CONTEXT(list);
+
+ name = list_escape(list->ns, name, TRUE);
+ return mlist->module_ctx.super.
+ get_mailbox_name_status(list, name, status);
+}
+
+static bool listescape_is_valid_existing_name(struct mailbox_list *list,
+ const char *name)
+{
+ struct listescape_mailbox_list *mlist = LIST_ESCAPE_LIST_CONTEXT(list);
+
+ name = list_escape(list->ns, name, TRUE);
+ return mlist->module_ctx.super.is_valid_existing_name(list, name);
+}
+
+static bool listescape_is_valid_create_name(struct mailbox_list *list,
+ const char *name)
+{
+ struct listescape_mailbox_list *mlist = LIST_ESCAPE_LIST_CONTEXT(list);
More information about the dovecot-cvs
mailing list