From dovecot at dovecot.org Thu Dec 1 09:16:10 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 01 Dec 2011 09:16:10 +0200 Subject: dovecot-2.1: auth: Fixed loading authdb_imap plugin when Dovecot... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/e99c65be76f7 changeset: 13788:e99c65be76f7 user: Timo Sirainen date: Thu Dec 01 09:15:53 2011 +0200 description: auth: Fixed loading authdb_imap plugin when Dovecot is configured --without-shared-libs diffstat: src/auth/Makefile.am | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diffs (13 lines): diff -r 9fa7c1b2c2ee -r e99c65be76f7 src/auth/Makefile.am --- a/src/auth/Makefile.am Wed Nov 30 18:48:44 2011 +0200 +++ b/src/auth/Makefile.am Thu Dec 01 09:15:53 2011 +0200 @@ -163,7 +163,8 @@ libauthdb_imap_la_LDFLAGS = -module -avoid-version libauthdb_imap_la_LIBADD = \ ../lib-imap-client/libimap_client.la \ - ../lib-ssl-iostream/libssl_iostream.la + ../lib-ssl-iostream/libssl_iostream.la \ + $(LIBDOVECOT) libauthdb_imap_la_CPPFLAGS = \ $(AM_CPPFLAGS) \ -I$(top_srcdir)/src/lib-imap \ From dovecot at dovecot.org Thu Dec 1 09:25:18 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 01 Dec 2011 09:25:18 +0200 Subject: dovecot-2.1: imapc: If remote server disconnects, log the reason. Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/8e5c9f3ca158 changeset: 13789:8e5c9f3ca158 user: Timo Sirainen date: Thu Dec 01 09:24:58 2011 +0200 description: imapc: If remote server disconnects, log the reason. diffstat: src/lib-imap-client/imapc-connection.c | 6 +++++- 1 files changed, 5 insertions(+), 1 deletions(-) diffs (17 lines): diff -r e99c65be76f7 -r 8e5c9f3ca158 src/lib-imap-client/imapc-connection.c --- a/src/lib-imap-client/imapc-connection.c Thu Dec 01 09:15:53 2011 +0200 +++ b/src/lib-imap-client/imapc-connection.c Thu Dec 01 09:24:58 2011 +0200 @@ -1108,8 +1108,12 @@ conn->name); } else if (!conn->handshake_failed) { errstr = ssl_iostream_get_last_error(conn->ssl_iostream); + if (errstr == NULL) { + errstr = conn->input->stream_errno == 0 ? "EOF" : + strerror(conn->input->stream_errno); + } i_error("imapc(%s): Server disconnected: %s", - conn->name, errstr != NULL ? errstr : ""); + conn->name, errstr); } imapc_connection_reconnect(conn); } From dovecot at dovecot.org Fri Dec 2 13:12:34 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 02 Dec 2011 13:12:34 +0200 Subject: dovecot-2.1: imapc: Check for when to prefer LOGIN to AUTHENTICA... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/6591f7783d55 changeset: 13790:6591f7783d55 user: Timo Sirainen date: Fri Dec 02 13:12:16 2011 +0200 description: imapc: Check for when to prefer LOGIN to AUTHENTICATE was wrong. diffstat: src/lib-imap-client/imapc-connection.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 8e5c9f3ca158 -r 6591f7783d55 src/lib-imap-client/imapc-connection.c --- a/src/lib-imap-client/imapc-connection.c Thu Dec 01 09:24:58 2011 +0200 +++ b/src/lib-imap-client/imapc-connection.c Fri Dec 02 13:12:16 2011 +0200 @@ -732,7 +732,7 @@ imapc_command_set_flags(cmd, IMAPC_COMMAND_FLAG_PRELOGIN); if ((set->master_user == NULL && - need_literal(set->username) && need_literal(set->password)) || + !need_literal(set->username) && !need_literal(set->password)) || (conn->capabilities & IMAPC_CAPABILITY_AUTH_PLAIN) == 0) { /* We can use LOGIN command */ imapc_command_sendf(cmd, "LOGIN %s %s", From dovecot at dovecot.org Fri Dec 2 14:26:39 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 02 Dec 2011 14:26:39 +0200 Subject: dovecot-2.1: lib-storage: Moved mailbox list iteration functions... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/37c2348b67f5 changeset: 13791:37c2348b67f5 user: Timo Sirainen date: Fri Dec 02 14:23:47 2011 +0200 description: lib-storage: Moved mailbox list iteration functions to a separate file. diffstat: src/lib-storage/Makefile.am | 1 + src/lib-storage/mailbox-list-iter.c | 396 +++++++++++++++++++++++++++++++++++ src/lib-storage/mailbox-list.c | 400 +----------------------------------- 3 files changed, 399 insertions(+), 398 deletions(-) diffs (truncated from 847 to 300 lines): diff -r 6591f7783d55 -r 37c2348b67f5 src/lib-storage/Makefile.am --- a/src/lib-storage/Makefile.am Fri Dec 02 13:12:16 2011 +0200 +++ b/src/lib-storage/Makefile.am Fri Dec 02 14:23:47 2011 +0200 @@ -40,6 +40,7 @@ mailbox-header.c \ mailbox-keywords.c \ mailbox-list.c \ + mailbox-list-iter.c \ mailbox-search-result.c \ mailbox-tree.c \ mailbox-uidvalidity.c diff -r 6591f7783d55 -r 37c2348b67f5 src/lib-storage/mailbox-list-iter.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib-storage/mailbox-list-iter.c Fri Dec 02 14:23:47 2011 +0200 @@ -0,0 +1,396 @@ +/* Copyright (c) 2006-2011 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "imap-match.h" +#include "mailbox-tree.h" +#include "mailbox-list-private.h" + +struct ns_list_iterate_context { + struct mailbox_list_iterate_context ctx; + struct mailbox_list_iterate_context *backend_ctx; + struct mail_namespace *namespaces; + pool_t pool; + const char **patterns, **patterns_ns_match; + enum namespace_type type_mask; +}; + +struct mailbox_list_iterate_context * +mailbox_list_iter_init(struct mailbox_list *list, const char *pattern, + enum mailbox_list_iter_flags flags) +{ + const char *patterns[2]; + + patterns[0] = pattern; + patterns[1] = NULL; + return mailbox_list_iter_init_multiple(list, patterns, flags); +} + +static int mailbox_list_subscriptions_refresh(struct mailbox_list *list) +{ + struct mail_namespace *ns = list->ns; + + if ((ns->flags & NAMESPACE_FLAG_SUBSCRIPTIONS) == 0) { + /* no subscriptions in this namespace. find where they are. */ + ns = mail_namespace_find_subscribable(ns->user->namespaces, + ns->prefix); + if (ns == NULL) { + /* no subscriptions */ + return 0; + } + } + return ns->list->v.subscriptions_refresh(ns->list, list); +} + +struct mailbox_list_iterate_context * +mailbox_list_iter_init_multiple(struct mailbox_list *list, + const char *const *patterns, + enum mailbox_list_iter_flags flags) +{ + struct mailbox_list_iterate_context *ctx; + int ret = 0; + + i_assert(*patterns != NULL); + + if ((flags & (MAILBOX_LIST_ITER_SELECT_SUBSCRIBED | + MAILBOX_LIST_ITER_RETURN_SUBSCRIBED)) != 0) + ret = mailbox_list_subscriptions_refresh(list); + + ctx = list->v.iter_init(list, patterns, flags); + if (ret < 0) + ctx->failed = TRUE; + return ctx; +} + +static bool +ns_match_simple(struct ns_list_iterate_context *ctx, struct mail_namespace *ns) +{ + if ((ctx->type_mask & ns->type) == 0) + return FALSE; + + if ((ctx->ctx.flags & MAILBOX_LIST_ITER_SKIP_ALIASES) != 0) { + if (ns->alias_for != NULL) + return FALSE; + } + return TRUE; +} + +static bool +ns_match_inbox(struct mail_namespace *ns, const char *pattern) +{ + struct imap_match_glob *glob; + + if ((ns->flags & NAMESPACE_FLAG_INBOX_USER) == 0) + return FALSE; + + glob = imap_match_init(pool_datastack_create(), pattern, + TRUE, mail_namespace_get_sep(ns)); + return imap_match(glob, "INBOX") == IMAP_MATCH_YES; +} + +static bool +ns_match_next(struct ns_list_iterate_context *ctx, struct mail_namespace *ns, + const char *pattern) +{ + struct imap_match_glob *glob; + enum imap_match_result result; + const char *prefix_without_sep; + unsigned int len; + + len = ns->prefix_len; + if (len > 0 && ns->prefix[len-1] == mail_namespace_get_sep(ns)) + len--; + + if ((ns->flags & (NAMESPACE_FLAG_LIST_PREFIX | + NAMESPACE_FLAG_LIST_CHILDREN)) == 0) { + /* non-listable namespace matches only with exact prefix */ + if (strncmp(ns->prefix, pattern, ns->prefix_len) != 0) + return FALSE; + } + + prefix_without_sep = t_strndup(ns->prefix, len); + if (*prefix_without_sep == '\0') + result = IMAP_MATCH_CHILDREN; + else { + glob = imap_match_init(pool_datastack_create(), pattern, + TRUE, mail_namespace_get_sep(ns)); + result = imap_match(glob, prefix_without_sep); + } + + if ((ctx->ctx.flags & MAILBOX_LIST_ITER_STAR_WITHIN_NS) == 0) { + switch (result) { + case IMAP_MATCH_YES: + case IMAP_MATCH_CHILDREN: + return TRUE; + case IMAP_MATCH_NO: + case IMAP_MATCH_PARENT: + break; + } + return FALSE; + } + + switch (result) { + case IMAP_MATCH_YES: + /* allow matching prefix only when it's done without + wildcards */ + if (strcmp(prefix_without_sep, pattern) == 0) + return TRUE; + break; + case IMAP_MATCH_CHILDREN: { + /* allow this only if there isn't another namespace + with longer prefix that matches this pattern + (namespaces are sorted by prefix length) */ + struct mail_namespace *tmp; + + T_BEGIN { + for (tmp = ns->next; tmp != NULL; tmp = tmp->next) { + if (ns_match_simple(ctx, tmp) && + ns_match_next(ctx, tmp, pattern)) + break; + } + } T_END; + if (tmp == NULL) + return TRUE; + break; + } + case IMAP_MATCH_NO: + case IMAP_MATCH_PARENT: + break; + } + return FALSE; +} + +static bool +ns_match(struct ns_list_iterate_context *ctx, struct mail_namespace *ns) +{ + unsigned int i; + + if (!ns_match_simple(ctx, ns)) + return FALSE; + + /* filter out namespaces whose prefix doesn't match. this same code + handles both with and without STAR_WITHIN_NS, so the "without" case + is slower than necessary, but this shouldn't matter much */ + T_BEGIN { + for (i = 0; ctx->patterns_ns_match[i] != NULL; i++) { + if (ns_match_inbox(ns, ctx->patterns_ns_match[i])) + break; + if (ns_match_next(ctx, ns, ctx->patterns_ns_match[i])) + break; + } + } T_END; + + return ctx->patterns_ns_match[i] != NULL; +} + +static struct mail_namespace * +ns_next(struct ns_list_iterate_context *ctx, struct mail_namespace *ns) +{ + for (; ns != NULL; ns = ns->next) { + if (ns_match(ctx, ns)) + break; + } + return ns; +} + +static const struct mailbox_info * +mailbox_list_ns_iter_next(struct mailbox_list_iterate_context *_ctx) +{ + struct ns_list_iterate_context *ctx = + (struct ns_list_iterate_context *)_ctx; + const struct mailbox_info *info; + + info = ctx->backend_ctx == NULL ? NULL : + mailbox_list_iter_next(ctx->backend_ctx); + if (info == NULL && ctx->namespaces != NULL) { + /* go to the next namespace */ + if (mailbox_list_iter_deinit(&ctx->backend_ctx) < 0) + _ctx->failed = TRUE; + ctx->ctx.list->ns = ctx->namespaces; + ctx->backend_ctx = + mailbox_list_iter_init_multiple(ctx->namespaces->list, + ctx->patterns, + _ctx->flags); + ctx->namespaces = ns_next(ctx, ctx->namespaces->next); + return mailbox_list_ns_iter_next(_ctx); + } + return info; +} + +static int +mailbox_list_ns_iter_deinit(struct mailbox_list_iterate_context *_ctx) +{ + struct ns_list_iterate_context *ctx = + (struct ns_list_iterate_context *)_ctx; + int ret; + + if (ctx->backend_ctx != NULL) { + if (mailbox_list_iter_deinit(&ctx->backend_ctx) < 0) + _ctx->failed = TRUE; + } + ret = _ctx->failed ? -1 : 0; + pool_unref(&ctx->pool); + return ret; +} + +static const char ** +dup_patterns_without_stars(pool_t pool, const char *const *patterns, + unsigned int count) +{ + const char **dup; + unsigned int i; + + dup = p_new(pool, const char *, count + 1); + for (i = 0; i < count; i++) { + char *p = p_strdup(pool, patterns[i]); + dup[i] = p; + + for (; *p != '\0'; p++) { + if (*p == '*') + *p = '%'; + } + } + return dup; +} + +struct mailbox_list_iterate_context * +mailbox_list_iter_init_namespaces(struct mail_namespace *namespaces, + const char *const *patterns, + enum namespace_type type_mask, + enum mailbox_list_iter_flags flags) +{ + struct ns_list_iterate_context *ctx; + unsigned int i, count; + pool_t pool; + + i_assert(namespaces != NULL); + + pool = pool_alloconly_create("mailbox list namespaces", 1024); + ctx = p_new(pool, struct ns_list_iterate_context, 1); + ctx->pool = pool; + ctx->type_mask = type_mask; + ctx->ctx.flags = flags; + ctx->ctx.list = p_new(pool, struct mailbox_list, 1); + ctx->ctx.list->v.iter_next = mailbox_list_ns_iter_next; + ctx->ctx.list->v.iter_deinit = mailbox_list_ns_iter_deinit; + + count = str_array_length(patterns); + ctx->patterns = p_new(pool, const char *, count + 1); + for (i = 0; i < count; i++) + ctx->patterns[i] = p_strdup(pool, patterns[i]); + + if ((flags & MAILBOX_LIST_ITER_STAR_WITHIN_NS) != 0) { + /* create copies of patterns with '*' wildcard changed to '%' */ + ctx->patterns_ns_match = + dup_patterns_without_stars(pool, ctx->patterns, count); + } else { From dovecot at dovecot.org Fri Dec 2 14:49:37 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 02 Dec 2011 14:49:37 +0200 Subject: dovecot-2.1: lib-storage: Added pool to struct mailbox_list_iter... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/b48fb6a08389 changeset: 13792:b48fb6a08389 user: Timo Sirainen date: Fri Dec 02 14:49:08 2011 +0200 description: lib-storage: Added pool to struct mailbox_list_iterate_context. diffstat: src/lib-storage/index/imapc/imapc-list.c | 14 ++++---- src/lib-storage/index/shared/shared-list.c | 14 ++++---- src/lib-storage/list/mailbox-list-fs-iter.c | 34 ++++++++-------------- src/lib-storage/list/mailbox-list-index-iter.c | 17 +++++------ src/lib-storage/list/mailbox-list-maildir-iter.c | 7 ++-- src/lib-storage/list/mailbox-list-none.c | 13 ++++---- src/lib-storage/list/mailbox-list-subscriptions.c | 15 ++++----- src/lib-storage/mailbox-list-private.h | 1 + src/plugins/acl/acl-mailbox-list.c | 11 ++++--- 9 files changed, 59 insertions(+), 67 deletions(-) diffs (truncated from 389 to 300 lines): diff -r 37c2348b67f5 -r b48fb6a08389 src/lib-storage/index/imapc/imapc-list.c --- a/src/lib-storage/index/imapc/imapc-list.c Fri Dec 02 14:23:47 2011 +0200 +++ b/src/lib-storage/index/imapc/imapc-list.c Fri Dec 02 14:49:08 2011 +0200 @@ -360,6 +360,7 @@ struct imapc_mailbox_list *list = (struct imapc_mailbox_list *)_list; struct mailbox_list_iterate_context *_ctx; struct imapc_mailbox_list_iterate_context *ctx; + pool_t pool; const char *ns_root_name; char sep; int ret = 0; @@ -382,12 +383,13 @@ sep = mailbox_list_get_hierarchy_sep(_list); - ctx = i_new(struct imapc_mailbox_list_iterate_context, 1); + pool = pool_alloconly_create("mailbox list imapc iter", 1024); + ctx = p_new(pool, struct imapc_mailbox_list_iterate_context, 1); + ctx->ctx.pool = pool; ctx->ctx.list = _list; ctx->ctx.flags = flags; - ctx->ctx.glob = imap_match_init_multiple(default_pool, patterns, - FALSE, sep); - array_create(&ctx->ctx.module_contexts, default_pool, sizeof(void *), 5); + ctx->ctx.glob = imap_match_init_multiple(pool, patterns, FALSE, sep); + array_create(&ctx->ctx.module_contexts, pool, sizeof(void *), 5); ctx->info.ns = _list->ns; @@ -451,9 +453,7 @@ mailbox_tree_iterate_deinit(&ctx->iter); mailbox_tree_deinit(&ctx->tree); - imap_match_deinit(&_ctx->glob); - array_free(&_ctx->module_contexts); - i_free(ctx); + pool_unref(&_ctx->pool); return ret; } diff -r 37c2348b67f5 -r b48fb6a08389 src/lib-storage/index/shared/shared-list.c --- a/src/lib-storage/index/shared/shared-list.c Fri Dec 02 14:23:47 2011 +0200 +++ b/src/lib-storage/index/shared/shared-list.c Fri Dec 02 14:49:08 2011 +0200 @@ -177,14 +177,16 @@ enum mailbox_list_iter_flags flags) { struct mailbox_list_iterate_context *ctx; + pool_t pool; char sep = mail_namespace_get_sep(list->ns); - ctx = i_new(struct mailbox_list_iterate_context, 1); + pool = pool_alloconly_create("mailbox list shared iter", 1024); + ctx = p_new(pool, struct mailbox_list_iterate_context, 1); + ctx->pool = pool; ctx->list = list; ctx->flags = flags; - ctx->glob = imap_match_init_multiple(default_pool, patterns, - FALSE, sep); - array_create(&ctx->module_contexts, default_pool, sizeof(void *), 5); + ctx->glob = imap_match_init_multiple(pool, patterns, FALSE, sep); + array_create(&ctx->module_contexts, pool, sizeof(void *), 5); if ((flags & MAILBOX_LIST_ITER_SELECT_SUBSCRIBED) == 0 && (list->ns->flags & NAMESPACE_FLAG_AUTOCREATED) == 0) T_BEGIN { @@ -201,9 +203,7 @@ static int shared_list_iter_deinit(struct mailbox_list_iterate_context *ctx) { - imap_match_deinit(&ctx->glob); - array_free(&ctx->module_contexts); - i_free(ctx); + pool_unref(&ctx->pool); return 0; } diff -r 37c2348b67f5 -r b48fb6a08389 src/lib-storage/list/mailbox-list-fs-iter.c --- a/src/lib-storage/list/mailbox-list-fs-iter.c Fri Dec 02 14:23:47 2011 +0200 +++ b/src/lib-storage/list/mailbox-list-fs-iter.c Fri Dec 02 14:49:08 2011 +0200 @@ -36,7 +36,7 @@ struct fs_list_iterate_context { struct mailbox_list_iterate_context ctx; - ARRAY_DEFINE(valid_patterns, char *); + ARRAY_DEFINE(valid_patterns, const char *); char sep; enum mailbox_info_flags inbox_flags; @@ -128,7 +128,7 @@ static int list_opendir(struct fs_list_iterate_context *ctx, const char *path, const char *list_path, DIR **dirp) { - char *const *patterns; + const char *const *patterns; unsigned int i; /* if no patterns have wildcards at this point of the path, we don't @@ -209,7 +209,8 @@ { struct fs_list_iterate_context *ctx; const char *path, *vpath, *rootdir, *test_pattern, *real_pattern; - char *pattern; + pool_t pool; + const char *pattern; DIR *dirp; unsigned int prefix_len; int ret; @@ -221,10 +222,12 @@ flags); } - ctx = i_new(struct fs_list_iterate_context, 1); + pool = pool_alloconly_create("mailbox list fs iter", 1024); + ctx = p_new(pool, struct fs_list_iterate_context, 1); + ctx->ctx.pool = pool; ctx->ctx.list = _list; ctx->ctx.flags = flags; - array_create(&ctx->ctx.module_contexts, default_pool, sizeof(void *), 5); + array_create(&ctx->ctx.module_contexts, pool, sizeof(void *), 5); ctx->info_pool = pool_alloconly_create("fs list", 1024); ctx->next = fs_list_next; @@ -232,7 +235,7 @@ ctx->info.ns = _list->ns; prefix_len = strlen(_list->ns->prefix); - i_array_init(&ctx->valid_patterns, 8); + p_array_init(&ctx->valid_patterns, pool, 8); for (; *patterns != NULL; patterns++) { /* check that we're not trying to do any "../../" lists */ test_pattern = *patterns; @@ -251,7 +254,7 @@ ctx->inbox_match = TRUE; continue; } - pattern = i_strdup(*patterns); + pattern = p_strdup(pool, *patterns); array_append(&ctx->valid_patterns, &pattern, 1); } } @@ -262,7 +265,7 @@ return &ctx->ctx; } patterns = (const void *)array_idx(&ctx->valid_patterns, 0); - ctx->ctx.glob = imap_match_init_multiple(default_pool, patterns, TRUE, + ctx->ctx.glob = imap_match_init_multiple(pool, patterns, TRUE, ctx->sep); vpath = _list->ns->prefix; @@ -300,18 +303,11 @@ { struct fs_list_iterate_context *ctx = (struct fs_list_iterate_context *)_ctx; - char **patterns; - unsigned int i, count; int ret = _ctx->failed ? -1 : 0; if ((_ctx->flags & MAILBOX_LIST_ITER_SELECT_SUBSCRIBED) != 0) return mailbox_list_subscriptions_iter_deinit(_ctx); - patterns = array_get_modifiable(&ctx->valid_patterns, &count); - for (i = 0; i < count; i++) - i_free(patterns[i]); - array_free(&ctx->valid_patterns); - while (ctx->dir != NULL) { struct list_dir_context *dir = ctx->dir; @@ -321,11 +317,7 @@ if (ctx->info_pool != NULL) pool_unref(&ctx->info_pool); - if (_ctx->glob != NULL) - imap_match_deinit(&_ctx->glob); - array_free(&_ctx->module_contexts); - i_free(ctx); - + pool_unref(&_ctx->pool); return ret; } @@ -639,7 +631,7 @@ { struct list_dir_context *dir = ctx->dir; struct dirent *d; - char *const *patterns; + const char *const *patterns; const char *fname, *path, *p; unsigned int pos; struct stat st; diff -r 37c2348b67f5 -r b48fb6a08389 src/lib-storage/list/mailbox-list-index-iter.c --- a/src/lib-storage/list/mailbox-list-index-iter.c Fri Dec 02 14:23:47 2011 +0200 +++ b/src/lib-storage/list/mailbox-list-index-iter.c Fri Dec 02 14:49:08 2011 +0200 @@ -14,14 +14,16 @@ { struct mailbox_list_index *ilist = INDEX_LIST_CONTEXT(list); struct mailbox_list_index_iterate_context *ctx; + pool_t pool; char ns_sep = mail_namespace_get_sep(list->ns); - ctx = i_new(struct mailbox_list_index_iterate_context, 1); + pool = pool_alloconly_create("mailbox list index iter", 1024); + ctx = p_new(pool, struct mailbox_list_index_iterate_context, 1); + ctx->ctx.pool = pool; ctx->ctx.list = list; ctx->ctx.flags = flags; - ctx->ctx.glob = imap_match_init_multiple(default_pool, patterns, - TRUE, ns_sep); - array_create(&ctx->ctx.module_contexts, default_pool, sizeof(void *), 5); + ctx->ctx.glob = imap_match_init_multiple(pool, patterns, TRUE, ns_sep); + array_create(&ctx->ctx.module_contexts, pool, sizeof(void *), 5); ctx->sep = ns_sep; if (mailbox_list_index_refresh(ctx->ctx.list) < 0) { @@ -31,7 +33,7 @@ } else { /* listing mailboxes from index */ ctx->info.ns = list->ns; - ctx->path = str_new(default_pool, 128); + ctx->path = str_new(pool, 128); ctx->next_node = ilist->mailbox_tree; ilist->iter_refcount++; } @@ -162,11 +164,8 @@ else { i_assert(ilist->iter_refcount > 0); ilist->iter_refcount--; - str_free(&ctx->path); } - imap_match_deinit(&ctx->ctx.glob); - array_free(&ctx->ctx.module_contexts); - i_free(ctx); + pool_unref(&_ctx->pool); return ret; } diff -r 37c2348b67f5 -r b48fb6a08389 src/lib-storage/list/mailbox-list-maildir-iter.c --- a/src/lib-storage/list/mailbox-list-maildir-iter.c Fri Dec 02 14:23:47 2011 +0200 +++ b/src/lib-storage/list/mailbox-list-maildir-iter.c Fri Dec 02 14:49:08 2011 +0200 @@ -19,7 +19,6 @@ struct maildir_list_iterate_context { struct mailbox_list_iterate_context ctx; - pool_t pool; const char *dir; char prefix_char; @@ -419,14 +418,14 @@ char ns_sep = mail_namespace_get_sep(_list->ns); int ret; - pool = pool_alloconly_create("maildir_list", 1024); + pool = pool_alloconly_create("mailbox list maildir iter", 1024); ctx = p_new(pool, struct maildir_list_iterate_context, 1); + ctx->ctx.pool = pool; ctx->ctx.list = _list; ctx->ctx.flags = flags; ctx->ctx.glob = imap_match_init_multiple(pool, patterns, TRUE, ns_sep); array_create(&ctx->ctx.module_contexts, pool, sizeof(void *), 5); - ctx->pool = pool; ctx->tree_ctx = mailbox_tree_init(ns_sep); ctx->info.ns = _list->ns; ctx->prefix_char = strcmp(_list->name, MAILBOX_LIST_NAME_IMAPDIR) == 0 ? @@ -470,7 +469,7 @@ if (ctx->tree_iter != NULL) mailbox_tree_iterate_deinit(&ctx->tree_iter); mailbox_tree_deinit(&ctx->tree_ctx); - pool_unref(&ctx->pool); + pool_unref(&ctx->ctx.pool); return ret; } diff -r 37c2348b67f5 -r b48fb6a08389 src/lib-storage/list/mailbox-list-none.c --- a/src/lib-storage/list/mailbox-list-none.c Fri Dec 02 14:23:47 2011 +0200 +++ b/src/lib-storage/list/mailbox-list-none.c Fri Dec 02 14:49:08 2011 +0200 @@ -133,13 +133,16 @@ enum mailbox_list_iter_flags flags) { struct noop_list_iterate_context *ctx; + pool_t pool; - ctx = i_new(struct noop_list_iterate_context, 1); + pool = pool_alloconly_create("mailbox list none iter", 1024); + ctx = p_new(pool, struct noop_list_iterate_context, 1); + ctx->ctx.pool = pool; ctx->ctx.list = list; ctx->ctx.flags = flags; - ctx->ctx.glob = imap_match_init_multiple(default_pool, patterns, TRUE, + ctx->ctx.glob = imap_match_init_multiple(pool, patterns, TRUE, mail_namespace_get_sep(list->ns)); - array_create(&ctx->ctx.module_contexts, default_pool, sizeof(void *), 5); + array_create(&ctx->ctx.module_contexts, pool, sizeof(void *), 5); if ((list->ns->flags & NAMESPACE_FLAG_INBOX_USER) != 0 && imap_match(ctx->ctx.glob, "INBOX") == IMAP_MATCH_YES) { ctx->list_inbox = TRUE; @@ -152,9 +155,7 @@ static int none_list_iter_deinit(struct mailbox_list_iterate_context *ctx) { - array_free(&ctx->module_contexts); From dovecot at dovecot.org Fri Dec 2 16:22:42 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 02 Dec 2011 16:22:42 +0200 Subject: dovecot-2.1: Moved autocreate plugin functionality into lib-stor... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/ee783a878120 changeset: 13793:ee783a878120 user: Timo Sirainen date: Fri Dec 02 16:22:31 2011 +0200 description: Moved autocreate plugin functionality into lib-storage. The autocreate plugin is still used for backwards compatibility. Mailboxes can be configured like: mailbox Sent { auto = subscribe } mailbox Spam { auto = create } diffstat: src/config/settings-get.pl | 1 + src/lib-storage/mail-storage-private.h | 2 + src/lib-storage/mail-storage-settings.c | 48 ++ src/lib-storage/mail-storage-settings.h | 12 + src/lib-storage/mail-storage.c | 77 +++- src/lib-storage/mailbox-list-iter.c | 270 ++++++++++++++++- src/lib-storage/mailbox-list-private.h | 1 + src/plugins/autocreate/autocreate-plugin.c | 473 ++-------------------------- 8 files changed, 434 insertions(+), 450 deletions(-) diffs (truncated from 1111 to 300 lines): diff -r b48fb6a08389 -r ee783a878120 src/config/settings-get.pl --- a/src/config/settings-get.pl Fri Dec 02 14:49:08 2011 +0200 +++ b/src/config/settings-get.pl Fri Dec 02 16:22:31 2011 +0200 @@ -8,6 +8,7 @@ print '#include "file-lock.h"'."\n"; print '#include "fsync-mode.h"'."\n"; print '#include "hash-format.h"'."\n"; +print '#include "unichar.h"'."\n"; print '#include "settings-parser.h"'."\n"; print '#include "all-settings.h"'."\n"; print '#include '."\n"; diff -r b48fb6a08389 -r ee783a878120 src/lib-storage/mail-storage-private.h --- a/src/lib-storage/mail-storage-private.h Fri Dec 02 14:49:08 2011 +0200 +++ b/src/lib-storage/mail-storage-private.h Fri Dec 02 16:22:31 2011 +0200 @@ -226,6 +226,8 @@ /* default vfuncs for new struct mails. */ const struct mail_vfuncs *mail_vfuncs; + /* Mailbox settings, or NULL if defaults */ + const struct mailbox_settings *set; /* If non-zero, fail mailbox_open() with this error. mailbox_alloc() can set this to force open to fail. */ diff -r b48fb6a08389 -r ee783a878120 src/lib-storage/mail-storage-settings.c --- a/src/lib-storage/mail-storage-settings.c Fri Dec 02 14:49:08 2011 +0200 +++ b/src/lib-storage/mail-storage-settings.c Fri Dec 02 16:22:31 2011 +0200 @@ -4,6 +4,7 @@ #include "array.h" #include "hash-format.h" #include "var-expand.h" +#include "unichar.h" #include "settings-parser.h" #include "mail-index.h" #include "mail-user.h" @@ -15,6 +16,7 @@ static bool mail_storage_settings_check(void *_set, pool_t pool, const char **error_r); static bool namespace_settings_check(void *_set, pool_t pool, const char **error_r); +static bool mailbox_settings_check(void *_set, pool_t pool, const char **error_r); static bool mail_user_settings_check(void *_set, pool_t pool, const char **error_r); #undef DEF @@ -142,6 +144,37 @@ }; #undef DEF +#define DEF(type, name) \ + { type, #name, offsetof(struct mailbox_settings, name), NULL } + +static const struct setting_define mailbox_setting_defines[] = { + DEF(SET_STR, name), + { SET_ENUM, "auto", offsetof(struct mailbox_settings, autocreate), NULL } , + + SETTING_DEFINE_LIST_END +}; + +const struct mailbox_settings mailbox_default_settings = { + .name = "", + .autocreate = MAILBOX_SET_AUTO_NO":" + MAILBOX_SET_AUTO_CREATE":" + MAILBOX_SET_AUTO_SUBSCRIBE +}; + +const struct setting_parser_info mailbox_setting_parser_info = { + .defines = mailbox_setting_defines, + .defaults = &mailbox_default_settings, + + .type_offset = offsetof(struct mailbox_settings, name), + .struct_size = sizeof(struct mailbox_settings), + + .parent_offset = (size_t)-1, + .parent = &mail_user_setting_parser_info, + + .check_func = mailbox_settings_check +}; + +#undef DEF #undef DEFLIST_UNIQUE #define DEF(type, name) \ { type, #name, offsetof(struct mail_user_settings, name), NULL } @@ -173,6 +206,7 @@ DEF(SET_STR, mail_log_prefix), DEFLIST_UNIQUE(namespaces, "namespace", &mail_namespace_setting_parser_info), + DEFLIST_UNIQUE(mailboxes, "mailbox", &mailbox_setting_parser_info), { SET_STRLIST, "plugin", offsetof(struct mail_user_settings, plugin_envs), NULL }, SETTING_DEFINE_LIST_END @@ -202,6 +236,7 @@ .mail_log_prefix = "%s(%u): ", .namespaces = ARRAY_INIT, + .mailboxes = ARRAY_INIT, .plugin_envs = ARRAY_INIT }; @@ -425,6 +460,19 @@ return TRUE; } +static bool mailbox_settings_check(void *_set, pool_t pool ATTR_UNUSED, + const char **error_r) +{ + struct mailbox_settings *set = _set; + + if (!uni_utf8_str_is_valid(set->name)) { + *error_r = t_strdup_printf("mailbox %s: name isn't valid UTF-8", + set->name); + return FALSE; + } + return TRUE; +} + static bool mail_user_settings_check(void *_set, pool_t pool ATTR_UNUSED, const char **error_r ATTR_UNUSED) { diff -r b48fb6a08389 -r ee783a878120 src/lib-storage/mail-storage-settings.h --- a/src/lib-storage/mail-storage-settings.h Fri Dec 02 14:49:08 2011 +0200 +++ b/src/lib-storage/mail-storage-settings.h Fri Dec 02 16:22:31 2011 +0200 @@ -55,6 +55,16 @@ struct mail_user_settings *user_set; }; +/* */ +#define MAILBOX_SET_AUTO_NO "no" +#define MAILBOX_SET_AUTO_CREATE "create" +#define MAILBOX_SET_AUTO_SUBSCRIBE "subscribe" +/* */ +struct mailbox_settings { + const char *name; + const char *autocreate; +}; + struct mail_user_settings { const char *base_dir; const char *auth_socket_path; @@ -77,6 +87,7 @@ const char *mail_log_prefix; ARRAY_DEFINE(namespaces, struct mail_namespace_settings *); + ARRAY_DEFINE(mailboxes, struct mailbox_settings *); ARRAY_DEFINE(plugin_envs, const char *); }; @@ -84,6 +95,7 @@ extern const struct setting_parser_info mail_namespace_setting_parser_info; extern const struct setting_parser_info mail_storage_setting_parser_info; extern const struct mail_namespace_settings mail_namespace_default_settings; +extern const struct mailbox_settings mailbox_default_settings; const void * mail_user_set_get_driver_settings(const struct setting_parser_info *info, diff -r b48fb6a08389 -r ee783a878120 src/lib-storage/mail-storage.c --- a/src/lib-storage/mail-storage.c Fri Dec 02 14:49:08 2011 +0200 +++ b/src/lib-storage/mail-storage.c Fri Dec 02 16:22:31 2011 +0200 @@ -602,6 +602,18 @@ return TRUE; } +static struct mailbox_settings * +mailbox_settings_find(struct mail_user *user, const char *vname) +{ + struct mailbox_settings *const *box_set; + + array_foreach(&user->set->mailboxes, box_set) { + if (strcmp((*box_set)->name, vname) == 0) + return *box_set; + } + return NULL; +} + struct mailbox *mailbox_alloc(struct mailbox_list *list, const char *vname, enum mailbox_flags flags) { @@ -628,6 +640,7 @@ T_BEGIN { box = storage->v.mailbox_alloc(storage, new_list, vname, flags); + box->set = mailbox_settings_find(storage->user, vname); hook_mailbox_allocated(box); } T_END; @@ -704,6 +717,14 @@ return FALSE; } +static bool mailbox_is_autocreated(struct mailbox *box) +{ + if (box->inbox_user) + return TRUE; + return box->set != NULL && + strcmp(box->set->autocreate, MAILBOX_SET_AUTO_NO) != 0; +} + int mailbox_exists(struct mailbox *box, bool auto_boxes, enum mailbox_existence *existence_r) { @@ -732,8 +753,7 @@ return 0; } - if (strcmp(box->name, "INBOX") == 0 && box->inbox_user && auto_boxes) { - /* INBOX always exists */ + if (auto_boxes && box->set != NULL && mailbox_is_autocreated(box)) { *existence_r = MAILBOX_EXISTENCE_SELECT; return 0; } @@ -788,6 +808,47 @@ return 0; } +static void mailbox_autocreate(struct mailbox *box) +{ + const char *errstr; + enum mail_error error; + + if (mailbox_create(box, NULL, FALSE) < 0) { + errstr = mailbox_get_last_error(box, &error); + if (error != MAIL_ERROR_NOTFOUND && !box->inbox_user) { + mail_storage_set_critical(box->storage, + "Failed to autocreate mailbox %s: %s", + box->vname, errstr); + } + } else if (box->set != NULL && + strcmp(box->set->autocreate, + MAILBOX_SET_AUTO_SUBSCRIBE) == 0) { + if (mailbox_set_subscribed(box, TRUE) < 0) { + mail_storage_set_critical(box->storage, + "Failed to autosubscribe to mailbox %s: %s", + box->vname, mailbox_get_last_error(box, NULL)); + } + } +} + +static int mailbox_autocreate_and_reopen(struct mailbox *box) +{ + int ret; + + mailbox_autocreate(box); + mailbox_close(box); + + ret = box->v.open(box); + if (ret < 0 && box->inbox_user && + !box->storage->user->inbox_open_error_logged) { + box->storage->user->inbox_open_error_logged = TRUE; + mail_storage_set_critical(box->storage, + "Opening INBOX failed: %s", + mailbox_get_last_error(box, NULL)); + } + return ret; +} + static int mailbox_open_full(struct mailbox *box, struct istream *input) { int ret; @@ -832,16 +893,8 @@ } T_END; if (ret < 0 && box->storage->error == MAIL_ERROR_NOTFOUND && - box->input == NULL && box->inbox_user) T_BEGIN { - /* INBOX should always exist. try to create it and retry. */ - (void)mailbox_create(box, NULL, FALSE); - mailbox_close(box); - ret = box->v.open(box); - if (ret < 0 && !box->storage->user->inbox_open_error_logged) { - box->storage->user->inbox_open_error_logged = TRUE; - i_error("Opening INBOX failed: %s", - mailbox_get_last_error(box, NULL)); - } + box->input == NULL && mailbox_is_autocreated(box)) T_BEGIN { + ret = mailbox_autocreate_and_reopen(box); } T_END; if (ret < 0) { diff -r b48fb6a08389 -r ee783a878120 src/lib-storage/mailbox-list-iter.c --- a/src/lib-storage/mailbox-list-iter.c Fri Dec 02 14:49:08 2011 +0200 +++ b/src/lib-storage/mailbox-list-iter.c Fri Dec 02 16:22:31 2011 +0200 @@ -1,10 +1,35 @@ /* Copyright (c) 2006-2011 Dovecot authors, see the included COPYING file */ #include "lib.h" +#include "array.h" #include "imap-match.h" #include "mailbox-tree.h" #include "mailbox-list-private.h" +enum autocreate_match_result { + /* list contains the mailbox */ + AUTOCREATE_MATCH_RESULT_YES = 0x01, + /* list contains children of the mailbox */ + AUTOCREATE_MATCH_RESULT_CHILDREN = 0x02, + /* list contains parents of the mailbox */ + AUTOCREATE_MATCH_RESULT_PARENT = 0x04 +}; + +struct autocreate_box { + const char *name; + enum mailbox_info_flags flags; + bool child_listed; +}; From dovecot at dovecot.org Fri Dec 2 17:07:51 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 02 Dec 2011 17:07:51 +0200 Subject: dovecot-2.1: Implemented IMAP SPECIAL-USE extension. Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/32d1a903d42d changeset: 13794:32d1a903d42d user: Timo Sirainen date: Fri Dec 02 17:05:31 2011 +0200 description: Implemented IMAP SPECIAL-USE extension. diffstat: configure.in | 2 +- src/imap/cmd-list.c | 22 ++++++++++-- src/lib-storage/mail-storage-settings.c | 56 +++++++++++++++++++++++++++++++- src/lib-storage/mail-storage-settings.h | 1 + src/lib-storage/mail-storage.c | 2 +- src/lib-storage/mail-storage.h | 3 + src/lib-storage/mailbox-list-iter.c | 51 ++++++++++++++++++++++------- src/lib-storage/mailbox-list-private.h | 1 + src/lib-storage/mailbox-list.h | 6 ++- 9 files changed, 121 insertions(+), 23 deletions(-) diffs (truncated from 351 to 300 lines): diff -r ee783a878120 -r 32d1a903d42d configure.in --- a/configure.in Fri Dec 02 16:22:31 2011 +0200 +++ b/configure.in Fri Dec 02 17:05:31 2011 +0200 @@ -2671,7 +2671,7 @@ dnl IDLE doesn't really belong to banner. It's there just to make Blackberries dnl happy, because otherwise BIS server disables push email. capability_banner="IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE" -capability="$capability_banner SORT SORT=DISPLAY THREAD=REFERENCES THREAD=REFS MULTIAPPEND UNSELECT CHILDREN NAMESPACE UIDPLUS LIST-EXTENDED I18NLEVEL=1 CONDSTORE QRESYNC ESEARCH ESORT SEARCHRES WITHIN CONTEXT=SEARCH LIST-STATUS FUZZY" +capability="$capability_banner SORT SORT=DISPLAY THREAD=REFERENCES THREAD=REFS MULTIAPPEND UNSELECT CHILDREN NAMESPACE UIDPLUS LIST-EXTENDED I18NLEVEL=1 CONDSTORE QRESYNC ESEARCH ESORT SEARCHRES WITHIN CONTEXT=SEARCH LIST-STATUS FUZZY SPECIAL-USE" AC_DEFINE_UNQUOTED(CAPABILITY_STRING, "$capability", IMAP capabilities) AC_DEFINE_UNQUOTED(CAPABILITY_BANNER_STRING, "$capability_banner", IMAP capabilities advertised in banner) diff -r ee783a878120 -r 32d1a903d42d src/imap/cmd-list.c --- a/src/imap/cmd-list.c Fri Dec 02 16:22:31 2011 +0200 +++ b/src/imap/cmd-list.c Fri Dec 02 17:05:31 2011 +0200 @@ -37,7 +37,7 @@ static void mailbox_flags2str(struct cmd_list_context *ctx, string_t *str, - enum mailbox_info_flags flags) + const char *special_use, enum mailbox_info_flags flags) { unsigned int orig_len = str_len(str); @@ -76,6 +76,11 @@ if ((flags & MAILBOX_UNMARKED) != 0) str_append(str, "\\UnMarked "); + if ((ctx->list_flags & MAILBOX_LIST_ITER_RETURN_SPECIALUSE) != 0 && + special_use != NULL) { + str_append(str, special_use); + str_append_c(str, ' '); + } if (str_len(str) != orig_len) str_truncate(str, str_len(str)-1); } @@ -150,6 +155,8 @@ list_flags |= MAILBOX_LIST_ITER_RETURN_SUBSCRIBED; else if (strcasecmp(str, "CHILDREN") == 0) list_flags |= MAILBOX_LIST_ITER_RETURN_CHILDREN; + else if (strcasecmp(str, "SPECIAL-USE") == 0) + list_flags |= MAILBOX_LIST_ITER_RETURN_SPECIALUSE; else if (strcasecmp(str, "STATUS") == 0 && imap_arg_get_list(&args[1], &list_args)) { if (imap_status_parse_items(ctx->cmd, list_args, @@ -262,6 +269,7 @@ list_namespace_send_prefix(struct cmd_list_context *ctx, bool have_children) { struct mail_namespace *const *listed; + const struct mailbox_settings *mailbox_set; unsigned int len; enum mailbox_info_flags flags; const char *name; @@ -330,7 +338,10 @@ str_printfa(str, "* %s (", ctx->lsub ? "LSUB" : "LIST"); if (ctx->lsub) flags |= MAILBOX_NONEXISTENT; - mailbox_flags2str(ctx, str, flags); + mailbox_set = (ctx->list_flags & MAILBOX_LIST_ITER_RETURN_SPECIALUSE) == 0 ? NULL : + mailbox_settings_find(ctx->cmd->client->user, name); + mailbox_flags2str(ctx, str, mailbox_set == NULL ? NULL : + mailbox_set->special_use, flags); str_append(str, ") "); list_reply_append_ns_sep_param(str, ns_sep); str_append_c(str, ' '); @@ -447,7 +458,7 @@ str_truncate(str, 0); str_printfa(str, "* %s (", ctx->lsub ? "LSUB" : "LIST"); - mailbox_flags2str(ctx, str, flags); + mailbox_flags2str(ctx, str, info->special_use, flags); str_append(str, ") "); list_reply_append_ns_sep_param(str, mail_namespace_get_sep(ctx->ns)); @@ -954,8 +965,9 @@ WORKAROUND_TB_LSUB_FLAGS) == 0) ctx->list_flags |= MAILBOX_LIST_ITER_RETURN_NO_FLAGS; } else if (!ctx->used_listext) { - /* non-extended LIST - return children flags always */ - ctx->list_flags |= MAILBOX_LIST_ITER_RETURN_CHILDREN; + /* non-extended LIST: use default flags */ + ctx->list_flags |= MAILBOX_LIST_ITER_RETURN_CHILDREN | + MAILBOX_LIST_ITER_RETURN_SPECIALUSE; } ctx->list_flags |= MAILBOX_LIST_ITER_SHOW_EXISTING_PARENT; diff -r ee783a878120 -r 32d1a903d42d src/lib-storage/mail-storage-settings.c --- a/src/lib-storage/mail-storage-settings.c Fri Dec 02 16:22:31 2011 +0200 +++ b/src/lib-storage/mail-storage-settings.c Fri Dec 02 17:05:31 2011 +0200 @@ -150,6 +150,7 @@ static const struct setting_define mailbox_setting_defines[] = { DEF(SET_STR, name), { SET_ENUM, "auto", offsetof(struct mailbox_settings, autocreate), NULL } , + DEF(SET_STR, special_use), SETTING_DEFINE_LIST_END }; @@ -158,7 +159,8 @@ .name = "", .autocreate = MAILBOX_SET_AUTO_NO":" MAILBOX_SET_AUTO_CREATE":" - MAILBOX_SET_AUTO_SUBSCRIBE + MAILBOX_SET_AUTO_SUBSCRIBE, + .special_use = "" }; const struct setting_parser_info mailbox_setting_parser_info = { @@ -460,7 +462,53 @@ return TRUE; } -static bool mailbox_settings_check(void *_set, pool_t pool ATTR_UNUSED, +static bool mailbox_special_use_exists(const char *name) +{ + if (name[0] != '\\') + return FALSE; + name++; + + if (strcasecmp(name, "All") == 0) + return TRUE; + if (strcasecmp(name, "Archive") == 0) + return TRUE; + if (strcasecmp(name, "Drafts") == 0) + return TRUE; + if (strcasecmp(name, "Flagged") == 0) + return TRUE; + if (strcasecmp(name, "Junk") == 0) + return TRUE; + if (strcasecmp(name, "Sent") == 0) + return TRUE; + if (strcasecmp(name, "Trash") == 0) + return TRUE; + return FALSE; +} + +static bool +mailbox_special_use_check(struct mailbox_settings *set, pool_t pool, + const char **error_r) +{ + const char *const *uses, *str; + unsigned int i; + + uses = t_strsplit_spaces(set->special_use, " "); + for (i = 0; uses[i] != NULL; i++) { + if (!mailbox_special_use_exists(uses[i])) { + *error_r = t_strdup_printf( + "mailbox %s: unknown special_use: %s", + set->name, uses[i]); + return FALSE; + } + } + /* make sure there are no extra spaces */ + str = t_strarray_join(uses, " "); + if (strcmp(str, set->special_use) != 0) + set->special_use = p_strdup(pool, str); + return TRUE; +} + +static bool mailbox_settings_check(void *_set, pool_t pool, const char **error_r) { struct mailbox_settings *set = _set; @@ -470,6 +518,10 @@ set->name); return FALSE; } + if (*set->special_use != '\0') { + if (!mailbox_special_use_check(set, pool, error_r)) + return FALSE; + } return TRUE; } diff -r ee783a878120 -r 32d1a903d42d src/lib-storage/mail-storage-settings.h --- a/src/lib-storage/mail-storage-settings.h Fri Dec 02 16:22:31 2011 +0200 +++ b/src/lib-storage/mail-storage-settings.h Fri Dec 02 17:05:31 2011 +0200 @@ -63,6 +63,7 @@ struct mailbox_settings { const char *name; const char *autocreate; + const char *special_use; }; struct mail_user_settings { diff -r ee783a878120 -r 32d1a903d42d src/lib-storage/mail-storage.c --- a/src/lib-storage/mail-storage.c Fri Dec 02 16:22:31 2011 +0200 +++ b/src/lib-storage/mail-storage.c Fri Dec 02 17:05:31 2011 +0200 @@ -602,7 +602,7 @@ return TRUE; } -static struct mailbox_settings * +const struct mailbox_settings * mailbox_settings_find(struct mail_user *user, const char *vname) { struct mailbox_settings *const *box_set; diff -r ee783a878120 -r 32d1a903d42d src/lib-storage/mail-storage.h --- a/src/lib-storage/mail-storage.h Fri Dec 02 16:22:31 2011 +0200 +++ b/src/lib-storage/mail-storage.h Fri Dec 02 17:05:31 2011 +0200 @@ -429,6 +429,9 @@ /* Returns the storage's settings. */ const struct mail_storage_settings * mailbox_get_settings(struct mailbox *box) ATTR_PURE; +/* Returns the mailbox's settings, or NULL if there are none. */ +const struct mailbox_settings * +mailbox_settings_find(struct mail_user *user, const char *vname); /* Returns name of given mailbox */ const char *mailbox_get_name(const struct mailbox *box) ATTR_PURE; diff -r ee783a878120 -r 32d1a903d42d src/lib-storage/mailbox-list-iter.c --- a/src/lib-storage/mailbox-list-iter.c Fri Dec 02 16:22:31 2011 +0200 +++ b/src/lib-storage/mailbox-list-iter.c Fri Dec 02 17:05:31 2011 +0200 @@ -3,6 +3,7 @@ #include "lib.h" #include "array.h" #include "imap-match.h" +#include "mail-storage.h" #include "mailbox-tree.h" #include "mailbox-list-private.h" @@ -17,6 +18,7 @@ struct autocreate_box { const char *name; + const struct mailbox_settings *set; enum mailbox_info_flags flags; bool child_listed; }; @@ -103,6 +105,7 @@ array_append(&actx->box_sets, &box_sets[i], 1); autobox = array_append_space(&actx->boxes); autobox->name = box_sets[i]->name; + autobox->set = box_sets[i]; } } } @@ -530,18 +533,41 @@ } static const struct mailbox_info * +mailbox_list_iter_next_call(struct mailbox_list_iterate_context *ctx) +{ + const struct mailbox_info *info; + const struct mailbox_settings *set; + + info = ctx->list->v.iter_next(ctx); + if (info == NULL) + return NULL; + + ctx->list->ns->flags |= NAMESPACE_FLAG_USABLE; + if ((ctx->list->flags & MAILBOX_LIST_ITER_RETURN_SPECIALUSE) != 0) { + set = mailbox_settings_find(ctx->list->ns->user, info->name); + if (set != NULL && *set->special_use != '\0') { + ctx->specialuse_info = *info; + ctx->specialuse_info.special_use = + *set->special_use == '\0' ? NULL : + set->special_use; + info = &ctx->specialuse_info; + } + } + return info; +} + +static const struct mailbox_info * autocreate_iter_next(struct mailbox_list_iterate_context *ctx) { struct mailbox_list_autocreate_iterate_context *actx = ctx->autocreate_ctx; const struct mailbox_info *info; - const struct autocreate_box *autoboxes; + const struct autocreate_box *autoboxes, *autobox; unsigned int count; if (actx->idx == 0) { - info = ctx->list->v.iter_next(ctx); + info = mailbox_list_iter_next_call(ctx); if (info != NULL) { - ctx->list->ns->flags |= NAMESPACE_FLAG_USABLE; actx->new_info = *info; return autocreate_iter_existing(ctx); } @@ -550,8 +576,13 @@ /* list missing mailboxes */ autoboxes = array_get(&actx->boxes, &count); while (actx->idx < count) { - if (autocreate_iter_autobox(ctx, &autoboxes[actx->idx++])) + autobox = &autoboxes[actx->idx++]; + if (autocreate_iter_autobox(ctx, autobox)) { + actx->new_info.special_use = + *autobox->set->special_use == '\0' ? NULL : + autobox->set->special_use; return &actx->new_info; + } } i_assert(array_count(&actx->boxes) == array_count(&actx->box_sets)); return NULL; @@ -560,16 +591,10 @@ const struct mailbox_info * mailbox_list_iter_next(struct mailbox_list_iterate_context *ctx) { From dovecot at dovecot.org Fri Dec 2 17:59:41 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 02 Dec 2011 17:59:41 +0200 Subject: dovecot-2.1: README: Added SPECIAL-USE RFC Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/092d55003a7b changeset: 13795:092d55003a7b user: Timo Sirainen date: Fri Dec 02 17:59:24 2011 +0200 description: README: Added SPECIAL-USE RFC diffstat: README | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (11 lines): diff -r 32d1a903d42d -r 092d55003a7b README --- a/README Fri Dec 02 17:05:31 2011 +0200 +++ b/README Fri Dec 02 17:59:24 2011 +0200 @@ -56,6 +56,7 @@ 5267 - Contexts for IMAP4 5530 - IMAP Response Codes 5819 - IMAP4 Extension for Returning STATUS Information in Extended LIST + 6154 - IMAP LIST Extension for Special-Use Mailboxes 6203 - IMAP4 Extension for Fuzzy Search Contact info From dovecot at dovecot.org Fri Dec 2 23:46:16 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 02 Dec 2011 23:46:16 +0200 Subject: dovecot-2.0: auth: Fixed vpopmail to work again after recent cha... Message-ID: details: http://hg.dovecot.org/dovecot-2.0/rev/42a7ba0adafe changeset: 12993:42a7ba0adafe user: Timo Sirainen date: Fri Dec 02 23:45:55 2011 +0200 description: auth: Fixed vpopmail to work again after recent change. diffstat: src/auth/passdb-vpopmail.c | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) diffs (22 lines): diff -r a8c2e04307c6 -r 42a7ba0adafe src/auth/passdb-vpopmail.c --- a/src/auth/passdb-vpopmail.c Wed Nov 23 19:04:15 2011 +0200 +++ b/src/auth/passdb-vpopmail.c Fri Dec 02 23:45:55 2011 +0200 @@ -75,7 +75,8 @@ password = NULL; *result_r = PASSDB_RESULT_USER_DISABLED; } else { - if (vpw->pw_clear_passwd != NULL) { + if (vpw->pw_clear_passwd != NULL && + *vpw->pw_clear_passwd != '\0') { password = t_strdup_noconst(vpw->pw_clear_passwd); *cleartext = TRUE; } else if (!*cleartext) @@ -120,7 +121,7 @@ enum passdb_result result; const char *scheme, *tmp_pass; char *crypted_pass; - bool cleartext; + bool cleartext = FALSE; int ret; crypted_pass = vpopmail_password_lookup(request, &cleartext, &result); From dovecot at dovecot.org Fri Dec 2 23:47:12 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 02 Dec 2011 23:47:12 +0200 Subject: dovecot-2.1: auth: Fixed vpopmail to work again after recent cha... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/c067025026ed changeset: 13796:c067025026ed user: Timo Sirainen date: Fri Dec 02 23:47:01 2011 +0200 description: auth: Fixed vpopmail to work again after recent change. diffstat: src/auth/passdb-vpopmail.c | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) diffs (22 lines): diff -r 092d55003a7b -r c067025026ed src/auth/passdb-vpopmail.c --- a/src/auth/passdb-vpopmail.c Fri Dec 02 17:59:24 2011 +0200 +++ b/src/auth/passdb-vpopmail.c Fri Dec 02 23:47:01 2011 +0200 @@ -75,7 +75,8 @@ password = NULL; *result_r = PASSDB_RESULT_USER_DISABLED; } else { - if (vpw->pw_clear_passwd != NULL) { + if (vpw->pw_clear_passwd != NULL && + *vpw->pw_clear_passwd != '\0') { password = t_strdup_noconst(vpw->pw_clear_passwd); *cleartext = TRUE; } else if (!*cleartext) @@ -120,7 +121,7 @@ enum passdb_result result; const char *scheme, *tmp_pass; char *crypted_pass; - bool cleartext; + bool cleartext = FALSE; int ret; crypted_pass = vpopmail_password_lookup(request, &cleartext, &result); From dovecot at dovecot.org Mon Dec 5 21:23:48 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 05 Dec 2011 21:23:48 +0200 Subject: dovecot-2.1: lib-storage: Don't crash when no there are no mailb... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/272b705f0938 changeset: 13797:272b705f0938 user: Timo Sirainen date: Mon Dec 05 21:23:40 2011 +0200 description: lib-storage: Don't crash when no there are no mailbox {} sections. diffstat: src/lib-storage/mail-storage.c | 3 +++ src/lib-storage/mailbox-list-iter.c | 2 ++ 2 files changed, 5 insertions(+), 0 deletions(-) diffs (25 lines): diff -r c067025026ed -r 272b705f0938 src/lib-storage/mail-storage.c --- a/src/lib-storage/mail-storage.c Fri Dec 02 23:47:01 2011 +0200 +++ b/src/lib-storage/mail-storage.c Mon Dec 05 21:23:40 2011 +0200 @@ -607,6 +607,9 @@ { struct mailbox_settings *const *box_set; + if (!array_is_created(&user->set->mailboxes)) + return NULL; + array_foreach(&user->set->mailboxes, box_set) { if (strcmp((*box_set)->name, vname) == 0) return *box_set; diff -r c067025026ed -r 272b705f0938 src/lib-storage/mailbox-list-iter.c --- a/src/lib-storage/mailbox-list-iter.c Fri Dec 02 23:47:01 2011 +0200 +++ b/src/lib-storage/mailbox-list-iter.c Mon Dec 05 21:23:40 2011 +0200 @@ -78,6 +78,8 @@ struct autocreate_box *autobox; unsigned int i, count; + if (!array_is_created(&user->set->mailboxes)) + return; box_sets = array_get(&user->set->mailboxes, &count); if (count == 0) return; From dovecot at dovecot.org Mon Dec 5 21:25:27 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 05 Dec 2011 21:25:27 +0200 Subject: dovecot-2.1: autocreate: Make sure we don't crash if there are n... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/3054d73cf293 changeset: 13798:3054d73cf293 user: Timo Sirainen date: Mon Dec 05 21:25:22 2011 +0200 description: autocreate: Make sure we don't crash if there are no mailbox{}es. diffstat: src/plugins/autocreate/autocreate-plugin.c | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diffs (13 lines): diff -r 272b705f0938 -r 3054d73cf293 src/plugins/autocreate/autocreate-plugin.c --- a/src/plugins/autocreate/autocreate-plugin.c Mon Dec 05 21:23:40 2011 +0200 +++ b/src/plugins/autocreate/autocreate-plugin.c Mon Dec 05 21:25:22 2011 +0200 @@ -67,6 +67,9 @@ static void autocreate_mail_user_created(struct mail_user *user) { + if (!array_is_created(&user->set->mailboxes)) + p_array_init(&user->set->mailboxes, user->pool, 16); + read_autobox_settings(user, "autocreate", FALSE); read_autobox_settings(user, "autosubscribe", TRUE); } From pigeonhole at rename-it.nl Mon Dec 5 23:29:16 2011 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Mon, 05 Dec 2011 22:29:16 +0100 Subject: dovecot-2.1-pigeonhole: lib-sieve: fixed -Wunused-but-set-variab... Message-ID: details: http://hg.rename-it.nl/dovecot-2.1-pigeonhole/rev/5c6c99a303da changeset: 1570:5c6c99a303da user: Stephan Bosch date: Mon Dec 05 22:28:54 2011 +0100 description: lib-sieve: fixed -Wunused-but-set-variable compiler warning in edit-mail.c. diffstat: src/lib-sieve/edit-mail.c | 12 ++++++------ 1 files changed, 6 insertions(+), 6 deletions(-) diffs (37 lines): diff -r b3bff60a18da -r 5c6c99a303da src/lib-sieve/edit-mail.c --- a/src/lib-sieve/edit-mail.c Tue Nov 29 22:47:13 2011 +0100 +++ b/src/lib-sieve/edit-mail.c Mon Dec 05 22:28:54 2011 +0100 @@ -693,19 +693,19 @@ (const char *value) { string_t *out; - unsigned int i, j; + unsigned int i; - for (i = 0; value[i] != '\0'; i++) { + for ( i = 0; value[i] != '\0'; i++ ) { if (value[i] == '\r' || value[i] == '\n') break; } - if (value[i] == '\0') { + if ( value[i] == '\0' ) { return i_strdup(value); } - + out = t_str_new(i + strlen(value+i) + 10); str_append_n(out, value, i); - for (j = i; value[i] != '\0'; i++) { + for ( ; value[i] != '\0'; i++ ) { if (value[i] == '\n') { i++; if (value[i] == '\0') @@ -722,7 +722,7 @@ str_append_c(out, value[i]); } } - + return i_strndup(str_c(out), str_len(out)); } From dovecot at dovecot.org Tue Dec 6 23:36:13 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 06 Dec 2011 23:36:13 +0200 Subject: dovecot-2.1: master: Be more relaxed about giving service auth's... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/24fe54f2cfcb changeset: 13799:24fe54f2cfcb user: Timo Sirainen date: Tue Dec 06 23:35:58 2011 +0200 description: master: Be more relaxed about giving service auth's client_limit being too low. imap/pop3/lmtp processes with service_count=1 use up a client only for a very short time. Don't count them. diffstat: src/master/master-settings.c | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diffs (14 lines): diff -r 3054d73cf293 -r 24fe54f2cfcb src/master/master-settings.c --- a/src/master/master-settings.c Mon Dec 05 21:25:22 2011 +0200 +++ b/src/master/master-settings.c Tue Dec 06 23:35:58 2011 +0200 @@ -553,7 +553,9 @@ service->protocol)) { /* each imap/pop3/lmtp process can use up a connection, although if service_count=1 it's only temporary */ - max_auth_client_processes += process_limit; + if (service->service_count != 1 || + strcmp(service->type, "login") == 0) + max_auth_client_processes += process_limit; } if (strcmp(service->type, "login") == 0 || strcmp(service->name, "auth") == 0) From dovecot at dovecot.org Tue Dec 6 23:51:32 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 06 Dec 2011 23:51:32 +0200 Subject: dovecot-2.1: lib-storage: Avoid crashes if listing subscriptions... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/85f33815c5e7 changeset: 13800:85f33815c5e7 user: Timo Sirainen date: Tue Dec 06 23:51:09 2011 +0200 description: lib-storage: Avoid crashes if listing subscriptions for a namespace that can't have any. i.e. the namespace and its parents all have subscriptions=no diffstat: src/lib-storage/mailbox-list-iter.c | 7 ++++++- 1 files changed, 6 insertions(+), 1 deletions(-) diffs (17 lines): diff -r 24fe54f2cfcb -r 85f33815c5e7 src/lib-storage/mailbox-list-iter.c --- a/src/lib-storage/mailbox-list-iter.c Tue Dec 06 23:35:58 2011 +0200 +++ b/src/lib-storage/mailbox-list-iter.c Tue Dec 06 23:51:09 2011 +0200 @@ -61,7 +61,12 @@ ns = mail_namespace_find_subscribable(ns->user->namespaces, ns->prefix); if (ns == NULL) { - /* no subscriptions */ + /* no subscriptions. avoid crashes by initializing + a subscriptions tree. */ + if (list->subscriptions == NULL) { + char sep = mail_namespace_get_sep(list->ns); + list->subscriptions = mailbox_tree_init(sep); + } return 0; } } From dovecot at dovecot.org Tue Dec 6 23:53:50 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 06 Dec 2011 23:53:50 +0200 Subject: dovecot-2.1: Moved mailbox {} settings inside namespace {} and n... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/867f06516121 changeset: 13801:867f06516121 user: Timo Sirainen date: Tue Dec 06 23:53:44 2011 +0200 description: Moved mailbox {} settings inside namespace {} and no longer require ns prefix in name. This allows specifying mailboxes more easily with per-user namespace prefixes. diffstat: src/lib-storage/mail-namespace.h | 2 +- src/lib-storage/mail-storage-settings.c | 108 +++++++++++++++------------- src/lib-storage/mail-storage-settings.h | 2 +- src/lib-storage/mail-storage.c | 17 ++++- src/lib-storage/mailbox-list-iter.c | 46 ++++++++--- src/plugins/autocreate/autocreate-plugin.c | 34 ++++++-- 6 files changed, 129 insertions(+), 80 deletions(-) diffs (truncated from 355 to 300 lines): diff -r 85f33815c5e7 -r 867f06516121 src/lib-storage/mail-namespace.h --- a/src/lib-storage/mail-namespace.h Tue Dec 06 23:51:09 2011 +0200 +++ b/src/lib-storage/mail-namespace.h Tue Dec 06 23:53:44 2011 +0200 @@ -66,7 +66,7 @@ /* FIXME: we should support multiple storages in one namespace */ struct mail_storage *storage; - const struct mail_namespace_settings *set, *unexpanded_set; + struct mail_namespace_settings *set, *unexpanded_set; const struct mail_storage_settings *mail_set; unsigned int destroyed:1; diff -r 85f33815c5e7 -r 867f06516121 src/lib-storage/mail-storage-settings.c --- a/src/lib-storage/mail-storage-settings.c Tue Dec 06 23:51:09 2011 +0200 +++ b/src/lib-storage/mail-storage-settings.c Tue Dec 06 23:53:44 2011 +0200 @@ -96,55 +96,6 @@ #undef DEF #define DEF(type, name) \ - { type, #name, offsetof(struct mail_namespace_settings, name), NULL } - -static const struct setting_define mail_namespace_setting_defines[] = { - DEF(SET_STR, name), - DEF(SET_ENUM, type), - DEF(SET_STR, separator), - DEF(SET_STR_VARS, prefix), - DEF(SET_STR_VARS, location), - { SET_ALIAS, "mail", 0, NULL }, - { SET_ALIAS, "mail_location", 0, NULL }, - DEF(SET_STR_VARS, alias_for), - - DEF(SET_BOOL, inbox), - DEF(SET_BOOL, hidden), - DEF(SET_ENUM, list), - DEF(SET_BOOL, subscriptions), - - SETTING_DEFINE_LIST_END -}; - -const struct mail_namespace_settings mail_namespace_default_settings = { - .name = "", - .type = "private:shared:public", - .separator = "", - .prefix = "", - .location = "", - .alias_for = NULL, - - .inbox = FALSE, - .hidden = FALSE, - .list = "yes:no:children", - .subscriptions = TRUE -}; - -const struct setting_parser_info mail_namespace_setting_parser_info = { - .defines = mail_namespace_setting_defines, - .defaults = &mail_namespace_default_settings, - - .type_offset = offsetof(struct mail_namespace_settings, name), - .struct_size = sizeof(struct mail_namespace_settings), - - .parent_offset = offsetof(struct mail_namespace_settings, user_set), - .parent = &mail_user_setting_parser_info, - - .check_func = namespace_settings_check -}; - -#undef DEF -#define DEF(type, name) \ { type, #name, offsetof(struct mailbox_settings, name), NULL } static const struct setting_define mailbox_setting_defines[] = { @@ -179,6 +130,63 @@ #undef DEF #undef DEFLIST_UNIQUE #define DEF(type, name) \ + { type, #name, offsetof(struct mail_namespace_settings, name), NULL } +#define DEFLIST_UNIQUE(field, name, defines) \ + { SET_DEFLIST_UNIQUE, name, \ + offsetof(struct mail_namespace_settings, field), defines } + +static const struct setting_define mail_namespace_setting_defines[] = { + DEF(SET_STR, name), + DEF(SET_ENUM, type), + DEF(SET_STR, separator), + DEF(SET_STR_VARS, prefix), + DEF(SET_STR_VARS, location), + { SET_ALIAS, "mail", 0, NULL }, + { SET_ALIAS, "mail_location", 0, NULL }, + DEF(SET_STR_VARS, alias_for), + + DEF(SET_BOOL, inbox), + DEF(SET_BOOL, hidden), + DEF(SET_ENUM, list), + DEF(SET_BOOL, subscriptions), + + DEFLIST_UNIQUE(mailboxes, "mailbox", &mailbox_setting_parser_info), + + SETTING_DEFINE_LIST_END +}; + +const struct mail_namespace_settings mail_namespace_default_settings = { + .name = "", + .type = "private:shared:public", + .separator = "", + .prefix = "", + .location = "", + .alias_for = NULL, + + .inbox = FALSE, + .hidden = FALSE, + .list = "yes:no:children", + .subscriptions = TRUE, + + .mailboxes = ARRAY_INIT +}; + +const struct setting_parser_info mail_namespace_setting_parser_info = { + .defines = mail_namespace_setting_defines, + .defaults = &mail_namespace_default_settings, + + .type_offset = offsetof(struct mail_namespace_settings, name), + .struct_size = sizeof(struct mail_namespace_settings), + + .parent_offset = offsetof(struct mail_namespace_settings, user_set), + .parent = &mail_user_setting_parser_info, + + .check_func = namespace_settings_check +}; + +#undef DEF +#undef DEFLIST_UNIQUE +#define DEF(type, name) \ { type, #name, offsetof(struct mail_user_settings, name), NULL } #define DEFLIST_UNIQUE(field, name, defines) \ { SET_DEFLIST_UNIQUE, name, \ @@ -208,7 +216,6 @@ DEF(SET_STR, mail_log_prefix), DEFLIST_UNIQUE(namespaces, "namespace", &mail_namespace_setting_parser_info), - DEFLIST_UNIQUE(mailboxes, "mailbox", &mailbox_setting_parser_info), { SET_STRLIST, "plugin", offsetof(struct mail_user_settings, plugin_envs), NULL }, SETTING_DEFINE_LIST_END @@ -238,7 +245,6 @@ .mail_log_prefix = "%s(%u): ", .namespaces = ARRAY_INIT, - .mailboxes = ARRAY_INIT, .plugin_envs = ARRAY_INIT }; diff -r 85f33815c5e7 -r 867f06516121 src/lib-storage/mail-storage-settings.h --- a/src/lib-storage/mail-storage-settings.h Tue Dec 06 23:51:09 2011 +0200 +++ b/src/lib-storage/mail-storage-settings.h Tue Dec 06 23:53:44 2011 +0200 @@ -52,6 +52,7 @@ const char *list; bool subscriptions; + ARRAY_DEFINE(mailboxes, struct mailbox_settings *); struct mail_user_settings *user_set; }; @@ -88,7 +89,6 @@ const char *mail_log_prefix; ARRAY_DEFINE(namespaces, struct mail_namespace_settings *); - ARRAY_DEFINE(mailboxes, struct mailbox_settings *); ARRAY_DEFINE(plugin_envs, const char *); }; diff -r 85f33815c5e7 -r 867f06516121 src/lib-storage/mail-storage.c --- a/src/lib-storage/mail-storage.c Tue Dec 06 23:51:09 2011 +0200 +++ b/src/lib-storage/mail-storage.c Tue Dec 06 23:53:44 2011 +0200 @@ -606,11 +606,24 @@ mailbox_settings_find(struct mail_user *user, const char *vname) { struct mailbox_settings *const *box_set; + struct mail_namespace *ns; - if (!array_is_created(&user->set->mailboxes)) + ns = mail_namespace_find(user->namespaces, vname); + if (ns == NULL) + return NULL; + if (!array_is_created(&ns->set->mailboxes)) return NULL; - array_foreach(&user->set->mailboxes, box_set) { + if (ns->prefix_len > 0 && + strncmp(ns->prefix, vname, ns->prefix_len-1) == 0) { + if (vname[ns->prefix_len-1] == mail_namespace_get_sep(ns)) + vname += ns->prefix_len; + else if (vname[ns->prefix_len-1] == '\0') { + /* namespace prefix itself */ + vname = ""; + } + } + array_foreach(&ns->set->mailboxes, box_set) { if (strcmp((*box_set)->name, vname) == 0) return *box_set; } diff -r 85f33815c5e7 -r 867f06516121 src/lib-storage/mailbox-list-iter.c --- a/src/lib-storage/mailbox-list-iter.c Tue Dec 06 23:51:09 2011 +0200 +++ b/src/lib-storage/mailbox-list-iter.c Tue Dec 06 23:53:44 2011 +0200 @@ -73,19 +73,39 @@ return ns->list->v.subscriptions_refresh(ns->list, list); } +static struct mailbox_settings * +mailbox_settings_add_ns_prefix(pool_t pool, struct mail_namespace *ns, + struct mailbox_settings *in_set) +{ + struct mailbox_settings *out_set; + + if (ns->prefix_len == 0 || strcasecmp(in_set->name, "INBOX") == 0) + return in_set; + + out_set = p_new(pool, struct mailbox_settings, 1); + *out_set = *in_set; + if (*in_set->name == '\0') { + /* namespace prefix itself */ + out_set->name = p_strndup(pool, ns->prefix, ns->prefix_len-1); + } else { + out_set->name = + p_strconcat(pool, ns->prefix, in_set->name, NULL); + } + return out_set; +} + static void mailbox_list_iter_init_autocreate(struct mailbox_list_iterate_context *ctx) { - struct mail_user *user = ctx->list->ns->user; + struct mail_namespace *ns = ctx->list->ns; struct mailbox_list_autocreate_iterate_context *actx; - struct mailbox_settings *const *box_sets; - struct mail_namespace *ns; + struct mailbox_settings *const *box_sets, *set; struct autocreate_box *autobox; unsigned int i, count; - if (!array_is_created(&user->set->mailboxes)) + if (!array_is_created(&ns->set->mailboxes)) return; - box_sets = array_get(&user->set->mailboxes, &count); + box_sets = array_get(&ns->set->mailboxes, &count); if (count == 0) return; @@ -100,19 +120,17 @@ if (strcmp(box_sets[i]->autocreate, MAILBOX_SET_AUTO_NO) == 0) continue; - ns = mail_namespace_find(user->namespaces, box_sets[i]->name); - if (ns != ctx->list->ns) - continue; + set = mailbox_settings_add_ns_prefix(ctx->pool, + ns, box_sets[i]); /* autocreate mailbox belongs to listed namespace */ - array_append(&actx->all_ns_box_sets, &box_sets[i], 1); + array_append(&actx->all_ns_box_sets, &set, 1); if ((ctx->flags & MAILBOX_LIST_ITER_SELECT_SUBSCRIBED) == 0 || - strcmp(box_sets[i]->autocreate, - MAILBOX_SET_AUTO_SUBSCRIBE) == 0) { - array_append(&actx->box_sets, &box_sets[i], 1); + strcmp(set->autocreate, MAILBOX_SET_AUTO_SUBSCRIBE) == 0) { + array_append(&actx->box_sets, &set, 1); autobox = array_append_space(&actx->boxes); - autobox->name = box_sets[i]->name; - autobox->set = box_sets[i]; + autobox->name = set->name; + autobox->set = set; } } } diff -r 85f33815c5e7 -r 867f06516121 src/plugins/autocreate/autocreate-plugin.c --- a/src/plugins/autocreate/autocreate-plugin.c Tue Dec 06 23:51:09 2011 +0200 +++ b/src/plugins/autocreate/autocreate-plugin.c Tue Dec 06 23:53:44 2011 +0200 @@ -7,15 +7,16 @@ #include "array.h" #include "unichar.h" #include "mail-user.h" +#include "mail-namespace.h" #include "mail-storage-hooks.h" #include "autocreate-plugin.h" static struct mailbox_settings * -mailbox_settings_find(struct mail_user *user, const char *vname) +mailbox_settings_find(struct mail_namespace *ns, const char *vname) { struct mailbox_settings *const *box_set; - array_foreach(&user->set->mailboxes, box_set) { + array_foreach(&ns->set->mailboxes, box_set) { if (strcmp((*box_set)->name, vname) == 0) return *box_set; } @@ -25,6 +26,7 @@ static void add_autobox(struct mail_user *user, const char *vname, bool subscriptions) From dovecot at dovecot.org Wed Dec 7 00:30:31 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 07 Dec 2011 00:30:31 +0200 Subject: dovecot-2.1: example-config: Use a default uncommented "namespac... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/2c8d39467f21 changeset: 13802:2c8d39467f21 user: Timo Sirainen date: Tue Dec 06 23:55:48 2011 +0200 description: example-config: Use a default uncommented "namespace inbox". diffstat: doc/example-config/conf.d/10-mail.conf | 11 +++-------- 1 files changed, 3 insertions(+), 8 deletions(-) diffs (35 lines): diff -r 867f06516121 -r 2c8d39467f21 doc/example-config/conf.d/10-mail.conf --- a/doc/example-config/conf.d/10-mail.conf Tue Dec 06 23:53:44 2011 +0200 +++ b/doc/example-config/conf.d/10-mail.conf Tue Dec 06 23:55:48 2011 +0200 @@ -39,12 +39,7 @@ # namespaces you'll typically want to enable ACL plugin also, otherwise all # users can access all the shared mailboxes, assuming they have permissions # on filesystem level to do so. -# -# REMEMBER: If you add any namespaces, the default namespace must be added -# explicitly, ie. mail_location does nothing unless you have a namespace -# without a location setting. Default namespace is simply done by having a -# namespace with empty prefix. -#namespace { +namespace inbox { # Namespace type: private, shared or public #type = private @@ -63,7 +58,7 @@ # There can be only one INBOX, and this setting defines which namespace # has it. - #inbox = no + inbox = yes # If namespace is hidden, it's not advertised to clients via NAMESPACE # extension. You'll most likely also want to set list=no. This is mostly @@ -80,7 +75,7 @@ # Namespace handles its own subscriptions. If set to "no", the parent # namespace handles them (empty prefix should always have this as "yes") #subscriptions = yes -#} +} # Example shared namespace configuration #namespace { From dovecot at dovecot.org Wed Dec 7 00:30:31 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 07 Dec 2011 00:30:31 +0200 Subject: dovecot-2.1: config: Allow section names to contain spaces. Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/2adcc2b87117 changeset: 13803:2adcc2b87117 user: Timo Sirainen date: Wed Dec 07 00:30:26 2011 +0200 description: config: Allow section names to contain spaces. diffstat: src/config/config-parser.c | 25 ++++++++++++++++++------- src/config/doveconf.c | 8 ++++++-- src/lib-settings/settings-parser.c | 5 ++++- 3 files changed, 28 insertions(+), 10 deletions(-) diffs (76 lines): diff -r 2c8d39467f21 -r 2adcc2b87117 src/config/config-parser.c --- a/src/config/config-parser.c Tue Dec 06 23:55:48 2011 +0200 +++ b/src/config/config-parser.c Wed Dec 07 00:30:26 2011 +0200 @@ -642,14 +642,25 @@ *value_r = ""; else { /* get section name */ - *value_r = line; - while (!IS_WHITE(*line) && *line != '\0') - line++; - - if (*line != '\0') { - *line++ = '\0'; - while (IS_WHITE(*line)) + if (*line != '"') { + *value_r = line; + while (!IS_WHITE(*line) && *line != '\0') line++; + if (*line != '\0') { + *line++ = '\0'; + while (IS_WHITE(*line)) + line++; + } + } else { + char *value = ++line; + while (*line != '"' && *line != '\0') + line++; + if (*line == '"') { + *line++ = '\0'; + while (IS_WHITE(*line)) + line++; + *value_r = str_unescape(value); + } } if (*line != '{') { *value_r = "Expecting '='"; diff -r 2c8d39467f21 -r 2adcc2b87117 src/config/doveconf.c --- a/src/config/doveconf.c Tue Dec 06 23:55:48 2011 +0200 +++ b/src/config/doveconf.c Wed Dec 07 00:30:26 2011 +0200 @@ -270,8 +270,12 @@ str_append_n(ctx->list_prefix, key2, p - key2); else str_append(ctx->list_prefix, key2); - if (unique_key && *value != '\0') - str_printfa(ctx->list_prefix, " %s", value); + if (unique_key && *value != '\0') { + if (strchr(value, ' ') == NULL) + str_printfa(ctx->list_prefix, " %s", value); + else + str_printfa(ctx->list_prefix, " \"%s\"", str_escape(value)); + } str_append(ctx->list_prefix, " {\n"); indent++; diff -r 2c8d39467f21 -r 2adcc2b87117 src/lib-settings/settings-parser.c --- a/src/lib-settings/settings-parser.c Tue Dec 06 23:55:48 2011 +0200 +++ b/src/lib-settings/settings-parser.c Wed Dec 07 00:30:26 2011 +0200 @@ -1989,7 +1989,7 @@ const char *settings_section_escape(const char *name) { #define CHAR_NEED_ESCAPE(c) \ - ((c) == '=' || (c) == SETTINGS_SEPARATOR || (c) == '\\') + ((c) == '=' || (c) == SETTINGS_SEPARATOR || (c) == '\\' || (c) == ' ') string_t *str; unsigned int i; @@ -2013,6 +2013,9 @@ case '\\': str_append(str, "\\\\"); break; + case ' ': + str_append(str, "\\_"); + break; default: str_append_c(str, name[i]); break; From dovecot at dovecot.org Wed Dec 7 00:49:10 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 07 Dec 2011 00:49:10 +0200 Subject: dovecot-2.1: example-config: Added example mailboxes. Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/9b9a206395f7 changeset: 13804:9b9a206395f7 user: Timo Sirainen date: Wed Dec 07 00:48:54 2011 +0200 description: example-config: Added example mailboxes. diffstat: doc/example-config/conf.d/15-mailboxes.conf | 47 +++++++++++++++++++++++++++++ doc/example-config/conf.d/Makefile.am | 1 + 2 files changed, 48 insertions(+), 0 deletions(-) diffs (62 lines): diff -r 2adcc2b87117 -r 9b9a206395f7 doc/example-config/conf.d/15-mailboxes.conf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/example-config/conf.d/15-mailboxes.conf Wed Dec 07 00:48:54 2011 +0200 @@ -0,0 +1,47 @@ +## +## Mailbox definitions +## + +# NOTE: Assumes "namespace inbox" has been defined in 10-mail.conf. +namespace inbox { + + #mailbox name { + # auto=create will automatically create this mailbox. + # auto=subscribe will both create and subscribe to the mailbox. + #auto = no + + # Space separated list of IMAP SPECIAL-USE attributes as specified by + # RFC 6154: \All \Archive \Drafts \Flagged \Junk \Sent \Trash + #special_use = + #} + + # These mailboxes are widely used and could perhaps be created automatically: + mailbox Drafts { + special_use = \Drafts + } + mailbox Junk { + special_use = \Junk + } + mailbox Trash { + special_use = \Trash + } + + # For \Sent mailboxes there are two widely used names. We'll mark both of + # them as \Sent. User typically deletes one of them if duplicates are created. + mailbox Sent { + special_use = \Sent + } + mailbox "Sent Messages" { + special_use = \Sent + } + + # If you have a virtual "All messages" mailbox: + #mailbox virtual/All { + # special_use = \All + #} + + # If you have a virtual "Flagged" mailbox: + #mailbox virtual/Flagged { + # special_use = \Flagged + #} +} diff -r 2adcc2b87117 -r 9b9a206395f7 doc/example-config/conf.d/Makefile.am --- a/doc/example-config/conf.d/Makefile.am Wed Dec 07 00:30:26 2011 +0200 +++ b/doc/example-config/conf.d/Makefile.am Wed Dec 07 00:48:54 2011 +0200 @@ -18,6 +18,7 @@ 10-master.conf \ 10-ssl.conf \ 15-lda.conf \ + 15-mailboxes.conf \ 20-imap.conf \ 20-lmtp.conf \ 20-pop3.conf \ From dovecot at dovecot.org Wed Dec 7 01:28:30 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 07 Dec 2011 01:28:30 +0200 Subject: dovecot-2.1: lib-storage: MAILBOX_LIST_ITER_RETURN_SPECIALUSE wa... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/b6083d4d77d5 changeset: 13805:b6083d4d77d5 user: Timo Sirainen date: Wed Dec 07 01:28:20 2011 +0200 description: lib-storage: MAILBOX_LIST_ITER_RETURN_SPECIALUSE was checked wrong diffstat: src/lib-storage/mailbox-list-iter.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 9b9a206395f7 -r b6083d4d77d5 src/lib-storage/mailbox-list-iter.c --- a/src/lib-storage/mailbox-list-iter.c Wed Dec 07 00:48:54 2011 +0200 +++ b/src/lib-storage/mailbox-list-iter.c Wed Dec 07 01:28:20 2011 +0200 @@ -568,7 +568,7 @@ return NULL; ctx->list->ns->flags |= NAMESPACE_FLAG_USABLE; - if ((ctx->list->flags & MAILBOX_LIST_ITER_RETURN_SPECIALUSE) != 0) { + if ((ctx->flags & MAILBOX_LIST_ITER_RETURN_SPECIALUSE) != 0) { set = mailbox_settings_find(ctx->list->ns->user, info->name); if (set != NULL && *set->special_use != '\0') { ctx->specialuse_info = *info; From dovecot at dovecot.org Wed Dec 7 01:48:14 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 07 Dec 2011 01:48:14 +0200 Subject: dovecot-2.1: lib-index: Added mail_index_reset_fscked() Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/8535def4ad01 changeset: 13806:8535def4ad01 user: Timo Sirainen date: Wed Dec 07 01:46:42 2011 +0200 description: lib-index: Added mail_index_reset_fscked() diffstat: src/lib-index/mail-index-fsck.c | 10 ++++++++++ src/lib-index/mail-index-private.h | 1 + src/lib-index/mail-index.h | 3 +++ 3 files changed, 14 insertions(+), 0 deletions(-) diffs (48 lines): diff -r b6083d4d77d5 -r 8535def4ad01 src/lib-index/mail-index-fsck.c --- a/src/lib-index/mail-index-fsck.c Wed Dec 07 01:28:20 2011 +0200 +++ b/src/lib-index/mail-index-fsck.c Wed Dec 07 01:46:42 2011 +0200 @@ -431,6 +431,8 @@ i_warning("fscking index file %s", index->filepath); + index->fscked = TRUE; + if (index->log->head == NULL) { /* we're trying to open the index files, but there wasn't any .log file. */ @@ -469,3 +471,11 @@ ret = mail_index_fsck(index); i_assert(ret == 0); } + +bool mail_index_reset_fscked(struct mail_index *index) +{ + bool ret = index->fscked; + + index->fscked = FALSE; + return ret; +} diff -r b6083d4d77d5 -r 8535def4ad01 src/lib-index/mail-index-private.h --- a/src/lib-index/mail-index-private.h Wed Dec 07 01:28:20 2011 +0200 +++ b/src/lib-index/mail-index-private.h Wed Dec 07 01:46:42 2011 +0200 @@ -241,6 +241,7 @@ unsigned int modseqs_enabled:1; unsigned int initial_create:1; unsigned int initial_mapped:1; + unsigned int fscked:1; }; extern struct mail_index_module_register mail_index_module_register; diff -r b6083d4d77d5 -r 8535def4ad01 src/lib-index/mail-index.h --- a/src/lib-index/mail-index.h Wed Dec 07 01:28:20 2011 +0200 +++ b/src/lib-index/mail-index.h Wed Dec 07 01:46:42 2011 +0200 @@ -360,6 +360,9 @@ /* Check and fix any found problems. Returns -1 if we couldn't lock for sync, 0 if everything went ok. */ int mail_index_fsck(struct mail_index *index); +/* Returns TRUE if mail_index_fsck() has been called since the last + mail_index_reset_fscked() call. */ +bool mail_index_reset_fscked(struct mail_index *index); /* Synchronize changes in view. You have to go through all records, or view will be marked inconsistent. Only sync_mask type records are From dovecot at dovecot.org Wed Dec 7 01:48:14 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 07 Dec 2011 01:48:14 +0200 Subject: dovecot-2.1: dbox: If index was fscked, rebuild indexes to make ... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/1e118913348b changeset: 13807:1e118913348b user: Timo Sirainen date: Wed Dec 07 01:48:03 2011 +0200 description: dbox: If index was fscked, rebuild indexes to make sure no mails got lost. diffstat: src/lib-storage/index/dbox-multi/mdbox-map.c | 4 ++++ src/lib-storage/index/dbox-multi/mdbox-sync.c | 4 ++++ src/lib-storage/index/dbox-single/sdbox-sync.c | 7 ++++++- 3 files changed, 14 insertions(+), 1 deletions(-) diffs (66 lines): diff -r 8535def4ad01 -r 1e118913348b src/lib-storage/index/dbox-multi/mdbox-map.c --- a/src/lib-storage/index/dbox-multi/mdbox-map.c Wed Dec 07 01:46:42 2011 +0200 +++ b/src/lib-storage/index/dbox-multi/mdbox-map.c Wed Dec 07 01:48:03 2011 +0200 @@ -222,6 +222,8 @@ ctx = mail_index_view_sync_begin(map->view, MAIL_INDEX_VIEW_SYNC_FLAG_FIX_INCONSISTENT); + if (mail_index_reset_fscked(map->view->index)) + mdbox_storage_set_corrupted(map->storage); if (mail_index_view_sync_commit(&ctx, &delayed_expunges) < 0) { mail_storage_set_internal_error(MAP_STORAGE(map)); mail_index_reset_error(map->index); @@ -473,6 +475,8 @@ log's head_offset = tail_offset */ ret = mail_index_sync_begin(atomic->map->index, &atomic->sync_ctx, &atomic->sync_view, &atomic->sync_trans, 0); + if (mail_index_reset_fscked(atomic->map->index)) + mdbox_storage_set_corrupted(atomic->map->storage); if (ret <= 0) { i_assert(ret != 0); mail_storage_set_internal_error(MAP_STORAGE(atomic->map)); diff -r 8535def4ad01 -r 1e118913348b src/lib-storage/index/dbox-multi/mdbox-sync.c --- a/src/lib-storage/index/dbox-multi/mdbox-sync.c Wed Dec 07 01:46:42 2011 +0200 +++ b/src/lib-storage/index/dbox-multi/mdbox-sync.c Wed Dec 07 01:48:03 2011 +0200 @@ -190,6 +190,8 @@ ret = mail_index_sync_begin(mbox->box.index, &ctx->index_sync_ctx, &ctx->sync_view, &ctx->trans, sync_flags); + if (mail_index_reset_fscked(mbox->box.index)) + mdbox_storage_set_corrupted(mbox->storage); if (ret < 0) { mail_storage_set_index_error(&mbox->box); return -1; @@ -328,6 +330,8 @@ ret = -1; } + if (mail_index_reset_fscked(box->index)) + mdbox_storage_set_corrupted(mbox->storage); if (ret == 0 && (index_mailbox_want_full_sync(&mbox->box, flags) || mbox->storage->corrupted)) { if ((flags & MAILBOX_SYNC_FLAG_FORCE_RESYNC) != 0) diff -r 8535def4ad01 -r 1e118913348b src/lib-storage/index/dbox-single/sdbox-sync.c --- a/src/lib-storage/index/dbox-single/sdbox-sync.c Wed Dec 07 01:46:42 2011 +0200 +++ b/src/lib-storage/index/dbox-single/sdbox-sync.c Wed Dec 07 01:48:03 2011 +0200 @@ -191,6 +191,8 @@ &ctx->index_sync_ctx, &ctx->sync_view, &ctx->trans, sync_flags); + if (mail_index_reset_fscked(mbox->box.index)) + sdbox_set_mailbox_corrupted(&mbox->box); if (ret <= 0) { if (ret < 0) mail_storage_set_index_error(&mbox->box); @@ -283,7 +285,10 @@ ret = -1; } - if (ret == 0 && index_mailbox_want_full_sync(&mbox->box, flags)) { + if (mail_index_reset_fscked(box->index)) + sdbox_set_mailbox_corrupted(box); + if (ret == 0 && (index_mailbox_want_full_sync(&mbox->box, flags) || + mbox->corrupted_rebuild_count != 0)) { if ((flags & MAILBOX_SYNC_FLAG_FORCE_RESYNC) != 0) sdbox_sync_flags |= SDBOX_SYNC_FLAG_FORCE_REBUILD; ret = sdbox_sync(mbox, sdbox_sync_flags); From pigeonhole at rename-it.nl Wed Dec 7 23:59:26 2011 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Wed, 07 Dec 2011 22:59:26 +0100 Subject: dovecot-2.1-pigeonhole: Completed sieve-filter tool to a useful ... Message-ID: details: http://hg.rename-it.nl/dovecot-2.1-pigeonhole/rev/3eb7a7460fa3 changeset: 1571:3eb7a7460fa3 user: Stephan Bosch date: Wed Dec 07 22:59:14 2011 +0100 description: Completed sieve-filter tool to a useful state. - Now compiles regularly without --with-unfinished-features - Still experimental though, so be careful. - Changed command structure a bit, removing the useless -M option. diffstat: TODO | 10 +-- doc/man/Makefile.am | 11 +-- doc/man/sieve-filter.1.in | 130 ++++++++++++++++---------------- src/sieve-tools/Makefile.am | 6 +- src/sieve-tools/sieve-filter.c | 185 ++++++++++++++++++++++++--------------------- 5 files changed, 170 insertions(+), 172 deletions(-) diffs (truncated from 696 to 300 lines): diff -r 5c6c99a303da -r 3eb7a7460fa3 TODO --- a/TODO Mon Dec 05 22:28:54 2011 +0100 +++ b/TODO Wed Dec 07 22:59:14 2011 +0100 @@ -1,6 +1,7 @@ Current activities: -- +* Build a sieve tool to filter an entire existing mailbox through a Sieve + script. Parallel plugin-based efforts: @@ -14,13 +15,6 @@ Next (mostly in order of descending priority/precedence): * Implement index extension -* Build a sieve tool to filter an entire existing mailbox through a Sieve - script. - > Needs to have single mail transaction for each destination folder for - all moved messages. Otherwise, partial failure cannot be prevented. - - Implement ability to group Sieve execution results of all processed messages - into one big `Sieve transaction' object, which (among other things) keeps - track of opened mailboxes and transactions. Is probably also more efficient. * Update include extension to latest draft (v10 currently): - Implement :optional tag. - Implement required ManageSieve behavior diff -r 5c6c99a303da -r 3eb7a7460fa3 doc/man/Makefile.am --- a/doc/man/Makefile.am Mon Dec 05 22:28:54 2011 +0100 +++ b/doc/man/Makefile.am Wed Dec 07 22:59:14 2011 +0100 @@ -1,10 +1,5 @@ pkgsysconfdir = $(sysconfdir)/dovecot rundir = ${prefix}/var/run/dovecot -unfinished = sieve-filter.1 - -if BUILD_UNFINISHED -unfinished_mans = $(unfinished) -endif dist_man1_MANS = \ sieved.1 @@ -13,7 +8,7 @@ sievec.1 \ sieve-dump.1 \ sieve-test.1 \ - $(unfinished_mans) + sieve-filter.1 nodist_man7_MANS = \ pigeonhole.7 @@ -27,8 +22,8 @@ sieve-test.1.in \ sieve-filter.1.in \ pigeonhole.7.in \ - sed.sh \ - $(man_includefiles) + sed.sh \ + $(man_includefiles) CLEANFILES = $(nodist_man1_MANS) $(nodist_man7_MANS) diff -r 5c6c99a303da -r 3eb7a7460fa3 doc/man/sieve-filter.1.in --- a/doc/man/sieve-filter.1.in Mon Dec 05 22:28:54 2011 +0100 +++ b/doc/man/sieve-filter.1.in Wed Dec 07 22:59:14 2011 +0100 @@ -4,17 +4,17 @@ sieve\-filter \- Pigeonhole\(aqs Sieve mailbox filter tool .PP -\fBWARNING: \fRThis tool is not finished and should \fB*NOT*\fR be used, unless -you feel like testing newly developed features! The behavior described in this -manual page represents the design and not necessarily what the tool currently -implements. +\fBWARNING: \fRThis tool is still experimental. Read this manual carefully, and +backup any important mail before using this tool. Also note that some of the +features documented here are not actually implemented yet; this is clearly +indicated where applicable. .\"------------------------------------------------------------------------ .SH SYNOPSIS .B sieve\-filter .RI [ options ] .I script\-file .I source\-mailbox -.RI [ source\-action ] +.RI [ discard\-action ] .SH DESCRIPTION .PP The \fBsieve\-filter\fP command is part of the Pigeonhole Project @@ -25,29 +25,37 @@ However, there are occasions when it is desirable to filter messages that are already stored in a mailbox, for instance when a bug in a Sieve script caused many messages to be delivered incorrectly. Using the sieve\-filter tool it is -possible to apply a Sieve script on all messages in a particular mailbox, making -it possible to delete messages, to store them in a different mailbox and to -change the assigned IMAP flags and keywords. Attempts to send messages to the -outside world are ignored by default for obvious reasons, but, using the proper -command line options, it is possible to capture outgoing mail as well. +possible to apply a Sieve script on all messages in a particular +\fIsource\-mailbox\fP, making it possible to delete messages, to store them in a +different mailbox and to change the assigned IMAP flags and keywords. Attempts +to send messages to the outside world are ignored by default for obvious +reasons, but, using the proper command line options, it is possible to capture +and handle outgoing mail as well. .PP If no options are specified, the sieve\-filter command runs in a simulation mode in which it only prints what would be performed, without actually doing anything. Use the \fB\-e\fP option to activate true script execution. Also, the -source mailbox is opened read\-only by default, so that the source mailbox -remains unchanged. Use the \fB\-W\fP option to allow changes in the source mailbox. -And even with the \fB\-W\fP option enabled, messages in the source mailbox are -only potentially modified and not (re)moved, unless a \fIsource\-action\fP -argument other than \fBkeep\fP is specified. +\fIsource\-mailbox\fP is opened read\-only by default, meaning that it normally +always remains unchanged. Use the \fB\-W\fP option to allow changes in the +\fIsource\-mailbox\fP. +.PP +Even with the \fB\-W\fP option enabled, messages in the \fIsource\-mailbox\fP +are only potentially modified or moved to a different folder. Messages are never +lost unless a \fIdiscard\-action\fP argument other than \fBkeep\fP (the default) +is specified. If the Sieve filter decides to store the message in the +\fIsource\-mailbox\fP, where it obviously already exists, it is never duplicated +there. However, in that case, the IMAP flags of the original message can be +modified by the Sieve interpreter, provided that \fB\-W\fP is specified. + .SS CAUTION Although this is a very useful tool, it can also be very destructive when used improperly. A small bug in your Sieve script in combination with the wrong command line options could cause it to discard the wrong e\-mails. And, even if -the source mailbox is opened in read\-only mode to prevent such mishaps, it can -still litter other mailboxes with spurious copies of your e\-mails if your Sieve -script decides to do so. Therefore, users are advised to read this manual -carefully and to use the simulation mode first to check what the script will do. -And, of course: +the \fIsource\-mailbox\fP is opened in read\-only mode to prevent such mishaps, +it can still litter other mailboxes with spurious copies of your e\-mails if +your Sieve script decides to do so. Therefore, users are advised to read this +manual carefully and to use the simulation mode first to check what the script +will do. And, of course: .PP \fBMAKING A BACKUP IS IMPERATIVE FOR ANY IMPORTANT MAIL!\fP @@ -72,32 +80,24 @@ Turns on execution mode. By default, the sieve\-filter command runs in simulation mode in which it changes nothing, meaning that no mailbox is altered in any way and no actions are performed. It only prints what would be done. -Using this option the sieve\-filter command becomes active and performs the +Using this option, the sieve\-filter command becomes active and performs the requested actions. .TP .BI \-m\ default\-mailbox -The mailbox where the (implicit) \fBkeep\fP Sieve action stores messages. This is -equal to the source mailbox by default. +The mailbox where the (implicit) \fBkeep\fP Sieve action stores messages. This +is equal to the \fIsource\-mailbox\fP by default. Specifying a different folder +will have the effect of moving (or copying if \fB\-W\fP is omitted) all kept +messages to the indicated folder, instead of just leaving them in the +\fIsource\-mailbox\fP. .TP -.B \-M -Enable move mode. This will cause all messages that were succesfully stored -somewhere else to be expunged from the source mailbox, regardless of what the -\fIsource\-action\fP is (refer to Arguments section below). However, if the -Sieve filter decides to keep the message in the source mailbox, it is left -there and not affected by this option. -.IP -Note that some Sieve actions, such as \fBredirect\fP, don't store the message -anywhere and are thus \- with respect to the fate of the message in the source -mailbox \- treated as if a \fBdiscard\fP action were executed. -.TP -.BI \-q\ output\-mailbox\ \fR[not\ implemented\ yet]\fP +.BI \-q\ output\-mailbox\ \fB[not\ implemented\ yet]\fP Store outgoing e\-mail into the indicated \fIoutput\-mailbox\fP. By default, the sieve\-filter command ignores Sieve actions such as redirect, reject, vacation and notify, but using this option outgoing messages can be appended to the indicated mailbox. This option has no effect in simulation mode. Flags of redirected messages are not preserved. .TP -.BI \-Q\ mail\-command\ \fR[not\ implemented\ yet]\fP +.BI \-Q\ mail\-command\ \fB[not\ implemented\ yet]\fP Send outgoing e\-mail (e.g. as produced by redirect, reject and vacation) through the specified program. By default, the sieve\-filter command ignores Sieve actions such as redirect, reject, vacation and notify, but using this @@ -105,7 +105,7 @@ command. This option has no effect in simulation mode. Unless you really know what you are doing, \fBDO NOT USE THIS TO FEED MAIL TO SENDMAIL!\fP. .TP -.BI \-s\ script\-file\ \fR[not\ implemented\ yet]\fP +.BI \-s\ script\-file\ \fB[not\ implemented\ yet]\fP Specify additional scripts to be executed before the main script. Multiple \fB\-s\fP arguments are allowed and the specified scripts are executed sequentially in the order specified at the command @@ -114,9 +114,13 @@ .BI \-u\ user Run the Sieve script for the given \fIuser\fP. .TP +.B \-v\ +Produce verbose output during filtering. +.TP .B \-W -Enables write access to the source mailbox. This allows deleting the messages -from the source mailbox and changing the assigned IMAP flags and keywords. +Enables write access to the \fIsource\-mailbox\fP. This allows (re)moving the +messages from the \fIsource\-mailbox\fP and changing the assigned IMAP flags and +keywords. .TP .BI \-x\ extensions Set the available extensions. The parameter is a space\-separated list of the @@ -136,7 +140,7 @@ .SH ARGUMENTS .TP .I script\-file -Specifies the script to (compile and) execute. +Specifies the Sieve script to (compile and) execute. Note that this tool looks for a pre\-compiled binary file with a \fI.svbin\fP extension and with basename and path identical to the specified script. Use the @@ -144,44 +148,40 @@ into a new binary. .TP .I source\-mailbox -The name of the source mailbox. +The name of the source mailbox containing the messages that the Sieve filter +will act upon. This mailbox is not modified unless the \fB\-W\fP option is +specified. .TP -.I source\-action -Specifies what is done with messages in the source mailbox once processed by the -Sieve script. The \fIsource\-action\fP parameter accepts one of the following values: +.I discard\-action +Specifies what is done with messages in the \fIsource\-mailbox\fP that where not +kept or otherwise stored by the Sieve script; i.e. those messages that would +normally be discarded if the Sieve script were executed at delivery. +The \fIdiscard\-action\fP parameter accepts one of the following values: .RS 7 .TP .BR keep\ (default) -Keep processed messages in source mailbox. When the filter decides to store the message -in the source mailbox, it is never duplicated there. However, in that case, the -IMAP flags of the original message can be modified by the Sieve interpreter. +Keep discarded messages in source mailbox. .TP .BI move\ mailbox -Move processed messages to the indicated \fImailbox\fP. This is for instance useful -to move messages to a Trash mailbox. +Move discarded messages to the indicated \fImailbox\fP. This is for instance +useful to move messages to a Trash mailbox. .TP .B delete -Flag processed messages as \\DELETED. +Flag discarded messages as \\DELETED. .TP .B expunge -Expunge processed messages, meaning that these are removed irreversibly when the +Expunge discarded messages, meaning that these are removed irreversibly when the tool finishes filtering. .RE .IP -The \fBsource\-action\fP is normally applied to all messages in the source mailbox, -but there are a few exceptions: -.RS 7 -.IP \(bu -When the \fB\-W\fP option is not specified, the source mailbox is immutable and -the specified \fIsource\-action\fP has no effect. -.IP \(bu -When the \fB\-M\fR option (move mode) is active, all messages that were -successfully moved to another mailbox are expunged irrespective of the specified -\fIsource\-action\fP. -.IP \(bu -If the filter decides to keep the message in the source mailbox, it is left there -and not affected by the \fIsource\-action\fP. -.RE +When the \fB\-W\fP option is not specified, the \fIsource\-mailbox\fP is +immutable and the specified \fIdiscard\-action\fP has no effect. This means that +messages are at most \fIcopied\fP to a new location. In contrast, when the +\fB\-W\fP is specified, messages that are successfully stored somewhere else by +the Sieve script are \fBalways\fP expunged from the \fIsource\-mailbox\fP, with +the effect that these are thus \fImoved\fP to the new location. This happens +irrespective of the specified \fIdiscard\-action\fP. Remember: only discarded +messages are affected by the specified \fIdiscard\-action\fP. .\"------------------------------------------------------------------------ diff -r 5c6c99a303da -r 3eb7a7460fa3 src/sieve-tools/Makefile.am --- a/src/sieve-tools/Makefile.am Mon Dec 05 22:28:54 2011 +0100 +++ b/src/sieve-tools/Makefile.am Wed Dec 07 22:59:14 2011 +0100 @@ -1,8 +1,4 @@ -bin_PROGRAMS = sievec sieve-dump sieve-test - -if BUILD_UNFINISHED -bin_PROGRAMS += sieve-filter -endif +bin_PROGRAMS = sievec sieve-dump sieve-test sieve-filter AM_CPPFLAGS = \ -I$(top_srcdir)/src/lib-sieve \ diff -r 5c6c99a303da -r 3eb7a7460fa3 src/sieve-tools/sieve-filter.c --- a/src/sieve-tools/sieve-filter.c Mon Dec 05 22:28:54 2011 +0100 +++ b/src/sieve-tools/sieve-filter.c Wed Dec 07 22:59:14 2011 +0100 @@ -36,20 +36,20 @@ printf( "Usage: sieve-filter [-c ] [-C] [-D] [-e] [-m ]\n" " [-P ] [-q ] [-Q ]\n" From dovecot at dovecot.org Thu Dec 8 05:03:37 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 08 Dec 2011 05:03:37 +0200 Subject: dovecot-2.1: director: Don't explicitly use base_dir. We're alre... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/ddf28d10ff0f changeset: 13809:ddf28d10ff0f user: Timo Sirainen date: Thu Dec 08 05:02:15 2011 +0200 description: director: Don't explicitly use base_dir. We're already chdired there, use relative paths. diffstat: src/director/Makefile.am | 3 +-- src/director/director-settings.c | 2 -- src/director/director-settings.h | 1 - src/director/director.c | 4 +--- src/director/main.c | 10 +--------- 5 files changed, 3 insertions(+), 17 deletions(-) diffs (105 lines): diff -r 3027626f7239 -r ddf28d10ff0f src/director/Makefile.am --- a/src/director/Makefile.am Thu Dec 08 05:02:12 2011 +0200 +++ b/src/director/Makefile.am Thu Dec 08 05:02:15 2011 +0200 @@ -7,8 +7,7 @@ -I$(top_srcdir)/src/lib-auth \ -I$(top_srcdir)/src/lib-imap \ -I$(top_srcdir)/src/lib-settings \ - -I$(top_srcdir)/src/lib-master \ - -DPKG_RUNDIR=\""$(rundir)"\" + -I$(top_srcdir)/src/lib-master director_LDADD = $(LIBDOVECOT) director_DEPENDENCIES = $(LIBDOVECOT_DEPS) diff -r 3027626f7239 -r ddf28d10ff0f src/director/director-settings.c --- a/src/director/director-settings.c Thu Dec 08 05:02:12 2011 +0200 +++ b/src/director/director-settings.c Thu Dec 08 05:02:15 2011 +0200 @@ -64,7 +64,6 @@ { type, #name, offsetof(struct director_settings, name), NULL } static const struct setting_define director_setting_defines[] = { - DEF(SET_STR, base_dir), DEF(SET_STR, master_user_separator), DEF(SET_STR, director_servers), @@ -76,7 +75,6 @@ }; const struct director_settings director_default_settings = { - .base_dir = PKG_RUNDIR, .master_user_separator = "", .director_servers = "", diff -r 3027626f7239 -r ddf28d10ff0f src/director/director-settings.h --- a/src/director/director-settings.h Thu Dec 08 05:02:12 2011 +0200 +++ b/src/director/director-settings.h Thu Dec 08 05:02:15 2011 +0200 @@ -2,7 +2,6 @@ #define DIRECTOR_SETTINGS_H struct director_settings { - const char *base_dir; const char *master_user_separator; const char *director_servers; diff -r 3027626f7239 -r ddf28d10ff0f src/director/director.c --- a/src/director/director.c Thu Dec 08 05:02:12 2011 +0200 +++ b/src/director/director.c Thu Dec 08 05:02:15 2011 +0200 @@ -576,7 +576,6 @@ director_state_change_callback_t *callback) { struct director *dir; - const char *path; dir = i_new(struct director, 1); dir->set = set; @@ -588,8 +587,7 @@ dir->users = user_directory_init(set->director_user_expire); dir->mail_hosts = mail_hosts_init(); - path = t_strconcat(set->base_dir, "/" DIRECTOR_IPC_PROXY_PATH, NULL); - dir->ipc_proxy = ipc_client_init(path); + dir->ipc_proxy = ipc_client_init(DIRECTOR_IPC_PROXY_PATH); return dir; } diff -r 3027626f7239 -r ddf28d10ff0f src/director/main.c --- a/src/director/main.c Thu Dec 08 05:02:12 2011 +0200 +++ b/src/director/main.c Thu Dec 08 05:02:15 2011 +0200 @@ -25,7 +25,6 @@ static struct director *director; static struct notify_connection *notify_conn; -static char *auth_socket_path, *userdb_socket_path; static int director_client_connected(int fd, const struct ip_addr *ip) { @@ -93,7 +92,7 @@ Both of them are handled exactly the same, except for which auth socket they connect to. */ userdb = len > 7 && strcmp(name + len - 7, "-userdb") == 0; - socket_path = userdb ? userdb_socket_path : auth_socket_path; + socket_path = userdb ? AUTH_USERDB_SOCKET_PATH : AUTH_SOCKET_PATH; auth = auth_connection_init(socket_path); if (auth_connection_connect(auth) == 0) { master_service_client_connection_accept(conn); @@ -151,11 +150,6 @@ set = master_service_settings_get_others(master_service)[0]; - auth_socket_path = i_strconcat(set->base_dir, - "/"AUTH_SOCKET_PATH, NULL); - userdb_socket_path = i_strconcat(set->base_dir, - "/"AUTH_USERDB_SOCKET_PATH, NULL); - listen_port = find_inet_listener_port(&listen_ip, set); if (listen_port == 0 && *set->director_servers != '\0') { i_fatal("No inet_listeners defined for director service " @@ -179,8 +173,6 @@ doveadm_connections_deinit(); login_connections_deinit(); auth_connections_deinit(); - i_free(auth_socket_path); - i_free(userdb_socket_path); } int main(int argc, char *argv[]) From dovecot at dovecot.org Thu Dec 8 05:03:37 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 08 Dec 2011 05:03:37 +0200 Subject: dovecot-2.1: director-test.sh script fixed to use a working path... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/3027626f7239 changeset: 13808:3027626f7239 user: Timo Sirainen date: Thu Dec 08 05:02:12 2011 +0200 description: director-test.sh script fixed to use a working path for director-test binary. diffstat: src/director/director-test.sh | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diffs (21 lines): diff -r 1e118913348b -r 3027626f7239 src/director/director-test.sh --- a/src/director/director-test.sh Wed Dec 07 01:48:03 2011 +0200 +++ b/src/director/director-test.sh Thu Dec 08 05:02:12 2011 +0200 @@ -4,6 +4,8 @@ echo "Add to /etc/hosts:" +curpath=`pwd` + hosts="" dirs="" i=0 @@ -64,7 +66,7 @@ } } service director-test { - executable = director-test /var/run/dovecot1/director-admin + executable = $curpath/director-test /var/run/dovecot1/director-admin process_limit = 1 inet_listener { From dovecot at dovecot.org Thu Dec 8 05:03:37 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 08 Dec 2011 05:03:37 +0200 Subject: dovecot-2.1: director: chroot to base_dir by default. Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/eebee8a4d486 changeset: 13810:eebee8a4d486 user: Timo Sirainen date: Thu Dec 08 05:03:22 2011 +0200 description: director: chroot to base_dir by default. diffstat: src/director/director-settings.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r ddf28d10ff0f -r eebee8a4d486 src/director/director-settings.c --- a/src/director/director-settings.c Thu Dec 08 05:02:15 2011 +0200 +++ b/src/director/director-settings.c Thu Dec 08 05:03:22 2011 +0200 @@ -40,7 +40,7 @@ .group = "", .privileged_group = "", .extra_groups = "", - .chroot = "", + .chroot = ".", .drop_priv_before_exec = FALSE, From dovecot at dovecot.org Thu Dec 8 05:13:53 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 08 Dec 2011 05:13:53 +0200 Subject: dovecot-2.1: ssl_parameters_regenerate setting is now "time" typ... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/ed9f4e03c2f9 changeset: 13812:ed9f4e03c2f9 user: Timo Sirainen date: Thu Dec 08 05:12:12 2011 +0200 description: ssl_parameters_regenerate setting is now "time" type, as it should have been. diffstat: src/config/old-set-parser.c | 6 ++++++ src/ssl-params/ssl-params-settings.c | 4 ++-- src/ssl-params/ssl-params.c | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) diffs (47 lines): diff -r 55a70ae49cb7 -r ed9f4e03c2f9 src/config/old-set-parser.c --- a/src/config/old-set-parser.c Thu Dec 08 05:05:57 2011 +0200 +++ b/src/config/old-set-parser.c Thu Dec 08 05:12:12 2011 +0200 @@ -140,6 +140,12 @@ set_rename(ctx, key, "ssl", value); return TRUE; } + if (strcmp(key, "ssl_parameters_regenerate") == 0 && + str_is_numeric(value, '\0')) { + obsolete(ctx, "%s should have 'hours' suffix", key); + config_apply_line(ctx, "", t_strconcat(key, "=", value, "h", NULL), NULL); + return TRUE; + } if (strcmp(key, "sieve") == 0 || strcmp(key, "sieve_storage") == 0) { if (strcmp(key, "sieve_storage") == 0) diff -r 55a70ae49cb7 -r ed9f4e03c2f9 src/ssl-params/ssl-params-settings.c --- a/src/ssl-params/ssl-params-settings.c Thu Dec 08 05:05:57 2011 +0200 +++ b/src/ssl-params/ssl-params-settings.c Thu Dec 08 05:12:12 2011 +0200 @@ -58,13 +58,13 @@ { type, #name, offsetof(struct ssl_params_settings, name), NULL } static const struct setting_define ssl_params_setting_defines[] = { - DEF(SET_UINT, ssl_parameters_regenerate), + DEF(SET_TIME, ssl_parameters_regenerate), SETTING_DEFINE_LIST_END }; static const struct ssl_params_settings ssl_params_default_settings = { - .ssl_parameters_regenerate = 24*7 + .ssl_parameters_regenerate = 3600*24*7 }; const struct setting_parser_info ssl_params_setting_parser_info = { diff -r 55a70ae49cb7 -r ed9f4e03c2f9 src/ssl-params/ssl-params.c --- a/src/ssl-params/ssl-params.c Thu Dec 08 05:05:57 2011 +0200 +++ b/src/ssl-params/ssl-params.c Thu Dec 08 05:12:12 2011 +0200 @@ -137,7 +137,7 @@ return; next_rebuild = param->last_mtime + - param->set.ssl_parameters_regenerate * 3600; + param->set.ssl_parameters_regenerate; if (ioloop_time >= next_rebuild) { ssl_params_rebuild(param); From dovecot at dovecot.org Thu Dec 8 05:13:53 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 08 Dec 2011 05:13:53 +0200 Subject: dovecot-2.1: indexer: Use stricter permissions for indexer-worke... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/55a70ae49cb7 changeset: 13811:55a70ae49cb7 user: Timo Sirainen date: Thu Dec 08 05:05:57 2011 +0200 description: indexer: Use stricter permissions for indexer-worker socket. diffstat: src/indexer/indexer-worker-settings.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r eebee8a4d486 -r 55a70ae49cb7 src/indexer/indexer-worker-settings.c --- a/src/indexer/indexer-worker-settings.c Thu Dec 08 05:03:22 2011 +0200 +++ b/src/indexer/indexer-worker-settings.c Thu Dec 08 05:05:57 2011 +0200 @@ -9,7 +9,7 @@ /* */ static struct file_listener_settings indexer_worker_unix_listeners_array[] = { - { "indexer-worker", 0666, "", "" } + { "indexer-worker", 0600, "$default_internal_user", "" } }; static struct file_listener_settings *indexer_worker_unix_listeners[] = { &indexer_worker_unix_listeners_array[0] From dovecot at dovecot.org Thu Dec 8 05:13:53 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 08 Dec 2011 05:13:53 +0200 Subject: dovecot-2.1: stats: Chroot to empty directory by default. Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/13fb5fa91ed9 changeset: 13813:13fb5fa91ed9 user: Timo Sirainen date: Thu Dec 08 05:13:44 2011 +0200 description: stats: Chroot to empty directory by default. diffstat: src/stats/stats-settings.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r ed9f4e03c2f9 -r 13fb5fa91ed9 src/stats/stats-settings.c --- a/src/stats/stats-settings.c Thu Dec 08 05:12:12 2011 +0200 +++ b/src/stats/stats-settings.c Thu Dec 08 05:13:44 2011 +0200 @@ -37,7 +37,7 @@ .group = "", .privileged_group = "", .extra_groups = "", - .chroot = "", + .chroot = "empty", .drop_priv_before_exec = FALSE, From dovecot at dovecot.org Thu Dec 8 05:17:07 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 08 Dec 2011 05:17:07 +0200 Subject: dovecot-2.1: lmtp: If lmtp_save_to_detail_mailbox=yes and there ... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/8c803201651e changeset: 13814:8c803201651e user: Timo Sirainen date: Thu Dec 08 05:17:01 2011 +0200 description: lmtp: If lmtp_save_to_detail_mailbox=yes and there was no detail, mail was logged as saved to "". diffstat: src/lmtp/commands.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 13fb5fa91ed9 -r 8c803201651e src/lmtp/commands.c --- a/src/lmtp/commands.c Thu Dec 08 05:13:44 2011 +0200 +++ b/src/lmtp/commands.c Thu Dec 08 05:17:01 2011 +0200 @@ -519,7 +519,7 @@ if (dctx.dest_addr == NULL) dctx.dest_addr = rcpt->address; dctx.final_dest_addr = rcpt->address; - if (rcpt->detail == '\0' || + if (*rcpt->detail == '\0' || !client->lmtp_set->lmtp_save_to_detail_mailbox) dctx.dest_mailbox_name = "INBOX"; else { From dovecot at dovecot.org Thu Dec 8 05:55:33 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 08 Dec 2011 05:55:33 +0200 Subject: dovecot-2.1: log: Removed slightly confusing code. Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/279a48aa9dc6 changeset: 13815:279a48aa9dc6 user: Timo Sirainen date: Thu Dec 08 05:24:48 2011 +0200 description: log: Removed slightly confusing code. A log client always receives a BYE, so don't free it earlier. diffstat: src/log/log-connection.c | 2 -- 1 files changed, 0 insertions(+), 2 deletions(-) diffs (12 lines): diff -r 8c803201651e -r 279a48aa9dc6 src/log/log-connection.c --- a/src/log/log-connection.c Thu Dec 08 05:17:01 2011 +0200 +++ b/src/log/log-connection.c Thu Dec 08 05:24:48 2011 +0200 @@ -115,8 +115,6 @@ message. */ if (client == NULL || !client->fatal_logged) i_error("%s", line + 14); - else - log_client_free(log, client, pid); } else { i_error("Received unknown command from master: %s", line); } From dovecot at dovecot.org Thu Dec 8 05:55:33 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 08 Dec 2011 05:55:33 +0200 Subject: dovecot-2.1: Added a new "FATAL" log command, which master uses ... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/e534d2bfda7f changeset: 13816:e534d2bfda7f user: Timo Sirainen date: Thu Dec 08 05:53:55 2011 +0200 description: Added a new "FATAL" log command, which master uses to log all abnormal process exits. The log process adds the process's log prefix or IP address to the message if available. diffstat: src/log/log-connection.c | 37 ++++++++++++++++++++++++++++++++++--- src/master/service-process.c | 7 ++++--- 2 files changed, 38 insertions(+), 6 deletions(-) diffs (89 lines): diff -r 279a48aa9dc6 -r e534d2bfda7f src/log/log-connection.c --- a/src/log/log-connection.c Thu Dec 08 05:24:48 2011 +0200 +++ b/src/log/log-connection.c Thu Dec 08 05:53:55 2011 +0200 @@ -76,7 +76,34 @@ } } -static void log_parse_master_line(const char *line) +static void +client_log_fatal(struct log_connection *log, struct log_client *client, + const char *line, const struct tm *tm) +{ + struct failure_context failure_ctx; + const char *prefix = log->default_prefix; + + memset(&failure_ctx, 0, sizeof(failure_ctx)); + failure_ctx.type = LOG_TYPE_FATAL; + failure_ctx.timestamp = tm; + + if (client != NULL) { + if (client->prefix != NULL) + prefix = client->prefix; + else if (client->ip.family != 0) { + line = t_strdup_printf("%s [last ip=%s]", + line, net_ip2addr(&client->ip)); + } + } + prefix = client != NULL && client->prefix != NULL ? + client->prefix : log->default_prefix; + i_set_failure_prefix(prefix); + i_log_type(&failure_ctx, "master: %s", line); + i_set_failure_prefix("log: "); +} + +static void +log_parse_master_line(const char *line, const struct tm *tm) { struct log_connection *const *logs, *log; struct log_client *client; @@ -110,11 +137,13 @@ return; } log_client_free(log, client, pid); + } else if (strncmp(line, "FATAL ", 6) == 0) { + client_log_fatal(log, client, line + 6, tm); } else if (strncmp(line, "DEFAULT-FATAL ", 14) == 0) { /* If the client has logged a fatal/panic, don't log this message. */ if (client == NULL || !client->fatal_logged) - i_error("%s", line + 14); + client_log_fatal(log, client, line + 14, tm); } else { i_error("Received unknown command from master: %s", line); } @@ -129,7 +158,9 @@ const char *prefix; if (log->master) { - log_parse_master_line(line); + T_BEGIN { + log_parse_master_line(line, tm); + } T_END; return; } diff -r 279a48aa9dc6 -r e534d2bfda7f src/master/service-process.c --- a/src/master/service-process.c Thu Dec 08 05:24:48 2011 +0200 +++ b/src/master/service-process.c Thu Dec 08 05:53:55 2011 +0200 @@ -479,16 +479,17 @@ { const char *data; - if (!default_fatal || process->service->log_fd[1] == -1) { + if (process->service->log_fd[1] == -1) { i_error("%s", str); return; } /* log it via the log process in charge of handling this process's logging */ - data = t_strdup_printf("%d %s DEFAULT-FATAL %s\n", + data = t_strdup_printf("%d %s %s %s\n", process->service->log_process_internal_fd, - dec2str(process->pid), str); + dec2str(process->pid), + default_fatal ? "DEFAULT-FATAL" : "FATAL", str); if (write(process->service->list->master_log_fd[1], data, strlen(data)) < 0) { i_error("write(log process) failed: %m"); From dovecot at dovecot.org Thu Dec 8 05:55:33 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 08 Dec 2011 05:55:33 +0200 Subject: dovecot-2.1: Added i_set_failure_send_prefix() and renamed i_set... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/618d3937f511 changeset: 13817:618d3937f511 user: Timo Sirainen date: Thu Dec 08 05:54:23 2011 +0200 description: Added i_set_failure_send_prefix() and renamed i_set_failure_ip() to _send_ip(). diffstat: src/lib/failures.c | 7 ++++++- src/lib/failures.h | 7 ++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diffs (38 lines): diff -r e534d2bfda7f -r 618d3937f511 src/lib/failures.c --- a/src/lib/failures.c Thu Dec 08 05:53:55 2011 +0200 +++ b/src/lib/failures.c Thu Dec 08 05:54:23 2011 +0200 @@ -694,11 +694,16 @@ log_stamp_format = i_strdup(fmt); } -void i_set_failure_ip(const struct ip_addr *ip) +void i_set_failure_send_ip(const struct ip_addr *ip) { i_failure_send_option("ip", net_ip2addr(ip)); } +void i_set_failure_send_prefix(const char *prefix) +{ + i_failure_send_option("prefix", prefix); +} + void i_set_failure_exit_callback(void (*callback)(int *status)) { failure_exit_callback = callback; diff -r e534d2bfda7f -r 618d3937f511 src/lib/failures.h --- a/src/lib/failures.h Thu Dec 08 05:53:55 2011 +0200 +++ b/src/lib/failures.h Thu Dec 08 05:54:23 2011 +0200 @@ -114,9 +114,10 @@ /* Prefix failures with a timestamp. fmt is in strftime() format. */ void i_set_failure_timestamp_format(const char *fmt); /* When logging with internal error protocol, update the process's current - IP address. This is mainly used by the master process to log some IP - address if the process crash. */ -void i_set_failure_ip(const struct ip_addr *ip); + IP address / log prefix by sending it to log process. This is mainly used to + improve the error message if the process crashes. */ +void i_set_failure_send_ip(const struct ip_addr *ip); +void i_set_failure_send_prefix(const char *prefix); /* Call the callback before exit()ing. The callback may update the status. */ void i_set_failure_exit_callback(void (*callback)(int *status)); From dovecot at dovecot.org Thu Dec 8 05:55:33 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 08 Dec 2011 05:55:33 +0200 Subject: dovecot-2.1: lib-storage: If client_limit=1, send user's log pre... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/45bc88eba07a changeset: 13818:45bc88eba07a user: Timo Sirainen date: Thu Dec 08 05:54:54 2011 +0200 description: lib-storage: If client_limit=1, send user's log prefix to log process. diffstat: src/lib-storage/mail-storage-service.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diffs (12 lines): diff -r 618d3937f511 -r 45bc88eba07a src/lib-storage/mail-storage-service.c --- a/src/lib-storage/mail-storage-service.c Thu Dec 08 05:54:23 2011 +0200 +++ b/src/lib-storage/mail-storage-service.c Thu Dec 08 05:54:54 2011 +0200 @@ -606,6 +606,8 @@ master_service_init_log(ctx->service, user->log_prefix); + if (master_service_get_client_limit(master_service) == 1) + i_set_failure_send_prefix(user->log_prefix); user->ioloop_ctx = io_loop_context_new(current_ioloop); io_loop_context_add_callbacks(user->ioloop_ctx, mail_storage_service_io_activate, From dovecot at dovecot.org Thu Dec 8 05:55:33 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 08 Dec 2011 05:55:33 +0200 Subject: dovecot-2.1: login: Send the last connected client's IP address ... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/d9ad41825a34 changeset: 13819:d9ad41825a34 user: Timo Sirainen date: Thu Dec 08 05:55:19 2011 +0200 description: login: Send the last connected client's IP address to log process. diffstat: src/login-common/main.c | 6 ++++++ 1 files changed, 6 insertions(+), 0 deletions(-) diffs (16 lines): diff -r 45bc88eba07a -r d9ad41825a34 src/login-common/main.c --- a/src/login-common/main.c Thu Dec 08 05:54:54 2011 +0200 +++ b/src/login-common/main.c Thu Dec 08 05:55:19 2011 +0200 @@ -218,6 +218,12 @@ struct login_access_lookup *lookup; master_service_client_connection_accept(conn); + if (conn->remote_ip.family != 0) { + /* log the connection's IP address in case we crash. it's of + course possible that another earlier client causes the + crash, but this is better than nothing. */ + i_set_failure_send_ip(&conn->remote_ip); + } /* make sure we're connected (or attempting to connect) to auth */ auth_client_connect(auth_client); From dovecot at dovecot.org Thu Dec 8 06:11:20 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 08 Dec 2011 06:11:20 +0200 Subject: dovecot-2.1: lib-storage: Fixed assert-crash in user deinit with... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/3b70254e0596 changeset: 13820:3b70254e0596 user: Timo Sirainen date: Thu Dec 08 06:11:03 2011 +0200 description: lib-storage: Fixed assert-crash in user deinit with some installations. diffstat: src/lib-storage/mail-user.c | 13 ++++++++++--- 1 files changed, 10 insertions(+), 3 deletions(-) diffs (30 lines): diff -r d9ad41825a34 -r 3b70254e0596 src/lib-storage/mail-user.c --- a/src/lib-storage/mail-user.c Thu Dec 08 05:55:19 2011 +0200 +++ b/src/lib-storage/mail-user.c Thu Dec 08 06:11:03 2011 +0200 @@ -26,7 +26,6 @@ static void mail_user_deinit_base(struct mail_user *user) { mail_namespaces_deinit(&user->namespaces); - pool_unref(&user->pool); } struct mail_user *mail_user_alloc(const char *username, @@ -137,8 +136,16 @@ i_assert(user->refcount > 0); *_user = NULL; - if (--user->refcount == 0) - user->v.deinit(user); + if (user->refcount > 1) { + user->refcount--; + return; + } + + /* call deinit() with refcount=1, otherwise we may assert-crash in + mail_user_ref() that is called by some deinit() handler. */ + user->v.deinit(user); + i_assert(user->refcount == 1); + pool_unref(&user->pool); } struct mail_user *mail_user_find(struct mail_user *user, const char *name) From dovecot at dovecot.org Thu Dec 8 07:02:12 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 08 Dec 2011 07:02:12 +0200 Subject: dovecot-2.1: lib-sql: If mysql/pgsql commit fails due to server ... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/782f09d13ece changeset: 13821:782f09d13ece user: Timo Sirainen date: Thu Dec 08 07:02:03 2011 +0200 description: lib-sql: If mysql/pgsql commit fails due to server disconnection, reconnect and retry. diffstat: src/lib-sql/driver-mysql.c | 47 ++++++++++++++++++++++++++++++++++----------- src/lib-sql/driver-pgsql.c | 41 +++++++++++++++++++++++++++++---------- 2 files changed, 65 insertions(+), 23 deletions(-) diffs (133 lines): diff -r 3b70254e0596 -r 782f09d13ece src/lib-sql/driver-mysql.c --- a/src/lib-sql/driver-mysql.c Thu Dec 08 06:11:03 2011 +0200 +++ b/src/lib-sql/driver-mysql.c Thu Dec 08 07:02:03 2011 +0200 @@ -506,31 +506,54 @@ return ret; } +static int driver_mysql_try_commit_s(struct mysql_transaction_context *ctx) +{ + struct sql_transaction_context *_ctx = &ctx->ctx; + + /* try to use a transaction in any case, + even if it's not actually functional. */ + if (transaction_send_query(ctx, "BEGIN", NULL) < 0) { + if (_ctx->db->state != SQL_DB_STATE_DISCONNECTED) + return -1; + /* we got disconnected, retry */ + return 0; + } + while (_ctx->head != NULL) { + if (transaction_send_query(ctx, _ctx->head->query, + _ctx->head->affected_rows) < 0) + return -1; + _ctx->head = _ctx->head->next; + } + if (transaction_send_query(ctx, "COMMIT", NULL) < 0) + return -1; + return 1; +} + static int driver_mysql_transaction_commit_s(struct sql_transaction_context *_ctx, const char **error_r) { struct mysql_transaction_context *ctx = (struct mysql_transaction_context *)_ctx; - int ret = 0; + struct mysql_db *db = (struct mysql_db *)_ctx->db; + int ret = 1; *error_r = NULL; if (_ctx->head != NULL) { - /* try to use a transaction in any case, - even if it doesn't work. */ - (void)transaction_send_query(ctx, "BEGIN", NULL); - while (_ctx->head != NULL) { - if (transaction_send_query(ctx, _ctx->head->query, - _ctx->head->affected_rows) < 0) - break; - _ctx->head = _ctx->head->next; + ret = driver_mysql_try_commit_s(ctx); + *error_r = t_strdup(ctx->error); + if (ret == 0) { + i_info("%s: Disconnected from database, " + "retrying commit", db->dbname); + if (sql_connect(_ctx->db) >= 0) { + ctx->failed = FALSE; + ret = driver_mysql_try_commit_s(ctx); + } } - ret = transaction_send_query(ctx, "COMMIT", NULL); - *error_r = ctx->error; } sql_transaction_rollback(&_ctx); - return ret; + return ret <= 0 ? -1 : 0; } static void diff -r 3b70254e0596 -r 782f09d13ece src/lib-sql/driver-pgsql.c --- a/src/lib-sql/driver-pgsql.c Thu Dec 08 06:11:03 2011 +0200 +++ b/src/lib-sql/driver-pgsql.c Thu Dec 08 07:02:03 2011 +0200 @@ -956,22 +956,16 @@ "ROLLBACK" : "COMMIT"); } -static int -driver_pgsql_transaction_commit_s(struct sql_transaction_context *_ctx, - const char **error_r) +static void +driver_pgsql_try_commit_s(struct pgsql_transaction_context *ctx, + const char **error_r) { - struct pgsql_transaction_context *ctx = - (struct pgsql_transaction_context *)_ctx; + struct sql_transaction_context *_ctx = &ctx->ctx; struct pgsql_db *db = (struct pgsql_db *)_ctx->db; struct sql_transaction_query *single_query = NULL; struct sql_result *result; - *error_r = NULL; - - if (ctx->failed || _ctx->head == NULL) { - /* nothing to be done */ - result = NULL; - } else if (_ctx->head->next == NULL) { + if (_ctx->head->next == NULL) { /* just a single query, send it */ single_query = _ctx->head; result = sql_query_s(_ctx->db, single_query->query); @@ -999,6 +993,31 @@ } if (result != NULL) sql_result_unref(result); +} + +static int +driver_pgsql_transaction_commit_s(struct sql_transaction_context *_ctx, + const char **error_r) +{ + struct pgsql_transaction_context *ctx = + (struct pgsql_transaction_context *)_ctx; + struct pgsql_db *db = (struct pgsql_db *)_ctx->db; + + *error_r = NULL; + + if (_ctx->head != NULL) { + driver_pgsql_try_commit_s(ctx, error_r); + if (_ctx->db->state == SQL_DB_STATE_DISCONNECTED) { + *error_r = t_strdup(*error_r); + i_info("%s: Disconnected from database, " + "retrying commit", pgsql_prefix(db)); + if (sql_connect(_ctx->db) >= 0) { + ctx->failed = FALSE; + *error_r = NULL; + driver_pgsql_try_commit_s(ctx, error_r); + } + } + } i_assert(ctx->refcount == 1); driver_pgsql_transaction_unref(ctx); From dovecot at dovecot.org Thu Dec 8 07:23:35 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 08 Dec 2011 07:23:35 +0200 Subject: dovecot-2.1: fts-lucene: Fixed Makefile.am Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/9cf6bb5fe98d changeset: 13822:9cf6bb5fe98d user: Timo Sirainen date: Thu Dec 08 07:23:25 2011 +0200 description: fts-lucene: Fixed Makefile.am diffstat: src/plugins/fts-lucene/Makefile.am | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 782f09d13ece -r 9cf6bb5fe98d src/plugins/fts-lucene/Makefile.am --- a/src/plugins/fts-lucene/Makefile.am Thu Dec 08 07:02:03 2011 +0200 +++ b/src/plugins/fts-lucene/Makefile.am Thu Dec 08 07:23:25 2011 +0200 @@ -34,7 +34,7 @@ noinst_HEADERS = \ fts-lucene-plugin.h \ - lucene-wrapper.h + lucene-wrapper.h \ SnowballAnalyzer.h \ SnowballFilter.h From dovecot at dovecot.org Thu Dec 8 07:36:49 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 08 Dec 2011 07:36:49 +0200 Subject: dovecot-2.1: lib-storage: Fixed assert-crash when search query c... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/338c8d9abba5 changeset: 13823:338c8d9abba5 user: Timo Sirainen date: Thu Dec 08 07:36:39 2011 +0200 description: lib-storage: Fixed assert-crash when search query contained (). diffstat: src/lib-storage/mail-search-build.c | 6 +++++- 1 files changed, 5 insertions(+), 1 deletions(-) diffs (16 lines): diff -r 9cf6bb5fe98d -r 338c8d9abba5 src/lib-storage/mail-search-build.c --- a/src/lib-storage/mail-search-build.c Thu Dec 08 07:23:25 2011 +0200 +++ b/src/lib-storage/mail-search-build.c Thu Dec 08 07:36:39 2011 +0200 @@ -58,7 +58,11 @@ if (strcmp(key, MAIL_SEARCH_PARSER_KEY_LIST) == 0) { if (mail_search_build_list(ctx, &sarg) < 0) return -1; - i_assert(sarg->value.subargs != NULL); + if (sarg->value.subargs == NULL) { + ctx->_error = "No search parameters inside list"; + return -1; + } + ctx->parent = old_parent; *arg_r = sarg; return 1; From dovecot at dovecot.org Thu Dec 8 07:37:01 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 08 Dec 2011 07:37:01 +0200 Subject: dovecot-2.0: lib-storage: Fixed assert-crash when search query c... Message-ID: details: http://hg.dovecot.org/dovecot-2.0/rev/ba68f9be07c4 changeset: 12994:ba68f9be07c4 user: Timo Sirainen date: Thu Dec 08 07:36:39 2011 +0200 description: lib-storage: Fixed assert-crash when search query contained (). diffstat: src/lib-storage/mail-search-build.c | 6 +++++- 1 files changed, 5 insertions(+), 1 deletions(-) diffs (16 lines): diff -r 42a7ba0adafe -r ba68f9be07c4 src/lib-storage/mail-search-build.c --- a/src/lib-storage/mail-search-build.c Fri Dec 02 23:45:55 2011 +0200 +++ b/src/lib-storage/mail-search-build.c Thu Dec 08 07:36:39 2011 +0200 @@ -56,7 +56,11 @@ if (strcmp(key, MAIL_SEARCH_PARSER_KEY_LIST) == 0) { if (mail_search_build_list(ctx, &sarg) < 0) return -1; - i_assert(sarg->value.subargs != NULL); + if (sarg->value.subargs == NULL) { + ctx->_error = "No search parameters inside list"; + return -1; + } + ctx->parent = old_parent; *arg_r = sarg; return 1; From dovecot at dovecot.org Thu Dec 8 07:51:39 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 08 Dec 2011 07:51:39 +0200 Subject: dovecot-2.1: lib-storage: Removed unnecessarily duplicated code. Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/ad58a2d5a290 changeset: 13824:ad58a2d5a290 user: Timo Sirainen date: Thu Dec 08 07:51:28 2011 +0200 description: lib-storage: Removed unnecessarily duplicated code. diffstat: src/lib-storage/index/index-transaction.c | 3 --- 1 files changed, 0 insertions(+), 3 deletions(-) diffs (13 lines): diff -r 338c8d9abba5 -r ad58a2d5a290 src/lib-storage/index/index-transaction.c --- a/src/lib-storage/index/index-transaction.c Thu Dec 08 07:36:39 2011 +0200 +++ b/src/lib-storage/index/index-transaction.c Thu Dec 08 07:51:28 2011 +0200 @@ -88,9 +88,6 @@ if ((flags & MAILBOX_TRANSACTION_FLAG_NO_CACHE_DEC) != 0) mail_cache_view_update_cache_decisions(t->cache_view, FALSE); - if ((flags & MAILBOX_TRANSACTION_FLAG_NO_CACHE_DEC) != 0) - mail_cache_view_update_cache_decisions(t->cache_view, FALSE); - /* set up after mail_cache_get_transaction(), so that we'll still have the cache_trans available in _index_commit() */ t->super = t->itrans->v; From dovecot at dovecot.org Thu Dec 8 09:36:49 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 08 Dec 2011 09:36:49 +0200 Subject: dovecot-2.1: liblib: Added str_to_time() Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/d9acfebce2c9 changeset: 13825:d9acfebce2c9 user: Timo Sirainen date: Thu Dec 08 09:28:54 2011 +0200 description: liblib: Added str_to_time() diffstat: src/lib/strnum.c | 11 +++++++++++ src/lib/strnum.h | 1 + 2 files changed, 12 insertions(+), 0 deletions(-) diffs (32 lines): diff -r ad58a2d5a290 -r d9acfebce2c9 src/lib/strnum.c --- a/src/lib/strnum.c Thu Dec 08 07:51:28 2011 +0200 +++ b/src/lib/strnum.c Thu Dec 08 09:28:54 2011 +0200 @@ -233,6 +233,17 @@ return 0; } +int str_to_time(const char *str, time_t *num_r) +{ + intmax_t l; + + if (str_to_intmax(str, &l) < 0) + return -1; + + *num_r = (time_t)l; + return 0; +} + bool str_uint_equals(const char *str, uintmax_t num) { uintmax_t l; diff -r ad58a2d5a290 -r d9acfebce2c9 src/lib/strnum.h --- a/src/lib/strnum.h Thu Dec 08 07:51:28 2011 +0200 +++ b/src/lib/strnum.h Thu Dec 08 09:28:54 2011 +0200 @@ -24,6 +24,7 @@ int str_to_gid(const char *str, gid_t *num_r) ATTR_WARN_UNUSED_RESULT; int str_to_pid(const char *str, pid_t *num_r) ATTR_WARN_UNUSED_RESULT; int str_to_uoff(const char *str, uoff_t *num_r) ATTR_WARN_UNUSED_RESULT; +int str_to_time(const char *str, time_t *num_r) ATTR_WARN_UNUSED_RESULT; /* Returns TRUE if str is a valid unsigned number that equals to num. */ bool str_uint_equals(const char *str, uintmax_t num); From dovecot at dovecot.org Thu Dec 8 09:36:49 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 08 Dec 2011 09:36:49 +0200 Subject: dovecot-2.1: lib-storage: Code cleanup. Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/ddfe3a0f75e6 changeset: 13826:ddfe3a0f75e6 user: Timo Sirainen date: Thu Dec 08 09:30:14 2011 +0200 description: lib-storage: Code cleanup. diffstat: src/lib-storage/index/index-mail-headers.c | 7 +-- src/lib-storage/index/index-mail.c | 47 +++++++++++++++++++---------- src/lib-storage/mailbox-header.c | 4 +- 3 files changed, 35 insertions(+), 23 deletions(-) diffs (89 lines): diff -r d9acfebce2c9 -r ddfe3a0f75e6 src/lib-storage/index/index-mail-headers.c --- a/src/lib-storage/index/index-mail-headers.c Thu Dec 08 09:28:54 2011 +0200 +++ b/src/lib-storage/index/index-mail-headers.c Thu Dec 08 09:30:14 2011 +0200 @@ -136,11 +136,10 @@ get_header_field_idx(struct mailbox *box, const char *field, enum mail_cache_decision_type decision) { - struct mail_cache_field header_field = { - NULL, 0, MAIL_CACHE_FIELD_HEADER, 0, - MAIL_CACHE_DECISION_NO - }; + struct mail_cache_field header_field; + memset(&header_field, 0, sizeof(header_field)); + header_field.type = MAIL_CACHE_FIELD_HEADER; header_field.decision = decision; T_BEGIN { header_field.name = t_strconcat("hdr.", field, NULL); diff -r d9acfebce2c9 -r ddfe3a0f75e6 src/lib-storage/index/index-mail.c --- a/src/lib-storage/index/index-mail.c Thu Dec 08 09:28:54 2011 +0200 +++ b/src/lib-storage/index/index-mail.c Thu Dec 08 09:30:14 2011 +0200 @@ -20,23 +20,36 @@ #include struct mail_cache_field global_cache_fields[MAIL_INDEX_CACHE_FIELD_COUNT] = { - { "flags", 0, MAIL_CACHE_FIELD_BITMASK, sizeof(uint32_t), 0 }, - { "date.sent", 0, MAIL_CACHE_FIELD_FIXED_SIZE, - sizeof(struct mail_sent_date), 0 }, - { "date.received", 0, MAIL_CACHE_FIELD_FIXED_SIZE, - sizeof(uint32_t), 0 }, - { "date.save", 0, MAIL_CACHE_FIELD_FIXED_SIZE, - sizeof(uint32_t), 0 }, - { "size.virtual", 0, MAIL_CACHE_FIELD_FIXED_SIZE, - sizeof(uoff_t), 0 }, - { "size.physical", 0, MAIL_CACHE_FIELD_FIXED_SIZE, - sizeof(uoff_t), 0 }, - { "imap.body", 0, MAIL_CACHE_FIELD_STRING, 0, 0 }, - { "imap.bodystructure", 0, MAIL_CACHE_FIELD_STRING, 0, 0 }, - { "imap.envelope", 0, MAIL_CACHE_FIELD_STRING, 0, 0 }, - { "pop3.uidl", 0, MAIL_CACHE_FIELD_STRING, 0, 0 }, - { "guid", 0, MAIL_CACHE_FIELD_STRING, 0, 0 }, - { "mime.parts", 0, MAIL_CACHE_FIELD_VARIABLE_SIZE, 0, 0 } + { .name = "flags", + .type = MAIL_CACHE_FIELD_BITMASK, + .field_size = sizeof(uint32_t) }, + { .name = "date.sent", + .type = MAIL_CACHE_FIELD_FIXED_SIZE, + .field_size = sizeof(struct mail_sent_date) }, + { .name = "date.received", + .type = MAIL_CACHE_FIELD_FIXED_SIZE, + .field_size = sizeof(uint32_t) }, + { .name = "date.save", + .type = MAIL_CACHE_FIELD_FIXED_SIZE, + .field_size = sizeof(uint32_t) }, + { .name = "size.virtual", + .type = MAIL_CACHE_FIELD_FIXED_SIZE, + .field_size = sizeof(uoff_t) }, + { .name = "size.physical", + .type = MAIL_CACHE_FIELD_FIXED_SIZE, + .field_size = sizeof(uoff_t) }, + { .name = "imap.body", + .type = MAIL_CACHE_FIELD_STRING }, + { .name = "imap.bodystructure", + .type = MAIL_CACHE_FIELD_STRING }, + { .name = "imap.envelope", + .type = MAIL_CACHE_FIELD_STRING }, + { .name = "pop3.uidl", + .type = MAIL_CACHE_FIELD_STRING }, + { .name = "guid", + .type = MAIL_CACHE_FIELD_STRING }, + { .name = "mime.parts", + .type = MAIL_CACHE_FIELD_VARIABLE_SIZE } }; static int index_mail_parse_body(struct index_mail *mail, diff -r d9acfebce2c9 -r ddfe3a0f75e6 src/lib-storage/mailbox-header.c --- a/src/lib-storage/mailbox-header.c Thu Dec 08 09:28:54 2011 +0200 +++ b/src/lib-storage/mailbox-header.c Thu Dec 08 09:30:14 2011 +0200 @@ -11,8 +11,8 @@ const char *const headers[]) { struct mail_cache_field *fields, header_field = { - NULL, 0, MAIL_CACHE_FIELD_HEADER, 0, - MAIL_CACHE_DECISION_TEMP + .type = MAIL_CACHE_FIELD_HEADER, + .decision = MAIL_CACHE_DECISION_TEMP }; struct mailbox_header_lookup_ctx *ctx; const char *const *name; From dovecot at dovecot.org Thu Dec 8 11:30:48 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 08 Dec 2011 11:30:48 +0200 Subject: dovecot-2.1: imapc: Crashfix on error conditions. Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/94e32772e593 changeset: 13827:94e32772e593 user: Timo Sirainen date: Thu Dec 08 11:30:42 2011 +0200 description: imapc: Crashfix on error conditions. diffstat: src/lib-storage/index/imapc/imapc-storage.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diffs (13 lines): diff -r ddfe3a0f75e6 -r 94e32772e593 src/lib-storage/index/imapc/imapc-storage.c --- a/src/lib-storage/index/imapc/imapc-storage.c Thu Dec 08 09:30:14 2011 +0200 +++ b/src/lib-storage/index/imapc/imapc-storage.c Thu Dec 08 11:30:42 2011 +0200 @@ -684,7 +684,8 @@ struct imapc_mailbox *mbox = context; imapc_noop_callback(reply, mbox->box.storage); - imapc_client_mailbox_idle(mbox->client_box); + if (mbox->client_box != NULL) + imapc_client_mailbox_idle(mbox->client_box); } static void imapc_notify_changes(struct mailbox *box) From dovecot at dovecot.org Thu Dec 8 11:41:10 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 08 Dec 2011 11:41:10 +0200 Subject: dovecot-2.0: lib-storage: Fixed listing INBOX's children with la... Message-ID: details: http://hg.dovecot.org/dovecot-2.0/rev/56618c35292a changeset: 12995:56618c35292a user: Timo Sirainen date: Thu Dec 08 11:41:01 2011 +0200 description: lib-storage: Fixed listing INBOX's children with layout=fs and non-mbox format. diffstat: src/lib-storage/list/mailbox-list-fs-iter.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diffs (13 lines): diff -r ba68f9be07c4 -r 56618c35292a src/lib-storage/list/mailbox-list-fs-iter.c --- a/src/lib-storage/list/mailbox-list-fs-iter.c Thu Dec 08 07:36:39 2011 +0200 +++ b/src/lib-storage/list/mailbox-list-fs-iter.c Thu Dec 08 11:41:01 2011 +0200 @@ -398,7 +398,8 @@ ctx->info.flags &= ~(MAILBOX_NOSELECT | MAILBOX_NONEXISTENT); if (*ns->prefix != '\0' && - (ns->flags & NAMESPACE_FLAG_INBOX_USER) != 0) { + (ns->flags & NAMESPACE_FLAG_INBOX_USER) != 0 && + (ctx->ctx.list->flags & MAILBOX_LIST_FLAG_MAILBOX_FILES) != 0) { /* we're listing INBOX for a namespace with a prefix. if there are children for the INBOX, they're returned under the mailbox prefix, not under the INBOX itself. */ From dovecot at dovecot.org Thu Dec 8 11:41:24 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 08 Dec 2011 11:41:24 +0200 Subject: dovecot-2.1: lib-storage: Fixed listing INBOX's children with la... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/9336f4968beb changeset: 13828:9336f4968beb user: Timo Sirainen date: Thu Dec 08 11:41:01 2011 +0200 description: lib-storage: Fixed listing INBOX's children with layout=fs and non-mbox format. diffstat: src/lib-storage/list/mailbox-list-fs-iter.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diffs (13 lines): diff -r 94e32772e593 -r 9336f4968beb src/lib-storage/list/mailbox-list-fs-iter.c --- a/src/lib-storage/list/mailbox-list-fs-iter.c Thu Dec 08 11:30:42 2011 +0200 +++ b/src/lib-storage/list/mailbox-list-fs-iter.c Thu Dec 08 11:41:01 2011 +0200 @@ -349,7 +349,8 @@ ctx->info.flags &= ~(MAILBOX_NOSELECT | MAILBOX_NONEXISTENT); if (*ns->prefix != '\0' && - (ns->flags & NAMESPACE_FLAG_INBOX_USER) != 0) { + (ns->flags & NAMESPACE_FLAG_INBOX_USER) != 0 && + (ctx->ctx.list->flags & MAILBOX_LIST_FLAG_MAILBOX_FILES) != 0) { /* we're listing INBOX for a namespace with a prefix. if there are children for the INBOX, they're returned under the mailbox prefix, not under the INBOX itself. */ From dovecot at dovecot.org Thu Dec 8 11:45:14 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 08 Dec 2011 11:45:14 +0200 Subject: dovecot-2.0: lib-storage: Reverted the last INBOX children listi... Message-ID: details: http://hg.dovecot.org/dovecot-2.0/rev/13378136ba3e changeset: 12996:13378136ba3e user: Timo Sirainen date: Thu Dec 08 11:45:04 2011 +0200 description: lib-storage: Reverted the last INBOX children listing change after all. diffstat: src/lib-storage/list/mailbox-list-fs-iter.c | 3 +-- 1 files changed, 1 insertions(+), 2 deletions(-) diffs (13 lines): diff -r 56618c35292a -r 13378136ba3e src/lib-storage/list/mailbox-list-fs-iter.c --- a/src/lib-storage/list/mailbox-list-fs-iter.c Thu Dec 08 11:41:01 2011 +0200 +++ b/src/lib-storage/list/mailbox-list-fs-iter.c Thu Dec 08 11:45:04 2011 +0200 @@ -398,8 +398,7 @@ ctx->info.flags &= ~(MAILBOX_NOSELECT | MAILBOX_NONEXISTENT); if (*ns->prefix != '\0' && - (ns->flags & NAMESPACE_FLAG_INBOX_USER) != 0 && - (ctx->ctx.list->flags & MAILBOX_LIST_FLAG_MAILBOX_FILES) != 0) { + (ns->flags & NAMESPACE_FLAG_INBOX_USER) != 0) { /* we're listing INBOX for a namespace with a prefix. if there are children for the INBOX, they're returned under the mailbox prefix, not under the INBOX itself. */ From dovecot at dovecot.org Thu Dec 8 11:45:29 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 08 Dec 2011 11:45:29 +0200 Subject: dovecot-2.1: lib-storage: Reverted the last INBOX children listi... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/b5056baa6193 changeset: 13829:b5056baa6193 user: Timo Sirainen date: Thu Dec 08 11:45:04 2011 +0200 description: lib-storage: Reverted the last INBOX children listing change after all. diffstat: src/lib-storage/list/mailbox-list-fs-iter.c | 3 +-- 1 files changed, 1 insertions(+), 2 deletions(-) diffs (13 lines): diff -r 9336f4968beb -r b5056baa6193 src/lib-storage/list/mailbox-list-fs-iter.c --- a/src/lib-storage/list/mailbox-list-fs-iter.c Thu Dec 08 11:41:01 2011 +0200 +++ b/src/lib-storage/list/mailbox-list-fs-iter.c Thu Dec 08 11:45:04 2011 +0200 @@ -349,8 +349,7 @@ ctx->info.flags &= ~(MAILBOX_NOSELECT | MAILBOX_NONEXISTENT); if (*ns->prefix != '\0' && - (ns->flags & NAMESPACE_FLAG_INBOX_USER) != 0 && - (ctx->ctx.list->flags & MAILBOX_LIST_FLAG_MAILBOX_FILES) != 0) { + (ns->flags & NAMESPACE_FLAG_INBOX_USER) != 0) { /* we're listing INBOX for a namespace with a prefix. if there are children for the INBOX, they're returned under the mailbox prefix, not under the INBOX itself. */ From dovecot at dovecot.org Thu Dec 8 13:34:54 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 08 Dec 2011 13:34:54 +0200 Subject: dovecot-2.0: lmtp: If lmtp_save_to_detail_mailbox=yes and there ... Message-ID: details: http://hg.dovecot.org/dovecot-2.0/rev/6d188f4e8e6a changeset: 12997:6d188f4e8e6a user: Timo Sirainen date: Thu Dec 08 05:17:01 2011 +0200 description: lmtp: If lmtp_save_to_detail_mailbox=yes and there was no detail, mail was logged as saved to "". diffstat: src/lmtp/commands.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 13378136ba3e -r 6d188f4e8e6a src/lmtp/commands.c --- a/src/lmtp/commands.c Thu Dec 08 11:45:04 2011 +0200 +++ b/src/lmtp/commands.c Thu Dec 08 05:17:01 2011 +0200 @@ -519,7 +519,7 @@ if (dctx.dest_addr == NULL) dctx.dest_addr = rcpt->address; dctx.final_dest_addr = rcpt->address; - if (rcpt->detail == '\0' || + if (*rcpt->detail == '\0' || !client->lmtp_set->lmtp_save_to_detail_mailbox) dctx.dest_mailbox_name = "INBOX"; else { From dovecot at dovecot.org Thu Dec 8 18:57:15 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 08 Dec 2011 18:57:15 +0200 Subject: dovecot-2.1: auth: If verbose_proctitle=yes, show which processe... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/ec3714f01ef2 changeset: 13830:ec3714f01ef2 user: Timo Sirainen date: Thu Dec 08 18:56:48 2011 +0200 description: auth: If verbose_proctitle=yes, show which processes are auth workers. diffstat: src/auth/main.c | 7 ++++++- 1 files changed, 6 insertions(+), 1 deletions(-) diffs (21 lines): diff -r b5056baa6193 -r ec3714f01ef2 src/auth/main.c --- a/src/auth/main.c Thu Dec 08 11:45:04 2011 +0200 +++ b/src/auth/main.c Thu Dec 08 18:56:48 2011 +0200 @@ -57,11 +57,16 @@ void auth_refresh_proctitle(void) { + const char *auth_worker_prefix; + if (!global_auth_settings->verbose_proctitle) return; + auth_worker_prefix = worker ? "worker " : ""; + process_title_set(t_strdup_printf( - "[%u wait, %u passdb, %u userdb]", + "%s[%u wait, %u passdb, %u userdb]", + auth_worker_prefix, auth_request_state_count[AUTH_REQUEST_STATE_NEW] + auth_request_state_count[AUTH_REQUEST_STATE_MECH_CONTINUE] + auth_request_state_count[AUTH_REQUEST_STATE_FINISHED], From dovecot at dovecot.org Thu Dec 8 18:57:32 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 08 Dec 2011 18:57:32 +0200 Subject: dovecot-2.0: auth: If verbose_proctitle=yes, show which processe... Message-ID: details: http://hg.dovecot.org/dovecot-2.0/rev/8ab42b468353 changeset: 12998:8ab42b468353 user: Timo Sirainen date: Thu Dec 08 18:56:48 2011 +0200 description: auth: If verbose_proctitle=yes, show which processes are auth workers. diffstat: src/auth/main.c | 7 ++++++- 1 files changed, 6 insertions(+), 1 deletions(-) diffs (21 lines): diff -r 6d188f4e8e6a -r 8ab42b468353 src/auth/main.c --- a/src/auth/main.c Thu Dec 08 05:17:01 2011 +0200 +++ b/src/auth/main.c Thu Dec 08 18:56:48 2011 +0200 @@ -49,11 +49,16 @@ void auth_refresh_proctitle(void) { + const char *auth_worker_prefix; + if (!global_auth_settings->verbose_proctitle) return; + auth_worker_prefix = worker ? "worker " : ""; + process_title_set(t_strdup_printf( - "[%u wait, %u passdb, %u userdb]", + "%s[%u wait, %u passdb, %u userdb]", + auth_worker_prefix, auth_request_state_count[AUTH_REQUEST_STATE_NEW] + auth_request_state_count[AUTH_REQUEST_STATE_MECH_CONTINUE] + auth_request_state_count[AUTH_REQUEST_STATE_FINISHED], From dovecot at dovecot.org Fri Dec 9 16:26:49 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 09 Dec 2011 16:26:49 +0200 Subject: dovecot-2.1: mdbox: Make sure m.* files aren't overwritten when ... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/31825aab83f6 changeset: 13831:31825aab83f6 user: Timo Sirainen date: Fri Dec 09 16:26:39 2011 +0200 description: mdbox: Make sure m.* files aren't overwritten when storage index isn't found. This mainly helps to avoid situations where m.1 is replaced by mail delivery when index directory has been (wrongly) changed. diffstat: src/lib-storage/index/dbox-multi/mdbox-map-private.h | 2 + src/lib-storage/index/dbox-multi/mdbox-map.c | 66 +++++++++++++++++-- 2 files changed, 61 insertions(+), 7 deletions(-) diffs (138 lines): diff -r ec3714f01ef2 -r 31825aab83f6 src/lib-storage/index/dbox-multi/mdbox-map-private.h --- a/src/lib-storage/index/dbox-multi/mdbox-map-private.h Thu Dec 08 18:56:48 2011 +0200 +++ b/src/lib-storage/index/dbox-multi/mdbox-map-private.h Fri Dec 09 16:26:39 2011 +0200 @@ -23,6 +23,8 @@ mode_t create_mode; gid_t create_gid; const char *create_gid_origin; + + unsigned int verify_existing_file_ids:1; }; struct mdbox_map_append { diff -r ec3714f01ef2 -r 31825aab83f6 src/lib-storage/index/dbox-multi/mdbox-map.c --- a/src/lib-storage/index/dbox-multi/mdbox-map.c Thu Dec 08 18:56:48 2011 +0200 +++ b/src/lib-storage/index/dbox-multi/mdbox-map.c Fri Dec 09 16:26:39 2011 +0200 @@ -108,7 +108,7 @@ struct stat st; if (stat(path, &st) == 0) - return 0; + return 1; if (mailbox_list_mkdir(map->root_list, NULL, path) < 0) { mail_storage_copy_list_error(MAP_STORAGE(map), map->root_list); @@ -119,14 +119,16 @@ static int mdbox_map_mkdir_storage(struct mdbox_map *map) { - if (mdbox_map_mkdir_storage_path(map, map->path) < 0) + int ret; + + if ((ret = mdbox_map_mkdir_storage_path(map, map->path)) < 0) return -1; if (strcmp(map->path, map->index_path) != 0) { if (mdbox_map_mkdir_storage_path(map, map->index_path) < 0) return -1; } - return 0; + return ret; } static void mdbox_map_cleanup(struct mdbox_map *map) @@ -150,7 +152,7 @@ static int mdbox_map_open_internal(struct mdbox_map *map, bool create_missing) { enum mail_index_open_flags open_flags; - int ret; + int ret = 0; if (map->view != NULL) { /* already opened */ @@ -160,11 +162,24 @@ open_flags = MAIL_INDEX_OPEN_FLAG_NEVER_IN_MEMORY | mail_storage_settings_to_index_flags(MAP_STORAGE(map)->set); if (create_missing) { - open_flags |= MAIL_INDEX_OPEN_FLAG_CREATE; - if (mdbox_map_mkdir_storage(map) < 0) + if ((ret = mdbox_map_mkdir_storage(map)) < 0) return -1; + if (ret > 0) { + /* storage/ directory already existed. + the index should exist also. */ + } else { + open_flags |= MAIL_INDEX_OPEN_FLAG_CREATE; + } } ret = mail_index_open(map->index, open_flags); + if (ret == 0 && create_missing) { + /* storage/ already existed, but indexes didn't. we'll need to + take extra steps to make sure we won't overwrite any m.* + files that may already exist. */ + map->verify_existing_file_ids = TRUE; + open_flags |= MAIL_INDEX_OPEN_FLAG_CREATE; + ret = mail_index_open(map->index, open_flags); + } if (ret < 0) { mail_storage_set_internal_error(MAP_STORAGE(map)); mail_index_reset_error(map->index); @@ -1147,13 +1162,39 @@ array_delete(&ctx->appends, count-1, 1); } +static int +mdbox_find_highest_file_id(struct mdbox_map *map, uint32_t *file_id_r) +{ + const unsigned int prefix_len = strlen(MDBOX_MAIL_FILE_PREFIX); + DIR *dir; + struct dirent *d; + unsigned int id, highest_id = 0; + + dir = opendir(map->path); + if (dir == NULL) { + i_error("opendir(%s) failed: %m", map->path); + return -1; + } + while ((d = readdir(dir)) != NULL) { + if (strncmp(d->d_name, MDBOX_MAIL_FILE_PREFIX, prefix_len) == 0 && + str_to_uint(d->d_name + prefix_len, &id) == 0) { + if (highest_id < id) + highest_id = id; + } + } + (void)closedir(dir); + + *file_id_r = highest_id; + return 0; +} + static int mdbox_map_assign_file_ids(struct mdbox_map_append_context *ctx, bool separate_transaction) { struct dbox_file_append_context *const *file_appends; unsigned int i, count; struct mdbox_map_mail_index_header hdr; - uint32_t first_file_id, file_id; + uint32_t first_file_id, file_id, existing_id; /* start the syncing. we'll need it even if there are no file ids to be assigned. */ @@ -1163,6 +1204,17 @@ mdbox_map_get_ext_hdr(ctx->map, ctx->atomic->sync_view, &hdr); file_id = hdr.highest_file_id + 1; + if (ctx->map->verify_existing_file_ids) { + /* storage/ directory had been already created but + without indexes. scan to see if there exists a higher + m.* file id than what is in header, so we won't + accidentally overwrite any existing files. */ + if (mdbox_find_highest_file_id(ctx->map, &existing_id) < 0) + return -1; + if (file_id < existing_id+1) + file_id = existing_id+1; + } + /* assign file_ids for newly created files */ first_file_id = file_id; file_appends = array_get(&ctx->file_appends, &count); From dovecot at dovecot.org Fri Dec 9 17:49:34 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 09 Dec 2011 17:49:34 +0200 Subject: dovecot-2.1: lib-storage: Fixed search when mail prefetching is ... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/5c2ef2374848 changeset: 13832:5c2ef2374848 user: Timo Sirainen date: Fri Dec 09 17:49:13 2011 +0200 description: lib-storage: Fixed search when mail prefetching is enabled. diffstat: src/lib-storage/index/index-search.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diffs (12 lines): diff -r 31825aab83f6 -r 5c2ef2374848 src/lib-storage/index/index-search.c --- a/src/lib-storage/index/index-search.c Fri Dec 09 16:26:39 2011 +0200 +++ b/src/lib-storage/index/index-search.c Fri Dec 09 17:49:13 2011 +0200 @@ -1423,6 +1423,8 @@ SEARCH_NOTIFY_INTERVAL_SECS) index_storage_search_notify(box, ctx); + mail_search_args_reset(_ctx->args->args, FALSE); + while (box->v.search_next_update_seq(_ctx)) { mail_set_seq(mail, _ctx->seq); From dovecot at dovecot.org Fri Dec 9 18:58:04 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 09 Dec 2011 18:58:04 +0200 Subject: dovecot-2.1: var_expand(): Added %{uid} and %{gid} variables. Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/8a63f621bd2e changeset: 13833:8a63f621bd2e user: Timo Sirainen date: Fri Dec 09 18:57:53 2011 +0200 description: var_expand(): Added %{uid} and %{gid} variables. diffstat: src/lib/var-expand.c | 5 +++++ 1 files changed, 5 insertions(+), 0 deletions(-) diffs (22 lines): diff -r 5c2ef2374848 -r 8a63f621bd2e src/lib/var-expand.c --- a/src/lib/var-expand.c Fri Dec 09 17:49:13 2011 +0200 +++ b/src/lib/var-expand.c Fri Dec 09 18:57:53 2011 +0200 @@ -11,6 +11,7 @@ #include "var-expand.h" #include +#include #include #define TABLE_LAST(t) \ @@ -160,6 +161,10 @@ case 3: if (strcmp(key, "pid") == 0) value = my_pid; + else if (strcmp(key, "uid") == 0) + value = dec2str(geteuid()); + else if (strcmp(key, "gid") == 0) + value = dec2str(getegid()); break; case 8: if (strcmp(key, "hostname") == 0) From dovecot at dovecot.org Fri Dec 9 19:00:56 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 09 Dec 2011 19:00:56 +0200 Subject: dovecot-2.0: var_expand(): Added %{uid} and %{gid} variables. Message-ID: details: http://hg.dovecot.org/dovecot-2.0/rev/af6d0858e64b changeset: 12999:af6d0858e64b user: Timo Sirainen date: Fri Dec 09 18:57:53 2011 +0200 description: var_expand(): Added %{uid} and %{gid} variables. diffstat: src/lib/var-expand.c | 5 +++++ 1 files changed, 5 insertions(+), 0 deletions(-) diffs (22 lines): diff -r 8ab42b468353 -r af6d0858e64b src/lib/var-expand.c --- a/src/lib/var-expand.c Thu Dec 08 18:56:48 2011 +0200 +++ b/src/lib/var-expand.c Fri Dec 09 18:57:53 2011 +0200 @@ -11,6 +11,7 @@ #include "var-expand.h" #include +#include #include #define TABLE_LAST(t) \ @@ -160,6 +161,10 @@ case 3: if (strcmp(key, "pid") == 0) value = my_pid; + else if (strcmp(key, "uid") == 0) + value = dec2str(geteuid()); + else if (strcmp(key, "gid") == 0) + value = dec2str(getegid()); break; case 8: if (strcmp(key, "hostname") == 0) From dovecot at dovecot.org Sat Dec 10 07:07:20 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 10 Dec 2011 07:07:20 +0200 Subject: dovecot-2.1: lib-storage: mailbox_list_get_vname() no longer tre... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/5366e59d573f changeset: 13834:5366e59d573f user: Timo Sirainen date: Sat Dec 10 07:03:09 2011 +0200 description: lib-storage: mailbox_list_get_vname() no longer treats INBOX case insensitively. The INBOX vname is case sensitive, the INBOX storage_name isn't, otherwise it's not possible to access /inBox cased mailboxes. diffstat: src/lib-storage/mailbox-list.c | 8 +++++--- 1 files changed, 5 insertions(+), 3 deletions(-) diffs (19 lines): diff -r 8a63f621bd2e -r 5366e59d573f src/lib-storage/mailbox-list.c --- a/src/lib-storage/mailbox-list.c Fri Dec 09 18:57:53 2011 +0200 +++ b/src/lib-storage/mailbox-list.c Sat Dec 10 07:03:09 2011 +0200 @@ -486,10 +486,12 @@ char list_sep, ns_sep, *ret; if ((list->ns->flags & NAMESPACE_FLAG_INBOX_USER) != 0 && - strcasecmp(vname, "INBOX") == 0 && + strcmp(vname, "INBOX") == 0 && list->ns->user == list->ns->owner) { - /* user's INBOX - use as-is */ - return "INBOX"; + /* user's INBOX - use as-is. NOTE: don't do case-insensitive + comparison, otherwise we can't differentiate between INBOX + and /inBox. */ + return vname; } if (*vname == '\0') { /* return namespace prefix without the separator */ From dovecot at dovecot.org Sat Dec 10 07:07:20 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 10 Dec 2011 07:07:20 +0200 Subject: dovecot-2.1: lib-storage: FS layout mailbox list iteration code ... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/ab696ead12cc changeset: 13835:ab696ead12cc user: Timo Sirainen date: Sat Dec 10 07:05:56 2011 +0200 description: lib-storage: FS layout mailbox list iteration code rewrite. This fixes listing non-ASCII mailboxes. Also the new way no longer keeps more than one file descriptor open. diffstat: src/lib-storage/list/mailbox-list-fs-flags.c | 4 +- src/lib-storage/list/mailbox-list-fs-iter.c | 1005 +++++++++++-------------- 2 files changed, 454 insertions(+), 555 deletions(-) diffs (truncated from 1193 to 300 lines): diff -r 5366e59d573f -r ab696ead12cc src/lib-storage/list/mailbox-list-fs-flags.c --- a/src/lib-storage/list/mailbox-list-fs-flags.c Sat Dec 10 07:03:09 2011 +0200 +++ b/src/lib-storage/list/mailbox-list-fs-flags.c Sat Dec 10 07:05:56 2011 +0200 @@ -117,7 +117,7 @@ *flags_r = 0; if (*list->set.maildir_name != '\0') { - /* maildir_name is set: we the code is common for all + /* maildir_name is set: the code is common for all storage types */ return list_is_maildir_mailbox(list, dir, fname, type, flags_r); } @@ -131,7 +131,7 @@ switch (type) { case MAILBOX_LIST_FILE_TYPE_DIR: if ((list->flags & MAILBOX_LIST_FLAG_MAILBOX_FILES) != 0) { - *flags_r |= MAILBOX_NOSELECT | MAILBOX_CHILDREN; + *flags_r |= MAILBOX_NOSELECT; return 1; } break; diff -r 5366e59d573f -r ab696ead12cc src/lib-storage/list/mailbox-list-fs-iter.c --- a/src/lib-storage/list/mailbox-list-fs-iter.c Sat Dec 10 07:03:09 2011 +0200 +++ b/src/lib-storage/list/mailbox-list-fs-iter.c Sat Dec 10 07:05:56 2011 +0200 @@ -14,193 +14,370 @@ struct list_dir_entry { const char *fname; - enum mailbox_list_file_type type; + enum mailbox_info_flags info_flags; }; struct list_dir_context { - struct list_dir_context *prev; + struct list_dir_context *parent; - DIR *dirp; - char *real_path, *virtual_path; + pool_t pool; + const char *storage_name; + /* this directory's info flags. */ + enum mailbox_info_flags info_flags; - const struct list_dir_entry *next_entry; - struct list_dir_entry entry; - char *entry_fname; - struct mailbox_info info; - - unsigned int pattern_pos; - - unsigned int delayed_send:1; + /* all files in this directory */ + ARRAY_DEFINE(entries, struct list_dir_entry); + unsigned int entry_idx; }; struct fs_list_iterate_context { struct mailbox_list_iterate_context ctx; - ARRAY_DEFINE(valid_patterns, const char *); + const char *const *valid_patterns; + /* roots can be either /foo, ~user/bar or baz */ + ARRAY_DEFINE(roots, const char *); + unsigned int root_idx; char sep; - enum mailbox_info_flags inbox_flags; - - const struct mailbox_info *(*next)(struct fs_list_iterate_context *ctx); - pool_t info_pool; struct mailbox_info info; - struct list_dir_context *dir; + /* current directory we're handling */ + struct list_dir_context *dir; - unsigned int inbox_match:1; unsigned int inbox_found:1; - unsigned int inbox_listed:1; }; -static const struct mailbox_info * -fs_list_next(struct fs_list_iterate_context *ctx); +static int +fs_get_existence_info_flag(struct fs_list_iterate_context *ctx, + const char *vname, + enum mailbox_info_flags *info_flags) +{ + struct mailbox *box; + enum mailbox_existence existence; + bool auto_boxes; + int ret; + + auto_boxes = (ctx->ctx.flags & MAILBOX_LIST_ITER_NO_AUTO_BOXES) == 0; + box = mailbox_alloc(ctx->ctx.list, vname, 0); + ret = mailbox_exists(box, auto_boxes, &existence); + mailbox_free(&box); + + if (ret < 0) { + /* this can only be an internal error */ + mailbox_list_set_internal_error(ctx->ctx.list); + return -1; + } + switch (existence) { + case MAILBOX_EXISTENCE_NONE: + *info_flags |= MAILBOX_NONEXISTENT; + break; + case MAILBOX_EXISTENCE_NOSELECT: + *info_flags |= MAILBOX_NOSELECT; + break; + case MAILBOX_EXISTENCE_SELECT: + *info_flags |= MAILBOX_SELECT; + break; + } + return 0; +} static int -pattern_get_path_pos(struct fs_list_iterate_context *ctx, const char *pattern, - const char *path, unsigned int *pos_r) +dir_entry_get(struct fs_list_iterate_context *ctx, const char *dir_path, + struct list_dir_context *dir, const struct dirent *d) { - unsigned int i, j; + const char *storage_name, *vname, *root_dir; + struct list_dir_entry *entry; + enum imap_match_result match; + enum mailbox_info_flags info_flags; + int ret; - if (strncasecmp(path, "INBOX", 5) == 0 && path[5] == ctx->sep) { - /* make sure INBOX prefix is matched case-insensitively */ - char *tmp = t_strdup_noconst(pattern); + /* skip . and .. */ + if (d->d_name[0] == '.' && + (d->d_name[1] == '\0' || + (d->d_name[1] == '.' && d->d_name[2] == '\0'))) + return 0; - if (strncmp(path, "INBOX", 5) != 0) - path = t_strdup_printf("INBOX%c%s", ctx->sep, path + 6); - - for (i = 0; tmp[i] != ctx->sep && tmp[i] != '\0'; i++) - tmp[i] = i_toupper(tmp[i]); - pattern = tmp; + if (strcmp(d->d_name, ctx->ctx.list->set.maildir_name) == 0) { + /* mail storage's internal directory (e.g. dbox-Mails). + this also means that the parent is selectable */ + dir->info_flags &= ~MAILBOX_NOSELECT; + dir->info_flags |= MAILBOX_SELECT; + return 0; + } + if (strcmp(d->d_name, ctx->ctx.list->set.subscription_fname) == 0) { + /* if this is the subscriptions file, skip it */ + root_dir = mailbox_list_get_path(ctx->ctx.list, NULL, + MAILBOX_LIST_PATH_TYPE_DIR); + if (strcmp(root_dir, dir_path) == 0) + return 0; } - for (i = j = 0; path[i] != '\0'; i++) { - if (pattern[j] == '*') + /* check the pattern */ + storage_name = *dir->storage_name == '\0' ? d->d_name : + t_strconcat(dir->storage_name, "/", d->d_name, NULL); + vname = mailbox_list_get_vname(ctx->ctx.list, storage_name); + match = imap_match(ctx->ctx.glob, vname); + + if ((dir->info_flags & (MAILBOX_CHILDREN | MAILBOX_NOCHILDREN | + MAILBOX_NOINFERIORS)) == 0 && + (ctx->ctx.flags & MAILBOX_LIST_ITER_RETURN_CHILDREN) != 0) { + /* we don't know yet if the parent has children. need to figure + out if this file is actually a visible mailbox */ + } else if (match != IMAP_MATCH_YES && + (match & IMAP_MATCH_CHILDREN) == 0) { + /* mailbox doesn't match any patterns, we don't care about it */ + return 0; + } + ret = ctx->ctx.list->v. + get_mailbox_flags(ctx->ctx.list, dir_path, d->d_name, + mailbox_list_get_file_type(d), &info_flags); + if (ret <= 0) + return ret; + if (!MAILBOX_INFO_FLAGS_FINISHED(info_flags)) { + /* mailbox existence isn't known yet. need to figure it out + the hard way. */ + if (fs_get_existence_info_flag(ctx, vname, &info_flags) < 0) return -1; + } + if ((info_flags & MAILBOX_NONEXISTENT) != 0) + return 0; - if (pattern[j] == '%') { - /* skip until we're at the next hierarchy separator */ - if (path[i] == ctx->sep) { - /* assume that pattern matches. we can't be - sure, but it'll be checked later. */ - for (j++; pattern[j] != '\0'; j++) { - if (pattern[j] == '*') - return -1; - if (pattern[j] == ctx->sep) { - j++; - break; - } - } - } - } else { - if (path[i] != pattern[j]) { - /* pattern doesn't match path at all */ - return 0; - } - j++; - } + /* mailbox exists - make sure parent knows it has children */ + dir->info_flags &= ~(MAILBOX_NOCHILDREN | MAILBOX_NOINFERIORS); + dir->info_flags |= MAILBOX_CHILDREN; + + if (match != IMAP_MATCH_YES && (match & IMAP_MATCH_CHILDREN) == 0) { + /* this mailbox didn't actually match any pattern, + we just needed to know the children state */ + return 0; } - *pos_r = j; - return 1; + + /* entry matched a pattern. we're going to return this. */ + entry = array_append_space(&dir->entries); + entry->fname = p_strdup(dir->pool, d->d_name); + entry->info_flags = info_flags; + return 0; } static bool -pattern_has_wildcard_at(struct fs_list_iterate_context *ctx, - const char *pattern, const char *path) +fs_list_get_storage_path(struct fs_list_iterate_context *ctx, + const char *storage_name, const char **path_r) { - unsigned int pos; - int ret; + const char *root, *path = storage_name; - if ((ret = pattern_get_path_pos(ctx, pattern, path, &pos)) < 0) - return TRUE; - if (ret == 0) - return FALSE; - - if (pattern[pos] == '\0') - return TRUE; - - for (; pattern[pos] != '\0' && pattern[pos] != ctx->sep; pos++) { - if (pattern[pos] == '%' || pattern[pos] == '*') - return TRUE; + if (*path == '~') { + if (!mailbox_list_try_get_absolute_path(ctx->ctx.list, &path)) { + /* couldn't expand ~user/ */ + return FALSE; + } + /* NOTE: the path may have been translated to a storage_name + instead of path */ } - return FALSE; + if (*path != '/') { + /* non-absolute path. add the mailbox root dir as prefix. */ + root = mailbox_list_get_path(ctx->ctx.list, NULL, + MAILBOX_LIST_PATH_TYPE_MAILBOX); + path = t_strconcat(root, "/", path, NULL); + } + *path_r = path; + return TRUE; } -static int list_opendir(struct fs_list_iterate_context *ctx, - const char *path, const char *list_path, DIR **dirp) +static int +fs_list_dir_read(struct fs_list_iterate_context *ctx, + struct list_dir_context *dir) { - const char *const *patterns; - unsigned int i; + DIR *fsdir; + struct dirent *d; + struct list_dir_entry *entry; + const char *path, *vname; + int ret = 0; - /* if no patterns have wildcards at this point of the path, we don't - have to readdir() the files. instead we can just go through the - mailboxes listed in patterns. */ - T_BEGIN { - patterns = array_idx(&ctx->valid_patterns, 0); - for (i = 0; patterns[i] != NULL; i++) { - if (pattern_has_wildcard_at(ctx, patterns[i], - list_path)) - break; + if (!fs_list_get_storage_path(ctx, dir->storage_name, &path)) + return 0; + + fsdir = opendir(path); + if (fsdir == NULL) { From dovecot at dovecot.org Sat Dec 10 07:28:42 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 10 Dec 2011 07:28:42 +0200 Subject: dovecot-2.1: config: Don't warn that ssl_parameters_regenerate=0... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/e28736bc8e09 changeset: 13836:e28736bc8e09 user: Timo Sirainen date: Sat Dec 10 07:28:22 2011 +0200 description: config: Don't warn that ssl_parameters_regenerate=0 should have "hours" suffix. diffstat: src/config/old-set-parser.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r ab696ead12cc -r e28736bc8e09 src/config/old-set-parser.c --- a/src/config/old-set-parser.c Sat Dec 10 07:05:56 2011 +0200 +++ b/src/config/old-set-parser.c Sat Dec 10 07:28:22 2011 +0200 @@ -141,7 +141,7 @@ return TRUE; } if (strcmp(key, "ssl_parameters_regenerate") == 0 && - str_is_numeric(value, '\0')) { + str_is_numeric(value, '\0') && strcmp(value, "0") != 0) { obsolete(ctx, "%s should have 'hours' suffix", key); config_apply_line(ctx, "", t_strconcat(key, "=", value, "h", NULL), NULL); return TRUE; From dovecot at dovecot.org Sat Dec 10 07:57:41 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 10 Dec 2011 07:57:41 +0200 Subject: dovecot-2.0: zlib: Avoid assert-crashing if parent ostream's wri... Message-ID: details: http://hg.dovecot.org/dovecot-2.0/rev/75daa638281b changeset: 13000:75daa638281b user: Timo Sirainen date: Sat Dec 10 07:57:16 2011 +0200 description: zlib: Avoid assert-crashing if parent ostream's write had failed earlier. diffstat: src/plugins/zlib/ostream-bzlib.c | 7 ++++++- src/plugins/zlib/ostream-zlib.c | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diffs (34 lines): diff -r af6d0858e64b -r 75daa638281b src/plugins/zlib/ostream-bzlib.c --- a/src/plugins/zlib/ostream-bzlib.c Fri Dec 09 18:57:53 2011 +0200 +++ b/src/plugins/zlib/ostream-bzlib.c Sat Dec 10 07:57:16 2011 +0200 @@ -82,7 +82,12 @@ bool done = FALSE; int ret; - i_assert(zs->avail_in == 0); + if (zs->avail_in != 0) { + i_assert(zstream->ostream.ostream.last_failed_errno != 0); + zstream->ostream.ostream.stream_errno = + zstream->ostream.ostream.last_failed_errno; + return -1; + } if (zstream->flushed) return 0; diff -r af6d0858e64b -r 75daa638281b src/plugins/zlib/ostream-zlib.c --- a/src/plugins/zlib/ostream-zlib.c Fri Dec 09 18:57:53 2011 +0200 +++ b/src/plugins/zlib/ostream-zlib.c Sat Dec 10 07:57:16 2011 +0200 @@ -141,7 +141,12 @@ bool done = FALSE; int ret; - i_assert(zs->avail_in == 0); + if (zs->avail_in != 0) { + i_assert(zstream->ostream.ostream.last_failed_errno != 0); + zstream->ostream.ostream.stream_errno = + zstream->ostream.ostream.last_failed_errno; + return -1; + } if (zstream->flushed) return 0; From dovecot at dovecot.org Sat Dec 10 07:57:43 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 10 Dec 2011 07:57:43 +0200 Subject: dovecot-2.1: zlib: Avoid assert-crashing if parent ostream's wri... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/aefc17d5b99e changeset: 13837:aefc17d5b99e user: Timo Sirainen date: Sat Dec 10 07:57:16 2011 +0200 description: zlib: Avoid assert-crashing if parent ostream's write had failed earlier. diffstat: src/plugins/zlib/ostream-bzlib.c | 7 ++++++- src/plugins/zlib/ostream-zlib.c | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diffs (34 lines): diff -r e28736bc8e09 -r aefc17d5b99e src/plugins/zlib/ostream-bzlib.c --- a/src/plugins/zlib/ostream-bzlib.c Sat Dec 10 07:28:22 2011 +0200 +++ b/src/plugins/zlib/ostream-bzlib.c Sat Dec 10 07:57:16 2011 +0200 @@ -69,7 +69,12 @@ bool done = FALSE; int ret; - i_assert(zs->avail_in == 0); + if (zs->avail_in != 0) { + i_assert(zstream->ostream.ostream.last_failed_errno != 0); + zstream->ostream.ostream.stream_errno = + zstream->ostream.ostream.last_failed_errno; + return -1; + } if (zstream->flushed) return 0; diff -r e28736bc8e09 -r aefc17d5b99e src/plugins/zlib/ostream-zlib.c --- a/src/plugins/zlib/ostream-zlib.c Sat Dec 10 07:28:22 2011 +0200 +++ b/src/plugins/zlib/ostream-zlib.c Sat Dec 10 07:57:16 2011 +0200 @@ -129,7 +129,12 @@ bool done = FALSE; int ret; - i_assert(zs->avail_in == 0); + if (zs->avail_in != 0) { + i_assert(zstream->ostream.ostream.last_failed_errno != 0); + zstream->ostream.ostream.stream_errno = + zstream->ostream.ostream.last_failed_errno; + return -1; + } if (zstream->flushed) return 0; From dovecot at dovecot.org Sat Dec 10 08:01:09 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 10 Dec 2011 08:01:09 +0200 Subject: dovecot-2.1: maildir: If saving fails, don't bother trying to fl... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/97af1836ea72 changeset: 13838:97af1836ea72 user: Timo Sirainen date: Sat Dec 10 08:01:02 2011 +0200 description: maildir: If saving fails, don't bother trying to flush the file's ostream. diffstat: src/lib-storage/index/maildir/maildir-save.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r aefc17d5b99e -r 97af1836ea72 src/lib-storage/index/maildir/maildir-save.c --- a/src/lib-storage/index/maildir/maildir-save.c Sat Dec 10 07:57:16 2011 +0200 +++ b/src/lib-storage/index/maildir/maildir-save.c Sat Dec 10 08:01:02 2011 +0200 @@ -524,7 +524,7 @@ } path = t_strconcat(ctx->tmpdir, "/", ctx->file_last->tmp_name, NULL); - if (o_stream_flush(_ctx->output) < 0) { + if (!ctx->failed && o_stream_flush(_ctx->output) < 0) { if (!mail_storage_set_error_from_errno(storage)) { mail_storage_set_critical(storage, "o_stream_flush(%s) failed: %m", path); From dovecot at dovecot.org Sat Dec 10 08:16:16 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 10 Dec 2011 08:16:16 +0200 Subject: dovecot-2.1: lib-fs: Added "mode" parameter to "posix" backend t... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/fcceee891448 changeset: 13839:fcceee891448 user: Timo Sirainen date: Sat Dec 10 08:15:58 2011 +0200 description: lib-fs: Added "mode" parameter to "posix" backend to specify mode for created files/dirs. diffstat: src/lib-fs/fs-posix.c | 60 +++++++++++++++++++++++++++++++++++--------------- 1 files changed, 42 insertions(+), 18 deletions(-) diffs (147 lines): diff -r 97af1836ea72 -r fcceee891448 src/lib-fs/fs-posix.c --- a/src/lib-fs/fs-posix.c Sat Dec 10 08:01:02 2011 +0200 +++ b/src/lib-fs/fs-posix.c Sat Dec 10 08:15:58 2011 +0200 @@ -13,12 +13,14 @@ #include "fs-api-private.h" #include +#include #include #include #include #define FS_POSIX_DOTLOCK_STALE_TIMEOUT_SECS (60*10) #define MAX_MKDIR_RETRY_COUNT 5 +#define FS_DEFAULT_MODE 0600 enum fs_posix_lock_method { FS_POSIX_LOCK_METHOD_FLOCK, @@ -29,6 +31,7 @@ struct fs fs; char *temp_file_prefix; enum fs_posix_lock_method lock_method; + mode_t mode, dir_mode; }; struct posix_fs_file { @@ -61,14 +64,33 @@ i_strdup(set->temp_file_prefix) : i_strdup("temp.dovecot."); fs->fs.set.temp_file_prefix = fs->temp_file_prefix; - if (*args == '\0') - fs->lock_method = FS_POSIX_LOCK_METHOD_FLOCK; - else if (strcmp(args, "lock=flock") == 0) - fs->lock_method = FS_POSIX_LOCK_METHOD_FLOCK; - else if (strcmp(args, "lock=dotlock") == 0) - fs->lock_method = FS_POSIX_LOCK_METHOD_DOTLOCK; - else - i_fatal("fs-posix: Unknown args '%s'", args); + fs->lock_method = FS_POSIX_LOCK_METHOD_FLOCK; + fs->mode = FS_DEFAULT_MODE; + T_BEGIN { + const char *const *tmp = t_strsplit_spaces(args, " "); + + for (; *tmp != NULL; tmp++) { + const char *arg = *tmp; + + if (strcmp(arg, "lock=flock") == 0) + fs->lock_method = FS_POSIX_LOCK_METHOD_FLOCK; + else if (strcmp(arg, "lock=dotlock") == 0) + fs->lock_method = FS_POSIX_LOCK_METHOD_DOTLOCK; + else if (strncmp(arg, "mode=", 5) == 0) { + fs->mode = strtoul(arg+5, NULL, 8) & 0666; + if (fs->mode == 0) { + i_fatal("fs-posix: Invalid mode: %s", + arg+5); + } + } else + i_fatal("fs-posix: Unknown arg '%s'", arg); + } + } T_END; + fs->dir_mode = fs->mode; + if ((fs->dir_mode & 0600) != 0) fs->dir_mode |= 0100; + if ((fs->dir_mode & 0060) != 0) fs->dir_mode |= 0010; + if ((fs->dir_mode & 0006) != 0) fs->dir_mode |= 0001; + return &fs->fs; } @@ -80,7 +102,7 @@ i_free(fs); } -static int fs_posix_create_parent_dir(struct fs *fs, const char *path) +static int fs_posix_create_parent_dir(struct posix_fs *fs, const char *path) { const char *dir, *fname; @@ -88,12 +110,12 @@ if (fname == NULL) return 1; dir = t_strdup_until(path, fname); - if (mkdir_parents(dir, 0700) == 0) + if (mkdir_parents(dir, fs->dir_mode) == 0) return 0; else if (errno == EEXIST) return 1; else { - fs_set_error(fs, "mkdir_parents(%s) failed: %m", dir); + fs_set_error(&fs->fs, "mkdir_parents(%s) failed: %m", dir); return -1; } } @@ -112,13 +134,13 @@ str_append_n(str, path, slash-path + 1); str_append(str, fs->temp_file_prefix); - fd = safe_mkstemp_hostpid(str, 0600, (uid_t)-1, (gid_t)-1); + fd = safe_mkstemp_hostpid(str, fs->mode, (uid_t)-1, (gid_t)-1); while (fd == -1 && errno == ENOENT && try_count <= MAX_MKDIR_RETRY_COUNT && (flags & FS_OPEN_FLAG_MKDIR) != 0) { - if (fs_posix_create_parent_dir(_fs, path) < 0) + if (fs_posix_create_parent_dir(fs, path) < 0) return -1; - fd = safe_mkstemp_hostpid(str, 0600, (uid_t)-1, (gid_t)-1); + fd = safe_mkstemp_hostpid(str, fs->mode, (uid_t)-1, (gid_t)-1); try_count++; } if (fd == -1) { @@ -462,8 +484,9 @@ return 0; } -static int fs_posix_link(struct fs *fs, const char *src, const char *dest) +static int fs_posix_link(struct fs *_fs, const char *src, const char *dest) { + struct posix_fs *fs = (struct posix_fs *)_fs; unsigned int try_count = 0; int ret; @@ -476,14 +499,15 @@ try_count++; } if (ret < 0) { - fs_set_error(fs, "link(%s, %s) failed: %m", src, dest); + fs_set_error(_fs, "link(%s, %s) failed: %m", src, dest); return -1; } return 0; } -static int fs_posix_rename(struct fs *fs, const char *src, const char *dest) +static int fs_posix_rename(struct fs *_fs, const char *src, const char *dest) { + struct posix_fs *fs = (struct posix_fs *)_fs; unsigned int try_count = 0; int ret; @@ -496,7 +520,7 @@ try_count++; } if (ret < 0) { - fs_set_error(fs, "link(%s, %s) failed: %m", src, dest); + fs_set_error(_fs, "link(%s, %s) failed: %m", src, dest); return -1; } return 0; From dovecot at dovecot.org Sat Dec 10 08:35:11 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 10 Dec 2011 08:35:11 +0200 Subject: dovecot-2.1: lib-index: If cache field's decision is forced no, ... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/95524ab3469f changeset: 13840:95524ab3469f user: Timo Sirainen date: Sat Dec 10 08:35:06 2011 +0200 description: lib-index: If cache field's decision is forced no, don't update the field's last_used. diffstat: src/lib-index/mail-cache-decisions.c | 13 ++++++++++--- 1 files changed, 10 insertions(+), 3 deletions(-) diffs (43 lines): diff -r fcceee891448 -r 95524ab3469f src/lib-index/mail-cache-decisions.c --- a/src/lib-index/mail-cache-decisions.c Sat Dec 10 08:15:58 2011 +0200 +++ b/src/lib-index/mail-cache-decisions.c Sat Dec 10 08:35:06 2011 +0200 @@ -74,6 +74,7 @@ uint32_t seq, unsigned int field) { struct mail_cache *cache = view->cache; + enum mail_cache_decision_type dec; const struct mail_index_header *hdr; uint32_t uid; @@ -82,8 +83,11 @@ if (view->no_decision_updates) return; - mail_index_lookup_uid(view->view, seq, &uid); - hdr = mail_index_get_header(view->view); + dec = cache->fields[field].field.decision; + if (dec == (MAIL_CACHE_DECISION_NO | MAIL_CACHE_DECISION_FORCED)) { + /* don't update last_used */ + return; + } if (ioloop_time - cache->fields[field].last_used > 3600*24) { /* update last_used about once a day */ @@ -92,13 +96,16 @@ cache->field_header_write_pending = TRUE; } - if (cache->fields[field].field.decision != MAIL_CACHE_DECISION_TEMP) { + if (dec != MAIL_CACHE_DECISION_TEMP) { /* a) forced decision b) not cached, mail_cache_decision_add() will handle this c) permanently cached already, okay. */ return; } + mail_index_lookup_uid(view->view, seq, &uid); + hdr = mail_index_get_header(view->view); + /* see if we want to change decision from TEMP to YES */ if (uid < cache->fields[field].uid_highwater || uid < hdr->day_first_uid[7]) { From dovecot at dovecot.org Sat Dec 10 08:41:17 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 10 Dec 2011 08:41:17 +0200 Subject: dovecot-2.1: lib-storage: Added separate %{gid} expansion to mai... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/499e4916bed5 changeset: 13841:499e4916bed5 user: Timo Sirainen date: Sat Dec 10 08:41:01 2011 +0200 description: lib-storage: Added separate %{gid} expansion to mail_user. The default %{gid} probably works also, but it's more reliable to do this explicitly. diffstat: src/lib-storage/mail-storage-service.c | 2 +- src/lib-storage/mail-user.c | 6 ++++-- src/lib-storage/mail-user.h | 5 +++-- 3 files changed, 8 insertions(+), 5 deletions(-) diffs (60 lines): diff -r 95524ab3469f -r 499e4916bed5 src/lib-storage/mail-storage-service.c --- a/src/lib-storage/mail-storage-service.c Sat Dec 10 08:35:06 2011 +0200 +++ b/src/lib-storage/mail-storage-service.c Sat Dec 10 08:41:01 2011 +0200 @@ -484,7 +484,7 @@ mail_user = mail_user_alloc(user->input.username, user->user_info, user->user_set); mail_user_set_home(mail_user, *home == '\0' ? NULL : home); - mail_user_set_vars(mail_user, geteuid(), ctx->service->name, + mail_user_set_vars(mail_user, geteuid(), getegid(), ctx->service->name, &user->input.local_ip, &user->input.remote_ip); mail_set = mail_user_set_get_storage_set(mail_user); diff -r 95524ab3469f -r 499e4916bed5 src/lib-storage/mail-user.c --- a/src/lib-storage/mail-user.c Sat Dec 10 08:35:06 2011 +0200 +++ b/src/lib-storage/mail-user.c Sat Dec 10 08:41:01 2011 +0200 @@ -159,11 +159,12 @@ return NULL; } -void mail_user_set_vars(struct mail_user *user, uid_t uid, const char *service, - const struct ip_addr *local_ip, +void mail_user_set_vars(struct mail_user *user, uid_t uid, gid_t gid, + const char *service, const struct ip_addr *local_ip, const struct ip_addr *remote_ip) { user->uid = uid; + user->gid = gid; user->service = p_strdup(user->pool, service); if (local_ip != NULL && local_ip->family != 0) { user->local_ip = p_new(user->pool, struct ip_addr, 1); @@ -188,6 +189,7 @@ { 'r', NULL, "rip" }, { 'p', NULL, "pid" }, { 'i', NULL, "uid" }, + { '\0', NULL, "gid" }, { '\0', NULL, NULL } }; struct var_expand_table *tab; diff -r 95524ab3469f -r 499e4916bed5 src/lib-storage/mail-user.h --- a/src/lib-storage/mail-user.h Sat Dec 10 08:35:06 2011 +0200 +++ b/src/lib-storage/mail-user.h Sat Dec 10 08:41:01 2011 +0200 @@ -20,6 +20,7 @@ const char *_home; uid_t uid; + gid_t gid; const char *service; struct ip_addr *local_ip, *remote_ip; const struct var_expand_table *var_expand_table; @@ -77,8 +78,8 @@ struct mail_user *mail_user_find(struct mail_user *user, const char *name); /* Specify mail location %variable expansion data. */ -void mail_user_set_vars(struct mail_user *user, uid_t uid, const char *service, - const struct ip_addr *local_ip, +void mail_user_set_vars(struct mail_user *user, uid_t uid, gid_t gid, + const char *service, const struct ip_addr *local_ip, const struct ip_addr *remote_ip); /* Return %variable expansion table for the user. */ const struct var_expand_table * From dovecot at dovecot.org Sat Dec 10 08:42:37 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 10 Dec 2011 08:42:37 +0200 Subject: dovecot-2.1: lib-index: Allow updating cache's last_used field w... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/ce29836e369e changeset: 13842:ce29836e369e user: Timo Sirainen date: Sat Dec 10 08:42:26 2011 +0200 description: lib-index: Allow updating cache's last_used field with mail_cache_register_fields() diffstat: src/lib-index/mail-cache-compress.c | 4 +- src/lib-index/mail-cache-decisions.c | 4 +- src/lib-index/mail-cache-fields.c | 50 +++++++++++++++++++++++------------ src/lib-index/mail-cache-private.h | 1 - src/lib-index/mail-cache.h | 2 + 5 files changed, 39 insertions(+), 22 deletions(-) diffs (162 lines): diff -r 499e4916bed5 -r ce29836e369e src/lib-index/mail-cache-compress.c --- a/src/lib-index/mail-cache-compress.c Sat Dec 10 08:41:01 2011 +0200 +++ b/src/lib-index/mail-cache-compress.c Sat Dec 10 08:42:26 2011 +0200 @@ -208,7 +208,7 @@ /* if the decision isn't forced and this field hasn't been accessed for a while, drop it */ if ((dec & MAIL_CACHE_DECISION_FORCED) == 0 && - (time_t)priv->last_used < max_drop_time && + priv->field.last_used < max_drop_time && !priv->adding) { dec = MAIL_CACHE_DECISION_NO; priv->field.decision = dec; @@ -218,7 +218,7 @@ if ((dec & ~MAIL_CACHE_DECISION_FORCED) == MAIL_CACHE_DECISION_NO && !priv->adding) { priv->used = FALSE; - priv->last_used = 0; + priv->field.last_used = 0; } ctx.field_file_map[i] = !priv->used ? diff -r 499e4916bed5 -r ce29836e369e src/lib-index/mail-cache-decisions.c --- a/src/lib-index/mail-cache-decisions.c Sat Dec 10 08:41:01 2011 +0200 +++ b/src/lib-index/mail-cache-decisions.c Sat Dec 10 08:42:26 2011 +0200 @@ -89,9 +89,9 @@ return; } - if (ioloop_time - cache->fields[field].last_used > 3600*24) { + if (ioloop_time - cache->fields[field].field.last_used > 3600*24) { /* update last_used about once a day */ - cache->fields[field].last_used = (uint32_t)ioloop_time; + cache->fields[field].field.last_used = (uint32_t)ioloop_time; if (cache->field_file_map[field] != (uint32_t)-1) cache->field_header_write_pending = TRUE; } diff -r 499e4916bed5 -r ce29836e369e src/lib-index/mail-cache-fields.c --- a/src/lib-index/mail-cache-fields.c Sat Dec 10 08:41:01 2011 +0200 +++ b/src/lib-index/mail-cache-fields.c Sat Dec 10 08:42:26 2011 +0200 @@ -65,11 +65,35 @@ return 0; } +static void +mail_cache_field_update(struct mail_cache *cache, + const struct mail_cache_field *newfield) +{ + struct mail_cache_field_private *orig; + + i_assert(newfield->type < MAIL_CACHE_FIELD_COUNT); + + orig = &cache->fields[newfield->idx]; + if (newfield->decision != MAIL_CACHE_DECISION_NO && + orig->field.decision != newfield->decision) { + orig->field.decision = newfield->decision; + orig->decision_dirty = TRUE; + } + if (orig->field.last_used < newfield->last_used) { + orig->field.last_used = newfield->last_used; + orig->decision_dirty = TRUE; + } + if (orig->decision_dirty) + cache->field_header_write_pending = TRUE; + + (void)field_type_verify(cache, newfield->idx, + newfield->type, newfield->field_size); +} + void mail_cache_register_fields(struct mail_cache *cache, struct mail_cache_field *fields, unsigned int fields_count) { - struct mail_cache_field *orig_field; void *orig_key, *orig_value; char *name; unsigned int new_idx; @@ -80,18 +104,9 @@ if (hash_table_lookup_full(cache->field_name_hash, fields[i].name, &orig_key, &orig_value)) { - i_assert(fields[i].type < MAIL_CACHE_FIELD_COUNT); - fields[i].idx = POINTER_CAST_TO(orig_value, unsigned int); - - orig_field = &cache->fields[fields[i].idx].field; - if (orig_field->decision == MAIL_CACHE_DECISION_NO) - orig_field->decision = fields[i].decision; - - (void)field_type_verify(cache, fields[i].idx, - fields[i].type, - fields[i].field_size); + mail_cache_field_update(cache, &fields[i]); continue; } @@ -130,6 +145,7 @@ name = p_strdup(cache->field_pool, fields[i].name); cache->fields[idx].field = fields[i]; cache->fields[idx].field.name = name; + cache->fields[idx].field.last_used = fields[i].last_used; cache->field_file_map[idx] = (uint32_t)-1; if (!field_has_fixed_size(cache->fields[idx].field.type)) @@ -387,12 +403,12 @@ cache->file_field_map[i] = fidx; /* update last_used if it's newer than ours */ - if (last_used[i] > cache->fields[fidx].last_used) - cache->fields[fidx].last_used = last_used[i]; + if (last_used[i] > cache->fields[fidx].field.last_used) + cache->fields[fidx].field.last_used = last_used[i]; dec = cache->fields[fidx].field.decision; - if ((time_t)cache->fields[fidx].last_used < max_drop_time && - cache->fields[fidx].last_used != 0 && + if (cache->fields[fidx].field.last_used < max_drop_time && + cache->fields[fidx].field.last_used != 0 && (dec & MAIL_CACHE_DECISION_FORCED) == 0 && dec != MAIL_CACHE_DECISION_NO) { /* time to drop this field. don't bother dropping @@ -469,7 +485,7 @@ buffer = buffer_create_dynamic(pool_datastack_create(), 256); copy_to_buf(cache, buffer, FALSE, - offsetof(struct mail_cache_field_private, last_used), + offsetof(struct mail_cache_field, last_used), sizeof(uint32_t)); ret = mail_cache_write(cache, buffer->data, buffer->used, offset + MAIL_CACHE_FIELD_LAST_USED()); @@ -532,7 +548,7 @@ /* we have to keep the field order for the existing fields. */ copy_to_buf(cache, dest, TRUE, - offsetof(struct mail_cache_field_private, last_used), + offsetof(struct mail_cache_field, last_used), sizeof(uint32_t)); copy_to_buf(cache, dest, TRUE, offsetof(struct mail_cache_field, field_size), diff -r 499e4916bed5 -r ce29836e369e src/lib-index/mail-cache-private.h --- a/src/lib-index/mail-cache-private.h Sat Dec 10 08:41:01 2011 +0200 +++ b/src/lib-index/mail-cache-private.h Sat Dec 10 08:42:26 2011 +0200 @@ -117,7 +117,6 @@ struct mail_cache_field field; uint32_t uid_highwater; - uint32_t last_used; /* Unused fields aren't written to cache file */ unsigned int used:1; diff -r 499e4916bed5 -r ce29836e369e src/lib-index/mail-cache.h --- a/src/lib-index/mail-cache.h Sat Dec 10 08:41:01 2011 +0200 +++ b/src/lib-index/mail-cache.h Sat Dec 10 08:42:26 2011 +0200 @@ -38,6 +38,8 @@ enum mail_cache_field_type type; unsigned int field_size; enum mail_cache_decision_type decision; + /* If higher than the current last_used field, update it */ + time_t last_used; }; struct mail_cache *mail_cache_open_or_create(struct mail_index *index); From dovecot at dovecot.org Sat Dec 10 08:43:14 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 10 Dec 2011 08:43:14 +0200 Subject: dovecot-2.1: doveadm: Compile fix for previous lib-index change. Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/186f2f5ee1c3 changeset: 13843:186f2f5ee1c3 user: Timo Sirainen date: Sat Dec 10 08:43:09 2011 +0200 description: doveadm: Compile fix for previous lib-index change. diffstat: src/doveadm/doveadm-dump-index.c | 3 +-- 1 files changed, 1 insertions(+), 2 deletions(-) diffs (20 lines): diff -r ce29836e369e -r 186f2f5ee1c3 src/doveadm/doveadm-dump-index.c --- a/src/doveadm/doveadm-dump-index.c Sat Dec 10 08:42:26 2011 +0200 +++ b/src/doveadm/doveadm-dump-index.c Sat Dec 10 08:43:09 2011 +0200 @@ -9,7 +9,6 @@ #include "message-part-serialize.h" #include "mail-index-private.h" #include "mail-cache-private.h" -#include "mail-cache-private.h" #include "mail-index-modseq.h" #include "doveadm-dump.h" @@ -344,7 +343,7 @@ printf(" - "); printf("%-4s %.16s\n", cache_decision2str(field->decision), - unixdate2str(cache->fields[cache_idx].last_used)); + unixdate2str(field->last_used)); } } From dovecot at dovecot.org Sat Dec 10 08:46:19 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 10 Dec 2011 08:46:19 +0200 Subject: dovecot-2.1: dsync: Update cache fields' decision and last_used ... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/3830d5a57fd4 changeset: 13844:3830d5a57fd4 user: Timo Sirainen date: Sat Dec 10 08:44:33 2011 +0200 description: dsync: Update cache fields' decision and last_used fields explicitly. This makes v2.1's dsync incompatible with v2.0's when used in different servers. diffstat: src/dsync/dsync-data.c | 8 +- src/dsync/dsync-data.h | 2 +- src/dsync/dsync-proxy-client.c | 4 +- src/dsync/dsync-proxy-server-cmd.c | 11 +- src/dsync/dsync-proxy.c | 99 ++++++++++++++++++++-- src/dsync/dsync-proxy.h | 11 +- src/dsync/dsync-worker-local.c | 31 +++--- src/dsync/dsync-worker-private.h | 2 +- src/dsync/test-dsync-common.c | 6 +- src/dsync/test-dsync-proxy.c | 7 +- src/dsync/test-dsync-worker.c | 2 +- src/dsync/test-dsync-worker.h | 2 +- src/lib-storage/index/dbox-multi/mdbox-storage.c | 4 +- src/lib-storage/index/dbox-single/sdbox-storage.c | 4 +- src/lib-storage/index/index-status.c | 13 ++- src/lib-storage/index/index-storage.c | 34 +++--- src/lib-storage/index/index-storage.h | 4 +- src/lib-storage/mail-storage.h | 14 ++- 18 files changed, 180 insertions(+), 78 deletions(-) diffs (truncated from 596 to 300 lines): diff -r 186f2f5ee1c3 -r 3830d5a57fd4 src/dsync/dsync-data.c --- a/src/dsync/dsync-data.c Sat Dec 10 08:43:09 2011 +0200 +++ b/src/dsync/dsync-data.c Sat Dec 10 08:44:33 2011 +0200 @@ -10,7 +10,8 @@ dsync_mailbox_dup(pool_t pool, const struct dsync_mailbox *box) { struct dsync_mailbox *dest; - const char *const *cache_fields = NULL, *dup; + const struct mailbox_cache_field *cache_fields = NULL; + struct mailbox_cache_field *dup; unsigned int i, count = 0; dest = p_new(pool, struct dsync_mailbox, 1); @@ -24,8 +25,9 @@ else { p_array_init(&dest->cache_fields, pool, count); for (i = 0; i < count; i++) { - dup = p_strdup(pool, cache_fields[i]); - array_append(&dest->cache_fields, &dup, 1); + dup = array_append_space(&dest->cache_fields); + *dup = cache_fields[i]; + dup->name = p_strdup(pool, dup->name); } } return dest; diff -r 186f2f5ee1c3 -r 3830d5a57fd4 src/dsync/dsync-data.h --- a/src/dsync/dsync-data.h Sat Dec 10 08:43:09 2011 +0200 +++ b/src/dsync/dsync-data.h Sat Dec 10 08:44:33 2011 +0200 @@ -28,7 +28,7 @@ otherwise it's the last rename timestamp. */ time_t last_change; enum dsync_mailbox_flags flags; - ARRAY_TYPE(const_string) cache_fields; + ARRAY_TYPE(mailbox_cache_field) cache_fields; }; ARRAY_DEFINE_TYPE(dsync_mailbox, struct dsync_mailbox *); #define dsync_mailbox_is_noselect(dsync_box) \ diff -r 186f2f5ee1c3 -r 3830d5a57fd4 src/dsync/dsync-proxy-client.c --- a/src/dsync/dsync-proxy-client.c Sat Dec 10 08:43:09 2011 +0200 +++ b/src/dsync/dsync-proxy-client.c Sat Dec 10 08:44:33 2011 +0200 @@ -893,7 +893,7 @@ static void proxy_client_worker_select_mailbox(struct dsync_worker *_worker, const mailbox_guid_t *mailbox, - const ARRAY_TYPE(const_string) *cache_fields) + const ARRAY_TYPE(mailbox_cache_field) *cache_fields) { struct proxy_client_dsync_worker *worker = (struct proxy_client_dsync_worker *)_worker; @@ -908,7 +908,7 @@ str_append(str, "BOX-SELECT\t"); dsync_proxy_mailbox_guid_export(str, mailbox); if (cache_fields != NULL) - dsync_proxy_strings_export(str, cache_fields); + dsync_proxy_cache_fields_export(str, cache_fields); str_append_c(str, '\n'); proxy_client_worker_cmd(worker, str); } T_END; diff -r 186f2f5ee1c3 -r 3830d5a57fd4 src/dsync/dsync-proxy-server-cmd.c --- a/src/dsync/dsync-proxy-server-cmd.c Sat Dec 10 08:43:09 2011 +0200 +++ b/src/dsync/dsync-proxy-server-cmd.c Sat Dec 10 08:44:33 2011 +0200 @@ -315,7 +315,7 @@ cmd_box_select(struct dsync_proxy_server *server, const char *const *args) { struct dsync_mailbox box; - unsigned int i, count; + const char *error; memset(&box, 0, sizeof(box)); if (args[0] == NULL || @@ -325,10 +325,11 @@ } args++; - count = str_array_length(args); - t_array_init(&box.cache_fields, count + 1); - for (i = 0; i < count; i++) - array_append(&box.cache_fields, &args[i], 1); + if (dsync_proxy_cache_fields_import(args, pool_datastack_create(), + &box.cache_fields, &error) < 0) { + i_error("box-select: %s", error); + return -1; + } dsync_worker_select_mailbox(server->worker, &box); return 1; } diff -r 186f2f5ee1c3 -r 3830d5a57fd4 src/dsync/dsync-proxy.c --- a/src/dsync/dsync-proxy.c Sat Dec 10 08:43:09 2011 +0200 +++ b/src/dsync/dsync-proxy.c Sat Dec 10 08:44:33 2011 +0200 @@ -8,27 +8,104 @@ #include "hex-binary.h" #include "mail-types.h" #include "imap-util.h" +#include "mail-cache.h" #include "dsync-data.h" #include "dsync-proxy.h" #include -void dsync_proxy_strings_export(string_t *str, - const ARRAY_TYPE(const_string) *strings) +#define DSYNC_CACHE_DECISION_NO 'n' +#define DSYNC_CACHE_DECISION_YES 'y' +#define DSYNC_CACHE_DECISION_TEMP 't' +#define DSYNC_CACHE_DECISION_FORCED 'f' + +void dsync_proxy_cache_fields_export(string_t *str, + const ARRAY_TYPE(mailbox_cache_field) *_fields) { - const char *const *fields; + const struct mailbox_cache_field *fields; unsigned int i, count; - if (!array_is_created(strings)) + if (!array_is_created(_fields)) return; - fields = array_get(strings, &count); + fields = array_get(_fields, &count); for (i = 0; i < count; i++) { str_append_c(str, '\t'); - str_tabescape_write(str, fields[i]); + str_tabescape_write(str, fields[i].name); + str_append_c(str, '\t'); + switch (fields[i].decision & ~MAIL_CACHE_DECISION_FORCED) { + case MAIL_CACHE_DECISION_NO: + str_append_c(str, DSYNC_CACHE_DECISION_NO); + break; + case MAIL_CACHE_DECISION_YES: + str_append_c(str, DSYNC_CACHE_DECISION_YES); + break; + case MAIL_CACHE_DECISION_TEMP: + str_append_c(str, DSYNC_CACHE_DECISION_TEMP); + break; + } + if ((fields[i].decision & MAIL_CACHE_DECISION_FORCED) != 0) + str_append_c(str, DSYNC_CACHE_DECISION_FORCED); + str_printfa(str, "\t%ld", fields[i].last_used); } } +static int dsync_proxy_cache_dec_parse(const char *str, + enum mail_cache_decision_type *dec_r) +{ + switch (*str++) { + case DSYNC_CACHE_DECISION_NO: + *dec_r = MAIL_CACHE_DECISION_NO; + break; + case DSYNC_CACHE_DECISION_YES: + *dec_r = MAIL_CACHE_DECISION_YES; + break; + case DSYNC_CACHE_DECISION_TEMP: + *dec_r = MAIL_CACHE_DECISION_TEMP; + break; + default: + return -1; + } + if (*str == DSYNC_CACHE_DECISION_FORCED) { + *dec_r |= MAIL_CACHE_DECISION_FORCED; + str++; + } + if (*str != '\0') + return -1; + return 0; +} + +int dsync_proxy_cache_fields_import(const char *const *args, pool_t pool, + ARRAY_TYPE(mailbox_cache_field) *fields, + const char **error_r) +{ + struct mailbox_cache_field *cache_field; + enum mail_cache_decision_type dec; + unsigned int i, count = str_array_length(args); + + if (count % 3 != 0) { + *error_r = "Invalid mailbox cache fields"; + return -1; + } + if (!array_is_created(fields)) + p_array_init(fields, pool, (count/3) + 1); + for (i = 0; i < count; i += 3) { + cache_field = array_append_space(fields); + cache_field->name = p_strdup(pool, args[i]); + + if (dsync_proxy_cache_dec_parse(args[i+1], &dec) < 0) { + *error_r = "Invalid cache decision"; + return -1; + } + cache_field->decision = dec; + if (str_to_time(args[i+2], &cache_field->last_used) < 0) { + *error_r = "Invalid cache last_used"; + return -1; + } + } + return 0; +} + void dsync_proxy_msg_export(string_t *str, const struct dsync_message *msg) { @@ -178,7 +255,7 @@ box->uid_validity, box->uid_next, box->message_count, (unsigned long long)box->highest_modseq, box->first_recent_uid); - dsync_proxy_strings_export(str, &box->cache_fields); + dsync_proxy_cache_fields_export(str, &box->cache_fields); } int dsync_proxy_mailbox_import_unescaped(pool_t pool, const char *const *args, @@ -270,11 +347,9 @@ args += i; count -= i; - p_array_init(&box_r->cache_fields, pool, count + 1); - for (i = 0; i < count; i++) { - const char *field_name = p_strdup(pool, args[i]); - array_append(&box_r->cache_fields, &field_name, 1); - } + if (dsync_proxy_cache_fields_import(args, pool, &box_r->cache_fields, + error_r) < 0) + return -1; return 0; } diff -r 186f2f5ee1c3 -r 3830d5a57fd4 src/dsync/dsync-proxy.h --- a/src/dsync/dsync-proxy.h Sat Dec 10 08:43:09 2011 +0200 +++ b/src/dsync/dsync-proxy.h Sat Dec 10 08:44:33 2011 +0200 @@ -6,14 +6,17 @@ #define DSYNC_PROXY_CLIENT_TIMEOUT_MSECS (14*60*1000) #define DSYNC_PROXY_SERVER_TIMEOUT_MSECS (15*60*1000) -#define DSYNC_PROXY_CLIENT_GREETING_LINE "dsync-client\t1" -#define DSYNC_PROXY_SERVER_GREETING_LINE "dsync-server\t1" +#define DSYNC_PROXY_CLIENT_GREETING_LINE "dsync-client\t2" +#define DSYNC_PROXY_SERVER_GREETING_LINE "dsync-server\t2" struct dsync_message; struct dsync_mailbox; -void dsync_proxy_strings_export(string_t *str, - const ARRAY_TYPE(const_string) *strings); +void dsync_proxy_cache_fields_export(string_t *str, + const ARRAY_TYPE(mailbox_cache_field) *fields); +int dsync_proxy_cache_fields_import(const char *const *args, pool_t pool, + ARRAY_TYPE(mailbox_cache_field) *fields, + const char **error_r); void dsync_proxy_msg_export(string_t *str, const struct dsync_message *msg); int dsync_proxy_msg_parse_flags(pool_t pool, const char *str, diff -r 186f2f5ee1c3 -r 3830d5a57fd4 src/dsync/dsync-worker-local.c --- a/src/dsync/dsync-worker-local.c Sat Dec 10 08:43:09 2011 +0200 +++ b/src/dsync/dsync-worker-local.c Sat Dec 10 08:44:33 2011 +0200 @@ -528,8 +528,8 @@ struct local_dsync_dir_change *dir_change, change_lookup; struct local_dsync_mailbox *old_lbox; enum mail_error error; - const char *const *fields; - unsigned int i, field_count; + struct mailbox_cache_field *cache_fields; + unsigned int i, cache_field_count; memset(dsync_box_r, 0, sizeof(*dsync_box_r)); @@ -595,12 +595,14 @@ dsync_box_r->highest_modseq = status.highest_modseq; p_clear(iter->ret_pool); - fields = array_get(metadata.cache_fields, &field_count); - p_array_init(&dsync_box_r->cache_fields, iter->ret_pool, field_count); - for (i = 0; i < field_count; i++) { - const char *field_name = p_strdup(iter->ret_pool, fields[i]); - - array_append(&dsync_box_r->cache_fields, &field_name, 1); + p_array_init(&dsync_box_r->cache_fields, iter->ret_pool, + array_count(metadata.cache_fields)); + array_append_array(&dsync_box_r->cache_fields, metadata.cache_fields); + cache_fields = array_get_modifiable(&dsync_box_r->cache_fields, + &cache_field_count); + for (i = 0; i < cache_field_count; i++) { + cache_fields[i].name = + p_strdup(iter->ret_pool, cache_fields[i].name); } old_lbox = hash_table_lookup(worker->mailbox_hash, @@ -1443,25 +1445,26 @@ static void local_worker_set_cache_fields(struct local_dsync_worker *worker, - const ARRAY_TYPE(const_string) *cache_fields) + const ARRAY_TYPE(mailbox_cache_field) *cache_fields) { struct mailbox_update update; - const char *const *fields, **new_fields; + const struct mailbox_cache_field *fields; + struct mailbox_cache_field *new_fields; unsigned int count; fields = array_get(cache_fields, &count); - new_fields = t_new(const char *, count + 1); - memcpy(new_fields, fields, sizeof(const char *) * count); From dovecot at dovecot.org Sat Dec 10 08:50:47 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 10 Dec 2011 08:50:47 +0200 Subject: dovecot-2.1: passdb imap: Log about failures. Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/9d1336b40592 changeset: 13845:9d1336b40592 user: Timo Sirainen date: Sat Dec 10 08:50:43 2011 +0200 description: passdb imap: Log about failures. diffstat: src/auth/passdb-imap.c | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-) diffs (17 lines): diff -r 3830d5a57fd4 -r 9d1336b40592 src/auth/passdb-imap.c --- a/src/auth/passdb-imap.c Sat Dec 10 08:44:33 2011 +0200 +++ b/src/auth/passdb-imap.c Sat Dec 10 08:50:43 2011 +0200 @@ -52,9 +52,13 @@ break; case IMAPC_COMMAND_STATE_NO: result = passdb_imap_get_failure_result(reply); + auth_request_log_info(request->auth_request, "imap", + "%s", reply->text_full); break; case IMAPC_COMMAND_STATE_BAD: case IMAPC_COMMAND_STATE_DISCONNECTED: + auth_request_log_error(request->auth_request, "imap", + "%s", reply->text_full); break; } request->verify_callback(result, request->auth_request); From dovecot at dovecot.org Sat Dec 10 10:59:46 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 10 Dec 2011 10:59:46 +0200 Subject: dovecot-2.1: lmtp: Simplify LMTP proxying by first reading the w... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/51d87deb5c26 changeset: 13846:51d87deb5c26 user: Timo Sirainen date: Sat Dec 10 10:59:30 2011 +0200 description: lmtp: Simplify LMTP proxying by first reading the whole input to memory/disk. This hopefully fixes problems related to LMTP proxying, at the cost of having to write large mails to temp directory. diffstat: src/lmtp/commands.c | 30 +---- src/lmtp/lmtp-proxy.c | 258 ++++++------------------------------------------- src/lmtp/lmtp-proxy.h | 2 +- 3 files changed, 42 insertions(+), 248 deletions(-) diffs (truncated from 439 to 300 lines): diff -r 9d1336b40592 -r 51d87deb5c26 src/lmtp/commands.c --- a/src/lmtp/commands.c Sat Dec 10 08:50:43 2011 +0200 +++ b/src/lmtp/commands.c Sat Dec 10 10:59:30 2011 +0200 @@ -717,18 +717,12 @@ client_input_handle(client); } -static void client_proxy_finish(bool timeout, void *context) +static void client_proxy_finish(void *context) { struct client *client = context; lmtp_proxy_deinit(&client->proxy); - if (timeout) { - client_destroy(client, - t_strdup_printf("421 4.4.2 %s", client->my_domain), - "Disconnected for inactivity"); - } else { - client_input_data_finish(client); - } + client_input_data_finish(client); } static const char *client_get_added_headers(struct client *client) @@ -765,10 +759,12 @@ struct istream *input; bool ret = TRUE; + io_remove(&client->io); i_stream_destroy(&client->dot_input); input = client_get_input(client); - client_input_data_write_local(client, input); + if (array_count(&client->state.rcpt_to) != 0) + client_input_data_write_local(client, input); if (client->proxy != NULL) { lmtp_proxy_start(client->proxy, input, NULL, client_proxy_finish, client); @@ -896,18 +892,8 @@ client_send_line(client, "354 OK"); io_remove(&client->io); - if (array_count(&client->state.rcpt_to) == 0) { - client->state.name = "DATA (proxy)"; - timeout_remove(&client->to_idle); - lmtp_proxy_start(client->proxy, client->dot_input, - client->state.added_headers, - client_proxy_finish, client); - i_stream_unref(&client->dot_input); - } else { - client->state.name = "DATA"; - client->io = io_add(client->fd_in, IO_READ, - client_input_data, client); - client_input_data_handle(client); - } + client->state.name = "DATA"; + client->io = io_add(client->fd_in, IO_READ, client_input_data, client); + client_input_data_handle(client); return -1; } diff -r 9d1336b40592 -r 51d87deb5c26 src/lmtp/lmtp-proxy.c --- a/src/lmtp/lmtp-proxy.c Sat Dec 10 08:50:43 2011 +0200 +++ b/src/lmtp/lmtp-proxy.c Sat Dec 10 10:59:30 2011 +0200 @@ -4,13 +4,11 @@ #include "array.h" #include "ioloop.h" #include "istream.h" -#include "istream-tee.h" #include "ostream.h" #include "lmtp-client.h" #include "lmtp-proxy.h" #define LMTP_MAX_LINE_LEN 1024 -#define LMTP_PROXY_DATA_INPUT_TIMEOUT_MSECS (1000*60) struct lmtp_proxy_recipient { struct lmtp_proxy_connection *conn; @@ -27,6 +25,7 @@ struct lmtp_client *client; struct istream *data_input; + struct timeout *to; unsigned int finished:1; unsigned int failed:1; @@ -41,11 +40,9 @@ ARRAY_DEFINE(rcpt_to, struct lmtp_proxy_recipient *); unsigned int next_data_reply_idx; - struct timeout *to, *to_data_idle, *to_finish; - struct io *io; - struct istream *data_input, *orig_data_input; + struct timeout *to_finish; + struct istream *data_input; struct ostream *client_output; - struct tee_istream *tee_data_input; unsigned int max_timeout_msecs; @@ -53,12 +50,9 @@ void *finish_context; unsigned int finished:1; - unsigned int input_timeout:1; - unsigned int handling_data_input:1; }; static void lmtp_conn_finish(void *context); -static void lmtp_proxy_data_input(struct lmtp_proxy *proxy); struct lmtp_proxy * lmtp_proxy_init(const char *my_hostname, const char *dns_client_socket_path, @@ -102,14 +96,8 @@ i_stream_unref(&proxy->data_input); if (proxy->client_output != NULL) o_stream_unref(&proxy->client_output); - if (proxy->to_data_idle != NULL) - timeout_remove(&proxy->to_data_idle); if (proxy->to_finish != NULL) timeout_remove(&proxy->to_finish); - if (proxy->to != NULL) - timeout_remove(&proxy->to); - if (proxy->io != NULL) - io_remove(&proxy->io); array_free(&proxy->rcpt_to); array_free(&proxy->connections); pool_unref(&proxy->pool); @@ -184,11 +172,19 @@ timeout_remove(&proxy->to_finish); proxy->finished = TRUE; - proxy->finish_callback(proxy->input_timeout, proxy->finish_context); + proxy->finish_callback(proxy->finish_context); } -static void lmtp_proxy_finish(struct lmtp_proxy *proxy) +static void lmtp_proxy_try_finish(struct lmtp_proxy *proxy) { + if (proxy->finish_callback == NULL) { + /* DATA command hasn't been sent yet */ + return; + } + if (!lmtp_proxy_send_data_replies(proxy)) { + /* we can't received reply from all clients yet */ + return; + } /* do the actual finishing in a timeout handler, since the finish callback causes the proxy to be destroyed and the code leading up to this function can be called from many different places. it's @@ -200,75 +196,18 @@ } } -static void lmtp_proxy_try_finish(struct lmtp_proxy *proxy) -{ - if (proxy->finish_callback == NULL) { - /* DATA command hasn't been sent yet */ - return; - } - if (lmtp_proxy_send_data_replies(proxy) && - (proxy->data_input == NULL || - proxy->data_input->eof || - proxy->data_input->stream_errno != 0 || - proxy->input_timeout)) - lmtp_proxy_finish(proxy); -} - static void lmtp_conn_finish(void *context) { struct lmtp_proxy_connection *conn = context; conn->finished = TRUE; + if (conn->to != NULL) + timeout_remove(&conn->to); if (conn->data_input != NULL) i_stream_unref(&conn->data_input); lmtp_proxy_try_finish(conn->proxy); } -static void lmtp_proxy_fail_all(struct lmtp_proxy *proxy, const char *reason) -{ - struct lmtp_proxy_connection *const *conns; - unsigned int i, count; - const char *line; - - conns = array_get(&proxy->connections, &count); - for (i = 0; i < count; i++) { - line = t_strdup_printf(ERRSTR_TEMP_REMOTE_FAILURE - " (%s while waiting for reply to %s)", reason, - lmtp_client_state_to_string(conns[i]->client)); - lmtp_client_fail(conns[i]->client, line); - } - - if (proxy->to_finish == NULL) { - /* we still have some DATA input to read */ - if (proxy->io == NULL) { - proxy->io = io_add(i_stream_get_fd(proxy->data_input), - IO_READ, - lmtp_proxy_data_input, proxy); - } - } -} - -static void lmtp_proxy_data_input_timeout(struct lmtp_proxy *proxy) -{ - struct lmtp_proxy_connection *const *conns; - unsigned int i, count; - - proxy->input_timeout = TRUE; - i_stream_close(proxy->orig_data_input); - - conns = array_get(&proxy->connections, &count); - for (i = 0; i < count; i++) { - lmtp_client_fail(conns[i]->client, ERRSTR_TEMP_REMOTE_FAILURE - " (timeout in DATA input)"); - } - if (proxy->to_finish == NULL) { - /* we had earlier failed all clients already and were just - waiting for DATA input to finish, but DATA input also failed - with a timeout. */ - lmtp_proxy_finish(proxy); - } -} - static void lmtp_proxy_conn_rcpt_to(bool success, const char *reply, void *context) { @@ -316,151 +255,21 @@ return 0; } -static uoff_t lmtp_proxy_find_lowest_offset(struct lmtp_proxy *proxy) +static void lmtp_proxy_more_data_sent(void *context) { - struct lmtp_proxy_connection *const *conns; - uoff_t min_offset = (uoff_t)-1; + struct lmtp_proxy_connection *conn = context; - array_foreach(&proxy->connections, conns) { - struct lmtp_proxy_connection *conn = *conns; - - if (conn->data_input != NULL && - min_offset > conn->data_input->v_offset && - i_stream_have_bytes_left(conn->data_input)) - min_offset = conn->data_input->v_offset; - } - return min_offset; + lmtp_client_send_more(conn->client); } -static bool lmtp_proxy_disconnect_hanging_output(struct lmtp_proxy *proxy) +static void lmtp_proxy_conn_timeout(struct lmtp_proxy_connection *conn) { - struct lmtp_proxy_connection *const *conns; - uoff_t min_offset; - size_t size; - const char *errstr; + const char *line; - min_offset = lmtp_proxy_find_lowest_offset(proxy); - if (min_offset == (uoff_t)-1) - return FALSE; - - /* disconnect all connections that are keeping us from reading - more input. */ - array_foreach(&proxy->connections, conns) { - struct lmtp_proxy_connection *conn = *conns; - - if (conn->data_input != NULL && - conn->data_input->v_offset == min_offset) { - (void)i_stream_get_data(conn->data_input, &size); - errstr = t_strdup_printf(ERRSTR_TEMP_REMOTE_FAILURE - " (DATA output stalled for %u secs, " - "%"PRIuUOFF_T"B sent, %"PRIuSIZE_T"B buffered)", - proxy->max_timeout_msecs/1000, - min_offset, size); - lmtp_client_fail(conn->client, errstr); - } - } - return TRUE; -} - -static void lmtp_proxy_output_timeout(struct lmtp_proxy *proxy) -{ - timeout_remove(&proxy->to); - - /* drop the connection with the most unread data */ - if (lmtp_proxy_disconnect_hanging_output(proxy)) - lmtp_proxy_data_input(proxy); - else { - /* no such connection, so we've already sent everything but - some servers aren't replying to us. disconnect all of - them. */ - i_assert(proxy->data_input->eof); - lmtp_proxy_fail_all(proxy, "timeout"); - } -} - -static void lmtp_proxy_wait_for_output(struct lmtp_proxy *proxy) -{ From pigeonhole at rename-it.nl Mon Dec 12 01:26:31 2011 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Mon, 12 Dec 2011 00:26:31 +0100 Subject: dovecot-2.1-pigeonhole: lib-sieve: made sure error locations nev... Message-ID: details: http://hg.rename-it.nl/dovecot-2.1-pigeonhole/rev/d56a318174db changeset: 1573:d56a318174db user: Stephan Bosch date: Mon Dec 12 00:25:47 2011 +0100 description: lib-sieve: made sure error locations never report `line 0'. diffstat: src/lib-sieve/sieve-error.c | 9 ++++++++- 1 files changed, 8 insertions(+), 1 deletions(-) diffs (20 lines): diff -r a224cdad4aa3 -r d56a318174db src/lib-sieve/sieve-error.c --- a/src/lib-sieve/sieve-error.c Mon Dec 12 00:23:04 2011 +0100 +++ b/src/lib-sieve/sieve-error.c Mon Dec 12 00:25:47 2011 +0100 @@ -41,8 +41,15 @@ sname = ( script == NULL ? NULL : sieve_script_name(script) ); - if ( sname == NULL || *sname == '\0' ) + if ( sname == NULL || *sname == '\0' ) { + if ( source_line == 0 ) + return NULL; + return t_strdup_printf("line %d", source_line); + } + + if ( source_line == 0 ) + return sname; return t_strdup_printf("%s: line %d", sname, source_line); } From pigeonhole at rename-it.nl Mon Dec 12 01:26:31 2011 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Mon, 12 Dec 2011 00:26:31 +0100 Subject: dovecot-2.1-pigeonhole: lib-sieve: fixed potention segfault occu... Message-ID: details: http://hg.rename-it.nl/dovecot-2.1-pigeonhole/rev/a224cdad4aa3 changeset: 1572:a224cdad4aa3 user: Stephan Bosch date: Mon Dec 12 00:23:04 2011 +0100 description: lib-sieve: fixed potention segfault occuring when interpreter initialization fails. diffstat: src/lib-sieve/sieve.c | 10 ++++++---- 1 files changed, 6 insertions(+), 4 deletions(-) diffs (28 lines): diff -r 3eb7a7460fa3 -r a224cdad4aa3 src/lib-sieve/sieve.c --- a/src/lib-sieve/sieve.c Wed Dec 07 22:59:14 2011 +0100 +++ b/src/lib-sieve/sieve.c Mon Dec 12 00:23:04 2011 +0100 @@ -438,8 +438,9 @@ } /* Cleanup */ - sieve_result_unref(&result); - + if ( result != NULL ) + sieve_result_unref(&result); + return ret; } @@ -476,9 +477,10 @@ if ( keep != NULL ) *keep = TRUE; } } - + /* Cleanup */ - sieve_result_unref(&result); + if ( result != NULL ) + sieve_result_unref(&result); return ret; } From pigeonhole at rename-it.nl Mon Dec 12 01:47:04 2011 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Mon, 12 Dec 2011 00:47:04 +0100 Subject: dovecot-2.1-pigeonhole: lib-sieve: added support for restricting... Message-ID: details: http://hg.rename-it.nl/dovecot-2.1-pigeonhole/rev/595ce12806d9 changeset: 1574:595ce12806d9 user: Stephan Bosch date: Mon Dec 12 00:46:59 2011 +0100 description: lib-sieve: added support for restricting certain extensions to (admin-controled) global scripts - Added sieve_global_extensions setting. diffstat: INSTALL | 20 ++- src/lib-sieve-tool/sieve-tool.c | 6 +- src/lib-sieve/plugins/ihave/ext-ihave-binary.c | 13 +- src/lib-sieve/plugins/ihave/tst-ihave.c | 12 +- src/lib-sieve/plugins/include/ext-include-binary.c | 5 +- src/lib-sieve/plugins/include/ext-include-common.c | 21 ++- src/lib-sieve/sieve-binary.c | 6 +- src/lib-sieve/sieve-binary.h | 5 +- src/lib-sieve/sieve-common.h | 2 +- src/lib-sieve/sieve-extensions.c | 140 ++++++++++++++-------- src/lib-sieve/sieve-extensions.h | 4 +- src/lib-sieve/sieve-interpreter.c | 33 ++++- src/lib-sieve/sieve-interpreter.h | 6 +- src/lib-sieve/sieve-plugins.c | 16 +- src/lib-sieve/sieve-runtime.h | 1 + src/lib-sieve/sieve-types.h | 18 ++- src/lib-sieve/sieve-validator.c | 28 ++++- src/lib-sieve/sieve-validator.h | 5 +- src/lib-sieve/sieve.c | 39 +++--- src/lib-sieve/sieve.h | 15 +- src/managesieve/cmd-putscript.c | 3 +- src/plugins/lda-sieve/lda-sieve-plugin.c | 56 +++++--- src/sieve-tools/sieve-filter.c | 4 +- src/sieve-tools/sieve-test.c | 8 +- src/testsuite/testsuite-script.c | 9 +- src/testsuite/testsuite.c | 6 +- 26 files changed, 316 insertions(+), 165 deletions(-) diffs (truncated from 1370 to 300 lines): diff -r d56a318174db -r 595ce12806d9 INSTALL --- a/INSTALL Mon Dec 12 00:25:47 2011 +0100 +++ b/INSTALL Mon Dec 12 00:46:59 2011 +0100 @@ -104,10 +104,22 @@ supported extensions are available, except for deprecated extensions or those that are still under development. Some system administrators may want to disable certain Sieve extensions or enable those that are not available by - default. Supported extensions are listed on this page. This setting can use - '+' and '-' to specify differences relative to the default. For example - `sieve_extensions = +imapflags' will enable the deprecated imapflags - extension in addition to all extensions enabled by default. + default. This setting can use '+' and '-' to specify differences relative to + the default. For example `sieve_extensions = +imapflags' will enable the + deprecated imapflags extension in addition to all extensions were already + enabled by default. + + sieve_global_extensions = + Which Sieve language extensions are ONLY avalable in global scripts. This can + be used to restrict the use of certain Sieve extensions to administrator + control, for instance when these extensions can cause security concerns. This + setting has higher precedence than the `sieve_extensions' setting (above), + meaning that the extensions enabled with this setting are never available to + the user's personal script no matter what is specified for the + `sieve_extensions' setting. The syntax of this setting is similar to + the `sieve_extensions' setting, with the difference that extensions are + enabled or disabled for exclusive use in global scripts. Currently, no + extensions are marked as such by default. sieve_plugins = The Pigeonhole Sieve interpreter can have plugins of its own. Using this diff -r d56a318174db -r 595ce12806d9 src/lib-sieve-tool/sieve-tool.c --- a/src/lib-sieve-tool/sieve-tool.c Mon Dec 12 00:25:47 2011 +0100 +++ b/src/lib-sieve-tool/sieve-tool.c Mon Dec 12 00:46:59 2011 +0100 @@ -519,7 +519,8 @@ sieve_error_handler_accept_infolog(ehandler, TRUE); sieve_error_handler_accept_debuglog(ehandler, svinst->debug); - if ( (sbin = sieve_compile(svinst, filename, name, ehandler, NULL)) == NULL ) + if ( (sbin = sieve_compile + (svinst, filename, name, ehandler, 0, NULL)) == NULL ) i_error("failed to compile sieve script '%s'", filename); sieve_error_handler_unref(&ehandler); @@ -536,7 +537,8 @@ ehandler = sieve_stderr_ehandler_create(svinst, 0); sieve_error_handler_accept_infolog(ehandler, TRUE); - if ( (sbin = sieve_open(svinst, filename, NULL, ehandler, NULL)) == NULL ) { + if ( (sbin = sieve_open + (svinst, filename, NULL, ehandler, 0, NULL)) == NULL ) { sieve_error_handler_unref(&ehandler); i_fatal("failed to compile sieve script"); } diff -r d56a318174db -r 595ce12806d9 src/lib-sieve/plugins/ihave/ext-ihave-binary.c --- a/src/lib-sieve/plugins/ihave/ext-ihave-binary.c Mon Dec 12 00:25:47 2011 +0100 +++ b/src/lib-sieve/plugins/ihave/ext-ihave-binary.c Mon Dec 12 00:46:59 2011 +0100 @@ -25,7 +25,8 @@ static bool ext_ihave_binary_open (const struct sieve_extension *ext, struct sieve_binary *sbin, void *context); static bool ext_ihave_binary_up_to_date - (const struct sieve_extension *ext, struct sieve_binary *sbin, void *context); + (const struct sieve_extension *ext, struct sieve_binary *sbin, void *context, + enum sieve_compile_flags cpflags); /* * Binary include extension @@ -187,16 +188,18 @@ static bool ext_ihave_binary_up_to_date (const struct sieve_extension *ext, struct sieve_binary *sbin ATTR_UNUSED, - void *context) + void *context, enum sieve_compile_flags cpflags) { struct ext_ihave_binary_context *binctx = (struct ext_ihave_binary_context *) context; - const char *const *exts; + const struct sieve_extension *mext; + const char *const *mexts; unsigned int count, i; - exts = array_get(&binctx->missing_extensions, &count); + mexts = array_get(&binctx->missing_extensions, &count); for ( i = 0; i < count; i++ ) { - if ( sieve_extension_get_by_name(ext->svinst, exts[i]) != NULL ) + if ( (mext=sieve_extension_get_by_name(ext->svinst, mexts[i])) != NULL && + ((cpflags & SIEVE_COMPILE_FLAG_NOGLOBAL) == 0 || !mext->global) ) return FALSE; } diff -r d56a318174db -r 595ce12806d9 src/lib-sieve/plugins/ihave/tst-ihave.c --- a/src/lib-sieve/plugins/ihave/tst-ihave.c Mon Dec 12 00:25:47 2011 +0100 +++ b/src/lib-sieve/plugins/ihave/tst-ihave.c Mon Dec 12 00:46:59 2011 +0100 @@ -49,6 +49,8 @@ struct sieve_ast_argument *arg = tst->first_positional; struct sieve_ast_argument *stritem; + enum sieve_compile_flags cpflags = sieve_validator_compile_flags(valdtr); + bool no_global = ( (cpflags & SIEVE_COMPILE_FLAG_NOGLOBAL) != 0 ); ARRAY_DEFINE(capabilities, struct _capability); struct _capability capability; const struct _capability *caps; @@ -71,13 +73,14 @@ capability.arg = arg; capability.ext = sieve_extension_get_by_name (tst->ext->svinst, sieve_ast_argument_strc(arg)); - array_append(&capabilities, &capability, 1); - if ( capability.ext == NULL ) { + if ( capability.ext == NULL || (no_global && capability.ext->global)) { all_known = FALSE; ext_ihave_ast_add_missing_extension (tst->ext, tst->ast_node->ast, sieve_ast_argument_strc(arg)); + } else { + array_append(&capabilities, &capability, 1); } break; @@ -90,13 +93,14 @@ capability.arg = stritem; capability.ext = sieve_extension_get_by_name (tst->ext->svinst, sieve_ast_argument_strc(stritem)); - array_append(&capabilities, &capability, 1); - if ( capability.ext == NULL ) { + if ( capability.ext == NULL || (no_global && capability.ext->global)) { all_known = FALSE; ext_ihave_ast_add_missing_extension (tst->ext, tst->ast_node->ast, sieve_ast_argument_strc(stritem)); + } else { + array_append(&capabilities, &capability, 1); } stritem = sieve_ast_strlist_next(stritem); diff -r d56a318174db -r 595ce12806d9 src/lib-sieve/plugins/include/ext-include-binary.c --- a/src/lib-sieve/plugins/include/ext-include-binary.c Mon Dec 12 00:25:47 2011 +0100 +++ b/src/lib-sieve/plugins/include/ext-include-binary.c Mon Dec 12 00:46:59 2011 +0100 @@ -28,7 +28,8 @@ static bool ext_include_binary_open (const struct sieve_extension *ext, struct sieve_binary *sbin, void *context); static bool ext_include_binary_up_to_date - (const struct sieve_extension *ext, struct sieve_binary *sbin, void *context); + (const struct sieve_extension *ext, struct sieve_binary *sbin, void *context, + enum sieve_compile_flags cpflags); static void ext_include_binary_free (const struct sieve_extension *ext, struct sieve_binary *sbin, void *context); @@ -327,7 +328,7 @@ static bool ext_include_binary_up_to_date (const struct sieve_extension *ext ATTR_UNUSED, struct sieve_binary *sbin, - void *context) + void *context, enum sieve_compile_flags cpflags ATTR_UNUSED) { struct ext_include_binary_context *binctx = (struct ext_include_binary_context *) context; diff -r d56a318174db -r 595ce12806d9 src/lib-sieve/plugins/include/ext-include-common.c --- a/src/lib-sieve/plugins/include/ext-include-common.c Mon Dec 12 00:25:47 2011 +0100 +++ b/src/lib-sieve/plugins/include/ext-include-common.c Mon Dec 12 00:46:59 2011 +0100 @@ -520,6 +520,7 @@ { struct sieve_binary_block *inc_block; const char *script_name = sieve_script_name(script); + enum sieve_compile_flags cpflags = 0; /* Check whether include limit is exceeded */ if ( ext_include_binary_script_get_count(binctx) >= @@ -546,8 +547,11 @@ /* Included scripts inherit global variable scope */ (void)ext_include_create_ast_context(this_ext, ast, cmd->ast_node->ast); + if ( location != EXT_INCLUDE_LOCATION_GLOBAL ) + cpflags |= SIEVE_RUNTIME_FLAG_NOGLOBAL; + /* Validate */ - if ( !sieve_validate(ast, ehandler, NULL) ) { + if ( !sieve_validate(ast, ehandler, cpflags, NULL) ) { sieve_command_generate_error(gentr, cmd, "failed to validate included script '%s'", str_sanitize(script_name, 80)); @@ -681,12 +685,17 @@ /* We are the top-level interpreter instance */ if ( result == SIEVE_EXEC_OK ) { + enum sieve_runtime_flags rtflags = 0; + + if ( included->location != EXT_INCLUDE_LOCATION_GLOBAL ) + rtflags |= SIEVE_RUNTIME_FLAG_NOGLOBAL; + /* Create interpreter for top-level included script * (first sub-interpreter) */ subinterp = sieve_interpreter_create_for_block (included->block, included->script, renv->msgdata, renv->scriptenv, - ehandler); + ehandler, rtflags); if ( subinterp != NULL ) { curctx = ext_include_interpreter_context_init_child @@ -734,14 +743,18 @@ result = ( sieve_interpreter_continue(subinterp, &interrupted) == 1 ); } else { if ( curctx->include != NULL ) { - /* Sub-include requested */ if ( result == SIEVE_EXEC_OK ) { + enum sieve_runtime_flags rtflags = 0; + + if ( curctx->include->location != EXT_INCLUDE_LOCATION_GLOBAL ) + rtflags |= SIEVE_RUNTIME_FLAG_NOGLOBAL; + /* Create sub-interpreter */ subinterp = sieve_interpreter_create_for_block (curctx->include->block, curctx->include->script, renv->msgdata, - renv->scriptenv, ehandler); + renv->scriptenv, ehandler, rtflags); if ( subinterp != NULL ) { curctx = ext_include_interpreter_context_init_child diff -r d56a318174db -r 595ce12806d9 src/lib-sieve/sieve-binary.c --- a/src/lib-sieve/sieve-binary.c Mon Dec 12 00:25:47 2011 +0100 +++ b/src/lib-sieve/sieve-binary.c Mon Dec 12 00:46:59 2011 +0100 @@ -290,7 +290,8 @@ * Up-to-date checking */ -bool sieve_binary_up_to_date(struct sieve_binary *sbin) +bool sieve_binary_up_to_date +(struct sieve_binary *sbin, enum sieve_compile_flags cpflags) { struct sieve_binary_extension_reg *const *regs; unsigned int ext_count, i; @@ -306,7 +307,8 @@ const struct sieve_binary_extension *binext = regs[i]->binext; if ( binext != NULL && binext->binary_up_to_date != NULL && - !binext->binary_up_to_date(regs[i]->extension, sbin, regs[i]->context) ) + !binext->binary_up_to_date + (regs[i]->extension, sbin, regs[i]->context, cpflags) ) return FALSE; } diff -r d56a318174db -r 595ce12806d9 src/lib-sieve/sieve-binary.h --- a/src/lib-sieve/sieve-binary.h Mon Dec 12 00:25:47 2011 +0100 +++ b/src/lib-sieve/sieve-binary.h Mon Dec 12 00:46:59 2011 +0100 @@ -64,7 +64,8 @@ struct sieve_binary *sieve_binary_open (struct sieve_instance *svinst, const char *path, struct sieve_script *script, enum sieve_error *error_r); -bool sieve_binary_up_to_date(struct sieve_binary *sbin); +bool sieve_binary_up_to_date + (struct sieve_binary *sbin, enum sieve_compile_flags cpflags); /* * Block management @@ -117,7 +118,7 @@ bool (*binary_up_to_date) (const struct sieve_extension *ext, struct sieve_binary *sbin, - void *context); + void *context, enum sieve_compile_flags cpflags); }; void sieve_binary_extension_set_context diff -r d56a318174db -r 595ce12806d9 src/lib-sieve/sieve-common.h --- a/src/lib-sieve/sieve-common.h Mon Dec 12 00:25:47 2011 +0100 +++ b/src/lib-sieve/sieve-common.h Mon Dec 12 00:46:59 2011 +0100 @@ -145,7 +145,7 @@ enum sieve_error *error_r); bool sieve_validate (struct sieve_ast *ast, struct sieve_error_handler *ehandler, - enum sieve_error *error_r); + enum sieve_compile_flags flags, enum sieve_error *error_r); /* * Sieve engine instance diff -r d56a318174db -r 595ce12806d9 src/lib-sieve/sieve-extensions.c --- a/src/lib-sieve/sieve-extensions.c Mon Dec 12 00:25:47 2011 +0100 +++ b/src/lib-sieve/sieve-extensions.c Mon Dec 12 00:46:59 2011 +0100 @@ -197,7 +197,6 @@ unsigned int i; struct sieve_extension_registry *ext_reg = p_new(svinst->pool, struct sieve_extension_registry, 1); - const char *extensions; struct sieve_extension *ext; svinst->ext_reg = ext_reg; @@ -260,16 +259,26 @@ } #endif - /* Use sieve_extensions if set */ - - if ( (extensions=sieve_setting_get(svinst, "sieve_extensions")) != NULL ) - sieve_extensions_set_string(svinst, extensions); - /* More extensions can be added through plugins */ From pigeonhole at rename-it.nl Mon Dec 12 01:49:26 2011 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Mon, 12 Dec 2011 00:49:26 +0100 Subject: dovecot-2.1-pigeonhole: Updated TODO. Message-ID: details: http://hg.rename-it.nl/dovecot-2.1-pigeonhole/rev/b5a2419f0dee changeset: 1575:b5a2419f0dee user: Stephan Bosch date: Mon Dec 12 00:49:22 2011 +0100 description: Updated TODO. diffstat: TODO | 1 - 1 files changed, 0 insertions(+), 1 deletions(-) diffs (11 lines): diff -r 595ce12806d9 -r b5a2419f0dee TODO --- a/TODO Mon Dec 12 00:46:59 2011 +0100 +++ b/TODO Mon Dec 12 00:49:22 2011 +0100 @@ -79,7 +79,6 @@ * Add support for stream matching for handling large values, e.g. from the body extension. * Implement message modification and extraction API in order to: - - Implement editheader extension - Implement replace, enclose, foreverypart, mime and extracttext extensions * Provide a solution for mail_get_headers_utf8 reparsing the whole message each time it is called (header and address test; Timo might provide solution from From dovecot at dovecot.org Mon Dec 12 06:07:45 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 12 Dec 2011 06:07:45 +0200 Subject: dovecot-2.1: lib-storage: Previously added %{gid} variable didn'... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/3c5fda349c1f changeset: 13847:3c5fda349c1f user: Timo Sirainen date: Mon Dec 12 06:07:33 2011 +0200 description: lib-storage: Previously added %{gid} variable didn't actually work. diffstat: src/lib-storage/mail-user.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (11 lines): diff -r 51d87deb5c26 -r 3c5fda349c1f src/lib-storage/mail-user.c --- a/src/lib-storage/mail-user.c Sat Dec 10 10:59:30 2011 +0200 +++ b/src/lib-storage/mail-user.c Mon Dec 12 06:07:33 2011 +0200 @@ -212,6 +212,7 @@ p_strdup(user->pool, net_ip2addr(user->remote_ip)); tab[7].value = my_pid; tab[8].value = p_strdup(user->pool, dec2str(user->uid)); + tab[9].value = p_strdup(user->pool, dec2str(user->gid)); user->var_expand_table = tab; return user->var_expand_table; From dovecot at dovecot.org Mon Dec 12 06:38:43 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 12 Dec 2011 06:38:43 +0200 Subject: dovecot-2.1: lib-storage: Handle %{uid} and %{gid} expansion wit... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/9352c4ccb1f9 changeset: 13848:9352c4ccb1f9 user: Timo Sirainen date: Mon Dec 12 06:36:31 2011 +0200 description: lib-storage: Handle %{uid} and %{gid} expansion without relying on process's euid/egid. diffstat: src/lib-storage/mail-storage-service.c | 301 ++++++++++++++++++-------------- src/lib-storage/mail-user.c | 6 +- src/lib-storage/mail-user.h | 4 +- 3 files changed, 177 insertions(+), 134 deletions(-) diffs (truncated from 477 to 300 lines): diff -r 3c5fda349c1f -r 9352c4ccb1f9 src/lib-storage/mail-storage-service.c --- a/src/lib-storage/mail-storage-service.c Mon Dec 12 06:07:33 2011 +0200 +++ b/src/lib-storage/mail-storage-service.c Mon Dec 12 06:36:31 2011 +0200 @@ -38,6 +38,15 @@ #define ERRSTR_INVALID_USER_SETTINGS \ "Invalid user settings. Refer to server log for more information." +struct mail_storage_service_privileges { + uid_t uid; + gid_t gid; + const char *uid_source, *gid_source; + + const char *home; + const char *chroot; +}; + struct mail_storage_service_ctx { pool_t pool; struct master_service *service; @@ -348,13 +357,124 @@ } } +static const struct var_expand_table * +get_var_expand_table(struct master_service *service, + struct mail_storage_service_input *input, + struct mail_storage_service_privileges *priv) +{ + static struct var_expand_table static_tab[] = { + { 'u', NULL, "user" }, + { 'n', NULL, "username" }, + { 'd', NULL, "domain" }, + { 's', NULL, "service" }, + { 'l', NULL, "lip" }, + { 'r', NULL, "rip" }, + { 'p', NULL, "pid" }, + { 'i', NULL, "uid" }, + { '\0', NULL, "gid" }, + { '\0', NULL, NULL } + }; + struct var_expand_table *tab; + + tab = t_malloc(sizeof(static_tab)); + memcpy(tab, static_tab, sizeof(static_tab)); + + tab[0].value = input->username; + tab[1].value = t_strcut(input->username, '@'); + tab[2].value = strchr(input->username, '@'); + if (tab[2].value != NULL) tab[2].value++; + tab[3].value = service->name; + tab[4].value = net_ip2addr(&input->local_ip); + tab[5].value = net_ip2addr(&input->remote_ip); + tab[6].value = my_pid; + tab[7].value = dec2str(priv->uid == (uid_t)-1 ? geteuid() : priv->uid); + tab[8].value = dec2str(priv->gid == (gid_t)-1 ? getegid() : priv->gid); + return tab; +} + +static const char * +user_expand_varstr(struct master_service *service, + struct mail_storage_service_input *input, + struct mail_storage_service_privileges *priv, + const char *str) +{ + string_t *ret; + + if (*str == SETTING_STRVAR_EXPANDED[0]) + return str + 1; + + i_assert(*str == SETTING_STRVAR_UNEXPANDED[0]); + + ret = t_str_new(256); + var_expand(ret, str + 1, get_var_expand_table(service, input, priv)); + return str_c(ret); +} + +static int +service_parse_privileges(struct mail_storage_service_ctx *ctx, + struct mail_storage_service_user *user, + struct mail_storage_service_privileges *priv_r, + const char **error_r) +{ + const struct mail_user_settings *set = user->user_set; + uid_t uid = (uid_t)-1; + gid_t gid = (gid_t)-1; + + memset(priv_r, 0, sizeof(*priv_r)); + if (*set->mail_uid != '\0') { + if (!parse_uid(set->mail_uid, &uid, error_r)) { + *error_r = t_strdup_printf("%s (from %s)", *error_r, + user->uid_source); + return -1; + } + if (uid < (uid_t)set->first_valid_uid || + (set->last_valid_uid != 0 && + uid > (uid_t)set->last_valid_uid)) { + *error_r = t_strdup_printf( + "Mail access for users with UID %s not permitted " + "(see first_valid_uid in config file, uid from %s).", + dec2str(uid), user->uid_source); + return -1; + } + } + priv_r->uid = uid; + priv_r->uid_source = user->uid_source; + + if (*set->mail_gid != '\0') { + if (!parse_gid(set->mail_gid, &gid, error_r)) { + *error_r = t_strdup_printf("%s (from %s)", *error_r, + user->gid_source); + return -1; + } + if (gid < (gid_t)set->first_valid_gid || + (set->last_valid_gid != 0 && + gid > (gid_t)set->last_valid_gid)) { + *error_r = t_strdup_printf( + "Mail access for users with GID %s not permitted " + "(see first_valid_gid in config file, gid from %s).", + dec2str(gid), user->gid_source); + return -1; + } + } + priv_r->gid = gid; + priv_r->gid_source = user->gid_source; + + /* variable strings are expanded in mail_user_init(), + but we need the home and chroot sooner so do them separately here. */ + priv_r->home = user_expand_varstr(ctx->service, &user->input, priv_r, + user->user_set->mail_home); + priv_r->chroot = user_expand_varstr(ctx->service, &user->input, priv_r, + user->user_set->mail_chroot); + return 0; +} + static int service_drop_privileges(struct mail_storage_service_user *user, - const struct mail_user_settings *set, - const char *home, const char *chroot, + struct mail_storage_service_privileges *priv, bool disallow_root, bool keep_setuid_root, bool setenv_only, const char **error_r) { + const struct mail_user_settings *set = user->user_set; struct restrict_access_settings rset; uid_t current_euid, setuid_uid = 0; const char *cur_chroot, *error; @@ -362,43 +482,17 @@ current_euid = geteuid(); restrict_access_init(&rset); restrict_access_get_env(&rset); - if (*set->mail_uid != '\0') { - if (!parse_uid(set->mail_uid, &rset.uid, &error)) { - *error_r = t_strdup_printf("%s (from %s)", error, - user->uid_source); - return -1; - } - if (rset.uid < (uid_t)set->first_valid_uid || - (set->last_valid_uid != 0 && - rset.uid > (uid_t)set->last_valid_uid)) { - *error_r = t_strdup_printf( - "Mail access for users with UID %s not permitted " - "(see first_valid_uid in config file, uid from %s).", - dec2str(rset.uid), user->uid_source); - return -1; - } - rset.uid_source = user->uid_source; + if (priv->uid != (uid_t)-1) { + rset.uid = priv->uid; + rset.uid_source = priv->uid_source; } else if (rset.uid == (uid_t)-1 && - disallow_root && current_euid == 0) { + disallow_root && current_euid == 0) { *error_r = "User is missing UID (see mail_uid setting)"; return -1; } - if (*set->mail_gid != '\0') { - if (!parse_gid(set->mail_gid, &rset.gid, &error)) { - *error_r = t_strdup_printf("%s (from %s)", error, - user->gid_source); - return -1; - } - if (rset.gid < (gid_t)set->first_valid_gid || - (set->last_valid_gid != 0 && - rset.gid > (gid_t)set->last_valid_gid)) { - *error_r = t_strdup_printf( - "Mail access for users with GID %s not permitted " - "(see first_valid_gid in config file, gid from %s).", - dec2str(rset.gid), user->gid_source); - return -1; - } - rset.gid_source = user->gid_source; + if (priv->gid != (gid_t)-1) { + rset.gid = priv->gid; + rset.gid_source = priv->gid_source; } else if (rset.gid == (gid_t)-1 && disallow_root && set->first_valid_gid > 0 && getegid() == 0) { *error_r = "User is missing GID (see mail_gid setting)"; @@ -419,7 +513,7 @@ rset.first_valid_gid = set->first_valid_gid; rset.last_valid_gid = set->last_valid_gid; - rset.chroot_dir = *chroot == '\0' ? NULL : chroot; + rset.chroot_dir = *priv->chroot == '\0' ? NULL : priv->chroot; rset.system_groups_user = user->system_groups_user; cur_chroot = restrict_access_get_current_chroot(); @@ -433,7 +527,7 @@ if (strcmp(rset.chroot_dir, cur_chroot) != 0) { *error_r = t_strdup_printf( "Process is already chrooted to %s, " - "can't chroot to %s", cur_chroot, chroot); + "can't chroot to %s", cur_chroot, priv->chroot); return -1; } /* chrooting to same directory where we're already chrooted */ @@ -460,7 +554,7 @@ disallow_root = FALSE; } if (!setenv_only) { - restrict_access(&rset, *home == '\0' ? NULL : home, + restrict_access(&rset, *priv->home == '\0' ? NULL : priv->home, disallow_root); } else { restrict_access_set_env(&rset); @@ -475,17 +569,21 @@ static int mail_storage_service_init_post(struct mail_storage_service_ctx *ctx, struct mail_storage_service_user *user, - const char *home, struct mail_user **mail_user_r, + struct mail_storage_service_privileges *priv, + struct mail_user **mail_user_r, const char **error_r) { const struct mail_storage_settings *mail_set; + const char *home = priv->home; struct mail_user *mail_user; mail_user = mail_user_alloc(user->input.username, user->user_info, user->user_set); mail_user_set_home(mail_user, *home == '\0' ? NULL : home); - mail_user_set_vars(mail_user, geteuid(), getegid(), ctx->service->name, + mail_user_set_vars(mail_user, ctx->service->name, &user->input.local_ip, &user->input.remote_ip); + mail_user->uid = priv->uid == (uid_t)-1 ? geteuid() : priv->uid; + mail_user->gid = priv->gid == (gid_t)-1 ? getegid() : priv->gid; mail_set = mail_user_set_get_storage_set(mail_user); @@ -528,54 +626,6 @@ return 0; } -static const struct var_expand_table * -get_var_expand_table(struct master_service *service, - struct mail_storage_service_input *input) -{ - static struct var_expand_table static_tab[] = { - { 'u', NULL, "user" }, - { 'n', NULL, "username" }, - { 'd', NULL, "domain" }, - { 's', NULL, "service" }, - { 'l', NULL, "lip" }, - { 'r', NULL, "rip" }, - { 'p', NULL, "pid" }, - { 'i', NULL, "uid" }, - { '\0', NULL, NULL } - }; - struct var_expand_table *tab; - - tab = t_malloc(sizeof(static_tab)); - memcpy(tab, static_tab, sizeof(static_tab)); - - tab[0].value = input->username; - tab[1].value = t_strcut(input->username, '@'); - tab[2].value = strchr(input->username, '@'); - if (tab[2].value != NULL) tab[2].value++; - tab[3].value = service->name; - tab[4].value = net_ip2addr(&input->local_ip); - tab[5].value = net_ip2addr(&input->remote_ip); - tab[6].value = my_pid; - tab[7].value = dec2str(geteuid()); - return tab; -} - -static const char * -user_expand_varstr(struct master_service *service, - struct mail_storage_service_input *input, const char *str) -{ - string_t *ret; - - if (*str == SETTING_STRVAR_EXPANDED[0]) - return str + 1; - - i_assert(*str == SETTING_STRVAR_UNEXPANDED[0]); - - ret = t_str_new(256); - var_expand(ret, str + 1, get_var_expand_table(service, input)); - return str_c(ret); -} - From dovecot at dovecot.org Mon Dec 12 06:48:58 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 12 Dec 2011 06:48:58 +0200 Subject: dovecot-2.1: imap: Convert LIST/LSUB patterns from mUTF-7 to UTF... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/b9fcac239aed changeset: 13849:b9fcac239aed user: Timo Sirainen date: Mon Dec 12 06:48:44 2011 +0200 description: imap: Convert LIST/LSUB patterns from mUTF-7 to UTF-8 for internal representation. diffstat: src/imap/cmd-list.c | 9 ++++++++- 1 files changed, 8 insertions(+), 1 deletions(-) diffs (43 lines): diff -r 9352c4ccb1f9 -r b9fcac239aed src/imap/cmd-list.c --- a/src/imap/cmd-list.c Mon Dec 12 06:36:31 2011 +0200 +++ b/src/imap/cmd-list.c Mon Dec 12 06:48:44 2011 +0200 @@ -889,9 +889,10 @@ struct client *client = cmd->client; const struct imap_arg *args, *list_args; unsigned int arg_count; - struct cmd_list_context *ctx; + struct cmd_list_context *ctx; ARRAY_DEFINE(patterns, const char *) = ARRAY_INIT; const char *pattern, *const *patterns_strarr; + string_t *str; /* [()] |() [RETURN ()] */ @@ -917,6 +918,7 @@ client_send_command_error(cmd, "Invalid reference."); return TRUE; } + str = t_str_new(64); if (imap_arg_get_list_full(&args[1], &list_args, &arg_count)) { ctx->used_listext = TRUE; /* convert pattern list to string array */ @@ -927,7 +929,10 @@ "Invalid pattern list."); return TRUE; } + if (imap_utf7_to_utf8(pattern, str) == 0) + pattern = t_strdup(str_c(str)); array_append(&patterns, &pattern, 1); + str_truncate(str, 0); } args += 2; } else { @@ -935,6 +940,8 @@ client_send_command_error(cmd, "Invalid pattern."); return TRUE; } + if (imap_utf7_to_utf8(pattern, str) == 0) + pattern = str_c(str); p_array_init(&patterns, cmd->pool, 1); array_append(&patterns, &pattern, 1); From dovecot at dovecot.org Mon Dec 12 07:04:57 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 12 Dec 2011 07:04:57 +0200 Subject: dovecot-2.1: auth: Handle proxy_maybe=yes for PASS lookups. (Fix... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/672f2737f596 changeset: 13850:672f2737f596 user: Timo Sirainen date: Mon Dec 12 07:04:46 2011 +0200 description: auth: Handle proxy_maybe=yes for PASS lookups. (Fixes it for LMTP.) diffstat: src/auth/auth-master-connection.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diffs (12 lines): diff -r b9fcac239aed -r 672f2737f596 src/auth/auth-master-connection.c --- a/src/auth/auth-master-connection.c Mon Dec 12 06:48:44 2011 +0200 +++ b/src/auth/auth-master-connection.c Mon Dec 12 07:04:46 2011 +0200 @@ -296,6 +296,8 @@ struct auth_stream_reply *reply = auth_request->extra_fields; string_t *str; + auth_request_proxy_finish(auth_request, result == PASSDB_RESULT_OK); + str = t_str_new(128); switch (result) { case PASSDB_RESULT_OK: From dovecot at dovecot.org Mon Dec 12 08:43:20 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 12 Dec 2011 08:43:20 +0200 Subject: dovecot-2.1: imapc: Removed HIGHESTMODSEQ handling from STATUS c... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/6fb8b5bd2541 changeset: 13851:6fb8b5bd2541 user: Timo Sirainen date: Mon Dec 12 08:43:04 2011 +0200 description: imapc: Removed HIGHESTMODSEQ handling from STATUS command. We don't currently even attempt to handle remote modseqs, so HIGHESTMODSEQ shouldn't be used either. diffstat: src/lib-storage/index/imapc/imapc-storage.c | 4 ---- 1 files changed, 0 insertions(+), 4 deletions(-) diffs (21 lines): diff -r 672f2737f596 -r 6fb8b5bd2541 src/lib-storage/index/imapc/imapc-storage.c --- a/src/lib-storage/index/imapc/imapc-storage.c Mon Dec 12 07:04:46 2011 +0200 +++ b/src/lib-storage/index/imapc/imapc-storage.c Mon Dec 12 08:43:04 2011 +0200 @@ -565,8 +565,6 @@ status->uidvalidity = num; else if (strcasecmp(key, "UNSEEN") == 0) status->unseen = num; - else if (strcasecmp(key, "HIGHESTMODSEQ") == 0) - status->highest_modseq = num; } } @@ -616,8 +614,6 @@ str_append(str, " UIDVALIDITY"); if ((items & STATUS_UNSEEN) != 0) str_append(str, " UNSEEN"); - if ((items & STATUS_HIGHESTMODSEQ) != 0) - str_append(str, " HIGHESTMODSEQ"); if (str_len(str) == 0) { /* nothing requested */ From dovecot at dovecot.org Mon Dec 12 08:44:15 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 12 Dec 2011 08:44:15 +0200 Subject: dovecot-2.1: imapc: Don't crash if we receive tagged BAD reply. Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/6c1080148739 changeset: 13853:6c1080148739 user: Timo Sirainen date: Mon Dec 12 08:36:25 2011 +0200 description: imapc: Don't crash if we receive tagged BAD reply. diffstat: src/lib-imap-client/imapc-connection.c | 8 ++------ 1 files changed, 2 insertions(+), 6 deletions(-) diffs (31 lines): diff -r 8dc4ffcc3b83 -r 6c1080148739 src/lib-imap-client/imapc-connection.c --- a/src/lib-imap-client/imapc-connection.c Mon Dec 12 08:29:50 2011 +0200 +++ b/src/lib-imap-client/imapc-connection.c Mon Dec 12 08:36:25 2011 +0200 @@ -951,12 +951,13 @@ unsigned int i, count; char *line, *linep; const char *p; - struct imap_parser *parser; struct imapc_command_reply reply; line = i_stream_next_line(conn->input); if (line == NULL) return 0; + /* make sure reply texts stays valid if input stream gets freed */ + line = t_strdup_noconst(line); memset(&reply, 0, sizeof(reply)); @@ -1033,12 +1034,7 @@ } imapc_connection_input_reset(conn); - - parser = conn->parser; - imap_parser_ref(parser); imapc_command_reply_free(cmd, &reply); - imap_parser_unref(&parser); - imapc_command_send_more(conn); return 1; } From dovecot at dovecot.org Mon Dec 12 08:44:15 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 12 Dec 2011 08:44:15 +0200 Subject: dovecot-2.1: imap: When fetching X-GUID, set MAIL_FETCH_GUID als... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/8dc4ffcc3b83 changeset: 13852:8dc4ffcc3b83 user: Timo Sirainen date: Mon Dec 12 08:29:50 2011 +0200 description: imap: When fetching X-GUID, set MAIL_FETCH_GUID also as "wanted fields" for optimization. diffstat: src/imap/imap-fetch.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (11 lines): diff -r 6fb8b5bd2541 -r 8dc4ffcc3b83 src/imap/imap-fetch.c --- a/src/imap/imap-fetch.c Mon Dec 12 08:43:04 2011 +0200 +++ b/src/imap/imap-fetch.c Mon Dec 12 08:29:50 2011 +0200 @@ -774,6 +774,7 @@ fetch_guid_init(struct imap_fetch_context *ctx ATTR_UNUSED, const char *name, const struct imap_arg **args ATTR_UNUSED) { + ctx->fetch_data |= MAIL_FETCH_GUID; imap_fetch_add_handler(ctx, TRUE, FALSE, name, "", fetch_guid, NULL); return TRUE; } From dovecot at dovecot.org Mon Dec 12 08:44:15 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 12 Dec 2011 08:44:15 +0200 Subject: dovecot-2.1: imapc: Added X-GM-EXT-1 and CONDSTORE to capabilities. Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/31810fed489d changeset: 13854:31810fed489d user: Timo Sirainen date: Mon Dec 12 08:41:50 2011 +0200 description: imapc: Added X-GM-EXT-1 and CONDSTORE to capabilities. diffstat: src/lib-imap-client/imapc-client.c | 2 ++ src/lib-imap-client/imapc-client.h | 2 ++ 2 files changed, 4 insertions(+), 0 deletions(-) diffs (24 lines): diff -r 6c1080148739 -r 31810fed489d src/lib-imap-client/imapc-client.c --- a/src/lib-imap-client/imapc-client.c Mon Dec 12 08:36:25 2011 +0200 +++ b/src/lib-imap-client/imapc-client.c Mon Dec 12 08:41:50 2011 +0200 @@ -20,6 +20,8 @@ { "UIDPLUS", IMAPC_CAPABILITY_UIDPLUS }, { "AUTH=PLAIN", IMAPC_CAPABILITY_AUTH_PLAIN }, { "STARTTLS", IMAPC_CAPABILITY_STARTTLS }, + { "X-GM-EXT-1", IMAPC_CAPABILITY_X_GM_EXT_1 }, + { "CONDSTORE", IMAPC_CAPABILITY_CONDSTORE }, { "IMAP4REV1", IMAPC_CAPABILITY_IMAP4REV1 }, { NULL, 0 } diff -r 6c1080148739 -r 31810fed489d src/lib-imap-client/imapc-client.h --- a/src/lib-imap-client/imapc-client.h Mon Dec 12 08:36:25 2011 +0200 +++ b/src/lib-imap-client/imapc-client.h Mon Dec 12 08:41:50 2011 +0200 @@ -16,6 +16,8 @@ IMAPC_CAPABILITY_UIDPLUS = 0x10, IMAPC_CAPABILITY_AUTH_PLAIN = 0x20, IMAPC_CAPABILITY_STARTTLS = 0x40, + IMAPC_CAPABILITY_X_GM_EXT_1 = 0x80, + IMAPC_CAPABILITY_CONDSTORE = 0x100, IMAPC_CAPABILITY_IMAP4REV1 = 0x40000000 }; From dovecot at dovecot.org Mon Dec 12 08:45:44 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 12 Dec 2011 08:45:44 +0200 Subject: dovecot-2.1: imapc: Added support for fetching GUID from remote ... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/0bdbb8d99492 changeset: 13855:0bdbb8d99492 user: Timo Sirainen date: Mon Dec 12 08:45:32 2011 +0200 description: imapc: Added support for fetching GUID from remote server, if supported. Currently this is only done for GMail. diffstat: src/lib-storage/index/imapc/imapc-mail-fetch.c | 34 +++++++++++++++- src/lib-storage/index/imapc/imapc-mail.c | 51 +++++++++++++++++++++++++- src/lib-storage/index/imapc/imapc-storage.c | 16 ++++++++ src/lib-storage/index/imapc/imapc-storage.h | 2 + 4 files changed, 99 insertions(+), 4 deletions(-) diffs (194 lines): diff -r 31810fed489d -r 0bdbb8d99492 src/lib-storage/index/imapc/imapc-mail-fetch.c --- a/src/lib-storage/index/imapc/imapc-mail-fetch.c Mon Dec 12 08:41:50 2011 +0200 +++ b/src/lib-storage/index/imapc/imapc-mail-fetch.c Mon Dec 12 08:45:32 2011 +0200 @@ -95,6 +95,11 @@ str_printfa(str, "UID FETCH %u (", _mail->uid); if ((fields & MAIL_FETCH_RECEIVED_DATE) != 0) str_append(str, "INTERNALDATE "); + if ((fields & MAIL_FETCH_GUID) != 0) { + str_append(str, mbox->guid_fetch_field_name); + str_append_c(str, ' '); + } + if ((fields & MAIL_FETCH_STREAM_BODY) != 0) str_append(str, "BODY.PEEK[] "); else if ((fields & MAIL_FETCH_STREAM_HEADER) != 0) @@ -152,6 +157,9 @@ if ((data->wanted_fields & MAIL_FETCH_RECEIVED_DATE) != 0 && data->received_date == (time_t)-1) fields |= MAIL_FETCH_RECEIVED_DATE; + if ((data->wanted_fields & MAIL_FETCH_GUID) != 0 && + data->guid == NULL && mbox->guid_fetch_field_name != NULL) + fields |= MAIL_FETCH_GUID; if (data->stream == NULL && data->access_part != 0) { if ((data->access_part & (READ_BODY | PARSE_BODY)) != 0) @@ -173,6 +181,11 @@ return FALSE; fields &= ~MAIL_FETCH_RECEIVED_DATE; } + if ((fields & MAIL_FETCH_GUID) != 0) { + if (imail->imail.data.guid == NULL) + return FALSE; + fields &= ~MAIL_FETCH_GUID; + } if ((fields & (MAIL_FETCH_STREAM_HEADER | MAIL_FETCH_STREAM_BODY)) != 0) { if (imail->imail.data.stream == NULL) @@ -186,10 +199,18 @@ int imapc_mail_fetch(struct mail *_mail, enum mail_fetch_field fields) { struct imapc_mail *imail = (struct imapc_mail *)_mail; - struct imapc_storage *storage = - (struct imapc_storage *)_mail->box->storage; + struct imapc_mailbox *mbox = + (struct imapc_mailbox *)_mail->box; int ret; + if ((fields & MAIL_FETCH_GUID) != 0 && + mbox->guid_fetch_field_name == NULL) { + mail_storage_set_error(_mail->box->storage, + MAIL_ERROR_NOTPOSSIBLE, + "Message GUID not available in this server"); + return -1; + } + T_BEGIN { ret = imapc_mail_send_fetch(_mail, fields); } T_END; @@ -200,7 +221,7 @@ or until all FETCH replies have been received (i.e. some FETCHes failed) */ while (!imapc_mail_have_fields(imail, fields) && imail->fetch_count > 0) - imapc_storage_run(storage); + imapc_storage_run(mbox->storage); return 0; } @@ -356,6 +377,13 @@ imap_parse_datetime(value, &t, &tz)) mail->imail.data.received_date = t; match = TRUE; + } else if (strcasecmp(key, "X-GM-MSGID") == 0 || + strcasecmp(key, "X-GUID") == 0) { + if (imap_arg_get_astring(&args[i+1], &value)) { + mail->imail.data.guid = + p_strdup(mail->imail.mail.pool, value); + } + match = TRUE; } } if (!match) { diff -r 31810fed489d -r 0bdbb8d99492 src/lib-storage/index/imapc/imapc-mail.c --- a/src/lib-storage/index/imapc/imapc-mail.c Mon Dec 12 08:41:50 2011 +0200 +++ b/src/lib-storage/index/imapc/imapc-mail.c Mon Dec 12 08:45:32 2011 +0200 @@ -267,6 +267,55 @@ buffer_free(&mail->body); } +static int imapc_mail_get_guid(struct mail *_mail, const char **value_r) +{ + struct index_mail *imail = (struct index_mail *)_mail; + struct imapc_mailbox *mbox = (struct imapc_mailbox *)_mail->box; + const enum index_cache_field cache_idx = + imail->ibox->cache_fields[MAIL_CACHE_GUID].idx; + string_t *str; + + if (imail->data.guid != NULL) { + *value_r = imail->data.guid; + return 0; + } + + str = str_new(imail->data_pool, 64); + if (mail_cache_lookup_field(_mail->transaction->cache_view, + str, imail->mail.mail.seq, cache_idx) > 0) { + *value_r = str_c(str); + return 0; + } + + /* GUID not in cache, fetch it */ + if (imapc_mail_fetch(_mail, MAIL_FETCH_GUID) < 0) + return -1; + if (imail->data.guid == NULL) { + imapc_mail_failed(_mail, mbox->guid_fetch_field_name); + return -1; + } + + index_mail_cache_add_idx(imail, cache_idx, + imail->data.guid, strlen(imail->data.guid)+1); + *value_r = imail->data.guid; + return 0; +} + +static int +imapc_mail_get_special(struct mail *_mail, enum mail_fetch_field field, + const char **value_r) +{ + switch (field) { + case MAIL_FETCH_GUID: + *value_r = ""; + return imapc_mail_get_guid(_mail, value_r); + default: + break; + } + + return index_mail_get_special(_mail, field, value_r); +} + struct mail_vfuncs imapc_mail_vfuncs = { imapc_mail_close, index_mail_free, @@ -291,7 +340,7 @@ index_mail_get_headers, index_mail_get_header_stream, imapc_mail_get_stream, - index_mail_get_special, + imapc_mail_get_special, index_mail_get_real_mail, index_mail_update_flags, index_mail_update_keywords, diff -r 31810fed489d -r 0bdbb8d99492 src/lib-storage/index/imapc/imapc-storage.c --- a/src/lib-storage/index/imapc/imapc-storage.c Mon Dec 12 08:41:50 2011 +0200 +++ b/src/lib-storage/index/imapc/imapc-storage.c Mon Dec 12 08:45:32 2011 +0200 @@ -410,6 +410,20 @@ imapc_client_stop(ctx->mbox->storage->client); } +static void imapc_mailbox_get_extensions(struct imapc_mailbox *mbox) +{ + enum imapc_capability capa = + imapc_client_get_capabilities(mbox->storage->client); + + if (mbox->guid_fetch_field_name == NULL) { + /* see if we can get message GUIDs somehow */ + if ((capa & IMAPC_CAPABILITY_X_GM_EXT_1) != 0) { + /* GMail */ + mbox->guid_fetch_field_name = "X-GM-MSGID"; + } + } +} + int imapc_mailbox_select(struct imapc_mailbox *mbox) { struct imapc_command *cmd; @@ -422,6 +436,8 @@ imapc_client_mailbox_set_reopen_cb(mbox->client_box, imapc_mailbox_reopen, mbox); + imapc_mailbox_get_extensions(mbox); + mbox->selecting = TRUE; ctx.mbox = mbox; ctx.ret = -2; diff -r 31810fed489d -r 0bdbb8d99492 src/lib-storage/index/imapc/imapc-storage.h --- a/src/lib-storage/index/imapc/imapc-storage.h Mon Dec 12 08:41:50 2011 +0200 +++ b/src/lib-storage/index/imapc/imapc-storage.h Mon Dec 12 08:45:32 2011 +0200 @@ -83,6 +83,8 @@ uint32_t prev_skipped_rseq, prev_skipped_uid; struct imapc_sync_context *sync_ctx; + const char *guid_fetch_field_name; + unsigned int selecting:1; unsigned int syncing:1; unsigned int initial_sync_done:1; From pigeonhole at rename-it.nl Mon Dec 12 10:01:58 2011 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Mon, 12 Dec 2011 09:01:58 +0100 Subject: dovecot-2.1-pigeonhole: Updated man pages with recent extension ... Message-ID: details: http://hg.rename-it.nl/dovecot-2.1-pigeonhole/rev/8fe82c5f0185 changeset: 1576:8fe82c5f0185 user: Stephan Bosch date: Mon Dec 12 09:01:53 2011 +0100 description: Updated man pages with recent extension configuration changes. diffstat: doc/man/sieve-dump.1.in | 21 ++++++++++++--------- doc/man/sieve-filter.1.in | 20 +++++++++++--------- doc/man/sieve-test.1.in | 21 ++++++++++++--------- doc/man/sievec.1.in | 19 +++++++++++-------- 4 files changed, 46 insertions(+), 35 deletions(-) diffs (150 lines): diff -r b5a2419f0dee -r 8fe82c5f0185 doc/man/sieve-dump.1.in --- a/doc/man/sieve-dump.1.in Mon Dec 12 00:49:22 2011 +0100 +++ b/doc/man/sieve-dump.1.in Mon Dec 12 09:01:53 2011 +0100 @@ -1,5 +1,5 @@ .\" Copyright (c) 2010-2011 Pigeonhole authors, see the included COPYING file -.TH "SIEVE\-DUMP" 1 "2011-11-19" "Pigeonhole for Dovecot v2.1" "Pigeonhole" +.TH "SIEVE\-DUMP" 1 "2011-12-12" "Pigeonhole for Dovecot v2.1" "Pigeonhole" .\"------------------------------------------------------------------------ .SH NAME sieve\-dump \- Pigeonhole\(aqs Sieve script binary dump tool @@ -47,16 +47,19 @@ .BI \-x\ extensions Set the available extensions. The parameter is a space\-separated list of the active extensions. By prepending the extension identifiers with \fB+\fP or -\fB\-\fP, extensions can be included or excluded relative to the default set of -extensions. If no extensions have a \fB+\fP or \fB\-\fP prefix, only those -extensions that are explicitly listed will be enabled. Unknown extensions are -ignored and a warning is produced. By default, all supported extensions are -available, except for deprecated extensions or those that are still under -development. +\fB\-\fP, extensions can be included or excluded relative to the configured set +of active extensions. If no extensions have a \fB+\fP or \fB\-\fP prefix, only +those extensions that are explicitly listed will be enabled. Unknown extensions +are ignored and a warning is produced. For example \fB\-x\fP \(dq+imapflags \-enotify\(dq will enable the deprecated -imapflags extension along with all extensions that are available by default, -except for the enotify extension. +imapflags extension and disable the enotify extension. The rest of the active +extensions depends on the \fIsieve_extensions\fP and +\fIsieve_global_extensions\fP settings. By default, i.e. +when \fIsieve_extensions\fP and \fIsieve_global_extensions\fP remain +unconfigured, all supported extensions are available, except for deprecated +extensions or those that are still under development. + .\"------------------------------------------------------------------------ .SH ARGUMENTS .TP diff -r b5a2419f0dee -r 8fe82c5f0185 doc/man/sieve-filter.1.in --- a/doc/man/sieve-filter.1.in Mon Dec 12 00:49:22 2011 +0100 +++ b/doc/man/sieve-filter.1.in Mon Dec 12 09:01:53 2011 +0100 @@ -1,5 +1,5 @@ .\" Copyright (c) 2010-2011 Pigeonhole authors, see the included COPYING file -.TH "SIEVE\-FILTER" 1 "2011-11-19" "Pigeonhole for Dovecot v2.1" "Pigeonhole" +.TH "SIEVE\-FILTER" 1 "2011-12-12" "Pigeonhole for Dovecot v2.1" "Pigeonhole" .SH NAME sieve\-filter \- Pigeonhole\(aqs Sieve mailbox filter tool @@ -125,16 +125,18 @@ .BI \-x\ extensions Set the available extensions. The parameter is a space\-separated list of the active extensions. By prepending the extension identifiers with \fB+\fP or -\fB\-\fP, extensions can be included or excluded relative to the default set of -extensions. If no extensions have a \fB+\fP or \fB\-\fP prefix, only those -extensions that are explicitly listed will be enabled. Unknown extensions are -ignored and a warning is produced. By default, all supported extensions are -available, except for deprecated extensions or those that are still under -development. +\fB\-\fP, extensions can be included or excluded relative to the configured set +of active extensions. If no extensions have a \fB+\fP or \fB\-\fP prefix, only +those extensions that are explicitly listed will be enabled. Unknown extensions +are ignored and a warning is produced. For example \fB\-x\fP \(dq+imapflags \-enotify\(dq will enable the deprecated -imapflags extension along with all extensions that are available by default, -except for the enotify extension. +imapflags extension and disable the enotify extension. The rest of the active +extensions depends on the \fIsieve_extensions\fP and +\fIsieve_global_extensions\fP settings. By default, i.e. +when \fIsieve_extensions\fP and \fIsieve_global_extensions\fP remain +unconfigured, all supported extensions are available, except for deprecated +extensions or those that are still under development. .\"------------------------------------------------------------------------ .SH ARGUMENTS diff -r b5a2419f0dee -r 8fe82c5f0185 doc/man/sieve-test.1.in --- a/doc/man/sieve-test.1.in Mon Dec 12 00:49:22 2011 +0100 +++ b/doc/man/sieve-test.1.in Mon Dec 12 09:01:53 2011 +0100 @@ -1,5 +1,5 @@ .\" Copyright (c) 2010-2011 Pigeonhole authors, see the included COPYING file -.TH "SIEVE\-TEST" 1 "2011-11-19" "Pigeonhole for Dovecot v2.1" "Pigeonhole" +.TH "SIEVE\-TEST" 1 "2011-12-12" "Pigeonhole for Dovecot v2.1" "Pigeonhole" .SH NAME sieve\-test \- Pigeonhole\(aqs Sieve script tester .\"------------------------------------------------------------------------ @@ -112,16 +112,19 @@ .BI \-x\ extensions Set the available extensions. The parameter is a space\-separated list of the active extensions. By prepending the extension identifiers with \fB+\fP or -\fB\-\fP, extensions can be included or excluded relative to the default set of -extensions. If no extensions have a \fB+\fP or \fB\-\fP prefix, only those -extensions that are explicitly listed will be enabled. Unknown extensions are -ignored and a warning is produced. By default, all supported extensions are -available, except for deprecated extensions or those that are still under -development. +\fB\-\fP, extensions can be included or excluded relative to the configured set +of active extensions. If no extensions have a \fB+\fP or \fB\-\fP prefix, only +those extensions that are explicitly listed will be enabled. Unknown extensions +are ignored and a warning is produced. For example \fB\-x\fP \(dq+imapflags \-enotify\(dq will enable the deprecated -imapflags extension along with all extensions that are available by default, -except for the enotify extension. +imapflags extension and disable the enotify extension. The rest of the active +extensions depends on the \fIsieve_extensions\fP and +\fIsieve_global_extensions\fP settings. By default, i.e. +when \fIsieve_extensions\fP and \fIsieve_global_extensions\fP remain +unconfigured, all supported extensions are available, except for deprecated +extensions or those that are still under development. + .\"------------------------------------------------------------------------ .SH ARGUMENTS .TP diff -r b5a2419f0dee -r 8fe82c5f0185 doc/man/sievec.1.in --- a/doc/man/sievec.1.in Mon Dec 12 00:49:22 2011 +0100 +++ b/doc/man/sievec.1.in Mon Dec 12 09:01:53 2011 +0100 @@ -1,5 +1,5 @@ .\" Copyright (c) 2010-2011 Pigeonhole authors, see the included COPYING file -.TH "SIEVEC" 1 "2011-11-19" "Pigeonhole for Dovecot v2.1" "Pigeonhole" +.TH "SIEVEC" 1 "2011-12-12" "Pigeonhole for Dovecot v2.1" "Pigeonhole" .\"------------------------------------------------------------------------ .SH NAME sievec \- Pigeonhole\(aqs Sieve script compiler @@ -60,16 +60,19 @@ .BI \-x\ extensions Set the available extensions. The parameter is a space\-separated list of the active extensions. By prepending the extension identifiers with \fB+\fP or -\fB\-\fP, extensions can be included or excluded relative to the default set of -extensions. If no extensions have a \fB+\fP or \fB\-\fP prefix, only +\fB\-\fP, extensions can be included or excluded relative to the configured set +of active extensions. If no extensions have a \fB+\fP or \fB\-\fP prefix, only those extensions that are explicitly listed will be enabled. Unknown extensions -are ignored and a warning is produced. By default, all supported extensions are -available, except for deprecated extensions or those that are still under -development. +are ignored and a warning is produced. For example \fB\-x\fP \(dq+imapflags \-enotify\(dq will enable the deprecated -imapflags extension along with all extensions that are available by default, -except for the enotify extension. +imapflags extension and disable the enotify extension. The rest of the active +extensions depends on the \fIsieve_extensions\fP and +\fIsieve_global_extensions\fP settings. By default, i.e. +when \fIsieve_extensions\fP and \fIsieve_global_extensions\fP remain +unconfigured, all supported extensions are available, except for deprecated +extensions or those that are still under development. + .\"------------------------------------------------------------------------ .SH ARGUMENTS .TP From pigeonhole at rename-it.nl Mon Dec 12 22:28:04 2011 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Mon, 12 Dec 2011 21:28:04 +0100 Subject: dovecot-2.1-pigeonhole: lib-sieve: store action: copy flags and ... Message-ID: details: http://hg.rename-it.nl/dovecot-2.1-pigeonhole/rev/a2d645ca6e32 changeset: 1577:a2d645ca6e32 user: Stephan Bosch date: Mon Dec 12 21:27:59 2011 +0100 description: lib-sieve: store action: copy flags and keywords from input mail, also when imap4flags extension is not active. This is currently only relevant for sieve-filter, which now properly preserves flags with this change. diffstat: src/lib-sieve/sieve-actions.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diffs (12 lines): diff -r 8fe82c5f0185 -r a2d645ca6e32 src/lib-sieve/sieve-actions.c --- a/src/lib-sieve/sieve-actions.c Mon Dec 12 09:01:53 2011 +0100 +++ b/src/lib-sieve/sieve-actions.c Mon Dec 12 21:27:59 2011 +0100 @@ -529,6 +529,8 @@ keywords = act_store_keywords_create(aenv, &trans->keywords, trans->box); mailbox_save_set_flags(save_ctx, trans->flags, keywords); + } else { + mailbox_save_copy_flags(save_ctx, mail); } if ( mailbox_copy(&save_ctx, mail) < 0 ) { From dovecot at dovecot.org Wed Dec 14 10:56:06 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 14 Dec 2011 10:56:06 +0200 Subject: dovecot-2.1: auth: Don't die if passwd-file can't open the file. Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/e7ec5649655a changeset: 13856:e7ec5649655a user: Timo Sirainen date: Wed Dec 14 10:55:11 2011 +0200 description: auth: Don't die if passwd-file can't open the file. The file is parsed after we already sent "we're ok" reply to master, so dying triggers infinite restarts. diffstat: src/auth/db-passwd-file.c | 3 +-- 1 files changed, 1 insertions(+), 2 deletions(-) diffs (13 lines): diff -r 0bdbb8d99492 -r e7ec5649655a src/auth/db-passwd-file.c --- a/src/auth/db-passwd-file.c Mon Dec 12 08:45:32 2011 +0200 +++ b/src/auth/db-passwd-file.c Wed Dec 14 10:55:11 2011 +0200 @@ -334,8 +334,7 @@ { if (db->default_file != NULL && db->default_file->stamp == 0) { /* no variables, open the file immediately */ - if (!passwd_file_open(db->default_file)) - exit(FATAL_DEFAULT); + (void)passwd_file_open(db->default_file); } } From dovecot at dovecot.org Wed Dec 14 11:58:11 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 14 Dec 2011 11:58:11 +0200 Subject: dovecot-2.1: imapc: Handle missing BODY[] reply by returning an ... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/69f388aa7ce9 changeset: 13857:69f388aa7ce9 user: Timo Sirainen date: Wed Dec 14 11:57:20 2011 +0200 description: imapc: Handle missing BODY[] reply by returning an empty mail instead of disconnecting. diffstat: src/lib-storage/index/imapc/imapc-mail.c | 10 +++++++++- 1 files changed, 9 insertions(+), 1 deletions(-) diffs (20 lines): diff -r e7ec5649655a -r 69f388aa7ce9 src/lib-storage/index/imapc/imapc-mail.c --- a/src/lib-storage/index/imapc/imapc-mail.c Wed Dec 14 10:55:11 2011 +0200 +++ b/src/lib-storage/index/imapc/imapc-mail.c Wed Dec 14 11:57:20 2011 +0200 @@ -157,7 +157,15 @@ if (data->stream == NULL) { imapc_mail_failed(_mail, "BODY[]"); - return -1; + /* this could be either a temporary server bug, or the + server may permanently just not return anything for + this mail. the latter happens at least with Exchange + when trying to fetch calendar "mails", so we'll just + return them as empty mails instead of disconnecting + the client. */ + mail->body_fetched = TRUE; + data->stream = i_stream_create_from_data(NULL, 0); + imapc_mail_init_stream(mail, TRUE); } } From dovecot at dovecot.org Wed Dec 14 12:34:45 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 14 Dec 2011 12:34:45 +0200 Subject: dovecot-2.1: imapc: Handle missing INTERNALDATE reply by returni... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/20ccdd42c14a changeset: 13858:20ccdd42c14a user: Timo Sirainen date: Wed Dec 14 12:33:59 2011 +0200 description: imapc: Handle missing INTERNALDATE reply by returning an empty mail instead of disconnecting. diffstat: src/lib-storage/index/imapc/imapc-mail.c | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diffs (14 lines): diff -r 69f388aa7ce9 -r 20ccdd42c14a src/lib-storage/index/imapc/imapc-mail.c --- a/src/lib-storage/index/imapc/imapc-mail.c Wed Dec 14 11:57:20 2011 +0200 +++ b/src/lib-storage/index/imapc/imapc-mail.c Wed Dec 14 12:33:59 2011 +0200 @@ -79,7 +79,9 @@ return -1; if (data->received_date == (time_t)-1) { imapc_mail_failed(_mail, "INTERNALDATE"); - return -1; + /* assume that the server never returns INTERNALDATE + for this mail (see BODY[] failure handling) */ + data->received_date = 0; } } *date_r = data->received_date; From dovecot at dovecot.org Wed Dec 14 12:58:57 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 14 Dec 2011 12:58:57 +0200 Subject: dovecot-2.1: imapc: Fixed missing BODY[]/INTERNALDATE to handle ... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/96ce297561a0 changeset: 13859:96ce297561a0 user: Timo Sirainen date: Wed Dec 14 12:57:55 2011 +0200 description: imapc: Fixed missing BODY[]/INTERNALDATE to handle actual failures again. diffstat: src/lib-storage/index/imapc/imapc-mail.c | 19 +++++++++++++------ 1 files changed, 13 insertions(+), 6 deletions(-) diffs (60 lines): diff -r 20ccdd42c14a -r 96ce297561a0 src/lib-storage/index/imapc/imapc-mail.c --- a/src/lib-storage/index/imapc/imapc-mail.c Wed Dec 14 12:33:59 2011 +0200 +++ b/src/lib-storage/index/imapc/imapc-mail.c Wed Dec 14 12:57:55 2011 +0200 @@ -50,19 +50,22 @@ return !imapc_msgmap_uid_to_rseq(msgmap, _mail->uid, &rseq); } -static void imapc_mail_failed(struct mail *mail, const char *field) +static int imapc_mail_failed(struct mail *mail, const char *field) { struct imapc_mailbox *mbox = (struct imapc_mailbox *)mail->box; - if (mail->expunged || imapc_mail_is_expunged(mail)) + if (mail->expunged || imapc_mail_is_expunged(mail)) { mail_set_expunged(mail); - else if (!imapc_client_mailbox_is_opened(mbox->client_box)) { + return -1; + } else if (!imapc_client_mailbox_is_opened(mbox->client_box)) { /* we've already logged a disconnection error */ mail_storage_set_internal_error(mail->box->storage); + return -1; } else { mail_storage_set_critical(mail->box->storage, "imapc: Remote server didn't send %s for UID %u in %s", field, mail->uid, mail->box->vname); + return 0; } } @@ -78,7 +81,8 @@ if (imapc_mail_fetch(_mail, MAIL_FETCH_RECEIVED_DATE) < 0) return -1; if (data->received_date == (time_t)-1) { - imapc_mail_failed(_mail, "INTERNALDATE"); + if (imapc_mail_failed(_mail, "INTERNALDATE") < 0) + return -1; /* assume that the server never returns INTERNALDATE for this mail (see BODY[] failure handling) */ data->received_date = 0; @@ -158,7 +162,10 @@ return -1; if (data->stream == NULL) { - imapc_mail_failed(_mail, "BODY[]"); + if (imapc_mail_failed(_mail, "BODY[]") < 0) + return -1; + i_assert(data->stream == NULL); + /* this could be either a temporary server bug, or the server may permanently just not return anything for this mail. the latter happens at least with Exchange @@ -301,7 +308,7 @@ if (imapc_mail_fetch(_mail, MAIL_FETCH_GUID) < 0) return -1; if (imail->data.guid == NULL) { - imapc_mail_failed(_mail, mbox->guid_fetch_field_name); + (void)imapc_mail_failed(_mail, mbox->guid_fetch_field_name); return -1; } From dovecot at dovecot.org Wed Dec 14 13:00:49 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 14 Dec 2011 13:00:49 +0200 Subject: dovecot-2.1: imapc: Avoid assert-crashing when replacing mail st... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/efb48f4e40a6 changeset: 13860:efb48f4e40a6 user: Timo Sirainen date: Wed Dec 14 13:00:05 2011 +0200 description: imapc: Avoid assert-crashing when replacing mail stream with a new one. diffstat: src/lib-storage/index/imapc/imapc-mail-fetch.c | 8 ++++---- src/lib-storage/index/index-mail.c | 24 +++++++++++++++++++++--- 2 files changed, 25 insertions(+), 7 deletions(-) diffs (92 lines): diff -r 96ce297561a0 -r efb48f4e40a6 src/lib-storage/index/imapc/imapc-mail-fetch.c --- a/src/lib-storage/index/imapc/imapc-mail-fetch.c Wed Dec 14 12:57:55 2011 +0200 +++ b/src/lib-storage/index/imapc/imapc-mail-fetch.c Wed Dec 14 13:00:05 2011 +0200 @@ -277,13 +277,13 @@ if (imail->mail.v.istream_opened != NULL) { if (imail->mail.v.istream_opened(_mail, &imail->data.stream) < 0) { - i_stream_unref(&imail->data.stream); + index_mail_close_streams(imail); return; } } else if (have_body) { ret = i_stream_get_size(imail->data.stream, TRUE, &size); if (ret < 0) { - i_stream_unref(&imail->data.stream); + index_mail_close_streams(imail); return; } i_assert(ret != 0); @@ -295,7 +295,7 @@ imail->data.stream_has_only_header = !have_body; if (index_mail_init_stream(imail, NULL, NULL, &input) < 0) - i_stream_unref(&imail->data.stream); + index_mail_close_streams(imail); } static void @@ -311,7 +311,7 @@ if (!body) return; /* maybe the existing stream has no body. replace it. */ - i_stream_unref(&imail->data.stream); + index_mail_close_streams(imail); if (mail->fd != -1) { if (close(mail->fd) < 0) i_error("close(imapc mail) failed: %m"); diff -r 96ce297561a0 -r efb48f4e40a6 src/lib-storage/index/index-mail.c --- a/src/lib-storage/index/index-mail.c Wed Dec 14 12:57:55 2011 +0200 +++ b/src/lib-storage/index/index-mail.c Wed Dec 14 13:00:05 2011 +0200 @@ -1137,7 +1137,7 @@ } } -void index_mail_close_streams(struct index_mail *mail) +static void index_mail_close_streams_full(struct index_mail *mail, bool closing) { struct index_mail_data *data = &mail->data; struct message_part *parts; @@ -1152,14 +1152,31 @@ i_stream_unref(&data->filter_stream); if (data->stream != NULL) { data->destroying_stream = TRUE; + if (!closing) { + /* we're replacing the stream with a new one. it's + allowed to have references until the mail is closed + (but we can't really check that) */ + i_stream_unset_destroy_callback(data->stream); + } i_stream_unref(&data->stream); - i_assert(!data->destroying_stream); + if (closing) { + /* there must be no references to the mail when the + mail is being closed. */ + i_assert(!mail->data.destroying_stream); + } else { + data->destroying_stream = FALSE; + } data->initialized_wrapper_stream = FALSE; data->destroy_callback_set = FALSE; } } +void index_mail_close_streams(struct index_mail *mail) +{ + index_mail_close_streams_full(mail, FALSE); +} + void index_mail_close(struct mail *_mail) { struct index_mail *mail = (struct index_mail *)_mail; @@ -1174,7 +1191,8 @@ index_mail_cache_dates(mail); } - index_mail_close_streams(mail); + index_mail_close_streams_full(mail, TRUE); + if (mail->data.wanted_headers != NULL) mailbox_header_lookup_unref(&mail->data.wanted_headers); } From dovecot at dovecot.org Wed Dec 14 13:51:36 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 14 Dec 2011 13:51:36 +0200 Subject: dovecot-2.1: Added i_stream_unset_destroy_callback() Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/46a1f211ef84 changeset: 13861:46a1f211ef84 user: Timo Sirainen date: Wed Dec 14 13:50:43 2011 +0200 description: Added i_stream_unset_destroy_callback() diffstat: src/lib/istream.c | 8 ++++++++ src/lib/istream.h | 2 ++ 2 files changed, 10 insertions(+), 0 deletions(-) diffs (30 lines): diff -r efb48f4e40a6 -r 46a1f211ef84 src/lib/istream.c --- a/src/lib/istream.c Wed Dec 14 13:00:05 2011 +0200 +++ b/src/lib/istream.c Wed Dec 14 13:50:43 2011 +0200 @@ -54,6 +54,14 @@ iostream->destroy_context = context; } +void i_stream_unset_destroy_callback(struct istream *stream) +{ + struct iostream_private *iostream = &stream->real_stream->iostream; + + iostream->destroy_callback = NULL; + iostream->destroy_context = NULL; +} + int i_stream_get_fd(struct istream *stream) { struct istream_private *_stream = stream->real_stream; diff -r efb48f4e40a6 -r 46a1f211ef84 src/lib/istream.h --- a/src/lib/istream.h Wed Dec 14 13:00:05 2011 +0200 +++ b/src/lib/istream.h Wed Dec 14 13:50:43 2011 +0200 @@ -54,6 +54,8 @@ #define i_stream_set_destroy_callback(stream, callback, context) \ CONTEXT_CALLBACK(i_stream_set_destroy_callback, istream_callback_t, \ callback, context, stream) +/* Remove the destroy callback. */ +void i_stream_unset_destroy_callback(struct istream *stream); /* Return file descriptor for stream, or -1 if none is available. */ int i_stream_get_fd(struct istream *stream); From dovecot at dovecot.org Wed Dec 14 14:29:53 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 14 Dec 2011 14:29:53 +0200 Subject: dovecot-2.1: imapc: Try to avoid crashes on deinit/disconnection. Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/1e8523481d89 changeset: 13862:1e8523481d89 user: Timo Sirainen date: Wed Dec 14 14:29:07 2011 +0200 description: imapc: Try to avoid crashes on deinit/disconnection. diffstat: src/lib-imap-client/imapc-client-private.h | 1 + src/lib-imap-client/imapc-client.c | 8 +++++++- src/lib-imap-client/imapc-connection.c | 9 ++++----- 3 files changed, 12 insertions(+), 6 deletions(-) diffs (89 lines): diff -r 46a1f211ef84 -r 1e8523481d89 src/lib-imap-client/imapc-client-private.h --- a/src/lib-imap-client/imapc-client-private.h Wed Dec 14 13:50:43 2011 +0200 +++ b/src/lib-imap-client/imapc-client-private.h Wed Dec 14 14:29:07 2011 +0200 @@ -36,6 +36,7 @@ bool reconnect_ok; bool reconnecting; + bool closing; }; void imapc_client_ref(struct imapc_client *client); diff -r 46a1f211ef84 -r 1e8523481d89 src/lib-imap-client/imapc-client.c --- a/src/lib-imap-client/imapc-client.c Wed Dec 14 13:50:43 2011 +0200 +++ b/src/lib-imap-client/imapc-client.c Wed Dec 14 14:29:07 2011 +0200 @@ -107,6 +107,7 @@ struct imapc_client_connection **connp; array_foreach_modifiable(&client->conns, connp) { + i_assert(imapc_connection_get_mailbox((*connp)->conn) == NULL); imapc_connection_deinit(&(*connp)->conn); i_free(*connp); } @@ -294,6 +295,8 @@ struct imapc_client_mailbox *box = *_box; struct imapc_client_connection *const *connp; + box->closing = TRUE; + /* cancel any pending commands */ imapc_connection_unselect(box); @@ -324,6 +327,8 @@ { struct imapc_command *cmd; + i_assert(!box->closing); + cmd = imapc_connection_cmd(box->conn, callback, context); imapc_command_set_mailbox(cmd, box); return cmd; @@ -346,7 +351,8 @@ { struct imapc_client_mailbox *selected_box; - if (imapc_connection_get_state(box->conn) != IMAPC_CONNECTION_STATE_DONE) + if (box->closing || + imapc_connection_get_state(box->conn) != IMAPC_CONNECTION_STATE_DONE) return FALSE; selected_box = imapc_connection_get_mailbox(box->conn); diff -r 46a1f211ef84 -r 1e8523481d89 src/lib-imap-client/imapc-connection.c --- a/src/lib-imap-client/imapc-connection.c Wed Dec 14 13:50:43 2011 +0200 +++ b/src/lib-imap-client/imapc-connection.c Wed Dec 14 14:29:07 2011 +0200 @@ -365,14 +365,14 @@ net_disconnect(conn->fd); conn->fd = -1; + imapc_connection_set_state(conn, IMAPC_CONNECTION_STATE_DISCONNECTED); imapc_connection_abort_commands(conn, TRUE, reconnecting); - imapc_connection_set_state(conn, IMAPC_CONNECTION_STATE_DISCONNECTED); } static void imapc_connection_set_disconnected(struct imapc_connection *conn) { + imapc_connection_set_state(conn, IMAPC_CONNECTION_STATE_DISCONNECTED); imapc_connection_abort_commands(conn, TRUE, FALSE); - imapc_connection_set_state(conn, IMAPC_CONNECTION_STATE_DISCONNECTED); } static void imapc_connection_reconnect(struct imapc_connection *conn) @@ -1819,9 +1819,6 @@ { struct imapc_connection *conn = box->conn; - imapc_connection_send_idle_done(conn); - imapc_connection_abort_commands(conn, FALSE, FALSE); - if (conn->selected_box != NULL || conn->selecting_box != NULL) { i_assert(conn->selected_box == box || conn->selecting_box == box); @@ -1829,6 +1826,8 @@ conn->selected_box = NULL; conn->selecting_box = NULL; } + imapc_connection_send_idle_done(conn); + imapc_connection_abort_commands(conn, FALSE, FALSE); } struct imapc_client_mailbox * From dovecot at dovecot.org Thu Dec 15 13:41:14 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 15 Dec 2011 13:41:14 +0200 Subject: dovecot-2.1: imapc: Assert crashfix. Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/d5eaa0c56b1e changeset: 13863:d5eaa0c56b1e user: Timo Sirainen date: Thu Dec 15 13:40:20 2011 +0200 description: imapc: Assert crashfix. diffstat: src/lib-imap-client/imapc-connection.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diffs (12 lines): diff -r 1e8523481d89 -r d5eaa0c56b1e src/lib-imap-client/imapc-connection.c --- a/src/lib-imap-client/imapc-connection.c Wed Dec 14 14:29:07 2011 +0200 +++ b/src/lib-imap-client/imapc-connection.c Thu Dec 15 13:40:20 2011 +0200 @@ -271,6 +271,8 @@ cmd->callback(&reply, cmd->context); imapc_command_free(cmd); } + if (conn->to != NULL) + timeout_remove(&conn->to); } static void From dovecot at dovecot.org Fri Dec 16 12:44:00 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 16 Dec 2011 12:44:00 +0200 Subject: dovecot-2.1: fts: Expunging could have expunged indexed FTS mail... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/01ddcf7cf568 changeset: 13865:01ddcf7cf568 user: Timo Sirainen date: Fri Dec 16 12:43:51 2011 +0200 description: fts: Expunging could have expunged indexed FTS mail from wrong mailbox. diffstat: src/plugins/fts/fts-expunge-log.c | 3 +-- 1 files changed, 1 insertions(+), 2 deletions(-) diffs (13 lines): diff -r 15c3002755de -r 01ddcf7cf568 src/plugins/fts/fts-expunge-log.c --- a/src/plugins/fts/fts-expunge-log.c Fri Dec 16 12:42:21 2011 +0200 +++ b/src/plugins/fts/fts-expunge-log.c Fri Dec 16 12:43:51 2011 +0200 @@ -206,8 +206,7 @@ struct fts_expunge_log_mailbox *mailbox; if (ctx->prev_mailbox != NULL && - memcmp(mailbox_guid, ctx->prev_mailbox->guid, - sizeof(mailbox_guid)) == 0) + memcmp(mailbox_guid, ctx->prev_mailbox->guid, GUID_128_SIZE) == 0) mailbox = ctx->prev_mailbox; else { mailbox = hash_table_lookup(ctx->mailboxes, mailbox_guid); From dovecot at dovecot.org Fri Dec 16 12:44:00 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 16 Dec 2011 12:44:00 +0200 Subject: dovecot-2.1: lib-storage: mailbox_list_get_permissions() didn't ... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/15c3002755de changeset: 13864:15c3002755de user: Timo Sirainen date: Fri Dec 16 12:42:21 2011 +0200 description: lib-storage: mailbox_list_get_permissions() didn't properly erase the full return struct. This shouldn't have caused any bugs currently. diffstat: src/lib-storage/mailbox-list.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r d5eaa0c56b1e -r 15c3002755de src/lib-storage/mailbox-list.c --- a/src/lib-storage/mailbox-list.c Thu Dec 15 13:40:20 2011 +0200 +++ b/src/lib-storage/mailbox-list.c Fri Dec 16 12:42:21 2011 +0200 @@ -612,7 +612,7 @@ const char *path, *parent_name, *p; struct stat st; - memset(permissions_r, 0, sizeof(permissions_r)); + memset(permissions_r, 0, sizeof(*permissions_r)); /* use safe defaults */ permissions_r->file_uid = (uid_t)-1; From dovecot at dovecot.org Fri Dec 16 12:50:58 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 16 Dec 2011 12:50:58 +0200 Subject: dovecot-2.1: --enable-devel-checks: Use -fcatch-undefined-behavi... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/c682a5bf3de7 changeset: 13866:c682a5bf3de7 user: Timo Sirainen date: Fri Dec 16 12:50:53 2011 +0200 description: --enable-devel-checks: Use -fcatch-undefined-behavior -ftrapv with clang. diffstat: configure.in | 7 +++++++ 1 files changed, 7 insertions(+), 0 deletions(-) diffs (24 lines): diff -r 01ddcf7cf568 -r c682a5bf3de7 configure.in --- a/configure.in Fri Dec 16 12:43:51 2011 +0200 +++ b/configure.in Fri Dec 16 12:50:53 2011 +0200 @@ -33,6 +33,7 @@ AS_HELP_STRING([--enable-devel-checks], [Enable some extra expensive checks for developers]), if test x$enableval = xyes; then AC_DEFINE(DEBUG,, Build with extra debugging checks) + want_devel_checks=yes fi) AC_ARG_ENABLE(asserts, @@ -319,6 +320,12 @@ CFLAGS="$old_cflags" ]) fi +if $CC -dM -E -x c /dev/null | grep __clang__ > /dev/null 2>&1; then + # clang specific options + if test "$want_devel_checks" = "yes"; then + CFLAGS="$CFLAGS -fcatch-undefined-behavior -ftrapv" + fi +fi dnl ** dnl ** just some generic stuff... From dovecot at dovecot.org Fri Dec 16 13:08:49 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 16 Dec 2011 13:08:49 +0200 Subject: dovecot-2.1: FS layout: Mark memory pool growing to avoid warnin... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/103ecbf3d5c7 changeset: 13868:103ecbf3d5c7 user: Timo Sirainen date: Fri Dec 16 13:08:49 2011 +0200 description: FS layout: Mark memory pool growing to avoid warnings with devel-checks. diffstat: src/lib-storage/list/mailbox-list-fs-iter.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 6ded89937e98 -r 103ecbf3d5c7 src/lib-storage/list/mailbox-list-fs-iter.c --- a/src/lib-storage/list/mailbox-list-fs-iter.c Fri Dec 16 13:08:18 2011 +0200 +++ b/src/lib-storage/list/mailbox-list-fs-iter.c Fri Dec 16 13:08:49 2011 +0200 @@ -258,7 +258,7 @@ struct list_dir_context *dir; pool_t pool; - pool = pool_alloconly_create("fs iter dir", 256); + pool = pool_alloconly_create(MEMPOOL_GROWING"fs iter dir", 256); dir = p_new(pool, struct list_dir_context, 1); dir->pool = pool; dir->storage_name = p_strdup(pool, storage_name); From dovecot at dovecot.org Fri Dec 16 13:08:49 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 16 Dec 2011 13:08:49 +0200 Subject: dovecot-2.1: FS layout: When deleting a mailbox, don't give an e... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/6ded89937e98 changeset: 13867:6ded89937e98 user: Timo Sirainen date: Fri Dec 16 13:08:18 2011 +0200 description: FS layout: When deleting a mailbox, don't give an error if mailbox has children. The mailbox got successfully deleted, but it still gave an error. diffstat: src/lib-storage/index/index-storage.c | 10 +++++++++- 1 files changed, 9 insertions(+), 1 deletions(-) diffs (27 lines): diff -r c682a5bf3de7 -r 6ded89937e98 src/lib-storage/index/index-storage.c --- a/src/lib-storage/index/index-storage.c Fri Dec 16 12:50:53 2011 +0200 +++ b/src/lib-storage/index/index-storage.c Fri Dec 16 13:08:18 2011 +0200 @@ -511,6 +511,7 @@ { struct mailbox_metadata metadata; struct mailbox_status status; + enum mail_error error; int ret_guid; if (!box->opened) { @@ -564,7 +565,14 @@ MAILBOX_LOG_RECORD_DELETE_MAILBOX, metadata.guid); } - return index_storage_mailbox_delete_dir(box, TRUE); + if (index_storage_mailbox_delete_dir(box, TRUE) < 0) { + (void)mailbox_get_last_error(box, &error); + if (error != MAIL_ERROR_EXISTS) + return -1; + /* we deleted the mailbox, but couldn't delete the directory + because it has children. that's not an error. */ + } + return 0; } int index_storage_mailbox_rename(struct mailbox *src, struct mailbox *dest, From dovecot at dovecot.org Fri Dec 16 13:12:09 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 16 Dec 2011 13:12:09 +0200 Subject: dovecot-2.0: FS layout: When deleting a mailbox, don't give an e... Message-ID: details: http://hg.dovecot.org/dovecot-2.0/rev/4ea24cabfd88 changeset: 13001:4ea24cabfd88 user: Timo Sirainen date: Fri Dec 16 13:12:04 2011 +0200 description: FS layout: When deleting a mailbox, don't give an error if mailbox has children. The mailbox got successfully deleted, but it still gave an error. diffstat: src/lib-storage/index/index-storage.c | 10 +++++++++- 1 files changed, 9 insertions(+), 1 deletions(-) diffs (27 lines): diff -r 75daa638281b -r 4ea24cabfd88 src/lib-storage/index/index-storage.c --- a/src/lib-storage/index/index-storage.c Sat Dec 10 07:57:16 2011 +0200 +++ b/src/lib-storage/index/index-storage.c Fri Dec 16 13:12:04 2011 +0200 @@ -434,6 +434,7 @@ int index_storage_mailbox_delete(struct mailbox *box) { uint8_t mailbox_guid[MAIL_GUID_128_SIZE]; + enum mail_error error; if (!box->opened) { /* \noselect mailbox, try deleting only the directory */ @@ -460,7 +461,14 @@ mailbox_list_add_change(box->list, MAILBOX_LOG_RECORD_DELETE_MAILBOX, mailbox_guid); - return index_storage_mailbox_delete_dir(box, TRUE); + if (index_storage_mailbox_delete_dir(box, TRUE) < 0) { + (void)mail_storage_get_last_error(box->storage, &error); + if (error != MAIL_ERROR_EXISTS) + return -1; + /* we deleted the mailbox, but couldn't delete the directory + because it has children. that's not an error. */ + } + return 0; } int index_storage_mailbox_rename(struct mailbox *src, struct mailbox *dest, From pigeonhole at rename-it.nl Sat Dec 17 00:40:42 2011 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Fri, 16 Dec 2011 23:40:42 +0100 Subject: dovecot-2.1-pigeonhole: lib-sieve: made sure that modified messa... Message-ID: details: http://hg.rename-it.nl/dovecot-2.1-pigeonhole/rev/a8780b39f887 changeset: 1578:a8780b39f887 user: Stephan Bosch date: Fri Dec 16 23:40:34 2011 +0100 description: lib-sieve: made sure that modified messages are not stored in the source mailbox when it was opened read-only. This is currently only relevant for the sieve-filter tool to avoid duplicating messages in the source folder. This can happen when the messages are modified (e.g. by the editheader extension) and the source folder is opened read-only, thus preventing deletion of the original message. diffstat: src/lib-sieve/edit-mail.c | 32 ++++++++++++++++++++------------ src/lib-sieve/sieve-actions.c | 23 +++++++++++++++++++---- 2 files changed, 39 insertions(+), 16 deletions(-) diffs (106 lines): diff -r a2d645ca6e32 -r a8780b39f887 src/lib-sieve/edit-mail.c --- a/src/lib-sieve/edit-mail.c Mon Dec 12 21:27:59 2011 +0100 +++ b/src/lib-sieve/edit-mail.c Fri Dec 16 23:40:34 2011 +0100 @@ -405,6 +405,10 @@ struct mail *edit_mail_get_mail(struct edit_mail *edmail) { + /* Return wrapped mail when nothing is modified yet */ + if ( !edmail->modified ) + return &edmail->wrapped->mail; + return &edmail->mail.mail; } @@ -1337,17 +1341,21 @@ { struct edit_mail *edmail = (struct edit_mail *)mail; - switch (field) { - case MAIL_FETCH_GUID: - /* This is in essence a new message */ - *value_r = ""; - return 0; - case MAIL_FETCH_UIDL_FILE_NAME: - /* Prevent hardlink copying */ - *value_r = ""; - return 0; - default: - break; + if ( edmail->modified ) { + /* Block certain fields when modified */ + + switch (field) { + case MAIL_FETCH_GUID: + /* This is in essence a new message */ + *value_r = ""; + return 0; + case MAIL_FETCH_UIDL_FILE_NAME: + /* Prevent hardlink copying */ + *value_r = ""; + return 0; + default: + break; + } } return edmail->wrapped->v.get_special(&edmail->wrapped->mail, field, value_r); @@ -1357,7 +1365,7 @@ { struct edit_mail *edmail = (struct edit_mail *)mail; - return edmail->wrapped->v.get_real_mail(&edmail->wrapped->mail); + return edit_mail_get_mail(edmail); } static void edit_mail_update_flags diff -r a2d645ca6e32 -r a8780b39f887 src/lib-sieve/sieve-actions.c --- a/src/lib-sieve/sieve-actions.c Mon Dec 12 21:27:59 2011 +0100 +++ b/src/lib-sieve/sieve-actions.c Fri Dec 16 23:40:34 2011 +0100 @@ -467,7 +467,8 @@ struct act_store_transaction *trans = (struct act_store_transaction *) tr_context; struct mail *mail = ( action->mail != NULL ? - action->mail : aenv->msgdata->mail ); + action->mail : aenv->msgdata->mail ); + struct mail *real_mail = mail_get_real_mail(mail); struct mail_save_context *save_ctx; struct mail_keywords *keywords = NULL; bool result = TRUE; @@ -483,12 +484,14 @@ return FALSE; /* If the message originates from the target mailbox, only update the flags - * and keywords + * and keywords (if not read-only) */ - if ( mailbox_backends_equal(trans->box, mail->box) ) { + if ( mailbox_backends_equal(trans->box, mail->box) || + (real_mail != mail && mailbox_backends_equal(trans->box, real_mail->box)) ) + { trans->redundant = TRUE; - if ( trans->flags_altered ) { + if ( trans->flags_altered && !mailbox_is_readonly(mail->box) ) { keywords = act_store_keywords_create (aenv, &trans->keywords, mail->box); @@ -501,6 +504,18 @@ } return TRUE; + + /* If the message is modified, only store it in the source mailbox when it is + * not opened read-only. Mail structs of modified messages have their own + * mailbox, unrelated to the orignal mail, so this case needs to be handled + * separately. + */ + } else if ( mail != aenv->msgdata->mail + && mailbox_is_readonly(aenv->msgdata->mail->box) + && ( mailbox_backends_equal(trans->box, aenv->msgdata->mail->box) ) ) { + + trans->redundant = TRUE; + return TRUE; } /* Mark attempt to store in default mailbox */ From pigeonhole at rename-it.nl Sat Dec 17 01:08:06 2011 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Sat, 17 Dec 2011 00:08:06 +0100 Subject: dovecot-2.1-pigeonhole: Updated man pages. Message-ID: details: http://hg.rename-it.nl/dovecot-2.1-pigeonhole/rev/8632ccc7173f changeset: 1579:8632ccc7173f user: Stephan Bosch date: Sat Dec 17 00:08:01 2011 +0100 description: Updated man pages. diffstat: doc/man/pigeonhole.7.in | 6 +++++- doc/man/sieve-dump.1.in | 3 ++- doc/man/sieve-filter.1.in | 27 +++++++++++++++------------ doc/man/sieve-test.1.in | 3 ++- doc/man/sievec.1.in | 3 ++- 5 files changed, 26 insertions(+), 16 deletions(-) diffs (144 lines): diff -r a8780b39f887 -r 8632ccc7173f doc/man/pigeonhole.7.in --- a/doc/man/pigeonhole.7.in Fri Dec 16 23:40:34 2011 +0100 +++ b/doc/man/pigeonhole.7.in Sat Dec 17 00:08:01 2011 +0100 @@ -1,5 +1,5 @@ .\" Copyright (c) 2010-2011 Pigeonhole authors, see the included COPYING file -.TH "PIGEONHOLE" 7 "2011-11-19" "Pigeonhole for Dovecot v2.1" "Pigeonhole" +.TH "PIGEONHOLE" 7 "2011-12-17" "Pigeonhole for Dovecot v2.1" "Pigeonhole" .\"------------------------------------------------------------------------ .SH NAME pigeonhole \- Overview of the Pigeonhole project\(aqs Sieve support for the @@ -60,6 +60,9 @@ The universal Sieve test tool for testing the effect of a Sieve script on a particular message. .TP +.BR sieve\-filter (1) +Filters all messages in a particular source mailbox through a Sieve script. +.TP .BR sieve\-dump (1) Dumps the content of a Sieve binary file for (development) debugging purposes. .\"------------------------------------------------------------------------ @@ -77,6 +80,7 @@ .BR dovecot\-lda (1), .BR sieve\-dump (1), .BR sieve\-test (1), +.BR sieve\-filter (1), .BR sievec (1) .\"------------------------------------- .PP diff -r a8780b39f887 -r 8632ccc7173f doc/man/sieve-dump.1.in --- a/doc/man/sieve-dump.1.in Fri Dec 16 23:40:34 2011 +0100 +++ b/doc/man/sieve-dump.1.in Sat Dec 17 00:08:01 2011 +0100 @@ -1,5 +1,5 @@ .\" Copyright (c) 2010-2011 Pigeonhole authors, see the included COPYING file -.TH "SIEVE\-DUMP" 1 "2011-12-12" "Pigeonhole for Dovecot v2.1" "Pigeonhole" +.TH "SIEVE\-DUMP" 1 "2011-12-17" "Pigeonhole for Dovecot v2.1" "Pigeonhole" .\"------------------------------------------------------------------------ .SH NAME sieve\-dump \- Pigeonhole\(aqs Sieve script binary dump tool @@ -97,6 +97,7 @@ .SH "SEE ALSO" .BR dovecot (1), .BR dovecot\-lda (1), +.BR sieve\-filter (1), .BR sieve\-test (1), .BR sievec (1), .BR pigeonhole (7) diff -r a8780b39f887 -r 8632ccc7173f doc/man/sieve-filter.1.in --- a/doc/man/sieve-filter.1.in Fri Dec 16 23:40:34 2011 +0100 +++ b/doc/man/sieve-filter.1.in Sat Dec 17 00:08:01 2011 +0100 @@ -1,5 +1,5 @@ .\" Copyright (c) 2010-2011 Pigeonhole authors, see the included COPYING file -.TH "SIEVE\-FILTER" 1 "2011-12-12" "Pigeonhole for Dovecot v2.1" "Pigeonhole" +.TH "SIEVE\-FILTER" 1 "2011-12-17" "Pigeonhole for Dovecot v2.1" "Pigeonhole" .SH NAME sieve\-filter \- Pigeonhole\(aqs Sieve mailbox filter tool @@ -27,10 +27,10 @@ many messages to be delivered incorrectly. Using the sieve\-filter tool it is possible to apply a Sieve script on all messages in a particular \fIsource\-mailbox\fP, making it possible to delete messages, to store them in a -different mailbox and to change the assigned IMAP flags and keywords. Attempts -to send messages to the outside world are ignored by default for obvious -reasons, but, using the proper command line options, it is possible to capture -and handle outgoing mail as well. +different mailbox, to change their content, and to change the assigned IMAP +flags and keywords. Attempts to send messages to the outside world are ignored +by default for obvious reasons, but, using the proper command line options, it +is possible to capture and handle outgoing mail as well. .PP If no options are specified, the sieve\-filter command runs in a simulation mode in which it only prints what would be performed, without actually doing @@ -44,8 +44,12 @@ lost unless a \fIdiscard\-action\fP argument other than \fBkeep\fP (the default) is specified. If the Sieve filter decides to store the message in the \fIsource\-mailbox\fP, where it obviously already exists, it is never duplicated -there. However, in that case, the IMAP flags of the original message can be -modified by the Sieve interpreter, provided that \fB\-W\fP is specified. +there. In that case, the IMAP flags of the original message can be modified by +the Sieve interpreter using the \fIimap4flags\fP extension, provided that +\fB\-W\fP is specified. If the message itself is modified by the Sieve +interpreter (e.g. using the \fIeditheader\fP extension), a new message is stored +and the old one is expunged. However, if \fB-W\fP is omitted, the original +message is left untouched and the modifications are discarded. .SS CAUTION Although this is a very useful tool, it can also be very destructive when used @@ -108,19 +112,18 @@ .BI \-s\ script\-file\ \fB[not\ implemented\ yet]\fP Specify additional scripts to be executed before the main script. Multiple \fB\-s\fP arguments are allowed and the specified scripts are executed -sequentially in the order specified at the command -line. +sequentially in the order specified at the command line. .TP .BI \-u\ user Run the Sieve script for the given \fIuser\fP. .TP -.B \-v\ +.B \-v Produce verbose output during filtering. .TP .B \-W Enables write access to the \fIsource\-mailbox\fP. This allows (re)moving the -messages from the \fIsource\-mailbox\fP and changing the assigned IMAP flags and -keywords. +messages from the \fIsource\-mailbox\fP, changing their contents, and changing +the assigned IMAP flags and keywords. .TP .BI \-x\ extensions Set the available extensions. The parameter is a space\-separated list of the diff -r a8780b39f887 -r 8632ccc7173f doc/man/sieve-test.1.in --- a/doc/man/sieve-test.1.in Fri Dec 16 23:40:34 2011 +0100 +++ b/doc/man/sieve-test.1.in Sat Dec 17 00:08:01 2011 +0100 @@ -1,5 +1,5 @@ .\" Copyright (c) 2010-2011 Pigeonhole authors, see the included COPYING file -.TH "SIEVE\-TEST" 1 "2011-12-12" "Pigeonhole for Dovecot v2.1" "Pigeonhole" +.TH "SIEVE\-TEST" 1 "2011-12-17" "Pigeonhole for Dovecot v2.1" "Pigeonhole" .SH NAME sieve\-test \- Pigeonhole\(aqs Sieve script tester .\"------------------------------------------------------------------------ @@ -236,5 +236,6 @@ .BR dovecot (1), .BR dovecot\-lda (1), .BR sieve\-dump (1), +.BR sieve\-filter (1), .BR sievec (1), .BR pigeonhole (7) diff -r a8780b39f887 -r 8632ccc7173f doc/man/sievec.1.in --- a/doc/man/sievec.1.in Fri Dec 16 23:40:34 2011 +0100 +++ b/doc/man/sievec.1.in Sat Dec 17 00:08:01 2011 +0100 @@ -1,5 +1,5 @@ .\" Copyright (c) 2010-2011 Pigeonhole authors, see the included COPYING file -.TH "SIEVEC" 1 "2011-12-12" "Pigeonhole for Dovecot v2.1" "Pigeonhole" +.TH "SIEVEC" 1 "2011-12-17" "Pigeonhole for Dovecot v2.1" "Pigeonhole" .\"------------------------------------------------------------------------ .SH NAME sievec \- Pigeonhole\(aqs Sieve script compiler @@ -118,5 +118,6 @@ .BR dovecot (1), .BR dovecot\-lda (1), .BR sieve\-dump (1), +.BR sieve\-filter (1), .BR sieve\-test (1), .BR pigeonhole (7) From pigeonhole at rename-it.nl Sat Dec 17 15:47:41 2011 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Sat, 17 Dec 2011 14:47:41 +0100 Subject: dovecot-2.1-pigeonhole: lib-sieve: fixed copy-paste error in sie... Message-ID: details: http://hg.rename-it.nl/dovecot-2.1-pigeonhole/rev/f566e0fce176 changeset: 1580:f566e0fce176 user: Stephan Bosch date: Sat Dec 17 14:47:23 2011 +0100 description: lib-sieve: fixed copy-paste error in sieve_get_warnings() It returned the number of errors in stead of the number of warnings. diffstat: src/lib-sieve/sieve-error.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 8632ccc7173f -r f566e0fce176 src/lib-sieve/sieve-error.c --- a/src/lib-sieve/sieve-error.c Sat Dec 17 00:08:01 2011 +0100 +++ b/src/lib-sieve/sieve-error.c Sat Dec 17 14:47:23 2011 +0100 @@ -489,7 +489,7 @@ { if ( ehandler == NULL || ehandler->pool == NULL ) return 0; - return ehandler->errors; + return ehandler->warnings; } bool sieve_errors_more_allowed(struct sieve_error_handler *ehandler) From pigeonhole at rename-it.nl Sat Dec 17 16:05:42 2011 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Sat, 17 Dec 2011 15:05:42 +0100 Subject: dovecot-2.1-pigeonhole: Fixed interaction of Sieve include exten... Message-ID: details: http://hg.rename-it.nl/dovecot-2.1-pigeonhole/rev/c67b7a0aec7b changeset: 1581:c67b7a0aec7b user: Stephan Bosch date: Sat Dec 17 15:04:59 2011 +0100 description: Fixed interaction of Sieve include extension with ManageSieve. Upon upload, the include extension is more lenient towards circular includes and missing scripts as required by RFC. The script is now also verified upon SETACTIVE when it was not active before. However, this new SETACTIVE behavior is not optimal for the situation where the active script was updated with PUTSCRIPT and contains an nonexistent include (ignored during upload). This can still cause runtime errors, since an already active script is not verified again during SETACTIVE. diffstat: TODO | 7 +- src/lib-sieve/plugins/include/cmd-include.c | 64 ++++++++++++++------ src/lib-sieve/plugins/include/ext-include-common.c | 39 ++++++++---- src/lib-sieve/plugins/include/ext-include-common.h | 2 +- src/lib-sieve/sieve-commands.h | 2 + src/lib-sieve/sieve-generator.c | 4 +- src/lib-sieve/sieve-generator.h | 5 +- src/lib-sieve/sieve-types.h | 12 +++- src/lib-sieve/sieve.c | 7 +- src/lib-sievestorage/sieve-storage-save.c | 18 ++++++ src/lib-sievestorage/sieve-storage-save.h | 3 + src/lib-sievestorage/sieve-storage-script.c | 32 +++++++++- src/lib-sievestorage/sieve-storage-script.h | 2 + src/managesieve/cmd-putscript.c | 11 ++- src/managesieve/cmd-setactive.c | 73 ++++++++++++++++++++--- 15 files changed, 218 insertions(+), 63 deletions(-) diffs (truncated from 641 to 300 lines): diff -r f566e0fce176 -r c67b7a0aec7b TODO --- a/TODO Sat Dec 17 14:47:23 2011 +0100 +++ b/TODO Sat Dec 17 15:04:59 2011 +0100 @@ -1,7 +1,7 @@ Current activities: -* Build a sieve tool to filter an entire existing mailbox through a Sieve - script. +* Update include extension to latest draft (v13 currently): + - Implement :optional tag. Parallel plugin-based efforts: @@ -15,9 +15,6 @@ Next (mostly in order of descending priority/precedence): * Implement index extension -* Update include extension to latest draft (v10 currently): - - Implement :optional tag. - - Implement required ManageSieve behavior * Add normalize() method to comparators to normalize the string before matching (for efficiency). * Improve error handling. diff -r f566e0fce176 -r c67b7a0aec7b src/lib-sieve/plugins/include/cmd-include.c --- a/src/lib-sieve/plugins/include/cmd-include.c Sat Dec 17 14:47:23 2011 +0100 +++ b/src/lib-sieve/plugins/include/cmd-include.c Sat Dec 17 15:04:59 2011 +0100 @@ -203,7 +203,8 @@ (struct cmd_include_context_data *) cmd->data; struct sieve_script *script; const char *script_path, *script_name; - enum sieve_error error = TRUE; + enum sieve_error error = SIEVE_ERROR_NONE; + bool include = TRUE; /* Check argument */ if ( !sieve_validate_positional_argument @@ -251,18 +252,33 @@ sieve_validator_error_handler(valdtr), &error); if ( script == NULL ) { - if ( error == SIEVE_ERROR_NOT_FOUND ) { - sieve_argument_validate_error(valdtr, arg, - "included %s script '%s' does not exist", - ext_include_script_location_name(ctx_data->location), - str_sanitize(script_name, 80)); + if ( error != SIEVE_ERROR_NOT_FOUND ) { + return FALSE; + } else { + enum sieve_compile_flags cpflags = + sieve_validator_compile_flags(valdtr); + + if ( (cpflags & SIEVE_COMPILE_FLAG_UPLOADED) != 0 ) { + sieve_argument_validate_warning(valdtr, arg, + "included %s script '%s' does not exist (ignored during upload)", + ext_include_script_location_name(ctx_data->location), + str_sanitize(script_name, 80)); + include = FALSE; + } else { + sieve_argument_validate_error(valdtr, arg, + "included %s script '%s' does not exist", + ext_include_script_location_name(ctx_data->location), + str_sanitize(script_name, 80)); + return FALSE; + } } - return FALSE; } - ext_include_ast_link_included_script(cmd->ext, cmd->ast_node->ast, script); - ctx_data->script = script; - + if ( include ) { + ext_include_ast_link_included_script(cmd->ext, cmd->ast_node->ast, script); + ctx_data->script = script; + } + arg = sieve_ast_arguments_detach(arg, 1); return TRUE; @@ -279,18 +295,26 @@ (struct cmd_include_context_data *) cmd->data; const struct ext_include_script_info *included; unsigned int flags = ctx_data->include_once; + int ret; - /* Compile (if necessary) and include the script into the binary. - * This yields the id of the binary block containing the compiled byte code. + /* Upon upload ctx_data->script may be NULL if the script was not found. We + * don't emit any code for this include command in that case. */ - if ( !ext_include_generate_include - (cgenv, cmd, ctx_data->location, ctx_data->script, &included, - ctx_data->include_once) ) - return FALSE; - - (void)sieve_operation_emit(cgenv->sblock, cmd->ext, &include_operation); - (void)sieve_binary_emit_unsigned(cgenv->sblock, included->id); - (void)sieve_binary_emit_byte(cgenv->sblock, flags); + if ( ctx_data->script != NULL ) { + /* Compile (if necessary) and include the script into the binary. + * This yields the id of the binary block containing the compiled byte code. + */ + if ( (ret=ext_include_generate_include + (cgenv, cmd, ctx_data->location, ctx_data->script, &included, + ctx_data->include_once)) < 0 ) + return FALSE; + + if ( ret > 0 ) { + (void)sieve_operation_emit(cgenv->sblock, cmd->ext, &include_operation); + (void)sieve_binary_emit_unsigned(cgenv->sblock, included->id); + (void)sieve_binary_emit_byte(cgenv->sblock, flags); + } + } return TRUE; } diff -r f566e0fce176 -r c67b7a0aec7b src/lib-sieve/plugins/include/ext-include-common.c --- a/src/lib-sieve/plugins/include/ext-include-common.c Sat Dec 17 14:47:23 2011 +0100 +++ b/src/lib-sieve/plugins/include/ext-include-common.c Sat Dec 17 15:04:59 2011 +0100 @@ -462,7 +462,7 @@ * Including a script during code generation */ -bool ext_include_generate_include +int ext_include_generate_include (const struct sieve_codegen_env *cgenv, struct sieve_command *cmd, enum ext_include_script_location location, struct sieve_script *script, const struct ext_include_script_info **included_r, bool once) @@ -470,7 +470,7 @@ const struct sieve_extension *this_ext = cmd->ext; struct ext_include_context *ext_ctx = (struct ext_include_context *)this_ext->context; - bool result = TRUE; + int result = 1; struct sieve_ast *ast; struct sieve_binary *sbin = cgenv->sbin; struct sieve_generator *gentr = cgenv->gentr; @@ -488,14 +488,14 @@ * already. */ if ( sieve_get_errors(ehandler) > 0 ) - return FALSE; + return -1; /* Limit nesting level */ if ( ctx->nesting_depth >= ext_ctx->max_nesting_depth ) { sieve_command_generate_error (gentr, cmd, "cannot nest includes deeper than %d levels", ext_ctx->max_nesting_depth); - return FALSE; + return -1; } /* Check for circular include */ @@ -503,9 +503,18 @@ pctx = ctx; while ( pctx != NULL ) { if ( sieve_script_equals(pctx->script, script) ) { + /* Just drop circular include when uploading inactive script; + * not an error + */ + if ( (cgenv->flags & SIEVE_COMPILE_FLAG_UPLOADED) != 0 && + (cgenv->flags & SIEVE_COMPILE_FLAG_ACTIVATED) == 0 ) { + sieve_command_generate_warning + (gentr, cmd, "circular include (ignored during upload)"); + return 0; + } + sieve_command_generate_error(gentr, cmd, "circular include"); - - return FALSE; + return -1; } pctx = pctx->parent; @@ -520,7 +529,7 @@ { struct sieve_binary_block *inc_block; const char *script_name = sieve_script_name(script); - enum sieve_compile_flags cpflags = 0; + enum sieve_compile_flags cpflags = cgenv->flags; /* Check whether include limit is exceeded */ if ( ext_include_binary_script_get_count(binctx) >= @@ -528,7 +537,7 @@ sieve_command_generate_error(gentr, cmd, "failed to include script '%s': no more than %u includes allowed", str_sanitize(script_name, 80), ext_ctx->max_includes); - return FALSE; + return -1; } /* No, allocate a new block in the binary and mark the script as included. @@ -541,13 +550,15 @@ if ( (ast = sieve_parse(script, ehandler, NULL)) == NULL ) { sieve_command_generate_error(gentr, cmd, "failed to parse included script '%s'", str_sanitize(script_name, 80)); - return FALSE; + return -1; } /* Included scripts inherit global variable scope */ (void)ext_include_create_ast_context(this_ext, ast, cmd->ast_node->ast); - if ( location != EXT_INCLUDE_LOCATION_GLOBAL ) + if ( location == EXT_INCLUDE_LOCATION_GLOBAL ) + cpflags &= ~SIEVE_RUNTIME_FLAG_NOGLOBAL; + else cpflags |= SIEVE_RUNTIME_FLAG_NOGLOBAL; /* Validate */ @@ -556,7 +567,7 @@ "failed to validate included script '%s'", str_sanitize(script_name, 80)); sieve_ast_unref(&ast); - return FALSE; + return -1; } /* Generate @@ -564,14 +575,14 @@ * FIXME: It might not be a good idea to recurse code generation for * included scripts. */ - subgentr = sieve_generator_create(ast, ehandler); + subgentr = sieve_generator_create(ast, ehandler, cpflags); ext_include_initialize_generator_context(cmd->ext, subgentr, ctx, script); if ( sieve_generator_run(subgentr, &inc_block) == NULL ) { sieve_command_generate_error(gentr, cmd, "failed to generate code for included script '%s'", str_sanitize(script_name, 80)); - result = FALSE; + result = -1; } sieve_generator_free(&subgentr); @@ -580,7 +591,7 @@ sieve_ast_unref(&ast); } - if ( result ) *included_r = included; + if ( result > 0 ) *included_r = included; return result; } diff -r f566e0fce176 -r c67b7a0aec7b src/lib-sieve/plugins/include/ext-include-common.h --- a/src/lib-sieve/plugins/include/ext-include-common.h Sat Dec 17 14:47:23 2011 +0100 +++ b/src/lib-sieve/plugins/include/ext-include-common.h Sat Dec 17 15:04:59 2011 +0100 @@ -142,7 +142,7 @@ (const struct sieve_extension *this_ext, const struct sieve_codegen_env *cgenv); -bool ext_include_generate_include +int ext_include_generate_include (const struct sieve_codegen_env *cgenv, struct sieve_command *cmd, enum ext_include_script_location location, struct sieve_script *script, const struct ext_include_script_info **included_r, bool once); diff -r f566e0fce176 -r c67b7a0aec7b src/lib-sieve/sieve-commands.h --- a/src/lib-sieve/sieve-commands.h Sat Dec 17 14:47:23 2011 +0100 +++ b/src/lib-sieve/sieve-commands.h Sat Dec 17 15:04:59 2011 +0100 @@ -200,6 +200,8 @@ #define sieve_command_generate_error(gentr, context, ...) \ sieve_generator_error(gentr, (context)->ast_node->source_line, __VA_ARGS__) +#define sieve_command_generate_warning(gentr, context, ...) \ + sieve_generator_warning(gentr, (context)->ast_node->source_line, __VA_ARGS__) /* Utility macros */ diff -r f566e0fce176 -r c67b7a0aec7b src/lib-sieve/sieve-generator.c --- a/src/lib-sieve/sieve-generator.c Sat Dec 17 14:47:23 2011 +0100 +++ b/src/lib-sieve/sieve-generator.c Sat Dec 17 15:04:59 2011 +0100 @@ -76,7 +76,8 @@ }; struct sieve_generator *sieve_generator_create -(struct sieve_ast *ast, struct sieve_error_handler *ehandler) +(struct sieve_ast *ast, struct sieve_error_handler *ehandler, + enum sieve_compile_flags flags) { pool_t pool; struct sieve_generator *gentr; @@ -91,6 +92,7 @@ sieve_error_handler_ref(ehandler); gentr->genenv.gentr = gentr; + gentr->genenv.flags = flags; gentr->genenv.ast = ast; sieve_ast_ref(ast); diff -r f566e0fce176 -r c67b7a0aec7b src/lib-sieve/sieve-generator.h --- a/src/lib-sieve/sieve-generator.h Sat Dec 17 14:47:23 2011 +0100 +++ b/src/lib-sieve/sieve-generator.h Sat Dec 17 15:04:59 2011 +0100 @@ -16,6 +16,8 @@ struct sieve_generator *gentr; struct sieve_instance *svinst; + enum sieve_compile_flags flags; + From pigeonhole at rename-it.nl Sat Dec 17 16:19:22 2011 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Sat, 17 Dec 2011 15:19:22 +0100 Subject: dovecot-2.0-pigeonhole: lib-sieve: made sure error locations nev... Message-ID: details: http://hg.rename-it.nl/dovecot-2.0-pigeonhole/rev/5bbd8d148b7d changeset: 1549:5bbd8d148b7d user: Stephan Bosch date: Mon Dec 12 00:25:47 2011 +0100 description: lib-sieve: made sure error locations never report `line 0'. diffstat: src/lib-sieve/sieve-error.c | 9 ++++++++- 1 files changed, 8 insertions(+), 1 deletions(-) diffs (20 lines): diff -r b2839569e943 -r 5bbd8d148b7d src/lib-sieve/sieve-error.c --- a/src/lib-sieve/sieve-error.c Sat Dec 17 15:11:40 2011 +0100 +++ b/src/lib-sieve/sieve-error.c Mon Dec 12 00:25:47 2011 +0100 @@ -41,8 +41,15 @@ sname = ( script == NULL ? NULL : sieve_script_name(script) ); - if ( sname == NULL || *sname == '\0' ) + if ( sname == NULL || *sname == '\0' ) { + if ( source_line == 0 ) + return NULL; + return t_strdup_printf("line %d", source_line); + } + + if ( source_line == 0 ) + return sname; return t_strdup_printf("%s: line %d", sname, source_line); } From pigeonhole at rename-it.nl Sat Dec 17 16:19:22 2011 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Sat, 17 Dec 2011 15:19:22 +0100 Subject: dovecot-2.0-pigeonhole: lib-sieve: fixed copy-paste error in sie... Message-ID: details: http://hg.rename-it.nl/dovecot-2.0-pigeonhole/rev/787832d0aa0a changeset: 1550:787832d0aa0a user: Stephan Bosch date: Sat Dec 17 14:47:23 2011 +0100 description: lib-sieve: fixed copy-paste error in sieve_get_warnings() It returned the number of errors in stead of the number of warnings. diffstat: src/lib-sieve/sieve-error.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 5bbd8d148b7d -r 787832d0aa0a src/lib-sieve/sieve-error.c --- a/src/lib-sieve/sieve-error.c Mon Dec 12 00:25:47 2011 +0100 +++ b/src/lib-sieve/sieve-error.c Sat Dec 17 14:47:23 2011 +0100 @@ -489,7 +489,7 @@ { if ( ehandler == NULL || ehandler->pool == NULL ) return 0; - return ehandler->errors; + return ehandler->warnings; } bool sieve_errors_more_allowed(struct sieve_error_handler *ehandler) From pigeonhole at rename-it.nl Sat Dec 17 16:19:21 2011 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Sat, 17 Dec 2011 15:19:21 +0100 Subject: dovecot-2.0-pigeonhole: lib-sieve: fixed potential segfault occu... Message-ID: details: http://hg.rename-it.nl/dovecot-2.0-pigeonhole/rev/b2839569e943 changeset: 1548:b2839569e943 user: Stephan Bosch date: Sat Dec 17 15:11:40 2011 +0100 description: lib-sieve: fixed potential segfault occuring when interpreter initialization fails. diffstat: src/lib-sieve/sieve.c | 10 ++++++---- 1 files changed, 6 insertions(+), 4 deletions(-) diffs (28 lines): diff -r a0215970fab1 -r b2839569e943 src/lib-sieve/sieve.c --- a/src/lib-sieve/sieve.c Sat Nov 19 17:54:11 2011 +0100 +++ b/src/lib-sieve/sieve.c Sat Dec 17 15:11:40 2011 +0100 @@ -438,8 +438,9 @@ } /* Cleanup */ - sieve_result_unref(&result); - + if ( result != NULL ) + sieve_result_unref(&result); + return ret; } @@ -476,9 +477,10 @@ if ( keep != NULL ) *keep = TRUE; } } - + /* Cleanup */ - sieve_result_unref(&result); + if ( result != NULL ) + sieve_result_unref(&result); return ret; } From pigeonhole at rename-it.nl Sat Dec 17 17:07:25 2011 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Sat, 17 Dec 2011 16:07:25 +0100 Subject: dovecot-2.1-pigeonhole: lib-managesieve-storage: added code to c... Message-ID: details: http://hg.rename-it.nl/dovecot-2.1-pigeonhole/rev/5834cc823e38 changeset: 1582:5834cc823e38 user: Stephan Bosch date: Sat Dec 17 16:07:16 2011 +0100 description: lib-managesieve-storage: added code to cleanup tmp directory every once in a while. This is borrowed from Dovecot's lib-storage/index/maildir. diffstat: src/lib-sievestorage/sieve-storage-private.h | 5 ++ src/lib-sievestorage/sieve-storage.c | 49 ++++++++++++++++++++---- 2 files changed, 45 insertions(+), 9 deletions(-) diffs (117 lines): diff -r c67b7a0aec7b -r 5834cc823e38 src/lib-sievestorage/sieve-storage-private.h --- a/src/lib-sievestorage/sieve-storage-private.h Sat Dec 17 15:04:59 2011 +0100 +++ b/src/lib-sievestorage/sieve-storage-private.h Sat Dec 17 16:07:16 2011 +0100 @@ -19,6 +19,11 @@ #define SIEVE_READ_BLOCK_SIZE (1024*8) +/* How often to scan tmp/ directory for old files (based on dir's atime) */ +#define SIEVE_STORAGE_TMP_SCAN_SECS (8*60*60) +/* Delete files having ctime older than this from tmp/. 36h is standard. */ +#define SIEVE_STORAGE_TMP_DELETE_SECS (36*60*60) + struct sieve_storage; struct sieve_storage_ehandler { diff -r c67b7a0aec7b -r 5834cc823e38 src/lib-sievestorage/sieve-storage.c --- a/src/lib-sievestorage/sieve-storage.c Sat Dec 17 15:04:59 2011 +0100 +++ b/src/lib-sievestorage/sieve-storage.c Sat Dec 17 16:07:16 2011 +0100 @@ -6,6 +6,7 @@ #include "ioloop.h" #include "mkdir-parents.h" #include "eacces-error.h" +#include "unlink-old-files.h" #include "sieve.h" #include "sieve-common.h" @@ -142,10 +143,10 @@ return 0; if ( errno == EACCES ) { - i_error("sieve-storage: %s", eacces_error_get("stat", dir)); + i_error("sieve-storage: mkdir_verify: %s", eacces_error_get("stat", dir)); return -1; } else if ( errno != ENOENT ) { - i_error("sieve-storage: stat(%s) failed: %m", dir); + i_error("sieve-storage: mkdir_verify: stat(%s) failed: %m", dir); return -1; } @@ -162,16 +163,44 @@ i_error("sieve-storage: storage was deleted while it was being created"); break; case EACCES: - i_error("sieve-storage: %s", eacces_error_get_creating("mkdir", dir)); + i_error("sieve-storage: %s", + eacces_error_get_creating("mkdir_parents_chgrp", dir)); break; default: - i_error("sieve-storage: mkdir(%s) failed: %m", dir); + i_error("sieve-storage: mkdir_parents_chgrp(%s) failed: %m", dir); break; } return -1; } +static int check_tmp(const char *path) +{ + struct stat st; + + /* If tmp/ directory exists, we need to clean it up once in a while */ + if ( stat(path, &st) < 0 ) { + if ( errno == ENOENT ) + return 0; + if ( errno == EACCES ) { + i_error("sieve-storage: check_tmp: %s", eacces_error_get("stat", path)); + return -1; + } + i_error("sieve-storage: check_tmp: stat(%s) failed: %m", path); + return -1; + } + + if ( st.st_atime > st.st_ctime + SIEVE_STORAGE_TMP_DELETE_SECS ) { + /* The directory should be empty. we won't do anything + until ctime changes. */ + } else if ( st.st_atime < ioloop_time - SIEVE_STORAGE_TMP_SCAN_SECS ) { + /* Time to scan */ + (void)unlink_old_files(path, "", + ioloop_time - SIEVE_STORAGE_TMP_DELETE_SECS); + } + return 1; +} + static struct sieve_storage *_sieve_storage_create (struct sieve_instance *svinst, const char *user, const char *home, bool debug) { @@ -184,6 +213,7 @@ const char *file_create_gid_origin; unsigned long long int uint_setting; size_t size_setting; + int ret; /* * Configure active script path @@ -321,16 +351,17 @@ /* * Ensure sieve local directory structure exists (full autocreate): - * This currently currently only consists of a ./tmp direcory + * This currently only consists of a ./tmp direcory */ tmp_dir = t_strconcat(storage_dir, "/tmp", NULL); - /*ret = maildir_check_tmp(box->storage, box->path); - if (ret < 0) - return -1;*/ + /* Try to find and clean up tmp dir */ + if ( (ret=check_tmp(tmp_dir)) < 0 ) + return NULL; - if ( mkdir_verify(tmp_dir, dir_create_mode, file_create_gid, + /* Auto-create if necessary */ + if ( ret == 0 && mkdir_verify(tmp_dir, dir_create_mode, file_create_gid, file_create_gid_origin, debug) < 0 ) return NULL; From pigeonhole at rename-it.nl Sat Dec 17 19:58:56 2011 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Sat, 17 Dec 2011 18:58:56 +0100 Subject: dovecot-2.1-pigeonhole: lib-sieve: made uniform scriptname <-> f... Message-ID: details: http://hg.rename-it.nl/dovecot-2.1-pigeonhole/rev/66b7b1636c8c changeset: 1583:66b7b1636c8c user: Stephan Bosch date: Sat Dec 17 18:58:48 2011 +0100 description: lib-sieve: made uniform scriptname <-> filename conversion functions. This puts the ".sieve" and ".svbin" file extension definitions in a single locatio. IMPORTANT: this fixes a bug in the include extension that implicitly mapped script names like "name.sieve" to "name". diffstat: src/lib-sieve/sieve-config.h | 3 + src/lib-sieve/sieve-script.c | 43 ++++++++++----------- src/lib-sieve/sieve-script.h | 15 ++++--- src/lib-sieve/sieve.c | 2 +- src/lib-sievestorage/sieve-storage-list.c | 4 +- src/lib-sievestorage/sieve-storage-quota.c | 2 +- src/lib-sievestorage/sieve-storage-save.c | 12 ++--- src/lib-sievestorage/sieve-storage-script.c | 24 +++--------- src/lib-sievestorage/sieve-storage-script.h | 3 - src/lib-sievestorage/sieve-storage.c | 2 +- src/sieve-tools/sievec.c | 2 +- src/testsuite/testsuite-binary.c | 9 ++-- tests/extensions/include/errors/circular-1.sieve | 2 +- tests/extensions/include/errors/circular-2.sieve | 2 +- tests/extensions/include/included/circular-one.sieve | 2 +- tests/extensions/include/included/circular-three-2.sieve | 2 +- tests/extensions/include/included/circular-three.sieve | 2 +- tests/extensions/include/included/circular-two.sieve | 2 +- tests/extensions/include/included/once-2.sieve | 2 +- tests/extensions/include/included/twice-2.sieve | 2 +- 20 files changed, 61 insertions(+), 76 deletions(-) diffs (truncated from 412 to 300 lines): diff -r 5834cc823e38 -r 66b7b1636c8c src/lib-sieve/sieve-config.h --- a/src/lib-sieve/sieve-config.h Sat Dec 17 16:07:16 2011 +0100 +++ b/src/lib-sieve/sieve-config.h Sat Dec 17 18:58:48 2011 +0100 @@ -8,4 +8,7 @@ #define SIEVE_IMPLEMENTATION PIGEONHOLE_NAME " Sieve " PIGEONHOLE_VERSION +#define SIEVE_SCRIPT_FILEEXT "sieve" +#define SIEVE_BINARY_FILEEXT "svbin" + #endif diff -r 5834cc823e38 -r 66b7b1636c8c src/lib-sieve/sieve-script.c --- a/src/lib-sieve/sieve-script.c Sat Dec 17 16:07:16 2011 +0100 +++ b/src/lib-sieve/sieve-script.c Sat Dec 17 18:58:48 2011 +0100 @@ -96,38 +96,35 @@ * Filename to name/name to filename */ -static inline const char *_sieve_scriptfile_get_basename(const char *filename) +const char *sieve_scriptfile_get_script_name(const char *filename) { const char *ext; /* Extract the script name */ ext = strrchr(filename, '.'); - if ( ext == NULL || ext == filename || strncmp(ext,".sieve",6) != 0 ) - return filename; + if ( ext == NULL || ext == filename || + strcmp(ext, "."SIEVE_SCRIPT_FILEEXT) != 0 ) + return NULL; return t_strdup_until(filename, ext); } -bool sieve_script_file_has_extension(const char *filename) +bool sieve_scriptfile_has_extension(const char *filename) { - const char *ext; - - /* See if it ends in .sieve already */ - ext = strrchr(filename, '.'); - if ( ext == NULL || ext == filename || strncmp(ext,".sieve",6) != 0 ) - return FALSE; - - return TRUE; + return ( sieve_scriptfile_get_script_name(filename) != NULL ); } -static inline const char *_sieve_scriptfile_from_name(const char *name) +const char *sieve_scriptfile_from_name(const char *name) { - if ( !sieve_script_file_has_extension(name) ) - return t_strconcat(name, ".sieve", NULL); + return t_strconcat(name, "."SIEVE_SCRIPT_FILEEXT, NULL); +} - return name; +const char *sieve_binfile_from_name(const char *name) +{ + return t_strconcat(name, "."SIEVE_BINARY_FILEEXT, NULL); } + /* * Common error handling */ @@ -192,12 +189,12 @@ filename++; } - basename = _sieve_scriptfile_get_basename(filename); + if ( (basename=sieve_scriptfile_get_script_name(filename)) == NULL ) + basename = filename; - if ( *dirpath == '\0' ) - binpath = t_strconcat(basename, ".svbin", NULL); - else - binpath = t_strconcat(dirpath, "/", basename, ".svbin", NULL); + binpath = sieve_binfile_from_name(basename); + if ( *dirpath != '\0' ) + binpath = t_strconcat(dirpath, "/", binpath, NULL); if ( name == NULL ) { name = basename; @@ -284,10 +281,10 @@ if ( dirpath[strlen(dirpath)-1] == '/' ) path = t_strconcat(dirpath, - _sieve_scriptfile_from_name(name), NULL); + sieve_scriptfile_from_name(name), NULL); else path = t_strconcat(dirpath, "/", - _sieve_scriptfile_from_name(name), NULL); + sieve_scriptfile_from_name(name), NULL); return sieve_script_init(NULL, svinst, path, name, ehandler, error_r); } diff -r 5834cc823e38 -r 66b7b1636c8c src/lib-sieve/sieve-script.h --- a/src/lib-sieve/sieve-script.h Sat Dec 17 16:07:16 2011 +0100 +++ b/src/lib-sieve/sieve-script.h Sat Dec 17 18:58:48 2011 +0100 @@ -16,6 +16,15 @@ bool sieve_script_name_is_valid(const char *scriptname); /* + * Sieve script filenames + */ + +bool sieve_scriptfile_has_extension(const char *filename); +const char *sieve_scriptfile_get_script_name(const char *filename); +const char *sieve_scriptfile_from_name(const char *name); +const char *sieve_binfile_from_name(const char *name); + +/* * Sieve script object */ @@ -33,12 +42,6 @@ void sieve_script_unref(struct sieve_script **script); /* - * Filename filter - */ - -bool sieve_script_file_has_extension(const char *filename); - -/* * Accessors */ diff -r 5834cc823e38 -r 66b7b1636c8c src/lib-sieve/sieve.c --- a/src/lib-sieve/sieve.c Sat Dec 17 16:07:16 2011 +0100 +++ b/src/lib-sieve/sieve.c Sat Dec 17 18:58:48 2011 +0100 @@ -765,7 +765,7 @@ return NULL; } - if ( !sieve_script_file_has_extension(dp->d_name) ) + if ( !sieve_scriptfile_has_extension(dp->d_name) ) continue; if ( sdir->path[strlen(sdir->path)-1] == '/' ) diff -r 5834cc823e38 -r 66b7b1636c8c src/lib-sievestorage/sieve-storage-list.c --- a/src/lib-sievestorage/sieve-storage-list.c Sat Dec 17 16:07:16 2011 +0100 +++ b/src/lib-sievestorage/sieve-storage-list.c Sat Dec 17 18:58:48 2011 +0100 @@ -69,9 +69,7 @@ if ( (dp = readdir(ctx->dirp)) == NULL ) return NULL; - scriptname = sieve_storage_file_get_scriptname - (storage, dp->d_name); - + scriptname = sieve_scriptfile_get_script_name(dp->d_name); if (scriptname != NULL ) { /* Don't list our active sieve script link if the link * resides in the script dir (generally a bad idea). diff -r 5834cc823e38 -r 66b7b1636c8c src/lib-sievestorage/sieve-storage-quota.c --- a/src/lib-sievestorage/sieve-storage-quota.c Sat Dec 17 16:07:16 2011 +0100 +++ b/src/lib-sievestorage/sieve-storage-quota.c Sat Dec 17 18:58:48 2011 +0100 @@ -78,7 +78,7 @@ } /* Parse filename */ - name = sieve_storage_file_get_scriptname(storage, dp->d_name); + name = sieve_scriptfile_get_script_name(dp->d_name); /* Ignore non-script files */ if ( name == NULL ) diff -r 5834cc823e38 -r 66b7b1636c8c src/lib-sievestorage/sieve-storage-save.c --- a/src/lib-sievestorage/sieve-storage-save.c Sat Dec 17 16:07:16 2011 +0100 +++ b/src/lib-sievestorage/sieve-storage-save.c Sat Dec 17 18:58:48 2011 +0100 @@ -59,13 +59,11 @@ } last_tv = tv; - if ( scriptname == NULL ) - return t_strdup_printf("NULL_%s.M%sP%s.%s.sieve", dec2str(tv.tv_sec), - dec2str(tv.tv_usec), my_pid, my_hostname); + scriptname = t_strdup_printf("%s_%s.M%sP%s.%s", + ( scriptname == NULL ? "NULL" : scriptname ), + dec2str(tv.tv_sec), dec2str(tv.tv_usec), my_pid, my_hostname); - return t_strdup_printf - ("%s-%s.M%sP%s.%s.sieve", scriptname, dec2str(tv.tv_sec), - dec2str(tv.tv_usec), my_pid, my_hostname); + return sieve_scriptfile_from_name(scriptname); } static int sieve_storage_create_tmp @@ -345,7 +343,7 @@ T_BEGIN { dest_path = t_strconcat((*ctx)->storage->dir, "/", - (*ctx)->scriptname, ".sieve", NULL); + sieve_scriptfile_from_name((*ctx)->scriptname), NULL); failed = !sieve_storage_script_move((*ctx), dest_path); } T_END; diff -r 5834cc823e38 -r 66b7b1636c8c src/lib-sievestorage/sieve-storage-script.c --- a/src/lib-sievestorage/sieve-storage-script.c Sat Dec 17 16:07:16 2011 +0100 +++ b/src/lib-sievestorage/sieve-storage-script.c Sat Dec 17 18:58:48 2011 +0100 @@ -88,7 +88,8 @@ } T_BEGIN { - path = t_strconcat( storage->dir, "/", scriptname, ".sieve", NULL ); + path = t_strconcat + ( storage->dir, "/", sieve_scriptfile_from_name(scriptname), NULL ); script = sieve_storage_script_init_from_path(storage, path, NULL); } T_END; @@ -111,19 +112,6 @@ return script; } -const char *sieve_storage_file_get_scriptname -(const struct sieve_storage *storage ATTR_UNUSED, const char *filename) -{ - const char *ext; - - ext = strrchr(filename, '.'); - - if ( ext == NULL || ext == filename || strcmp(ext,".sieve") != 0 ) - return NULL; - - return t_strdup_until(filename, ext); -} - static int sieve_storage_read_active_link (struct sieve_storage *storage, const char **link_r) { @@ -179,7 +167,7 @@ } /* Check the script name */ - scriptname = sieve_storage_file_get_scriptname(storage, fname); + scriptname = sieve_scriptfile_get_script_name(fname); /* Warn if link is deemed to be invalid */ if ( scriptname == NULL ) { @@ -377,7 +365,7 @@ T_BEGIN { dstpath = t_strconcat - ( storage->dir, "/dovecot.orig.sieve", NULL ); + ( storage->dir, "/", sieve_scriptfile_from_name("dovecot.orig"), NULL ); if ( file_copy(storage->active_path, dstpath, 1) < 1 ) { sieve_storage_set_critical(storage, "Active sieve script file '%s' is a regular file and copying it to " @@ -434,7 +422,7 @@ for (;;) { /* First the new symlink is created with a different filename */ active_path_new = t_strdup_printf - ("%s-new.%s.P%sM%s.%s.sieve", + ("%s-new.%s.P%sM%s.%s", storage->active_path, dec2str(tv->tv_sec), my_pid, dec2str(tv->tv_usec), my_hostname); @@ -569,7 +557,7 @@ } T_BEGIN { - newfile = t_strconcat( newname, ".sieve", NULL ); + newfile = sieve_scriptfile_from_name(newname); newpath = t_strconcat( storage->dir, "/", newfile, NULL ); /* The normal rename() system call overwrites the existing file without diff -r 5834cc823e38 -r 66b7b1636c8c src/lib-sievestorage/sieve-storage-script.h --- a/src/lib-sievestorage/sieve-storage-script.h Sat Dec 17 16:07:16 2011 +0100 +++ b/src/lib-sievestorage/sieve-storage-script.h Sat Dec 17 18:58:48 2011 +0100 @@ -11,9 +11,6 @@ struct sieve_script *sieve_storage_script_init (struct sieve_storage *storage, const char *scriptname); -const char *sieve_storage_file_get_scriptname - (const struct sieve_storage *storage, const char *filename); - int sieve_storage_get_active_scriptfile (struct sieve_storage *storage, const char **file_r); int sieve_storage_get_active_scriptname diff -r 5834cc823e38 -r 66b7b1636c8c src/lib-sievestorage/sieve-storage.c --- a/src/lib-sievestorage/sieve-storage.c Sat Dec 17 16:07:16 2011 +0100 +++ b/src/lib-sievestorage/sieve-storage.c Sat Dec 17 18:58:48 2011 +0100 @@ -23,7 +23,7 @@ #include #include -#define SIEVE_DEFAULT_PATH "~/.dovecot.sieve" +#define SIEVE_DEFAULT_PATH "~/.dovecot."SIEVE_SCRIPT_FILEEXT #define MAX_DIR_CREATE_MODE 0770 diff -r 5834cc823e38 -r 66b7b1636c8c src/sieve-tools/sievec.c --- a/src/sieve-tools/sievec.c Sat Dec 17 16:07:16 2011 +0100 +++ b/src/sieve-tools/sievec.c Sat Dec 17 18:58:48 2011 +0100 @@ -112,7 +112,7 @@ break; } - if ( sieve_script_file_has_extension(dp->d_name) ) { + if ( sieve_scriptfile_has_extension(dp->d_name) ) { From pigeonhole at rename-it.nl Sat Dec 17 20:00:42 2011 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Sat, 17 Dec 2011 19:00:42 +0100 Subject: dovecot-2.0-pigeonhole: lib-sieve: made uniform scriptname <-> f... Message-ID: details: http://hg.rename-it.nl/dovecot-2.0-pigeonhole/rev/cc6d38c3f87f changeset: 1551:cc6d38c3f87f user: Stephan Bosch date: Sat Dec 17 18:58:48 2011 +0100 description: lib-sieve: made uniform scriptname <-> filename conversion functions. This puts the ".sieve" and ".svbin" file extension definitions in a single locatio. IMPORTANT: this fixes a bug in the include extension that implicitly mapped script names like "name.sieve" to "name". diffstat: src/lib-sieve/sieve-config.h | 3 + src/lib-sieve/sieve-script.c | 43 ++++++++++----------- src/lib-sieve/sieve-script.h | 15 ++++--- src/lib-sieve/sieve.c | 2 +- src/lib-sievestorage/sieve-storage-list.c | 4 +- src/lib-sievestorage/sieve-storage-quota.c | 2 +- src/lib-sievestorage/sieve-storage-save.c | 12 ++--- src/lib-sievestorage/sieve-storage-script.c | 24 +++--------- src/lib-sievestorage/sieve-storage-script.h | 3 - src/lib-sievestorage/sieve-storage.c | 2 +- src/sieve-tools/sievec.c | 2 +- src/testsuite/testsuite-binary.c | 9 ++-- tests/extensions/include/errors/circular-1.sieve | 2 +- tests/extensions/include/errors/circular-2.sieve | 2 +- tests/extensions/include/included/circular-one.sieve | 2 +- tests/extensions/include/included/circular-three-2.sieve | 2 +- tests/extensions/include/included/circular-three.sieve | 2 +- tests/extensions/include/included/circular-two.sieve | 2 +- tests/extensions/include/included/once-2.sieve | 2 +- tests/extensions/include/included/twice-2.sieve | 2 +- 20 files changed, 61 insertions(+), 76 deletions(-) diffs (truncated from 412 to 300 lines): diff -r 787832d0aa0a -r cc6d38c3f87f src/lib-sieve/sieve-config.h --- a/src/lib-sieve/sieve-config.h Sat Dec 17 14:47:23 2011 +0100 +++ b/src/lib-sieve/sieve-config.h Sat Dec 17 18:58:48 2011 +0100 @@ -8,4 +8,7 @@ #define SIEVE_IMPLEMENTATION PIGEONHOLE_NAME " Sieve " PIGEONHOLE_VERSION +#define SIEVE_SCRIPT_FILEEXT "sieve" +#define SIEVE_BINARY_FILEEXT "svbin" + #endif diff -r 787832d0aa0a -r cc6d38c3f87f src/lib-sieve/sieve-script.c --- a/src/lib-sieve/sieve-script.c Sat Dec 17 14:47:23 2011 +0100 +++ b/src/lib-sieve/sieve-script.c Sat Dec 17 18:58:48 2011 +0100 @@ -96,38 +96,35 @@ * Filename to name/name to filename */ -static inline const char *_sieve_scriptfile_get_basename(const char *filename) +const char *sieve_scriptfile_get_script_name(const char *filename) { const char *ext; /* Extract the script name */ ext = strrchr(filename, '.'); - if ( ext == NULL || ext == filename || strncmp(ext,".sieve",6) != 0 ) - return filename; + if ( ext == NULL || ext == filename || + strcmp(ext, "."SIEVE_SCRIPT_FILEEXT) != 0 ) + return NULL; return t_strdup_until(filename, ext); } -bool sieve_script_file_has_extension(const char *filename) +bool sieve_scriptfile_has_extension(const char *filename) { - const char *ext; - - /* See if it ends in .sieve already */ - ext = strrchr(filename, '.'); - if ( ext == NULL || ext == filename || strncmp(ext,".sieve",6) != 0 ) - return FALSE; - - return TRUE; + return ( sieve_scriptfile_get_script_name(filename) != NULL ); } -static inline const char *_sieve_scriptfile_from_name(const char *name) +const char *sieve_scriptfile_from_name(const char *name) { - if ( !sieve_script_file_has_extension(name) ) - return t_strconcat(name, ".sieve", NULL); + return t_strconcat(name, "."SIEVE_SCRIPT_FILEEXT, NULL); +} - return name; +const char *sieve_binfile_from_name(const char *name) +{ + return t_strconcat(name, "."SIEVE_BINARY_FILEEXT, NULL); } + /* * Common error handling */ @@ -192,12 +189,12 @@ filename++; } - basename = _sieve_scriptfile_get_basename(filename); + if ( (basename=sieve_scriptfile_get_script_name(filename)) == NULL ) + basename = filename; - if ( *dirpath == '\0' ) - binpath = t_strconcat(basename, ".svbin", NULL); - else - binpath = t_strconcat(dirpath, "/", basename, ".svbin", NULL); + binpath = sieve_binfile_from_name(basename); + if ( *dirpath != '\0' ) + binpath = t_strconcat(dirpath, "/", binpath, NULL); if ( name == NULL ) { name = basename; @@ -284,10 +281,10 @@ if ( dirpath[strlen(dirpath)-1] == '/' ) path = t_strconcat(dirpath, - _sieve_scriptfile_from_name(name), NULL); + sieve_scriptfile_from_name(name), NULL); else path = t_strconcat(dirpath, "/", - _sieve_scriptfile_from_name(name), NULL); + sieve_scriptfile_from_name(name), NULL); return sieve_script_init(NULL, svinst, path, name, ehandler, error_r); } diff -r 787832d0aa0a -r cc6d38c3f87f src/lib-sieve/sieve-script.h --- a/src/lib-sieve/sieve-script.h Sat Dec 17 14:47:23 2011 +0100 +++ b/src/lib-sieve/sieve-script.h Sat Dec 17 18:58:48 2011 +0100 @@ -16,6 +16,15 @@ bool sieve_script_name_is_valid(const char *scriptname); /* + * Sieve script filenames + */ + +bool sieve_scriptfile_has_extension(const char *filename); +const char *sieve_scriptfile_get_script_name(const char *filename); +const char *sieve_scriptfile_from_name(const char *name); +const char *sieve_binfile_from_name(const char *name); + +/* * Sieve script object */ @@ -33,12 +42,6 @@ void sieve_script_unref(struct sieve_script **script); /* - * Filename filter - */ - -bool sieve_script_file_has_extension(const char *filename); - -/* * Accessors */ diff -r 787832d0aa0a -r cc6d38c3f87f src/lib-sieve/sieve.c --- a/src/lib-sieve/sieve.c Sat Dec 17 14:47:23 2011 +0100 +++ b/src/lib-sieve/sieve.c Sat Dec 17 18:58:48 2011 +0100 @@ -761,7 +761,7 @@ return NULL; } - if ( !sieve_script_file_has_extension(dp->d_name) ) + if ( !sieve_scriptfile_has_extension(dp->d_name) ) continue; if ( sdir->path[strlen(sdir->path)-1] == '/' ) diff -r 787832d0aa0a -r cc6d38c3f87f src/lib-sievestorage/sieve-storage-list.c --- a/src/lib-sievestorage/sieve-storage-list.c Sat Dec 17 14:47:23 2011 +0100 +++ b/src/lib-sievestorage/sieve-storage-list.c Sat Dec 17 18:58:48 2011 +0100 @@ -69,9 +69,7 @@ if ( (dp = readdir(ctx->dirp)) == NULL ) return NULL; - scriptname = sieve_storage_file_get_scriptname - (storage, dp->d_name); - + scriptname = sieve_scriptfile_get_script_name(dp->d_name); if (scriptname != NULL ) { /* Don't list our active sieve script link if the link * resides in the script dir (generally a bad idea). diff -r 787832d0aa0a -r cc6d38c3f87f src/lib-sievestorage/sieve-storage-quota.c --- a/src/lib-sievestorage/sieve-storage-quota.c Sat Dec 17 14:47:23 2011 +0100 +++ b/src/lib-sievestorage/sieve-storage-quota.c Sat Dec 17 18:58:48 2011 +0100 @@ -78,7 +78,7 @@ } /* Parse filename */ - name = sieve_storage_file_get_scriptname(storage, dp->d_name); + name = sieve_scriptfile_get_script_name(dp->d_name); /* Ignore non-script files */ if ( name == NULL ) diff -r 787832d0aa0a -r cc6d38c3f87f src/lib-sievestorage/sieve-storage-save.c --- a/src/lib-sievestorage/sieve-storage-save.c Sat Dec 17 14:47:23 2011 +0100 +++ b/src/lib-sievestorage/sieve-storage-save.c Sat Dec 17 18:58:48 2011 +0100 @@ -59,13 +59,11 @@ } last_tv = tv; - if ( scriptname == NULL ) - return t_strdup_printf("NULL_%s.M%sP%s.%s.sieve", dec2str(tv.tv_sec), - dec2str(tv.tv_usec), my_pid, my_hostname); + scriptname = t_strdup_printf("%s_%s.M%sP%s.%s", + ( scriptname == NULL ? "NULL" : scriptname ), + dec2str(tv.tv_sec), dec2str(tv.tv_usec), my_pid, my_hostname); - return t_strdup_printf - ("%s-%s.M%sP%s.%s.sieve", scriptname, dec2str(tv.tv_sec), - dec2str(tv.tv_usec), my_pid, my_hostname); + return sieve_scriptfile_from_name(scriptname); } static int sieve_storage_create_tmp @@ -327,7 +325,7 @@ T_BEGIN { dest_path = t_strconcat((*ctx)->storage->dir, "/", - (*ctx)->scriptname, ".sieve", NULL); + sieve_scriptfile_from_name((*ctx)->scriptname), NULL); failed = !sieve_storage_script_move((*ctx), dest_path); } T_END; diff -r 787832d0aa0a -r cc6d38c3f87f src/lib-sievestorage/sieve-storage-script.c --- a/src/lib-sievestorage/sieve-storage-script.c Sat Dec 17 14:47:23 2011 +0100 +++ b/src/lib-sievestorage/sieve-storage-script.c Sat Dec 17 18:58:48 2011 +0100 @@ -88,7 +88,8 @@ } T_BEGIN { - path = t_strconcat( storage->dir, "/", scriptname, ".sieve", NULL ); + path = t_strconcat + ( storage->dir, "/", sieve_scriptfile_from_name(scriptname), NULL ); script = sieve_storage_script_init_from_path(storage, path, NULL); } T_END; @@ -111,19 +112,6 @@ return script; } -const char *sieve_storage_file_get_scriptname -(const struct sieve_storage *storage ATTR_UNUSED, const char *filename) -{ - const char *ext; - - ext = strrchr(filename, '.'); - - if ( ext == NULL || ext == filename || strcmp(ext,".sieve") != 0 ) - return NULL; - - return t_strdup_until(filename, ext); -} - static int sieve_storage_read_active_link (struct sieve_storage *storage, const char **link_r) { @@ -179,7 +167,7 @@ } /* Check the script name */ - scriptname = sieve_storage_file_get_scriptname(storage, fname); + scriptname = sieve_scriptfile_get_script_name(fname); /* Warn if link is deemed to be invalid */ if ( scriptname == NULL ) { @@ -351,7 +339,7 @@ T_BEGIN { dstpath = t_strconcat - ( storage->dir, "/dovecot.orig.sieve", NULL ); + ( storage->dir, "/", sieve_scriptfile_from_name("dovecot.orig"), NULL ); if ( file_copy(storage->active_path, dstpath, 1) < 1 ) { sieve_storage_set_critical(storage, "Active sieve script file '%s' is a regular file and copying it to " @@ -408,7 +396,7 @@ for (;;) { /* First the new symlink is created with a different filename */ active_path_new = t_strdup_printf - ("%s-new.%s.P%sM%s.%s.sieve", + ("%s-new.%s.P%sM%s.%s", storage->active_path, dec2str(tv->tv_sec), my_pid, dec2str(tv->tv_usec), my_hostname); @@ -543,7 +531,7 @@ } T_BEGIN { - newfile = t_strconcat( newname, ".sieve", NULL ); + newfile = sieve_scriptfile_from_name(newname); newpath = t_strconcat( storage->dir, "/", newfile, NULL ); /* The normal rename() system call overwrites the existing file without diff -r 787832d0aa0a -r cc6d38c3f87f src/lib-sievestorage/sieve-storage-script.h --- a/src/lib-sievestorage/sieve-storage-script.h Sat Dec 17 14:47:23 2011 +0100 +++ b/src/lib-sievestorage/sieve-storage-script.h Sat Dec 17 18:58:48 2011 +0100 @@ -11,9 +11,6 @@ struct sieve_script *sieve_storage_script_init (struct sieve_storage *storage, const char *scriptname); -const char *sieve_storage_file_get_scriptname - (const struct sieve_storage *storage, const char *filename); - int sieve_storage_get_active_scriptfile (struct sieve_storage *storage, const char **file_r); diff -r 787832d0aa0a -r cc6d38c3f87f src/lib-sievestorage/sieve-storage.c --- a/src/lib-sievestorage/sieve-storage.c Sat Dec 17 14:47:23 2011 +0100 +++ b/src/lib-sievestorage/sieve-storage.c Sat Dec 17 18:58:48 2011 +0100 @@ -22,7 +22,7 @@ #include #include -#define SIEVE_DEFAULT_PATH "~/.dovecot.sieve" +#define SIEVE_DEFAULT_PATH "~/.dovecot."SIEVE_SCRIPT_FILEEXT #define MAX_DIR_CREATE_MODE 0770 diff -r 787832d0aa0a -r cc6d38c3f87f src/sieve-tools/sievec.c --- a/src/sieve-tools/sievec.c Sat Dec 17 14:47:23 2011 +0100 +++ b/src/sieve-tools/sievec.c Sat Dec 17 18:58:48 2011 +0100 @@ -112,7 +112,7 @@ break; } - if ( sieve_script_file_has_extension(dp->d_name) ) { + if ( sieve_scriptfile_has_extension(dp->d_name) ) { From dovecot at dovecot.org Mon Dec 19 09:10:44 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 19 Dec 2011 09:10:44 +0200 Subject: dovecot-2.1: sdbox: Added support for autodetection. Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/1d73272eba6c changeset: 13869:1d73272eba6c user: Timo Sirainen date: Mon Dec 19 09:10:29 2011 +0200 description: sdbox: Added support for autodetection. diffstat: src/lib-storage/index/dbox-single/sdbox-storage.c | 63 +++++++++++++++++++++- 1 files changed, 60 insertions(+), 3 deletions(-) diffs (92 lines): diff -r 103ecbf3d5c7 -r 1d73272eba6c src/lib-storage/index/dbox-single/sdbox-storage.c --- a/src/lib-storage/index/dbox-single/sdbox-storage.c Fri Dec 16 13:08:49 2011 +0200 +++ b/src/lib-storage/index/dbox-single/sdbox-storage.c Mon Dec 19 09:10:29 2011 +0200 @@ -28,6 +28,63 @@ return &storage->storage.storage; } +static const char * +sdbox_storage_find_root_dir(const struct mail_namespace *ns) +{ + bool debug = ns->mail_set->mail_debug; + const char *home, *path; + + if (mail_user_get_home(ns->owner, &home) > 0) { + path = t_strconcat(home, "/sdbox", NULL); + if (access(path, R_OK|W_OK|X_OK) == 0) { + if (debug) + i_debug("sdbox: root exists (%s)", path); + return path; + } + if (debug) + i_debug("sdbox: access(%s, rwx): failed: %m", path); + } + return NULL; +} + +static bool sdbox_storage_autodetect(const struct mail_namespace *ns, + struct mailbox_list_settings *set) +{ + bool debug = ns->mail_set->mail_debug; + struct stat st; + const char *path, *root_dir; + + if (set->root_dir != NULL) + root_dir = set->root_dir; + else { + root_dir = sdbox_storage_find_root_dir(ns); + if (root_dir == NULL) { + if (debug) + i_debug("sdbox: couldn't find root dir"); + return FALSE; + } + } + + /* NOTE: this check works for mdbox as well. we'll rely on the + autodetect ordering to catch mdbox before we get here. */ + path = t_strconcat(root_dir, "/"DBOX_MAILBOX_DIR_NAME, NULL); + if (stat(path, &st) < 0) { + if (debug) + i_debug("sdbox autodetect: stat(%s) failed: %m", path); + return FALSE; + } + + if (!S_ISDIR(st.st_mode)) { + if (debug) + i_debug("sdbox autodetect: %s not a directory", path); + return FALSE; + } + + set->root_dir = root_dir; + dbox_storage_get_list_settings(ns, set); + return TRUE; +} + static struct mailbox * sdbox_mailbox_alloc(struct mail_storage *storage, struct mailbox_list *list, const char *vname, enum mailbox_flags flags) @@ -303,7 +360,7 @@ dbox_storage_destroy, NULL, dbox_storage_get_list_settings, - NULL, + sdbox_storage_autodetect, sdbox_mailbox_alloc, NULL } @@ -314,13 +371,13 @@ .class_flags = MAIL_STORAGE_CLASS_FLAG_FILE_PER_MSG, .v = { - NULL, + NULL, sdbox_storage_alloc, dbox_storage_create, dbox_storage_destroy, NULL, dbox_storage_get_list_settings, - NULL, + sdbox_storage_autodetect, sdbox_mailbox_alloc, NULL } From dovecot at dovecot.org Mon Dec 19 09:13:10 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 19 Dec 2011 09:13:10 +0200 Subject: dovecot-2.0: sdbox: Added support for autodetection. Message-ID: details: http://hg.dovecot.org/dovecot-2.0/rev/e1fc2ab5e9f9 changeset: 13002:e1fc2ab5e9f9 user: Timo Sirainen date: Mon Dec 19 09:12:58 2011 +0200 description: sdbox: Added support for autodetection. diffstat: src/lib-storage/index/dbox-single/sdbox-storage.c | 63 +++++++++++++++++++++- 1 files changed, 60 insertions(+), 3 deletions(-) diffs (92 lines): diff -r 4ea24cabfd88 -r e1fc2ab5e9f9 src/lib-storage/index/dbox-single/sdbox-storage.c --- a/src/lib-storage/index/dbox-single/sdbox-storage.c Fri Dec 16 13:12:04 2011 +0200 +++ b/src/lib-storage/index/dbox-single/sdbox-storage.c Mon Dec 19 09:12:58 2011 +0200 @@ -28,6 +28,63 @@ return &storage->storage.storage; } +static const char * +sdbox_storage_find_root_dir(const struct mail_namespace *ns) +{ + bool debug = ns->mail_set->mail_debug; + const char *home, *path; + + if (mail_user_get_home(ns->owner, &home) > 0) { + path = t_strconcat(home, "/sdbox", NULL); + if (access(path, R_OK|W_OK|X_OK) == 0) { + if (debug) + i_debug("sdbox: root exists (%s)", path); + return path; + } + if (debug) + i_debug("sdbox: access(%s, rwx): failed: %m", path); + } + return NULL; +} + +static bool sdbox_storage_autodetect(const struct mail_namespace *ns, + struct mailbox_list_settings *set) +{ + bool debug = ns->mail_set->mail_debug; + struct stat st; + const char *path, *root_dir; + + if (set->root_dir != NULL) + root_dir = set->root_dir; + else { + root_dir = sdbox_storage_find_root_dir(ns); + if (root_dir == NULL) { + if (debug) + i_debug("sdbox: couldn't find root dir"); + return FALSE; + } + } + + /* NOTE: this check works for mdbox as well. we'll rely on the + autodetect ordering to catch mdbox before we get here. */ + path = t_strconcat(root_dir, "/"DBOX_MAILBOX_DIR_NAME, NULL); + if (stat(path, &st) < 0) { + if (debug) + i_debug("sdbox autodetect: stat(%s) failed: %m", path); + return FALSE; + } + + if (!S_ISDIR(st.st_mode)) { + if (debug) + i_debug("sdbox autodetect: %s not a directory", path); + return FALSE; + } + + set->root_dir = root_dir; + dbox_storage_get_list_settings(ns, set); + return TRUE; +} + static struct mailbox * sdbox_mailbox_alloc(struct mail_storage *storage, struct mailbox_list *list, const char *name, enum mailbox_flags flags) @@ -339,7 +396,7 @@ dbox_storage_destroy, NULL, dbox_storage_get_list_settings, - NULL, + sdbox_storage_autodetect, sdbox_mailbox_alloc, NULL } @@ -350,13 +407,13 @@ .class_flags = 0, .v = { - NULL, + NULL, sdbox_storage_alloc, dbox_storage_create, dbox_storage_destroy, NULL, dbox_storage_get_list_settings, - NULL, + sdbox_storage_autodetect, sdbox_mailbox_alloc, NULL } From dovecot at dovecot.org Tue Dec 20 13:16:56 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 20 Dec 2011 13:16:56 +0200 Subject: dovecot-2.1: dict-file: Updated dotlock settings. Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/53114d335053 changeset: 13870:53114d335053 user: Timo Sirainen date: Tue Dec 20 13:16:55 2011 +0200 description: dict-file: Updated dotlock settings. diffstat: src/lib-dict/dict-file.c | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) diffs (15 lines): diff -r 1d73272eba6c -r 53114d335053 src/lib-dict/dict-file.c --- a/src/lib-dict/dict-file.c Mon Dec 19 09:10:29 2011 +0200 +++ b/src/lib-dict/dict-file.c Tue Dec 20 13:16:55 2011 +0200 @@ -64,8 +64,9 @@ }; static struct dotlock_settings file_dict_dotlock_settings = { - .timeout = 30, - .stale_timeout = 5 + .timeout = 60*2, + .stale_timeout = 60, + .use_io_notify = TRUE }; static struct dict *file_dict_init(struct dict *driver, const char *uri, From dovecot at dovecot.org Tue Dec 20 13:19:59 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 20 Dec 2011 13:19:59 +0200 Subject: dovecot-2.0: dict-file: Updated dotlock settings. Message-ID: details: http://hg.dovecot.org/dovecot-2.0/rev/4016e43d648f changeset: 13003:4016e43d648f user: Timo Sirainen date: Tue Dec 20 13:16:55 2011 +0200 description: dict-file: Updated dotlock settings. diffstat: src/lib-dict/dict-file.c | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) diffs (15 lines): diff -r e1fc2ab5e9f9 -r 4016e43d648f src/lib-dict/dict-file.c --- a/src/lib-dict/dict-file.c Mon Dec 19 09:12:58 2011 +0200 +++ b/src/lib-dict/dict-file.c Tue Dec 20 13:16:55 2011 +0200 @@ -64,8 +64,9 @@ }; static struct dotlock_settings file_dict_dotlock_settings = { - .timeout = 30, - .stale_timeout = 5 + .timeout = 60*2, + .stale_timeout = 60, + .use_io_notify = TRUE }; static struct dict *file_dict_init(struct dict *driver, const char *uri, From dovecot at dovecot.org Tue Dec 20 14:39:52 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 20 Dec 2011 14:39:52 +0200 Subject: dovecot-2.0: script-login: Close extra fds to avoid failing with... Message-ID: details: http://hg.dovecot.org/dovecot-2.0/rev/728c54eade74 changeset: 13004:728c54eade74 user: Timo Sirainen date: Tue Dec 20 14:39:56 2011 +0200 description: script-login: Close extra fds to avoid failing with --enable-devel-checks. diffstat: src/util/script-login.c | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-) diffs (17 lines): diff -r 4016e43d648f -r 728c54eade74 src/util/script-login.c --- a/src/util/script-login.c Tue Dec 20 13:16:55 2011 +0200 +++ b/src/util/script-login.c Tue Dec 20 14:39:56 2011 +0200 @@ -126,9 +126,13 @@ i_fatal("dup2() failed: %m"); if (dup2(fd, STDOUT_FILENO) < 0) i_fatal("dup2() failed: %m"); + if (close(fd) < 0) + i_fatal("close() failed: %m"); if (conn->fd != SCRIPT_COMM_FD) { if (dup2(conn->fd, SCRIPT_COMM_FD) < 0) i_fatal("dup2() failed: %m"); + if (close(conn->fd) < 0) + i_fatal("close() failed: %m"); } /* close all listener sockets */ From dovecot at dovecot.org Tue Dec 20 14:40:09 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 20 Dec 2011 14:40:09 +0200 Subject: dovecot-2.1: script-login: Close extra fds to avoid failing with... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/477106b6f4c7 changeset: 13871:477106b6f4c7 user: Timo Sirainen date: Tue Dec 20 14:40:18 2011 +0200 description: script-login: Close extra fds to avoid failing with --enable-devel-checks. diffstat: src/util/script-login.c | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-) diffs (17 lines): diff -r 53114d335053 -r 477106b6f4c7 src/util/script-login.c --- a/src/util/script-login.c Tue Dec 20 13:16:55 2011 +0200 +++ b/src/util/script-login.c Tue Dec 20 14:40:18 2011 +0200 @@ -128,9 +128,13 @@ i_fatal("dup2() failed: %m"); if (dup2(fd, STDOUT_FILENO) < 0) i_fatal("dup2() failed: %m"); + if (close(fd) < 0) + i_fatal("close() failed: %m"); if (conn->fd != SCRIPT_COMM_FD) { if (dup2(conn->fd, SCRIPT_COMM_FD) < 0) i_fatal("dup2() failed: %m"); + if (close(conn->fd) < 0) + i_fatal("close() failed: %m"); } /* close all listener sockets */ From dovecot at dovecot.org Tue Dec 20 14:45:03 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 20 Dec 2011 14:45:03 +0200 Subject: dovecot-2.0: script-login -d: Ignore chrooting, we can't exec an... Message-ID: details: http://hg.dovecot.org/dovecot-2.0/rev/49a77e9dad66 changeset: 13005:49a77e9dad66 user: Timo Sirainen date: Tue Dec 20 14:45:09 2011 +0200 description: script-login -d: Ignore chrooting, we can't exec anything inside chroot. diffstat: src/util/script-login.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diffs (12 lines): diff -r 728c54eade74 -r 49a77e9dad66 src/util/script-login.c --- a/src/util/script-login.c Tue Dec 20 14:39:56 2011 +0200 +++ b/src/util/script-login.c Tue Dec 20 14:45:09 2011 +0200 @@ -119,6 +119,8 @@ if (mail_storage_service_lookup(service_ctx, &input, &user, &error) <= 0) i_fatal("%s", error); mail_storage_service_restrict_setenv(service_ctx, user); + /* we can't exec anything in a chroot */ + env_remove("RESTRICT_CHROOT"); restrict_access_by_env(getenv("HOME"), TRUE); } From dovecot at dovecot.org Tue Dec 20 14:45:12 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 20 Dec 2011 14:45:12 +0200 Subject: dovecot-2.1: script-login -d: Ignore chrooting, we can't exec an... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/73fbc40b860f changeset: 13872:73fbc40b860f user: Timo Sirainen date: Tue Dec 20 14:45:22 2011 +0200 description: script-login -d: Ignore chrooting, we can't exec anything inside chroot. diffstat: src/util/script-login.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diffs (12 lines): diff -r 477106b6f4c7 -r 73fbc40b860f src/util/script-login.c --- a/src/util/script-login.c Tue Dec 20 14:40:18 2011 +0200 +++ b/src/util/script-login.c Tue Dec 20 14:45:22 2011 +0200 @@ -121,6 +121,8 @@ if (mail_storage_service_lookup(service_ctx, &input, &user, &error) <= 0) i_fatal("%s", error); mail_storage_service_restrict_setenv(service_ctx, user); + /* we can't exec anything in a chroot */ + env_remove("RESTRICT_CHROOT"); restrict_access_by_env(getenv("HOME"), TRUE); } From pigeonhole at rename-it.nl Tue Dec 20 21:05:26 2011 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Tue, 20 Dec 2011 20:05:26 +0100 Subject: dovecot-2.1-pigeonhole: lib-sieve: adjusted code fetch api for h... Message-ID: details: http://hg.rename-it.nl/dovecot-2.1-pigeonhole/rev/35639e4925a7 changeset: 1584:35639e4925a7 user: Stephan Bosch date: Tue Dec 20 20:05:21 2011 +0100 description: lib-sieve: adjusted code fetch api for handling omitted operands better. Removes quite a bit of duplicated source code. diffstat: src/lib-sieve/cmd-redirect.c | 4 +- src/lib-sieve/ext-fileinto.c | 4 +- src/lib-sieve/plugins/date/tst-date.c | 26 +------- src/lib-sieve/plugins/editheader/cmd-deleteheader.c | 26 +------- src/lib-sieve/plugins/imap4flags/tag-flags.c | 61 ++++++++------------ src/lib-sieve/sieve-code.c | 59 ++++++++++++++++++- src/lib-sieve/sieve-code.h | 10 ++- 7 files changed, 98 insertions(+), 92 deletions(-) diffs (truncated from 394 to 300 lines): diff -r 66b7b1636c8c -r 35639e4925a7 src/lib-sieve/cmd-redirect.c --- a/src/lib-sieve/cmd-redirect.c Sat Dec 17 18:58:48 2011 +0100 +++ b/src/lib-sieve/cmd-redirect.c Tue Dec 20 20:05:21 2011 +0100 @@ -209,8 +209,8 @@ return ret; /* Read the address */ - if ( (ret=sieve_opr_string_read_ex(renv, address, "address", &redirect, - &literal_address)) <= 0 ) + if ( (ret=sieve_opr_string_read_ex + (renv, address, "address", FALSE, &redirect, &literal_address)) <= 0 ) return ret; /* diff -r 66b7b1636c8c -r 35639e4925a7 src/lib-sieve/ext-fileinto.c --- a/src/lib-sieve/ext-fileinto.c Sat Dec 17 18:58:48 2011 +0100 +++ b/src/lib-sieve/ext-fileinto.c Tue Dec 20 20:05:21 2011 +0100 @@ -183,8 +183,8 @@ return ret; /* Folder operand */ - if ( (ret=sieve_opr_string_read_ex(renv, address, "folder", &folder, - &folder_literal)) <= 0 ) + if ( (ret=sieve_opr_string_read_ex + (renv, address, "folder", FALSE, &folder, &folder_literal)) <= 0 ) return ret; /* diff -r 66b7b1636c8c -r 35639e4925a7 src/lib-sieve/plugins/date/tst-date.c --- a/src/lib-sieve/plugins/date/tst-date.c Sat Dec 17 18:58:48 2011 +0100 +++ b/src/lib-sieve/plugins/date/tst-date.c Tue Dec 20 20:05:21 2011 +0100 @@ -331,7 +331,6 @@ { int opt_code = 0; const struct sieve_operation *op = denv->oprtn; - struct sieve_operand operand; sieve_code_dumpf(denv, "%s", sieve_operation_mnemonic(op)); sieve_code_descend(denv); @@ -347,18 +346,8 @@ switch ( opt_code ) { case OPT_DATE_ZONE: - if ( !sieve_operand_read(denv->sblock, address, "zone", &operand) ) { - sieve_code_dumpf(denv, "ERROR: INVALID OPERAND"); + if ( !sieve_opr_string_dump_ex(denv, address, "zone", "ORIGINAL") ) return FALSE; - } - - if ( sieve_operand_is_omitted(&operand) ) { - sieve_code_dumpf(denv, "zone: ORIGINAL"); - } else { - if ( !sieve_opr_string_dump_data - (denv, &operand, address, "zone") ) - return FALSE; - } break; default: return FALSE; @@ -388,7 +377,6 @@ SIEVE_MATCH_TYPE_DEFAULT(is_match_type); struct sieve_comparator cmp = SIEVE_COMPARATOR_DEFAULT(i_ascii_casemap_comparator); - struct sieve_operand oprnd; string_t *date_part = NULL, *zone = NULL; struct sieve_stringlist *hdr_list = NULL, *hdr_value_list; struct sieve_stringlist *value_list, *key_list; @@ -408,18 +396,10 @@ switch ( opt_code ) { case OPT_DATE_ZONE: - if ( (ret=sieve_operand_runtime_read(renv, address, "zone", &oprnd)) - <= 0 ) + if ( (ret=sieve_opr_string_read_ex + (renv, address, "zone", TRUE, &zone, &zone_literal)) <= 0 ) return ret; - if ( !sieve_operand_is_omitted(&oprnd) ) { - if ( (ret=sieve_opr_string_read_data - (renv, &oprnd, address, "zone", &zone)) <= 0 ) - return ret; - - zone_literal = sieve_operand_is_string_literal(&oprnd); - } - zone_specified = TRUE; break; default: diff -r 66b7b1636c8c -r 35639e4925a7 src/lib-sieve/plugins/editheader/cmd-deleteheader.c --- a/src/lib-sieve/plugins/editheader/cmd-deleteheader.c Sat Dec 17 18:58:48 2011 +0100 +++ b/src/lib-sieve/plugins/editheader/cmd-deleteheader.c Tue Dec 20 20:05:21 2011 +0100 @@ -316,7 +316,6 @@ static bool cmd_deleteheader_operation_dump (const struct sieve_dumptime_env *denv, sieve_size_t *address) { - struct sieve_operand oprnd; int opt_code = 0; sieve_code_dumpf(denv, "DELETEHEADER"); @@ -347,19 +346,7 @@ if ( !sieve_opr_string_dump(denv, address, "field name") ) return FALSE; - sieve_code_mark(denv); - - if ( !sieve_operand_read - (denv->sblock, address, "value patterns", &oprnd) ) { - sieve_code_dumpf(denv, "ERROR: INVALID OPERAND"); - return FALSE; - } - - if ( sieve_operand_is_omitted(&oprnd) ) - return TRUE; - - return sieve_opr_stringlist_dump_data - (denv, &oprnd, address, "value patterns"); + return sieve_opr_stringlist_dump_ex(denv, address, "value patterns", ""); } /* @@ -371,7 +358,6 @@ { const struct sieve_extension *this_ext = renv->oprtn->ext; int opt_code = 0; - struct sieve_operand oprnd; struct sieve_comparator cmp = SIEVE_COMPARATOR_DEFAULT(i_ascii_casemap_comparator); struct sieve_match_type mcht = @@ -423,13 +409,9 @@ <= 0 ) return ret; - /* Read value-patterns */ - if ( (ret=sieve_operand_runtime_read - (renv, address, "value-patterns", &oprnd)) <= 0 ) - return ret; - - if ( !sieve_operand_is_omitted(&oprnd) && (ret=sieve_opr_stringlist_read_data - (renv, &oprnd, address, "value-patterns", &vpattern_list)) <= 0 ) + /* Read value-patterns */ + if ( (ret=sieve_opr_stringlist_read_ex + (renv, address, "value-patterns", TRUE, &vpattern_list)) <= 0 ) return ret; /* diff -r 66b7b1636c8c -r 35639e4925a7 src/lib-sieve/plugins/imap4flags/tag-flags.c --- a/src/lib-sieve/plugins/imap4flags/tag-flags.c Sat Dec 17 18:58:48 2011 +0100 +++ b/src/lib-sieve/plugins/imap4flags/tag-flags.c Tue Dec 20 20:05:21 2011 +0100 @@ -197,19 +197,7 @@ (const struct sieve_side_effect *seffect ATTR_UNUSED, const struct sieve_dumptime_env *denv, sieve_size_t *address) { - struct sieve_operand oprnd; - - if ( !sieve_operand_read(denv->sblock, address, "flags", &oprnd) ) { - sieve_code_dumpf(denv, "ERROR: INVALID OPERAND"); - return FALSE; - } - - if ( sieve_operand_is_omitted(&oprnd) ) { - sieve_code_dumpf(denv, "flags: INTERNAL"); - return TRUE; - } - - return sieve_opr_stringlist_dump_data(denv, &oprnd, address, "flags"); + return sieve_opr_stringlist_dump_ex(denv, address, "flags", "INTERNAL"); } static struct seff_flags_context *seff_flags_get_implicit_context @@ -252,43 +240,30 @@ return ctx; } -static int seff_flags_read_context +static int seff_flags_do_read_context (const struct sieve_side_effect *seffect, const struct sieve_runtime_env *renv, sieve_size_t *address, void **se_context) { - struct sieve_operand oprnd; pool_t pool = sieve_result_pool(renv->result); struct seff_flags_context *ctx; string_t *flags_item; - struct sieve_stringlist *flag_list; - int ret; + struct sieve_stringlist *flag_list = NULL; + int ret; + + if ( (ret=sieve_opr_stringlist_read_ex + (renv, address, "flags", TRUE, &flag_list)) <= 0 ) + return ret; - t_push(); - - /* Check whether explicit flag list operand is present */ - if ( (ret=sieve_operand_runtime_read(renv, address, "flags", &oprnd)) <= 0 ) { - t_pop(); - return ret; - } - - if ( sieve_operand_is_omitted(&oprnd) ) { + if ( flag_list == NULL ) { /* Flag list is omitted, use current value of internal * variable to construct side effect context. */ *se_context = seff_flags_get_implicit_context (SIEVE_OBJECT_EXTENSION(seffect), renv->result); - t_pop(); return SIEVE_EXEC_OK; } - - /* Read flag-list */ - if ( (ret=sieve_opr_stringlist_read_data - (renv, &oprnd, address, NULL, &flag_list)) <= 0 ) { - t_pop(); - return ret; - } - + ctx = p_new(pool, struct seff_flags_context, 1); p_array_init(&ctx->keywords, pool, 2); @@ -325,12 +300,24 @@ } *se_context = (void *) ctx; - - t_pop(); return SIEVE_EXEC_OK; } +static int seff_flags_read_context +(const struct sieve_side_effect *seffect, + const struct sieve_runtime_env *renv, sieve_size_t *address, + void **se_context) +{ + int ret; + + T_BEGIN { + ret = seff_flags_do_read_context(seffect, renv, address, se_context); + } T_END; + + return ret; +} + /* Result verification */ static int seff_flags_merge diff -r 66b7b1636c8c -r 35639e4925a7 src/lib-sieve/sieve-code.c --- a/src/lib-sieve/sieve-code.c Sat Dec 17 18:58:48 2011 +0100 +++ b/src/lib-sieve/sieve-code.c Tue Dec 20 20:05:21 2011 +0100 @@ -536,7 +536,7 @@ bool sieve_opr_string_dump_ex (const struct sieve_dumptime_env *denv, sieve_size_t *address, - const char *field_name, bool *literal_r) + const char *field_name, const char *omitted_value) { struct sieve_operand operand; @@ -546,7 +546,11 @@ return FALSE; } - *literal_r = sieve_operand_is_string_literal(&operand); + if ( omitted_value != NULL && sieve_operand_is_omitted(&operand) ) { + if ( *omitted_value != '\0' ) + sieve_code_dumpf(denv, "%s: %s", field_name, omitted_value); + return TRUE; + } return sieve_opr_string_dump_data(denv, &operand, address, field_name); } @@ -592,7 +596,7 @@ int sieve_opr_string_read_ex (const struct sieve_runtime_env *renv, sieve_size_t *address, - const char *field_name, string_t **str_r, bool *literal_r) + const char *field_name, bool optional, string_t **str_r, bool *literal_r) { struct sieve_operand operand; int ret; @@ -601,7 +605,13 @@ <= 0 ) return ret; - *literal_r = sieve_operand_is_string_literal(&operand); + if ( optional && sieve_operand_is_omitted(&operand) ) { + *str_r = NULL; + return TRUE; + } + + if ( literal_r != NULL ) + *literal_r = sieve_operand_is_string_literal(&operand); return sieve_opr_string_read_data(renv, &operand, address, field_name, str_r); } @@ -732,6 +742,27 @@ return sieve_opr_stringlist_dump_data(denv, &operand, address, field_name); From dovecot at dovecot.org Wed Dec 21 14:40:26 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 21 Dec 2011 14:40:26 +0200 Subject: dovecot-2.1: imapc: When searching for unused index dirs, ignore... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/056934abd2ef changeset: 13873:056934abd2ef user: Timo Sirainen date: Wed Dec 21 14:40:29 2011 +0200 description: imapc: When searching for unused index dirs, ignore any ACLs. This also fixes a crash. diffstat: src/lib-storage/index/imapc/imapc-list.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (11 lines): diff -r 73fbc40b860f -r 056934abd2ef src/lib-storage/index/imapc/imapc-list.c --- a/src/lib-storage/index/imapc/imapc-list.c Tue Dec 20 14:45:22 2011 +0200 +++ b/src/lib-storage/index/imapc/imapc-list.c Wed Dec 21 14:40:29 2011 +0200 @@ -294,6 +294,7 @@ return; iter = mailbox_list_iter_init(fs_list, "*", + MAILBOX_LIST_ITER_RAW_LIST | MAILBOX_LIST_ITER_NO_AUTO_BOXES | MAILBOX_LIST_ITER_RETURN_NO_FLAGS); while ((info = mailbox_list_iter_next(iter)) != NULL) { From pigeonhole at rename-it.nl Tue Dec 27 12:56:33 2011 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Tue, 27 Dec 2011 11:56:33 +0100 Subject: dovecot-2.1-pigeonhole: lib-sieve-tool: mail_raw: started using ... Message-ID: details: http://hg.rename-it.nl/dovecot-2.1-pigeonhole/rev/fc9923837fa0 changeset: 1585:fc9923837fa0 user: Stephan Bosch date: Tue Dec 27 11:56:25 2011 +0100 description: lib-sieve-tool: mail_raw: started using mail_temp_dir setting. diffstat: src/lib-sieve-tool/mail-raw.c | 15 ++++++++------- 1 files changed, 8 insertions(+), 7 deletions(-) diffs (51 lines): diff -r 35639e4925a7 -r fc9923837fa0 src/lib-sieve-tool/mail-raw.c --- a/src/lib-sieve-tool/mail-raw.c Tue Dec 20 20:05:21 2011 +0100 +++ b/src/lib-sieve-tool/mail-raw.c Tue Dec 27 11:56:25 2011 +0100 @@ -56,14 +56,15 @@ */ static int seekable_fd_callback -(const char **path_r, void *context ATTR_UNUSED) +(const char **path_r, void *context) { + struct mail_user *ruser = (struct mail_user *)context; const char *dir, *p; string_t *path; int fd; - path = t_str_new(128); - str_append(path, "/tmp/dovecot.sieve-tool."); + path = t_str_new(128); + mail_user_set_get_temp_prefix(path, ruser->set); fd = safe_mkstemp(path, 0600, (uid_t)-1, (gid_t)-1); if (fd == -1 && errno == ENOENT) { dir = str_c(path); @@ -95,8 +96,8 @@ return fd; } -static struct istream *create_raw_stream -(int fd, time_t *mtime_r, const char **sender) +static struct istream *mail_raw_create_stream +(struct mail_user *ruser, int fd, time_t *mtime_r, const char **sender) { struct istream *input, *input2, *input_list[2]; const unsigned char *data; @@ -143,7 +144,7 @@ input_list[0] = input2; input_list[1] = NULL; input = i_stream_create_seekable(input_list, MAIL_MAX_MEMORY_BUFFER, - seekable_fd_callback, NULL); + seekable_fd_callback, (void*)ruser); i_stream_unref(&input2); return input; } @@ -227,7 +228,7 @@ if ( path == NULL || strcmp(path, "-") == 0 ) { path = NULL; - input = create_raw_stream(0, &mtime, &sender); + input = mail_raw_create_stream(ruser, 0, &mtime, &sender); } mailr = mail_raw_create(ruser, input, path, sender, mtime); From pigeonhole at rename-it.nl Tue Dec 27 23:21:58 2011 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Tue, 27 Dec 2011 22:21:58 +0100 Subject: dovecot-2.1-pigeonhole: lib-sieve: fixed bug in message snapshots. Message-ID: details: http://hg.rename-it.nl/dovecot-2.1-pigeonhole/rev/d17f4a699ad2 changeset: 1588:d17f4a699ad2 user: Stephan Bosch date: Tue Dec 27 22:21:34 2011 +0100 description: lib-sieve: fixed bug in message snapshots. Message substitutions would not always cause a proper snapshot. diffstat: src/lib-sieve/sieve-message.c | 5 ++++- 1 files changed, 4 insertions(+), 1 deletions(-) diffs (36 lines): diff -r c58e9eb1010d -r d17f4a699ad2 src/lib-sieve/sieve-message.c --- a/src/lib-sieve/sieve-message.c Tue Dec 27 21:29:19 2011 +0100 +++ b/src/lib-sieve/sieve-message.c Tue Dec 27 22:21:34 2011 +0100 @@ -78,6 +78,7 @@ ARRAY_DEFINE(ext_contexts, void *); unsigned int edit_snapshot:1; + unsigned int substitute_snapshot:1; }; /* @@ -376,7 +377,7 @@ return -1; } - if ( msgctx->edit_snapshot ) { + if ( msgctx->substitute_snapshot ) { version = sieve_message_version_new(msgctx); } else { version = sieve_message_version_get(msgctx); @@ -392,6 +393,7 @@ sieve_message_context_flush(msgctx); + msgctx->substitute_snapshot = FALSE; msgctx->edit_snapshot = FALSE; return 1; @@ -436,6 +438,7 @@ (struct sieve_message_context *msgctx) { msgctx->edit_snapshot = TRUE; + msgctx->substitute_snapshot = TRUE; } /* From pigeonhole at rename-it.nl Tue Dec 27 22:12:02 2011 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Tue, 27 Dec 2011 21:12:02 +0100 Subject: dovecot-2.1-pigeonhole: lib-sieve: added support for substitutin... Message-ID: details: http://hg.rename-it.nl/dovecot-2.1-pigeonhole/rev/4cc6444438f6 changeset: 1586:4cc6444438f6 user: Stephan Bosch date: Tue Dec 27 21:11:49 2011 +0100 description: lib-sieve: added support for substituting the entire message. This is needed for the new extprograms plugin. diffstat: src/lib-sieve/cmd-discard.c | 2 +- src/lib-sieve/cmd-keep.c | 2 - src/lib-sieve/cmd-redirect.c | 4 +- src/lib-sieve/ext-reject.c | 2 +- src/lib-sieve/plugins/body/ext-body-common.c | 11 +- src/lib-sieve/plugins/enotify/cmd-notify.c | 2 +- src/lib-sieve/plugins/notify/cmd-notify.c | 2 +- src/lib-sieve/plugins/vacation/cmd-vacation.c | 2 +- src/lib-sieve/sieve-actions.c | 4 +- src/lib-sieve/sieve-message.c | 223 ++++++++++++++++++++++++++----- src/lib-sieve/sieve-message.h | 7 +- src/lib-sieve/sieve-result.c | 24 ++- src/lib-sieve/sieve-result.h | 4 +- src/testsuite/testsuite-message.c | 14 +- 14 files changed, 226 insertions(+), 77 deletions(-) diffs (truncated from 646 to 300 lines): diff -r fc9923837fa0 -r 4cc6444438f6 src/lib-sieve/cmd-discard.c --- a/src/lib-sieve/cmd-discard.c Tue Dec 27 11:56:25 2011 +0100 +++ b/src/lib-sieve/cmd-discard.c Tue Dec 27 21:11:49 2011 +0100 @@ -109,7 +109,7 @@ "discard action; cancel implicit keep"); if ( sieve_result_add_action - (renv, NULL, &act_discard, NULL, NULL, 0) < 0 ) + (renv, NULL, &act_discard, NULL, NULL, 0, FALSE) < 0 ) return SIEVE_EXEC_FAILURE; return SIEVE_EXEC_OK; diff -r fc9923837fa0 -r 4cc6444438f6 src/lib-sieve/cmd-keep.c --- a/src/lib-sieve/cmd-keep.c Tue Dec 27 11:56:25 2011 +0100 +++ b/src/lib-sieve/cmd-keep.c Tue Dec 27 21:11:49 2011 +0100 @@ -107,8 +107,6 @@ if ( sieve_result_add_keep(renv, slist) < 0 ) return SIEVE_EXEC_FAILURE; - sieve_message_snapshot(renv->msgctx); - return SIEVE_EXEC_OK; } diff -r fc9923837fa0 -r 4cc6444438f6 src/lib-sieve/cmd-redirect.c --- a/src/lib-sieve/cmd-redirect.c Tue Dec 27 11:56:25 2011 +0100 +++ b/src/lib-sieve/cmd-redirect.c Tue Dec 27 21:11:49 2011 +0100 @@ -248,11 +248,9 @@ if ( sieve_result_add_action (renv, NULL, &act_redirect, slist, (void *) act, - svinst->max_redirects) < 0 ) + svinst->max_redirects, TRUE) < 0 ) return SIEVE_EXEC_FAILURE; - sieve_message_snapshot(renv->msgctx); - return SIEVE_EXEC_OK; } diff -r fc9923837fa0 -r 4cc6444438f6 src/lib-sieve/ext-reject.c --- a/src/lib-sieve/ext-reject.c Tue Dec 27 11:56:25 2011 +0100 +++ b/src/lib-sieve/ext-reject.c Tue Dec 27 21:11:49 2011 +0100 @@ -306,7 +306,7 @@ act->ereject = ( sieve_operation_is(oprtn, ereject_operation) ); if ( sieve_result_add_action - (renv, this_ext, &act_reject, slist, (void *) act, 0) < 0 ) + (renv, this_ext, &act_reject, slist, (void *) act, 0, FALSE) < 0 ) return SIEVE_EXEC_FAILURE; return SIEVE_EXEC_OK; diff -r fc9923837fa0 -r 4cc6444438f6 src/lib-sieve/plugins/body/ext-body-common.c --- a/src/lib-sieve/plugins/body/ext-body-common.c Tue Dec 27 11:56:25 2011 +0100 +++ b/src/lib-sieve/plugins/body/ext-body-common.c Tue Dec 27 21:11:49 2011 +0100 @@ -192,9 +192,10 @@ * Add requested message body parts to the cache that are missing. */ static bool ext_body_parts_add_missing -(const struct sieve_message_data *msgdata, struct ext_body_message_context *ctx, +(struct sieve_message_context *msgctx, struct ext_body_message_context *ctx, const char * const *content_types, bool decode_to_plain) { + struct mail *mail = sieve_message_get_mail(msgctx); struct ext_body_part_cached *body_part = NULL, *header_part = NULL; struct message_parser_ctx *parser; struct message_decoder_context *decoder; @@ -212,9 +213,9 @@ } /* Get the message stream */ - if ( mail_get_stream(msgdata->mail, NULL, NULL, &input) < 0 ) + if ( mail_get_stream(mail, NULL, NULL, &input) < 0 ) return FALSE; - //if (mail_get_parts(msgdata->mail, &parts) < 0) + //if (mail_get_parts(mail, &parts) < 0) // return FALSE; buffer_set_used_size(ctx->tmp_buffer, 0); @@ -395,7 +396,7 @@ T_BEGIN { /* Fill the return_body_parts array */ if ( !ext_body_parts_add_missing - (renv->msgdata, ctx, content_types, decode_to_plain != 0) ) + (renv->msgctx, ctx, content_types, decode_to_plain != 0) ) result = FALSE; } T_END; @@ -419,7 +420,7 @@ buffer_t *buf; if ( ctx->raw_body == NULL ) { - struct mail *mail = renv->msgdata->mail; + struct mail *mail = sieve_message_get_mail(renv->msgctx); struct istream *input; struct message_size hdr_size, body_size; const unsigned char *data; diff -r fc9923837fa0 -r 4cc6444438f6 src/lib-sieve/plugins/enotify/cmd-notify.c --- a/src/lib-sieve/plugins/enotify/cmd-notify.c Tue Dec 27 11:56:25 2011 +0100 +++ b/src/lib-sieve/plugins/enotify/cmd-notify.c Tue Dec 27 21:11:49 2011 +0100 @@ -487,7 +487,7 @@ act->from = p_strdup(pool, str_c(from)); if ( sieve_result_add_action - (renv, this_ext, &act_notify, slist, (void *) act, 0) < 0 ) + (renv, this_ext, &act_notify, slist, (void *) act, 0, FALSE) < 0 ) return SIEVE_EXEC_FAILURE; return SIEVE_EXEC_OK; diff -r fc9923837fa0 -r 4cc6444438f6 src/lib-sieve/plugins/notify/cmd-notify.c --- a/src/lib-sieve/plugins/notify/cmd-notify.c Tue Dec 27 11:56:25 2011 +0100 +++ b/src/lib-sieve/plugins/notify/cmd-notify.c Tue Dec 27 21:11:49 2011 +0100 @@ -554,7 +554,7 @@ } if ( sieve_result_add_action - (renv, this_ext, &act_notify_old, NULL, (void *) act, 0) < 0 ) + (renv, this_ext, &act_notify_old, NULL, (void *) act, 0, FALSE) < 0 ) return SIEVE_EXEC_FAILURE; } diff -r fc9923837fa0 -r 4cc6444438f6 src/lib-sieve/plugins/vacation/cmd-vacation.c --- a/src/lib-sieve/plugins/vacation/cmd-vacation.c Tue Dec 27 11:56:25 2011 +0100 +++ b/src/lib-sieve/plugins/vacation/cmd-vacation.c Tue Dec 27 21:11:49 2011 +0100 @@ -728,7 +728,7 @@ } if ( sieve_result_add_action - (renv, this_ext, &act_vacation, slist, (void *) act, 0) < 0 ) + (renv, this_ext, &act_vacation, slist, (void *) act, 0, FALSE) < 0 ) return SIEVE_EXEC_FAILURE; return SIEVE_EXEC_OK; diff -r fc9923837fa0 -r 4cc6444438f6 src/lib-sieve/sieve-actions.c --- a/src/lib-sieve/sieve-actions.c Tue Dec 27 11:56:25 2011 +0100 +++ b/src/lib-sieve/sieve-actions.c Tue Dec 27 21:11:49 2011 +0100 @@ -231,8 +231,8 @@ act = p_new(pool, struct act_store_context, 1); act->mailbox = p_strdup(pool, mailbox); - return sieve_result_add_action(renv, NULL, &act_store, seffects, - (void *) act, 0); + return sieve_result_add_action + (renv, NULL, &act_store, seffects, (void *)act, 0, TRUE); } void sieve_act_store_add_flags diff -r fc9923837fa0 -r 4cc6444438f6 src/lib-sieve/sieve-message.c --- a/src/lib-sieve/sieve-message.c Tue Dec 27 11:56:25 2011 +0100 +++ b/src/lib-sieve/sieve-message.c Tue Dec 27 21:11:49 2011 +0100 @@ -7,7 +7,12 @@ #include "array.h" #include "str.h" #include "str-sanitize.h" +#include "istream.h" #include "mail-storage.h" +#include "mail-user.h" +#include "master-service.h" +#include "master-service-settings.h" +#include "raw-storage.h" #include "edit-mail.h" @@ -39,12 +44,21 @@ * Message context */ +struct sieve_message_version { + struct mail *mail; + struct mailbox *box; + struct mailbox_transaction_context *trans; + struct edit_mail *edit_mail; +}; + struct sieve_message_context { pool_t pool; + pool_t context_pool; int refcount; struct sieve_instance *svinst; + struct mail_user *mail_user; const struct sieve_message_data *msgdata; /* Normalized envelope addresses */ @@ -55,9 +69,10 @@ const struct sieve_address *envelope_orig_recipient; const struct sieve_address *envelope_final_recipient; - /* Edited mail struct */ + /* Message versioning */ - struct edit_mail *edit_mail; + struct mail_user *raw_mail_user; + ARRAY_DEFINE(versions, struct sieve_message_version); /* Context data for extensions */ ARRAY_DEFINE(ext_contexts, void *); @@ -65,18 +80,63 @@ unsigned int edit_snapshot:1; }; +/* + * Message versions + */ + +static inline struct sieve_message_version *sieve_message_version_new +(struct sieve_message_context *msgctx) +{ + return array_append_space(&msgctx->versions); +} + +static inline struct sieve_message_version *sieve_message_version_get +(struct sieve_message_context *msgctx) +{ + struct sieve_message_version *versions; + unsigned int count; + + versions = array_get_modifiable(&msgctx->versions, &count); + if ( count == 0 ) + return array_append_space(&msgctx->versions); + + return &versions[count-1]; +} + +static inline void sieve_message_version_free +(struct sieve_message_version *version) +{ + if ( version->edit_mail != NULL ) { + edit_mail_unwrap(&version->edit_mail); + version->edit_mail = NULL; + } + + if ( version->mail != NULL ) { + mail_free(&version->mail); + mailbox_transaction_rollback(&version->trans); + mailbox_free(&version->box); + version->mail = NULL; + } +} + +/* + * Message context object + */ + struct sieve_message_context *sieve_message_context_create -(struct sieve_instance *svinst, const struct sieve_message_data *msgdata) +(struct sieve_instance *svinst, struct mail_user *mail_user, + const struct sieve_message_data *msgdata) { struct sieve_message_context *msgctx; - + msgctx = i_new(struct sieve_message_context, 1); msgctx->refcount = 1; msgctx->svinst = svinst; + msgctx->mail_user = mail_user; msgctx->msgdata = msgdata; - sieve_message_context_flush(msgctx); + sieve_message_context_reset(msgctx); return msgctx; } @@ -86,50 +146,69 @@ msgctx->refcount++; } -void sieve_message_context_unref(struct sieve_message_context **msgctx) +static void sieve_message_context_clear(struct sieve_message_context *msgctx) { - i_assert((*msgctx)->refcount > 0); - - if (--(*msgctx)->refcount != 0) - return; - - pool_unref(&((*msgctx)->pool)); - - if ( (*msgctx)->edit_mail != NULL ) - edit_mail_unwrap(&(*msgctx)->edit_mail); - - i_free(*msgctx); - *msgctx = NULL; -} - -void sieve_message_context_flush(struct sieve_message_context *msgctx) -{ - pool_t pool; + struct sieve_message_version *versions; + unsigned int count, i; if ( msgctx->pool != NULL ) { - pool_unref(&msgctx->pool); + versions = array_get_modifiable(&msgctx->versions, &count); + + for ( i = 0; i < count; i++ ) { + sieve_message_version_free(&versions[i]); + } + From pigeonhole at rename-it.nl Tue Dec 27 22:29:50 2011 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Tue, 27 Dec 2011 21:29:50 +0100 Subject: dovecot-2.1-pigeonhole: lib-sieve: fixed memory leak in previous... Message-ID: details: http://hg.rename-it.nl/dovecot-2.1-pigeonhole/rev/c58e9eb1010d changeset: 1587:c58e9eb1010d user: Stephan Bosch date: Tue Dec 27 21:29:19 2011 +0100 description: lib-sieve: fixed memory leak in previous change. diffstat: src/lib-sieve/sieve-message.c | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diffs (13 lines): diff -r 4cc6444438f6 -r c58e9eb1010d src/lib-sieve/sieve-message.c --- a/src/lib-sieve/sieve-message.c Tue Dec 27 21:11:49 2011 +0100 +++ b/src/lib-sieve/sieve-message.c Tue Dec 27 21:29:19 2011 +0100 @@ -179,6 +179,9 @@ sieve_message_context_clear(*msgctx); + if ( (*msgctx)->context_pool != NULL ) + pool_unref(&((*msgctx)->context_pool)); + i_free(*msgctx); *msgctx = NULL; } From dovecot at dovecot.org Thu Dec 29 14:47:20 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 29 Dec 2011 14:47:20 +0200 Subject: dovecot-2.1: mail-log: Removed unnecessary code. Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/3c7e01a5c7b7 changeset: 13874:3c7e01a5c7b7 user: Timo Sirainen date: Thu Dec 29 11:19:52 2011 +0200 description: mail-log: Removed unnecessary code. diffstat: src/plugins/mail-log/Makefile.am | 2 -- src/plugins/mail-log/mail-log-plugin.c | 2 +- 2 files changed, 1 insertions(+), 3 deletions(-) diffs (25 lines): diff -r 056934abd2ef -r 3c7e01a5c7b7 src/plugins/mail-log/Makefile.am --- a/src/plugins/mail-log/Makefile.am Wed Dec 21 14:40:29 2011 +0200 +++ b/src/plugins/mail-log/Makefile.am Thu Dec 29 11:19:52 2011 +0200 @@ -4,8 +4,6 @@ -I$(top_srcdir)/src/lib-imap \ -I$(top_srcdir)/src/lib-index \ -I$(top_srcdir)/src/lib-storage \ - -I$(top_srcdir)/src/lib-storage/index \ - -I$(top_srcdir)/src/lib-storage/index/maildir \ -I$(top_srcdir)/src/plugins/notify NOPLUGIN_LDFLAGS = diff -r 056934abd2ef -r 3c7e01a5c7b7 src/plugins/mail-log/mail-log-plugin.c --- a/src/plugins/mail-log/mail-log-plugin.c Wed Dec 21 14:40:29 2011 +0200 +++ b/src/plugins/mail-log/mail-log-plugin.c Thu Dec 29 11:19:52 2011 +0200 @@ -6,8 +6,8 @@ #include "str.h" #include "str-sanitize.h" #include "imap-util.h" +#include "mail-user.h" #include "mail-storage-private.h" -#include "mailbox-list-private.h" #include "notify-plugin.h" #include "mail-log-plugin.h" From dovecot at dovecot.org Thu Dec 29 14:47:20 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 29 Dec 2011 14:47:20 +0200 Subject: dovecot-2.1: Merged dsync into "doveadm dsync". Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/4c827134997f changeset: 13875:4c827134997f user: Timo Sirainen date: Thu Dec 29 14:43:45 2011 +0200 description: Merged dsync into "doveadm dsync". dsync symlink is installed for backwards compatibility. diffstat: .hgignore | 1 - configure.in | 2 +- src/Makefile.am | 1 - src/doveadm/Makefile.am | 7 + src/doveadm/client-connection.c | 17 +- src/doveadm/doveadm-mail.c | 68 +- src/doveadm/doveadm-mail.h | 15 +- src/doveadm/doveadm-settings.c | 2 + src/doveadm/doveadm-settings.h | 1 + src/doveadm/doveadm.c | 3 + src/doveadm/dsync/Makefile.am | 80 + src/doveadm/dsync/doveadm-dsync.c | 494 +++++ src/doveadm/dsync/doveadm-dsync.h | 10 + src/doveadm/dsync/dsync-brain-msgs-new.c | 392 ++++ src/doveadm/dsync/dsync-brain-msgs.c | 537 ++++++ src/doveadm/dsync/dsync-brain-private.h | 144 + src/doveadm/dsync/dsync-brain.c | 917 +++++++++++ src/doveadm/dsync/dsync-brain.h | 28 + src/doveadm/dsync/dsync-data.c | 146 + src/doveadm/dsync/dsync-data.h | 84 + src/doveadm/dsync/dsync-proxy-client.c | 1191 ++++++++++++++ src/doveadm/dsync/dsync-proxy-server-cmd.c | 608 +++++++ src/doveadm/dsync/dsync-proxy-server.c | 205 ++ src/doveadm/dsync/dsync-proxy-server.h | 46 + src/doveadm/dsync/dsync-proxy.c | 412 ++++ src/doveadm/dsync/dsync-proxy.h | 55 + src/doveadm/dsync/dsync-worker-local.c | 1899 +++++++++++++++++++++++ src/doveadm/dsync/dsync-worker-private.h | 105 + src/doveadm/dsync/dsync-worker.c | 285 +++ src/doveadm/dsync/dsync-worker.h | 164 + src/doveadm/dsync/test-dsync-brain-msgs.c | 670 ++++++++ src/doveadm/dsync/test-dsync-brain.c | 289 +++ src/doveadm/dsync/test-dsync-common.c | 80 + src/doveadm/dsync/test-dsync-common.h | 18 + src/doveadm/dsync/test-dsync-proxy-server-cmd.c | 482 +++++ src/doveadm/dsync/test-dsync-proxy.c | 184 ++ src/doveadm/dsync/test-dsync-worker.c | 481 +++++ src/doveadm/dsync/test-dsync-worker.h | 96 + src/dsync/Makefile.am | 88 - src/dsync/dsync-brain-msgs-new.c | 392 ---- src/dsync/dsync-brain-msgs.c | 537 ------ src/dsync/dsync-brain-private.h | 144 - src/dsync/dsync-brain.c | 918 ----------- src/dsync/dsync-brain.h | 28 - src/dsync/dsync-data.c | 146 - src/dsync/dsync-data.h | 84 - src/dsync/dsync-proxy-client.c | 1192 -------------- src/dsync/dsync-proxy-server-cmd.c | 609 ------- src/dsync/dsync-proxy-server.c | 206 -- src/dsync/dsync-proxy-server.h | 46 - src/dsync/dsync-proxy.c | 412 ---- src/dsync/dsync-proxy.h | 55 - src/dsync/dsync-worker-local.c | 1895 ---------------------- src/dsync/dsync-worker-private.h | 105 - src/dsync/dsync-worker.c | 285 --- src/dsync/dsync-worker.h | 164 - src/dsync/dsync.c | 364 ---- src/dsync/test-dsync-brain-msgs.c | 670 -------- src/dsync/test-dsync-brain.c | 294 --- src/dsync/test-dsync-common.c | 80 - src/dsync/test-dsync-common.h | 18 - src/dsync/test-dsync-proxy-server-cmd.c | 485 ----- src/dsync/test-dsync-proxy.c | 184 -- src/dsync/test-dsync-worker.c | 481 ----- src/dsync/test-dsync-worker.h | 96 - 65 files changed, 10173 insertions(+), 10024 deletions(-) diffs (truncated from 20702 to 300 lines): diff -r 3c7e01a5c7b7 -r 4c827134997f .hgignore --- a/.hgignore Thu Dec 29 11:19:52 2011 +0200 +++ b/.hgignore Thu Dec 29 14:43:45 2011 +0200 @@ -66,7 +66,6 @@ src/dns/dns-client src/doveadm/doveadm src/doveadm/doveadm-server -src/dsync/dsync src/imap-login/imap-login src/imap/imap src/indexer/indexer diff -r 3c7e01a5c7b7 -r 4c827134997f configure.in --- a/configure.in Thu Dec 29 11:19:52 2011 +0200 +++ b/configure.in Thu Dec 29 14:43:45 2011 +0200 @@ -2750,7 +2750,7 @@ src/auth/Makefile src/config/Makefile src/doveadm/Makefile -src/dsync/Makefile +src/doveadm/dsync/Makefile src/lda/Makefile src/log/Makefile src/lmtp/Makefile diff -r 3c7e01a5c7b7 -r 4c827134997f src/Makefile.am --- a/src/Makefile.am Thu Dec 29 11:19:52 2011 +0200 +++ b/src/Makefile.am Thu Dec 29 14:43:45 2011 +0200 @@ -41,7 +41,6 @@ director \ util \ doveadm \ - dsync \ ssl-params \ stats \ plugins diff -r 3c7e01a5c7b7 -r 4c827134997f src/doveadm/Makefile.am --- a/src/doveadm/Makefile.am Thu Dec 29 11:19:52 2011 +0200 +++ b/src/doveadm/Makefile.am Thu Dec 29 14:43:45 2011 +0200 @@ -1,6 +1,8 @@ doveadm_moduledir = $(moduledir)/doveadm pkglibexecdir = $(libexecdir)/dovecot +SUBDIRS = dsync + bin_PROGRAMS = doveadm pkglibexec_PROGRAMS = doveadm-server @@ -35,6 +37,7 @@ ../lib-otp/libotp.a libs = \ + dsync/libdsync.a \ $(LIBDOVECOT_STORAGE) \ $(unused_objects) @@ -122,3 +125,7 @@ doveadm-settings.h \ doveadm-util.h \ doveadm-who.h + +install-exec-local: + rm -f $(DESTDIR)$(bindir)/dsync + $(LN_S) doveadm $(DESTDIR)$(bindir)/dsync diff -r 3c7e01a5c7b7 -r 4c827134997f src/doveadm/client-connection.c --- a/src/doveadm/client-connection.c Thu Dec 29 11:19:52 2011 +0200 +++ b/src/doveadm/client-connection.c Thu Dec 29 14:43:45 2011 +0200 @@ -41,9 +41,6 @@ const struct mail_storage_service_input *input, int argc, char *argv[]) { - enum mail_storage_service_flags service_flags = - MAIL_STORAGE_SERVICE_FLAG_NO_LOG_INIT | - MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP; struct doveadm_mail_cmd_context *ctx; const struct doveadm_mail_cmd *cmd; const char *getopt_args; @@ -56,12 +53,15 @@ return FALSE; } - if (doveadm_debug) - service_flags |= MAIL_STORAGE_SERVICE_FLAG_DEBUG; - ctx = doveadm_mail_cmd_init(cmd, set); ctx->full_args = (const void *)(argv + 1); + ctx->service_flags |= + MAIL_STORAGE_SERVICE_FLAG_NO_LOG_INIT | + MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP; + if (doveadm_debug) + ctx->service_flags |= MAIL_STORAGE_SERVICE_FLAG_DEBUG; + getopt_args = t_strconcat("AS:u:", ctx->getopt_args, NULL); while ((c = getopt(argc, argv, getopt_args)) > 0) { switch (c) { @@ -106,7 +106,10 @@ } ctx->args = (const void *)argv; - doveadm_mail_single_user(ctx, input, service_flags); + if (ctx->v.preinit != NULL) + ctx->v.preinit(ctx); + + doveadm_mail_single_user(ctx, input); doveadm_mail_server_flush(); ctx->v.deinit(ctx); doveadm_print_flush(); diff -r 3c7e01a5c7b7 -r 4c827134997f src/doveadm/doveadm-mail.c --- a/src/doveadm/doveadm-mail.c Thu Dec 29 11:19:52 2011 +0200 +++ b/src/doveadm/doveadm-mail.c Thu Dec 29 14:43:45 2011 +0200 @@ -19,6 +19,7 @@ #include "doveadm.h" #include "doveadm-settings.h" #include "doveadm-print.h" +#include "dsync/doveadm-dsync.h" #include "doveadm-mail.h" #include @@ -186,7 +187,6 @@ const struct mail_storage_service_input *input, const char **error_r) { - struct mail_storage_service_user *service_user; const char *error; int ret; @@ -199,7 +199,7 @@ return ret; ret = mail_storage_service_lookup(ctx->storage_service, input, - &service_user, &error); + &ctx->cur_service_user, &error); if (ret <= 0) { if (ret < 0) { *error_r = t_strdup_printf("User lookup failed: %s", @@ -208,31 +208,32 @@ return ret; } - ret = mail_storage_service_next(ctx->storage_service, service_user, + ret = mail_storage_service_next(ctx->storage_service, + ctx->cur_service_user, &ctx->cur_mail_user); if (ret < 0) { *error_r = "User init failed"; - mail_storage_service_user_free(&service_user); + mail_storage_service_user_free(&ctx->cur_service_user); return ret; } ctx->v.run(ctx, ctx->cur_mail_user); mail_user_unref(&ctx->cur_mail_user); - mail_storage_service_user_free(&service_user); + mail_storage_service_user_free(&ctx->cur_service_user); return 1; } void doveadm_mail_single_user(struct doveadm_mail_cmd_context *ctx, - const struct mail_storage_service_input *input, - enum mail_storage_service_flags service_flags) + const struct mail_storage_service_input *input) { const char *error; int ret; i_assert(input->username != NULL); + ctx->cur_username = input->username; ctx->storage_service = mail_storage_service_init(master_service, NULL, - service_flags); + ctx->service_flags); ctx->v.init(ctx, ctx->args); if (hook_doveadm_mail_init != NULL) hook_doveadm_mail_init(ctx); @@ -251,21 +252,20 @@ static void doveadm_mail_all_users(struct doveadm_mail_cmd_context *ctx, char *argv[], - const char *wildcard_user, - enum mail_storage_service_flags service_flags) + const char *wildcard_user) { struct mail_storage_service_input input; unsigned int user_idx, user_count, interval, n; const char *user, *error; int ret; - service_flags |= MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP; + ctx->service_flags |= MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP; memset(&input, 0, sizeof(input)); input.service = "doveadm"; ctx->storage_service = mail_storage_service_init(master_service, NULL, - service_flags); + ctx->service_flags); lib_signals_set_handler(SIGINT, 0, sig_die, NULL); lib_signals_set_handler(SIGTERM, 0, sig_die, NULL); @@ -355,20 +355,19 @@ static void doveadm_mail_cmd(const struct doveadm_mail_cmd *cmd, int argc, char *argv[]) { - enum mail_storage_service_flags service_flags = - MAIL_STORAGE_SERVICE_FLAG_NO_LOG_INIT; struct doveadm_mail_cmd_context *ctx; - const char *getopt_args, *username, *wildcard_user; + const char *getopt_args, *wildcard_user; int c; - if (doveadm_debug) - service_flags |= MAIL_STORAGE_SERVICE_FLAG_DEBUG; - ctx = doveadm_mail_cmd_init(cmd, doveadm_settings); ctx->full_args = (const void *)(argv + 1); + ctx->service_flags |= MAIL_STORAGE_SERVICE_FLAG_NO_LOG_INIT; + if (doveadm_debug) + ctx->service_flags |= MAIL_STORAGE_SERVICE_FLAG_DEBUG; + getopt_args = t_strconcat("AS:u:", ctx->getopt_args, NULL); - username = getenv("USER"); + ctx->cur_username = getenv("USER"); wildcard_user = NULL; while ((c = getopt(argc, argv, getopt_args)) > 0) { switch (c) { @@ -381,12 +380,14 @@ doveadm_settings->doveadm_worker_count = 1; break; case 'u': - service_flags |= + ctx->service_flags |= MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP; - username = optarg; - if (strchr(username, '*') != NULL || - strchr(username, '?') != NULL) - wildcard_user = username; + ctx->cur_username = optarg; + if (strchr(ctx->cur_username, '*') != NULL || + strchr(ctx->cur_username, '?') != NULL) { + wildcard_user = ctx->cur_username; + ctx->cur_username = NULL; + } break; default: if (ctx->v.parse_arg == NULL || @@ -400,6 +401,8 @@ cmd->name, argv[0]); } ctx->args = (const void *)argv; + if (ctx->v.preinit != NULL) + ctx->v.preinit(ctx); ctx->iterate_single_user = !ctx->iterate_all_users && wildcard_user == NULL; @@ -412,16 +415,16 @@ if (ctx->iterate_single_user) { struct mail_storage_service_input input; - if (username == NULL) + if (ctx->cur_username == NULL) i_fatal("USER environment is missing and -u option not used"); memset(&input, 0, sizeof(input)); input.service = "doveadm"; - input.username = username; - doveadm_mail_single_user(ctx, &input, service_flags); + input.username = ctx->cur_username; + doveadm_mail_single_user(ctx, &input); } else { - service_flags |= MAIL_STORAGE_SERVICE_FLAG_TEMP_PRIV_DROP; - doveadm_mail_all_users(ctx, argv, wildcard_user, service_flags); + ctx->service_flags |= MAIL_STORAGE_SERVICE_FLAG_TEMP_PRIV_DROP; + doveadm_mail_all_users(ctx, argv, wildcard_user); } if (ctx->search_args != NULL) mail_search_args_unref(&ctx->search_args); @@ -432,6 +435,8 @@ /* service deinit unloads mail plugins, so do it late */ mail_storage_service_deinit(&ctx->storage_service); + if (ctx->exit_code != 0) + exit(ctx->exit_code); if (ctx->failed) exit(FATAL_DEFAULT); pool_unref(&ctx->pool); @@ -579,7 +584,10 @@ &cmd_mailbox_rename, &cmd_mailbox_subscribe, &cmd_mailbox_unsubscribe, - &cmd_mailbox_status + &cmd_mailbox_status, + &cmd_dsync_backup, + &cmd_dsync_mirror, + &cmd_dsync_server }; void doveadm_mail_init(void) diff -r 3c7e01a5c7b7 -r 4c827134997f src/doveadm/doveadm-mail.h --- a/src/doveadm/doveadm-mail.h Thu Dec 29 11:19:52 2011 +0200 +++ b/src/doveadm/doveadm-mail.h Thu Dec 29 14:43:45 2011 +0200 From dovecot at dovecot.org Fri Dec 30 11:55:19 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 30 Dec 2011 11:55:19 +0200 Subject: dovecot-2.1: lib-storage: Added struct mailbox.set_subscribed() ... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/bc9217cb0193 changeset: 13876:bc9217cb0193 user: Timo Sirainen date: Fri Dec 30 11:54:48 2011 +0200 description: lib-storage: Added struct mailbox.set_subscribed() virtual method. diffstat: src/lib-storage/index/cydir/cydir-storage.c | 1 + src/lib-storage/index/dbox-multi/mdbox-storage.c | 1 + src/lib-storage/index/dbox-single/sdbox-storage.c | 1 + src/lib-storage/index/imapc/imapc-storage.c | 1 + src/lib-storage/index/index-storage.c | 35 +++++++++++++++++++++++ src/lib-storage/index/index-storage.h | 1 + src/lib-storage/index/maildir/maildir-storage.c | 1 + src/lib-storage/index/mbox/mbox-storage.c | 1 + src/lib-storage/index/raw/raw-storage.c | 1 + src/lib-storage/mail-storage-private.h | 1 + src/lib-storage/mail-storage.c | 33 +-------------------- src/lib-storage/test-mailbox.c | 9 +++++ src/plugins/virtual/virtual-storage.c | 1 + 13 files changed, 56 insertions(+), 31 deletions(-) diffs (226 lines): diff -r 4c827134997f -r bc9217cb0193 src/lib-storage/index/cydir/cydir-storage.c --- a/src/lib-storage/index/cydir/cydir-storage.c Thu Dec 29 14:43:45 2011 +0200 +++ b/src/lib-storage/index/cydir/cydir-storage.c Fri Dec 30 11:54:48 2011 +0200 @@ -139,6 +139,7 @@ index_storage_mailbox_rename, index_storage_get_status, NULL, + index_storage_set_subscribed, index_storage_list_index_has_changed, index_storage_list_index_update_sync, cydir_storage_sync_init, diff -r 4c827134997f -r bc9217cb0193 src/lib-storage/index/dbox-multi/mdbox-storage.c --- a/src/lib-storage/index/dbox-multi/mdbox-storage.c Thu Dec 29 14:43:45 2011 +0200 +++ b/src/lib-storage/index/dbox-multi/mdbox-storage.c Fri Dec 30 11:54:48 2011 +0200 @@ -437,6 +437,7 @@ index_storage_mailbox_rename, index_storage_get_status, mdbox_mailbox_get_metadata, + index_storage_set_subscribed, index_storage_list_index_has_changed, index_storage_list_index_update_sync, mdbox_storage_sync_init, diff -r 4c827134997f -r bc9217cb0193 src/lib-storage/index/dbox-single/sdbox-storage.c --- a/src/lib-storage/index/dbox-single/sdbox-storage.c Thu Dec 29 14:43:45 2011 +0200 +++ b/src/lib-storage/index/dbox-single/sdbox-storage.c Fri Dec 30 11:54:48 2011 +0200 @@ -397,6 +397,7 @@ index_storage_mailbox_rename, index_storage_get_status, sdbox_mailbox_get_metadata, + index_storage_set_subscribed, index_storage_list_index_has_changed, index_storage_list_index_update_sync, sdbox_storage_sync_init, diff -r 4c827134997f -r bc9217cb0193 src/lib-storage/index/imapc/imapc-storage.c --- a/src/lib-storage/index/imapc/imapc-storage.c Thu Dec 29 14:43:45 2011 +0200 +++ b/src/lib-storage/index/imapc/imapc-storage.c Fri Dec 30 11:54:48 2011 +0200 @@ -772,6 +772,7 @@ index_storage_mailbox_rename, imapc_mailbox_get_status, imapc_mailbox_get_metadata, + index_storage_set_subscribed, NULL, NULL, imapc_mailbox_sync_init, diff -r 4c827134997f -r bc9217cb0193 src/lib-storage/index/index-storage.c --- a/src/lib-storage/index/index-storage.c Thu Dec 29 14:43:45 2011 +0200 +++ b/src/lib-storage/index/index-storage.c Fri Dec 30 11:54:48 2011 +0200 @@ -664,3 +664,38 @@ } } T_END; } + +int index_storage_set_subscribed(struct mailbox *box, bool set) +{ + struct mail_namespace *ns; + struct mailbox_list *list = box->list; + const char *subs_name; + + if ((list->ns->flags & NAMESPACE_FLAG_SUBSCRIPTIONS) != 0) + subs_name = box->name; + else { + /* subscriptions=no namespace, find another one where we can + add the subscription to */ + ns = mail_namespace_find_subscribable(list->ns->user->namespaces, + box->vname); + if (ns == NULL) { + mail_storage_set_error(box->storage, MAIL_ERROR_NOTPOSSIBLE, + "This namespace has no subscriptions"); + return -1; + } + /* use as the + subscription name */ + subs_name = t_strconcat(list->ns->prefix, box->name, NULL); + /* drop the common prefix (typically there isn't one) */ + i_assert(strncmp(ns->prefix, subs_name, strlen(ns->prefix)) == 0); + subs_name += strlen(ns->prefix); + + list = ns->list; + } + if (mailbox_list_set_subscribed(list, subs_name, set) < 0) { + mail_storage_copy_list_error(box->storage, list); + return -1; + } + return 0; +} + diff -r 4c827134997f -r bc9217cb0193 src/lib-storage/index/index-storage.h --- a/src/lib-storage/index/index-storage.h Thu Dec 29 14:43:45 2011 +0200 +++ b/src/lib-storage/index/index-storage.h Fri Dec 30 11:54:48 2011 +0200 @@ -134,6 +134,7 @@ void index_save_context_free(struct mail_save_context *ctx); void index_copy_cache_fields(struct mail_save_context *ctx, struct mail *src_mail, uint32_t dest_seq); +int index_storage_set_subscribed(struct mailbox *box, bool set); bool index_keyword_array_cmp(const ARRAY_TYPE(keyword_indexes) *k1, const ARRAY_TYPE(keyword_indexes) *k2); diff -r 4c827134997f -r bc9217cb0193 src/lib-storage/index/maildir/maildir-storage.c --- a/src/lib-storage/index/maildir/maildir-storage.c Thu Dec 29 14:43:45 2011 +0200 +++ b/src/lib-storage/index/maildir/maildir-storage.c Fri Dec 30 11:54:48 2011 +0200 @@ -625,6 +625,7 @@ index_storage_mailbox_rename, index_storage_get_status, maildir_mailbox_get_metadata, + index_storage_set_subscribed, maildir_list_index_has_changed, maildir_list_index_update_sync, maildir_storage_sync_init, diff -r 4c827134997f -r bc9217cb0193 src/lib-storage/index/mbox/mbox-storage.c --- a/src/lib-storage/index/mbox/mbox-storage.c Thu Dec 29 14:43:45 2011 +0200 +++ b/src/lib-storage/index/mbox/mbox-storage.c Fri Dec 30 11:54:48 2011 +0200 @@ -776,6 +776,7 @@ index_storage_mailbox_rename, index_storage_get_status, mbox_mailbox_get_metadata, + index_storage_set_subscribed, index_storage_list_index_has_changed, index_storage_list_index_update_sync, mbox_storage_sync_init, diff -r 4c827134997f -r bc9217cb0193 src/lib-storage/index/raw/raw-storage.c --- a/src/lib-storage/index/raw/raw-storage.c Thu Dec 29 14:43:45 2011 +0200 +++ b/src/lib-storage/index/raw/raw-storage.c Fri Dec 30 11:54:48 2011 +0200 @@ -218,6 +218,7 @@ index_storage_mailbox_rename, index_storage_get_status, index_mailbox_get_metadata, + index_storage_set_subscribed, index_storage_list_index_has_changed, index_storage_list_index_update_sync, raw_storage_sync_init, diff -r 4c827134997f -r bc9217cb0193 src/lib-storage/mail-storage-private.h --- a/src/lib-storage/mail-storage-private.h Thu Dec 29 14:43:45 2011 +0200 +++ b/src/lib-storage/mail-storage-private.h Fri Dec 30 11:54:48 2011 +0200 @@ -126,6 +126,7 @@ int (*get_metadata)(struct mailbox *box, enum mailbox_metadata_items items, struct mailbox_metadata *metadata_r); + int (*set_subscribed)(struct mailbox *box, bool set); /* Lookup sync extension record and figure out if it mailbox has changed since. Returns 1 = yes, 0 = no, -1 = error. */ diff -r 4c827134997f -r bc9217cb0193 src/lib-storage/mail-storage.c --- a/src/lib-storage/mail-storage.c Thu Dec 29 14:43:45 2011 +0200 +++ b/src/lib-storage/mail-storage.c Fri Dec 30 11:54:48 2011 +0200 @@ -1199,42 +1199,13 @@ int mailbox_set_subscribed(struct mailbox *box, bool set) { - struct mail_namespace *ns; - struct mailbox_list *list = box->list; - const char *subs_name; - - if (!mailbox_list_is_valid_existing_name(list, box->name)) { + if (!mailbox_list_is_valid_existing_name(box->list, box->name)) { mail_storage_set_error(box->storage, MAIL_ERROR_PARAMS, "Invalid mailbox name"); return -1; } - if ((list->ns->flags & NAMESPACE_FLAG_SUBSCRIPTIONS) != 0) - subs_name = box->name; - else { - /* subscriptions=no namespace, find another one where we can - add the subscription to */ - ns = mail_namespace_find_subscribable(list->ns->user->namespaces, - box->vname); - if (ns == NULL) { - mail_storage_set_error(box->storage, MAIL_ERROR_NOTPOSSIBLE, - "This namespace has no subscriptions"); - return -1; - } - /* use as the - subscription name */ - subs_name = t_strconcat(list->ns->prefix, box->name, NULL); - /* drop the common prefix (typically there isn't one) */ - i_assert(strncmp(ns->prefix, subs_name, strlen(ns->prefix)) == 0); - subs_name += strlen(ns->prefix); - - list = ns->list; - } - if (mailbox_list_set_subscribed(list, subs_name, set) < 0) { - mail_storage_copy_list_error(box->storage, list); - return -1; - } - return 0; + return box->v.set_subscribed(box, set); } struct mail_storage *mailbox_get_storage(const struct mailbox *box) diff -r 4c827134997f -r bc9217cb0193 src/lib-storage/test-mailbox.c --- a/src/lib-storage/test-mailbox.c Thu Dec 29 14:43:45 2011 +0200 +++ b/src/lib-storage/test-mailbox.c Fri Dec 30 11:54:48 2011 +0200 @@ -82,6 +82,14 @@ return 0; } +static int test_mailbox_set_subscribed(struct mailbox *box, + bool set ATTR_UNUSED) +{ + mail_storage_set_error(box->storage, MAIL_ERROR_NOTPOSSIBLE, + "Test mailbox subscribing isn't supported"); + return -1; +} + static struct mailbox_sync_context * test_mailbox_sync_init(struct mailbox *box, enum mailbox_sync_flags flags ATTR_UNUSED) @@ -244,6 +252,7 @@ test_mailbox_rename, test_mailbox_get_status, NULL, + test_mailbox_set_subscribed, NULL, NULL, test_mailbox_sync_init, diff -r 4c827134997f -r bc9217cb0193 src/plugins/virtual/virtual-storage.c --- a/src/plugins/virtual/virtual-storage.c Thu Dec 29 14:43:45 2011 +0200 +++ b/src/plugins/virtual/virtual-storage.c Fri Dec 30 11:54:48 2011 +0200 @@ -528,6 +528,7 @@ index_storage_mailbox_rename, virtual_storage_get_status, virtual_mailbox_get_metadata, + index_storage_set_subscribed, NULL, NULL, virtual_storage_sync_init, From dovecot at dovecot.org Fri Dec 30 12:33:17 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 30 Dec 2011 12:33:17 +0200 Subject: dovecot-2.1: Use master_service_connection.name for determining ... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/5df67a23afb9 changeset: 13878:5df67a23afb9 user: Timo Sirainen date: Fri Dec 30 12:33:06 2011 +0200 description: Use master_service_connection.name for determining listener type. diffstat: src/auth/main.c | 38 +++++++++++++++++++------------------- src/director/main.c | 17 ++++------------- src/ipc/main.c | 22 ++++++++-------------- 3 files changed, 31 insertions(+), 46 deletions(-) diffs (146 lines): diff -r cdf2c63ece6a -r 5df67a23afb9 src/auth/main.c --- a/src/auth/main.c Fri Dec 30 12:31:58 2011 +0200 +++ b/src/auth/main.c Fri Dec 30 12:33:06 2011 +0200 @@ -96,21 +96,9 @@ } static enum auth_socket_type -auth_socket_type_get(int listen_fd, const char **path_r) +auth_socket_type_get(const char *path) { - const char *path, *name, *suffix; - - /* figure out if this is a server or network socket by - checking the socket path name. */ - if (net_getunixname(listen_fd, &path) < 0) { - if (errno != ENOTSOCK) - i_fatal("getunixname(%d) failed: %m", listen_fd); - /* not UNIX socket. let's just assume it's an - auth client. */ - *path_r = NULL; - return AUTH_SOCKET_CLIENT; - } - *path_r = path; + const char *name, *suffix; name = strrchr(path, '/'); if (name == NULL) @@ -146,11 +134,17 @@ struct auth_socket_listener *l; l = array_idx_modifiable(&listeners, fd); - l->type = auth_socket_type_get(fd, &path); - l->path = i_strdup(path); - if (l->type == AUTH_SOCKET_USERDB) { - if (stat(path, &l->st) < 0) - i_error("stat(%s) failed: %m", path); + if (net_getunixname(fd, &path) < 0) { + if (errno != ENOTSOCK) + i_fatal("getunixname(%d) failed: %m", fd); + /* not a unix socket, set its name and type lazily */ + } else { + l->type = auth_socket_type_get(path); + l->path = i_strdup(path); + if (l->type == AUTH_SOCKET_USERDB) { + if (stat(path, &l->st) < 0) + i_error("stat(%s) failed: %m", path); + } } } } @@ -311,6 +305,12 @@ struct auth *auth; l = array_idx_modifiable(&listeners, conn->listen_fd); + if (l->type == AUTH_SOCKET_UNKNOWN) { + /* first connection from inet socket, figure out its type + from the listener name */ + l->type = auth_socket_type_get(conn->name); + l->path = i_strdup(conn->name); + } auth = auth_find_service(NULL); switch (l->type) { case AUTH_SOCKET_MASTER: diff -r cdf2c63ece6a -r 5df67a23afb9 src/director/main.c --- a/src/director/main.c Fri Dec 30 12:31:58 2011 +0200 +++ b/src/director/main.c Fri Dec 30 12:33:06 2011 +0200 @@ -41,7 +41,7 @@ static void client_connected(struct master_service_connection *conn) { struct auth_connection *auth; - const char *path, *name, *socket_path; + const char *socket_path; struct ip_addr ip; unsigned int local_port, len; bool userdb; @@ -70,17 +70,8 @@ return; } - if (net_getunixname(conn->listen_fd, &path) < 0) - i_fatal("getunixname(%d) failed: %m", conn->listen_fd); - - name = strrchr(path, '/'); - if (name == NULL) - name = path; - else - name++; - - len = strlen(name); - if (len > 6 && strcmp(name + len - 6, "-admin") == 0) { + len = strlen(conn->name); + if (len > 6 && strcmp(conn->name + len - 6, "-admin") == 0) { /* doveadm connection */ master_service_client_connection_accept(conn); (void)doveadm_connection_init(director, conn->fd); @@ -91,7 +82,7 @@ b) login connection Both of them are handled exactly the same, except for which auth socket they connect to. */ - userdb = len > 7 && strcmp(name + len - 7, "-userdb") == 0; + userdb = len > 7 && strcmp(conn->name + len - 7, "-userdb") == 0; socket_path = userdb ? AUTH_USERDB_SOCKET_PATH : AUTH_SOCKET_PATH; auth = auth_connection_init(socket_path); if (auth_connection_connect(auth) == 0) { diff -r cdf2c63ece6a -r 5df67a23afb9 src/ipc/main.c --- a/src/ipc/main.c Fri Dec 30 12:31:58 2011 +0200 +++ b/src/ipc/main.c Fri Dec 30 12:33:06 2011 +0200 @@ -8,30 +8,24 @@ #include "ipc-connection.h" #include "client.h" -static bool ipc_socket_is_client(int listen_fd) +static bool ipc_socket_is_client(const char *name) { - const char *path, *name; + unsigned int len; - if (net_getunixname(listen_fd, &path) < 0) { - if (errno != ENOTSOCK) - i_fatal("getunixname(%d) failed: %m", listen_fd); - /* not a UNIX socket. let's just assume it's a client. */ + if (strcmp(name, "ipc") == 0) return TRUE; - } - name = strrchr(path, '/'); - if (name == NULL) - name = path; - else - name++; - return strcmp(name, "ipc") == 0; + len = strlen(name); + if (len > 7 && strcmp(name + len - 7, "-client") == 0) + return TRUE; + return FALSE; } static void client_connected(struct master_service_connection *conn) { master_service_client_connection_accept(conn); - if (ipc_socket_is_client(conn->listen_fd)) + if (ipc_socket_is_client(conn->name)) (void)client_create(conn->fd); else (void)ipc_connection_create(conn->listen_fd, conn->fd); From dovecot at dovecot.org Fri Dec 30 12:33:17 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 30 Dec 2011 12:33:17 +0200 Subject: dovecot-2.1: Listener names are now in struct master_service_con... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/cdf2c63ece6a changeset: 13877:cdf2c63ece6a user: Timo Sirainen date: Fri Dec 30 12:31:58 2011 +0200 description: Listener names are now in struct master_service_connection.name This allows service to use the names to figure out what type the listener is. diffstat: src/lib-master/master-service-private.h | 5 ++++- src/lib-master/master-service.c | 11 +++++++++++ src/lib-master/master-service.h | 1 + src/master/service-process.c | 12 ++++++++++++ src/master/service.c | 6 ++++++ src/master/service.h | 1 + 6 files changed, 35 insertions(+), 1 deletions(-) diffs (171 lines): diff -r bc9217cb0193 -r cdf2c63ece6a src/lib-master/master-service-private.h --- a/src/lib-master/master-service-private.h Fri Dec 30 11:54:48 2011 +0200 +++ b/src/lib-master/master-service-private.h Fri Dec 30 12:31:58 2011 +0200 @@ -9,6 +9,7 @@ int fd; bool ssl; struct io *io; + const char *name; }; struct master_service { @@ -28,7 +29,9 @@ int syslog_facility; unsigned int socket_count, ssl_socket_count; - struct master_service_listener *listeners; + struct master_service_listener *listeners; + char **listener_names; + unsigned int listener_names_count; struct io *io_status_write, *io_status_error; unsigned int service_count_left; diff -r bc9217cb0193 -r cdf2c63ece6a src/lib-master/master-service.c --- a/src/lib-master/master-service.c Fri Dec 30 11:54:48 2011 +0200 +++ b/src/lib-master/master-service.c Fri Dec 30 12:31:58 2011 +0200 @@ -4,6 +4,7 @@ #include "lib-signals.h" #include "ioloop.h" #include "array.h" +#include "strescape.h" #include "env-util.h" #include "home-expand.h" #include "process-title.h" @@ -172,6 +173,13 @@ value = getenv("SSL_SOCKET_COUNT"); if (value != NULL) service->ssl_socket_count = atoi(value); + value = getenv("SOCKET_NAMES"); + if (value != NULL) { + service->listener_names = + p_strsplit_tabescaped(default_pool, value); + service->listener_names_count = + str_array_length((void *)service->listener_names); + } /* set up some kind of logging until we know exactly how and where we want to log */ @@ -746,6 +754,7 @@ l->fd = -1; } conn.ssl = l->ssl; + conn.name = l->name; net_set_nonblock(conn.fd, TRUE); master_service_client_connection_created(service); @@ -779,6 +788,8 @@ l->service = service; l->fd = MASTER_LISTEN_FD_FIRST + i; + l->name = i < service->listener_names_count ? + service->listener_names[i] : ""; if (i >= service->socket_count - service->ssl_socket_count) l->ssl = TRUE; diff -r bc9217cb0193 -r cdf2c63ece6a src/lib-master/master-service.h --- a/src/lib-master/master-service.h Fri Dec 30 11:54:48 2011 +0200 +++ b/src/lib-master/master-service.h Fri Dec 30 12:31:58 2011 +0200 @@ -28,6 +28,7 @@ struct master_service_connection { int fd; int listen_fd; + const char *name; struct ip_addr remote_ip; unsigned int remote_port; diff -r bc9217cb0193 -r cdf2c63ece6a src/master/service-process.c --- a/src/master/service-process.c Fri Dec 30 11:54:48 2011 +0200 +++ b/src/master/service-process.c Fri Dec 30 12:31:58 2011 +0200 @@ -10,6 +10,7 @@ #include "base64.h" #include "hash.h" #include "str.h" +#include "strescape.h" #include "llist.h" #include "hostpid.h" #include "env-util.h" @@ -38,6 +39,7 @@ { struct service_listener *const *listeners; ARRAY_TYPE(dup2) dups; + string_t *listener_names; unsigned int i, count, n = 0, socket_listener_count, ssl_socket_count; /* stdin/stdout is already redirected to /dev/null. Other master fds @@ -50,6 +52,7 @@ socket_listener_count = 0; listeners = array_get(&service->listeners, &count); t_array_init(&dups, count + 10); + listener_names = t_str_new(256); switch (service->type) { case SERVICE_TYPE_LOG: @@ -73,11 +76,17 @@ break; } + /* anvil/log fds have no names */ + for (i = MASTER_LISTEN_FD_FIRST; i < n; i++) + str_append_c(listener_names, '\t'); + /* first add non-ssl listeners */ for (i = 0; i < count; i++) { if (listeners[i]->fd != -1 && (listeners[i]->type != SERVICE_LISTENER_INET || !listeners[i]->set.inetset.set->ssl)) { + str_tabescape_write(listener_names, listeners[i]->name); + str_append_c(listener_names, '\t'); dup2_append(&dups, listeners[i]->fd, MASTER_LISTEN_FD_FIRST + n); n++; socket_listener_count++; @@ -89,6 +98,8 @@ if (listeners[i]->fd != -1 && listeners[i]->type == SERVICE_LISTENER_INET && listeners[i]->set.inetset.set->ssl) { + str_tabescape_write(listener_names, listeners[i]->name); + str_append_c(listener_names, '\t'); dup2_append(&dups, listeners[i]->fd, MASTER_LISTEN_FD_FIRST + n); n++; socket_listener_count++; @@ -147,6 +158,7 @@ env_put(t_strdup_printf("SOCKET_COUNT=%d", socket_listener_count)); env_put(t_strdup_printf("SSL_SOCKET_COUNT=%d", ssl_socket_count)); + env_put(t_strdup_printf("SOCKET_NAMES=%s", str_c(listener_names))); } static void diff -r bc9217cb0193 -r cdf2c63ece6a src/master/service.c --- a/src/master/service.c Fri Dec 30 11:54:48 2011 +0200 +++ b/src/master/service.c Fri Dec 30 12:31:58 2011 +0200 @@ -46,6 +46,11 @@ l->type = type; l->fd = -1; l->set.fileset.set = set; + l->name = strrchr(set->path, '/'); + if (l->name != NULL) + l->name++; + else + l->name = set->path; if (get_uidgid(set->user, &l->set.fileset.uid, &gid, error_r) < 0) set_name = "user"; @@ -123,6 +128,7 @@ l->set.inetset.set = set; l->set.inetset.ip = *ip; l->inet_address = p_strdup(service->list->pool, address); + l->name = set->name; if (set->port > 65535) { *error_r = t_strdup_printf("Invalid port: %u", set->port); diff -r bc9217cb0193 -r cdf2c63ece6a src/master/service.h --- a/src/master/service.h Fri Dec 30 11:54:48 2011 +0200 +++ b/src/master/service.h Fri Dec 30 12:31:58 2011 +0200 @@ -21,6 +21,7 @@ int fd; /* may be -1 */ struct io *io; + const char *name; const char *inet_address; union { From dovecot at dovecot.org Fri Dec 30 17:44:47 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 30 Dec 2011 17:44:47 +0200 Subject: dovecot-2.1: doveadm stats top: Added -b parameter to use read_b... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/193c66096bb3 changeset: 13879:193c66096bb3 user: Timo Sirainen date: Fri Dec 30 17:44:23 2011 +0200 description: doveadm stats top: Added -b parameter to use read_bytes/write_bytes fields for disk io. This is useful when the kernel doesn't support the actual disk IO fields. diffstat: src/doveadm/doveadm-stats.c | 19 ++++++++++++++----- 1 files changed, 14 insertions(+), 5 deletions(-) diffs (61 lines): diff -r 5df67a23afb9 -r 193c66096bb3 src/doveadm/doveadm-stats.c --- a/src/doveadm/doveadm-stats.c Fri Dec 30 12:33:06 2011 +0200 +++ b/src/doveadm/doveadm-stats.c Fri Dec 30 17:44:23 2011 +0200 @@ -48,6 +48,8 @@ }; static struct top_context *sort_ctx = NULL; +static const char *disk_input_field = "disk_input"; +static const char *disk_output_field = "disk_output"; static char ** p_read_next_line(pool_t pool, struct istream *input) @@ -318,8 +320,8 @@ return; } if (strcmp(ctx->sort_type, "disk") == 0) { - if (!stats_header_find(ctx, "disk_input", &ctx->sort_idx1) || - !stats_header_find(ctx, "disk_output", &ctx->sort_idx2)) + if (!stats_header_find(ctx, disk_input_field, &ctx->sort_idx1) || + !stats_header_find(ctx, disk_output_field, &ctx->sort_idx2)) i_fatal("disk sort type is missing fields"); return; } @@ -407,12 +409,15 @@ { static const char *names[] = { "user", "service", "user_cpu", "sys_cpu", - "disk_input", "disk_output" + "", "" }; struct winsize ws; struct top_line *const *lines; unsigned int i, j, row, maxrow, count, indexes[N_ELEMENTS(names)]; + names[4] = disk_input_field; + names[5] = disk_output_field; + /* ANSI clear screen and move cursor to top of screen */ printf("\x1b[2J\x1b[1;1H"); fflush(stdout); doveadm_print_deinit(); @@ -499,8 +504,12 @@ path = t_strconcat(doveadm_settings->base_dir, "/stats", NULL); - while ((c = getopt(argc, argv, "s:")) > 0) { + while ((c = getopt(argc, argv, "bs:")) > 0) { switch (c) { + case 'b': + disk_input_field = "read_bytes"; + disk_output_field = "write_bytes"; + break; case 's': path = optarg; break; @@ -525,5 +534,5 @@ }; struct doveadm_cmd doveadm_cmd_stats_top = { - cmd_stats_top, "stats top", "[-s ] []" + cmd_stats_top, "stats top", "[-s ] [-b] []" };